From 80f1077b35e1d4d9d87558f80a6a8eb3d905a021 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 23:28:42 +0100 Subject: [PATCH 001/249] Updating snapcraft --- snapcraft.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 0fbd1c7..c6632f9 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -3,15 +3,14 @@ title: LogarithmPlotter version: '0.5.0' summary: Create and edit Bode plots confinement: strict -base: core20 +base: core22 grade: stable icon: LogarithmPlotter/logarithmplotter.svg adopt-info: linuxfiles license: GPL-3.0+ architectures: - - build-on: amd64 - run-on: amd64 + - amd64 plugs: gtk-3-themes: From f73012104710f748e4557c4d94bede0e743da7c7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 6 Mar 2024 18:52:58 +0100 Subject: [PATCH 002/249] Fixing the icon on wayland, building on MacOS, and date on changelog --- CHANGELOG.md | 2 +- LogarithmPlotter/logarithmplotter.py | 1 + scripts/build-macosx.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be8eec8..c4b7c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.5.0 (11 Jan 2023) +## v0.5.0 (11 Jan 2024) **New** diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index f6f2cb3..1071c81 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -89,6 +89,7 @@ def run(): QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") + app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 03da330..1946ad3 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -5,7 +5,7 @@ cd "$DIR/.." rm $(find . -name "*.qmlc") rm $(find . -name "*.pyc") -python3 -m pip install -U pyinstaller<6.0 +python3 -m pip install -U "pyinstaller<6.0" # Building translations cd "LogarithmPlotter/i18n/" From a6fcf6da19da0a308f191796dbc6a25ee3c3b5a7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 25 Mar 2024 18:58:07 +0100 Subject: [PATCH 003/249] Fixing sequence no longer working with current rendering method. --- .../qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index 352a386..cd0960a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -65,11 +65,15 @@ class Sequence extends Expr.Expression { cache(n = 1) { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var expr = C.parser.parse(str).simplify() + // Chache values required for this one. + if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) + this.cache(n-this.valuePlus) + // Setting current variables C.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - C.currentObjectsByName + C.currentObjectsByName, + {[this.name]: this.calcValues} ) - C.currentVars[this.name] = this.calcValues this.calcValues[n] = expr.evaluate(C.currentVars) } From 08fea34366b30cc36115dee59cbbc63618c6538d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 28 Mar 2024 03:09:37 +0100 Subject: [PATCH 004/249] Converting as many JS libraries to ECMAScript modules. --- LogarithmPlotter/i18n/lp_de.ts | 473 ++++------- LogarithmPlotter/i18n/lp_en.ts | 473 ++++------- LogarithmPlotter/i18n/lp_es.ts | 803 ++++-------------- LogarithmPlotter/i18n/lp_fr.ts | 473 ++++------- LogarithmPlotter/i18n/lp_hu.ts | 469 ++++------ LogarithmPlotter/i18n/lp_nb_NO.ts | 711 ++++------------ LogarithmPlotter/i18n/lp_template.ts | 803 ++++-------------- LogarithmPlotter/i18n/update.sh | 2 +- LogarithmPlotter/logarithmplotter.py | 1 + .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 14 +- .../LogarithmPlotter/History/History.qml | 10 +- .../History/HistoryBrowser.qml | 2 +- .../LogarithmPlotter/History/HistoryItem.qml | 2 +- .../LogarithmPlotter/LogGraphCanvas.qml | 9 +- .../LogarithmPlotter/LogarithmPlotter.qml | 37 +- .../ObjectLists/Editor/CustomPropertyList.qml | 25 +- .../ObjectLists/Editor/Dialog.qml | 20 +- .../ObjectLists/ObjectCreationGrid.qml | 13 +- .../ObjectLists/ObjectLists.qml | 21 +- .../ObjectLists/ObjectRow.qml | 26 +- .../LogarithmPlotter/PickLocationOverlay.qml | 9 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 1 - .../Setting/ExpressionEditor.qml | 23 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 4 +- .../ViewPositionChangeOverlay.qml | 5 +- .../js/history/{color.js => color.mjs} | 9 +- .../js/history/{common.js => common.mjs} | 46 +- .../js/history/{create.js => create.mjs} | 12 +- .../js/history/{delete.js => delete.mjs} | 12 +- .../{editproperty.js => editproperty.mjs} | 33 +- .../js/history/{name.js => name.mjs} | 15 +- .../js/history/{position.js => position.mjs} | 20 +- .../history/{visibility.js => visibility.mjs} | 8 +- .../js/{historylib.js => historylib.mjs} | 37 +- .../js/{ => lib/expr-eval}/expr-eval.js | 0 .../js/lib/expr-eval/integration.js | 121 +++ .../autoload.js => lib/qmlpolyfills.mjs} | 40 +- .../ad5001/LogarithmPlotter/js/math/common.js | 99 --- .../js/math/{domain.js => domain.mjs} | 171 ++-- .../js/math/{expression.js => expression.mjs} | 44 +- .../ad5001/LogarithmPlotter/js/math/latex.js | 282 ------ .../ad5001/LogarithmPlotter/js/math/latex.mjs | 288 +++++++ .../js/math/{sequence.js => sequence.mjs} | 46 +- .../js/{mathlib.js => mathlib.mjs} | 33 +- .../eu/ad5001/LogarithmPlotter/js/modules.js | 7 + .../eu/ad5001/LogarithmPlotter/js/objects.js | 96 --- .../eu/ad5001/LogarithmPlotter/js/objects.mjs | 112 +++ .../LogarithmPlotter/js/objs/autoload.mjs | 42 + .../js/objs/{common.js => common.mjs} | 154 ++-- .../js/objs/{function.js => function.mjs} | 48 +- .../js/objs/{gainbode.js => gainbode.mjs} | 62 +- .../js/objs/{phasebode.js => phasebode.mjs} | 44 +- .../js/objs/{point.js => point.mjs} | 16 +- .../objs/{repartition.js => repartition.mjs} | 23 +- .../js/objs/{sequence.js => sequence.mjs} | 36 +- .../{sommegainsbode.js => sommegainsbode.mjs} | 59 +- ...sommephasesbode.js => sommephasesbode.mjs} | 54 +- .../js/objs/{text.js => text.mjs} | 16 +- .../js/objs/{xcursor.js => xcursor.mjs} | 18 +- .../js/{parameters.js => parameters.mjs} | 10 +- .../LogarithmPlotter/js/parsing/README.md | 2 +- .../js/parsing/{common.js => common.mjs} | 5 +- .../js/parsing/{parsing.js => parsing.mjs} | 26 +- .../js/parsing/{polyfill.js => polyfill.mjs} | 25 +- .../parsing/{reference.js => reference.mjs} | 27 +- .../parsing/{tokenizer.js => tokenizer.mjs} | 39 +- .../eu/ad5001/LogarithmPlotter/js/runtime.mjs | 45 + .../js/{utils.js => utils.mjs} | 148 ++-- 68 files changed, 2604 insertions(+), 4255 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{color.js => color.mjs} (93%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{common.js => common.mjs} (72%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{create.js => create.mjs} (81%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{delete.js => delete.mjs} (83%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{editproperty.js => editproperty.mjs} (86%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{name.js => name.mjs} (83%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{position.js => position.mjs} (89%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{visibility.js => visibility.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{historylib.js => historylib.mjs} (66%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => lib/expr-eval}/expr-eval.js (100%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{objs/autoload.js => lib/qmlpolyfills.mjs} (53%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{domain.js => domain.mjs} (79%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{expression.js => expression.mjs} (63%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{sequence.js => sequence.mjs} (66%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{mathlib.js => mathlib.mjs} (54%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{common.js => common.mjs} (77%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{function.js => function.mjs} (90%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{gainbode.js => gainbode.mjs} (67%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{phasebode.js => phasebode.mjs} (76%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{point.js => point.mjs} (91%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{repartition.js => repartition.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sequence.js => sequence.mjs} (78%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommegainsbode.js => sommegainsbode.mjs} (72%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommephasesbode.js => sommephasesbode.mjs} (74%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{text.js => text.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{xcursor.js => xcursor.mjs} (95%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{parameters.js => parameters.mjs} (96%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{common.js => common.mjs} (93%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{parsing.js => parsing.mjs} (60%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{polyfill.js => polyfill.mjs} (88%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{reference.js => reference.mjs} (91%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{tokenizer.js => tokenizer.mjs} (84%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{utils.js => utils.mjs} (75%) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 0bb06bf..2aad151 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Über LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Create &Erstellen - + &Settings &Einstellungen - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Expression editor Ausdruckseditor - + Automatically close parenthesises and brackets Klammern automatisch schließen - + Enable syntax highlighting Syntaxhervorhebung einschalten - + Enable autocompletion Automatische Vervollständigung einschalten - + Color Scheme Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - + Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - + Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Automatically close parenthesises and brackets in expressions Automatisches Schließen von Klammern in Ausdrücken - + Enable syntax highlighting for expressions Syntaxhervorhebung für Ausdrücke einschalten - + Enable autocompletion interface in expression editor Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren - + Color scheme: Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen @@ -437,62 +437,62 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - + Objects Objekte - + Settings Einstellungen - + History Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -500,7 +500,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectCreationGrid - + + Create new: + Neu erstellen: @@ -513,55 +513,55 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Alle %1 ausblenden - + Show all %1 Alle %1 anzeigen Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen ObjectRow - + Hide %1 %2 Ausblenden %1 %2 - + Show %1 %2 Anzeigen %1 %2 - + Set %1 %2 position Position von %1 %2 einstellen - + Delete %1 %2 %1 %2 löschen - + Pick new color for %1 %2 Neue Farbe für %1 %2 auswählen @@ -569,41 +569,41 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: Snap to grid - Am Gitter einrasten + Am Gitter einrasten - + Snap to grid: Am Raster einrasten: - + Pick X X nehmen - + Pick Y Y nehmen - + Open picker settings Zeigereinstellungen öffnen - + Hide picker settings Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -815,8 +815,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color - - %1 %2's color changed from %3 to %4. %1 %2 wurde von %3 bis %4 umgefärbt. @@ -824,27 +822,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -852,9 +845,9 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - + - + %1: @@ -864,8 +857,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - - New %1 %2 created. Neu %1 %2 erstellt. @@ -873,8 +864,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete - - %1 %2 deleted. %1 %2 gelöscht. @@ -882,12 +871,10 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -895,176 +882,166 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - - + + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - - - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - - - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Die letzte Änderung wurde rückgängig gemacht. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler @@ -1114,12 +1091,10 @@ Ausdruck analysiert: %3 function - Function Funktion - Functions Funktionen @@ -1127,24 +1102,18 @@ Ausdruck analysiert: %3 gainbode - Bode Magnitude Bode-Magnitude - Bode Magnitudes Bode-Magnituden - - low-pass Tiefpass - - high-pass Hochpass @@ -1153,27 +1122,27 @@ Ausdruck analysiert: %3 historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. @@ -1193,7 +1162,7 @@ Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.o DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1206,7 +1175,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1217,11 +1186,29 @@ Der Prozess '{}' brauchte zu lange, um beendet zu werden: Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -1229,114 +1216,90 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - above ↑ Über - below ↓ Unter - - left ← Links - - right → Rechts - above-left ↖ Oben links - above-right ↗ Oben rechts - below-left ↙ Unten links - below-right ↘ Unten rechts - center >|< Zentrum - top ↑ Über - bottom ↓ Unter - top-left ↖ Oben links - top-right ↗ Oben rechts - bottom-left ↙ Unten links - bottom-right ↘ Unten rechts - application Anwendung - function Funktion - high Hoch - low Tief - Next to target Neben dem Ziel - With label Mit Etikett - Hidden Versteckt @@ -1344,12 +1307,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde phasebode - Bode Phase Bode-Phase - Bode Phases Bode-Phasen @@ -1357,12 +1318,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde point - Point Punkt - Points Punkte @@ -1370,12 +1329,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde position - Position of %1 %2 set from "%3" to "%4". %1 %2 wurde von "%3" nach "%4" verschoben. - Position of %1 set from %2 to %3. %1 wurde von %2 nach %3 verschoben. @@ -1383,175 +1340,125 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde prop - expression Ausdruck - definitionDomain Definitionsbereich - destinationDomain Reichweite - - - - - - - - - - labelPosition Position des Etiketts - displayMode Anzeigemodus - - - - - - - labelX X-Position des Etiketts - - drawPoints Unentschiedene Punkte - - drawDashedLines Gestrichelte Linien anzeigen - - om_0 ω₀ - pass Pass - gain Größenordnung - omGraduation Teilung auf ω zeigen - phase Phase - unit Einheit - - - x X - - y Y - pointStyle Punkt-Stil - probabilities Wahrscheinlichkeiten - text Inhalt - disableLatex LaTeX-Rendering für diesen Text deaktivieren - targetElement Zielobjekt - approximate Ungefähren Wert anzeigen - rounding Rundung - displayStyle Stil - targetValuePosition Wertposition des Ziels - defaultExpression Standardausdruck - baseValues Initialisierungswerte color - Farbe + Farbe repartition - Repartition Verteilungsfunktion - Repartition functions Verteilungsfunktionen @@ -1559,12 +1466,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sequence - Sequence Folge - Sequences Folgen @@ -1572,8 +1477,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommegainsbode - - Bode Magnitudes Sum Bode-Magnituden Summe @@ -1581,8 +1484,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommephasesbode - - Bode Phases Sum Bode-Phasen Summe @@ -1590,12 +1491,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde text - Text Text - Texts Texte @@ -1608,7 +1507,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. @@ -1626,37 +1525,37 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 or %2 Verwendung: %1 oder %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) @@ -1664,14 +1563,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility - - %1 %2 shown. %1 %2 angezeigt. - - %1 %2 hidden. %1 %2 ausgeblendet. @@ -1679,12 +1574,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde xcursor - X Cursor X Zeiger - X Cursors X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 91b0e51..591e2c2 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter About LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Create &Create - + &Settings &Settings - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + Enable LaTeX rendering Enable LaTeX rendering - + Expression editor Expression editor - + Automatically close parenthesises and brackets Automatically close parentheses and brackets - + Enable syntax highlighting Enable syntax highlighting - + Enable autocompletion Enable autocompletion - + Color Scheme Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - + Enable LaTeX rendering Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions Automatically close parentheses and brackets in expressions - + Enable syntax highlighting for expressions Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor Enable autocompletion interface in expression editor - + Color scheme: Color scheme: - + User manual User manual - + Changelog Changelog - + Done Done @@ -437,62 +437,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects Objects - + Settings Settings - + History History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -500,7 +500,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: + Create new: @@ -513,55 +513,55 @@ These settings can be changed at any time from the "Settings" menu.Hide all %1 - + Show all %1 Show all %1 Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 ObjectRow - + Hide %1 %2 Hide %1 %2 - + Show %1 %2 Show %1 %2 - + Set %1 %2 position Set %1 %2 position - + Delete %1 %2 Delete %1 %2 - + Pick new color for %1 %2 Pick new color for %1 %2 @@ -569,41 +569,41 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: Snap to grid - Snap to grid + Snap to grid - + Snap to grid: Snap to grid: - + Pick X Pick X - + Pick Y Pick Y - + Open picker settings Open picker settings - + Hide picker settings Hide picker settings - + (no pick selected) (no pick selected) @@ -815,8 +815,6 @@ These settings can be changed at any time from the "Settings" menu. color - - %1 %2's color changed from %3 to %4. %1 %2's color changed from %3 to %4. @@ -824,27 +822,22 @@ These settings can be changed at any time from the "Settings" menu. comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - Note: Specify the probability for each value. Note: Specify the probability for each value. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -852,9 +845,9 @@ These settings can be changed at any time from the "Settings" menu. control - + - + %1: @@ -864,8 +857,6 @@ These settings can be changed at any time from the "Settings" menu. create - - New %1 %2 created. New %1 %2 created. @@ -873,8 +864,6 @@ These settings can be changed at any time from the "Settings" menu. delete - - %1 %2 deleted. %1 %2 deleted. @@ -882,12 +871,10 @@ These settings can be changed at any time from the "Settings" menu. editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -895,176 +882,166 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - - + First argument to map is not a function. First argument to map is not a function. - - + Second argument to map is not an array. Second argument to map is not an array. - - + First argument to fold is not a function. First argument to fold is not a function. - - + Second argument to fold is not an array. Second argument to fold is not an array. - - - + First argument to filter is not a function. First argument to filter is not a function. - - - + Second argument to filter is not an array. Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error @@ -1114,12 +1091,10 @@ Evaluated expression: %3 function - Function Function - Functions Functions @@ -1127,24 +1102,18 @@ Evaluated expression: %3 gainbode - Bode Magnitude Bode Magnitude - Bode Magnitudes Bode Magnitudes - - low-pass low-pass - - high-pass high-pass @@ -1153,27 +1122,27 @@ Evaluated expression: %3 historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. @@ -1193,7 +1162,7 @@ Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.or DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1206,7 +1175,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1217,11 +1186,29 @@ Process '{}' took too long to finish: Please make sure your LaTeX installation is correct and report a bug if so. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -1229,114 +1216,90 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - above ↑ Above - below ↓ Below - - left ← Left - - right → Right - above-left ↖ Above left - above-right ↗ Above right - below-left ↙ Below left - below-right ↘ Below right - center >|< Center - top ↑ Top - bottom ↓ Bottom - top-left ↖ Top left - top-right ↗ Top right - bottom-left ↙ Bottom left - bottom-right ↘ Bottom right - application Application - function Function - high High - low Low - Next to target Next to target - With label With label - Hidden Hidden @@ -1344,12 +1307,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. phasebode - Bode Phase Bode Phase - Bode Phases Bode Phases @@ -1357,12 +1318,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. point - Point Point - Points Points @@ -1370,12 +1329,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. position - Position of %1 %2 set from "%3" to "%4". %1 %2 moved from "%3" to "%4". - Position of %1 set from %2 to %3. %1 moved from %2 to %3. @@ -1383,175 +1340,125 @@ Please make sure your LaTeX installation is correct and report a bug if so. prop - expression Expression - definitionDomain Domain - destinationDomain Range - - - - - - - - - - labelPosition Label position - displayMode Display mode - - - - - - - labelX Label's X position - - drawPoints Show points - - drawDashedLines Show dashed lines - - om_0 ω₀ - pass Pass - gain Magnitude gain - omGraduation Show graduation on ω₀ - phase Phase - unit Unit to use - - - x X - - y Y - pointStyle Point style - probabilities Probabilities list - text Content - disableLatex Disable LaTeX rendering for this text - targetElement Object to target - approximate Show approximate value - rounding Rounding - displayStyle Display style - targetValuePosition Target's value position - defaultExpression Default expression - baseValues Initialisation values color - Color + Color repartition - Repartition Distribution - Repartition functions Distribution functions @@ -1559,12 +1466,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. sequence - Sequence Sequence - Sequences Sequences @@ -1572,8 +1477,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommegainsbode - - Bode Magnitudes Sum Bode Magnitudes Sum @@ -1581,8 +1484,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommephasesbode - - Bode Phases Sum Bode Phases Sum @@ -1590,12 +1491,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. text - Text Text - Texts Texts @@ -1608,7 +1507,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. @@ -1626,37 +1525,37 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 or %2 Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1664,14 +1563,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. visibility - - %1 %2 shown. %1 %2 shown. - - %1 %2 hidden. %1 %2 hidden. @@ -1679,12 +1574,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. xcursor - X Cursor X Cursor - X Cursors X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 11bbbc5..a9a0f09 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Sobre LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Create &Crear - + &Settings &Ajustes - + Check for updates on startup Comprobación de las actualizaciones al arrancar - + Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -259,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -305,68 +305,68 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -405,62 +405,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: @@ -481,7 +481,7 @@ These settings can be changed at any time from the "Settings" menu. - + Show all %1 @@ -489,27 +489,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -756,251 +756,173 @@ These settings can be changed at any time from the "Settings" menu. - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: - - create - - - - New %1 %2 created. - - - - - delete - - - - %1 %2 deleted. - - - - - editproperty - - - %1 of %2 %3 changed from "%4" to "%5". - - - - - %1 of %2 changed from %3 to %4. - - - error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1008,7 +930,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1019,13 +941,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1033,49 +955,11 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - function - - - Function - - - - - Functions - - - - - gainbode - - - Bode Magnitude - - - - - Bode Magnitudes - - - - - - low-pass - - - - - - high-pass - - - latex @@ -1091,7 +975,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1100,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1109,381 +993,22 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden - - - - - phasebode - - - Bode Phase - - - - - Bode Phases - - - - - point - - - Point - - - - - Points - - - - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - - - repartition - - - Repartition - - - - - Repartition functions - - - - - sequence - - - Sequence - - - - - Sequences - - - - - sommegainsbode - - - - Bode Magnitudes Sum - - - - - sommephasesbode - - - - Bode Phases Sum - - - - - text - - - Text - - - - - Texts + + Built with PySide6 (Qt) v{} and python v{} @@ -1495,7 +1020,7 @@ Please make sure your latex installation is correct and report a bug if so. - + No update available. @@ -1513,66 +1038,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - - visibility - - - - %1 %2 shown. - - - - - - %1 %2 hidden. - - - - - xcursor - - - X Cursor - - - - - X Cursors - - - diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index aeb408f..68b0f1a 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter À propos de LogarithmPlotter @@ -33,148 +33,148 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Create &Créer - + &Settings &Paramètres - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - + Enable LaTeX rendering Activer le rendu LaTeX - + Expression editor Éditeur de formule - + Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - + Enable syntax highlighting Activer la coloration syntaxique - + Enable autocompletion Activer l'autocomplétion - + Color Scheme Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -203,13 +203,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -217,42 +217,42 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -261,63 +261,63 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -338,59 +338,59 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - + Enable LaTeX rendering Activer le rendu LaTeX - + Automatically close parenthesises and brackets in expressions Fermer automatiquement les parenthèses et les crochets dans les formules - + Enable syntax highlighting for expressions Activer la coloration syntaxique des formules - + Enable autocompletion interface in expression editor Activer l'interface d'autocomplétion dans l'éditeur de formules - + Color scheme: Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -401,12 +401,12 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - + Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -445,62 +445,62 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - + Objects Objets - + Settings Paramètres - + History Historique - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -508,7 +508,7 @@ These settings can always be changed at any time from the "Settings" m ObjectCreationGrid - + + Create new: + Créer : @@ -521,55 +521,55 @@ These settings can always be changed at any time from the "Settings" m Cacher tous les %1 - + Show all %1 Montrer tous les %1 Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 ObjectRow - + Hide %1 %2 Cacher l'objet %1 %2 - + Show %1 %2 Montrer l'objet %1 %2 - + Set %1 %2 position Définir la position de l'objet %1 %2 - + Delete %1 %2 Supprimer l'objet %1 %2 - + Pick new color for %1 %2 Choisissez une nouvelle couleur pour %1 %2 @@ -577,41 +577,41 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : Snap to grid - Placement sur la grille + Placement sur la grille - + Snap to grid: Aligner sur la grille : - + Pick X Prendre la position X - + Pick Y Prendre la position Y - + Open picker settings Ouvrir les paramètres du pointeur - + Hide picker settings Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -823,8 +823,6 @@ These settings can always be changed at any time from the "Settings" m color - - %1 %2's color changed from %3 to %4. %1 %2 a été re colorisé du %3 au %4. @@ -832,28 +830,23 @@ These settings can always be changed at any time from the "Settings" m comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -861,9 +854,9 @@ These settings can always be changed at any time from the "Settings" m control - + - + %1: @@ -873,8 +866,6 @@ These settings can always be changed at any time from the "Settings" m create - - New %1 %2 created. Nouvel objet %1 %2 créé. @@ -882,8 +873,6 @@ These settings can always be changed at any time from the "Settings" m delete - - %1 %2 deleted. %1 %2 supprimé(e). @@ -891,12 +880,10 @@ These settings can always be changed at any time from the "Settings" m editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -904,176 +891,166 @@ These settings can always be changed at any time from the "Settings" m error - - + + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - - - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - - - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1084,7 +1061,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1098,13 +1075,13 @@ La dernière modification a été annulée. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1115,7 +1092,7 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur @@ -1123,12 +1100,10 @@ Formule analysée : %3 function - Function Fonction - Functions Fonctions @@ -1136,24 +1111,18 @@ Formule analysée : %3 gainbode - Bode Magnitude Gain de Bode - Bode Magnitudes Gains de Bode - - low-pass passe-bas - - high-pass passe-haut @@ -1162,27 +1131,27 @@ Formule analysée : %3 historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. @@ -1202,7 +1171,7 @@ Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l&apos DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1215,7 +1184,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1226,11 +1195,29 @@ Le processus '{}' a mis trop de temps à se terminer : Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -1238,114 +1225,90 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - above ↑ Au dessus - below ↓ En dessous - - left ← À gauche - - right → À droite - above-left ↖ Au dessus à gauche - above-right ↗ Au dessus à droite - below-left ↙ En dessous à gauche - below-right ↘ En dessous à droite - center >|< Centré - top ↑ Au dessus - bottom ↓ En dessous - top-left ↖ Au dessus à gauche - top-right ↗ Au dessus à droite - bottom-left ↙ En dessous à gauche - bottom-right ↘ En dessous à droite - application Application - function Fonction - high Haut - low Bas - Next to target A côté de la cible - With label Avec l'étiquette - Hidden Caché @@ -1353,12 +1316,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c phasebode - Bode Phase Phase de Bode - Bode Phases Phases de Bode @@ -1366,12 +1327,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c point - Point Point - Points Points @@ -1379,12 +1338,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c position - Position of %1 %2 set from "%3" to "%4". %1 %2 a été déplacé depuis "%3" vers "%4". - Position of %1 set from %2 to %3. %1 a été déplacé depuis %2 vers %3. @@ -1392,175 +1349,125 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c prop - expression Expression - definitionDomain Domaine de définition - destinationDomain Portée - - - - - - - - - - labelPosition Position de l'étiquette - displayMode Mode d'affichage - - - - - - - labelX Position en X de l'étiquette - - drawPoints Afficher les points - - drawDashedLines Afficher les pointillés - - om_0 ω₀ - pass Passe - gain Gain - omGraduation Afficher la graduation sur ω₀ - phase Phase - unit Unité de la phase - - - x X - - y Y - pointStyle Style du point - probabilities Liste de probabilités - text Contenu - disableLatex Désactiver le rendu LaTeX pour ce texte - targetElement Objet à cibler - approximate Afficher la valeur approximative - rounding Arrondi - displayStyle Style d'affichage - targetValuePosition Position de la valeur de la cible - defaultExpression Expression - baseValues Valeurs d'initialisation color - Couleur + Couleur repartition - Repartition Répartition - Repartition functions Fonctions de répartition @@ -1568,12 +1475,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sequence - Sequence Suite - Sequences Suites @@ -1581,8 +1486,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommegainsbode - - Bode Magnitudes Sum Sommes des gains de Bode @@ -1590,8 +1493,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommephasesbode - - Bode Phases Sum Somme des phases de Bode @@ -1599,12 +1500,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c text - Text Texte - Texts Textes @@ -1617,7 +1516,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. @@ -1635,37 +1534,37 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 or %2 Emploi : %1 ou %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) @@ -1673,14 +1572,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility - - %1 %2 shown. %1 %2 affiché(e). - - %1 %2 hidden. %1 %2 cachée(e). @@ -1688,12 +1583,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c xcursor - X Cursor Curseur X - X Cursors Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 89396ce..5a311df 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter LogarithmPlotter névjegye @@ -33,147 +33,147 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Create &Létrehozás - + &Settings &Beállítások - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Expression editor Kifejezésszerkesztő - + Automatically close parenthesises and brackets Zárójelek automatikus bezárása - + Enable syntax highlighting Mondattani kiemelés engedélyezése - + Enable autocompletion Automatikus befejezés engedélyezése - + Color Scheme Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - + Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Automatically close parenthesises and brackets in expressions Zárójelek automatikus bezárása a kifejezésekben - + Enable syntax highlighting for expressions Mondattani kiemelés engedélyezése a kifejezésekhez - + Enable autocompletion interface in expression editor Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben - + Color scheme: Színséma: - + User manual Használati utasítás - + Changelog Változásnapló - + Done Kész @@ -437,62 +437,62 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - + Objects Tárgyak - + Settings Beállítások - + History Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -500,7 +500,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectCreationGrid - + + Create new: + Új létrehozása: @@ -513,55 +513,55 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Összes %1 elrejtése - + Show all %1 Összes %1 megjelenítése Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 ObjectRow - + Hide %1 %2 %1 %2 elrejtése - + Show %1 %2 %1 %2 megjelenítése - + Set %1 %2 position %1 %2 helye beállítása - + Delete %1 %2 %1 %2 törlése - + Pick new color for %1 %2 Válasszon új színt a következőhöz: %1 %2 @@ -569,41 +569,41 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: Snap to grid - Rácshoz illesztés + Rácshoz illesztés - + Snap to grid: Rácshoz igazítás: - + Pick X X kijelölése - + Pick Y Y kijelölése - + Open picker settings Kijelölési beállítások megnyitása - + Hide picker settings Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -815,8 +815,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color - - %1 %2's color changed from %3 to %4. %1 %2 színe %3-ról %4-re változott. @@ -824,27 +822,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … - If you have latex enabled, you can use use latex markup in between $$ to create equations. Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -852,9 +845,9 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. control - + - + %1: @@ -864,8 +857,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create - - New %1 %2 created. Új %1 %2 létrehozva. @@ -873,8 +864,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. delete - - %1 %2 deleted. %1 %2 törölve. @@ -882,12 +871,10 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -895,176 +882,166 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - - + + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - + + Parse error [%1:%2]: %3 Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - - + First argument to map is not a function. Az első leképezési argumentum nem függvény. - - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - - - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - - - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Az utolsó módosítás visszavonása. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba @@ -1114,12 +1091,10 @@ Kiértékelt kifejezés: %3 function - Function Függvény - Functions Függvények @@ -1127,24 +1102,18 @@ Kiértékelt kifejezés: %3 gainbode - Bode Magnitude Bode-nagyságrend - Bode Magnitudes Bode-nagyságrendek - - low-pass aluláteresztő - - high-pass felüláteresztő @@ -1153,23 +1122,23 @@ Kiértékelt kifejezés: %3 historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. @@ -1189,7 +1158,7 @@ Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1202,7 +1171,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1213,11 +1182,29 @@ A(z) „{}” folyamat túl sokáig tartott a befejezéshez: Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -1225,114 +1212,90 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - above ↑ Felett - below ↓ Alatt - - left ← Balra - - right → Jobbra - above-left ↖ Felett, balra - above-right ↗ Felett, jobbra - below-left ↙ Alatt, balra - below-right ↘ Alatt, jobbra - center >|< Középre - top ↑ Felső - bottom ↓ Alsó - top-left ↖ Bal felső - top-right ↗ Jobb felső - bottom-left ↙ Bal alsó - bottom-right ↘ Jobb alsó - application Alkalmazás - function Függvény - high Magas - low Alul - Next to target Cél mellé - With label Címkével - Hidden Rejtett @@ -1340,12 +1303,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents phasebode - Bode Phase Bode-fázis - Bode Phases Bode-fázisok @@ -1353,12 +1314,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents point - Point Pont - Points Pontok @@ -1366,12 +1325,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents position - Position of %1 %2 set from "%3" to "%4". %1 %2 áthelyezve innen: „%3” ide: „%4”. - Position of %1 set from %2 to %3. %1 áthelyezve innen: %2 ide: %3. @@ -1379,158 +1336,110 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents prop - expression Kifejezés - definitionDomain Abszcissza tartomány - destinationDomain Ordináta tartomány - - - - - - - - - - labelPosition Címke helyzete - displayMode Megjelenítési mód - - - - - - - labelX Címke X helyzete - - drawPoints Pontok megjelenítése - - drawDashedLines Szaggatott vonalak megjelenítése - - om_0 ω₀ - pass Áteresztő - gain Nagyságrend nyeresége - omGraduation ω₀ érettségi megjelenítése - phase Fázis - unit Egység használata - - - x X - - y Y - pointStyle Pontstílus - probabilities Valószínűségek listája - text Tartalom - disableLatex LaTeX-megjelenítés letiltása ennél a szövegnél - targetElement Tárgycél - approximate Hozzávetőleges érték megjelenítése - rounding Kerekítés - displayStyle Megjelenítési stílus - targetValuePosition Cél értékpozíciója - defaultExpression Alapértelmezett kifejezés - baseValues Kezdeményezési értékek @@ -1538,12 +1447,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents repartition - Repartition Elosztás - Repartition functions Elosztási függvények @@ -1551,12 +1458,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sequence - Sequence Sorozat - Sequences Sorozatok @@ -1564,8 +1469,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommegainsbode - - Bode Magnitudes Sum Bode-nagyságrendek összege @@ -1573,8 +1476,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommephasesbode - - Bode Phases Sum Bode-fázisok összege @@ -1582,12 +1483,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents text - Text Szöveg - Texts Szövegek @@ -1600,7 +1499,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. @@ -1618,37 +1517,37 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 or %2 Használat: %1 vagy %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) @@ -1656,14 +1555,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility - - %1 %2 shown. %1 %2 megjelenítve. - - %1 %2 hidden. %1 %2 rejtve. @@ -1671,12 +1566,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents xcursor - X Cursor X kurzor - X Cursors X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 18d0f09..98fa6fb 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Om @@ -33,147 +33,147 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Create &Opprett - + &Settings &Innstillinger - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - + Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -437,62 +437,62 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - + Objects Objekter - + Settings Innstillinger - + History Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -500,7 +500,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectCreationGrid - + + Create new: + Opprett ny: @@ -513,17 +513,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Skjul alle %1 - + Show all %1 Vis alle %1 Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -531,37 +531,37 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 ObjectRow - + Hide %1 %2 Skjul %1 %2 - + Show %1 %2 Vis %1 %2 - + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 Slett %1 %2 - + Pick new color for %1 %2 Velg ny farge for %1 %2 @@ -569,41 +569,41 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: Snap to grid - Fest til rutenett + Fest til rutenett - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -812,49 +812,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: @@ -864,199 +827,179 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create - - New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. delete - - %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. editproperty - %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». - - - - %1 of %2 changed from %3 to %4. - + %1 av %2 %3 endret fra «%4» til «%5». error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1064,7 +1007,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1075,13 +1018,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1089,7 +1032,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1097,12 +1040,10 @@ Evaluated expression: %3 function - Function Funksjon - Functions Funksjoner @@ -1110,24 +1051,18 @@ Evaluated expression: %3 gainbode - Bode Magnitude Bode-magnitude - Bode Magnitudes Bode-magnituder - - low-pass lavpass - - high-pass høypass @@ -1136,23 +1071,23 @@ Evaluated expression: %3 historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. @@ -1170,7 +1105,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1179,7 +1114,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1188,138 +1123,32 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden + + Built with PySide6 (Qt) v{} and python v{} phasebode - Bode Phase Bode-fase - Bode Phases Bode-faser @@ -1327,197 +1156,21 @@ Please make sure your latex installation is correct and report a bug if so. point - Point Punkt - Points Punkter - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - repartition - Repartition Distribusjon - Repartition functions Distribusjonsfunksjoner @@ -1525,21 +1178,17 @@ Please make sure your latex installation is correct and report a bug if so. sequence - Sequence Følge - Sequences - Følger + Følger sommegainsbode - - Bode Magnitudes Sum Bode-magnitudesum @@ -1547,8 +1196,6 @@ Please make sure your latex installation is correct and report a bug if so. sommephasesbode - - Bode Phases Sum Bode-fasesum @@ -1556,12 +1203,10 @@ Please make sure your latex installation is correct and report a bug if so. text - Text Tekst - Texts Tekster @@ -1574,7 +1219,7 @@ Please make sure your latex installation is correct and report a bug if so.En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. @@ -1592,36 +1237,36 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) @@ -1629,29 +1274,23 @@ Please make sure your latex installation is correct and report a bug if so. visibility - - %1 %2 shown. - %1 %2 vist. + %1 %2 vist. - - %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. xcursor - X Cursor - X-peker + X-peker - X Cursors - X-pekere + X-pekere diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 2cbbff2..b88fc2e 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -259,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -305,68 +305,68 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -405,62 +405,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: @@ -481,7 +481,7 @@ These settings can be changed at any time from the "Settings" menu. - + Show all %1 @@ -489,27 +489,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -756,251 +756,173 @@ These settings can be changed at any time from the "Settings" menu. - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: - - create - - - - New %1 %2 created. - - - - - delete - - - - %1 %2 deleted. - - - - - editproperty - - - %1 of %2 %3 changed from "%4" to "%5". - - - - - %1 of %2 changed from %3 to %4. - - - error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1008,7 +930,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1019,13 +941,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1033,49 +955,11 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - function - - - Function - - - - - Functions - - - - - gainbode - - - Bode Magnitude - - - - - Bode Magnitudes - - - - - - low-pass - - - - - - high-pass - - - latex @@ -1091,7 +975,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1100,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1109,381 +993,22 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden - - - - - phasebode - - - Bode Phase - - - - - Bode Phases - - - - - point - - - Point - - - - - Points - - - - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - - - repartition - - - Repartition - - - - - Repartition functions - - - - - sequence - - - Sequence - - - - - Sequences - - - - - sommegainsbode - - - - Bode Magnitudes Sum - - - - - sommephasesbode - - - - Bode Phases Sum - - - - - text - - - Text - - - - - Texts + + Built with PySide6 (Qt) v{} and python v{} @@ -1495,7 +1020,7 @@ Please make sure your latex installation is correct and report a bug if so. - + No update available. @@ -1513,66 +1038,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - - visibility - - - - %1 %2 shown. - - - - - - %1 %2 hidden. - - - - - xcursor - - - X Cursor - - - - - X Cursors - - - diff --git a/LogarithmPlotter/i18n/update.sh b/LogarithmPlotter/i18n/update.sh index aa48415..b8c4716 100755 --- a/LogarithmPlotter/i18n/update.sh +++ b/LogarithmPlotter/i18n/update.sh @@ -1,2 +1,2 @@ #!/bin/bash -lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts +lupdate -extensions mjs,js,qs,qml,py -recursive .. -ts lp_*.ts diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 1071c81..28affed 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -112,6 +112,7 @@ def run(): global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) + engine.globalObject().setProperty('Runtime', engine.newObject()) engine.rootContext().setContextProperty("Helper", helper) engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 7a33bce..a77de0c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -20,9 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import "js/objects.js" as Objects -import "js/historylib.js" as HistoryLib -import "js/math/latex.js" as LatexJS +import "js/historylib.mjs" as HistoryLib /*! @@ -105,17 +103,17 @@ MenuBar { title: qsTr("&Create") // Services repeater Repeater { - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) MenuItem { - text: Objects.types[modelData].displayType() - visible: Objects.types[modelData].createable() + text: Runtime.Objects.types[modelData].displayType() + visible: Runtime.Objects.types[modelData].createable() height: visible ? implicitHeight : 0 icon.name: modelData icon.source: './icons/objects/' + modelData + '.svg' icon.color: sysPalette.buttonText onTriggered: { - var newObj = Objects.createNewRegisteredObject(modelData) + var newObj = Runtime.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } @@ -153,7 +151,7 @@ MenuBar { checked: Helper.getSettingBool("enable_latex") onTriggered: { Helper.setSettingBool("enable_latex", checked) - LatexJS.enabled = checked + Runtime.Latex.enabled = checked drawCanvas.requestPaint() } icon.name: 'Expression' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index df9503d..8a9a6ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -19,9 +19,7 @@ import QtQuick import QtQml import QtQuick.Window -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib -import "../js/history/common.js" as HistoryCommon +import "../js/historylib.mjs" as HistoryLib /*! \qmltype History @@ -214,8 +212,8 @@ Item { } Component.onCompleted: { - HistoryLib.history = historyObj - HistoryCommon.themeTextColor = sysPalette.windowText - HistoryCommon.imageDepth = Screen.devicePixelRatio + Runtime.History.history = historyObj + Runtime.History.themeTextColor = sysPalette.windowText + Runtime.History.imageDepth = Screen.devicePixelRatio } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 69ddfdb..b7a79c8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -19,7 +19,7 @@ import QtQuick.Controls import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/utils.js" as Utils +import "../js/utils.mjs" as Utils /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 041ddfa..3e9b906 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -19,7 +19,7 @@ import QtQuick.Controls import QtQuick import Qt5Compat.GraphicalEffects -import "../js/utils.js" as Utils +import "../js/utils.mjs" as Utils import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 64bef06..908bdb6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -18,9 +18,8 @@ import QtQuick import Qt.labs.platform as Native -import "js/objects.js" as Objects -import "js/utils.js" as Utils -import "js/mathlib.js" as MathLib +import "js/utils.mjs" as Utils +import "js/mathlib.mjs" as MathLib /*! \qmltype LogGraphCanvas @@ -190,8 +189,8 @@ Canvas { drawAxises(ctx) drawLabels(ctx) ctx.lineWidth = linewidth - for(var objType in Objects.currentObjects) { - for(var obj of Objects.currentObjects[objType]){ + for(var objType in Runtime.Objects.currentObjects) { + for(var obj of Runtime.Objects.currentObjects[objType]){ ctx.strokeStyle = obj.color ctx.fillStyle = obj.color if(obj.visible) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 5b77730..1715967 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -21,11 +21,10 @@ import QtQuick.Controls import eu.ad5001.MixedMenu 1.1 import QtQuick.Layouts 1.12 import QtQuick -// Auto loading all objects. -import "js/objs/autoload.js" as ALObjects -import "js/objects.js" as Objects -import "js/math/latex.js" as LatexJS +// Auto loading all modules. +import "js/modules.js" as Modules + import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup @@ -50,9 +49,9 @@ ApplicationWindow { Component.onCompleted: { // LatexJS initialization. - LatexJS.enabled = Helper.getSettingBool("enable_latex") - LatexJS.Renderer = Latex - LatexJS.defaultColor = sysPalette.windowText + Runtime.Latex.enabled = Helper.getSettingBool("enable_latex") + Runtime.Latex.Renderer = Latex + Runtime.Latex.defaultColor = sysPalette.windowText } } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } @@ -201,9 +200,9 @@ ApplicationWindow { filename += '.lpf' settings.saveFilename = filename var objs = {} - for(var objType in Objects.currentObjects){ + for(var objType in Runtime.Objects.currentObjects){ objs[objType] = [] - for(var obj of Objects.currentObjects[objType]) { + for(var obj of Runtime.Objects.currentObjects[objType]) { objs[objType].push(obj.export()) } } @@ -265,19 +264,19 @@ ApplicationWindow { root.width = data["width"] // Importing objects - Objects.currentObjects = {} - Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Objects.currentObjectsByName[key]; + Runtime.Objects.currentObjects = {} + Runtime.Object.keys(Objects.currentObjectsByName).forEach(key => { + delete Runtime.Objects.currentObjectsByName[key]; // Required to keep the same reference for the copy of the object used in expression variable detection. // Another way would be to change the reference as well, but I feel like the code would be less clean. }) for(let objType in data['objects']) { - if(Object.keys(Objects.types).indexOf(objType) > -1) { - Objects.currentObjects[objType] = [] + if(Object.keys(Runtime.Objects.types).indexOf(objType) > -1) { + Runtime.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Objects.types[objType](...objData) - Objects.currentObjects[objType].push(obj) - Objects.currentObjectsByName[obj.name] = obj + let obj = new Runtime.Objects.types[objType](...objData) + Runtime.Objects.currentObjects[objType].push(obj) + Runtime.Objects.currentObjectsByName[obj.name] = obj } } else { error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; @@ -285,8 +284,8 @@ ApplicationWindow { } // Updating object dependencies. - for(let objName in Objects.currentObjectsByName) - Objects.currentObjectsByName[objName].update() + for(let objName in Runtime.Objects.currentObjectsByName) + Runtime.Objects.currentObjectsByName[objName].update() // Importing history if("history" in data) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 3f2f5ab..eb163f3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -20,10 +20,9 @@ import QtQuick import QtQuick.Controls import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../../js/objects.js" as Objects -import "../../js/historylib.js" as HistoryLib -import "../../js/utils.js" as Utils -import "../../js/mathlib.js" as MathLib +import "../../js/historylib.mjs" as HistoryLib +import "../../js/utils.mjs" as Utils +import "../../js/mathlib.mjs" as MathLib /*! \qmltype CustomPropertyList @@ -188,8 +187,8 @@ Repeater { // Base, untranslated version of the model. property var baseModel: selectObjMode ? - Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : []) + Runtime.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) : propertyType.values // Translated version of the model. model: selectObjMode ? baseModel : propertyType.translatedValues @@ -199,20 +198,20 @@ Repeater { if(selectObjMode) { // This is only done when what we're selecting are Objects. // Setting object property. - var selectedObj = Objects.currentObjectsByName[baseModel[newIndex]] + var selectedObj = Runtime.Objects.currentObjectsByName[baseModel[newIndex]] if(newIndex != 0) { // Make sure we don't set the object to null. if(selectedObj == null) { // Creating new object. - selectedObj = Objects.createNewRegisteredObject(propertyType.objType) + selectedObj = Runtime.Objects.createNewRegisteredObject(propertyType.objType) history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) - baseModel = Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : + baseModel = Runtime.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) currentIndex = baseModel.indexOf(selectedObj.name) } - selectedObj.requiredBy.push(Objects.currentObjects[objType][objIndex]) - //Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) + selectedObj.requiredBy.push(Runtime.Objects.currentObjects[objType][objIndex]) + //Runtime.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) history.addToHistory(new HistoryLib.EditedProperty( @@ -256,7 +255,7 @@ Repeater { obj.name, objType, propertyName, obj[propertyName], exported )) - //Objects.currentObjects[objType][objIndex][propertyName] = exported + //Runtime.Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported root.changed() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 78efdae..2c2b9d0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -22,11 +22,9 @@ import QtQuick.Dialogs as D import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "../../js/objects.js" as Objects -import "../../js/objs/common.js" as ObjectsCommons -import "../../js/historylib.js" as HistoryLib -import "../../js/utils.js" as Utils -import "../../js/mathlib.js" as MathLib +import "../../js/historylib.mjs" as HistoryLib +import "../../js/utils.mjs" as Utils +import "../../js/mathlib.mjs" as MathLib /*! \qmltype Dialog @@ -54,7 +52,7 @@ Popup.BaseDialog { \qmlproperty var EditorDialog::obj Instance of the object being edited. */ - property var obj: Objects.currentObjects[objType][objIndex] + property var obj: Runtime.Objects.currentObjects[objType][objIndex] /*! \qmlproperty var EditorDialog::posPicker Reference to the global PositionPicker QML object. @@ -87,7 +85,7 @@ Popup.BaseDialog { Label { id: dlgTitle verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + text: qsTr("Edit properties of %1 %2").arg(Runtime.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) font.pixelSize: 20 color: sysPalette.windowText } @@ -113,14 +111,14 @@ Popup.BaseDialog { onChanged: function(newValue) { let newName = Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { - if(newName in Objects.currentObjectsByName) { + if(newName in Runtime.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { history.addToHistory(new HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) - Objects.renameObject(obj.name, newName) - objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + Runtime.Objects.renameObject(obj.name, newName) + objEditor.obj = Runtime.Objects.currentObjects[objEditor.objType][objEditor.objIndex] objectListList.update() } } @@ -165,7 +163,7 @@ Popup.BaseDialog { */ function open() { dlgCustomProperties.model = [] // Reset - let objProps = Objects.types[objEditor.objType].properties() + let objProps = Runtime.Objects.types[objEditor.objType].properties() dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. objEditor.show() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 1fd7364..6fd42c9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -18,8 +18,7 @@ import QtQuick import QtQuick.Controls -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib +import "../js/historylib.mjs" as HistoryLib import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting @@ -44,7 +43,7 @@ Column { // Open editor objectEditor.obj = obj objectEditor.objType = obj.type - objectEditor.objIndex = Objects.currentObjects[obj.type].indexOf(obj) + objectEditor.objIndex = Runtime.Objects.currentObjects[obj.type].indexOf(obj) objectEditor.open() // Disconnect potential link posPicker.picked.disconnect(openEditorDialog) @@ -61,12 +60,12 @@ Column { width: parent.width columns: 3 Repeater { - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) Button { id: createBtn width: 96 - visible: Objects.types[modelData].createable() + visible: Runtime.Objects.types[modelData].createable() height: visible ? width*0.8 : 0 // The KDE SDK is kinda buggy, so it respects neither specified color nor display propreties. //display: AbstractButton.TextUnderIcon @@ -94,7 +93,7 @@ Column { anchors.rightMargin: 4 horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 - text: Objects.types[modelData].displayType() + text: Runtime.Objects.types[modelData].displayType() wrapMode: Text.WordWrap clip: true } @@ -104,7 +103,7 @@ Column { ToolTip.text: label.text onClicked: { - let newObj = Objects.createNewRegisteredObject(modelData) + let newObj = Runtime.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index e7d7a6f..f7d9e27 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -21,7 +21,6 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.ObjectLists.Editor 1.0 as Editor -import "../js/objects.js" as Objects /*! \qmltype ObjectLists @@ -47,7 +46,7 @@ ScrollView { ListView { id: objectsListView - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) implicitHeight: contentItem.childrenRect.height + footerItem.height + 10 @@ -55,7 +54,7 @@ ScrollView { id: objTypeList property string objType: objectsListView.model[index] property var editingRows: [] - model: Objects.currentObjects[objType] + model: Runtime.Objects.currentObjects[objType] width: objectsListView.width implicitHeight: contentItem.childrenRect.height visible: model != undefined && model.length > 0 @@ -70,21 +69,23 @@ ScrollView { CheckBox { id: typeVisibilityCheckBox - checked: Objects.currentObjects[objType] != undefined ? Objects.currentObjects[objType].every(obj => obj.visible) : true + checked: Runtime.Objects.currentObjects[objType] != undefined ? Runtime.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(var obj of Objects.currentObjects[objType]) obj.visible = this.checked + for(var obj of Runtime.Objects.currentObjects[objType]) obj.visible = this.checked for(var obj of objTypeList.editingRows) obj.objVisible = this.checked objectListList.changed() } ToolTip.visible: hovered - ToolTip.text: checked ? qsTr("Hide all %1").arg(Objects.types[objType].displayTypeMultiple()) : qsTr("Show all %1").arg(Objects.types[objType].displayTypeMultiple()) + ToolTip.text: checked ? + qsTr("Hide all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) : + qsTr("Show all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) } Label { id: typeHeaderText verticalAlignment: TextInput.AlignVCenter - text: qsTranslate("control", "%1: ").arg(Objects.types[objType].displayTypeMultiple()) + text: qsTranslate("control", "%1: ").arg(Runtime.Objects.types[objType].displayTypeMultiple()) font.pixelSize: 20 } } @@ -92,11 +93,11 @@ ScrollView { delegate: ObjectRow { id: controlRow width: objTypeList.width - obj: Objects.currentObjects[objType][index] + obj: Runtime.Objects.currentObjects[objType][index] posPicker: positionPicker onChanged: { - obj = Objects.currentObjects[objType][index] + obj = Runtime.Objects.currentObjects[objType][index] objectListList.update() } @@ -128,7 +129,7 @@ ScrollView { function update() { objectListList.changed() for(var objType in objectListList.listViews) { - objectListList.listViews[objType].model = Objects.currentObjects[objType] + objectListList.listViews[objType].model = Runtime.Objects.currentObjects[objType] } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index ab3f2f7..cdd9e3a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -21,9 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib -import "../js/math/latex.js" as LatexJS +import "../js/historylib.mjs" as HistoryLib /*! @@ -91,16 +89,16 @@ Item { id: objDescription anchors.left: objVisibilityCheckBox.right anchors.right: deleteButton.left - height: LatexJS.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight + height: Runtime.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight verticalAlignment: TextInput.AlignVCenter - text: LatexJS.enabled ? "" : obj.getReadableString() + text: Runtime.Latex.enabled ? "" : obj.getReadableString() font.pixelSize: 14 Image { id: latexDescription anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - visible: LatexJS.enabled + visible: Runtime.Latex.enabled property double depth: Screen.devicePixelRatio property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" @@ -111,7 +109,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { - objEditor.obj = Objects.currentObjects[obj.type][index] + objEditor.obj = Runtime.Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow @@ -213,10 +211,14 @@ Item { function deleteRecursively(object) { for(let toRemove of object.requiredBy) deleteRecursively(toRemove) - object.requiredBy = [] - history.addToHistory(new HistoryLib.DeleteObject( - object.name, object.type, object.export() - )) - Objects.deleteObject(object.name) + if(Runtime.Objects.currentObjectsByName[object.name] != undefined) { + // Object still exists + // Temporary fix for objects require not being propertly updated. + object.requiredBy = [] + history.addToHistory(new HistoryLib.DeleteObject( + object.name, object.type, object.export() + )) + Runtime.Objects.deleteObject(object.name) + } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index afc8d61..c92182a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -19,9 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/objects.js" as Objects -import "js/mathlib.js" as MathLib -import "js/historylib.js" as HistoryLib +import "js/mathlib.mjs" as MathLib +import "js/historylib.mjs" as HistoryLib /*! \qmltype PickLocationOverlay @@ -114,7 +113,7 @@ Item { if(mouse.button == Qt.LeftButton) { // Validate let newValueX = !parent.userPickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) let newValueY = !parent.userPickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) - let obj = Objects.currentObjectsByName[objName] + let obj = Runtime.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { history.addToHistory(new HistoryLib.EditedPosition( @@ -324,7 +323,7 @@ Item { Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. */ function parseValue(value, objType, propertyName) { - if(Objects.types[objType].properties()[propertyName] == 'number') + if(Runtime.Objects.types[objType].properties()[propertyName] == 'number') return parseFloat(value) else return new MathLib.Expression(value) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index dddafab..9ddfa0f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -18,7 +18,6 @@ import QtQuick import QtQuick.Controls -import "../js/math/latex.js" as Latex /*! \qmltype GreetScreen diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index fa3dece..be5160b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -20,10 +20,9 @@ import QtQuick.Controls import QtQuick import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P -import "../js/mathlib.js" as MathLib -import "../js/utils.js" as Utils -import "../js/objects.js" as Objects -import "../js/parsing/parsing.js" as Parsing +import "../js/mathlib.mjs" as MathLib +import "../js/utils.mjs" as Utils +import "../js/parsing/parsing.mjs" as Parsing /*! @@ -392,9 +391,9 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property bool doesObjectExist: isEnteringProperty && (objectName in Objects.currentObjectsByName) + property bool doesObjectExist: isEnteringProperty && (objectName in Runtime.Objects.currentObjectsByName) property var objectProperties: doesObjectExist ? - Objects.currentObjectsByName[objectName].constructor.properties() : + Runtime.Objects.currentObjectsByName[objectName].constructor.properties() : {} categoryItems: Object.keys(objectProperties) autocompleteGenerator: (item) => { @@ -461,9 +460,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected - categoryItems: Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) + categoryItems: Runtime.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), + 'text': item, 'annotation': Runtime.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -476,9 +475,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected - categoryItems: Object.keys(Objects.currentObjectsByName).filter(obj => obj != self) + categoryItems: Object.keys(Runtime.Objects.currentObjectsByName).filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': `${Objects.currentObjectsByName[item].constructor.displayType()}`, + 'text': item, 'annotation': `${Runtime.Objects.currentObjectsByName[item].constructor.displayType()}`, 'autocomplete': item+'.', 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -538,8 +537,8 @@ Item { throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) // Recursive dependencies let dependentOnSelfObjects = expr.requiredObjects().filter( - (obj) => Objects.currentObjectsByName[obj].getDependenciesList() - .includes(Objects.currentObjectsByName[control.self]) + (obj) => Runtime.Objects.currentObjectsByName[obj].getDependenciesList() + .includes(Runtime.Objects.currentObjectsByName[control.self]) ) if(dependentOnSelfObjects.length == 1) throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 208e3e9..2c50c56 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -16,11 +16,11 @@ * along with this program. If not, see . */ +import QtQuick import QtQuick.Controls -import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "js/utils.js" as Utils +import "js/utils.mjs" as Utils /*! \qmltype Settings diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 0d80da4..85b461e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -19,9 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/objects.js" as Objects -import "js/mathlib.js" as MathLib -import "js/historylib.js" as HistoryLib +import "js/mathlib.mjs" as MathLib +import "js/historylib.mjs" as HistoryLib /*! \qmltype ViewPositionChangeOverlay diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index 9f921b5..c8bb577 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -16,13 +16,10 @@ * along with this program. If not, see . */ -.pragma library +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -.import "editproperty.js" as EP -.import "../objects.js" as Objects - - -class ColorChanged extends EP.EditedProperty { +export default class ColorChanged extends EditedProperty { // Action used everytime when an object's color is changed type(){return 'ColorChanged'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs similarity index 72% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 2baf532..d9a3bc8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,16 +16,29 @@ * along with this program. If not, see . */ -.pragma library - -.import "../math/latex.js" as Latex - -var themeTextColor; -var imageDepth = 2; -var fontSize = 14; +import { RuntimeAPI } from "../runtime.mjs" +import Latex from "../math/latex.mjs" -class Action { +class HistoryCommonAPI extends RuntimeAPI { + constructor() { + super('History', [ + Runtime.Latex + ]) + // History QML object + this.history = null; + this.themeTextColor = "#ff0000"; + this.imageDepth = 2; + this.fontSize = 14; + } +} + +/** @type {HistoryCommonAPI} */ +Runtime.History = Runtime.History || new HistoryCommonAPI() + +export const API = Runtime.History + +export class Action { /** * Type of the action. * @@ -48,15 +61,11 @@ class Action { /** * Undoes the action. - * - * @returns {string} */ undo() {} /** * Redoes the action. - * - * @returns {string} */ redo() {} @@ -64,7 +73,7 @@ class Action { * Export the action to a serializable format. * NOTE: These arguments will be reinputed in the constructor in this order. * - * @returns {string} + * @returns {string[]} */ export() { return [this.targetName, this.targetType] @@ -86,7 +95,7 @@ class Action { * @returns {string} */ getIconRichText(type) { - return `` + return `` } /** @@ -98,8 +107,13 @@ class Action { renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let latexInfo = Latex.Renderer.render(latexString, imageDepth*(fontSize+2), themeTextColor).split(",") - return `` + let imgDepth = Runtime.History.imageDepth + let [src, width, height] = Latex.Renderer.render( + latexString, + imgDepth * (Runtime.History.fontSize + 2), + Runtime.History.themeTextColor + ).split(",") + return `` } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs similarity index 81% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index 8eca385..e474133 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -16,12 +16,10 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import { Action } from "common.mjs" -.import "../objects.js" as Objects -.import "common.js" as C - -class CreateNewObject extends C.Action { +export default class CreateNewObject extends Action { // Action used for the creation of an object type(){return 'CreateNewObject'} @@ -37,10 +35,6 @@ class CreateNewObject extends C.Action { undo() { Objects.deleteObject(this.targetName) - //let targetIndex = Objects.getObjectsName(this.targetType).indexOf(this.targetName) - //delete Objects.currentObjectsByName[this.targetName] - //Objects.currentObjects[this.targetType][targetIndex].delete() - //Objects.currentObjects[this.targetType].splice(targetIndex, 1) } redo() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs similarity index 83% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index c70d2d0..ea1deb1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "../objects.js" as Objects -.import "create.js" as Create +import Objects from "../objects.mjs" +import CreateNewObject from "create.mjs" -class DeleteObject extends Create.CreateNewObject { - // Action used at the deletion of an object. Basicly the same thing as creating a new object, except Redo & Undo are reversed. +export default class DeleteObject extends CreateNewObject { + /** + * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed. + */ type(){return 'DeleteObject'} icon(){return 'delete'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs similarity index 86% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 9b712f2..3540cfe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -16,15 +16,13 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import * as MathLib from "../mathlib.mjs" +import { Action } from "common.mjs" +import { DrawableObject } from "../objs/common.mjs" -.import "../objects.js" as Objects -.import "../math/latex.js" as Latex -.import "../mathlib.js" as MathLib -.import "../objs/common.js" as Common -.import "common.js" as C - -class EditedProperty extends C.Action { +export default class EditedProperty extends Action { // Action used everytime an object's property has been changed type(){return 'EditedProperty'} @@ -33,7 +31,16 @@ class EditedProperty extends C.Action { color(darkVer=false){ return darkVer ? 'darkslateblue' : 'cyan'; } - + + /** + * + * @param {string} targetName - Name of the object to target + * @param {string} targetType - Type of the object to target. + * @param {string} targetProperty - Property being changed + * @param {any} previousValue - Previous value before change + * @param {any} newValue - New value after change + * @param {boolean} valueIsExpressionNeedingImport - True if the value needs to be imported. (e.g expressions) + */ constructor(targetName = "", targetType = "Point", targetProperty = "visible", previousValue = false, newValue = true, valueIsExpressionNeedingImport = false) { super(targetName, targetType) this.targetProperty = targetProperty @@ -42,10 +49,10 @@ class EditedProperty extends C.Action { this.newValue = newValue this.propertyType = Objects.types[targetType].properties()[targetProperty] if(valueIsExpressionNeedingImport) { - if(typeof this.propertyType == 'object' && this.propertyType.type == "Expression") { + if(typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { this.previousValue = new MathLib.Expression(this.previousValue); this.newValue = new MathLib.Expression(this.newValue); - } else if(this.propertyType == "Domain") { + } else if(this.propertyType === "Domain") { this.previousValue = MathLib.parseDomain(this.previousValue); this.newValue = MathLib.parseDomain(this.newValue); } else { @@ -70,7 +77,7 @@ class EditedProperty extends C.Action { export() { if(this.previousValue instanceof MathLib.Expression) { return [this.targetName, this.targetType, this.targetProperty, this.previousValue.toEditableString(), this.newValue.toEditableString(), true] - } else if(this.previousValue instanceof Common.DrawableObject) { + } else if(this.previousValue instanceof DrawableObject) { return [this.targetName, this.targetType, this.targetProperty, this.previousValue.name, this.newValue.name, true] } else { return [this.targetName, this.targetType, this.targetProperty, this.previousValue, this.newValue, false] @@ -110,7 +117,7 @@ class EditedProperty extends C.Action { // HTML this.prevHTML = ' '+this.prevString+' ' this.nextHTML = ' '+this.nextString+' ' - if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type == "Expression") { + if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { this.prevHTML= this.renderLatexAsHtml(this.previousValue.latexMarkup) this.nextHTML= this.renderLatexAsHtml(this.newValue.latexMarkup) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs similarity index 83% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index 89f97c3..7698adf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -16,19 +16,16 @@ * along with this program. If not, see . */ -.pragma library - -.import "editproperty.js" as EP -.import "../objects.js" as Objects +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -class NameChanged extends EP.EditedProperty { +export default class NameChanged extends EditedProperty { // Action used everytime an object's property has been changed type(){return 'NameChanged'} icon(){return 'name'} - - + color(darkVer=false){return darkVer ? 'darkorange' : 'orange'} constructor(targetName = "", targetType = "Point", newName = "") { @@ -45,10 +42,6 @@ class NameChanged extends EP.EditedProperty { redo() { Objects.renameObject(this.previousValue, this.newValue) - //let obj = Objects.currentObjectsByName[this.previousValue] - //obj.name = this.newValue - //Objects.currentObjectsByName[this.newValue] = obj - //delete Objects.currentObjectsByName[this.previousValue] } getReadableString() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs similarity index 89% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index c171124..eaf4b65 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import * as MathLib from "../mathlib.mjs" +import { escapeHTML } from "../utils.mjs" +import { Action } from "common.mjs" +import { DrawableObject } from "../objs/common.mjs" -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../math/latex.js" as Latex -.import "../utils.js" as Utils -.import "../objs/common.js" as Common -.import "common.js" as C - -class EditedPosition extends C.Action { +export default class EditedPosition extends Action { // Action used for objects that have a X and Y expression properties (points, texts...) type(){return 'EditedPosition'} @@ -68,8 +66,8 @@ class EditedPosition extends C.Action { this.prevHTML = this.renderLatexAsHtml(`\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)`) this.nextHTML = this.renderLatexAsHtml(`\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)`) } else { - this.prevHTML = ' '+Utils.escapeHTML(this.prevString)+' ' - this.nextHTML = ' '+Utils.escapeHTML(this.nextString)+' ' + this.prevHTML = ' '+escapeHTML(this.prevString)+' ' + this.nextHTML = ' '+escapeHTML(this.nextString)+' ' } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index 78981eb..d38b33f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -16,13 +16,11 @@ * along with this program. If not, see . */ -.pragma library - -.import "editproperty.js" as EP -.import "../objects.js" as Objects +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -class EditedVisibility extends EP.EditedProperty { +export default class EditedVisibility extends EditedProperty { // Action used when an object's shown or hidden. type(){return 'EditedVisibility'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs similarity index 66% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs index d9fa812..189d59b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs @@ -18,30 +18,27 @@ // This library helps containing actions to be undone or redone (in other words, editing history) // Each type of event is repertoried as an action that can be listed for everything that's undoable. -.pragma library -.import "history/common.js" as Common -.import "history/create.js" as Create -.import "history/delete.js" as Delete -.import "history/editproperty.js" as EP -.import "history/position.js" as Pos -.import "history/visibility.js" as V -.import "history/name.js" as Name -.import "history/color.js" as Color - -var history = null; +import { Action as A } from "history/common.mjs" +import Create from "history/create.mjs" +import Delete from "history/delete.mjs" +import EP from "history/editproperty.mjs" +import Pos from "history/position.mjs" +import V from "history/visibility.mjs" +import Name from "history/name.mjs" +import Color from "history/color.mjs" -var Action = Common.Action -var CreateNewObject = Create.CreateNewObject -var DeleteObject = Delete.DeleteObject -var EditedProperty = EP.EditedProperty -var EditedPosition = Pos.EditedPosition -var EditedVisibility = V.EditedVisibility -var NameChanged = Name.NameChanged -var ColorChanged = Color.ColorChanged +export const Action = A +export const CreateNewObject = Create +export const DeleteObject = Delete +export const EditedProperty = EP +export const EditedPosition = Pos +export const EditedVisibility = V +export const NameChanged = Name +export const ColorChanged = Color -var Actions = { +export const Actions = { "Action": Action, "CreateNewObject": CreateNewObject, "DeleteObject": DeleteObject, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js new file mode 100644 index 0000000..68a88c1 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js @@ -0,0 +1,121 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +.pragma library + +.import "expr-eval.js" as ExprEval +.import "../../runtime.mjs" as R + +let RuntimeAPI = R.RuntimeAPI + +const evalVariables = { + // Variables not provided by expr-eval.js, needs to be provided manually + "pi": Math.PI, + "PI": Math.PI, + "π": Math.PI, + "inf": Infinity, + "infinity": Infinity, + "Infinity": Infinity, + "∞": Infinity, + "e": Math.E, + "E": Math.E, + "true": true, + "false": false +} + +class ExprParserAPI extends RuntimeAPI { + constructor() { + super('ExprParser', [ + /** @type {ObjectsAPI} */ + Runtime.Objects + ]) + this.currentVars = {} + this.Internals = ExprEval + this._parser = new ExprEval.Parser() + + this._parser.consts = Object.assign({}, this._parser.consts, evalVariables) + + this._parser.functions.integral = this.integral.bind(this) + this._parser.functions.derivative = this.derivative.bind(this) + } + + /** + * Parses arguments for a function, returns the corresponding JS function if it exists. + * Throws either usage error otherwise. + * @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ]. + * @param {string} usage1 - Usage for executable object. + * @param {string} usage2 - Usage for string function. + * @return {function} JS function to call. + */ + parseArgumentsForFunction(args, usage1, usage2) { + let f, target, variable + if(args.length === 1) { + // Parse object + f = args[0] + if(typeof f !== 'object' || !f.execute) + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) + let target = f + f = (x) => target.execute(x) + } else if(args.length === 2) { + // Parse variable + [f,variable] = args + if(typeof f !== 'string' || typeof variable !== 'string') + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) + f = this._parser.parse(f).toJSFunction(variable, this.currentVars) + } else + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + return f + } + + /** + * @param {string} expression - Expression to parse + */ + parse(expression) { + return this._parser.parse(expression) + } + + integral(a, b, ...args) { + let usage1 = qsTranslate('usage', 'integral(, , )') + let usage2 = qsTranslate('usage', 'integral(, , , )') + let f = this.parseArgumentsForFunction(args, usage1, usage2) + if(a == null || b == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + + // https://en.wikipedia.org/wiki/Simpson%27s_rule + // Simpler, faster than tokenizing the expression + return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) + } + + derivative(...args) { + let usage1 = qsTranslate('usage', 'derivative(, )') + let usage2 = qsTranslate('usage', 'derivative(, , )') + let x = args.pop() + let f = this.parseArgumentsForFunction(args, usage1, usage2) + if(x == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + + let derivative_precision = x/10 + return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision + } +} + +/** @type {ExprParserAPI} */ +Runtime.ExprParser = Runtime.ExprParser || new ExprParserAPI() + + + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs similarity index 53% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index 8ee04cf..d3214f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -1,42 +1,30 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -.pragma library +// Type polyfills for IDEs. +// Never directly imported. -.import "common.js" as C -.import "point.js" as P -.import "text.js" as T -.import "function.js" as F -.import "gainbode.js" as GB -.import "phasebode.js" as PB -.import "sommegainsbode.js" as SGB -.import "sommephasesbode.js" as SPB -.import "xcursor.js" as X -.import "sequence.js" as S -.import "repartition.js" as R - -C.registerObject(P.Point) -C.registerObject(T.Text) -C.registerObject(F.Function) -C.registerObject(GB.GainBode) -C.registerObject(PB.PhaseBode) -C.registerObject(SGB.SommeGainsBode) -C.registerObject(SPB.SommePhasesBode) -C.registerObject(X.XCursor) -C.registerObject(S.Sequence) -C.registerObject(R.RepartitionFunction) +Runtime = Runtime || {} +/** @type {function(string, string): string} */ +qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTranslate not implemented.'); } +/** @type {function(string): string} */ +qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } +/** @type {function(string, string): string} */ +QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } +/** @type {function(string|boolean|int): string} */ +String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js deleted file mode 100644 index 0858522..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "../expr-eval.js" as ExprEval -.import "../utils.js" as Utils -.import "latex.js" as Latex - -var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually - "pi": Math.PI, - "PI": Math.PI, - "π": Math.PI, - "inf": Infinity, - "infinity": Infinity, - "Infinity": Infinity, - "∞": Infinity, - "e": Math.E, - "E": Math.E, - "true": true, - "false": false - -} - -var currentVars = {} -var currentObjectsByName = {} // Mirror of currentObjectsByName in objects.js - -const parser = new ExprEval.Parser() - -parser.consts = Object.assign({}, parser.consts, evalVariables) - -/** - * Parses arguments for a function, returns the corresponding JS function if it exists. - * Throws either usage error otherwise. - * @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ]. - * @param {string} usage1 - Usage for executable object. - * @param {string} usage2 - Usage for string function. - * @return {callable} JS function to call.. - */ -function parseArgumentsForFunction(args, usage1, usage2) { - let f, target, variable - if(args.length == 1) { - // Parse object - f = args[0] - if(typeof f != 'object' || !f.execute) - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) - let target = f - f = (x) => target.execute(x) - } else if(args.length == 2) { - // Parse variable - [f,variable] = args - if(typeof f != 'string' || typeof variable != 'string') - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) - f = parser.parse(f).toJSFunction(variable, currentVars) - } else - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - return f -} - -// Function definition -parser.functions.integral = function(a, b, ...args) { - let usage1 = qsTranslate('usage', 'integral(, , )') - let usage2 = qsTranslate('usage', 'integral(, , , )') - let f = parseArgumentsForFunction(args, usage1, usage2) - if(a == null || b == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - - // https://en.wikipedia.org/wiki/Simpson%27s_rule - // Simpler, faster than tokenizing the expression - return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) -} - -parser.functions.derivative = function(...args) { - let usage1 = qsTranslate('usage', 'derivative(, )') - let usage2 = qsTranslate('usage', 'derivative(, , )') - let x = args.pop() - let f = parseArgumentsForFunction(args, usage1, usage2) - if(x == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - - let derivative_precision = x/10 - return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision -} - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs similarity index 79% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index 6c47a23..e2606c4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -16,21 +16,19 @@ * along with this program. If not, see . */ -.pragma library - -.import "expression.js" as Expr +import { Expression, executeExpression } from "expression.mjs" /** * Main abstract domain class * It doesn't represent any kind of domain and is meant to be extended. */ -class Domain { +export class Domain { constructor() {} /** * Checks whether x is included in the domain. * @param {number} x - The x value. - * @return {bool} true if included, false otherwise. + * @return {boolean} true if included, false otherwise. */ includes(x) { return false } @@ -166,7 +164,7 @@ class Domain { /** * Represents an empty set. */ -class EmptySet extends Domain { +export class EmptySet extends Domain { constructor() { super() this.displayName = "∅" @@ -187,12 +185,12 @@ class EmptySet extends Domain { /** * Domain classes for ranges (e.g ]0;3[, [1;2[ ...) */ -class Range extends Domain { +export class Range extends Domain { constructor(begin, end, openBegin, openEnd) { super() - if(typeof begin == 'number' || typeof begin == 'string') begin = new Expr.Expression(begin.toString()) + if(typeof begin == 'number' || typeof begin == 'string') begin = new Expression(begin.toString()) this.begin = begin - if(typeof end == 'number' || typeof end == 'string') end = new Expr.Expression(end.toString()) + if(typeof end == 'number' || typeof end == 'string') end = new Expression(end.toString()) this.end = end this.openBegin = openBegin this.openEnd = openEnd @@ -201,7 +199,7 @@ class Range extends Domain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) } @@ -229,9 +227,9 @@ class Range extends Domain { } static import(frm) { - var openBegin = frm.trim().charAt(0) == "]" - var openEnd = frm.trim().charAt(frm.length -1) == "[" - var [begin, end] = frm.substr(1, frm.length-2).split(";") + let openBegin = frm.trim().charAt(0) === "]" + let openEnd = frm.trim().charAt(frm.length -1) === "[" + let [begin, end] = frm.substr(1, frm.length-2).split(";") return new Range(begin.trim(), end.trim(), openBegin, openEnd) } } @@ -239,17 +237,16 @@ class Range extends Domain { /** * Domain classes for special domains (N, Z, ...) */ -class SpecialDomain extends Domain { +export class SpecialDomain extends Domain { /** * @constructs SpecialDomain * @param {string} displayName * @param {function} isValid - function returning true when number is in domain false when it isn't. * @param {function} next - function provides the next positive value in the domain after the one given. * @param {function} previous - function provides the previous positive value in the domain before the one given. - * @param {bool} moveSupported - Only true if next and previous functions are valid. - * @param items + * @param {boolean} moveSupported - Only true if next and previous functions are valid. */ - constructor(displayName, isValid, next = x => true, previous = x => true, + constructor(displayName, isValid, next = () => true, previous = () => true, moveSupported = true) { super() this.displayName = displayName @@ -260,17 +257,17 @@ class SpecialDomain extends Domain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.isValid(x) } next(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.nextValue(x) } previous(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.prevValue(x) } @@ -300,14 +297,14 @@ class SpecialDomain extends Domain { /** * Domain classes for sets (e.g {0;3}, {0;1;2;pi} ...) */ -class DomainSet extends SpecialDomain { +export class DomainSet extends SpecialDomain { constructor(values) { super('', x => true, x => x, true) - var newVals = {} + let newVals = {} this.executedValues = [] - for(var value of values) { - var expr = new Expr.Expression(value.toString()) - var ex = expr.execute() + for(let value of values) { + let expr = new Expression(value.toString()) + let ex = expr.execute() newVals[ex] = expr this.executedValues.push(ex) } @@ -318,30 +315,30 @@ class DomainSet extends SpecialDomain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) - for(var value of this.values) - if(x == value.execute()) return true + if(typeof x == 'string') x = executeExpression(x) + for(let value of this.values) + if(x === value.execute()) return true return false } next(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x < this.executedValues[0]) return this.executedValues[0] - for(var i = 1; i < this.values.length; i++) { - var prevValue = this.executedValues[i-1] - var value = this.executedValues[i] + for(let i = 1; i < this.values.length; i++) { + let prevValue = this.executedValues[i-1] + let value = this.executedValues[i] if(x >= prevValue && x < value) return value } return null } previous(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x > this.executedValues[this.executedValues.length-1]) return this.executedValues[this.executedValues.length-1] - for(var i = 1; i < this.values.length; i++) { - var prevValue = this.executedValues[i-1] - var value = this.executedValues[i] + for(let i = 1; i < this.values.length; i++) { + let prevValue = this.executedValues[i-1] + let value = this.executedValues[i] if(x > prevValue && x <= value) return prevValue } return null @@ -354,56 +351,56 @@ class DomainSet extends SpecialDomain { union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) { - var newValues = [] - var values = this.values.concat(domain.values).filter(function(val){ + let newValues = [] + let values = this.values.concat(domain.values).filter(function(val){ newValues.push(val.execute()) - return newValues.indexOf(val.execute()) == newValues.length - 1 + return newValues.indexOf(val.execute()) === newValues.length - 1 }) return new DomainSet(values) } - var notIncludedValues = [] - for(var value in this.values) { - var value = this.executedValues[i] + let notIncludedValues = [] + for(let i = 0; i < this.values.length; i++) { + let value = this.executedValues[i] if(domain instanceof Range) { - if(domain.begin.execute() == value && domain.openBegin) { + if(domain.begin.execute() === value && domain.openBegin) { domain.openBegin = false } - if(domain.end.execute() == value && domain.openEnd) { + if(domain.end.execute() === value && domain.openEnd) { domain.openEnd = false } } if(!domain.includes(value)) notIncludedValues.push(this.values[i].toEditableString()) } - if(notIncludedValues.length == 0) return domain + if(notIncludedValues.length === 0) return domain return new UnionDomain(domain, new DomainSet(notIncludedValues)) } intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) { - var domValues = domain.values.map(expr => expr.execute()) + let domValues = domain.values.map(expr => expr.execute()) this.values = this.values.filter(function(val){ return domValues.indexOf(val.execute()) >= 0 }) return this } - var includedValues = [] - for(var i in this.values) { - var value = this.executedValues[i] + let includedValues = [] + for(let i in this.values) { + let value = this.executedValues[i] if(domain instanceof Range) { - if(domain.begin.execute() == value && !domain.openBegin) { + if(domain.begin.execute() === value && !domain.openBegin) { domain.openBegin = false } - if(domain.end.execute() == value && !domain.openEnd) { + if(domain.end.execute() === value && !domain.openEnd) { domain.openEnd = false } } if(domain.includes(value)) includedValues.push(this.values[i].toEditableString()) } - if(includedValues.length == 0) return new EmptySet() - if(includedValues.length == this.values.length) return this + if(includedValues.length === 0) return new EmptySet() + if(includedValues.length === this.values.length) return this return new IntersectionDomain(domain, new DomainSet(includedValues)) } @@ -415,7 +412,7 @@ class DomainSet extends SpecialDomain { /** * Domain representing the union between two domains. */ -class UnionDomain extends Domain { +export class UnionDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -450,10 +447,10 @@ class UnionDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∪") - if(domains.length == 1) domains = frm.trim().split("U") // Fallback - var dom2 = parseDomain(domains.pop()) - var dom1 = parseDomain(domains.join('∪')) + let domains = frm.trim().split("∪") + if(domains.length === 1) domains = frm.trim().split("U") // Fallback + let dom2 = parseDomain(domains.pop()) + let dom1 = parseDomain(domains.join('∪')) return dom1.union(dom2) } } @@ -461,7 +458,7 @@ class UnionDomain extends Domain { /** * Domain representing the intersection between two domains. */ -class IntersectionDomain extends Domain { +export class IntersectionDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -496,9 +493,9 @@ class IntersectionDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∩") - var dom1 = parseDomain(domains.pop()) - var dom2 = parseDomain(domains.join('∩')) + let domains = frm.trim().split("∩") + let dom1 = parseDomain(domains.pop()) + let dom2 = parseDomain(domains.join('∩')) return dom1.intersection(dom2) } } @@ -506,7 +503,7 @@ class IntersectionDomain extends Domain { /** * Domain representing the minus between two domains. */ -class MinusDomain extends Domain { +export class MinusDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -524,10 +521,10 @@ class MinusDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∖") - if(domains.length == 1) domains = frm.trim().split("\\") // Fallback - var dom1 = parseDomain(domains.shift()) - var dom2 = parseDomain(domains.join('∪')) + let domains = frm.trim().split("∖") + if(domains.length === 1) domains = frm.trim().split("\\") // Fallback + let dom1 = parseDomain(domains.shift()) + let dom2 = parseDomain(domains.join('∪')) return new MinusDomain(dom1, dom2) } } @@ -551,53 +548,53 @@ Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}" Domain.RME = new Range(-Infinity,0,true,true) Domain.RME.displayName = "ℝ⁻*" Domain.RME.latexMarkup = "\\mathbb{R}^{+*}" -Domain.N = new SpecialDomain('ℕ', x => x%1==0 && x >= 0, +Domain.N = new SpecialDomain('ℕ', x => x%1===0 && x >= 0, x => Math.max(Math.floor(x)+1, 0), x => Math.max(Math.ceil(x)-1, 0)) Domain.N.latexMarkup = "\\mathbb{N}" -Domain.NE = new SpecialDomain('ℕ*', x => x%1==0 && x > 0, +Domain.NE = new SpecialDomain('ℕ*', x => x%1===0 && x > 0, x => Math.max(Math.floor(x)+1, 1), x => Math.max(Math.ceil(x)-1, 1)) Domain.NE.latexMarkup = "\\mathbb{N}^{*}" -Domain.Z = new SpecialDomain('ℤ', x => x%1==0, x => Math.floor(x)+1, x => Math.ceil(x)-1) +Domain.Z = new SpecialDomain('ℤ', x => x%1===0, x => Math.floor(x)+1, x => Math.ceil(x)-1) Domain.Z.latexMarkup = "\\mathbb{Z}" -Domain.ZE = new SpecialDomain('ℤ*', x => x%1==0 && x != 0, - x => Math.floor(x)+1 == 0 ? Math.floor(x)+2 : Math.floor(x)+1, - x => Math.ceil(x)-1 == 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) +Domain.ZE = new SpecialDomain('ℤ*', x => x%1===0 && x !== 0, + x => Math.floor(x)+1 === 0 ? Math.floor(x)+2 : Math.floor(x)+1, + x => Math.ceil(x)-1 === 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}" -Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1==0 && x <= 0, +Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1===0 && x <= 0, x => Math.min(Math.floor(x)+1, 0), x => Math.min(Math.ceil(x)-1, 0)) Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}" -Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1==0 && x < 0, +Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1===0 && x < 0, x => Math.min(Math.floor(x)+1, -1), x => Math.min(Math.ceil(x)-1, -1)) Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" Domain.NLog = new SpecialDomain('ℕˡᵒᵍ', - x => x/Math.pow(10, x.toString().length-1) % 1 == 0 && x > 0, + x => x/Math.pow(10, x.toString().length-1) % 1 === 0 && x > 0, function(x) { - var x10pow = Math.pow(10, x.toString().length-1) + let x10pow = Math.pow(10, x.toString().length-1) return Math.max(1, (Math.floor(x/x10pow)+1)*x10pow) }, function(x) { - var x10pow = Math.pow(10, x.toString().length-1) + let x10pow = Math.pow(10, x.toString().length-1) return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow) }) Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" -var refedDomains = [] +let refedDomains = [] /** - * Parses a domain, that can use parenthesises. + * Parses a domain, that can use parentheses. * e.g (N ∪ [-1;0[) ∩ (Z \ {0;3}) * @param {string} domain - string of the domain to be parsed. * @returns {Domain} Parsed domain. */ -function parseDomain(domain) { +export function parseDomain(domain) { if(!domain.includes(')') && !domain.includes('(')) return parseDomainSimple(domain) - var domStr + let domStr while((domStr = /\(([^)(]+)\)/.exec(domain)) !== null) { - var dom = parseDomainSimple(domStr[1].trim()); + let dom = parseDomainSimple(domStr[1].trim()); domain = domain.replace(domStr[0], 'D' + refedDomains.length) refedDomains.push(dom) } @@ -605,20 +602,20 @@ function parseDomain(domain) { } /** - * Parses a domain, without parenthesises. + * Parses a domain, without parentheses. * e.g N ∪ [-1;0[, Z \ {0;3}, N+*... * @param {string} domain - string of the domain to be parsed. * @returns {Domain} Parsed domain. */ -function parseDomainSimple(domain) { +export function parseDomainSimple(domain) { domain = domain.trim() if(domain.includes("U") || domain.includes("∪")) return UnionDomain.import(domain) if(domain.includes("∩")) return IntersectionDomain.import(domain) if(domain.includes("∖") || domain.includes("\\")) return MinusDomain.import(domain) - if(domain.charAt(0) == "{" && domain.charAt(domain.length -1) == "}") return DomainSet.import(domain) + if(domain.charAt(0) === "{" && domain.charAt(domain.length -1) === "}") return DomainSet.import(domain) if(domain.includes("]") || domain.includes("[")) return Range.import(domain) if(["R", "ℝ", "N", "ℕ", "Z", "ℤ"].some(str => domain.toUpperCase().includes(str))) return Domain.import(domain) - if(domain[0] == 'D') return refedDomains[parseInt(domain.substr(1))] + if(domain[0] === 'D') return refedDomains[parseInt(domain.substr(1))] return new EmptySet() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs similarity index 63% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 4a57746..3a16499 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -16,21 +16,25 @@ * along with this program. If not, see . */ -.pragma library -.import "common.js" as C -.import "latex.js" as Latex -.import "../utils.js" as Utils +import Latex from "latex.mjs" +import * as Utils from "../utils.mjs" /** * Represents any kind of x-based or non variable based expression. */ -class Expression { +export class Expression { constructor(expr) { + if(!Runtime.ExprParser) + throw new Error('Expression parser not initialized.') + if(!Runtime.Objects) + throw new Error('Objects API not initialized.') this.expr = Utils.exponentsToExpression(expr) - this.calc = C.parser.parse(this.expr).simplify() + this.calc = Runtime.ExprParser.parse(this.expr).simplify() this.cached = this.isConstant() - this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null + this.cachedValue = null + if(this.cached && this.allRequirementsFullfilled()) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -40,37 +44,37 @@ class Expression { } requiredObjects() { - return this.calc.variables().filter(objName => objName != "x" && objName != "n") + return this.calc.variables().filter(objName => objName !== "x" && objName !== "n") } allRequirementsFullfilled() { - return this.requiredObjects().every(objName => objName in C.currentObjectsByName) + return this.requiredObjects().every(objName => objName in Runtime.Objects.currentObjectsByName) } undefinedVariables() { - return this.requiredObjects().filter(objName => !(objName in C.currentObjectsByName)) + return this.requiredObjects().filter(objName => !(objName in Runtime.Objects.currentObjectsByName)) } recache() { if(this.cached) - this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) } execute(x = 1) { if(this.cached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) return this.cachedValue } - C.currentVars = Object.assign({'x': x}, C.currentObjectsByName) - return this.calc.evaluate(C.currentVars) + Runtime.ExprParser.currentVars = Object.assign({'x': x}, Runtime.Objects.currentObjectsByName) + return this.calc.evaluate(Runtime.ExprParser.currentVars) } simplify(x) { - var expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate() == 0) return '0' - var str = Utils.makeExpressionReadable(expr.toString()); - if(str != undefined && str.match(/^\d*\.\d+$/)) { + let expr = this.calc.substitute('x', x).simplify() + if(expr.evaluate() === 0) return '0' + let str = Utils.makeExpressionReadable(expr.toString()); + if(str !== undefined && str.match(/^\d*\.\d+$/)) { if(str.split('.')[1].split('0').length > 7) { // Likely rounding error str = parseFloat(str.substring(0, str.length-1)).toString(); @@ -89,11 +93,11 @@ class Expression { toString(forceSign=false) { let str = Utils.makeExpressionReadable(this.calc.toString()) - if(str[0] != '-' && forceSign) str = '+' + str + if(str[0] !== '-' && forceSign) str = '+' + str return str } } -function executeExpression(expr){ +export function executeExpression(expr){ return (new Expression(expr.toString())).execute() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js deleted file mode 100644 index 50883b2..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ /dev/null @@ -1,282 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "../expr-eval.js" as ExprEval - - -/** - * true if latex has been enabled by the user, false otherwise. - */ -var enabled = false -/** - * LaTeX python backend QObject. - */ -var Renderer = null -/** - * Default window color used to render LaTeX formulas. - */ -var defaultColor = "black" - -/** - * Puts element within parenthesis. - * - * @param {string} elem - element to put within parenthesis. - * @returns {string} - */ -function par(elem) { - return '(' + elem + ')' -} - -/** - * Checks if the element contains at least one of the elements of - * the string array contents, but not at the first position of the string, - * and returns the parenthesis version if so. - * - * @param {string} elem - element to put within parenthesis. - * @param {Array} contents - Array of elements to put within parenthesis. - * @returns {string} - */ -function parif(elem, contents) { - elem = elem.toString() - if(elem[0] != "(" && elem[elem.length-1] != ")" && contents.some(x => elem.indexOf(x) > 0)) - return par(elem) - if(elem[0] == "(" && elem[elem.length-1] == ")") - return elem.substr(1, elem.length-2) - return elem -} - - -/** - * Creates a latex expression for a function. - * - * @param {string} f - Function to convert - * @param {Array} args - Arguments of the function - * @returns {string} - */ -function functionToLatex(f, args) { - switch(f) { - case "derivative": - if(args.length == 3) - return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; - else - return '\\frac{d' + args[0] + '}{dx}(x)'; - break; - case "integral": - if(args.length == 4) - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); - else - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; - break; - case "sqrt": - return '\\sqrt\\left(' + args.join(', ') + '\\right)'; - break; - case "abs": - return '\\left|' + args.join(', ') + '\\right|'; - break; - case "floor": - return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; - break; - case "ceil": - return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; - break; - default: - return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; - break; - } -} - - -/** - * Creates a latex variable from a variable. - * - * @param {string} vari - variable text to convert - * @param {bool} wrapIn$ - checks whether the escaped chars should be escaped - * @returns {string} - */ -function variable(vari, wrapIn$ = false) { - let unicodechars = ["α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀", - "pi", "∞"] - let equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", - "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", - "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", - "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", - "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", - "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", - "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", - "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", - "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", - "\\pi", "\\infty"] - if(wrapIn$) - for(let i = 0; i < unicodechars.length; i++) { - if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') - } - else - for(let i = 0; i < unicodechars.length; i++) { - if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) - } - return vari; -} - -/** - * Converts expr-eval tokens to a latex string. - * - * @param {Array} tokens - expr-eval tokens list - * @returns {string} - */ -function expression(tokens) { - var nstack = []; - var n1, n2, n3; - var f, args, argCount; - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - var type = item.type; - - switch(type) { - case ExprEval.INUMBER: - if(item.value == Infinity) { - nstack.push("\\infty") - } else if(typeof item.value === 'number' && item.value < 0) { - nstack.push(par(item.value)); - } else if(Array.isArray(item.value)) { - nstack.push('[' + item.value.map(ExprEval.escapeValue).join(', ') + ']'); - } else { - nstack.push(ExprEval.escapeValue(item.value)); - } - break; - case ExprEval.IOP2: - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - switch(f) { - case '-': - case '+': - nstack.push(n1 + f + n2); - break; - case '||': - case 'or': - case '&&': - case 'and': - case '==': - case '!=': - nstack.push(par(n1) + f + par(n2)); - break; - case '*': - if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") - nstack.push(parif(n1,['+','-']) + n2) - else - nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); - break; - case '/': - nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); - break; - case '^': - nstack.push(parif(n1,['+','-','*','/','!']) + "^{" + n2 + "}"); - break; - case '%': - nstack.push(parif(n1,['+','-','*','/','!','^']) + " \\mathrm{mod} " + parif(n2,['+','-','*','/','!','^'])); - break; - case '[': - nstack.push(n1 + '[' + n2 + ']'); - break; - default: - throw new EvalError("Unknown operator " + ope + "."); - } - break; - case ExprEval.IOP3: // Thirdiary operator - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - if (f === '?') { - nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); - } else { - throw new EvalError('Unknown operator ' + ope + '.'); - } - break; - case ExprEval.IVAR: - case ExprEval.IVARNAME: - nstack.push(variable(item.value.toString())); - break; - case ExprEval.IOP1: // Unary operator - n1 = nstack.pop(); - f = item.value; - switch(f) { - case '-': - case '+': - nstack.push(par(f + n1)); - break; - case '!': - nstack.push(parif(n1,['+','-','*','/','^']) + '!'); - break; - default: - nstack.push(f + parif(n1,['+','-','*','/','^'])); - break; - } - break; - case ExprEval.IFUNCALL: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - f = nstack.pop(); - // Handling various functions - nstack.push(functionToLatex(f, args)) - break; - case ExprEval.IFUNDEF: - nstack.push(par(n1 + '(' + args.join(', ') + ') = ' + n2)); - break; - case ExprEval.IMEMBER: - n1 = nstack.pop(); - nstack.push(n1 + '.' + item.value); - break; - case ExprEval.IARRAY: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - nstack.push('[' + args.join(', ') + ']'); - break; - case ExprEval.IEXPR: - nstack.push('(' + expression(item.value) + ')'); - break; - case ExprEval.IENDSTATEMENT: - break; - default: - throw new EvalError('invalid Expression'); - break; - } - } - if (nstack.length > 1) { - nstack = [ nstack.join(';') ] - } - return String(nstack[0]); -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs new file mode 100644 index 0000000..c7975e7 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -0,0 +1,288 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { RuntimeAPI } from '../runtime.mjs' + +const unicodechars = ["α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀", + "pi", "∞"] +const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", + "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", + "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", + "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", + "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", + "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", + "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", + "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", + "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", + "\\pi", "\\infty"] + +console.log(Runtime.ExprParser) + +class LatexAPI extends RuntimeAPI { + constructor() { + super('Latex', [ + /** @type {ExprParserAPI} */ + Runtime.ExprParser + ]) + /** + * true if latex has been enabled by the user, false otherwise. + */ + this.enabled = false + /** + * LaTeX python backend QObject. + */ + this.Renderer = null + } + + /** + * Puts element within parenthesis. + * + * @param {string} elem - element to put within parenthesis. + * @returns {string} + */ + par(elem) { + return '(' + elem + ')' + } + + /** + * Checks if the element contains at least one of the elements of + * the string array contents, but not at the first position of the string, + * and returns the parenthesis version if so. + * + * @param {string} elem - element to put within parenthesis. + * @param {Array} contents - Array of elements to put within parenthesis. + * @returns {string} + */ + parif(elem, contents) { + elem = elem.toString() + if(elem[0] !== "(" && elem[elem.length-1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) + return this.par(elem) + if(elem[0] === "(" && elem[elem.length-1] === ")") + return elem.substr(1, elem.length-2) + return elem + } + + /** + * Creates a latex expression for a function. + * + * @param {string} f - Function to convert + * @param {(number,string)[]} args - Arguments of the function + * @returns {string} + */ + functionToLatex(f, args) { + switch(f) { + case "derivative": + if(args.length === 3) + return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; + else + return '\\frac{d' + args[0] + '}{dx}(x)'; + break; + case "integral": + if(args.length === 4) + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); + else + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; + break; + case "sqrt": + return '\\sqrt\\left(' + args.join(', ') + '\\right)'; + break; + case "abs": + return '\\left|' + args.join(', ') + '\\right|'; + break; + case "floor": + return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; + break; + case "ceil": + return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; + break; + default: + return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; + break; + } + } + + /** + * Creates a latex variable from a variable. + * + * @param {string} vari - variable text to convert + * @param {boolean} wrapIn$ - checks whether the escaped chars should be escaped + * @returns {string} + */ + variable(vari, wrapIn$ = false) { + if(wrapIn$) + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') + } + else + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) + } + return vari; + } + + /** + * Converts expr-eval tokens to a latex string. + * + * @param {Array} tokens - expr-eval tokens list + * @returns {string} + */ + expression(tokens) { + let nstack = [] + let n1, n2, n3 + let f, args, argCount + for (let i = 0; i < tokens.length; i++) { + let item = tokens[i] + let type = item.type + + switch(type) { + case Runtime.ExprParser.Internals.INUMBER: + if(item.value === Infinity) { + nstack.push("\\infty") + } else if(typeof item.value === 'number' && item.value < 0) { + nstack.push(this.par(item.value)); + } else if(Array.isArray(item.value)) { + nstack.push('[' + item.value.map(Runtime.ExprParser.Internals.escapeValue).join(', ') + ']'); + } else { + nstack.push(Runtime.ExprParser.Internals.escapeValue(item.value)); + } + break; + case Runtime.ExprParser.Internals.IOP2: + n2 = nstack.pop(); + n1 = nstack.pop(); + f = item.value; + switch(f) { + case '-': + case '+': + nstack.push(n1 + f + n2); + break; + case '||': + case 'or': + case '&&': + case 'and': + case '==': + case '!=': + nstack.push(this.par(n1) + f + this.par(n2)); + break; + case '*': + if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") + nstack.push(this.parif(n1,['+','-']) + n2) + else + nstack.push(this.parif(n1,['+','-']) + " \\times " + this.parif(n2,['+','-'])); + break; + case '/': + nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); + break; + case '^': + nstack.push(this.parif(n1,['+','-','*','/','!']) + "^{" + n2 + "}"); + break; + case '%': + nstack.push(this.parif(n1,['+','-','*','/','!','^']) + " \\mathrm{mod} " + parif(n2,['+','-','*','/','!','^'])); + break; + case '[': + nstack.push(n1 + '[' + n2 + ']'); + break; + default: + throw new EvalError("Unknown operator " + ope + "."); + } + break; + case Runtime.ExprParser.Internals.IOP3: // Thirdiary operator + n3 = nstack.pop(); + n2 = nstack.pop(); + n1 = nstack.pop(); + f = item.value; + if (f === '?') { + nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); + } else { + throw new EvalError('Unknown operator ' + ope + '.'); + } + break; + case Runtime.ExprParser.Internals.IVAR: + case Runtime.ExprParser.Internals.IVARNAME: + nstack.push(this.variable(item.value.toString())); + break; + case Runtime.ExprParser.Internals.IOP1: // Unary operator + n1 = nstack.pop(); + f = item.value; + switch(f) { + case '-': + case '+': + nstack.push(this.par(f + n1)); + break; + case '!': + nstack.push(this.parif(n1,['+','-','*','/','^']) + '!'); + break; + default: + nstack.push(f + this.parif(n1,['+','-','*','/','^'])); + break; + } + break; + case Runtime.ExprParser.Internals.IFUNCALL: + argCount = item.value; + args = []; + while (argCount-- > 0) { + args.unshift(nstack.pop()); + } + f = nstack.pop(); + // Handling various functions + nstack.push(this.functionToLatex(f, args)) + break; + case Runtime.ExprParser.Internals.IFUNDEF: + nstack.push(this.par(n1 + '(' + args.join(', ') + ') = ' + n2)); + break; + case Runtime.ExprParser.Internals.IMEMBER: + n1 = nstack.pop(); + nstack.push(n1 + '.' + item.value); + break; + case Runtime.ExprParser.Internals.IARRAY: + argCount = item.value; + args = []; + while (argCount-- > 0) { + args.unshift(nstack.pop()); + } + nstack.push('[' + args.join(', ') + ']'); + break; + case Runtime.ExprParser.Internals.IEXPR: + nstack.push('(' + this.expression(item.value) + ')'); + break; + case Runtime.ExprParser.Internals.IENDSTATEMENT: + break; + default: + throw new EvalError('invalid Expression'); + } + } + if (nstack.length > 1) { + nstack = [ nstack.join(';') ] + } + return String(nstack[0]); + } +} + +/** @type {LatexAPI} */ +Runtime.Latex = Runtime.Latex || new LatexAPI() + +export default Runtime.Latex diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs similarity index 66% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index cd0960a..2dafdcd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -16,18 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as C -.import "expression.js" as Expr -.import "../utils.js" as Utils -.import "../math/latex.js" as Latex - +import * as Expr from "expression.mjs" +import * as Utils from "../utils.mjs" +import Latex from "../math/latex.mjs" /** * Represents mathematical object for sequences. */ -class Sequence extends Expr.Expression { +export class Sequence extends Expr.Expression { constructor(name, baseValues = {}, valuePlus = 1, expr = "") { // u[n+valuePlus] = expr super(expr) @@ -35,9 +31,9 @@ class Sequence extends Expr.Expression { this.baseValues = baseValues this.calcValues = Object.assign({}, baseValues) this.latexValues = Object.assign({}, baseValues) - for(var n in this.calcValues) + for(let n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { - let parsed = C.parser.parse(this.calcValues[n].toString()).simplify() + let parsed = Runtime.ExprParser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate() } @@ -45,7 +41,7 @@ class Sequence extends Expr.Expression { } isConstant() { - return this.expr.indexOf("n") == -1 + return this.expr.indexOf("n") === -1 } execute(n = 1) { @@ -63,25 +59,25 @@ class Sequence extends Expr.Expression { } cache(n = 1) { - var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - var expr = C.parser.parse(str).simplify() - // Chache values required for this one. + let str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) + let expr = Runtime.ExprParser.parse(str).simplify() + // Cache values required for this one. if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) this.cache(n-this.valuePlus) // Setting current variables - C.currentVars = Object.assign( + Runtime.ExprParser.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - C.currentObjectsByName, + Runtime.Objects.currentObjectsByName, {[this.name]: this.calcValues} ) - this.calcValues[n] = expr.evaluate(C.currentVars) + this.calcValues[n] = expr.evaluate(Runtime.ExprParser.currentVars) } toString(forceSign=false) { - var str = Utils.makeExpressionReadable(this.calc.toString()) - if(str[0] != '-' && forceSign) str = '+' + str - var subtxt = this.valuePlus == 0 ? 'ₙ' : Utils.textsub('n+' + this.valuePlus) - var ret = `${this.name}${subtxt} = ${str}${this.baseValues.length == 0 ? '' : "\n"}` + let str = Utils.makeExpressionReadable(this.calc.toString()) + if(str[0] !== '-' && forceSign) str = '+' + str + let subtxt = this.valuePlus === 0 ? 'ₙ' : Utils.textsub('n+' + this.valuePlus) + let ret = `${this.name}${subtxt} = ${str}${this.baseValues.length === 0 ? '' : "\n"}` ret += Object.keys(this.baseValues).map( n => `${this.name}${Utils.textsub(n)} = ${this.baseValues[n]}` ).join('; ') @@ -89,10 +85,10 @@ class Sequence extends Expr.Expression { } toLatexString(forceSign=false) { - var str = this.latexMarkup - if(str[0] != '-' && forceSign) str = '+' + str - var subtxt = '_{n' + (this.valuePlus == 0 ? '' : '+' + this.valuePlus) + '}' - var ret = `\\begin{array}{l}${Latex.variable(this.name)}${subtxt} = ${str}${this.latexValues.length == 0 ? '' : "\n"}\\\\` + let str = this.latexMarkup + if(str[0] !== '-' && forceSign) str = '+' + str + let subtxt = '_{n' + (this.valuePlus === 0 ? '' : '+' + this.valuePlus) + '}' + let ret = `\\begin{array}{l}${Latex.variable(this.name)}${subtxt} = ${str}${this.latexValues.length === 0 ? '' : "\n"}\\\\` ret += Object.keys(this.latexValues).map( n => `${this.name}_{${n}} = ${this.latexValues[n]}` ).join('; ') + "\\end{array}" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs similarity index 54% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs index 9ecb377..88f9c1e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs @@ -16,26 +16,25 @@ * along with this program. If not, see . */ -.pragma library -.import "math/expression.js" as Expr -.import "math/sequence.js" as Seq +import * as Expr from "math/expression.mjs" +import * as Seq from "math/sequence.mjs" +import * as Dom from "math/domain.mjs" -.import "math/domain.js" as Dom -var Expression = Expr.Expression -var executeExpression = Expr.executeExpression -var Sequence = Seq.Sequence +export const Expression = Expr.Expression +export const executeExpression = Expr.executeExpression +export const Sequence = Seq.Sequence // Domains -var Domain = Dom.Domain -var EmptySet = Dom.EmptySet -var Range = Dom.Range -var SpecialDomain = Dom.SpecialDomain -var DomainSet = Dom.DomainSet -var UnionDomain = Dom.UnionDomain -var IntersectionDomain = Dom.IntersectionDomain -var MinusDomain = Dom.MinusDomain +export const Domain = Dom.Domain +export const EmptySet = Dom.EmptySet +export const Range = Dom.Range +export const SpecialDomain = Dom.SpecialDomain +export const DomainSet = Dom.DomainSet +export const UnionDomain = Dom.UnionDomain +export const IntersectionDomain = Dom.IntersectionDomain +export const MinusDomain = Dom.MinusDomain -var parseDomain = Dom.parseDomain -var parseDomainSimple = Dom.parseDomainSimple +export const parseDomain = Dom.parseDomain +export const parseDomainSimple = Dom.parseDomainSimple diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js new file mode 100644 index 0000000..773f1c3 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js @@ -0,0 +1,7 @@ + +// Loading modules in order +.import "objects.mjs" as Objects +.import "lib/expr-eval/integration.js" as ExprParser +.import "objs/autoload.mjs" as Autoload +.import "math/latex.mjs" as Latex +.import "history/common.mjs" as HistoryCommon diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js deleted file mode 100644 index 90dd468..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "utils.js" as Utils -.import "math/common.js" as MathCommons -.import "parameters.js" as P - -var types = {} - -var currentObjects = {} -var currentObjectsByName = {} -MathCommons.currentObjectsByName = currentObjectsByName // Required for using objects in variables. - -function renameObject(oldName, newName) { - /** - * Renames an object from its old name to the new one. - * @param {string} oldName - Current name of the object. - * @param {string} newName - Name to rename the object to. - */ - let obj = currentObjectsByName[oldName] - delete currentObjectsByName[oldName] - currentObjectsByName[newName] = obj - obj.name = newName -} - -function deleteObject(objName) { - /** - * Deletes an object by its given name. - * @param {string} objName - Current name of the object. - */ - let obj = currentObjectsByName[objName] - currentObjects[obj.type].splice(currentObjects[obj.type].indexOf(obj),1) - obj.delete() - delete currentObjectsByName[objName] -} - -function getObjectsName(objType) { - /** - * Gets a list of all names of a certain object type. - * @param {string} objType - Type of the object to query. Can be ExecutableObject for all ExecutableObjects. - * @return {array} List of names of the objects. - */ - if(objType == "ExecutableObject") { - // NOTE: QMLJS does not support flatMap. - // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) - let types = getExecutableTypes() - let elementNames = [''] - for(let elemType of types) - elementNames = elementNames.concat(currentObjects[elemType].map(obj => obj.name)) - return elementNames - } - if(currentObjects[objType] == undefined) return [] - return currentObjects[objType].map(obj => obj.name) -} - -function getExecutableTypes() { - /** - * Returns a list of all object types which are executable objects. - * @return {array} List of all object types which are executable objects. - */ - return Object.keys(currentObjects).filter(objType => types[objType].executable()) -} - -function createNewRegisteredObject(objType, args=[]) { - /** - * Creates and register an object in the database. - * @param {string} objType - Type of the object to create. - * @param {string} args - List of arguments for the objects (can be empty). - * @return {[objType]} Newly created object. - */ - if(Object.keys(types).indexOf(objType) == -1) return null // Object type does not exist. - var newobj = new types[objType](...args) - if(Object.keys(currentObjects).indexOf(objType) == -1) { - currentObjects[objType] = [] - } - currentObjects[objType].push(newobj) - currentObjectsByName[newobj.name] = newobj - return newobj -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs new file mode 100644 index 0000000..b7a2dae --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -0,0 +1,112 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { RuntimeAPI } from './runtime.mjs' + +class ObjectsAPI extends RuntimeAPI { + + constructor() { + super('Objects') + + this.types = {} + /** + * List of objects for each type of object. + * @type {Object.} + */ + this.currentObjects = {} + /** + * List of objects matched by their name. + * @type {Object.} + */ + this.currentObjectsByName = {} + } + + /** + * Renames an object from its old name to the new one. + * @param {string} oldName - Current name of the object. + * @param {string} newName - Name to rename the object to. + */ + renameObject(oldName, newName) { + let obj = this.currentObjectsByName[oldName] + delete this.currentObjectsByName[oldName] + this.currentObjectsByName[newName] = obj + obj.name = newName + } + + /** + * Deletes an object by its given name. + * @param {string} objName - Current name of the object. + */ + deleteObject(objName) { + let obj = this.currentObjectsByName[objName] + if(obj !== undefined) { + this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj),1) + obj.delete() + delete this.currentObjectsByName[objName] + } + } + + /** + * Gets a list of all names of a certain object type. + * @param {string} objType - Type of the object to query. Can be ExecutableObject for all ExecutableObjects. + * @returns {string[]} List of names of the objects. + */ + getObjectsName(objType) { + if(objType === "ExecutableObject") { + // NOTE: QMLJS does not support flatMap. + // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) + let types = this.getExecutableTypes() + let elementNames = [''] + for(let elemType of types) + elementNames = elementNames.concat(this.currentObjects[elemType].map(obj => obj.name)) + return elementNames + } + if(this.currentObjects[objType] === undefined) return [] + return this.currentObjects[objType].map(obj => obj.name) + } + + /** + * Returns a list of all object types which are executable objects. + * @return {string[]} List of all object types which are executable objects. + */ + getExecutableTypes() { + return Object.keys(this.currentObjects).filter(objType => this.types[objType].executable()) + } + + /** + * Creates and register an object in the database. + * @param {string} objType - Type of the object to create. + * @param {string[]} args - List of arguments for the objects (can be empty). + * @return {DrawableObject} Newly created object. + */ + createNewRegisteredObject(objType, args= []) { + if(Object.keys(this.types).indexOf(objType) === -1) return null // Object type does not exist. + let newobj = new this.types[objType](...args) + if(Object.keys(this.currentObjects).indexOf(objType) === -1) { + this.currentObjects[objType] = [] + } + this.currentObjects[objType].push(newobj) + this.currentObjectsByName[newobj.name] = newobj + return newobj + } +} + +/** @type {ObjectsAPI} */ +Runtime.Objects = Runtime.Objects || new ObjectsAPI() + +export default Runtime.Objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs new file mode 100644 index 0000000..c3e8f63 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -0,0 +1,42 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { API as ObjectsCommonAPI } from "common.mjs" +import Point from "point.mjs" +import Text from "text.mjs" +import Function from "function.mjs" +import GainBode from "gainbode.mjs" +import PhaseBode from "phasebode.mjs" +import SommeGainsBode from "sommegainsbode.mjs" +import SommePhasesBode from "sommephasesbode.mjs" +import XCursor from "xcursor.mjs" +import Sequence from "sequence.mjs" +import RepartitionFunction from "repartition.mjs" + +if(Object.keys(Runtime.Objects.types).length === 0) { + ObjectsCommonAPI.registerObject(Point) + ObjectsCommonAPI.registerObject(Text) + ObjectsCommonAPI.registerObject(Function) + ObjectsCommonAPI.registerObject(GainBode) + ObjectsCommonAPI.registerObject(PhaseBode) + ObjectsCommonAPI.registerObject(SommeGainsBode) + ObjectsCommonAPI.registerObject(SommePhasesBode) + ObjectsCommonAPI.registerObject(XCursor) + ObjectsCommonAPI.registerObject(Sequence) + ObjectsCommonAPI.registerObject(RepartitionFunction) +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs similarity index 77% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index bc31bac..7821037 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -16,42 +16,71 @@ * along with this program. If not, see . */ -.pragma library - -.import "../utils.js" as Utils -.import "../objects.js" as Objects -.import "../math/latex.js" as Latex -.import "../parameters.js" as P -.import "../math/common.js" as C +import { getRandomColor, textsub } from "../utils.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import {RuntimeAPI} from "../runtime.mjs" // This file contains the default data to be imported from all other objects -/** - * Creates a new name for an object, based on the \c allowedLetters. - * If variables with each of the allowedLetters is created, a subscript - * number is added to the name. - * @param {string} prefix - Prefix to the name. - * @return {string} New unused name for a new object. - */ -function getNewName(allowedLetters, prefix='') { - // Allows to get a new name, based on the allowed letters, - // as well as adding a sub number when needs be. - var newid = 0 - var ret - do { - var letter = allowedLetters[newid % allowedLetters.length] - var num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) - ret = prefix + letter + (num > 0 ? Utils.textsub(num-1) : '') - newid += 1 - } while(ret in Objects.currentObjectsByName) - return ret +class ObjectsCommonAPI extends RuntimeAPI { + + constructor() { + super('ObjectsCommon', [ + Runtime.Objects, + Runtime.ExprParser, + Runtime.Latex + ]) + } + + /** + * Creates a new name for an object, based on the \c allowedLetters. + * If variables with each of the allowedLetters is created, a subscript + * number is added to the name. + * @param {string} allowedLetters + * @param {string} prefix - Prefix to the name. + * @return {string} New unused name for a new object. + */ + getNewName(allowedLetters, prefix='') { + // Allows to get a new name, based on the allowed letters, + // as well as adding a sub number when needs be. + let newid = 0 + let ret + do { + let letter = allowedLetters[newid % allowedLetters.length] + let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) + ret = prefix + letter + (num > 0 ? textsub(num-1) : '') + newid += 1 + } while(ret in Objects.currentObjectsByName) + return ret + } + + /** + * Registers the object \c obj in the object list. + * @param {DrawableObject} obj - Object to be registered. + */ + registerObject(obj) { + // Registers an object to be used in LogarithmPlotter. + // This function is called from autoload.mjs + if(obj.prototype instanceof DrawableObject) { + if(!Objects.types[obj.type()]) + Objects.types[obj.type()] = obj + } else { + console.error("Could not register object " + (obj.type()) + ", as it isn't a DrawableObject.") + } + } } +/** @type {ObjectsCommonAPI} */ +Runtime.ObjectsCommon = Runtime.ObjectsCommon || new ObjectsCommonAPI() + +export const API = Runtime.ObjectsCommon + /** * Class to extend for every type of object that * can be drawn on the canvas. */ -class DrawableObject { +export class DrawableObject { /** * Base name of the object. Needs to be constant over time. * @return {string} Type of the object. @@ -73,7 +102,7 @@ class DrawableObject { /** * True if this object can be created by the user, false if it can only * be instantiated by other objects - * @return {bool} + * @return {boolean} */ static createable() {return true} @@ -89,30 +118,30 @@ class DrawableObject { * If the property is to be translated, the key should be passed * through the QT_TRANSLATE_NOOP macro in that form: * [QT_TRANSLATE_NOOP('prop','key')] - * Enums that are translated should be indexed in parameters.js and + * Enums that are translated should be indexed in parameters.mjs and * then be linked directly here. * - * @return {Dictionary} + * @return {Object.} */ static properties() {return {}} /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. - * @return {bool} + * @return {boolean} */ static executable() {return false} /** * Base constructor for the object. * @param {string} name - Name of the object - * @param {bool} visible - true if the object is visible, false otherwise. - * @param {color} color - Color of the object (can be string or QColor) + * @param {boolean} visible - true if the object is visible, false otherwise. + * @param {color|string} color - Color of the object (can be string or QColor) * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. * @constructor() */ constructor(name, visible = true, color = null, labelContent = 'name + value') { - if(color == null) color = Utils.getRandomColor() + if(color == null) color = getRandomColor() this.type = this.constructor.type() this.name = name this.visible = visible @@ -145,7 +174,7 @@ class DrawableObject { * Latex markuped version of the readable string. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. - * See ../latex.js for helper methods. + * See ../latex.mjs for helper methods. * @return {string} */ getLatexString() { @@ -172,7 +201,7 @@ class DrawableObject { * Latex markup string content of the label depending on the value of the \c latexContent. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. - * See ../latex.js for helper methods. + * See ../latex.mjs for helper methods. * @return {string} */ getLatexLabel() { @@ -204,25 +233,26 @@ class DrawableObject { update() { // Refreshing dependencies. for(let obj of this.requires) - obj.requiredBy = obj.requiredBy.filter(dep => dep != this) + obj.requiredBy = obj.requiredBy.filter(dep => dep !== this) // Checking objects this one depends on this.requires = [] + let currentObjectsByName = Objects.currentObjectsByName let properties = this.constructor.properties() for(let property in properties) if(typeof properties[property] == 'object' && 'type' in properties[property]) - if(properties[property].type == 'Expression' && this[property] != null) { + if(properties[property].type === 'Expression' && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { - if(objName in C.currentObjectsByName && !this.requires.includes(C.currentObjectsByName[objName])) { - this.requires.push(C.currentObjectsByName[objName]) - C.currentObjectsByName[objName].requiredBy.push(this) + if(objName in currentObjectsByName && !this.requires.includes(currentObjectsByName[objName])) { + this.requires.push(currentObjectsByName[objName]) + currentObjectsByName[objName].requiredBy.push(this) } } if(this[property].cached && this[property].requiredObjects().length > 0) // Recalculate this[property].recache() - } else if(properties[property].type == 'ObjectType' && this[property] != null) { + } else if(properties[property].type === 'ObjectType' && this[property] != null) { // Object dependency this.requires.push(this[property]) this[property].requiredBy.push(this) @@ -239,12 +269,16 @@ class DrawableObject { for(let toRemove of this.requiredBy) { // Normally, there should be none here, but better leave nothing just in case. Objects.deleteObject(toRemove.name) } + console.log(this.requires) + for(let toRemoveFrom of this.requires) { + toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this) + } } /** * Abstract method. Draw the object onto the \c canvas with the 2D context \c ctx. * @param {Canvas} canvas - * @param {Context2D} ctx + * @param {CanvasRenderingContext2D} ctx */ draw(canvas, ctx) {} @@ -256,7 +290,7 @@ class DrawableObject { * * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} offset - Margin between the position and the object to be drawn - * @param {Dictionary} size - Size of the label item, containing two properties, "width" and "height" + * @param {Object.} size - Size of the label item, containing two properties, "width" and "height" * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label @@ -310,17 +344,17 @@ class DrawableObject { * \c drawFunctionText (x,y,text) depending on whether to use latex. * * @param {Canvas} canvas - * @param {Context2D} ctx + * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis - * @param {bool} forceText - Force the rendering of the label as text + * @param {boolean} forceText - Force the rendering of the label as text * @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed * @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ - drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false, + drawLabel(canvas, ctx, labelPosition, posX, posY,forceText = false, getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { // Default functions if(getLatexFunction == null) @@ -333,7 +367,7 @@ class DrawableObject { drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height) // Positioned from left bottom // Drawing the label let offset - if(!forceText && Latex.enabled) { // TODO: Check for user setting with Latex. + if(!forceText && Latex.enabled) { // With latex let drawLblCb = function(canvas, ctx, ltxImg) { this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) @@ -355,6 +389,7 @@ class DrawableObject { } } + /** * Class to be extended for every object on which * an y for a x can be computed with the execute function. @@ -362,7 +397,7 @@ class DrawableObject { * return null. However, theses same x values will * return false when passed to canExecute. */ -class ExecutableObject extends DrawableObject { +export class ExecutableObject extends DrawableObject { /** * Returns the corresponding y value for an x value. * If the object isn't defined on the given x, then @@ -376,38 +411,25 @@ class ExecutableObject extends DrawableObject { * Returns false if the object isn't defined on the given x, true otherwise. * * @param {number} x - * @returns {bool} + * @returns {boolean} */ canExecute(x = 1) {return true} /** * Returns the simplified expression string for a given x. * * @param {number} x - * @returns {bool} + * @returns {string} */ simplify(x = 1) {return '0'} - /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. - * @return {bool} + * @return {boolean} */ static executable() {return true} } -/** - * Registers the object \c obj in the object list. - * @param {DrawableObject} obj - Object to be registered. - */ -function registerObject(obj) { - // Registers an object to be used in LogarithmPlotter. - // This function is called from autoload.js - if(obj.prototype instanceof DrawableObject) { - Objects.types[obj.type()] = obj - } else { - console.error("Could not register object " + (obj.type()) + ", as it isn't a DrawableObject.") - } -} + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs similarity index 90% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index aa43a08..1a52dba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../utils.js" as Utils -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { textsub } from "../utils.mjs" +import { API as Common, ExecutableObject } from "common.mjs" +import { parseDomain, Expression, SpecialDomain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -class Function extends Common.ExecutableObject { +export default class Function extends ExecutableObject { static type(){return 'Function'} static displayType(){return qsTr('Function')} static displayTypeMultiple(){return qsTr('Functions')} @@ -54,11 +52,11 @@ class Function extends Common.ExecutableObject { drawPoints = true, drawDashedLines = true) { if(name == null) name = Common.getNewName('fghjqlmnopqrstuvwabcde') super(name, visible, color, labelContent) - if(typeof expression == 'number' || typeof expression == 'string') expression = new MathLib.Expression(expression.toString()) + if(typeof expression == 'number' || typeof expression == 'string') expression = new Expression(expression.toString()) this.expression = expression - if(typeof definitionDomain == 'string') definitionDomain = MathLib.parseDomain(definitionDomain) + if(typeof definitionDomain == 'string') definitionDomain = parseDomain(definitionDomain) this.definitionDomain = definitionDomain - if(typeof destinationDomain == 'string') destinationDomain = MathLib.parseDomain(destinationDomain) + if(typeof destinationDomain == 'string') destinationDomain = parseDomain(destinationDomain) this.destinationDomain = destinationDomain this.displayMode = displayMode this.labelPosition = labelPosition @@ -68,15 +66,15 @@ class Function extends Common.ExecutableObject { } getReadableString() { - if(this.displayMode == 'application') { + if(this.displayMode === 'application') { return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⟼ ${this.expression.toString()}` } else { - return `${this.name}(x) = ${this.expression.toString()}\nD${Utils.textsub(this.name)} = ${this.definitionDomain}` + return `${this.name}(x) = ${this.expression.toString()}\nD${textsub(this.name)} = ${this.definitionDomain}` } } getLatexString() { - if(this.displayMode == 'application') { + if(this.displayMode === 'application') { return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { @@ -111,14 +109,16 @@ class Function extends Common.ExecutableObject { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } - + + /** + * Reusable in other objects. + * Drawing small traits every few pixels + */ static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { - // Reusable in other objects. - // Drawing small traits every 0.2px - var pxprecision = 10 - var previousX = canvas.px2x(0) - var previousY = null; - if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) { + let pxprecision = 10 + let previousX = canvas.px2x(0) + let previousY = null; + if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) { // Point based functions. previousX = definitionDomain.next(previousX) if(previousX === null) previousX = definitionDomain.next(canvas.px2x(0)) @@ -126,8 +126,8 @@ class Function extends Common.ExecutableObject { if(!drawPoints && !drawDash) return while(previousX !== null && canvas.x2px(previousX) < canvas.canvasSize.width) { // Reconverted for canvas to fix for logarithmic scales. - var currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); - var currentY = expr.execute(currentX) + let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); + let currentY = expr.execute(currentX) if(currentX === null) break; if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && (destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) { @@ -173,7 +173,7 @@ class Function extends Common.ExecutableObject { do { tmpPx--; currentX = canvas.px2x(tmpPx) - } while(!definitionDomain.includes(currentX) && currentX != previousX) + } while(!definitionDomain.includes(currentX) && currentX !== previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.canvasSize.height)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs similarity index 67% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index 9604656..696084d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -16,19 +16,19 @@ * along with this program. If not, see . */ -.pragma library +import { parseDomain, executeExpression, Expression, EmptySet, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../objects.js" as Objects -.import "../utils.js" as Utils -.import "../mathlib.js" as MathLib -.import "../historylib.js" as HistoryLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import Function from "function.mjs" + +import { API as HistoryAPI } from "../history/common.mjs" +import { CreateNewObject } from "../historylib.mjs" -class GainBode extends Common.ExecutableObject { +export default class GainBode extends ExecutableObject { static type(){return 'Gain Bode'} static displayType(){return qsTr('Bode Magnitude')} static displayTypeMultiple(){return qsTr('Bode Magnitudes')} @@ -44,7 +44,7 @@ class GainBode extends Common.ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { if(name == null) name = Common.getNewName('G') - if(name == 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). + if(name === 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). super(name, visible, color, labelContent) if(typeof om_0 == "string") { // Point name or create one @@ -52,7 +52,7 @@ class GainBode extends Common.ExecutableObject { if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) - HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' } @@ -60,7 +60,7 @@ class GainBode extends Common.ExecutableObject { } this.om_0 = om_0 this.pass = pass - if(typeof gain == 'number' || typeof gain == 'string') gain = new MathLib.Expression(gain.toString()) + if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString()) this.gain = gain this.labelPosition = labelPosition this.labelX = labelX @@ -68,12 +68,12 @@ class GainBode extends Common.ExecutableObject { } getReadableString() { - let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec` } getLatexString() { - let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} \\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ ${this.gain.latexMarkup}\\textsf{ dB/dec} @@ -86,9 +86,9 @@ class GainBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) - if((this.pass == 'high' && x < this.om_0.x) || (this.pass == 'low' && x > this.om_0.x)) { - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) + if(typeof x == 'string') x = executeExpression(x) + if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) { + let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.execute(x) } else { return this.om_0.y.execute() @@ -96,10 +96,10 @@ class GainBode extends Common.ExecutableObject { } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) - if((this.pass == 'high' && xval < this.om_0.x) || (this.pass == 'low' && xval > this.om_0.x)) { - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) + let xval = x + if(typeof x == 'string') xval = executeExpression(x) + if((this.pass === 'high' && xval < this.om_0.x) || (this.pass === 'low' && xval > this.om_0.x)) { + let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.simplify(x) } else { return this.om_0.y.toString() @@ -111,20 +111,20 @@ class GainBode extends Common.ExecutableObject { } draw(canvas, ctx) { - var base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) - var inDrawDom = new MathLib.EmptySet() + let base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] + let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) + let inDrawDom = new EmptySet() - if(this.pass == 'high') { - // High pass, linear line from begining, then constant to the end. + if(this.pass === 'high') { + // High pass, linear line from beginning, then constant to the end. canvas.drawLine(ctx, base[0], base[1], canvas.canvasSize.width, base[1]) - inDrawDom = MathLib.parseDomain(`]-inf;${this.om_0.x}[`) + inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`) } else { // Low pass, constant from the beginning, linear line to the end. canvas.drawLine(ctx, base[0], base[1], 0, base[1]) - inDrawDom = MathLib.parseDomain(`]${this.om_0.x};+inf[`) + inDrawDom = parseDomain(`]${this.om_0.x};+inf[`) } - F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) + Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) // Dashed line representing break in function var xpos = canvas.x2px(this.om_0.x.execute()) var dashPxSize = 10 @@ -137,7 +137,7 @@ class GainBode extends Common.ExecutableObject { update() { super.update() - if(Objects.currentObjects['Somme gains Bode'] != undefined && Objects.currentObjects['Somme gains Bode'].length > 0) { + if(Objects.currentObjects['Somme gains Bode'] !== undefined && Objects.currentObjects['Somme gains Bode'].length > 0) { Objects.currentObjects['Somme gains Bode'][0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme gains Bode') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs similarity index 76% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index edf9d68..14ff351 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -16,17 +16,17 @@ * along with this program. If not, see . */ -.pragma library +import { executeExpression, Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../historylib.js" as HistoryLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import { API as HistoryAPI } from "../history/common.mjs" +import { CreateNewObject } from "../historylib.mjs" -class PhaseBode extends Common.ExecutableObject { +export default class PhaseBode extends ExecutableObject { static type(){return 'Phase Bode'} static displayType(){return qsTr('Bode Phase')} static displayTypeMultiple(){return qsTr('Bode Phases')} @@ -41,9 +41,9 @@ class PhaseBode extends Common.ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) { if(name == null) name = Common.getNewName('φ') - if(name == 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). + if(name === 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). super(name, visible, color, labelContent) - if(typeof phase == 'number' || typeof phase == 'string') phase = new MathLib.Expression(phase.toString()) + if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString()) this.phase = phase if(typeof om_0 == "string") { // Point name or create one @@ -52,7 +52,7 @@ class PhaseBode extends Common.ExecutableObject { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), this.color, 'name']) om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' - HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' } om_0.requiredBy.push(this) @@ -77,7 +77,7 @@ class PhaseBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x < this.om_0.x) { return this.om_0.y.execute() } else { @@ -86,13 +86,13 @@ class PhaseBode extends Common.ExecutableObject { } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) + let xval = x + if(typeof x == 'string') xval = executeExpression(x) if(xval < this.om_0.x) { return this.om_0.y.toString() } else { - var newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() - return (new MathLib.Expression(newExp)).toString() + let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() + return (new Expression(newExp)).toString() } } @@ -101,11 +101,11 @@ class PhaseBode extends Common.ExecutableObject { } draw(canvas, ctx) { - var baseX = canvas.x2px(this.om_0.x.execute()) - var omy = this.om_0.y.execute() - var augmt = this.phase.execute() - var baseY = canvas.y2px(omy) - var augmtY = canvas.y2px(omy+augmt) + let baseX = canvas.x2px(this.om_0.x.execute()) + let omy = this.om_0.y.execute() + let augmt = this.phase.execute() + let baseY = canvas.y2px(omy) + let augmtY = canvas.y2px(omy+augmt) // Before change line. canvas.drawLine(ctx, 0, baseY, Math.min(baseX, canvas.canvasSize.height), baseY) // Transition line. @@ -118,7 +118,7 @@ class PhaseBode extends Common.ExecutableObject { } update() { - if(Objects.currentObjects['Somme phases Bode'] != undefined && Objects.currentObjects['Somme phases Bode'].length > 0) { + if(Objects.currentObjects['Somme phases Bode'] !== undefined && Objects.currentObjects['Somme phases Bode'].length > 0) { Objects.currentObjects['Somme phases Bode'][0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme phases Bode') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs similarity index 91% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index effdee1..d03053d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -16,15 +16,13 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" +import { API as Common, DrawableObject } from "common.mjs" -class Point extends Common.DrawableObject { +export default class Point extends DrawableObject { static type(){return 'Point'} static displayType(){return qsTr('Point')} static displayTypeMultiple(){return qsTr('Points')} @@ -40,9 +38,9 @@ class Point extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'above', pointStyle = '●') { if(name == null) name = Common.getNewName('ABCDEFJKLMNOPQRSTUVW') super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) + if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.pointStyle = pointStyle diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index e872876..32105d1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -16,14 +16,12 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -class RepartitionFunction extends Common.ExecutableObject { +export default class RepartitionFunction extends ExecutableObject { static type(){return 'Repartition'} static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} @@ -34,7 +32,7 @@ class RepartitionFunction extends Common.ExecutableObject { 'comment', 'Note: Specify the probability for each value.' ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d\.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), }} constructor(name = null, visible = true, color = null, labelContent = 'name + value', @@ -69,7 +67,7 @@ class RepartitionFunction extends Common.ExecutableObject { } execute(x = 1) { - var ret = 0; + let ret = 0; Object.keys(this.probabilities).sort((a,b) => a-b).forEach(idx => { if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, '.')) }) @@ -77,6 +75,7 @@ class RepartitionFunction extends Common.ExecutableObject { } canExecute(x = 1) {return true} + // Simplify returns the simplified string of the expression. simplify(x = 1) { return this.execute(x) @@ -94,8 +93,8 @@ class RepartitionFunction extends Common.ExecutableObject { } draw(canvas, ctx) { - var currentY = 0; - var keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) + let currentY = 0; + let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { canvas.drawLine(ctx, 0, @@ -109,8 +108,8 @@ class RepartitionFunction extends Common.ExecutableObject { ctx.stroke(); } } - for(var i = 0; i < keys.length-1; i++) { - var idx = keys[i]; + for(let i = 0; i < keys.length-1; i++) { + let idx = keys[i]; currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { canvas.drawLine(ctx, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs similarity index 78% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index c08aac8..4e06b56 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -16,16 +16,15 @@ * along with this program. If not, see . */ -.pragma library +import { Sequence as MathSequence, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import Function from "function.mjs" -class Sequence extends Common.ExecutableObject { +export default class Sequence extends ExecutableObject { static type(){return 'Sequence'} static displayType(){return qsTr('Sequence')} static displayTypeMultiple(){return qsTr('Sequences')} @@ -59,18 +58,21 @@ class Sequence extends Common.ExecutableObject { export() { return [this.name, this.visible, this.color.toString(), this.labelContent, - this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, this.labelPosition, this.labelX] + this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, + this.labelPosition, this.labelX] } update() { + console.log('Updating sequence', this.sequence) + console.trace() super.update() if( - this.sequence == null || this.baseValues != this.sequence.baseValues || - this.sequence.name != this.name || - this.sequence.expr != Object.values(this.defaultExpression)[0] || - this.sequence.valuePlus != Object.keys(this.defaultExpression)[0] + this.sequence == null || this.baseValues !== this.sequence.baseValues || + this.sequence.name !== this.name || + this.sequence.expr !== Object.values(this.defaultExpression)[0] || + this.sequence.valuePlus !== Object.keys(this.defaultExpression)[0] ) - this.sequence = new MathLib.Sequence( + this.sequence = new MathSequence( this.name, this.baseValues, Object.keys(this.defaultExpression)[0], Object.values(this.defaultExpression)[0] @@ -86,15 +88,15 @@ class Sequence extends Common.ExecutableObject { } execute(x = 1) { - if(x % 1 == 0) + if(x % 1 === 0) return this.sequence.execute(x) return null } - canExecute(x = 1) {return x%1 == 0} + canExecute(x = 1) {return x%1 === 0} // Simplify returns the simplified string of the expression. simplify(x = 1) { - if(x % 1 == 0) + if(x % 1 === 0) return this.sequence.simplify(x) return null } @@ -122,7 +124,7 @@ class Sequence extends Common.ExecutableObject { } draw(canvas, ctx) { - F.Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? MathLib.Domain.NE : MathLib.Domain.N, MathLib.Domain.R, this.drawPoints, this.drawDashedLines) + Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs similarity index 72% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index f8b3fee..e03ca81 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -16,17 +16,16 @@ * along with this program. If not, see . */ -.pragma library +import { parseDomain, Expression, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { ExecutableObject } from "common.mjs" +import Function from "function.mjs" -class SommeGainsBode extends Common.ExecutableObject { +export default class SommeGainsBode extends ExecutableObject { static type(){return 'Somme gains Bode'} static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} @@ -58,7 +57,7 @@ class SommeGainsBode extends Common.ExecutableObject { } execute(x = 0) { - for(var [dbfn, inDrawDom] of this.cachedParts) { + for(let [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { return dbfn.execute(x) } @@ -71,7 +70,7 @@ class SommeGainsBode extends Common.ExecutableObject { } simplify(x = 1) { - for(var [dbfn, inDrawDom] of this.cachedParts) { + for(let [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { return dbfn.simplify(x) } @@ -82,33 +81,33 @@ class SommeGainsBode extends Common.ExecutableObject { recalculateCache() { this.cachedParts = [] // Calculating this is fairly resource expansive so it's cached. - if(Objects.currentObjects['Gain Bode'] != undefined) { + if(Objects.currentObjects['Gain Bode'] !== undefined) { console.log('Recalculating cache gain') // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - var drawMin = 0.001 + let drawMin = 0.001 - var baseY = 0 - var om0xGains = {1000000000: 0} // To draw the last part - var om0xPass = {1000000000: 'high'} // To draw the last part + let baseY = 0 + let om0xGains = {1000000000: 0} // To draw the last part + let om0xPass = {1000000000: 'high'} // To draw the last part Objects.currentObjects['Gain Bode'].forEach(function(gainObj) { // Sorting by their om_0 position. - var om0x = gainObj.om_0.x.execute() - if(om0xGains[om0x] == undefined) { + let om0x = gainObj.om_0.x.execute() + if(om0xGains[om0x] === undefined) { om0xGains[om0x] = gainObj.gain.execute() - om0xPass[om0x] = gainObj.pass == 'high' + om0xPass[om0x] = gainObj.pass === 'high' } else { om0xGains[om0x+0.001] = gainObj.gain.execute() - om0xPass[om0x+0.001] = gainObj.pass == 'high' + om0xPass[om0x+0.001] = gainObj.pass === 'high' } baseY += gainObj.execute(drawMin) }) // Sorting the om_0x - var om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... + let om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... om0xList.sort((a,b) => a - b) // Adding the total gains. - var gainsBeforeP = [] - var gainsAfterP = [] - var gainTotal = 0 - for(var om0x of om0xList){ + let gainsBeforeP = [] + let gainsAfterP = [] + let gainTotal = 0 + for(let om0x of om0xList){ if(om0xPass[om0x]) { // High-pass gainsBeforeP.push(om0xGains[om0x]) gainsAfterP.push(0) @@ -119,10 +118,10 @@ class SommeGainsBode extends Common.ExecutableObject { } } // Calculating parts - var previousPallier = drawMin - for(var pallier = 0; pallier < om0xList.length; pallier++) { - var dbfn = new MathLib.Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) - var inDrawDom = MathLib.parseDomain(`]${previousPallier};${om0xList[pallier]}]`) + let previousPallier = drawMin + for(let pallier = 0; pallier < om0xList.length; pallier++) { + let dbfn = new Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) + let inDrawDom = parseDomain(`]${previousPallier};${om0xList[pallier]}]`) this.cachedParts.push([dbfn, inDrawDom]) previousPallier = om0xList[pallier] baseY = dbfn.execute(om0xList[pallier]) @@ -133,8 +132,8 @@ class SommeGainsBode extends Common.ExecutableObject { draw(canvas, ctx) { if(this.cachedParts.length > 0) { - for(var [dbfn, inDrawDom] of this.cachedParts) { - F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) + for(let [dbfn, inDrawDom] of this.cachedParts) { + Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) if(inDrawDom.includes(this.labelX)) { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs similarity index 74% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index eb1c3e0..328c069 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import { executeExpression, Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { ExecutableObject } from "common.mjs" - -class SommePhasesBode extends Common.ExecutableObject { +export default class SommePhasesBode extends ExecutableObject { static type(){return 'Somme phases Bode'} static displayType(){return qsTr('Bode Phases Sum')} static displayTypeMultiple(){return qsTr('Bode Phases Sum')} @@ -57,18 +55,18 @@ class SommePhasesBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) - for(var i = 0; i < this.om0xList.length-1; i++) { + if(typeof x == 'string') x = executeExpression(x) + for(let i = 0; i < this.om0xList.length-1; i++) { if(x >= this.om0xList[i] && x < this.om0xList[i+1]) return this.phasesList[i] } } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) - for(var i = 0; i < this.om0xList.length-1; i++) { + let xval = x + if(typeof x == 'string') xval = executeExpression(x) + for(let i = 0; i < this.om0xList.length-1; i++) { if(xval >= this.om0xList[i] && xval < this.om0xList[i+1]) { - return (new MathLib.Expression(this.phasesExprList[i])).simplify() + return (new Expression(this.phasesExprList[i])).simplify() } } return '0' @@ -80,20 +78,20 @@ class SommePhasesBode extends Common.ExecutableObject { recalculateCache() { // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - var drawMin = 0.001 - var drawMax = 100000 + let drawMin = 0.001 + let drawMax = 100000 this.om0xList = [drawMin, drawMax] this.phasesList = [0] this.phasesExprList = ['0'] - var phasesDict = {} - var phasesExprDict = {} + let phasesDict = {} + let phasesExprDict = {} phasesDict[drawMax] = 0 - if(Objects.currentObjects['Phase Bode'] != undefined) { + if(Objects.currentObjects['Phase Bode'] !== undefined) { console.log('Recalculating cache phase') - for(var obj of Objects.currentObjects['Phase Bode']) { + for(let obj of Objects.currentObjects['Phase Bode']) { this.om0xList.push(obj.om_0.x.execute()) - if(phasesDict[obj.om_0.x.execute()] == undefined) { + if(phasesDict[obj.om_0.x.execute()] === undefined) { phasesDict[obj.om_0.x.execute()] = obj.phase.execute() phasesExprDict[obj.om_0.x.execute()] = obj.phase.toEditableString() } else { @@ -104,8 +102,8 @@ class SommePhasesBode extends Common.ExecutableObject { this.phasesExprList[0] += '+' + obj.om_0.y.toEditableString() } this.om0xList.sort((a,b) => a - b) - var totalAdded = this.phasesList[0] - for(var i = 1; i < this.om0xList.length; i++) { + let totalAdded = this.phasesList[0] + for(let i = 1; i < this.om0xList.length; i++) { this.phasesList[i] = this.phasesList[i-1] + phasesDict[this.om0xList[i]] this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict[this.om0xList[i]] } @@ -113,11 +111,11 @@ class SommePhasesBode extends Common.ExecutableObject { } draw(canvas, ctx) { - for(var i = 0; i < this.om0xList.length-1; i++) { - var om0xBegin = canvas.x2px(this.om0xList[i]) - var om0xEnd = canvas.x2px(this.om0xList[i+1]) - var baseY = canvas.y2px(this.phasesList[i]) - var nextY = canvas.y2px(this.phasesList[i+1]) + for(let i = 0; i < this.om0xList.length-1; i++) { + let om0xBegin = canvas.x2px(this.om0xList[i]) + let om0xEnd = canvas.x2px(this.om0xList[i+1]) + let baseY = canvas.y2px(this.phasesList[i]) + let nextY = canvas.y2px(this.phasesList[i+1]) canvas.drawLine(ctx, om0xBegin, baseY, om0xEnd, baseY) canvas.drawLine(ctx, om0xEnd, baseY, om0xEnd, nextY) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index b513ea2..040e7bd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, DrawableObject } from "common.mjs" - -class Text extends Common.DrawableObject { +export default class Text extends DrawableObject { static type(){return 'Text'} static displayType(){return qsTr('Text')} static displayTypeMultiple(){return qsTr('Texts')} @@ -45,9 +43,9 @@ class Text extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { if(name == null) name = Common.getNewName('t') super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) + if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.text = text diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs similarity index 95% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index cea2864..036c408 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -16,17 +16,15 @@ * along with this program. If not, see . */ -.pragma library +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" +import Objects from "../objects.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, DrawableObject } from "common.mjs" - -class XCursor extends Common.DrawableObject { +export default class XCursor extends DrawableObject { static type(){return 'X Cursor'} static displayType(){return qsTr('X Cursor')} static displayTypeMultiple(){return qsTr('X Cursors')} @@ -51,7 +49,7 @@ class XCursor extends Common.DrawableObject { super(name, visible, color, labelContent) this.approximate = approximate this.rounding = rounding - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x this.targetElement = targetElement if(typeof targetElement == "string") { @@ -171,7 +169,7 @@ class XCursor extends Common.DrawableObject { (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) // Drawing label at the position of the target element. - if(this.targetValuePosition == 'Next to target' && this.targetElement != null) { + if(this.targetValuePosition === 'Next to target' && this.targetElement != null) { let ypos = canvas.y2px(this.targetElement.execute(this.x.execute())) this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs similarity index 96% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 2ef194a..2cf28a3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -class Expression { +export class Expression { constructor(...variables) { this.type = 'Expression' this.variables = variables @@ -27,7 +27,7 @@ class Expression { } } -class Enum { +export class Enum { constructor(...values) { this.type = 'Enum' this.values = values @@ -39,7 +39,7 @@ class Enum { } } -class ObjectType { +export class ObjectType { constructor(objType) { this.type = 'ObjectType' this.objType = objType @@ -50,7 +50,7 @@ class ObjectType { } } -class List { +export class List { constructor(type, format = /^.+$/, label = '', forbidAdding = false) { // type can be string, int and double. this.type = 'List' @@ -65,7 +65,7 @@ class List { } } -class Dictionary { +export class Dictionary { constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { // type & keyType can be string, int and double. this.type = 'Dict' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md index a0ff7e7..8fa8a93 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md @@ -2,4 +2,4 @@ Here lies the potential new, abandoned, cleaner implementation of the parsing system that was supposed to replace expr-eval.js, but never came to be because it's unfinished. If somebody has the will to finish this, you're welcome to try, as I won't. -Currently, the tokenizer is complete in use to provide tokens for the syntax highlighting. +Currently, the tokenizer is complete in use to provide tokens for the syntax highlighting, and the reference to provide usage. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs index 53a5941..3313a1b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -.pragma library -class InputExpression { +export default class InputExpression { constructor(expression) { this.position = 0; this.input = expression; @@ -33,7 +32,7 @@ class InputExpression { } skip(char) { - if(!this.atEnd() && this.peek() == char) { + if(!this.atEnd() && this.peek() === char) { this.position++; } else { this.raise("Unexpected character " + this.peek() + ". Expected character " + char); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs similarity index 60% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs index b2cc6bc..71d34d1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs @@ -16,19 +16,17 @@ * along with this program. If not, see . */ -.pragma library +import * as Reference from "reference.mjs" +import * as T from "./tokenizer.mjs" +import InputExpression from "common.mjs" -.import "reference.js" as Reference -.import "tokenizer.js" as TK -.import "common.js" as Common +export const Input = InputExpression +export const TokenType = T.TokenType +export const Token = T.Token +export const Tokenizer = T.ExpressionTokenizer -var Input = Common.InputExpression -var TokenType = TK.TokenType -var Token = TK.Token -var Tokenizer = TK.ExpressionTokenizer - -var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST -var FUNCTIONS = Reference.FUNCTIONS -var FUNCTIONS_USAGE = Reference.FUNCTIONS_USAGE -var CONSTANTS_LIST = Reference.CONSTANTS_LIST -var CONSTANTS = Reference.CONSTANTS +export const FUNCTIONS_LIST = Reference.FUNCTIONS_LIST +export const FUNCTIONS = Reference.FUNCTIONS +export const FUNCTIONS_USAGE = Reference.FUNCTIONS_USAGE +export const CONSTANTS_LIST = Reference.CONSTANTS_LIST +export const CONSTANTS = Reference.CONSTANTS diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs similarity index 88% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs index df880c5..ac845ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs @@ -17,10 +17,7 @@ */ // Contains polyfill math functions used for reference. - -.pragma library - -function factorial(x) { +export function factorial(x) { if (x < 0) // Integrating by less than 0 if(isFinite(n)) return Infinity @@ -43,7 +40,7 @@ let GAMMA_P = [ 0.36899182659531622704e-5 ] -function gamma(n) { +export function gamma(n) { if(n <= 0) // Integrating by less than 0 if(isFinite(n)) return Infinity @@ -91,7 +88,7 @@ function gamma(n) { return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x } -function arrayMap(f, arr) { +export function arrayMap(f, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')) if (!Array.isArray(arr)) @@ -99,7 +96,7 @@ function arrayMap(f, arr) { return arr.map(f) } -function arrayFold(f, init, arr) { +export function arrayFold(f, init, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')) if (!Array.isArray(arr)) @@ -107,7 +104,7 @@ function arrayFold(f, init, arr) { return arr.reduce(f, init) } -function arrayFilter(f, arr) { +export function arrayFilter(f, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) if (!Array.isArray(arr)) @@ -115,21 +112,13 @@ function arrayFilter(f, arr) { return arr.filter(f) } -function arrayFilter(f, arr) { - if (typeof f != 'function') - throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) - if (!Array.isArray(arr)) - throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')) - return arr.filter(f) -} - -function arrayJoin(sep, arr) { +export function arrayJoin(sep, arr) { if (!Array.isArray(arr)) throw new Error(qsTranslate('error', 'Second argument to join is not an array.')) return arr.join(sep) } -function indexOf(target, s) { +export function indexOf(target, s) { if (!(Array.isArray(s) || typeof s === 'string')) throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')) return s.indexOf(target) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs similarity index 91% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs index 5d1cb9f..d6ce9dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -.pragma library +import * as Polyfill from "polyfill.mjs" -.import "polyfill.js" as Polyfill - - -const CONSTANTS = { +export const CONSTANTS = { "π": Math.PI, "pi": Math.PI, "inf": Infinity, @@ -29,9 +26,9 @@ const CONSTANTS = { "∞": Infinity, "e": Math.E }; -const CONSTANTS_LIST = Object.keys(CONSTANTS); +export const CONSTANTS_LIST = Object.keys(CONSTANTS); -const FUNCTIONS = { +export const FUNCTIONS = { // The functions commented are the one either not implemented // in the parser, or not to be used for autocompletion. // Unary operators @@ -94,9 +91,9 @@ const FUNCTIONS = { 'integral': () => 0, // TODO: Implement 'derivative': () => 0, } -const FUNCTIONS_LIST = Object.keys(FUNCTIONS); +export const FUNCTIONS_LIST = Object.keys(FUNCTIONS); -class P { +export class P { // Parameter class. constructor(type, name = '', optional = false, multipleAllowed = false) { this.name = name @@ -107,7 +104,7 @@ class P { toString() { let base_string = this.type - if(this.name != '') + if(this.name !== '') base_string = `${this.name}: ${base_string}` if(this.multipleAllowed) base_string += '...' @@ -119,12 +116,12 @@ class P { } } -let string = new P('string') -let bool = new P('bool') -let number = new P('number') -let array = new P('array') +export let string = new P('string') +export let bool = new P('bool') +export let number = new P('number') +export let array = new P('array') -const FUNCTIONS_USAGE = { +export const FUNCTIONS_USAGE = { 'length': [string], 'not': [bool], // Math functions diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs similarity index 84% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs index 9a907fa..bad6e7e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs @@ -16,18 +16,17 @@ * along with this program. If not, see . */ -.pragma library -.import "reference.js" as Reference +import * as Reference from "reference.mjs" const WHITESPACES = " \t\n\r" -const STRING_LIMITORS = '"\'`'; +const STRING_LIMITERS = '"\'`'; const OPERATORS = "+-*/^%?:=!><"; -const PUNCTUTATION = "()[]{},."; +const PUNCTUATION = "()[]{},."; const NUMBER_CHARS = "0123456789" const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ" -var TokenType = { +export const TokenType = { // Expression type "WHITESPACE": "WHITESPACE", "VARIABLE": "VARIABLE", @@ -40,7 +39,7 @@ var TokenType = { "UNKNOWN": "UNKNOWN" } -class Token { +export class Token { constructor(type, value, startPosition) { this.type = type; this.value = value; @@ -48,7 +47,13 @@ class Token { } } -class ExpressionTokenizer { +export class ExpressionTokenizer { + /** + * + * @param {InputExpression} input + * @param {boolean} tokenizeWhitespaces + * @param {boolean} errorOnUnknown + */ constructor(input, tokenizeWhitespaces = false, errorOnUnknown = true) { this.input = input; this.currentToken = null; @@ -71,12 +76,12 @@ class ExpressionTokenizer { readString() { let delimitation = this.input.peek(); - if(STRING_LIMITORS.includes(delimitation)) { + if(STRING_LIMITERS.includes(delimitation)) { this.input.skip(delimitation) let included = ""; let justEscaped = false; - while(!this.input.atEnd() && (!STRING_LIMITORS.includes(this.input.peek()) || justEscaped)) { - justEscaped = this.input.peek() == "\\" + while(!this.input.atEnd() && (!STRING_LIMITERS.includes(this.input.peek()) || justEscaped)) { + justEscaped = this.input.peek() === "\\" if(!justEscaped) included += this.input.next(); } @@ -92,8 +97,8 @@ class ExpressionTokenizer { readNumber() { let included = ""; let hasDot = false; - while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() == '.')) { - if(this.input.peek() == ".") { + while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === '.')) { + if(this.input.peek() === ".") { if(hasDot) this.input.raise("Unexpected '.'. Expected digit") hasDot = true; } @@ -130,14 +135,14 @@ class ExpressionTokenizer { if(this.input.atEnd()) return null; let c = this.input.peek(); if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces(); - if(STRING_LIMITORS.includes(c)) return this.readString(); + if(STRING_LIMITERS.includes(c)) return this.readString(); if(NUMBER_CHARS.includes(c)) return this.readNumber(); if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier(); if(OPERATORS.includes(c)) return this.readOperator(); if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position-1); - if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); + if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); if(this.errorOnUnknown) - this.input.throw("Unknown token character " + c) + this.input.raise("Unknown token character " + c) else return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position-1); } @@ -163,7 +168,7 @@ class ExpressionTokenizer { skip(type) { let next = this.next(); - if(next.type != type) - input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); + if(next.type !== type) + this.input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs new file mode 100644 index 0000000..0d859aa --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs @@ -0,0 +1,45 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * Base class for global APIs in runtime. + */ +export class RuntimeAPI { + + /** + * + * @param {string} name - Name of the API + * @param {(RuntimeAPI|undefined)[]} requires - List of APIs required to initialize this one. + */ + constructor(name, requires = []) { + console.log(`Loading module ${name}...`) + this.__check_requirements(requires, name) + } + + /** + * Checks if all requirements are defined. + * @param {(RuntimeAPI|undefined)[]} requires + * @param {string} name + */ + __check_requirements(requires, name) { + for(let requirement of requires) { + if(requirement === undefined) + throw new Error(`Requirement ${requires.indexOf(requirement)} of ${name} has not been initialized.`) + } + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs similarity index 75% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs index 0b62f8f..162e751 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs @@ -1,24 +1,22 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -.pragma library - -var powerpos = { +const powerpos = { "-": "⁻", "+": "⁺", "=": "⁼", @@ -62,12 +60,13 @@ var powerpos = { "z": "ᶻ" } -var exponents = [ +const exponents = [ "⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹" ] -var exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') -var indicepos = { +const exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') + +const indicepos = { "-": "₋", "+": "₊", "=": "₌", @@ -103,10 +102,10 @@ var indicepos = { "x": "ₓ", } // Put a text in sup position -function textsup(text) { - var ret = "" +export function textsup(text) { + let ret = "" text = text.toString() - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { if(Object.keys(powerpos).indexOf(text[i]) >= 0) { ret += powerpos[text[i]] } else { @@ -117,10 +116,10 @@ function textsup(text) { } // Put a text in sub position -function textsub(text) { - var ret = "" +export function textsub(text) { + let ret = "" text = text.toString() - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { if(Object.keys(indicepos).indexOf(text[i]) >= 0) { ret += indicepos[text[i]] } else { @@ -130,8 +129,13 @@ function textsub(text) { return ret } -function simplifyExpression(str) { - var replacements = [ +/** + * Simplifies (mathematically) a mathematical expression. + * @param {string} str - Expression to parse + * @returns {string} + */ +export function simplifyExpression(str) { + let replacements = [ // Operations not done by parser. // [// Decomposition way 2 // /(^|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)($| [+-]|\))/g, @@ -149,16 +153,16 @@ function simplifyExpression(str) { // n1 & n3 are multiplied, opeM is the main operation (- or +). // Putting all n in form of number //n2 = n2 == undefined ? 1 : parseFloat(n) - n1 = m1 == undefined ? 1 : eval(m1 + '1') - n2 = m2 == undefined ? 1 : eval('1' + m2) - n3 = m3 == undefined ? 1 : eval(m3 + '1') - n4 = m4 == undefined ? 1 : eval('1' + m4) - //var [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) + n1 = m1 === undefined ? 1 : eval(m1 + '1') + n2 = m2 === undefined ? 1 : eval('1' + m2) + n3 = m3 === undefined ? 1 : eval(m3 + '1') + n4 = m4 === undefined ? 1 : eval('1' + m4) + //let [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) // Falling back to * in case it does not exist (the corresponding n would be 1) - var [ope2, ope4] = [ope2, ope4].map(ope => ope == '/' ? '/' : '*') - var coeff1 = n1*n2 - var coeff2 = n3*n4 - var coefficient = coeff1+coeff2-(opeM == '-' ? 2*coeff2 : 0) + [ope2, ope4] = [ope2, ope4].map(ope => ope === '/' ? '/' : '*') + let coeff1 = n1*n2 + let coeff2 = n3*n4 + let coefficient = coeff1+coeff2-(opeM === '-' ? 2*coeff2 : 0) return `${coefficient} * π` } @@ -172,14 +176,14 @@ function simplifyExpression(str) { function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], [ // Removing parenthesis when content is only multiplied. - /(^|[*\/-+] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, + /(^|[*\/+-] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], - [// Simplification additions/substractions. - /(^|[^*\/] |\()([-.\d]+) (\+|\-) (\([^)(]+\)|[^)(]+) (\+|\-) ([-.\d]+)($| [^*\/]|\))/g, + [// Simplification additions/subtractions. + /(^|[^*\/] |\()([-.\d]+) [+-] (\([^)(]+\)|[^)(]+) [+-] ([-.\d]+)($| [^*\/]|\))/g, function(match, b4, n1, op1, middle, op2, n2, after) { - var total - if(op2 == '+') { + let total + if(op2 === '+') { total = parseFloat(n1) + parseFloat(n2) } else { total = parseFloat(n1) - parseFloat(n2) @@ -188,14 +192,14 @@ function simplifyExpression(str) { } ], [// Simplification multiplications/divisions. - /([-.\d]+) (\*|\/) (\([^)(]+\)|[^)(+-]+) (\*|\/) ([-.\d]+)/g, + /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, function(match, n1, op1, middle, op2, n2) { - if(parseInt(n1) == n1 && parseInt(n2) == n2 && op2 == '/' && - (parseInt(n1) / parseInt(n2)) % 1 != 0) { + if(parseInt(n1) === n1 && parseInt(n2) === n2 && op2 === '/' && + (parseInt(n1) / parseInt(n2)) % 1 !== 0) { // Non int result for int division. return `(${n1} / ${n2}) ${op1} ${middle}` } else { - if(op2 == '*') { + if(op2 === '*') { return `${parseFloat(n1) * parseFloat(n2)} ${op1} ${middle}` } else { return `${parseFloat(n1) / parseFloat(n2)} ${op1} ${middle}` @@ -206,7 +210,7 @@ function simplifyExpression(str) { [// Starting & ending parenthesis if not needed. /^\s*\((.*)\)\s*$/g, function(match, middle) { - var str = middle + let str = middle // Replace all groups while(/\([^)(]+\)/g.test(str)) str = str.replace(/\([^)(]+\)/g, '') @@ -225,19 +229,19 @@ function simplifyExpression(str) { // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], // [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], // [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - // [/(\s|^|\()1(\.0+)? (\*|\/) /g, '$1'], + // [/(\s|^|\()1(\.0+)? [\*\/] /g, '$1'], // [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], - // [/ (\*|\/) 1(\.0+)?(\s|$|\))/g, '$3'], + // [/ [\*\/] 1(\.0+)?(\s|$|\))/g, '$3'], // [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], // [/(^| |\() /g, '$1'], // [/ ($|\))/g, '$1'], ] // Replacements - var found + let found do { found = false - for(var replacement of replacements) + for(let replacement of replacements) while(replacement[0].test(str)) { found = true str = str.replace(replacement[0], replacement[1]) @@ -247,9 +251,15 @@ function simplifyExpression(str) { } -function makeExpressionReadable(str) { - var replacements = [ - // variables +/** + * Transforms a mathematical expression to make it readable by humans. + * NOTE: Will break parsing of expression. + * @param {string} str - Expression to parse. + * @returns {string} + */ +export function makeExpressionReadable(str) { + let replacements = [ + // letiables [/pi/g, 'π'], [/Infinity/g, '∞'], [/inf/g, '∞'], @@ -264,28 +274,35 @@ function makeExpressionReadable(str) { [/(\d|\))×/g, '$1'], //[/×(\d|\()/g, '$1'], [/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], - [/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { + [/integral\((.+),\s?(.+),\s?["'](.+)["'],\s?["'](.+)["']\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` } else { return `∫${textsup(b)}${textsub(a)} ${body} d${by}` } }], - [/derivative\(?("|')(.+)("|'), ?("|')(.+)("|'), ?(.+)\)?/g, function(match, p1, body, p2, p3, by, p4, x) { + [/derivative\(?["'](.+)["'], ?["'](.+)["'], ?(.+)\)?/g, function(match, p1, body, p2, p3, by, p4, x) { return `d(${body.replace(new RegExp(by, 'g'), 'x')})/dx` }] ] // str = simplifyExpression(str) // Replacements - for(var replacement of replacements) + for(let replacement of replacements) while(replacement[0].test(str)) str = str.replace(replacement[0], replacement[1]) return str } -function parseName(str, removeUnallowed = true) { - var replacements = [ +/** + * Parses a variable name to make it readable by humans. + * + * @param {string} str - Variable name to parse + * @param {boolean} removeUnallowed - Remove domain symbols disallowed in name. + * @returns {string} - The parsed name + */ +export function parseName(str, removeUnallowed = true) { + let replacements = [ // Greek letters [/([^a-z]|^)al(pha)?([^a-z]|$)/g, '$1α$3'], [/([^a-z]|^)be(ta)?([^a-z]|$)/g, '$1β$3'], @@ -330,7 +347,7 @@ function parseName(str, removeUnallowed = true) { ] if(!removeUnallowed) replacements.pop() // Replacements - for(var replacement of replacements) + for(let replacement of replacements) str = str.replace(replacement[0], replacement[1]) return str } @@ -339,21 +356,36 @@ String.prototype.toLatinUppercase = function() { return this.replace(/[a-z]/g, function(match){return match.toUpperCase()}) } -function camelCase2readable(label) { - var parsed = parseName(label, false) +/** + * Transforms camel case strings to a space separated one. + * + * @param {string} label - Camel case to parse + * @returns {string} Parsed label. + */ +export function camelCase2readable(label) { + let parsed = parseName(label, false) return parsed.charAt(0).toLatinUppercase() + parsed.slice(1).replace(/([A-Z])/g," $1") } -function getRandomColor() { - var clrs = '0123456789ABCDEF'; - var color = '#'; - for(var i = 0; i < 6; i++) { - color += clrs[Math.floor(Math.random() * (16-5*(i%2==0)))]; +/** + * Creates a randomized color string. + * @returns {string} + */ +export function getRandomColor() { + let clrs = '0123456789ABCDEF'; + let color = '#'; + for(let i = 0; i < 6; i++) { + color += clrs[Math.floor(Math.random() * (16-5*(i%2===0)))]; } return color; } -function escapeHTML(str) { +/** + * Escapes text to html entities. + * @param {string} str + * @returns {string} + */ +export function escapeHTML(str) { return str.replace(/&/g,'&').replace(//g,'>') ; } @@ -364,6 +396,6 @@ function escapeHTML(str) { * @param {string} expression - The expression to replace in. * @return {string} The parsed expression */ -function exponentsToExpression(expression) { +export function exponentsToExpression(expression) { return expression.replace(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join('')) } From 861bb001c98c134cf4729bd986a9848266584f46 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 28 Mar 2024 22:52:14 +0100 Subject: [PATCH 005/249] Changing version, making Helper objects globals, adding their polyfills. --- LogarithmPlotter/__init__.py | 4 +- LogarithmPlotter/logarithmplotter.py | 9 +- .../LogarithmPlotter/LogarithmPlotter.qml | 11 +-- .../LogarithmPlotter/js/history/common.mjs | 2 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 27 +++++- .../ad5001/LogarithmPlotter/js/math/latex.mjs | 7 +- LogarithmPlotter/util/latex.py | 88 ++++++++----------- 7 files changed, 77 insertions(+), 71 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 4b060a5..d8bb713 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,8 +17,8 @@ """ from shutil import which -__VERSION__ = "0.5.0" -is_release = True +__VERSION__ = "0.5.1" +is_release = False # Check if development version, if so get the date of the latest git patch diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 28affed..f8670bd 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -112,9 +112,12 @@ def run(): global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) - engine.globalObject().setProperty('Runtime', engine.newObject()) - engine.rootContext().setContextProperty("Helper", helper) - engine.rootContext().setContextProperty("Latex", latex) + modules = engine.newObject() + engine.globalObject().setProperty('Runtime', modules) + engine.globalObject().setProperty('Helper', engine.newQObject(helper)) + engine.globalObject().setProperty("Latex", engine.newQObject(latex)) + # engine.rootContext().setContextProperty("Helper", helper) + # engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 1715967..4c9a7b4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -44,16 +44,7 @@ ApplicationWindow { color: sysPalette.window title: "LogarithmPlotter " + (settings.saveFilename != "" ? " - " + settings.saveFilename.split('/').pop() : "") + (history.saved ? "" : "*") - SystemPalette { - id: sysPalette; colorGroup: SystemPalette.Active - - Component.onCompleted: { - // LatexJS initialization. - Runtime.Latex.enabled = Helper.getSettingBool("enable_latex") - Runtime.Latex.Renderer = Latex - Runtime.Latex.defaultColor = sysPalette.windowText - } - } + SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } menuBar: appMenu.trueItem diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index d9a3bc8..78476ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -108,7 +108,7 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") let imgDepth = Runtime.History.imageDepth - let [src, width, height] = Latex.Renderer.render( + let [src, width, height] = Latex.render( latexString, imgDepth * (Runtime.History.fontSize + 2), Runtime.History.themeTextColor diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index d3214f7..a940967 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -27,4 +27,29 @@ qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } /** @type {function(string, string): string} */ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } /** @type {function(string|boolean|int): string} */ -String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } \ No newline at end of file +String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } + +/** Typehints for Helper. */ +const Helper = { + /** @type {function(string): boolean} */ + getSettingBool: (setting) => true, + /** @type {function(string): int} */ + getSettingInt: (setting) => 0, + /** @type {function(string): string} */ + getSetting: (setting) => '', + /** @type {function(string, boolean)} */ + setSettingBool: (setting, value) => {}, + /** @type {function(string, int)} */ + setSettingInt: (setting, value) => 0, + /** @type {function(string, string)} */ + setSetting: (setting, value) => '', + /** @type {function(string, string)} */ + write: (filename, data) => {}, + /** @type {function(string): string} */ + load: (filename) => '', +} + +const Latex = { + /** @type {function(string, number, string): string} */ + render: (latex_markup, font_size, color) => '', +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index c7975e7..ef1f862 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -50,11 +50,12 @@ class LatexAPI extends RuntimeAPI { /** * true if latex has been enabled by the user, false otherwise. */ - this.enabled = false + this.enabled = Helper.getSettingBool("enable_latex") /** - * LaTeX python backend QObject. + * Mirror method for Python object. + * @type {function(string, number, string): string}. */ - this.Renderer = null + this.render = Latex.render } /** diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index ce22bb7..d519e18 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -51,17 +51,19 @@ $$$$ $markup $$$$ \end{document} """) - + + class Latex(QObject): """ Base class to convert Latex equations into PNG images with custom font color and size. It doesn't have any python dependency, but requires a working latex installation and dvipng to be installed on the system. """ + def __init__(self, tempdir: TemporaryDirectory): QObject.__init__(self) self.tempdir = tempdir - + def check_latex_install(self): """ Checks if the current latex installation is valid. @@ -69,22 +71,23 @@ class Latex(QObject): if LATEX_PATH is None: print("No Latex installation found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", + QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) elif DVIPNG_PATH is None: print("DVIPNG not found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) - + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) + @Property(bool) def latexSupported(self): return LATEX_PATH is not None and DVIPNG_PATH is not None - + @Slot(str, float, QColor, result=str) def render(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Prepares and renders a latex string into a png file. """ - markup_hash = "render"+str(hash(latex_markup)) + markup_hash = "render" + str(hash(latex_markup)) export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) @@ -101,21 +104,21 @@ class Latex(QObject): # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) - except Exception as e: # One of the processes failed. A message will be sent every time. + except Exception as e: # One of the processes failed. A message will be sent every time. raise e - img = QImage(export_path); + img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' - + def create_latex_doc(self, export_path: str, latex_markup: str): """ Creates a temporary latex document with base file_hash as file name and a given expression markup latex_markup. """ ltx_path = export_path + ".tex" f = open(export_path + ".tex", 'w') - f.write(DEFAULT_LATEX_DOC.substitute(markup = latex_markup)) + f.write(DEFAULT_LATEX_DOC.substitute(markup=latex_markup)) f.close() - + def convert_latex_to_dvi(self, export_path: str): """ Converts a TEX file to a DVI file. @@ -124,7 +127,7 @@ class Latex(QObject): LATEX_PATH, export_path + ".tex" ]) - + def convert_dvi_to_png(self, dvi_path: str, export_path: str, font_size: float, color: QColor): """ Converts a DVI file to a PNG file. @@ -135,61 +138,44 @@ class Latex(QObject): depth = int(font_size * 72.27 / 100) * 10 self.run([ DVIPNG_PATH, - '-T', 'tight', # Make sure image borders are as tight around the equation as possible to avoid blank space. - '--truecolor', # Make sure it's rendered in 24 bit colors. - '-D',f'{depth}', # Depth of the image - '-bg', 'Transparent', # Transparent background - '-fg',f'{fg}', # Foreground of the wanted color. - f'{dvi_path}.dvi', # Input file - '-o',f'{export_path}.png', # Output file + '-T', 'tight', # Make sure image borders are as tight around the equation as possible to avoid blank space. + '--truecolor', # Make sure it's rendered in 24 bit colors. + '-D', f'{depth}', # Depth of the image + '-bg', 'Transparent', # Transparent background + '-fg', f'{fg}', # Foreground of the wanted color. + f'{dvi_path}.dvi', # Input file + '-o', f'{export_path}.png', # Output file ]) - + def run(self, process: list): """ Runs a subprocess and handles exceptions and messages them to the user. """ proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) try: - out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. + out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: # Process errored - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) - raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), proc.returncode, + str(out, 'utf8') + "\n" + str(err, 'utf8'))) + raise Exception( + " ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, + 'utf8') + "\n" + str( + err, 'utf8')) except TimeoutExpired as e: # Process timed out proc.kill() out, err = proc.communicate() QMessageBox.warning(None, "LogarithmPlotter - Latex", QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), str(out, 'utf8')+"\n"+str(err,'utf8'))) - raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) - - def cleanup(self, export_path): + .format(" ".join(process), str(out, 'utf8') + "\n" + str(err, 'utf8'))) + raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8') + "\n" + str(err, 'utf8')) + + def cleanup(self, export_path): """ Removes auxiliary, logs and Tex temporary files. """ for i in [".tex", ".aux", ".log"]: remove(export_path + i) - - """ - @Slot(str, float, QColor, result=str) - def render_legacy(self, latexstring, font_size, color = True): - exprpath = path.join(self.tempdir.name, f'{hash(latexstring)}_{font_size}_{color.rgb()}.png') - print("Rendering", latexstring, exprpath) - if not path.exists(exprpath): - fg = color.convertTo(QColor.Rgb) - fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' - preview('$${' + latexstring + '}$$', viewer='file', filename=exprpath, dvioptions=[ - "-T", "tight", - "-z", "0", - "--truecolor", - f"-D {int(font_size * 72.27 / 100) * 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion - "-bg", "Transparent", - "-fg", fg], - euler=False) - img = QImage(exprpath); - # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded - return f'{exprpath},{img.width()},{img.height()}' - """ From 73cba855921276d5e0f452e0f2a1b0102f2a3c95 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 01:55:13 +0100 Subject: [PATCH 006/249] Creating Canvas JS Module. --- LogarithmPlotter/logarithmplotter.py | 2 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 10 +- .../LogarithmPlotter/History/History.qml | 6 +- .../LogarithmPlotter/LogGraphCanvas.qml | 331 +---------- .../LogarithmPlotter/LogarithmPlotter.qml | 26 +- .../ObjectLists/Editor/CustomPropertyList.qml | 19 +- .../ObjectLists/Editor/Dialog.qml | 12 +- .../ObjectLists/ObjectCreationGrid.qml | 10 +- .../ObjectLists/ObjectLists.qml | 20 +- .../ObjectLists/ObjectRow.qml | 12 +- .../LogarithmPlotter/PickLocationOverlay.qml | 19 +- .../Setting/ExpressionEditor.qml | 16 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 8 +- .../ViewPositionChangeOverlay.qml | 5 +- .../js/{modules.js => autoload.js} | 1 + .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 523 ++++++++++++++++++ .../LogarithmPlotter/js/history/common.mjs | 22 +- .../js/lib/expr-eval/integration.js | 10 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 15 +- .../LogarithmPlotter/js/math/expression.mjs | 20 +- .../ad5001/LogarithmPlotter/js/math/latex.mjs | 41 +- .../LogarithmPlotter/js/math/sequence.mjs | 10 +- .../js/{runtime.mjs => modules.mjs} | 6 +- .../eu/ad5001/LogarithmPlotter/js/objects.mjs | 8 +- .../LogarithmPlotter/js/objs/autoload.mjs | 2 +- .../LogarithmPlotter/js/objs/common.mjs | 43 +- .../LogarithmPlotter/js/objs/function.mjs | 26 +- .../LogarithmPlotter/js/objs/gainbode.mjs | 27 +- .../LogarithmPlotter/js/objs/phasebode.mjs | 11 +- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 20 +- .../LogarithmPlotter/js/objs/repartition.mjs | 42 +- .../LogarithmPlotter/js/objs/sequence.mjs | 6 +- .../js/objs/sommegainsbode.mjs | 10 +- .../js/objs/sommephasesbode.mjs | 10 +- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 4 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 34 +- 36 files changed, 797 insertions(+), 590 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{modules.js => autoload.js} (87%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{runtime.mjs => modules.mjs} (89%) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index f8670bd..5270534 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -113,7 +113,7 @@ def run(): helper = Helper(pwd, tmpfile) latex = Latex(tempdir) modules = engine.newObject() - engine.globalObject().setProperty('Runtime', modules) + engine.globalObject().setProperty('Modules', modules) engine.globalObject().setProperty('Helper', engine.newQObject(helper)) engine.globalObject().setProperty("Latex", engine.newQObject(latex)) # engine.rootContext().setContextProperty("Helper", helper) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index a77de0c..3de96ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -103,17 +103,17 @@ MenuBar { title: qsTr("&Create") // Services repeater Repeater { - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) MenuItem { - text: Runtime.Objects.types[modelData].displayType() - visible: Runtime.Objects.types[modelData].createable() + text: Modules.Objects.types[modelData].displayType() + visible: Modules.Objects.types[modelData].createable() height: visible ? implicitHeight : 0 icon.name: modelData icon.source: './icons/objects/' + modelData + '.svg' icon.color: sysPalette.buttonText onTriggered: { - var newObj = Runtime.Objects.createNewRegisteredObject(modelData) + var newObj = Modules.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } @@ -151,7 +151,7 @@ MenuBar { checked: Helper.getSettingBool("enable_latex") onTriggered: { Helper.setSettingBool("enable_latex", checked) - Runtime.Latex.enabled = checked + Modules.Latex.enabled = checked drawCanvas.requestPaint() } icon.name: 'Expression' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 8a9a6ba..afc7281 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -212,8 +212,8 @@ Item { } Component.onCompleted: { - Runtime.History.history = historyObj - Runtime.History.themeTextColor = sysPalette.windowText - Runtime.History.imageDepth = Screen.devicePixelRatio + Modules.History.history = historyObj + Modules.History.themeTextColor = sysPalette.windowText + Modules.History.imageDepth = Screen.devicePixelRatio } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 908bdb6..973142f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -126,37 +126,6 @@ Canvas { */ property int maxgradx: 20 - /*! - \qmlproperty var LogGraphCanvas::yaxisstepExpr - Expression for the y axis step (used to create labels). - */ - property var yaxisstepExpr: (new MathLib.Expression(`x*(${yaxisstep})`)) - /*! - \qmlproperty double LogGraphCanvas::yaxisstep1 - Value of the for the y axis step. - */ - property double yaxisstep1: yaxisstepExpr.execute(1) - /*! - \qmlproperty int LogGraphCanvas::drawMaxY - Minimum value of y that should be drawn onto the canvas. - */ - property int drawMaxY: Math.ceil(Math.max(Math.abs(ymax), Math.abs(px2y(canvasSize.height)))/yaxisstep1) - /*! - \qmlproperty var LogGraphCanvas::xaxisstepExpr - Expression for the x axis step (used to create labels). - */ - property var xaxisstepExpr: (new MathLib.Expression(`x*(${xaxisstep})`)) - /*! - \qmlproperty double LogGraphCanvas::xaxisstep1 - Value of the for the x axis step. - */ - property double xaxisstep1: xaxisstepExpr.execute(1) - /*! - \qmlproperty int LogGraphCanvas::drawMaxX - Maximum value of x that should be drawn onto the canvas. - */ - property int drawMaxX: Math.ceil(Math.max(Math.abs(xmin), Math.abs(px2x(canvasSize.width)))/xaxisstep1) - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. @@ -168,7 +137,10 @@ Canvas { */ property var ctx - Component.onCompleted: imageLoaders = {} + Component.onCompleted: { + imageLoaders = {} + Modules.Canvas.initialize(canvas, drawingErrorDialog) + } Native.MessageDialog { id: drawingErrorDialog @@ -183,27 +155,7 @@ Canvas { onPaint: function(rect) { //console.log('Redrawing') if(rect.width == canvas.width) { // Redraw full canvas - ctx = getContext("2d"); - reset(ctx) - drawGrille(ctx) - drawAxises(ctx) - drawLabels(ctx) - ctx.lineWidth = linewidth - for(var objType in Runtime.Objects.currentObjects) { - for(var obj of Runtime.Objects.currentObjects[objType]){ - ctx.strokeStyle = obj.color - ctx.fillStyle = obj.color - if(obj.visible) - try { - obj.draw(canvas, ctx) - } catch(e) { - // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) - drawingErrorDialog.showDialog(objType, obj.name, e.message) - history.undo() - } - } - } - ctx.lineWidth = 1 + Modules.Canvas.redraw() } } @@ -216,277 +168,4 @@ Canvas { } }) } - - /*! - \qmlmethod void LogGraphCanvas::reset(var ctx) - Resets the canvas to a blank one with default setting using 2D \c ctx. - */ - function reset(ctx){ - // Reset - ctx.fillStyle = "#FFFFFF" - ctx.strokeStyle = "#000000" - ctx.font = `${canvas.textsize}px sans-serif` - ctx.fillRect(0,0,width,height) - } - - // Drawing the log based graph - - /*! - \qmlmethod void LogGraphCanvas::drawGrille(var ctx) - Draws the grid using 2D \c ctx. - */ - function drawGrille(ctx) { - ctx.strokeStyle = "#C0C0C0" - if(logscalex) { - for(var xpow = -maxgradx; xpow <= maxgradx; xpow++) { - for(var xmulti = 1; xmulti < 10; xmulti++) { - drawXLine(ctx, Math.pow(10, xpow)*xmulti) - } - } - } else { - for(var x = 0; x < drawMaxX; x+=1) { - drawXLine(ctx, x*xaxisstep1) - drawXLine(ctx, -x*xaxisstep1) - } - } - for(var y = 0; y < drawMaxY; y+=1) { - drawYLine(ctx, y*yaxisstep1) - drawYLine(ctx, -y*yaxisstep1) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawAxises(var ctx) - Draws the graph axises using 2D \c ctx. - */ - function drawAxises(ctx) { - ctx.strokeStyle = "#000000" - var axisypos = logscalex ? 1 : 0 - drawXLine(ctx, axisypos) - drawYLine(ctx, 0) - var axisypx = x2px(axisypos) // X coordinate of Y axis - var axisxpx = y2px(0) // Y coordinate of X axis - // Drawing arrows - drawLine(ctx, axisypx, 0, axisypx-10, 10) - drawLine(ctx, axisypx, 0, axisypx+10, 10) - drawLine(ctx, canvasSize.width, axisxpx, canvasSize.width-10, axisxpx-10) - drawLine(ctx, canvasSize.width, axisxpx, canvasSize.width-10, axisxpx+10) - } - - /*! - \qmlmethod void LogGraphCanvas::drawLabels(var ctx) - Draws all labels (graduation & axises labels) using 2D \c ctx. - */ - function drawLabels(ctx) { - var axisypx = x2px(logscalex ? 1 : 0) // X coordinate of Y axis - var axisxpx = y2px(0) // Y coordinate of X axis - // Labels - ctx.fillStyle = "#000000" - ctx.font = `${canvas.textsize}px sans-serif` - ctx.fillText(ylabel, axisypx+10, 24) - var textSize = ctx.measureText(xlabel).width - ctx.fillText(xlabel, canvasSize.width-14-textSize, axisxpx-5) - // Axis graduation labels - ctx.font = `${canvas.textsize-4}px sans-serif` - - var txtMinus = ctx.measureText('-').width - if(showxgrad) { - if(logscalex) { - for(var xpow = -maxgradx; xpow <= maxgradx; xpow+=1) { - var textSize = ctx.measureText("10"+Utils.textsup(xpow)).width - if(xpow != 0) - drawVisibleText(ctx, "10"+Utils.textsup(xpow), x2px(Math.pow(10,xpow))-textSize/2, axisxpx+16+(6*(xpow==1))) - } - } else { - for(var x = 1; x < drawMaxX; x += 1) { - var drawX = x*xaxisstep1 - var txtX = xaxisstepExpr.simplify(x).replace(/^\((.+)\)$/, '$1') - var textSize = measureText(ctx, txtX, 6).height - drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+textsize/2+textSize) - drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+textsize/2+textSize) - } - } - } - if(showygrad) { - for(var y = 0; y < drawMaxY; y += 1) { - var drawY = y*yaxisstep1 - var txtY = yaxisstepExpr.simplify(y).replace(/^\((.+)\)$/, '$1') - var textSize = ctx.measureText(txtY).width - drawVisibleText(ctx, txtY, axisypx-6-textSize, y2px(drawY)+4+(10*(y==0))) - if(y != 0) - drawVisibleText(ctx, '-'+txtY, axisypx-6-textSize-txtMinus, y2px(-drawY)+4) - } - } - ctx.fillStyle = "#FFFFFF" - } - - /*! - \qmlmethod void LogGraphCanvas::drawXLine(var ctx, double x) - Draws an horizontal line at \c x plot coordinate using 2D \c ctx. - */ - function drawXLine(ctx, x) { - if(isVisible(x, ymax)) { - drawLine(ctx, x2px(x), 0, x2px(x), canvasSize.height) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawXLine(var ctx, double x) - Draws an vertical line at \c y plot coordinate using 2D \c ctx. - */ - function drawYLine(ctx, y) { - if(isVisible(xmin, y)) { - drawLine(ctx, 0, y2px(y), canvasSize.width, y2px(y)) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawVisibleText(var ctx, string text, double x, double y) - Writes multline \c text onto the canvas using 2D \c ctx. - \note The \c x and \c y properties here are relative to the canvas, not the plot. - */ - function drawVisibleText(ctx, text, x, y) { - if(x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height) { - text.toString().split("\n").forEach(function(txt, i){ - ctx.fillText(txt, x, y+(canvas.textsize*i)) - }) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawVisibleImage(var ctx, var image, double x, double y) - Draws an \c image onto the canvas using 2D \c ctx. - \note The \c x, \c y \c width and \c height properties here are relative to the canvas, not the plot. - */ - function drawVisibleImage(ctx, image, x, y, width, height) { - //console.log("Drawing image", isImageLoaded(image), isImageError(image)) - markDirty(Qt.rect(x, y, width, height)); - ctx.drawImage(image, x, y, width, height) - /*if(true || (x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height)) { - }*/ - } - - /*! - \qmlmethod var LogGraphCanvas::measureText(var ctx, string text) - Measures the wicth and height of a multiline \c text that would be drawn onto the canvas using 2D \c ctx. - Return format: dictionary {"width": width, "height": height} - */ - function measureText(ctx, text) { - let theight = 0 - let twidth = 0 - let defaultHeight = ctx.measureText("M").width // Approximate but good enough! - text.split("\n").forEach(function(txt, i){ - theight += defaultHeight - if(ctx.measureText(txt).width > twidth) twidth = ctx.measureText(txt).width - }) - return {'width': twidth, 'height': theight} - } - - /*! - \qmlmethod double LogGraphCanvas::x2px(double x) - Converts an \c x coordinate to it's relative position on the canvas. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function x2px(x) { - if(logscalex) { - var logxmin = Math.log(xmin) - return (Math.log(x)-logxmin)*xzoom - } else return (x - xmin)*xzoom - } - - /*! - \qmlmethod double LogGraphCanvas::y2px(double y) - Converts an \c y coordinate to it's relative position on the canvas. - The y axis not supporting logarithmic scale, it only support linear convertion. - */ - function y2px(y) { - return (ymax-y)*yzoom - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2x(px) { - if(logscalex) { - return Math.exp(px/xzoom+Math.log(xmin)) - } else return (px/xzoom+xmin) - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2y(px) { - return -(px/yzoom-ymax) - } - - /*! - \qmlmethod bool LogGraphCanvas::isVisible(double x, double y) - Checks whether a plot point (\c x, \c y) is visible or not on the canvas. - */ - function isVisible(x, y) { - return (x2px(x) >= 0 && x2px(x) <= canvasSize.width) && (y2px(y) >= 0 && y2px(y) <= canvasSize.height) - } - - /*! - \qmlmethod bool LogGraphCanvas::drawLine(var ctx, double x1, double y1, double x2, double y2) - Draws a line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - */ - function drawLine(ctx, x1, y1, x2, y2) { - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - } - - /*! - \qmlmethod bool LogGraphCanvas::drawDashedLine2(var ctx, double x1, double y1, double x2, double y2) - Draws a dashed line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - */ - function drawDashedLine2(ctx, x1, y1, x2, y2, dashPxSize = 5) { - ctx.setLineDash([dashPxSize, dashPxSize]); - drawLine(ctx, x1, y1, x2, y2) - ctx.setLineDash([]); - } - - /*! - \qmlmethod bool LogGraphCanvas::drawDashedLine(var ctx, double x1, double y1, double x2, double y2) - Draws a dashed line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - (Legacy slower method) - */ - function drawDashedLine(ctx, x1, y1, x2, y2, dashPxSize = 10) { - var distance = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) - var progPerc = dashPxSize/distance - ctx.beginPath(); - ctx.moveTo(x1, y1); - for(var i = 0; i < 1; i += progPerc) { - ctx.lineTo(x1-(x1-x2)*i, y1-(y1-y2)*i) - ctx.moveTo(x1-(x1-x2)*(i+progPerc/2), y1-(y1-y2)*(i+progPerc/2)) - } - ctx.stroke(); - } - - /*! - \qmlmethod var LogGraphCanvas::renderLatexImage(string ltxText, color) - Renders latex markup \c ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. - */ - function renderLatexImage(ltxText, color, callback) { - let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, textsize, color).split(",") - let imgData = { - "source": ltxSrc, - "width": parseFloat(ltxWidth), - "height": parseFloat(ltxHeight) - }; - if(!isImageLoaded(ltxSrc) && !isImageLoading(ltxSrc)){ - // Wait until the image is loaded to callback. - loadImage(ltxSrc) - imageLoaders[ltxSrc] = [callback, imgData] - } else { - // Callback directly - callback(canvas, ctx, imgData) - } - } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 4c9a7b4..3fb9697 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/modules.js" as Modules +import "js/autoload.js" as ModulesAutoload import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 @@ -191,9 +191,9 @@ ApplicationWindow { filename += '.lpf' settings.saveFilename = filename var objs = {} - for(var objType in Runtime.Objects.currentObjects){ + for(var objType in Modules.Objects.currentObjects){ objs[objType] = [] - for(var obj of Runtime.Objects.currentObjects[objType]) { + for(var obj of Modules.Objects.currentObjects[objType]) { objs[objType].push(obj.export()) } } @@ -255,19 +255,19 @@ ApplicationWindow { root.width = data["width"] // Importing objects - Runtime.Objects.currentObjects = {} - Runtime.Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Runtime.Objects.currentObjectsByName[key]; + Modules.Objects.currentObjects = {} + Modules.Object.keys(Objects.currentObjectsByName).forEach(key => { + delete Modules.Objects.currentObjectsByName[key]; // Required to keep the same reference for the copy of the object used in expression variable detection. // Another way would be to change the reference as well, but I feel like the code would be less clean. }) for(let objType in data['objects']) { - if(Object.keys(Runtime.Objects.types).indexOf(objType) > -1) { - Runtime.Objects.currentObjects[objType] = [] + if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { + Modules.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Runtime.Objects.types[objType](...objData) - Runtime.Objects.currentObjects[objType].push(obj) - Runtime.Objects.currentObjectsByName[obj.name] = obj + let obj = new Modules.Objects.types[objType](...objData) + Modules.Objects.currentObjects[objType].push(obj) + Modules.Objects.currentObjectsByName[obj.name] = obj } } else { error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; @@ -275,8 +275,8 @@ ApplicationWindow { } // Updating object dependencies. - for(let objName in Runtime.Objects.currentObjectsByName) - Runtime.Objects.currentObjectsByName[objName].update() + for(let objName in Modules.Objects.currentObjectsByName) + Modules.Objects.currentObjectsByName[objName].update() // Importing history if("history" in data) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index eb163f3..a6f57d6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -130,6 +130,7 @@ Repeater { } } catch(e) { // Error in expression or domain + console.trace() parsingErrorDialog.showDialog(propertyName, newValue, e.message) } } @@ -187,8 +188,8 @@ Repeater { // Base, untranslated version of the model. property var baseModel: selectObjMode ? - Runtime.Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) + Modules.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) : propertyType.values // Translated version of the model. model: selectObjMode ? baseModel : propertyType.translatedValues @@ -198,20 +199,20 @@ Repeater { if(selectObjMode) { // This is only done when what we're selecting are Objects. // Setting object property. - var selectedObj = Runtime.Objects.currentObjectsByName[baseModel[newIndex]] + var selectedObj = Modules.Objects.currentObjectsByName[baseModel[newIndex]] if(newIndex != 0) { // Make sure we don't set the object to null. if(selectedObj == null) { // Creating new object. - selectedObj = Runtime.Objects.createNewRegisteredObject(propertyType.objType) + selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType) history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) - baseModel = Runtime.Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : + baseModel = Modules.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) currentIndex = baseModel.indexOf(selectedObj.name) } - selectedObj.requiredBy.push(Runtime.Objects.currentObjects[objType][objIndex]) - //Runtime.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) + selectedObj.requiredBy.push(Modules.Objects.currentObjects[objType][objIndex]) + //Modules.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) history.addToHistory(new HistoryLib.EditedProperty( @@ -255,7 +256,7 @@ Repeater { obj.name, objType, propertyName, obj[propertyName], exported )) - //Runtime.Objects.currentObjects[objType][objIndex][propertyName] = exported + //Modules.Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported root.changed() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 2c2b9d0..6f650ef 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -52,7 +52,7 @@ Popup.BaseDialog { \qmlproperty var EditorDialog::obj Instance of the object being edited. */ - property var obj: Runtime.Objects.currentObjects[objType][objIndex] + property var obj: Modules.Objects.currentObjects[objType][objIndex] /*! \qmlproperty var EditorDialog::posPicker Reference to the global PositionPicker QML object. @@ -85,7 +85,7 @@ Popup.BaseDialog { Label { id: dlgTitle verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Runtime.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + text: qsTr("Edit properties of %1 %2").arg(Modules.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) font.pixelSize: 20 color: sysPalette.windowText } @@ -111,14 +111,14 @@ Popup.BaseDialog { onChanged: function(newValue) { let newName = Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { - if(newName in Runtime.Objects.currentObjectsByName) { + if(newName in Modules.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { history.addToHistory(new HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) - Runtime.Objects.renameObject(obj.name, newName) - objEditor.obj = Runtime.Objects.currentObjects[objEditor.objType][objEditor.objIndex] + Modules.Objects.renameObject(obj.name, newName) + objEditor.obj = Modules.Objects.currentObjects[objEditor.objType][objEditor.objIndex] objectListList.update() } } @@ -163,7 +163,7 @@ Popup.BaseDialog { */ function open() { dlgCustomProperties.model = [] // Reset - let objProps = Runtime.Objects.types[objEditor.objType].properties() + let objProps = Modules.Objects.types[objEditor.objType].properties() dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. objEditor.show() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 6fd42c9..3e621b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -43,7 +43,7 @@ Column { // Open editor objectEditor.obj = obj objectEditor.objType = obj.type - objectEditor.objIndex = Runtime.Objects.currentObjects[obj.type].indexOf(obj) + objectEditor.objIndex = Modules.Objects.currentObjects[obj.type].indexOf(obj) objectEditor.open() // Disconnect potential link posPicker.picked.disconnect(openEditorDialog) @@ -60,12 +60,12 @@ Column { width: parent.width columns: 3 Repeater { - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) Button { id: createBtn width: 96 - visible: Runtime.Objects.types[modelData].createable() + visible: Modules.Objects.types[modelData].createable() height: visible ? width*0.8 : 0 // The KDE SDK is kinda buggy, so it respects neither specified color nor display propreties. //display: AbstractButton.TextUnderIcon @@ -93,7 +93,7 @@ Column { anchors.rightMargin: 4 horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 - text: Runtime.Objects.types[modelData].displayType() + text: Modules.Objects.types[modelData].displayType() wrapMode: Text.WordWrap clip: true } @@ -103,7 +103,7 @@ Column { ToolTip.text: label.text onClicked: { - let newObj = Runtime.Objects.createNewRegisteredObject(modelData) + let newObj = Modules.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index f7d9e27..d92c36b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -46,7 +46,7 @@ ScrollView { ListView { id: objectsListView - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) implicitHeight: contentItem.childrenRect.height + footerItem.height + 10 @@ -54,7 +54,7 @@ ScrollView { id: objTypeList property string objType: objectsListView.model[index] property var editingRows: [] - model: Runtime.Objects.currentObjects[objType] + model: Modules.Objects.currentObjects[objType] width: objectsListView.width implicitHeight: contentItem.childrenRect.height visible: model != undefined && model.length > 0 @@ -69,23 +69,23 @@ ScrollView { CheckBox { id: typeVisibilityCheckBox - checked: Runtime.Objects.currentObjects[objType] != undefined ? Runtime.Objects.currentObjects[objType].every(obj => obj.visible) : true + checked: Modules.Objects.currentObjects[objType] != undefined ? Modules.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(var obj of Runtime.Objects.currentObjects[objType]) obj.visible = this.checked + for(var obj of Modules.Objects.currentObjects[objType]) obj.visible = this.checked for(var obj of objTypeList.editingRows) obj.objVisible = this.checked objectListList.changed() } ToolTip.visible: hovered ToolTip.text: checked ? - qsTr("Hide all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) : - qsTr("Show all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) + qsTr("Hide all %1").arg(Modules.Objects.types[objType].displayTypeMultiple()) : + qsTr("Show all %1").arg(Modules.Objects.types[objType].displayTypeMultiple()) } Label { id: typeHeaderText verticalAlignment: TextInput.AlignVCenter - text: qsTranslate("control", "%1: ").arg(Runtime.Objects.types[objType].displayTypeMultiple()) + text: qsTranslate("control", "%1: ").arg(Modules.Objects.types[objType].displayTypeMultiple()) font.pixelSize: 20 } } @@ -93,11 +93,11 @@ ScrollView { delegate: ObjectRow { id: controlRow width: objTypeList.width - obj: Runtime.Objects.currentObjects[objType][index] + obj: Modules.Objects.currentObjects[objType][index] posPicker: positionPicker onChanged: { - obj = Runtime.Objects.currentObjects[objType][index] + obj = Modules.Objects.currentObjects[objType][index] objectListList.update() } @@ -129,7 +129,7 @@ ScrollView { function update() { objectListList.changed() for(var objType in objectListList.listViews) { - objectListList.listViews[objType].model = Runtime.Objects.currentObjects[objType] + objectListList.listViews[objType].model = Modules.Objects.currentObjects[objType] } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index cdd9e3a..0772da8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -89,16 +89,16 @@ Item { id: objDescription anchors.left: objVisibilityCheckBox.right anchors.right: deleteButton.left - height: Runtime.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight + height: Modules.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight verticalAlignment: TextInput.AlignVCenter - text: Runtime.Latex.enabled ? "" : obj.getReadableString() + text: Modules.Latex.enabled ? "" : obj.getReadableString() font.pixelSize: 14 Image { id: latexDescription anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - visible: Runtime.Latex.enabled + visible: Modules.Latex.enabled property double depth: Screen.devicePixelRatio property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" @@ -109,7 +109,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { - objEditor.obj = Runtime.Objects.currentObjects[obj.type][index] + objEditor.obj = Modules.Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow @@ -211,14 +211,14 @@ Item { function deleteRecursively(object) { for(let toRemove of object.requiredBy) deleteRecursively(toRemove) - if(Runtime.Objects.currentObjectsByName[object.name] != undefined) { + if(Modules.Objects.currentObjectsByName[object.name] != undefined) { // Object still exists // Temporary fix for objects require not being propertly updated. object.requiredBy = [] history.addToHistory(new HistoryLib.DeleteObject( object.name, object.type, object.export() )) - Runtime.Objects.deleteObject(object.name) + Modules.Objects.deleteObject(object.name) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index c92182a..d8a6ac3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -113,7 +113,7 @@ Item { if(mouse.button == Qt.LeftButton) { // Validate let newValueX = !parent.userPickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) let newValueY = !parent.userPickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) - let obj = Runtime.Objects.currentObjectsByName[objName] + let obj = Modules.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { history.addToHistory(new HistoryLib.EditedPosition( @@ -262,7 +262,7 @@ Item { color: 'black' anchors.top: parent.top anchors.left: parent.left - anchors.leftMargin: canvas.x2px(picked.mouseX) + anchors.leftMargin: Modules.Canvas.x2px(picked.mouseX) visible: parent.userPickX } @@ -273,7 +273,7 @@ Item { color: 'black' anchors.top: parent.top anchors.left: parent.left - anchors.topMargin: canvas.y2px(picked.mouseY) + anchors.topMargin: Modules.Canvas.y2px(picked.mouseY) visible: parent.userPickY } @@ -282,25 +282,26 @@ Item { x: picker.mouseX - width - 5 y: picker.mouseY - height - 5 color: 'black' - property double axisX: canvas.xaxisstep1 + property double axisX: Modules.Canvas.axesStep.x.value + property double axisY: Modules.Canvas.axesStep.y.value property double mouseX: { - let xpos = canvas.px2x(picker.mouseX) + let xpos = Modules.Canvas.px2x(picker.mouseX) if(snapToGridCheckbox.checked) { if(canvas.logscalex) { // Calculate the logged power let pow = Math.pow(10, Math.floor(Math.log10(xpos))) return pow*Math.round(xpos/pow) } else { - return canvas.xaxisstep1*Math.round(xpos/canvas.xaxisstep1) + return axisX*Math.round(xpos/axisX) } } else { return xpos.toFixed(parent.precision) } } property double mouseY: { - let ypos = canvas.px2y(picker.mouseY) + let ypos = Modules.Canvas.px2y(picker.mouseY) if(snapToGridCheckbox.checked) { - return canvas.yaxisstep1*Math.round(ypos/canvas.yaxisstep1) + return axisY*Math.round(ypos/axisY) } else { return ypos.toFixed(parent.precision) } @@ -323,7 +324,7 @@ Item { Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. */ function parseValue(value, objType, propertyName) { - if(Runtime.Objects.types[objType].properties()[propertyName] == 'number') + if(Modules.Objects.types[objType].properties()[propertyName] == 'number') return parseFloat(value) else return new MathLib.Expression(value) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index be5160b..ad7e67c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -391,9 +391,9 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property bool doesObjectExist: isEnteringProperty && (objectName in Runtime.Objects.currentObjectsByName) + property bool doesObjectExist: isEnteringProperty && (objectName in Modules.Objects.currentObjectsByName) property var objectProperties: doesObjectExist ? - Runtime.Objects.currentObjectsByName[objectName].constructor.properties() : + Modules.Objects.currentObjectsByName[objectName].constructor.properties() : {} categoryItems: Object.keys(objectProperties) autocompleteGenerator: (item) => { @@ -460,9 +460,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected - categoryItems: Runtime.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) + categoryItems: Modules.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Runtime.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), + 'text': item, 'annotation': Modules.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -475,9 +475,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected - categoryItems: Object.keys(Runtime.Objects.currentObjectsByName).filter(obj => obj != self) + categoryItems: Object.keys(Modules.Objects.currentObjectsByName).filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': `${Runtime.Objects.currentObjectsByName[item].constructor.displayType()}`, + 'text': item, 'annotation': `${Modules.Objects.currentObjectsByName[item].constructor.displayType()}`, 'autocomplete': item+'.', 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -537,8 +537,8 @@ Item { throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) // Recursive dependencies let dependentOnSelfObjects = expr.requiredObjects().filter( - (obj) => Runtime.Objects.currentObjectsByName[obj].getDependenciesList() - .includes(Runtime.Objects.currentObjectsByName[control.self]) + (obj) => Modules.Objects.currentObjectsByName[obj].getDependenciesList() + .includes(Modules.Objects.currentObjectsByName[control.self]) ) if(dependentOnSelfObjects.length == 1) throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 2c50c56..b15caed 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -222,10 +222,10 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - value: canvas.px2x(canvas.canvasSize.width).toFixed(2) + value: Modules.Canvas.px2x(canvas.width).toFixed(2) onChanged: function(xvaluemax) { if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.canvasSize.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") @@ -241,10 +241,10 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2) + defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.canvasSize.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 85b461e..3d5ff68 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -94,7 +94,7 @@ Item { property int positionChangeTimer: 0 function updatePosition(deltaX, deltaY) { - settingsInstance.xmin = (canvas.px2x(canvas.x2px(settingsInstance.xmin)-deltaX)) + settingsInstance.xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) settingsInstance.ymax += deltaY/canvas.yzoom settingsInstance.ymax = settingsInstance.ymax.toFixed(4) settingsInstance.changed() @@ -107,6 +107,7 @@ Item { prevY = mouse.y parent.beginPositionChange() } + onPositionChanged: function(mouse) { positionChangeTimer++ if(positionChangeTimer == 3) { @@ -118,12 +119,14 @@ Item { positionChangeTimer = 0 } } + onReleased: function(mouse) { let deltaX = mouse.x - prevX let deltaY = mouse.y - prevY updatePosition(deltaX, deltaY) parent.endPositionChange(deltaX, deltaY) } + onWheel: function(wheel) { // Scrolling let scrollSteps = Math.round(wheel.angleDelta.y / 120) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js similarity index 87% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 773f1c3..4c79c64 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -5,3 +5,4 @@ .import "objs/autoload.mjs" as Autoload .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon +.import "canvas.mjs" as CanvasAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs new file mode 100644 index 0000000..d68bd9d --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -0,0 +1,523 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Module} from "./modules.mjs" +import {textsup} from "./utils.mjs" +import {Expression} from "./mathlib.mjs" + + +class CanvasAPI extends Module { + + constructor() { + super('Canvas', [ + Modules.Objects, + Modules.History + ]) + + /** @type {HTMLCanvasElement} */ + this._canvas = null + + /** @type {CanvasRenderingContext2D} */ + this._ctx = null + + /** + * @type {Object} + * @property {function(string, string, string)} showDialog + * @private + */ + this._drawingErrorDialog = null + /** + * + * @type {Object.} + */ + this.axesSteps = { + x: { + expression: null, + value: -1, + maxDraw: -1 + }, + y: { + expression: null, + value: -1, + maxDraw: -1 + } + } + } + + initialize(canvasObject, drawingErrorDialog) { + this._canvas = canvasObject + this._drawingErrorDialog = drawingErrorDialog + } + + get width() { return this._canvas.width } + + get height() { return this._canvas.height } + + /** + * Minimum x of the diagram, provided from settings. + * @returns {number} + */ + get xmin() { return this._canvas.xmin } + + /** + * Zoom on the x-axis of the diagram, provided from settings. + * @returns {number} + */ + get xzoom() { return this._canvas.xzoom } + + /** + * Maximum y of the diagram, provided from settings. + * @returns {number} + */ + get ymax() { return this._canvas.ymax } + + /** + * Zoom on the y-axis of the diagram, provided from settings. + * @returns {number} + */ + get yzoom() { return this._canvas.yzoom } + + /** + * Label used on the x-axis, provided from settings. + * @returns {string} + */ + get xlabel() { return this._canvas.xlabel } + + /** + * Label used on the y-axis, provided from settings. + * @returns {string} + */ + get ylabel() { return this._canvas.ylabel } + + /** + * Width of lines that will be drawn into the canvas, provided from settings. + * @returns {number} + */ + get linewidth() { return this._canvas.linewidth } + + /** + * Font size of the text that will be drawn into the canvas, provided from settings. + * @returns {number} + */ + get textsize() { return this._canvas.textsize } + + /** + * True if the canvas should be in logarithmic mode, false otherwise. + * @returns {boolean} + */ + get logscalex() { return this._canvas.logscalex } + + /** + * True if the x graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showxgrad() { return this._canvas.showxgrad } + + /** + * True if the y graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showygrad() { return this._canvas.showygrad } + + /** + * Max power of the logarithmic scaled on the x axis in logarithmic mode. + * @returns {number} + */ + get maxgradx() { return this._canvas.maxgradx } + + // + // Methods to draw the canvas + // + + /** + * Redraws the entire canvas + */ + redraw() { + this._ctx = this._canvas.getContext("2d") + this._computeAxes() + this._reset() + this._drawGrid() + this._drawAxes() + this._drawLabels() + this._ctx.lineWidth = this.linewidth + for(let objType in Modules.Objects.currentObjects) { + for(let obj of Modules.Objects.currentObjects[objType]){ + this._ctx.strokeStyle = obj.color + this._ctx.fillStyle = obj.color + if(obj.visible) + try { + obj.draw(this) + } catch(e) { + // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) + this._drawingErrorDialog.showDialog(objType, obj.name, e.message) + Modules.History.undo() + } + } + } + this._ctx.lineWidth = 1 + } + + /** + * Calculates informations for drawing gradations for axes. + * @private + */ + _computeAxes() { + let exprY = new Expression(`x*(${this._canvas.yaxisstep})`) + let y1 = exprY.execute(1) + let exprX = new Expression(`x*(${this._canvas.xaxisstep})`) + let x1 = exprX.execute(1) + this.axesSteps = { + x: { + expression: exprX, + value: x1, + maxDraw: Math.ceil(Math.max(Math.abs(this.xmin), Math.abs(this.px2x(this.width)))/x1) + }, + y: { + expression: exprY, + value: y1, + maxDraw: Math.ceil(Math.max(Math.abs(this.ymax), Math.abs(this.px2y(this.height)))/y1) + } + } + } + + /** + * Resets the canvas to a blank one with default setting. + * @private + */ + _reset(){ + // Reset + this._ctx.fillStyle = "#FFFFFF" + this._ctx.strokeStyle = "#000000" + this._ctx.font = `${this.textsize}px sans-serif` + this._ctx.fillRect(0,0,this.width,this.height) + } + + /** + * Draws the grid. + * @private + */ + _drawGrid() { + this._ctx.strokeStyle = "#C0C0C0" + if(this.logscalex) { + for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) { + for(let xmulti = 1; xmulti < 10; xmulti++) { + this.drawXLine(Math.pow(10, xpow)*xmulti) + } + } + } else { + for(let x = 0; x < this.axesSteps.x.maxDraw; x+=1) { + this.drawXLine(x*this.axesSteps.x.value) + this.drawXLine(-x*this.axesSteps.x.value) + } + } + for(let y = 0; y < this.axesSteps.y.maxDraw; y+=1) { + this.drawYLine(y*this.axesSteps.y.value) + this.drawYLine(-y*this.axesSteps.y.value) + } + } + + /** + * Draws the graph axes. + * @private + */ + _drawAxes() { + this._ctx.strokeStyle = "#000000" + let axisypos = this.logscalex ? 1 : 0 + this.drawXLine(axisypos) + this.drawYLine(0) + let axisypx = this.x2px(axisypos) // X coordinate of Y axis + let axisxpx = this.y2px(0) // Y coordinate of X axis + // Drawing arrows + this.drawLine(axisypx, 0, axisypx-10, 10) + this.drawLine(axisypx, 0, axisypx+10, 10) + this.drawLine(this.width, axisxpx, this.width-10, axisxpx-10) + this.drawLine(this.width, axisxpx, this.width-10, axisxpx+10) + } + + /** + * Resets the canvas to a blank one with default setting. + * @private + */ + _drawLabels() { + let axisypx = this.x2px(this.logscalex ? 1 : 0) // X coordinate of Y axis + let axisxpx = this.y2px(0) // Y coordinate of X axis + // Labels + this._ctx.fillStyle = "#000000" + this._ctx.font = `${this.textsize}px sans-serif` + this._ctx.fillText(this.ylabel, axisypx+10, 24) + let textWidth = this._ctx.measureText(this.xlabel).width + this._ctx.fillText(this.xlabel, this.width-14-textWidth, axisxpx-5) + // Axis graduation labels + this._ctx.font = `${this.textsize-4}px sans-serif` + + let txtMinus = this._ctx.measureText('-').width + if(this.showxgrad) { + if(this.logscalex) { + for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow+=1) { + textWidth = this._ctx.measureText("10"+textsup(xpow)).width + if(xpow !== 0) + this.drawVisibleText("10"+textsup(xpow), this.x2px(Math.pow(10,xpow))-textWidth/2, axisxpx+16+(6*(xpow===1))) + } + } else { + for(let x = 1; x < this.axesSteps.x.maxDraw; x += 1) { + let drawX = x*this.axesSteps.x.value + let txtX = this.axesSteps.x.expression.simplify(x).replace(/^\((.+)\)$/, '$1') + let textHeight = this.measureText(txtX).height + this.drawVisibleText(txtX, this.x2px(drawX)-4, axisxpx+this.textsize/2+textHeight) + this.drawVisibleText('-'+txtX, this.x2px(-drawX)-4, axisxpx+this.textsize/2+textHeight) + } + } + } + if(this.showygrad) { + for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { + let drawY = y*this.axesSteps.y.value + let txtY = this.axesSteps.y.expression.simplify(y).replace(/^\((.+)\)$/, '$1') + textWidth = this._ctx.measureText(txtY).width + this.drawVisibleText(txtY, axisypx-6-textWidth, this.y2px(drawY)+4+(10*(y===0))) + if(y !== 0) + this.drawVisibleText('-'+txtY, axisypx-6-textWidth-txtMinus, this.y2px(-drawY)+4) + } + } + this._ctx.fillStyle = "#FFFFFF" + } + + // + // Public functions + // + + /** + * Draws an horizontal line at x plot coordinate. + * @param {number} x + */ + drawXLine(x) { + if(this.isVisible(x, this.ymax)) { + this.drawLine(this.x2px(x), 0, this.x2px(x), this.height) + } + } + + /** + * Draws an vertical line at y plot coordinate + * @param {number} y + * @private + */ + drawYLine(y) { + if(this.isVisible(this.xmin, y)) { + this.drawLine(0, this.y2px(y), this.width, this.y2px(y)) + } + } + + /** + * Writes multiline text onto the canvas. + * NOTE: The x and y properties here are relative to the canvas, not the plot. + * @param {string} text + * @param {number} x + * @param {number} y + */ + drawVisibleText(text, x, y) { + if(x > 0 && x < this.width && y > 0 && y < this.height) { + text.toString().split("\n").forEach((txt, i) => { + this._ctx.fillText(txt, x, y+(this.textsize*i)) + }) + } + } + + /** + * Draws an image onto the canvas. + * NOTE: The x, y width and height properties here are relative to the canvas, not the plot. + * @param {CanvasImageSource} image + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + drawVisibleImage(image, x, y, width, height) { + this._canvas.markDirty(Qt.rect(x, y, width, height)); + this._ctx.drawImage(image, x, y, width, height) + } + + /** + * Measures the width and height of a multiline text that would be drawn onto the canvas. + * @param {string} text + * @returns {{width: number, height: number}} + */ + measureText(text) { + let theight = 0 + let twidth = 0 + let defaultHeight = this.textsize * 1.2 // Approximate but good enough! + for(let txt of text.split("\n")) { + theight += defaultHeight + if(this._ctx.measureText(txt).width > twidth) twidth = this._ctx.measureText(txt).width + } + return {'width': twidth, 'height': theight} + } + + /** + * Converts an x coordinate to its relative position on the canvas. + * It supports both logarithmic and non-logarithmic scale depending on the currently selected mode. + * @param {number} x + * @returns {number} + */ + x2px(x) { + if(this.logscalex) { + let logxmin = Math.log(this.xmin) + return (Math.log(x)-logxmin)*this.xzoom + } else return (x - this.xmin)*this.xzoom + } + + /** + * Converts an y coordinate to it's relative position on the canvas. + * The y-axis not supporting logarithmic scale, it only supports linear conversion. + * @param {number} y + * @returns {number} + */ + y2px(y) { + return (this.ymax-y)*this.yzoom + } + + /** + * Converts an x px position on the canvas to it's corresponding coordinate on the plot. + * It supports both logarithmic and non-logarithmic scale depending on the currently selected mode. + * @param {number} px + * @returns {number} + */ + px2x(px) { + if(this.logscalex) { + return Math.exp(px/this.xzoom+Math.log(this.xmin)) + } else return (px/this.xzoom+this.xmin) + } + + /** + * Converts an x px position on the canvas to it's corresponding coordinate on the plot. + * It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + * @param {number} px + * @returns {number} + */ + px2y(px) { + return -(px/this.yzoom-this.ymax) + } + + /** + * Checks whether a plot point (x, y) is visible or not on the canvas. + * @param {number} x + * @param {number} y + * @returns {boolean} + */ + isVisible(x, y) { + return (this.x2px(x) >= 0 && this.x2px(x) <= this.width) && (this.y2px(y) >= 0 && this.y2px(y) <= this.height) + } + + /** + * Draws a line from plot point (x1, y1) to plot point (x2, y2). + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + */ + drawLine(x1, y1, x2, y2) { + this._ctx.beginPath(); + this._ctx.moveTo(x1, y1); + this._ctx.lineTo(x2, y2); + this._ctx.stroke(); + } + + /** + * Draws a dashed line from plot point (x1, y1) to plot point (x2, y2). + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} dashPxSize + */ + drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) { + this._ctx.setLineDash([dashPxSize/2, dashPxSize]); + this.drawLine(x1, y1, x2, y2) + this._ctx.setLineDash([]); + } + + /** + * Renders latex markup ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. + * @param {string} ltxText + * @param {string} color + * @param {function({width: number, height: number, source: string})} callback + */ + renderLatexImage(ltxText, color, callback) { + let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, this.textsize, color).split(",") + let imgData = { + "source": ltxSrc, + "width": parseFloat(ltxWidth), + "height": parseFloat(ltxHeight) + }; + if(!this._canvas.isImageLoaded(ltxSrc) && !this._canvas.isImageLoading(ltxSrc)){ + // Wait until the image is loaded to callback. + this._canvas.loadImage(ltxSrc) + this._canvas.imageLoaders[ltxSrc] = [callback, imgData] + } else { + // Callback directly + callback(imgData) + } + } + + // + // Context methods + // + + get font() { return this._ctx.font } + set font(value) { return this._ctx.font = value } + + /** + * Draws an act on the canvas centered on a point. + * @param {number} x + * @param {number} y + * @param {number} radius + * @param {number} startAngle + * @param {number} endAngle + * @param {boolean} counterclockwise + */ + arc(x, y, radius, startAngle, endAngle, counterclockwise=false) { + this._ctx.beginPath() + this._ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) + this._ctx.stroke() + } + + /** + * Draws a filled circle centered on a point. + * @param {number} x + * @param {number} y + * @param {number} radius + */ + disc(x, y, radius) { + this._ctx.beginPath(); + this._ctx.arc(x, y, radius, 0, 2 * Math.PI) + this._ctx.fill(); + } + + /** + * Draws a filled rectangle onto the canvas. + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + fillRect(x, y, w, h) { + this._ctx.fillRect(x, y, w, h) + } +} + +/** @type {CanvasAPI} */ +Modules.Canvas = Modules.Canvas || new CanvasAPI() +export const API = Modules.Canvas \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 78476ca..b662098 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from "../runtime.mjs" +import { Module } from "../modules.mjs" import Latex from "../math/latex.mjs" -class HistoryCommonAPI extends RuntimeAPI { +class HistoryCommonAPI extends Module { constructor() { super('History', [ - Runtime.Latex + Modules.Latex ]) // History QML object this.history = null; @@ -31,12 +31,16 @@ class HistoryCommonAPI extends RuntimeAPI { this.imageDepth = 2; this.fontSize = 14; } + + undo() { this.history.undo() } + redo() { this.history.redo() } + addToHistory(action) { this.history.addToHistory(action) } } /** @type {HistoryCommonAPI} */ -Runtime.History = Runtime.History || new HistoryCommonAPI() +Modules.History = Modules.History || new HistoryCommonAPI() -export const API = Runtime.History +export const API = Modules.History export class Action { /** @@ -95,7 +99,7 @@ export class Action { * @returns {string} */ getIconRichText(type) { - return `` + return `` } /** @@ -107,11 +111,11 @@ export class Action { renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let imgDepth = Runtime.History.imageDepth + let imgDepth = Modules.History.imageDepth let [src, width, height] = Latex.render( latexString, - imgDepth * (Runtime.History.fontSize + 2), - Runtime.History.themeTextColor + imgDepth * (Modules.History.fontSize + 2), + Modules.History.themeTextColor ).split(",") return `` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js index 68a88c1..998ed32 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js @@ -19,9 +19,7 @@ .pragma library .import "expr-eval.js" as ExprEval -.import "../../runtime.mjs" as R - -let RuntimeAPI = R.RuntimeAPI +.import "../../modules.mjs" as M const evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually @@ -38,11 +36,11 @@ const evalVariables = { "false": false } -class ExprParserAPI extends RuntimeAPI { +class ExprParserAPI extends M.Module { constructor() { super('ExprParser', [ /** @type {ObjectsAPI} */ - Runtime.Objects + Modules.Objects ]) this.currentVars = {} this.Internals = ExprEval @@ -115,7 +113,7 @@ class ExprParserAPI extends RuntimeAPI { } /** @type {ExprParserAPI} */ -Runtime.ExprParser = Runtime.ExprParser || new ExprParserAPI() +Modules.ExprParser = Modules.ExprParser || new ExprParserAPI() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index a940967..5302aca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -19,7 +19,7 @@ // Type polyfills for IDEs. // Never directly imported. -Runtime = Runtime || {} +Modules = Modules || {} /** @type {function(string, string): string} */ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTranslate not implemented.'); } /** @type {function(string): string} */ @@ -29,6 +29,19 @@ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Er /** @type {function(string|boolean|int): string} */ String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } +const Qt = { + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @returns {{x, width, y, height}} + */ + rect: function(x, y, width, height) { + return {x: x, y: y, width: width, height: height}; + } +} + /** Typehints for Helper. */ const Helper = { /** @type {function(string): boolean} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 3a16499..66cd044 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -25,16 +25,16 @@ import * as Utils from "../utils.mjs" */ export class Expression { constructor(expr) { - if(!Runtime.ExprParser) + if(!Modules.ExprParser) throw new Error('Expression parser not initialized.') - if(!Runtime.Objects) + if(!Modules.Objects) throw new Error('Objects API not initialized.') this.expr = Utils.exponentsToExpression(expr) - this.calc = Runtime.ExprParser.parse(this.expr).simplify() + this.calc = Modules.ExprParser.parse(this.expr).simplify() this.cached = this.isConstant() this.cachedValue = null if(this.cached && this.allRequirementsFullfilled()) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -48,26 +48,26 @@ export class Expression { } allRequirementsFullfilled() { - return this.requiredObjects().every(objName => objName in Runtime.Objects.currentObjectsByName) + return this.requiredObjects().every(objName => objName in Modules.Objects.currentObjectsByName) } undefinedVariables() { - return this.requiredObjects().filter(objName => !(objName in Runtime.Objects.currentObjectsByName)) + return this.requiredObjects().filter(objName => !(objName in Modules.Objects.currentObjectsByName)) } recache() { if(this.cached) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) } execute(x = 1) { if(this.cached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) return this.cachedValue } - Runtime.ExprParser.currentVars = Object.assign({'x': x}, Runtime.Objects.currentObjectsByName) - return this.calc.evaluate(Runtime.ExprParser.currentVars) + Modules.ExprParser.currentVars = Object.assign({'x': x}, Modules.Objects.currentObjectsByName) + return this.calc.evaluate(Modules.ExprParser.currentVars) } simplify(x) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index ef1f862..7418b9c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from '../runtime.mjs' +import { Module } from '../modules.mjs' const unicodechars = ["α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", @@ -39,13 +39,12 @@ const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", "\\pi", "\\infty"] -console.log(Runtime.ExprParser) - -class LatexAPI extends RuntimeAPI { + +class LatexAPI extends Module { constructor() { super('Latex', [ /** @type {ExprParserAPI} */ - Runtime.ExprParser + Modules.ExprParser ]) /** * true if latex has been enabled by the user, false otherwise. @@ -161,18 +160,18 @@ class LatexAPI extends RuntimeAPI { let type = item.type switch(type) { - case Runtime.ExprParser.Internals.INUMBER: + case Modules.ExprParser.Internals.INUMBER: if(item.value === Infinity) { nstack.push("\\infty") } else if(typeof item.value === 'number' && item.value < 0) { nstack.push(this.par(item.value)); } else if(Array.isArray(item.value)) { - nstack.push('[' + item.value.map(Runtime.ExprParser.Internals.escapeValue).join(', ') + ']'); + nstack.push('[' + item.value.map(Modules.ExprParser.Internals.escapeValue).join(', ') + ']'); } else { - nstack.push(Runtime.ExprParser.Internals.escapeValue(item.value)); + nstack.push(Modules.ExprParser.Internals.escapeValue(item.value)); } break; - case Runtime.ExprParser.Internals.IOP2: + case Modules.ExprParser.Internals.IOP2: n2 = nstack.pop(); n1 = nstack.pop(); f = item.value; @@ -211,7 +210,7 @@ class LatexAPI extends RuntimeAPI { throw new EvalError("Unknown operator " + ope + "."); } break; - case Runtime.ExprParser.Internals.IOP3: // Thirdiary operator + case Modules.ExprParser.Internals.IOP3: // Thirdiary operator n3 = nstack.pop(); n2 = nstack.pop(); n1 = nstack.pop(); @@ -222,11 +221,11 @@ class LatexAPI extends RuntimeAPI { throw new EvalError('Unknown operator ' + ope + '.'); } break; - case Runtime.ExprParser.Internals.IVAR: - case Runtime.ExprParser.Internals.IVARNAME: + case Modules.ExprParser.Internals.IVAR: + case Modules.ExprParser.Internals.IVARNAME: nstack.push(this.variable(item.value.toString())); break; - case Runtime.ExprParser.Internals.IOP1: // Unary operator + case Modules.ExprParser.Internals.IOP1: // Unary operator n1 = nstack.pop(); f = item.value; switch(f) { @@ -242,7 +241,7 @@ class LatexAPI extends RuntimeAPI { break; } break; - case Runtime.ExprParser.Internals.IFUNCALL: + case Modules.ExprParser.Internals.IFUNCALL: argCount = item.value; args = []; while (argCount-- > 0) { @@ -252,14 +251,14 @@ class LatexAPI extends RuntimeAPI { // Handling various functions nstack.push(this.functionToLatex(f, args)) break; - case Runtime.ExprParser.Internals.IFUNDEF: + case Modules.ExprParser.Internals.IFUNDEF: nstack.push(this.par(n1 + '(' + args.join(', ') + ') = ' + n2)); break; - case Runtime.ExprParser.Internals.IMEMBER: + case Modules.ExprParser.Internals.IMEMBER: n1 = nstack.pop(); nstack.push(n1 + '.' + item.value); break; - case Runtime.ExprParser.Internals.IARRAY: + case Modules.ExprParser.Internals.IARRAY: argCount = item.value; args = []; while (argCount-- > 0) { @@ -267,10 +266,10 @@ class LatexAPI extends RuntimeAPI { } nstack.push('[' + args.join(', ') + ']'); break; - case Runtime.ExprParser.Internals.IEXPR: + case Modules.ExprParser.Internals.IEXPR: nstack.push('(' + this.expression(item.value) + ')'); break; - case Runtime.ExprParser.Internals.IENDSTATEMENT: + case Modules.ExprParser.Internals.IENDSTATEMENT: break; default: throw new EvalError('invalid Expression'); @@ -284,6 +283,6 @@ class LatexAPI extends RuntimeAPI { } /** @type {LatexAPI} */ -Runtime.Latex = Runtime.Latex || new LatexAPI() +Modules.Latex = Modules.Latex || new LatexAPI() -export default Runtime.Latex +export default Modules.Latex diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index 2dafdcd..a1a96cd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -33,7 +33,7 @@ export class Sequence extends Expr.Expression { this.latexValues = Object.assign({}, baseValues) for(let n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { - let parsed = Runtime.ExprParser.parse(this.calcValues[n].toString()).simplify() + let parsed = Modules.ExprParser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate() } @@ -60,17 +60,17 @@ export class Sequence extends Expr.Expression { cache(n = 1) { let str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - let expr = Runtime.ExprParser.parse(str).simplify() + let expr = Modules.ExprParser.parse(str).simplify() // Cache values required for this one. if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) this.cache(n-this.valuePlus) // Setting current variables - Runtime.ExprParser.currentVars = Object.assign( + Modules.ExprParser.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - Runtime.Objects.currentObjectsByName, + Modules.Objects.currentObjectsByName, {[this.name]: this.calcValues} ) - this.calcValues[n] = expr.evaluate(Runtime.ExprParser.currentVars) + this.calcValues[n] = expr.evaluate(Modules.ExprParser.currentVars) } toString(forceSign=false) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs similarity index 89% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs index 0d859aa..1b68b89 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs @@ -19,12 +19,12 @@ /** * Base class for global APIs in runtime. */ -export class RuntimeAPI { +export class Module { /** * * @param {string} name - Name of the API - * @param {(RuntimeAPI|undefined)[]} requires - List of APIs required to initialize this one. + * @param {(Module|undefined)[]} requires - List of APIs required to initialize this one. */ constructor(name, requires = []) { console.log(`Loading module ${name}...`) @@ -33,7 +33,7 @@ export class RuntimeAPI { /** * Checks if all requirements are defined. - * @param {(RuntimeAPI|undefined)[]} requires + * @param {(Module|undefined)[]} requires * @param {string} name */ __check_requirements(requires, name) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs index b7a2dae..c45b65e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from './runtime.mjs' +import { Module } from './modules.mjs' -class ObjectsAPI extends RuntimeAPI { +class ObjectsAPI extends Module { constructor() { super('Objects') @@ -107,6 +107,6 @@ class ObjectsAPI extends RuntimeAPI { } /** @type {ObjectsAPI} */ -Runtime.Objects = Runtime.Objects || new ObjectsAPI() +Modules.Objects = Modules.Objects || new ObjectsAPI() -export default Runtime.Objects +export default Modules.Objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index c3e8f63..f29710b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -28,7 +28,7 @@ import XCursor from "xcursor.mjs" import Sequence from "sequence.mjs" import RepartitionFunction from "repartition.mjs" -if(Object.keys(Runtime.Objects.types).length === 0) { +if(Object.keys(Modules.Objects.types).length === 0) { ObjectsCommonAPI.registerObject(Point) ObjectsCommonAPI.registerObject(Text) ObjectsCommonAPI.registerObject(Function) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 7821037..5fb31ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -19,17 +19,17 @@ import { getRandomColor, textsub } from "../utils.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import {RuntimeAPI} from "../runtime.mjs" +import {Module} from "../modules.mjs" // This file contains the default data to be imported from all other objects -class ObjectsCommonAPI extends RuntimeAPI { +class ObjectsCommonAPI extends Module { constructor() { super('ObjectsCommon', [ - Runtime.Objects, - Runtime.ExprParser, - Runtime.Latex + Modules.Objects, + Modules.ExprParser, + Modules.Latex ]) } @@ -72,9 +72,9 @@ class ObjectsCommonAPI extends RuntimeAPI { } /** @type {ObjectsCommonAPI} */ -Runtime.ObjectsCommon = Runtime.ObjectsCommon || new ObjectsCommonAPI() +Modules.ObjectsCommon = Modules.ObjectsCommon || new ObjectsCommonAPI() -export const API = Runtime.ObjectsCommon +export const API = Modules.ObjectsCommon /** * Class to extend for every type of object that @@ -269,18 +269,17 @@ export class DrawableObject { for(let toRemove of this.requiredBy) { // Normally, there should be none here, but better leave nothing just in case. Objects.deleteObject(toRemove.name) } - console.log(this.requires) for(let toRemoveFrom of this.requires) { toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this) } } /** - * Abstract method. Draw the object onto the \c canvas with the 2D context \c ctx. - * @param {Canvas} canvas + * Abstract method. Draw the object onto the \c canvas with the. + * @param {CanvasAPI} canvas * @param {CanvasRenderingContext2D} ctx */ - draw(canvas, ctx) {} + draw(canvas) {} /** * Applicates a \c drawFunction with two position arguments depending on @@ -343,7 +342,7 @@ export class DrawableObject { * Then, it's displayed using the \c drawFunctionLatex (x,y,imageData) and * \c drawFunctionText (x,y,text) depending on whether to use latex. * - * @param {Canvas} canvas + * @param {CanvasAPI} canvas * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis @@ -354,7 +353,7 @@ export class DrawableObject { * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ - drawLabel(canvas, ctx, labelPosition, posX, posY,forceText = false, + drawLabel(canvas, labelPosition, posX, posY,forceText = false, getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { // Default functions if(getLatexFunction == null) @@ -362,25 +361,25 @@ export class DrawableObject { if(getTextFunction == null) getTextFunction = this.getLabel.bind(this) if(drawFunctionLatex == null) - drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height) + drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height) if(drawFunctionText == null) - drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height) // Positioned from left bottom + drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height) // Positioned from left bottom // Drawing the label let offset if(!forceText && Latex.enabled) { // With latex - let drawLblCb = function(canvas, ctx, ltxImg) { - this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) - } + let drawLblCb = ((ltxImg) => { + this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) + }).bind(this) let ltxLabel = getLatexFunction(); - if(ltxLabel != "") + if(ltxLabel !== "") canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) } else { // Without latex let text = getTextFunction() - ctx.font = `${canvas.textsize}px sans-serif` - let textSize = canvas.measureText(ctx, text) - this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) + canvas.font = `${canvas.textsize}px sans-serif` + let textSize = canvas.measureText(text) + this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 1a52dba..0d68830 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -104,17 +104,17 @@ export default class Function extends ExecutableObject { return '' } - draw(canvas, ctx) { - Function.drawFunction(canvas, ctx, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) + draw(canvas) { + Function.drawFunction(canvas, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } /** * Reusable in other objects. * Drawing small traits every few pixels */ - static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { + static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { let pxprecision = 10 let previousX = canvas.px2x(0) let previousY = null; @@ -124,7 +124,7 @@ export default class Function extends ExecutableObject { if(previousX === null) previousX = definitionDomain.next(canvas.px2x(0)) previousY = expr.execute(previousX) if(!drawPoints && !drawDash) return - while(previousX !== null && canvas.x2px(previousX) < canvas.canvasSize.width) { + while(previousX !== null && canvas.x2px(previousX) < canvas.width) { // Reconverted for canvas to fix for logarithmic scales. let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); let currentY = expr.execute(currentX) @@ -132,10 +132,10 @@ export default class Function extends ExecutableObject { if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && (destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) { if(drawDash) - canvas.drawDashedLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + canvas.drawDashedLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) if(drawPoints) { - ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) + canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } previousX = currentX @@ -143,8 +143,8 @@ export default class Function extends ExecutableObject { } if(drawPoints) { // Drawing the last cross - ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) + canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } else { // Use max precision if function is trigonometrical on log scale. @@ -154,7 +154,7 @@ export default class Function extends ExecutableObject { // Calculate the previousY at the start of the canvas if(definitionDomain.includes(previousX)) previousY = expr.execute(previousX) - for(let px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { + for(let px = pxprecision; px < canvas.width; px += pxprecision) { let currentX = canvas.px2x(px) if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { // Should draw up to currentX, but NOT at previousX. @@ -176,12 +176,12 @@ export default class Function extends ExecutableObject { } while(!definitionDomain.includes(currentX) && currentX !== previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) - let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.canvasSize.height)) + let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.height)) if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { let currentY = expr.execute(currentX) if(destinationDomain.includes(currentY)) { if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY-currentY) < maxvariation) { - canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + canvas.drawLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) } } previousY = currentY diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index 696084d..fb0e9cd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -40,7 +40,7 @@ export default class GainBode extends ExecutableObject { [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', [QT_TRANSLATE_NOOP('prop','omGraduation')]: 'boolean' }} - + constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { if(name == null) name = Common.getNewName('G') @@ -52,12 +52,13 @@ export default class GainBode extends ExecutableObject { if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) - HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' } om_0.requiredBy.push(this) } + /** @type {Point} */ this.om_0 = om_0 this.pass = pass if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString()) @@ -98,7 +99,7 @@ export default class GainBode extends ExecutableObject { simplify(x = 1) { let xval = x if(typeof x == 'string') xval = executeExpression(x) - if((this.pass === 'high' && xval < this.om_0.x) || (this.pass === 'low' && xval > this.om_0.x)) { + if((this.pass === 'high' && xval < this.om_0.x.execute()) || (this.pass === 'low' && xval > this.om_0.x.execute())) { let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.simplify(x) } else { @@ -110,29 +111,29 @@ export default class GainBode extends ExecutableObject { return true } - draw(canvas, ctx) { - let base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] + draw(canvas) { + let base = [canvas.x2px(this.om_0.x.execute()), canvas.y2px(this.om_0.y.execute())] let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) let inDrawDom = new EmptySet() if(this.pass === 'high') { // High pass, linear line from beginning, then constant to the end. - canvas.drawLine(ctx, base[0], base[1], canvas.canvasSize.width, base[1]) + canvas.drawLine(base[0], base[1], canvas.width, base[1]) inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`) } else { // Low pass, constant from the beginning, linear line to the end. - canvas.drawLine(ctx, base[0], base[1], 0, base[1]) + canvas.drawLine(base[0], base[1], 0, base[1]) inDrawDom = parseDomain(`]${this.om_0.x};+inf[`) } - Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) + Function.drawFunction(canvas, dbfn, inDrawDom, Domain.R) // Dashed line representing break in function - var xpos = canvas.x2px(this.om_0.x.execute()) - var dashPxSize = 10 - for(var i = 0; i < canvas.canvasSize.height && this.omGraduation; i += dashPxSize*2) - canvas.drawLine(ctx, xpos, i, xpos, i+dashPxSize) + let xpos = canvas.x2px(this.om_0.x.execute()) + let dashPxSize = 10 + for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize*2) + canvas.drawLine(xpos, i, xpos, i+dashPxSize) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index 14ff351..5b32ec5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -57,6 +57,7 @@ export default class PhaseBode extends ExecutableObject { } om_0.requiredBy.push(this) } + /** @type {Point} */ this.om_0 = om_0 this.unit = unit this.labelPosition = labelPosition @@ -100,21 +101,21 @@ export default class PhaseBode extends ExecutableObject { return true } - draw(canvas, ctx) { + draw(canvas) { let baseX = canvas.x2px(this.om_0.x.execute()) let omy = this.om_0.y.execute() let augmt = this.phase.execute() let baseY = canvas.y2px(omy) let augmtY = canvas.y2px(omy+augmt) // Before change line. - canvas.drawLine(ctx, 0, baseY, Math.min(baseX, canvas.canvasSize.height), baseY) + canvas.drawLine(0, baseY, Math.min(baseX, canvas.height), baseY) // Transition line. - canvas.drawLine(ctx, baseX, baseY, baseX, augmtY) + canvas.drawLine(baseX, baseY, baseX, augmtY) // After change line - canvas.drawLine(ctx, Math.max(0, baseX), augmtY, canvas.canvasSize.width, augmtY) + canvas.drawLine(Math.max(0, baseX), augmtY, canvas.width, augmtY) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index d03053d..03de816 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -58,24 +58,22 @@ export default class Point extends DrawableObject { return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.pointStyle] } - draw(canvas, ctx) { - var [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] - var pointSize = 8+(ctx.lineWidth*2) + draw(canvas) { + let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] + let pointSize = 8+(canvas.linewidth*2) switch(this.pointStyle) { case '●': - ctx.beginPath(); - ctx.ellipse(canvasX-pointSize/2, canvasY-pointSize/2, pointSize, pointSize) - ctx.fill(); + canvas.disc(canvasX, canvasY, pointSize/2) break; case '✕': - canvas.drawLine(ctx, canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2) - canvas.drawLine(ctx, canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2) + canvas.drawLine(canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2) + canvas.drawLine(canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2) break; case '+': - ctx.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2) - ctx.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) + canvas.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2) + canvas.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) break; } - this.drawLabel(canvas, ctx, this.labelPosition, canvasX, canvasY) + this.drawLabel(canvas, this.labelPosition, canvasX, canvasY) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 32105d1..0bee9a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -92,61 +92,51 @@ export default class RepartitionFunction extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { let currentY = 0; let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { - canvas.drawLine(ctx, - 0, - canvas.y2px(0), - canvas.x2px(keys[0]), - canvas.y2px(0) - ) + canvas.drawLine(0, canvas.y2px(0), canvas.x2px(keys[0]), canvas.y2px(0)) if(canvas.isVisible(keys[0],0)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); - ctx.stroke(); + canvas.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); } } for(let i = 0; i < keys.length-1; i++) { let idx = keys[i]; currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { - canvas.drawLine(ctx, + canvas.drawLine( Math.max(0,canvas.x2px(idx)), canvas.y2px(currentY), - Math.min(canvas.canvasSize.width,canvas.x2px(keys[i+1])), + Math.min(canvas.width,canvas.x2px(keys[i+1])), canvas.y2px(currentY) ) if(canvas.isVisible(idx,currentY)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(idx),canvas.y2px(currentY), 4, 0, 2 * Math.PI); - ctx.fill(); + canvas.disc(canvas.x2px(idx), canvas.y2px(currentY), 4) } if(canvas.isVisible(keys[i+1],currentY)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); - ctx.stroke(); + canvas.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); } } } if(canvas.isVisible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) { - canvas.drawLine(ctx, + canvas.drawLine( Math.max(0,canvas.x2px(keys[keys.length-1])), canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), - canvas.canvasSize.width, + canvas.width, canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))) ) - ctx.beginPath(); - ctx.arc( + canvas.disc( canvas.x2px(keys[keys.length-1]), - canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), - 4, 0, 2 * Math.PI); - ctx.fill(); + canvas.y2px( + currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.')) + ), + 4 + ) } // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 4e06b56..a7af26f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -123,11 +123,11 @@ export default class Sequence extends ExecutableObject { } } - draw(canvas, ctx) { - Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) + draw(canvas) { + Function.drawFunction(canvas, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index e03ca81..947c99f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -89,7 +89,7 @@ export default class SommeGainsBode extends ExecutableObject { let baseY = 0 let om0xGains = {1000000000: 0} // To draw the last part let om0xPass = {1000000000: 'high'} // To draw the last part - Objects.currentObjects['Gain Bode'].forEach(function(gainObj) { // Sorting by their om_0 position. + for(/** @type {GainBode} */ let gainObj of Objects.currentObjects['Gain Bode']) { // Sorting by their om_0 position. let om0x = gainObj.om_0.x.execute() if(om0xGains[om0x] === undefined) { om0xGains[om0x] = gainObj.gain.execute() @@ -99,7 +99,7 @@ export default class SommeGainsBode extends ExecutableObject { om0xPass[om0x+0.001] = gainObj.pass === 'high' } baseY += gainObj.execute(drawMin) - }) + } // Sorting the om_0x let om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... om0xList.sort((a,b) => a - b) @@ -130,13 +130,13 @@ export default class SommeGainsBode extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { if(this.cachedParts.length > 0) { for(let [dbfn, inDrawDom] of this.cachedParts) { - Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) + Function.drawFunction(canvas, dbfn, inDrawDom, Domain.R) if(inDrawDom.includes(this.labelX)) { // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index 328c069..30ad4b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -89,7 +89,7 @@ export default class SommePhasesBode extends ExecutableObject { if(Objects.currentObjects['Phase Bode'] !== undefined) { console.log('Recalculating cache phase') - for(let obj of Objects.currentObjects['Phase Bode']) { + for(/** @type {PhaseBode} */ let obj of Objects.currentObjects['Phase Bode']) { this.om0xList.push(obj.om_0.x.execute()) if(phasesDict[obj.om_0.x.execute()] === undefined) { phasesDict[obj.om_0.x.execute()] = obj.phase.execute() @@ -110,18 +110,18 @@ export default class SommePhasesBode extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { for(let i = 0; i < this.om0xList.length-1; i++) { let om0xBegin = canvas.x2px(this.om0xList[i]) let om0xEnd = canvas.x2px(this.om0xList[i+1]) let baseY = canvas.y2px(this.phasesList[i]) let nextY = canvas.y2px(this.phasesList[i+1]) - canvas.drawLine(ctx, om0xBegin, baseY, om0xEnd, baseY) - canvas.drawLine(ctx, om0xEnd, baseY, om0xEnd, nextY) + canvas.drawLine(om0xBegin, baseY, om0xEnd, baseY) + canvas.drawLine(om0xEnd, baseY, om0xEnd, nextY) } // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index 040e7bd..e3e2ba2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -90,9 +90,9 @@ export default class Text extends DrawableObject { return `\\textsf{${this.latexMarkupText()}}` } - draw(canvas, ctx) { + draw(canvas) { let yOffset = this.disableLatex ? canvas.textsize-4 : 0 - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 036c408..236bd4a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -91,8 +91,8 @@ export default class XCursor extends DrawableObject { } getTargetValueLatexLabel() { - var t = this.targetElement - var approx = '' + let t = this.targetElement + let approx = '' if(this.approximate) { approx = t.execute(this.x.execute()) approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) @@ -142,39 +142,35 @@ export default class XCursor extends DrawableObject { } } - draw(canvas, ctx) { + draw(canvas) { let xpos = canvas.x2px(this.x.execute()) switch(this.displayStyle) { case '— — — — — — —': - var dashPxSize = 10 - for(var i = 0; i < canvas.canvasSize.height; i += dashPxSize*2) - canvas.drawLine(ctx, xpos, i, xpos, i+dashPxSize) + canvas.drawDashedLine(xpos, 0, xpos, canvas.height, 20) break; case '⸺⸺⸺⸺⸺⸺': - canvas.drawXLine(ctx, this.x.execute()) + canvas.drawXLine(this.x.execute()) break; case '• • • • • • • • • •': - var pointDistancePx = 10 - var pointSize = 2 - ctx.beginPath(); - for(var i = 0; i < canvas.canvasSize.height; i += pointDistancePx) - ctx.ellipse(xpos-pointSize/2, i-pointSize/2, pointSize, pointSize) - ctx.fill(); + let pointDistancePx = 10 + let pointSize = 2 + for(let i = 0; i < canvas.height; i += pointDistancePx) + canvas.disc(xpos, i, pointSize) break; } // Drawing label at the top of the canvas. - this.drawLabel(canvas, ctx, this.labelPosition, xpos, 0, false, null, null, - (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, 5, ltxImg.width, ltxImg.height), - (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) + this.drawLabel(canvas, this.labelPosition, xpos, 0, false, null, null, + (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, 5, ltxImg.width, ltxImg.height), + (x,y,text,textSize) => canvas.drawVisibleText(text, x, textSize.height+5)) // Drawing label at the position of the target element. if(this.targetValuePosition === 'Next to target' && this.targetElement != null) { let ypos = canvas.y2px(this.targetElement.execute(this.x.execute())) - this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, + this.drawLabel(canvas, this.labelPosition, xpos, ypos, false, this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), - (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height), - (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height)) + (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height), + (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height)) } } } From 82e8413e56ef3360ac0359111593178aea7b56f4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 17:53:10 +0100 Subject: [PATCH 007/249] Creating IO JS module. --- LogarithmPlotter/i18n/lp_de.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_en.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_es.ts | 192 ++++----- LogarithmPlotter/i18n/lp_fr.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_hu.ts | 373 +++++++++-------- LogarithmPlotter/i18n/lp_nb_NO.ts | 233 ++++++----- LogarithmPlotter/i18n/lp_template.ts | 192 ++++----- LogarithmPlotter/logarithmplotter.py | 57 ++- .../LogarithmPlotter/LogarithmPlotter.qml | 156 ++------ .../eu/ad5001/LogarithmPlotter/Settings.qml | 10 +- .../eu/ad5001/LogarithmPlotter/js/autoload.js | 3 +- .../LogarithmPlotter/js/history/common.mjs | 3 + .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 168 ++++++++ LogarithmPlotter/util/config.py | 2 +- LogarithmPlotter/util/helper.py | 61 +-- LogarithmPlotter/util/js.py | 52 +++ LogarithmPlotter/util/latex.py | 5 +- LogarithmPlotter/util/native.py | 25 +- LogarithmPlotter/util/update.py | 33 +- 19 files changed, 1472 insertions(+), 1224 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs create mode 100644 LogarithmPlotter/util/js.py diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 2aad151..407b284 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -437,64 +437,52 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - Objects - Objekte + Objekte - Settings - Einstellungen + Einstellungen - History - Verlauf + Verlauf - Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. - Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. - Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. - Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. - Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: - Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. - Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! - &Update - &Aktualisieren + &Aktualisieren - &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -519,23 +507,23 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -575,7 +563,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid - Am Gitter einrasten + Am Gitter einrasten @@ -603,7 +591,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -816,30 +804,30 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color %1 %2's color changed from %3 to %4. - %1 %2 wurde von %3 bis %4 umgefärbt. + %1 %2 wurde von %3 bis %4 umgefärbt. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) + Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) Note: Specify the probability for each value. - Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. + Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. + Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -858,25 +846,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. delete %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 of %2 changed from %3 to %4. - %1 von %2 wurde von %3 auf %4 geändert. + %1 von %2 wurde von %3 auf %4 geändert. @@ -943,11 +931,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. @@ -1041,7 +1029,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler @@ -1092,63 +1080,126 @@ Ausdruck analysiert: %3 function Function - Funktion + Funktion Functions - Funktionen + Funktionen gainbode Bode Magnitude - Bode-Magnitude + Bode-Magnitude Bode Magnitudes - Bode-Magnituden + Bode-Magnituden low-pass - Tiefpass + Tiefpass high-pass - Hochpass + Hochpass historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. + + + + io + + + Objects + Objekte + + + + Settings + Einstellungen + + + + History + Verlauf + + + + Saved plot to '%1'. + Gespeicherte Grafik auf '%1'. + + + + Loading file '%1'. + Laden der Datei '%1'. + + + + Unknown object type: %1. + Unbekannter Objekttyp: %1. + + + + Invalid file provided. + Ungültige Datei angegeben. + + + + Could not save file: + Die Datei konnte nicht gespeichert werden: + + + + Loaded file '%1'. + Geladene Datei '%1'. + + + + Copied plot screenshot to clipboard! + Grafik in die Zwischenablage kopiert! + + + + &Update + &Aktualisieren + + + + &Update LogarithmPlotter + LogarithmPlotter &aktualisieren latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1157,12 +1208,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1175,7 +1226,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1186,317 +1237,297 @@ Der Prozess '{}' brauchte zu lange, um beendet zu werden: Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 umbenannt in %3. + %1 %2 umbenannt in %3. parameters above - ↑ Über + ↑ Über below - ↓ Unter + ↓ Unter left - ← Links + ← Links right - → Rechts + → Rechts above-left - ↖ Oben links + ↖ Oben links above-right - ↗ Oben rechts + ↗ Oben rechts below-left - ↙ Unten links + ↙ Unten links below-right - ↘ Unten rechts + ↘ Unten rechts center - >|< Zentrum + >|< Zentrum top - ↑ Über + ↑ Über bottom - ↓ Unter + ↓ Unter top-left - ↖ Oben links + ↖ Oben links top-right - ↗ Oben rechts + ↗ Oben rechts bottom-left - ↙ Unten links + ↙ Unten links bottom-right - ↘ Unten rechts + ↘ Unten rechts application - Anwendung + Anwendung function - Funktion + Funktion high - Hoch + Hoch low - Tief + Tief Next to target - Neben dem Ziel + Neben dem Ziel With label - Mit Etikett + Mit Etikett Hidden - Versteckt + Versteckt phasebode Bode Phase - Bode-Phase + Bode-Phase Bode Phases - Bode-Phasen + Bode-Phasen point Point - Punkt + Punkt Points - Punkte + Punkte position Position of %1 %2 set from "%3" to "%4". - %1 %2 wurde von "%3" nach "%4" verschoben. + %1 %2 wurde von "%3" nach "%4" verschoben. Position of %1 set from %2 to %3. - %1 wurde von %2 nach %3 verschoben. + %1 wurde von %2 nach %3 verschoben. prop expression - Ausdruck + Ausdruck definitionDomain - Definitionsbereich + Definitionsbereich destinationDomain - Reichweite + Reichweite labelPosition - Position des Etiketts + Position des Etiketts displayMode - Anzeigemodus + Anzeigemodus labelX - X-Position des Etiketts + X-Position des Etiketts drawPoints - Unentschiedene Punkte + Unentschiedene Punkte drawDashedLines - Gestrichelte Linien anzeigen + Gestrichelte Linien anzeigen om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Größenordnung + Größenordnung omGraduation - Teilung auf ω zeigen + Teilung auf ω zeigen phase - Phase + Phase unit - Einheit + Einheit x - X + X y - Y + Y pointStyle - Punkt-Stil + Punkt-Stil probabilities - Wahrscheinlichkeiten + Wahrscheinlichkeiten text - Inhalt + Inhalt disableLatex - LaTeX-Rendering für diesen Text deaktivieren + LaTeX-Rendering für diesen Text deaktivieren targetElement - Zielobjekt + Zielobjekt approximate - Ungefähren Wert anzeigen + Ungefähren Wert anzeigen rounding - Rundung + Rundung displayStyle - Stil + Stil targetValuePosition - Wertposition des Ziels + Wertposition des Ziels defaultExpression - Standardausdruck + Standardausdruck baseValues - Initialisierungswerte + Initialisierungswerte color - Farbe + Farbe repartition Repartition - Verteilungsfunktion + Verteilungsfunktion Repartition functions - Verteilungsfunktionen + Verteilungsfunktionen sequence Sequence - Folge + Folge Sequences - Folgen + Folgen sommegainsbode Bode Magnitudes Sum - Bode-Magnituden Summe + Bode-Magnituden Summe sommephasesbode Bode Phases Sum - Bode-Phasen Summe + Bode-Phasen Summe text Text - Text + Text Texts - Texte + Texte @@ -1507,7 +1538,7 @@ File does not exist. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. @@ -1525,37 +1556,37 @@ File does not exist. usage - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 or %2 Verwendung: %1 oder %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) @@ -1564,22 +1595,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. xcursor X Cursor - X Zeiger + X Zeiger X Cursors - X Zeiger + X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 591e2c2..f700aa6 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 @@ -437,64 +437,52 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - Objects - Objects + Objects - Settings - Settings + Settings - History - History + History - Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. - Loading file '%1'. - Loading file '%1'. + Loading file '%1'. - Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. - Invalid file provided. - Invalid file provided. + Invalid file provided. - Could not save file: - Could not save file: + Could not save file: - Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. - Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! - &Update - &Update + &Update - &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -519,23 +507,23 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -575,7 +563,7 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid - Snap to grid + Snap to grid @@ -603,7 +591,7 @@ These settings can be changed at any time from the "Settings" menu.Hide picker settings - + (no pick selected) (no pick selected) @@ -816,30 +804,30 @@ These settings can be changed at any time from the "Settings" menu.color %1 %2's color changed from %3 to %4. - %1 %2's color changed from %3 to %4. + %1 %2's color changed from %3 to %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) + The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) Note: Specify the probability for each value. - Note: Specify the probability for each value. + Note: Specify the probability for each value. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - If you have latex enabled, you can use use latex markup in between $$ to create equations. + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -858,25 +846,25 @@ These settings can be changed at any time from the "Settings" menu.create New %1 %2 created. - New %1 %2 created. + New %1 %2 created. delete %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 changed from %3 to %4. - %1 of %2 changed from %3 to %4. + %1 of %2 changed from %3 to %4. @@ -943,11 +931,11 @@ These settings can be changed at any time from the "Settings" menu. Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. @@ -1041,7 +1029,7 @@ These settings can be changed at any time from the "Settings" menu.Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error @@ -1092,63 +1080,126 @@ Evaluated expression: %3 function Function - Function + Function Functions - Functions + Functions gainbode Bode Magnitude - Bode Magnitude + Bode Magnitude Bode Magnitudes - Bode Magnitudes + Bode Magnitudes low-pass - low-pass + low-pass high-pass - high-pass + high-pass historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. + + + + io + + + Objects + Objects + + + + Settings + Settings + + + + History + History + + + + Saved plot to '%1'. + Saved plot to '%1'. + + + + Loading file '%1'. + Loading file '%1'. + + + + Unknown object type: %1. + Unknown object type: %1. + + + + Invalid file provided. + Invalid file provided. + + + + Could not save file: + Could not save file: + + + + Loaded file '%1'. + Loaded file '%1'. + + + + Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! + + + + &Update + &Update + + + + &Update LogarithmPlotter + &Update LogarithmPlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1157,12 +1208,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1175,7 +1226,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1186,317 +1237,297 @@ Process '{}' took too long to finish: Please make sure your LaTeX installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 renamed to %3. + %1 %2 renamed to %3. parameters above - ↑ Above + ↑ Above below - ↓ Below + ↓ Below left - ← Left + ← Left right - → Right + → Right above-left - ↖ Above left + ↖ Above left above-right - ↗ Above right + ↗ Above right below-left - ↙ Below left + ↙ Below left below-right - ↘ Below right + ↘ Below right center - >|< Center + >|< Center top - ↑ Top + ↑ Top bottom - ↓ Bottom + ↓ Bottom top-left - ↖ Top left + ↖ Top left top-right - ↗ Top right + ↗ Top right bottom-left - ↙ Bottom left + ↙ Bottom left bottom-right - ↘ Bottom right + ↘ Bottom right application - Application + Application function - Function + Function high - High + High low - Low + Low Next to target - Next to target + Next to target With label - With label + With label Hidden - Hidden + Hidden phasebode Bode Phase - Bode Phase + Bode Phase Bode Phases - Bode Phases + Bode Phases point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 moved from "%3" to "%4". + %1 %2 moved from "%3" to "%4". Position of %1 set from %2 to %3. - %1 moved from %2 to %3. + %1 moved from %2 to %3. prop expression - Expression + Expression definitionDomain - Domain + Domain destinationDomain - Range + Range labelPosition - Label position + Label position displayMode - Display mode + Display mode labelX - Label's X position + Label's X position drawPoints - Show points + Show points drawDashedLines - Show dashed lines + Show dashed lines om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Magnitude gain + Magnitude gain omGraduation - Show graduation on ω₀ + Show graduation on ω₀ phase - Phase + Phase unit - Unit to use + Unit to use x - X + X y - Y + Y pointStyle - Point style + Point style probabilities - Probabilities list + Probabilities list text - Content + Content disableLatex - Disable LaTeX rendering for this text + Disable LaTeX rendering for this text targetElement - Object to target + Object to target approximate - Show approximate value + Show approximate value rounding - Rounding + Rounding displayStyle - Display style + Display style targetValuePosition - Target's value position + Target's value position defaultExpression - Default expression + Default expression baseValues - Initialisation values + Initialisation values color - Color + Color repartition Repartition - Distribution + Distribution Repartition functions - Distribution functions + Distribution functions sequence Sequence - Sequence + Sequence Sequences - Sequences + Sequences sommegainsbode Bode Magnitudes Sum - Bode Magnitudes Sum + Bode Magnitudes Sum sommephasesbode Bode Phases Sum - Bode Phases Sum + Bode Phases Sum text Text - Text + Text Texts - Texts + Texts @@ -1507,7 +1538,7 @@ File does not exist. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. @@ -1525,37 +1556,37 @@ File does not exist. usage - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 or %2 Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1564,22 +1595,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. xcursor X Cursor - X Cursor + X Cursor X Cursors - X Cursors + X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index a9a0f09..c8f4310 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -402,69 +402,6 @@ These settings can be changed at any time from the "Settings" menu. - - LogarithmPlotter - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - - - ObjectCreationGrid @@ -547,7 +484,7 @@ These settings can be changed at any time from the "Settings" menu. - + (no pick selected) @@ -922,7 +859,7 @@ These settings can be changed at any time from the "Settings" menu. - + Error while parsing expression for property %1: %2 @@ -930,7 +867,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -941,7 +878,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -955,27 +892,90 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error + + io + + + Objects + + + + + Settings + + + + + History + + + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save file: + + + + + Loaded file '%1'. + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter + + + latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -984,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -992,26 +992,6 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - update @@ -1020,7 +1000,7 @@ File does not exist. - + No update available. @@ -1038,36 +1018,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 68b0f1a..d1c0f95 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -203,13 +203,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -261,32 +261,32 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -445,64 +445,52 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - Objects - Objets + Objets - Settings - Paramètres + Paramètres - History - Historique + Historique - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. - Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. - Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. - Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. - Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : - Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. - Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! - &Update - &Mise à jour + &Mise à jour - &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -527,23 +515,23 @@ These settings can always be changed at any time from the "Settings" m Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -583,7 +571,7 @@ These settings can always be changed at any time from the "Settings" m Snap to grid - Placement sur la grille + Placement sur la grille @@ -611,7 +599,7 @@ These settings can always be changed at any time from the "Settings" m Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -824,31 +812,31 @@ These settings can always be changed at any time from the "Settings" m color %1 %2's color changed from %3 to %4. - %1 %2 a été re colorisé du %3 au %4. + %1 %2 a été re colorisé du %3 au %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) + Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) Note: Specify the probability for each value. - Note : Spécifiez la probabilité pour chaque valeur. + Note : Spécifiez la probabilité pour chaque valeur. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... - Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. + Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -867,25 +855,25 @@ These settings can always be changed at any time from the "Settings" m create New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. delete %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 of %2 changed from %3 to %4. - %1 de %2 modifiée de %3 à %4. + %1 de %2 modifiée de %3 à %4. @@ -952,11 +940,11 @@ These settings can always be changed at any time from the "Settings" m Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. @@ -1050,7 +1038,7 @@ These settings can always be changed at any time from the "Settings" m Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1061,7 +1049,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1075,7 +1063,7 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe @@ -1092,7 +1080,7 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur @@ -1101,63 +1089,126 @@ Formule analysée : %3 function Function - Fonction + Fonction Functions - Fonctions + Fonctions gainbode Bode Magnitude - Gain de Bode + Gain de Bode Bode Magnitudes - Gains de Bode + Gains de Bode low-pass - passe-bas + passe-bas high-pass - passe-haut + passe-haut historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. + + + + io + + + Objects + Objets + + + + Settings + Paramètres + + + + History + Historique + + + + Saved plot to '%1'. + Graphe sauvegardé dans '%1'. + + + + Loading file '%1'. + Chargement du fichier '%1'. + + + + Unknown object type: %1. + Type d'objet inconnu : %1. + + + + Invalid file provided. + Fichier fourni invalide. + + + + Could not save file: + Impossible de sauvegarder le fichier : + + + + Loaded file '%1'. + Fichier '%1' chargé. + + + + Copied plot screenshot to clipboard! + Image du graphe copiée dans le presse-papiers ! + + + + &Update + &Mise à jour + + + + &Update LogarithmPlotter + &Mettre à jour LogarithmPlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1166,12 +1217,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1184,7 +1235,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1195,317 +1246,297 @@ Le processus '{}' a mis trop de temps à se terminer : Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 renommé(e) en %3. + %1 %2 renommé(e) en %3. parameters above - ↑ Au dessus + ↑ Au dessus below - ↓ En dessous + ↓ En dessous left - ← À gauche + ← À gauche right - → À droite + → À droite above-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche above-right - ↗ Au dessus à droite + ↗ Au dessus à droite below-left - ↙ En dessous à gauche + ↙ En dessous à gauche below-right - ↘ En dessous à droite + ↘ En dessous à droite center - >|< Centré + >|< Centré top - ↑ Au dessus + ↑ Au dessus bottom - ↓ En dessous + ↓ En dessous top-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche top-right - ↗ Au dessus à droite + ↗ Au dessus à droite bottom-left - ↙ En dessous à gauche + ↙ En dessous à gauche bottom-right - ↘ En dessous à droite + ↘ En dessous à droite application - Application + Application function - Fonction + Fonction high - Haut + Haut low - Bas + Bas Next to target - A côté de la cible + A côté de la cible With label - Avec l'étiquette + Avec l'étiquette Hidden - Caché + Caché phasebode Bode Phase - Phase de Bode + Phase de Bode Bode Phases - Phases de Bode + Phases de Bode point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 a été déplacé depuis "%3" vers "%4". + %1 %2 a été déplacé depuis "%3" vers "%4". Position of %1 set from %2 to %3. - %1 a été déplacé depuis %2 vers %3. + %1 a été déplacé depuis %2 vers %3. prop expression - Expression + Expression definitionDomain - Domaine de définition + Domaine de définition destinationDomain - Portée + Portée labelPosition - Position de l'étiquette + Position de l'étiquette displayMode - Mode d'affichage + Mode d'affichage labelX - Position en X de l'étiquette + Position en X de l'étiquette drawPoints - Afficher les points + Afficher les points drawDashedLines - Afficher les pointillés + Afficher les pointillés om_0 - ω₀ + ω₀ pass - Passe + Passe gain - Gain + Gain omGraduation - Afficher la graduation sur ω₀ + Afficher la graduation sur ω₀ phase - Phase + Phase unit - Unité de la phase + Unité de la phase x - X + X y - Y + Y pointStyle - Style du point + Style du point probabilities - Liste de probabilités + Liste de probabilités text - Contenu + Contenu disableLatex - Désactiver le rendu LaTeX pour ce texte + Désactiver le rendu LaTeX pour ce texte targetElement - Objet à cibler + Objet à cibler approximate - Afficher la valeur approximative + Afficher la valeur approximative rounding - Arrondi + Arrondi displayStyle - Style d'affichage + Style d'affichage targetValuePosition - Position de la valeur de la cible + Position de la valeur de la cible defaultExpression - Expression + Expression baseValues - Valeurs d'initialisation + Valeurs d'initialisation color - Couleur + Couleur repartition Repartition - Répartition + Répartition Repartition functions - Fonctions de répartition + Fonctions de répartition sequence Sequence - Suite + Suite Sequences - Suites + Suites sommegainsbode Bode Magnitudes Sum - Sommes des gains de Bode + Sommes des gains de Bode sommephasesbode Bode Phases Sum - Somme des phases de Bode + Somme des phases de Bode text Text - Texte + Texte Texts - Textes + Textes @@ -1516,7 +1547,7 @@ File does not exist. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. @@ -1534,37 +1565,37 @@ File does not exist. usage - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 or %2 Emploi : %1 ou %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) @@ -1573,22 +1604,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). xcursor X Cursor - Curseur X + Curseur X X Cursors - Curseurs X + Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 5a311df..9222b65 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -437,64 +437,52 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - Objects - Tárgyak + Tárgyak - Settings - Beállítások + Beállítások - History - Előzmények + Előzmények - Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. - Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. - Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. - Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. - Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: - Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. - Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! - &Update - &Frissítés + &Frissítés - &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -519,23 +507,23 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -575,7 +563,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid - Rácshoz illesztés + Rácshoz illesztés @@ -603,7 +591,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -816,30 +804,30 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color %1 %2's color changed from %3 to %4. - %1 %2 színe %3-ról %4-re változott. + %1 %2 színe %3-ról %4-re változott. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) + A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) Note: Specify the probability for each value. - Megjegyzés: Adja meg az egyes értékek valószínűségét. + Megjegyzés: Adja meg az egyes értékek valószínűségét. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … If you have latex enabled, you can use use latex markup in between $$ to create equations. - Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. + Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -858,25 +846,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. delete %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 of %2 changed from %3 to %4. - %1/%2 megváltozott. Régi érték: %3, új érték: %4. + %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -943,11 +931,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. @@ -1041,7 +1029,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba @@ -1092,59 +1080,122 @@ Kiértékelt kifejezés: %3 function Function - Függvény + Függvény Functions - Függvények + Függvények gainbode Bode Magnitude - Bode-nagyságrend + Bode-nagyságrend Bode Magnitudes - Bode-nagyságrendek + Bode-nagyságrendek low-pass - aluláteresztő + aluláteresztő high-pass - felüláteresztő + felüláteresztő historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. + + + + io + + + Objects + + + + + Settings + Beállítások + + + + History + Előzmények + + + + Saved plot to '%1'. + Ábra mentve ide: „%1”. + + + + Loading file '%1'. + A(z) „%1” fájl betöltése folyamatban van. + + + + Unknown object type: %1. + Ismeretlen objektumtípus: %1. + + + + Invalid file provided. + A megadott fájl érvénytelen. + + + + Could not save file: + A fájl mentése nem sikerült: + + + + Loaded file '%1'. + A(z) „%1” fájl betöltve. + + + + Copied plot screenshot to clipboard! + Ábra képernyőkép vágólapra másolva! + + + + &Update + &Frissítés + + + + &Update LogarithmPlotter + A LogarithmPlotter &frissítése latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1153,12 +1204,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1171,7 +1222,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1182,313 +1233,293 @@ A(z) „{}” folyamat túl sokáig tartott a befejezéshez: Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 átnevezve erre: %3. + %1 %2 átnevezve erre: %3. parameters above - ↑ Felett + ↑ Felett below - ↓ Alatt + ↓ Alatt left - ← Balra + ← Balra right - → Jobbra + → Jobbra above-left - ↖ Felett, balra + ↖ Felett, balra above-right - ↗ Felett, jobbra + ↗ Felett, jobbra below-left - ↙ Alatt, balra + ↙ Alatt, balra below-right - ↘ Alatt, jobbra + ↘ Alatt, jobbra center - >|< Középre + >|< Középre top - ↑ Felső + ↑ Felső bottom - ↓ Alsó + ↓ Alsó top-left - ↖ Bal felső + ↖ Bal felső top-right - ↗ Jobb felső + ↗ Jobb felső bottom-left - ↙ Bal alsó + ↙ Bal alsó bottom-right - ↘ Jobb alsó + ↘ Jobb alsó application - Alkalmazás + Alkalmazás function - Függvény + Függvény high - Magas + Magas low - Alul + Alul Next to target - Cél mellé + Cél mellé With label - Címkével + Címkével Hidden - Rejtett + Rejtett phasebode Bode Phase - Bode-fázis + Bode-fázis Bode Phases - Bode-fázisok + Bode-fázisok point Point - Pont + Pont Points - Pontok + Pontok position Position of %1 %2 set from "%3" to "%4". - %1 %2 áthelyezve innen: „%3” ide: „%4”. + %1 %2 áthelyezve innen: „%3” ide: „%4”. Position of %1 set from %2 to %3. - %1 áthelyezve innen: %2 ide: %3. + %1 áthelyezve innen: %2 ide: %3. prop expression - Kifejezés + Kifejezés definitionDomain - Abszcissza tartomány + Abszcissza tartomány destinationDomain - Ordináta tartomány + Ordináta tartomány labelPosition - Címke helyzete + Címke helyzete displayMode - Megjelenítési mód + Megjelenítési mód labelX - Címke X helyzete + Címke X helyzete drawPoints - Pontok megjelenítése + Pontok megjelenítése drawDashedLines - Szaggatott vonalak megjelenítése + Szaggatott vonalak megjelenítése om_0 - ω₀ + ω₀ pass - Áteresztő + Áteresztő gain - Nagyságrend nyeresége + Nagyságrend nyeresége omGraduation - ω₀ érettségi megjelenítése + ω₀ érettségi megjelenítése phase - Fázis + Fázis unit - Egység használata + Egység használata x - X + X y - Y + Y pointStyle - Pontstílus + Pontstílus probabilities - Valószínűségek listája + Valószínűségek listája text - Tartalom + Tartalom disableLatex - LaTeX-megjelenítés letiltása ennél a szövegnél + LaTeX-megjelenítés letiltása ennél a szövegnél targetElement - Tárgycél + Tárgycél approximate - Hozzávetőleges érték megjelenítése + Hozzávetőleges érték megjelenítése rounding - Kerekítés + Kerekítés displayStyle - Megjelenítési stílus + Megjelenítési stílus targetValuePosition - Cél értékpozíciója + Cél értékpozíciója defaultExpression - Alapértelmezett kifejezés + Alapértelmezett kifejezés baseValues - Kezdeményezési értékek + Kezdeményezési értékek repartition Repartition - Elosztás + Elosztás Repartition functions - Elosztási függvények + Elosztási függvények sequence Sequence - Sorozat + Sorozat Sequences - Sorozatok + Sorozatok sommegainsbode Bode Magnitudes Sum - Bode-nagyságrendek összege + Bode-nagyságrendek összege sommephasesbode Bode Phases Sum - Bode-fázisok összege + Bode-fázisok összege text Text - Szöveg + Szöveg Texts - Szövegek + Szövegek @@ -1499,7 +1530,7 @@ File does not exist. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. @@ -1517,37 +1548,37 @@ File does not exist. usage - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 or %2 Használat: %1 vagy %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) @@ -1556,22 +1587,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. xcursor X Cursor - X kurzor + X kurzor X Cursors - X kurzorok + X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 98fa6fb..faeb53b 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Om @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -437,64 +437,52 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - Objects - Objekter + Objekter - Settings - Innstillinger + Innstillinger - History - Historikk + Historikk - Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». - Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. - Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. - Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. - Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: - Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». - Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! - &Update - &Oppdater + &Oppdater - &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -519,11 +507,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -531,11 +519,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -575,7 +563,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid - Fest til rutenett + Fest til rutenett @@ -603,7 +591,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + (no pick selected) @@ -999,7 +987,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Error while parsing expression for property %1: %2 @@ -1007,7 +995,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1018,7 +1006,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -1032,7 +1020,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1041,71 +1029,134 @@ Evaluated expression: %3 function Function - Funksjon + Funksjon Functions - Funksjoner + Funksjoner gainbode Bode Magnitude - Bode-magnitude + Bode-magnitude Bode Magnitudes - Bode-magnituder + Bode-magnituder low-pass - lavpass + lavpass high-pass - høypass + høypass historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. + + + + io + + + Objects + Objekter + + + + Settings + Innstillinger + + + + History + Historikk + + + + Saved plot to '%1'. + Lagret plott i «%1». + + + + Loading file '%1'. + Laster inn «%1»-fil. + + + + Unknown object type: %1. + Ukjent objekttype: %1. + + + + Invalid file provided. + Ugyldig fil angitt. + + + + Could not save file: + Kunne ikke lagre fil: + + + + Loaded file '%1'. + Lastet inn filen «%1». + + + + Copied plot screenshot to clipboard! + Kopierte plott-skjermavbildning til utklippstavlen! + + + + &Update + &Oppdater + + + + &Update LogarithmPlotter + &Installer ny versjon av LogartimePlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1114,7 +1165,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1122,64 +1173,44 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - phasebode Bode Phase - Bode-fase + Bode-fase Bode Phases - Bode-faser + Bode-faser point Point - Punkt + Punkt Points - Punkter + Punkter repartition Repartition - Distribusjon + Distribusjon Repartition functions - Distribusjonsfunksjoner + Distribusjonsfunksjoner sequence Sequence - Følge + Følge Sequences @@ -1190,25 +1221,25 @@ File does not exist. sommegainsbode Bode Magnitudes Sum - Bode-magnitudesum + Bode-magnitudesum sommephasesbode Bode Phases Sum - Bode-fasesum + Bode-fasesum text Text - Tekst + Tekst Texts - Tekster + Tekster @@ -1219,7 +1250,7 @@ File does not exist. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. @@ -1237,36 +1268,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index b88fc2e..3e4a80b 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -402,69 +402,6 @@ These settings can be changed at any time from the "Settings" menu. - - LogarithmPlotter - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - - - ObjectCreationGrid @@ -547,7 +484,7 @@ These settings can be changed at any time from the "Settings" menu. - + (no pick selected) @@ -922,7 +859,7 @@ These settings can be changed at any time from the "Settings" menu. - + Error while parsing expression for property %1: %2 @@ -930,7 +867,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -941,7 +878,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -955,27 +892,90 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error + + io + + + Objects + + + + + Settings + + + + + History + + + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save file: + + + + + Loaded file '%1'. + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter + + + latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -984,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -992,26 +992,6 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - update @@ -1020,7 +1000,7 @@ File does not exist. - + No update available. @@ -1038,36 +1018,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 5270534..d4fd4aa 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -41,15 +41,16 @@ chdir(path.dirname(path.realpath(__file__))) if path.realpath(path.join(getcwd(), "..")) not in sys_path: sys_path.append(path.realpath(path.join(getcwd(), ".."))) - from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config, native from LogarithmPlotter.util.update import check_for_updates from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex +from LogarithmPlotter.util.js import PyJSValue config.init() + def get_linux_theme(): des = { "KDE": "Fusion", @@ -62,9 +63,9 @@ def get_linux_theme(): else: # Android return "Material" - + + def run(): - if not 'QT_QUICK_CONTROLS_STYLE' in environ: environ["QT_QUICK_CONTROLS_STYLE"] = { "linux": get_linux_theme(), @@ -73,9 +74,9 @@ def run(): "cygwin": "Fusion", "darwin": "macOS" }[platform] - + dep_time = time() - print("Loaded dependencies in " + str((dep_time - start_time)*1000) + "ms.") + print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") icon_fallbacks = QIcon.fallbackSearchPaths(); base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") @@ -85,47 +86,45 @@ def run(): icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) QIcon.setFallbackSearchPaths(icon_fallbacks); - - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) - + # Installing translators translator = QTranslator() # Check if lang is forced. - forcedlang = [p for p in argv if p[:7]=="--lang="] + forcedlang = [p for p in argv if p[:7] == "--lang="] locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() - if (translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n")))): + if translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): app.installTranslator(translator); - + # Installing macOS file handler. macOSFileOpenHandler = None if platform == "darwin": macOSFileOpenHandler = native.MacOSFileOpenHandler() app.installEventFilter(macOSFileOpenHandler) - + engine = QQmlApplicationEngine() global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) - modules = engine.newObject() - engine.globalObject().setProperty('Modules', modules) - engine.globalObject().setProperty('Helper', engine.newQObject(helper)) - engine.globalObject().setProperty("Latex", engine.newQObject(latex)) - # engine.rootContext().setContextProperty("Helper", helper) - # engine.rootContext().setContextProperty("Latex", latex) + js_globals = PyJSValue(engine.globalObject()) + js_globals.Modules = engine.newObject() + js_globals.Helper = engine.newQObject(helper) + js_globals.Latex = engine.newQObject(latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) - - app.translate("About","About LogarithmPlotter") # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. + + app.translate("About", "About LogarithmPlotter") + # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. engine.addImportPath(path.realpath(path.join(getcwd(), "qml"))) engine.load(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) - if not engine.rootObjects(): print("No root object", path.realpath(path.join(getcwd(), "qml"))) @@ -135,26 +134,26 @@ def run(): # Open the current diagram chdir(pwd) if len(argv) > 0 and path.exists(argv[-1]) and argv[-1].split('.')[-1] in ['lpf']: - engine.rootObjects()[0].loadDiagram(argv[-1]) + js_globals.Modules.IO.loadDiagram(argv[-1]) chdir(path.dirname(path.realpath(__file__))) - + if platform == "darwin": - macOSFileOpenHandler.init_graphics(engine.rootObjects()[0]) - + macOSFileOpenHandler.init_io(js_globals.Modules.IO) + # Check for LaTeX installation if LaTeX support is enabled if config.getSetting("enable_latex"): latex.check_latex_install() - + # Check for updates if config.getSetting("check_for_updates"): check_for_updates(__VERSION__, engine.rootObjects()[0]) - + exit_code = app.exec() - + tempdir.cleanup() config.save() exit(exit_code) + if __name__ == "__main__": run() - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 3fb9697..388264c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -86,19 +86,19 @@ ApplicationWindow { width: parent.width anchors.top: parent.top TabButton { - text: qsTr("Objects") + text: qsTranslate('io', "Objects") icon.name: 'polygon-add-nodes' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTr("Settings") + text: qsTranslate('io', "Settings") icon.name: 'preferences-system-symbolic' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTr("History") + text: qsTranslate('io', "History") icon.name: 'view-history' icon.color: sysPalette.windowText //height: 24 @@ -159,7 +159,7 @@ ApplicationWindow { property bool firstDrawDone: false - onPainted: if(!firstDrawDone) { + onPainted: if(!firstDrawDone) { firstDrawDone = true; console.info("First paint done in " + (new Date().getTime()-(StartTime*1000)) + "ms") if(TestBuild == true) { @@ -182,130 +182,6 @@ ApplicationWindow { } } - /*! - \qmlmethod void LogarithmPlotter::saveDiagram(string filename) - Saves the diagram to a certain \c filename. - */ - function saveDiagram(filename) { - if(['lpf'].indexOf(filename.split('.')[filename.split('.').length-1]) == -1) - filename += '.lpf' - settings.saveFilename = filename - var objs = {} - for(var objType in Modules.Objects.currentObjects){ - objs[objType] = [] - for(var obj of Modules.Objects.currentObjects[objType]) { - objs[objType].push(obj.export()) - } - } - Helper.write(filename, JSON.stringify({ - "xzoom": settings.xzoom, - "yzoom": settings.yzoom, - "xmin": settings.xmin, - "ymax": settings.ymax, - "xaxisstep": settings.xaxisstep, - "yaxisstep": settings.yaxisstep, - "xaxislabel": settings.xlabel, - "yaxislabel": settings.ylabel, - "logscalex": settings.logscalex, - "linewidth": settings.linewidth, - "showxgrad": settings.showxgrad, - "showygrad": settings.showygrad, - "textsize": settings.textsize, - "history": history.serialize(), - "width": root.width, - "height": root.height, - "objects": objs, - "type": "logplotv1" - })) - alert.show(qsTr("Saved plot to '%1'.").arg(filename.split("/").pop())) - history.saved = true - } - - /*! - \qmlmethod void LogarithmPlotter::saveDiagram(string filename) - Loads the diagram from a certain \c filename. - */ - function loadDiagram(filename) { - let basename = filename.split("/").pop() - alert.show(qsTr("Loading file '%1'.").arg(basename)) - let data = JSON.parse(Helper.load(filename)) - let error = ""; - if(Object.keys(data).includes("type") && data["type"] == "logplotv1") { - history.clear() - // Importing settings - settings.saveFilename = filename - settings.xzoom = data["xzoom"] - settings.yzoom = data["yzoom"] - settings.xmin = data["xmin"] - settings.ymax = data["ymax"] - settings.xaxisstep = data["xaxisstep"] - settings.yaxisstep = data["yaxisstep"] - settings.xlabel = data["xaxislabel"] - settings.ylabel = data["yaxislabel"] - settings.logscalex = data["logscalex"] - if("showxgrad" in data) - settings.showxgrad = data["showxgrad"] - if("showygrad" in data) - settings.textsize = data["showygrad"] - if("linewidth" in data) - settings.linewidth = data["linewidth"] - if("textsize" in data) - settings.textsize = data["textsize"] - root.height = data["height"] - root.width = data["width"] - - // Importing objects - Modules.Objects.currentObjects = {} - Modules.Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Modules.Objects.currentObjectsByName[key]; - // Required to keep the same reference for the copy of the object used in expression variable detection. - // Another way would be to change the reference as well, but I feel like the code would be less clean. - }) - for(let objType in data['objects']) { - if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { - Modules.Objects.currentObjects[objType] = [] - for(let objData of data['objects'][objType]) { - let obj = new Modules.Objects.types[objType](...objData) - Modules.Objects.currentObjects[objType].push(obj) - Modules.Objects.currentObjectsByName[obj.name] = obj - } - } else { - error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; - } - } - - // Updating object dependencies. - for(let objName in Modules.Objects.currentObjectsByName) - Modules.Objects.currentObjectsByName[objName].update() - - // Importing history - if("history" in data) - history.unserialize(...data["history"]) - - // Refreshing sidebar - if(sidebarSelector.currentIndex == 0) { - // For some reason, if we load a file while the tab is on object, - // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. - sidebarSelector.currentIndex = 1 - objectLists.update() - delayRefreshTimer.start() - } else { - objectLists.update() - } - } else { - error = qsTr("Invalid file provided.") - } - if(error != "") { - console.log(error) - alert.show(qsTr("Could not save file: ") + error) - // TODO: Error handling - return - } - drawCanvas.requestPaint() - alert.show(qsTr("Loaded file '%1'.").arg(basename)) - history.saved = true - } - Timer { id: delayRefreshTimer repeat: false @@ -327,6 +203,22 @@ ApplicationWindow { } } + /*! + \qmlmethod void LogarithmPlotter::updateObjectsLists() + Updates the objects lists when loading a file. + */ + function updateObjectsLists() { + if(sidebarSelector.currentIndex === 0) { + // For some reason, if we load a file while the tab is on object, + // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. + sidebarSelector.currentIndex = 1 + objectLists.update() + delayRefreshTimer.start() + } else { + objectLists.update() + } + } + /*! \qmlmethod void LogarithmPlotter::copyDiagramToClipboard() Copies the current diagram image to the clipboard. @@ -335,7 +227,7 @@ ApplicationWindow { var file = Helper.gettmpfile() drawCanvas.save(file) Helper.copyImageToClipboard() - alert.show(qsTr("Copied plot screenshot to clipboard!")) + alert.show(qsTranslate('io', "Copied plot screenshot to clipboard!")) } /*! @@ -350,11 +242,11 @@ ApplicationWindow { Menu { id: updateMenu - title: qsTr("&Update") + title: qsTranslate('io', "&Update") Action { - text: qsTr("&Update LogarithmPlotter") + text: qsTranslate('io', "&Update LogarithmPlotter") icon.name: 'update' - onTriggered: Qt.openUrlExternally("https://dev.apps.ad5001.eu/logarithmplotter") + onTriggered: Qt.openUrlExternally("https://apps.ad5001.eu/logarithmplotter/") } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index b15caed..cf09695 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -127,6 +127,10 @@ ScrollView { */ property string saveFilename: "" + Component.onCompleted: { + Modules.IO.initialize(root, settings, alert) + } + Column { spacing: 10 width: parent.width @@ -138,9 +142,9 @@ ScrollView { var filePath = fdiag.currentFile.toString().substr(7) settings.saveFilename = filePath if(exportMode) { - root.saveDiagram(filePath) + Modules.IO.saveDiagram(filePath) } else { - root.loadDiagram(filePath) + Modules.IO.loadDiagram(filePath) if(xAxisLabel.find(settings.xlabel) == -1) xAxisLabel.model.append({text: settings.xlabel}) xAxisLabel.editText = settings.xlabel if(yAxisLabel.find(settings.ylabel) == -1) yAxisLabel.model.append({text: settings.ylabel}) @@ -442,7 +446,7 @@ ScrollView { if(settings.saveFilename == "") { saveAs() } else { - root.saveDiagram(settings.saveFilename) + Modules.IO.saveDiagram(settings.saveFilename) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 4c79c64..9f207a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -5,4 +5,5 @@ .import "objs/autoload.mjs" as Autoload .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon -.import "canvas.mjs" as CanvasAPI \ No newline at end of file +.import "canvas.mjs" as CanvasAPI +.import "io.mjs" as IOAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index b662098..66d35fd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -34,7 +34,10 @@ class HistoryCommonAPI extends Module { undo() { this.history.undo() } redo() { this.history.redo() } + clear() { this.history.clear() } addToHistory(action) { this.history.addToHistory(action) } + unserialize(data) { this.history.unserialize(data) } + serialize() { return this.history.serialize() } } /** @type {HistoryCommonAPI} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs new file mode 100644 index 0000000..fe87ad8 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -0,0 +1,168 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Module} from "./modules.mjs" + +class IOAPI extends Module { + + constructor() { + super('IO', [ + Modules.Objects, + Modules.History + ]) + /** + * Path of the currently opened file. Empty if no file is opened. + * @type {string} + */ + this.saveFileName = "" + } + + /** + * Initializes module with QML elements. + * @param {LogarithmPlotter} rootElement + * @param {Settings} settings + * @param {{show: function(string)}} alert + */ + initialize(rootElement, settings, alert) { + this.rootElement = rootElement + this.settings = settings + this.alert = alert + } + + /** + * Saves the diagram to a certain \c filename. + * @param {string} filename + */ + saveDiagram(filename) { + // Add extension if necessary + if(['lpf'].indexOf(filename.split('.')[filename.split('.').length-1]) === -1) + filename += '.lpf' + this.saveFilename = filename + let objs = {} + for(let objType in Modules.Objects.currentObjects){ + objs[objType] = [] + for(let obj of Modules.Objects.currentObjects[objType]) { + objs[objType].push(obj.export()) + } + } + let settings = { + "xzoom": this.settings.xzoom, + "yzoom": this.settings.yzoom, + "xmin": this.settings.xmin, + "ymax": this.settings.ymax, + "xaxisstep": this.settings.xaxisstep, + "yaxisstep": this.settings.yaxisstep, + "xaxislabel": this.settings.xlabel, + "yaxislabel": this.settings.ylabel, + "logscalex": this.settings.logscalex, + "linewidth": this.settings.linewidth, + "showxgrad": this.settings.showxgrad, + "showygrad": this.settings.showygrad, + "textsize": this.settings.textsize, + "history": Modules.History.serialize(), + "width": this.rootElement.width, + "height": this.rootElement.height, + "objects": objs, + "type": "logplotv1" + } + Helper.write(filename, JSON.stringify(settings)) + this.alert.show(qsTranslate('io', "Saved plot to '%1'.").arg(filename.split("/").pop())) + Modules.History.history.saved = true + } + + /** + * Loads the diagram from a certain \c filename. + * @param {string} filename + */ + loadDiagram(filename) { + let basename = filename.split("/").pop() + this.alert.show(qsTranslate('io', "Loading file '%1'.").arg(basename)) + let data = JSON.parse(Helper.load(filename)) + let error = ""; + if(Object.keys(data).includes("type") && data["type"] === "logplotv1") { + Modules.History.clear() + // Importing settings + this.settings.saveFilename = filename + this.settings.xzoom = data["xzoom"] + this.settings.yzoom = data["yzoom"] + this.settings.xmin = data["xmin"] + this.settings.ymax = data["ymax"] + this.settings.xaxisstep = data["xaxisstep"] + this.settings.yaxisstep = data["yaxisstep"] + this.settings.xlabel = data["xaxislabel"] + this.settings.ylabel = data["yaxislabel"] + this.settings.logscalex = data["logscalex"] + if("showxgrad" in data) + this.settings.showxgrad = data["showxgrad"] + if("showygrad" in data) + this.settings.textsize = data["showygrad"] + if("linewidth" in data) + this.settings.linewidth = data["linewidth"] + if("textsize" in data) + this.settings.textsize = data["textsize"] + this.rootElement.height = data["height"] + this.rootElement.width = data["width"] + + // Importing objects + Modules.Objects.currentObjects = {} + for(let key of Object.keys(Modules.Objects.currentObjectsByName)) { + delete Modules.Objects.currentObjectsByName[key]; + // Required to keep the same reference for the copy of the object used in expression variable detection. + // Another way would be to change the reference as well, but I feel like the code would be less clean. + } + for(let objType in data['objects']) { + if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { + Modules.Objects.currentObjects[objType] = [] + for(let objData of data['objects'][objType]) { + let obj = new Modules.Objects.types[objType](...objData) + Modules.Objects.currentObjects[objType].push(obj) + Modules.Objects.currentObjectsByName[obj.name] = obj + } + } else { + error += qsTranslate('io', "Unknown object type: %1.").arg(objType) + "\n"; + } + } + + // Updating object dependencies. + for(let objName in Modules.Objects.currentObjectsByName) + Modules.Objects.currentObjectsByName[objName].update() + + // Importing history + if("history" in data) + Modules.History.unserialize(...data["history"]) + + // Refreshing sidebar + this.rootElement.updateObjectsLists() + } else { + error = qsTranslate('io', "Invalid file provided.") + } + if(error !== "") { + console.log(error) + this.alert.show(qsTranslate('io', "Could not save file: ") + error) + // TODO: Error handling + return + } + Modules.Canvas.redraw() + this.alert.show(qsTranslate('io', "Loaded file '%1'.").arg(basename)) + Modules.History.history.saved = true + } + +} + +/** @type {IOAPI} */ +Modules.IO = Modules.IO || new IOAPI() diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index f19e000..bdd11b7 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -47,7 +47,7 @@ CONFIG_PATH = { CONFIG_FILE = path.join(CONFIG_PATH, "config.json") initialized = False -current_config= DEFAULT_SETTINGS +current_config = DEFAULT_SETTINGS def init(): diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 127e587..e6e9dfb 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -31,11 +31,12 @@ from urllib.error import HTTPError, URLError from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config + class ChangelogFetcher(QRunnable): def __init__(self, helper): QRunnable.__init__(self) self.helper = helper - + def run(self): msg_text = "Unknown changelog error." try: @@ -43,17 +44,19 @@ class ChangelogFetcher(QRunnable): r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + __VERSION__) lines = r.readlines() r.close() - msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() + msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() except HTTPError as e: - msg_text = QCoreApplication.translate("changelog","Could not fetch changelog: Server error {}.").format(str(e.code)) + msg_text = QCoreApplication.translate("changelog", "Could not fetch changelog: Server error {}.").format( + str(e.code)) except URLError as e: - msg_text = QCoreApplication.translate("changelog","Could not fetch update: {}.").format(str(e.reason)) + msg_text = QCoreApplication.translate("changelog", "Could not fetch update: {}.").format(str(e.reason)) self.helper.gotChangelog.emit(msg_text) + class Helper(QObject): changelogFetched = Signal(str) gotChangelog = Signal(str) - + def __init__(self, cwd: str, tmpfile: str): QObject.__init__(self) self.cwd = cwd @@ -62,7 +65,7 @@ class Helper(QObject): def fetched(self, changelog: str): self.changelogFetched.emit(changelog) - + @Slot(str, str) def write(self, filename, filedata): chdir(self.cwd) @@ -70,17 +73,17 @@ class Helper(QObject): if filename.split(".")[-1] == "lpf": # Add header to file filedata = "LPFv1" + filedata - f = open(path.realpath(filename), 'w', -1, 'utf8') + f = open(path.realpath(filename), 'w', -1, 'utf8') f.write(filedata) f.close() chdir(path.dirname(path.realpath(__file__))) - + @Slot(str, result=str) def load(self, filename): chdir(self.cwd) data = '{}' if path.exists(path.realpath(filename)): - f = open(path.realpath(filename), 'r', -1, 'utf8') + f = open(path.realpath(filename), 'r', -1, 'utf8') data = f.read() f.close() try: @@ -94,10 +97,13 @@ class Helper(QObject): raise Exception(QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__))) else: raise Exception("Invalid LogarithmPlotter file.") - except Exception as e: # If file can't be loaded - QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main','Could not open file "{}":\n{}').format(filename, e), QMessageBox.Ok) # Cannot parse file + except Exception as e: # If file can't be loaded + QMessageBox.warning(None, 'LogarithmPlotter', + QCoreApplication.translate('main', 'Could not open file "{}":\n{}').format(filename, + e), + QMessageBox.Ok) # Cannot parse file else: - QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main','Could not open file: "{}"\nFile does not exist.').format(filename), QMessageBox.Ok) # Cannot parse file + QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.').format(filename), QMessageBox.Ok) # Cannot parse file try: chdir(path.dirname(path.realpath(__file__))) except NotADirectoryError as e: @@ -105,60 +111,62 @@ class Helper(QObject): # See more at https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues/1 pass return data - + @Slot(result=str) def gettmpfile(self): return self.tmpfile - + @Slot() def copyImageToClipboard(self): clipboard = QApplication.clipboard() clipboard.setImage(QImage(self.tmpfile)) - + @Slot(result=str) def getVersion(self): return __VERSION__ - + @Slot(str, result=str) def getSetting(self, namespace): return config.getSetting(namespace) - + @Slot(str, result=int) def getSettingInt(self, namespace): return config.getSetting(namespace) - + @Slot(str, result=bool) def getSettingBool(self, namespace): return config.getSetting(namespace) - + @Slot(str, str) def setSetting(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str, bool) def setSettingBool(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str, int) def setSettingInt(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str) def setLanguage(self, new_lang): config.setSetting("language", new_lang) - + @Slot(result=str) def getDebugInfos(self): """ Returns the version info about Qt, PySide6 & Python """ - return QCoreApplication.translate('main',"Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, sys_version.split("\n")[0]) - + return QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, + sys_version.split( + "\n")[0]) + @Slot() def fetchChangelog(self): changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") print(changelog_cache_path) - if path.exists(changelog_cache_path): + if path.exists(changelog_cache_path): # We have a cached version of the changelog, for env that don't have access to the internet. f = open(changelog_cache_path); self.changelogFetched.emit("".join(f.readlines()).strip()) @@ -167,4 +175,3 @@ class Helper(QObject): # Fetch it from the internet. runnable = ChangelogFetcher(self) QThreadPool.globalInstance().start(runnable) - diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py new file mode 100644 index 0000000..4514a42 --- /dev/null +++ b/LogarithmPlotter/util/js.py @@ -0,0 +1,52 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from PySide6.QtQml import QJSValue + + +class PyJSValue: + """ + Wrapper to provide easy way to interact with JavaScript values in Python directly. + """ + def __init__(self, js_value: QJSValue, parent: QJSValue = None): + self.qjs_value = js_value + self._parent = parent + + def __getattr__(self, item): + return PyJSValue(self.qjs_value.property(item), self.qjs_value) + + def __setattr__(self, key, value): + if key in ['qjs_value', '_parent']: + # Fallback + object.__setattr__(self, key, value) + elif isinstance(value, PyJSValue): + # Set property + self.qjs_value.setProperty(key, value.qjs_value) + else: + print('Setting', key, value) + self.qjs_value.setProperty(key, value) + + def __call__(self, *args, **kwargs): + if self.qjs_value.isCallable(): + if self._parent is None: + return self.qjs_value.call(args) + else: + return self.qjs_value.callWithInstance(self._parent, args) + else: + raise ValueError('Cannot call non-function JS value.') + diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index d519e18..c670e1e 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -160,10 +160,7 @@ class Latex(QObject): QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") .format(" ".join(process), proc.returncode, str(out, 'utf8') + "\n" + str(err, 'utf8'))) - raise Exception( - " ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, - 'utf8') + "\n" + str( - err, 'utf8')) + raise Exception("{0} process exited with return code {1}:\n{2}\n{3}".format(" ".join(process), str(proc.returncode), str(out, 'utf8'), str(err, 'utf8'))) except TimeoutExpired as e: # Process timed out proc.kill() diff --git a/LogarithmPlotter/util/native.py b/LogarithmPlotter/util/native.py index 01d9022..7e32119 100644 --- a/LogarithmPlotter/util/native.py +++ b/LogarithmPlotter/util/native.py @@ -20,29 +20,30 @@ from PySide6.QtCore import QObject, QEvent + # On macOS, opening a file through finder can only be fetched through the -# QFileOpenEvent and NOT throught command line parameters. +# QFileOpenEvent and NOT through command line parameters. class MacOSFileOpenHandler(QObject): def __init__(self): - self.initilized = False - self.mainwindow = None + self.initialized = False + self.io_module = None self.opened_file = "" QObject.__init__(self) - - def init_graphics(self, mainwindow): - self.mainwindow = mainwindow - self.initilized = True + + def init_io(self, io_modules): + self.io_module = io_modules + self.initialized = True if self.opened_file != "": self.open_file() - + def open_file(self): - self.mainwindow.loadDiagram(self.opened_file) - + self.io_module.loadDiagram(self.opened_file) + def eventFilter(self, obj, event): if event.type() == QEvent.FileOpen: - print("Got file", event.file(), self.initilized) + print("Got file", event.file(), self.initialized) self.opened_file = event.file() - if self.initilized: + if self.initialized: self.open_file() return True else: diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 25400ce..dbacbfe 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -21,9 +21,11 @@ from urllib.request import urlopen from urllib.error import HTTPError, URLError from sys import argv + class UpdateInformation(QObject): got_update_info = Signal(bool, str, bool) + class UpdateCheckerRunnable(QRunnable): def __init__(self, current_version, callback): QRunnable.__init__(self) @@ -40,44 +42,51 @@ class UpdateCheckerRunnable(QRunnable): lines = r.readlines() r.close() # Parsing version - version = "".join(map(chr, lines[0])).strip() # Converts byte to string. + version = "".join(map(chr, lines[0])).strip() # Converts byte to string. version_tuple = version.split(".") is_version_newer = False if "dev" in self.current_version: # We're on a dev version - current_version_tuple = self.current_version.split(".")[:-1] # Removing the dev0+git bit. - is_version_newer = version_tuple >= current_version_tuple # If equals, that means we got out of testing phase. + current_version_tuple = self.current_version.split(".")[:-1] # Removing the dev0+git bit. + is_version_newer = version_tuple >= current_version_tuple # If equals, that means we got out of testing phase. else: current_version_tuple = self.current_version.split(".") is_version_newer = version_tuple > current_version_tuple if is_version_newer: - msg_text = QCoreApplication.translate("update","An update for LogarithPlotter (v{}) is available.").format(version) + msg_text = QCoreApplication.translate("update", + "An update for LogarithPlotter (v{}) is available.").format( + version) update_available = True else: show_alert = False - msg_text = QCoreApplication.translate("update","No update available.") - + msg_text = QCoreApplication.translate("update", "No update available.") + except HTTPError as e: - msg_text = QCoreApplication.translate("update","Could not fetch update information: Server error {}.").format(str(e.code)) + msg_text = QCoreApplication.translate("update", + "Could not fetch update information: Server error {}.").format( + str(e.code)) except URLError as e: - msg_text = QCoreApplication.translate("update","Could not fetch update information: {}.").format(str(e.reason)) - self.callback.got_update_info.emit(show_alert, msg_text,update_available) + msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.").format( + str(e.reason)) + self.callback.got_update_info.emit(show_alert, msg_text, update_available) + def check_for_updates(current_version, window): """ Checks for updates in the background, and sends an alert with information. """ if "--no-check-for-updates" in argv: - return # + return + def cb(show_alert, msg_text, update_available): pass if show_alert: window.showAlert(msg_text) if update_available: window.showUpdateMenu() - + update_info = UpdateInformation() update_info.got_update_info.connect(cb) - + runnable = UpdateCheckerRunnable(current_version, update_info) QThreadPool.globalInstance().start(runnable) From 8e75f13e9a9417c60bf5729d705247a27f0621b3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 17:56:09 +0100 Subject: [PATCH 008/249] Removing vanished translations. --- LogarithmPlotter/i18n/lp_de.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_en.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_fr.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_hu.ts | 232 ++++++++++++++--------------- LogarithmPlotter/i18n/lp_nb_NO.ts | 92 ++++++------ 5 files changed, 516 insertions(+), 516 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 407b284..4d9a064 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -438,51 +438,51 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter Objects - Objekte + Objekte Settings - Einstellungen + Einstellungen History - Verlauf + Verlauf Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! &Update - &Aktualisieren + &Aktualisieren &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -507,23 +507,23 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -563,7 +563,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid - Am Gitter einrasten + Am Gitter einrasten @@ -804,30 +804,30 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color %1 %2's color changed from %3 to %4. - %1 %2 wurde von %3 bis %4 umgefärbt. + %1 %2 wurde von %3 bis %4 umgefärbt. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) + Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) Note: Specify the probability for each value. - Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. + Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. + Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -846,25 +846,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. delete %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 of %2 changed from %3 to %4. - %1 von %2 wurde von %3 auf %4 geändert. + %1 von %2 wurde von %3 auf %4 geändert. @@ -931,11 +931,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. @@ -1080,57 +1080,57 @@ Ausdruck analysiert: %3 function Function - Funktion + Funktion Functions - Funktionen + Funktionen gainbode Bode Magnitude - Bode-Magnitude + Bode-Magnitude Bode Magnitudes - Bode-Magnituden + Bode-Magnituden low-pass - Tiefpass + Tiefpass high-pass - Hochpass + Hochpass historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. @@ -1241,293 +1241,293 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde name %1 %2 renamed to %3. - %1 %2 umbenannt in %3. + %1 %2 umbenannt in %3. parameters above - ↑ Über + ↑ Über below - ↓ Unter + ↓ Unter left - ← Links + ← Links right - → Rechts + → Rechts above-left - ↖ Oben links + ↖ Oben links above-right - ↗ Oben rechts + ↗ Oben rechts below-left - ↙ Unten links + ↙ Unten links below-right - ↘ Unten rechts + ↘ Unten rechts center - >|< Zentrum + >|< Zentrum top - ↑ Über + ↑ Über bottom - ↓ Unter + ↓ Unter top-left - ↖ Oben links + ↖ Oben links top-right - ↗ Oben rechts + ↗ Oben rechts bottom-left - ↙ Unten links + ↙ Unten links bottom-right - ↘ Unten rechts + ↘ Unten rechts application - Anwendung + Anwendung function - Funktion + Funktion high - Hoch + Hoch low - Tief + Tief Next to target - Neben dem Ziel + Neben dem Ziel With label - Mit Etikett + Mit Etikett Hidden - Versteckt + Versteckt phasebode Bode Phase - Bode-Phase + Bode-Phase Bode Phases - Bode-Phasen + Bode-Phasen point Point - Punkt + Punkt Points - Punkte + Punkte position Position of %1 %2 set from "%3" to "%4". - %1 %2 wurde von "%3" nach "%4" verschoben. + %1 %2 wurde von "%3" nach "%4" verschoben. Position of %1 set from %2 to %3. - %1 wurde von %2 nach %3 verschoben. + %1 wurde von %2 nach %3 verschoben. prop expression - Ausdruck + Ausdruck definitionDomain - Definitionsbereich + Definitionsbereich destinationDomain - Reichweite + Reichweite labelPosition - Position des Etiketts + Position des Etiketts displayMode - Anzeigemodus + Anzeigemodus labelX - X-Position des Etiketts + X-Position des Etiketts drawPoints - Unentschiedene Punkte + Unentschiedene Punkte drawDashedLines - Gestrichelte Linien anzeigen + Gestrichelte Linien anzeigen om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Größenordnung + Größenordnung omGraduation - Teilung auf ω zeigen + Teilung auf ω zeigen phase - Phase + Phase unit - Einheit + Einheit x - X + X y - Y + Y pointStyle - Punkt-Stil + Punkt-Stil probabilities - Wahrscheinlichkeiten + Wahrscheinlichkeiten text - Inhalt + Inhalt disableLatex - LaTeX-Rendering für diesen Text deaktivieren + LaTeX-Rendering für diesen Text deaktivieren targetElement - Zielobjekt + Zielobjekt approximate - Ungefähren Wert anzeigen + Ungefähren Wert anzeigen rounding - Rundung + Rundung displayStyle - Stil + Stil targetValuePosition - Wertposition des Ziels + Wertposition des Ziels defaultExpression - Standardausdruck + Standardausdruck baseValues - Initialisierungswerte + Initialisierungswerte color - Farbe + Farbe repartition Repartition - Verteilungsfunktion + Verteilungsfunktion Repartition functions - Verteilungsfunktionen + Verteilungsfunktionen sequence Sequence - Folge + Folge Sequences - Folgen + Folgen sommegainsbode Bode Magnitudes Sum - Bode-Magnituden Summe + Bode-Magnituden Summe sommephasesbode Bode Phases Sum - Bode-Phasen Summe + Bode-Phasen Summe text Text - Text + Text Texts - Texte + Texte @@ -1595,22 +1595,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. xcursor X Cursor - X Zeiger + X Zeiger X Cursors - X Zeiger + X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f700aa6..f565fe7 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 @@ -438,51 +438,51 @@ These settings can be changed at any time from the "Settings" menu.LogarithmPlotter Objects - Objects + Objects Settings - Settings + Settings History - History + History Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. Loading file '%1'. - Loading file '%1'. + Loading file '%1'. Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. Invalid file provided. - Invalid file provided. + Invalid file provided. Could not save file: - Could not save file: + Could not save file: Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! &Update - &Update + &Update &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -507,23 +507,23 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -563,7 +563,7 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid - Snap to grid + Snap to grid @@ -804,30 +804,30 @@ These settings can be changed at any time from the "Settings" menu.color %1 %2's color changed from %3 to %4. - %1 %2's color changed from %3 to %4. + %1 %2's color changed from %3 to %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) + The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) Note: Specify the probability for each value. - Note: Specify the probability for each value. + Note: Specify the probability for each value. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - If you have latex enabled, you can use use latex markup in between $$ to create equations. + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -846,25 +846,25 @@ These settings can be changed at any time from the "Settings" menu.create New %1 %2 created. - New %1 %2 created. + New %1 %2 created. delete %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 changed from %3 to %4. - %1 of %2 changed from %3 to %4. + %1 of %2 changed from %3 to %4. @@ -931,11 +931,11 @@ These settings can be changed at any time from the "Settings" menu. Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. @@ -1080,57 +1080,57 @@ Evaluated expression: %3 function Function - Function + Function Functions - Functions + Functions gainbode Bode Magnitude - Bode Magnitude + Bode Magnitude Bode Magnitudes - Bode Magnitudes + Bode Magnitudes low-pass - low-pass + low-pass high-pass - high-pass + high-pass historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. @@ -1241,293 +1241,293 @@ Please make sure your LaTeX installation is correct and report a bug if so.name %1 %2 renamed to %3. - %1 %2 renamed to %3. + %1 %2 renamed to %3. parameters above - ↑ Above + ↑ Above below - ↓ Below + ↓ Below left - ← Left + ← Left right - → Right + → Right above-left - ↖ Above left + ↖ Above left above-right - ↗ Above right + ↗ Above right below-left - ↙ Below left + ↙ Below left below-right - ↘ Below right + ↘ Below right center - >|< Center + >|< Center top - ↑ Top + ↑ Top bottom - ↓ Bottom + ↓ Bottom top-left - ↖ Top left + ↖ Top left top-right - ↗ Top right + ↗ Top right bottom-left - ↙ Bottom left + ↙ Bottom left bottom-right - ↘ Bottom right + ↘ Bottom right application - Application + Application function - Function + Function high - High + High low - Low + Low Next to target - Next to target + Next to target With label - With label + With label Hidden - Hidden + Hidden phasebode Bode Phase - Bode Phase + Bode Phase Bode Phases - Bode Phases + Bode Phases point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 moved from "%3" to "%4". + %1 %2 moved from "%3" to "%4". Position of %1 set from %2 to %3. - %1 moved from %2 to %3. + %1 moved from %2 to %3. prop expression - Expression + Expression definitionDomain - Domain + Domain destinationDomain - Range + Range labelPosition - Label position + Label position displayMode - Display mode + Display mode labelX - Label's X position + Label's X position drawPoints - Show points + Show points drawDashedLines - Show dashed lines + Show dashed lines om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Magnitude gain + Magnitude gain omGraduation - Show graduation on ω₀ + Show graduation on ω₀ phase - Phase + Phase unit - Unit to use + Unit to use x - X + X y - Y + Y pointStyle - Point style + Point style probabilities - Probabilities list + Probabilities list text - Content + Content disableLatex - Disable LaTeX rendering for this text + Disable LaTeX rendering for this text targetElement - Object to target + Object to target approximate - Show approximate value + Show approximate value rounding - Rounding + Rounding displayStyle - Display style + Display style targetValuePosition - Target's value position + Target's value position defaultExpression - Default expression + Default expression baseValues - Initialisation values + Initialisation values color - Color + Color repartition Repartition - Distribution + Distribution Repartition functions - Distribution functions + Distribution functions sequence Sequence - Sequence + Sequence Sequences - Sequences + Sequences sommegainsbode Bode Magnitudes Sum - Bode Magnitudes Sum + Bode Magnitudes Sum sommephasesbode Bode Phases Sum - Bode Phases Sum + Bode Phases Sum text Text - Text + Text Texts - Texts + Texts @@ -1595,22 +1595,22 @@ Please make sure your LaTeX installation is correct and report a bug if so.visibility %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. xcursor X Cursor - X Cursor + X Cursor X Cursors - X Cursors + X Cursors diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index d1c0f95..f9671dc 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -261,32 +261,32 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -446,51 +446,51 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter Objects - Objets + Objets Settings - Paramètres + Paramètres History - Historique + Historique Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! &Update - &Mise à jour + &Mise à jour &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -515,23 +515,23 @@ These settings can always be changed at any time from the "Settings" m Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -571,7 +571,7 @@ These settings can always be changed at any time from the "Settings" m Snap to grid - Placement sur la grille + Placement sur la grille @@ -812,31 +812,31 @@ These settings can always be changed at any time from the "Settings" m color %1 %2's color changed from %3 to %4. - %1 %2 a été re colorisé du %3 au %4. + %1 %2 a été re colorisé du %3 au %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) + Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) Note: Specify the probability for each value. - Note : Spécifiez la probabilité pour chaque valeur. + Note : Spécifiez la probabilité pour chaque valeur. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... - Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. + Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -855,25 +855,25 @@ These settings can always be changed at any time from the "Settings" m create New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. delete %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 of %2 changed from %3 to %4. - %1 de %2 modifiée de %3 à %4. + %1 de %2 modifiée de %3 à %4. @@ -940,11 +940,11 @@ These settings can always be changed at any time from the "Settings" m Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. @@ -1089,57 +1089,57 @@ Formule analysée : %3 function Function - Fonction + Fonction Functions - Fonctions + Fonctions gainbode Bode Magnitude - Gain de Bode + Gain de Bode Bode Magnitudes - Gains de Bode + Gains de Bode low-pass - passe-bas + passe-bas high-pass - passe-haut + passe-haut historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. @@ -1250,293 +1250,293 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c name %1 %2 renamed to %3. - %1 %2 renommé(e) en %3. + %1 %2 renommé(e) en %3. parameters above - ↑ Au dessus + ↑ Au dessus below - ↓ En dessous + ↓ En dessous left - ← À gauche + ← À gauche right - → À droite + → À droite above-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche above-right - ↗ Au dessus à droite + ↗ Au dessus à droite below-left - ↙ En dessous à gauche + ↙ En dessous à gauche below-right - ↘ En dessous à droite + ↘ En dessous à droite center - >|< Centré + >|< Centré top - ↑ Au dessus + ↑ Au dessus bottom - ↓ En dessous + ↓ En dessous top-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche top-right - ↗ Au dessus à droite + ↗ Au dessus à droite bottom-left - ↙ En dessous à gauche + ↙ En dessous à gauche bottom-right - ↘ En dessous à droite + ↘ En dessous à droite application - Application + Application function - Fonction + Fonction high - Haut + Haut low - Bas + Bas Next to target - A côté de la cible + A côté de la cible With label - Avec l'étiquette + Avec l'étiquette Hidden - Caché + Caché phasebode Bode Phase - Phase de Bode + Phase de Bode Bode Phases - Phases de Bode + Phases de Bode point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 a été déplacé depuis "%3" vers "%4". + %1 %2 a été déplacé depuis "%3" vers "%4". Position of %1 set from %2 to %3. - %1 a été déplacé depuis %2 vers %3. + %1 a été déplacé depuis %2 vers %3. prop expression - Expression + Expression definitionDomain - Domaine de définition + Domaine de définition destinationDomain - Portée + Portée labelPosition - Position de l'étiquette + Position de l'étiquette displayMode - Mode d'affichage + Mode d'affichage labelX - Position en X de l'étiquette + Position en X de l'étiquette drawPoints - Afficher les points + Afficher les points drawDashedLines - Afficher les pointillés + Afficher les pointillés om_0 - ω₀ + ω₀ pass - Passe + Passe gain - Gain + Gain omGraduation - Afficher la graduation sur ω₀ + Afficher la graduation sur ω₀ phase - Phase + Phase unit - Unité de la phase + Unité de la phase x - X + X y - Y + Y pointStyle - Style du point + Style du point probabilities - Liste de probabilités + Liste de probabilités text - Contenu + Contenu disableLatex - Désactiver le rendu LaTeX pour ce texte + Désactiver le rendu LaTeX pour ce texte targetElement - Objet à cibler + Objet à cibler approximate - Afficher la valeur approximative + Afficher la valeur approximative rounding - Arrondi + Arrondi displayStyle - Style d'affichage + Style d'affichage targetValuePosition - Position de la valeur de la cible + Position de la valeur de la cible defaultExpression - Expression + Expression baseValues - Valeurs d'initialisation + Valeurs d'initialisation color - Couleur + Couleur repartition Repartition - Répartition + Répartition Repartition functions - Fonctions de répartition + Fonctions de répartition sequence Sequence - Suite + Suite Sequences - Suites + Suites sommegainsbode Bode Magnitudes Sum - Sommes des gains de Bode + Sommes des gains de Bode sommephasesbode Bode Phases Sum - Somme des phases de Bode + Somme des phases de Bode text Text - Texte + Texte Texts - Textes + Textes @@ -1604,22 +1604,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). xcursor X Cursor - Curseur X + Curseur X X Cursors - Curseurs X + Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 9222b65..d263236 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -438,51 +438,51 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter Objects - Tárgyak + Tárgyak Settings - Beállítások + Beállítások History - Előzmények + Előzmények Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! &Update - &Frissítés + &Frissítés &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -507,23 +507,23 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -563,7 +563,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid - Rácshoz illesztés + Rácshoz illesztés @@ -804,30 +804,30 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color %1 %2's color changed from %3 to %4. - %1 %2 színe %3-ról %4-re változott. + %1 %2 színe %3-ról %4-re változott. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) + A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) Note: Specify the probability for each value. - Megjegyzés: Adja meg az egyes értékek valószínűségét. + Megjegyzés: Adja meg az egyes értékek valószínűségét. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … If you have latex enabled, you can use use latex markup in between $$ to create equations. - Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. + Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -846,25 +846,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. delete %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 of %2 changed from %3 to %4. - %1/%2 megváltozott. Régi érték: %3, új érték: %4. + %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -931,11 +931,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. @@ -1080,53 +1080,53 @@ Kiértékelt kifejezés: %3 function Function - Függvény + Függvény Functions - Függvények + Függvények gainbode Bode Magnitude - Bode-nagyságrend + Bode-nagyságrend Bode Magnitudes - Bode-nagyságrendek + Bode-nagyságrendek low-pass - aluláteresztő + aluláteresztő high-pass - felüláteresztő + felüláteresztő historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. @@ -1237,289 +1237,289 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents name %1 %2 renamed to %3. - %1 %2 átnevezve erre: %3. + %1 %2 átnevezve erre: %3. parameters above - ↑ Felett + ↑ Felett below - ↓ Alatt + ↓ Alatt left - ← Balra + ← Balra right - → Jobbra + → Jobbra above-left - ↖ Felett, balra + ↖ Felett, balra above-right - ↗ Felett, jobbra + ↗ Felett, jobbra below-left - ↙ Alatt, balra + ↙ Alatt, balra below-right - ↘ Alatt, jobbra + ↘ Alatt, jobbra center - >|< Középre + >|< Középre top - ↑ Felső + ↑ Felső bottom - ↓ Alsó + ↓ Alsó top-left - ↖ Bal felső + ↖ Bal felső top-right - ↗ Jobb felső + ↗ Jobb felső bottom-left - ↙ Bal alsó + ↙ Bal alsó bottom-right - ↘ Jobb alsó + ↘ Jobb alsó application - Alkalmazás + Alkalmazás function - Függvény + Függvény high - Magas + Magas low - Alul + Alul Next to target - Cél mellé + Cél mellé With label - Címkével + Címkével Hidden - Rejtett + Rejtett phasebode Bode Phase - Bode-fázis + Bode-fázis Bode Phases - Bode-fázisok + Bode-fázisok point Point - Pont + Pont Points - Pontok + Pontok position Position of %1 %2 set from "%3" to "%4". - %1 %2 áthelyezve innen: „%3” ide: „%4”. + %1 %2 áthelyezve innen: „%3” ide: „%4”. Position of %1 set from %2 to %3. - %1 áthelyezve innen: %2 ide: %3. + %1 áthelyezve innen: %2 ide: %3. prop expression - Kifejezés + Kifejezés definitionDomain - Abszcissza tartomány + Abszcissza tartomány destinationDomain - Ordináta tartomány + Ordináta tartomány labelPosition - Címke helyzete + Címke helyzete displayMode - Megjelenítési mód + Megjelenítési mód labelX - Címke X helyzete + Címke X helyzete drawPoints - Pontok megjelenítése + Pontok megjelenítése drawDashedLines - Szaggatott vonalak megjelenítése + Szaggatott vonalak megjelenítése om_0 - ω₀ + ω₀ pass - Áteresztő + Áteresztő gain - Nagyságrend nyeresége + Nagyságrend nyeresége omGraduation - ω₀ érettségi megjelenítése + ω₀ érettségi megjelenítése phase - Fázis + Fázis unit - Egység használata + Egység használata x - X + X y - Y + Y pointStyle - Pontstílus + Pontstílus probabilities - Valószínűségek listája + Valószínűségek listája text - Tartalom + Tartalom disableLatex - LaTeX-megjelenítés letiltása ennél a szövegnél + LaTeX-megjelenítés letiltása ennél a szövegnél targetElement - Tárgycél + Tárgycél approximate - Hozzávetőleges érték megjelenítése + Hozzávetőleges érték megjelenítése rounding - Kerekítés + Kerekítés displayStyle - Megjelenítési stílus + Megjelenítési stílus targetValuePosition - Cél értékpozíciója + Cél értékpozíciója defaultExpression - Alapértelmezett kifejezés + Alapértelmezett kifejezés baseValues - Kezdeményezési értékek + Kezdeményezési értékek repartition Repartition - Elosztás + Elosztás Repartition functions - Elosztási függvények + Elosztási függvények sequence Sequence - Sorozat + Sorozat Sequences - Sorozatok + Sorozatok sommegainsbode Bode Magnitudes Sum - Bode-nagyságrendek összege + Bode-nagyságrendek összege sommephasesbode Bode Phases Sum - Bode-fázisok összege + Bode-fázisok összege text Text - Szöveg + Szöveg Texts - Szövegek + Szövegek @@ -1587,22 +1587,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. xcursor X Cursor - X kurzor + X kurzor X Cursors - X kurzorok + X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index faeb53b..369aa32 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -438,51 +438,51 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.LogarithmPlotter Objects - Objekter + Objekter Settings - Innstillinger + Innstillinger History - Historikk + Historikk Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! &Update - &Oppdater + &Oppdater &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -507,11 +507,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -519,11 +519,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -563,7 +563,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid - Fest til rutenett + Fest til rutenett @@ -1029,53 +1029,53 @@ Evaluated expression: %3 function Function - Funksjon + Funksjon Functions - Funksjoner + Funksjoner gainbode Bode Magnitude - Bode-magnitude + Bode-magnitude Bode Magnitudes - Bode-magnituder + Bode-magnituder low-pass - lavpass + lavpass high-pass - høypass + høypass historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. @@ -1177,40 +1177,40 @@ Please make sure your latex installation is correct and report a bug if so.phasebode Bode Phase - Bode-fase + Bode-fase Bode Phases - Bode-faser + Bode-faser point Point - Punkt + Punkt Points - Punkter + Punkter repartition Repartition - Distribusjon + Distribusjon Repartition functions - Distribusjonsfunksjoner + Distribusjonsfunksjoner sequence Sequence - Følge + Følge Sequences @@ -1221,25 +1221,25 @@ Please make sure your latex installation is correct and report a bug if so.sommegainsbode Bode Magnitudes Sum - Bode-magnitudesum + Bode-magnitudesum sommephasesbode Bode Phases Sum - Bode-fasesum + Bode-fasesum text Text - Tekst + Tekst Texts - Tekster + Tekster From 5f8c756dc73cb6c94925e51e49d01f8bfb607ff5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 1 Apr 2024 23:48:57 +0200 Subject: [PATCH 009/249] Enforcing type safety at import. --- .../LogarithmPlotter/js/history/common.mjs | 4 +- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 3 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 2 + .../LogarithmPlotter/js/objs/common.mjs | 62 ++-- .../LogarithmPlotter/js/objs/function.mjs | 10 +- .../LogarithmPlotter/js/objs/repartition.mjs | 18 +- .../LogarithmPlotter/js/objs/sequence.mjs | 1 - .../ad5001/LogarithmPlotter/js/objs/text.mjs | 2 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 4 +- .../ad5001/LogarithmPlotter/js/parameters.mjs | 276 +++++++++++++++++- 10 files changed, 327 insertions(+), 55 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 66d35fd..229a294 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -36,7 +36,7 @@ class HistoryCommonAPI extends Module { redo() { this.history.redo() } clear() { this.history.clear() } addToHistory(action) { this.history.addToHistory(action) } - unserialize(data) { this.history.unserialize(data) } + unserialize(...data) { this.history.unserialize(...data) } serialize() { return this.history.serialize() } } @@ -124,7 +124,7 @@ export class Action { } /** - * Returns a string with the HTML-formated description of the action. + * Returns a string with the HTML-formatted description of the action. * * @returns {string} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index fe87ad8..f9fde47 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -129,7 +129,8 @@ class IOAPI extends Module { if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { Modules.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Modules.Objects.types[objType](...objData) + /** @type {DrawableObject} */ + let obj = Modules.Objects.types[objType].import(...objData) Modules.Objects.currentObjects[objType].push(obj) Modules.Objects.currentObjectsByName[obj.name] = obj } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index 5302aca..bf0661e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -26,6 +26,8 @@ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTra qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } /** @type {function(string, string): string} */ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } +/** @type {function(string): string} */ +QT_TR_NOOP = QT_TR_NOOP || function(string) { throw new Error('QT_TR_NOOP not implemented.'); } /** @type {function(string|boolean|int): string} */ String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 5fb31ba..c38b5c1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -20,6 +20,7 @@ import { getRandomColor, textsub } from "../utils.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" import {Module} from "../modules.mjs" +import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" // This file contains the default data to be imported from all other objects @@ -34,7 +35,7 @@ class ObjectsCommonAPI extends Module { } /** - * Creates a new name for an object, based on the \c allowedLetters. + * Creates a new name for an object, based on the allowedLetters. * If variables with each of the allowedLetters is created, a subscript * number is added to the name. * @param {string} allowedLetters @@ -56,7 +57,7 @@ class ObjectsCommonAPI extends Module { } /** - * Registers the object \c obj in the object list. + * Registers the object obj in the object list. * @param {DrawableObject} obj - Object to be registered. */ registerObject(obj) { @@ -131,6 +132,22 @@ export class DrawableObject { * @return {boolean} */ static executable() {return false} + + /** + * Imports the object from its serialized form. + * @return {DrawableObject} + */ + static import(name, visible, color, labelContent, ...args) { + let importedArgs = [name.toString(), visible === true, color.toString(), labelContent] + console.log('---') + console.log(this, name, args) + for(let [name, propType] of Object.entries(this.properties())) + if(!name.startsWith('comment')) { + console.log(name, propType, importedArgs.length-4, args[importedArgs.length-4]) + importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4])) + } + return new this(...importedArgs) + } /** * Base constructor for the object. @@ -138,7 +155,7 @@ export class DrawableObject { * @param {boolean} visible - true if the object is visible, false otherwise. * @param {color|string} color - Color of the object (can be string or QColor) * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. - * @constructor() + * @constructor */ constructor(name, visible = true, color = null, labelContent = 'name + value') { if(color == null) color = getRandomColor() @@ -150,15 +167,18 @@ export class DrawableObject { this.requiredBy = [] this.requires = [] } - + /** - * Serilizes the object in an array that can be JSON serialized. + * Serializes the object in an array that can be JSON serialized. * These parameters will be re-entered in the constructor when restored. * @return {array} */ export() { - // Should return what will be inputed as arguments when a file is loaded (serializable form) - return [this.name, this.visible, this.color.toString(), this.labelContent] + let exportList = [this.name, this.visible, this.color.toString(), this.labelContent] + for(let [name, propType] of Object.entries(this.constructor.properties())) + if(!name.startsWith('comment')) + exportList.push(serializesByPropertyType(propType, this[name])) + return exportList } /** @@ -182,7 +202,7 @@ export class DrawableObject { } /** - * Readable string content of the label depending on the value of the \c latexContent. + * Readable string content of the label depending on the value of the latexContent. * @return {string} */ getLabel() { @@ -198,7 +218,7 @@ export class DrawableObject { } /** - * Latex markup string content of the label depending on the value of the \c latexContent. + * Latex markup string content of the label depending on the value of the latexContent. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. * See ../latex.mjs for helper methods. @@ -275,16 +295,15 @@ export class DrawableObject { } /** - * Abstract method. Draw the object onto the \c canvas with the. + * Abstract method. Draw the object onto the canvas with the. * @param {CanvasAPI} canvas - * @param {CanvasRenderingContext2D} ctx */ draw(canvas) {} /** - * Applicates a \c drawFunction with two position arguments depending on - * both the \c posX and \c posY of where the label should be displayed, - * and the \c labelPosition which declares the label should be displayed + * Applicates a drawFunction with two position arguments depending on + * both the posX and posY of where the label should be displayed, + * and the labelPosition which declares the label should be displayed * relatively to that position. * * @param {string|Enum} labelPosition - Position of the label relative to the marked position @@ -333,17 +352,16 @@ export class DrawableObject { } /** - * Automatically draw text (by default the label of the object on the \c canvas with - * the 2D context \c ctx depending on user settings. - * This method takes into account both the \c posX and \c posY of where the label - * should be displayed, including the \c labelPosition relative to it. - * The text is get both through the \c getLatexFunction and \c getTextFunction + * Automatically draw text (by default the label of the object on the canvas + * depending on user settings. + * This method takes into account both the posX and posY of where the label + * should be displayed, including the labelPosition relative to it. + * The text is get both through the getLatexFunction and getTextFunction * depending on whether to use latex. - * Then, it's displayed using the \c drawFunctionLatex (x,y,imageData) and - * \c drawFunctionText (x,y,text) depending on whether to use latex. + * Then, it's displayed using the drawFunctionLatex (x,y,imageData) and + * drawFunctionText (x,y,text) depending on whether to use latex. * * @param {CanvasAPI} canvas - * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 0d68830..2386a96 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -35,8 +35,8 @@ export default class Function extends ExecutableObject { 'comment', 'Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}' ), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','displayMode')]: P.Enum.FunctionDisplayType, + [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', 'comment2': QT_TRANSLATE_NOOP( 'comment', @@ -81,13 +81,13 @@ export default class Function extends ExecutableObject { return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } } - + export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), + return [this.name, this.visible, this.color.toString(), this.labelContent, + this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), this.displayMode, this.labelPosition, this.labelX, this.drawPoints, this.drawDashedLines] } - + execute(x = 1) { if(this.definitionDomain.includes(x)) return this.expression.execute(x) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 0bee9a0..6c5245d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -26,21 +26,25 @@ export default class RepartitionFunction extends ExecutableObject { static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', 'comment1': QT_TRANSLATE_NOOP( 'comment', 'Note: Specify the probability for each value.' ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'double', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, + [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', }} + static import(name, visible, color, labelContent, ...args) { + if(args.length === 5) + // Two legacy values no longer included. + args.shift(); args.shift() + return super.import(name, visible, color, labelContent, ...args) + } constructor(name = null, visible = true, color = null, labelContent = 'name + value', - beginIncluded = true, drawLineEnds = true, probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { + probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { if(name == null) name = Common.getNewName('XYZUVW', "F_") super(name, visible, color, labelContent) - this.beginIncluded = beginIncluded - this.drawLineEnds = drawLineEnds this.probabilities = probabilities this.labelPosition = labelPosition this.labelX = labelX @@ -49,7 +53,7 @@ export default class RepartitionFunction extends ExecutableObject { export() { return [this.name, this.visible, this.color.toString(), this.labelContent, - this.beginIncluded, this.drawLineEnds, this.probabilities, this.labelPosition, this.labelX] + this.probabilities, this.labelPosition, this.labelX] } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index a7af26f..a2e8673 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -64,7 +64,6 @@ export default class Sequence extends ExecutableObject { update() { console.log('Updating sequence', this.sequence) - console.trace() super.update() if( this.sequence == null || this.baseValues !== this.sequence.baseValues || diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index e3e2ba2..ed62b81 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -32,7 +32,7 @@ export default class Text extends DrawableObject { [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, [QT_TRANSLATE_NOOP('prop','text')]: 'string', - 'comment1': QT_TRANSLATE_NOOP( + 'comment1': QT_TRANSLATE_NOOP( 'comment', 'If you have latex enabled, you can use use latex markup in between $$ to create equations.' ), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 236bd4a..45727dd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -29,8 +29,8 @@ export default class XCursor extends DrawableObject { static displayType(){return qsTr('X Cursor')} static displayTypeMultiple(){return qsTr('X Cursors')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', - [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject'), + [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), + [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject', true), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','approximate')]: 'boolean', [QT_TRANSLATE_NOOP('prop','rounding')]: 'number', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 2cf28a3..0427531 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -1,72 +1,204 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +import {parseDomain, Expression as Expr, Domain} from "./mathlib.mjs" -export class Expression { +const NONE = class Empty {} + +let stringValuesValidators = { + 'int': [parseInt, (x) => !isNaN(x)], + 'double': [parseFloat, (x) => !isNaN(x)], + 'string': [(x) => x, () => true] +} +let stringValidatorTypes = Object.keys(stringValuesValidators) + + +class PropertyType { + /** + * Validates if a value corresponds to the current property type, and if so, returns it. + * @param value + * @returns {null|object} + */ + parse(value) { + throw new TypeError(`validate function of ${typeof this} has not been implemented.`) + } + + /** + * Exports the value of this property type. + * @param value + * @returns {string|number|bool|object} + */ + export(value) { + throw new TypeError(`export function of ${typeof this} has not been implemented.`) + } +} + + +export class Expression extends PropertyType { constructor(...variables) { + super() this.type = 'Expression' this.variables = variables } toString() { - return this.variables.length == 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + return this.variables.length === 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + } + + parse(value) { + let result = NONE + if(typeof value == 'string') + try { + result = new Expr(value) + } catch(e) { + // Silently error and return null + console.trace() + console.log(`Error parsing expression ${value}:`) + console.error(e) + } + return result + } + + export(value) { + if(value instanceof Expr) + return value.toEditableString() + else + throw new TypeError(`Exportation error: ${value} is not an expression.`) } } -export class Enum { + +export class Enum extends PropertyType { constructor(...values) { + super() this.type = 'Enum' this.values = values + this.legacyValues = {} this.translatedValues = values.map(x => qsTr(x)) } toString() { - return this.type + return `${this.type}(${this.values.join(', ')})` + } + + parse(value) { + let result = NONE + if(this.values.includes(value)) + result = value + else if(this.legacyValues[value]) + result = this.legacyValues[value] + return result + } + + export(value) { + if(this.values.includes(value)) + return value + else if(this.legacyValues[value]) + return this.legacyValues[value] + else + throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(', ')}.`) } } -export class ObjectType { - constructor(objType) { + +export class ObjectType extends PropertyType { + constructor(objType, allowNull=false) { + super() this.type = 'ObjectType' this.objType = objType + this.allowNull = allowNull } toString() { return this.objType } + + parse(name) { + let result = NONE + if(typeof name == 'string' && name in Modules.Objects.currentObjectsByName) { + let obj = Modules.Objects.currentObjectsByName[name] + if (obj.type === this.objType || (this.objType === 'ExecutableObject' && obj.execute)) { + result = obj + } else { + // Silently error and return null + console.trace() + console.error(new TypeError(`Object ${name} is of not of type ${this.objType}:`)) + } + } else if(this.allowNull && (name == null || name === "null")) + result = null + return result + } + + export(value) { + if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) + return value + else + throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`) + } } -export class List { + +export class List extends PropertyType { constructor(type, format = /^.+$/, label = '', forbidAdding = false) { + super() // type can be string, int and double. this.type = 'List' this.valueType = type + if(!stringValidatorTypes.includes(this.valueType)) + throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(', ')}.`) this.format = format this.label = label this.forbidAdding = forbidAdding } toString() { - return this.objType + return `${this.type}(${this.valueType}:${this.format})` + } + + parse(value) { + let result = NONE + if(typeof value == 'object' && value.__proto__ === Array) { + let list = [] + for(let v of value) { + if (this.format.test(v)) { + v = stringValuesValidators[this.valueType][0](v) + if(stringValuesValidators[this.valueType][1](v)) + list.append(v) + } + } + if(list.length === value.length) + result = value + } + return result + } + + export(value) { + if(typeof value == 'object' && value.__proto__ === Array) + return value + else + throw new TypeError(`Exportation error: ${value} not a list.`) + } } -export class Dictionary { + +export class Dictionary extends PropertyType { constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { + super() // type & keyType can be string, int and double. this.type = 'Dict' this.valueType = type @@ -77,9 +209,35 @@ export class Dictionary { this.postKeyLabel = postKeyLabel this.forbidAdding = forbidAdding } - + toString() { - return 'Dictionary' + return `${this.type}(${this.keyType}:${this.keyFormat}: ${this.valueType}:${this.format})` + } + + parse(value) { + let result = NONE + if(typeof value == 'object' && value.__proto__ !== Array) { + let dict = [] + for(let [k, v] of Object.entries(value)) { + if (this.format.test(v) && this.keyFormat.test(k)) { + k = stringValuesValidators[this.keyType][0](k) + v = stringValuesValidators[this.valueType][0](v) + if(stringValuesValidators[this.keyType][1](k)) + if(stringValuesValidators[this.valueType][1](v)) + dict[k] = v + } + } + if(Object.keys(dict).length === Object.keys(value).length) + result = value + } + return result + } + + export(value) { + if(typeof value == 'object' && value.__proto__ !== Array) + return value + else + throw new TypeError(`Exportation error: ${value} not a dictionary.`) } } @@ -95,6 +253,14 @@ Enum.Position = new Enum( QT_TR_NOOP('below-left'), QT_TR_NOOP('below-right') ) +Enum.Position.legacyValues = { + 'top': 'above', + 'bottom': 'below', + 'top-left': 'above-left', + 'top-right': 'above-right', + 'bottom-left': 'below-left', + 'bottom-right': 'below-right', +} Enum.Positioning = new Enum( QT_TR_NOOP('center'), @@ -125,4 +291,86 @@ Enum.XCursorValuePosition = new Enum( QT_TR_NOOP('Hidden') ) +/** + * Ensures whether a provided value is of the corresponding type. + * @param {string|PropertyType} propertyType + * @param {string|number|boolean|array|object}value + * @returns {Object} + */ +export function ensureTypeSafety(propertyType, value) { + let result + let error = false + if(typeof propertyType == 'string') + switch(propertyType) { + case 'string': + result = value + error = typeof value !== 'string' + break + case 'number': + result = parseFloat(value) + error = isNaN(result) + break + case 'boolean': + result = value + error = value !== true && value !== false + break + case 'Domain': + try { + error = typeof value !== 'string' + if(!error) + result = parseDomain(value) + } catch(e) { + // Parse domain sometimes returns an empty set when it cannot parse a domain. + // It's okay though, it shouldn't be user parsed value, so returning an empty set + // is okay for a corrupted file, rather than erroring. + console.trace() + console.log(`Error parsing domain ${value}:`) + console.error(e) + error = true + } + break + } + else if(propertyType instanceof PropertyType) { + result = propertyType.parse(value) + error = result === NONE + } else + throw new TypeError(`Importation error: Unknown property type ${propertyType}.`) + if(error) { + console.trace() + throw new TypeError(`Importation error: Couldn't parse ${JSON.stringify(value)} as ${propertyType}.`) + } + return result +} +/** + * Serializes a property by its type to export into JSON. + * @param {string|PropertyType} propertyType + * @param value + * @returns {Object} + */ +export function serializesByPropertyType(propertyType, value) { + let result + if(typeof propertyType == 'string') + switch(propertyType) { + case 'string': + result = value.toString() + break + case 'number': + result = parseFloat(value) + break + case 'boolean': + result = value === true + break + case 'Domain': + if(value instanceof Domain) + result = value.toString() + else + throw new TypeError(`Exportation error: ${value} is not a domain.`) + break + } + else if(propertyType instanceof PropertyType) { + result = propertyType.export(value) + } else + throw new TypeError(`Exportation error: Unknown property type ${propertyType}.`) + return result +} \ No newline at end of file From 781a0f4aae7e5a0ea10d12476a4f99cab1833d8d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 00:11:56 +0200 Subject: [PATCH 010/249] Enforcing type safety at export --- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 22 +++++++++---------- .../LogarithmPlotter/js/objs/common.mjs | 4 +--- .../LogarithmPlotter/js/objs/function.mjs | 6 ----- .../LogarithmPlotter/js/objs/gainbode.mjs | 5 ----- .../LogarithmPlotter/js/objs/phasebode.mjs | 5 ----- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 4 ---- .../LogarithmPlotter/js/objs/repartition.mjs | 13 +++++------ .../LogarithmPlotter/js/objs/sequence.mjs | 6 ----- .../js/objs/sommegainsbode.mjs | 4 ---- .../js/objs/sommephasesbode.mjs | 4 ---- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 4 ---- .../LogarithmPlotter/js/objs/xcursor.mjs | 6 ----- .../ad5001/LogarithmPlotter/js/parameters.mjs | 6 +++-- 13 files changed, 21 insertions(+), 68 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index f9fde47..396ada8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -98,15 +98,15 @@ class IOAPI extends Module { Modules.History.clear() // Importing settings this.settings.saveFilename = filename - this.settings.xzoom = data["xzoom"] - this.settings.yzoom = data["yzoom"] - this.settings.xmin = data["xmin"] - this.settings.ymax = data["ymax"] - this.settings.xaxisstep = data["xaxisstep"] - this.settings.yaxisstep = data["yaxisstep"] - this.settings.xlabel = data["xaxislabel"] - this.settings.ylabel = data["yaxislabel"] - this.settings.logscalex = data["logscalex"] + this.settings.xzoom = parseFloat(data["xzoom"]) || 100 + this.settings.yzoom = parseFloat(data["yzoom"]) || 10 + this.settings.xmin = parseFloat(data["xmin"]) || 5/10 + this.settings.ymax = parseFloat(data["ymax"]) || 24 + this.settings.xaxisstep = data["xaxisstep"] || "4" + this.settings.yaxisstep = data["yaxisstep"] || "4" + this.settings.xlabel = data["xaxislabel"] || "" + this.settings.ylabel = data["yaxislabel"] || "" + this.settings.logscalex = data["logscalex"] === true if("showxgrad" in data) this.settings.showxgrad = data["showxgrad"] if("showygrad" in data) @@ -115,8 +115,8 @@ class IOAPI extends Module { this.settings.linewidth = data["linewidth"] if("textsize" in data) this.settings.textsize = data["textsize"] - this.rootElement.height = data["height"] - this.rootElement.width = data["width"] + this.rootElement.height = parseFloat(data["height"]) || 500 + this.rootElement.width = parseFloat(data["width"]) || 1000 // Importing objects Modules.Objects.currentObjects = {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index c38b5c1..173aef4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -139,11 +139,9 @@ export class DrawableObject { */ static import(name, visible, color, labelContent, ...args) { let importedArgs = [name.toString(), visible === true, color.toString(), labelContent] - console.log('---') - console.log(this, name, args) + console.log('Importing', this.type(), name, args) for(let [name, propType] of Object.entries(this.properties())) if(!name.startsWith('comment')) { - console.log(name, propType, importedArgs.length-4, args[importedArgs.length-4]) importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4])) } return new this(...importedArgs) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 2386a96..fb9e93c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -82,12 +82,6 @@ export default class Function extends ExecutableObject { } } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), - this.displayMode, this.labelPosition, this.labelX, this.drawPoints, this.drawDashedLines] - } - execute(x = 1) { if(this.definitionDomain.includes(x)) return this.expression.execute(x) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index fb0e9cd..a4a6416 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -81,11 +81,6 @@ export default class GainBode extends ExecutableObject { \\end{array}` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.om_0.name, this.pass.toString(), this.gain.toEditableString(), this.labelPosition, this.labelX, this.omGraduation] - } - execute(x=1) { if(typeof x == 'string') x = executeExpression(x) if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index 5b32ec5..bee6ee6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -64,11 +64,6 @@ export default class PhaseBode extends ExecutableObject { this.labelX = labelX } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.om_0.name, this.phase.toEditableString(), this.unit, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name}: ${this.phase.toString(true)}${this.unit} at ${this.om_0.name} = ${this.om_0.x}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 03de816..f53eb72 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -54,10 +54,6 @@ export default class Point extends DrawableObject { return `${Latex.variable(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.pointStyle] - } - draw(canvas) { let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] let pointSize = 8+(canvas.linewidth*2) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 6c5245d..2dd632d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -35,9 +35,12 @@ export default class RepartitionFunction extends ExecutableObject { [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', }} static import(name, visible, color, labelContent, ...args) { - if(args.length === 5) + console.log(args, args.length) + if(args.length === 5) { // Two legacy values no longer included. - args.shift(); args.shift() + args.shift() + args.shift() + } return super.import(name, visible, color, labelContent, ...args) } @@ -51,12 +54,6 @@ export default class RepartitionFunction extends ExecutableObject { this.update() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.probabilities, this.labelPosition, this.labelX] - } - - getReadableString() { let keys = Object.keys(this.probabilities).sort((a,b) => a-b); let varname = this.name.substring(this.name.indexOf("_")+1) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index a2e8673..10cb154 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -55,12 +55,6 @@ export default class Sequence extends ExecutableObject { this.labelX = labelX this.update() } - - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, - this.labelPosition, this.labelX] - } update() { console.log('Updating sequence', this.sequence) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index 947c99f..236c3d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -44,10 +44,6 @@ export default class SommeGainsBode extends ExecutableObject { this.recalculateCache() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index 30ad4b0..1483788 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -42,10 +42,6 @@ export default class SommePhasesBode extends ExecutableObject { this.recalculateCache() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index ed62b81..dfd0d27 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -78,10 +78,6 @@ export default class Text extends DrawableObject { return `${Latex.variable(this.name)} = "\\textsf{${this.latexMarkupText()}}"` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.text, this.disableLatex] - } - getLabel() { return this.text } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 45727dd..2e3c6e0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -60,12 +60,6 @@ export default class XCursor extends DrawableObject { this.targetValuePosition = targetValuePosition } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.x.toEditableString(), this.targetElement == null ? null : this.targetElement.name, this.labelPosition, - this.approximate, this.rounding, this.displayStyle, this.targetValuePosition] - } - getReadableString() { if(this.targetElement == null) return `${this.name} = ${this.x.toString()}` return `${this.name} = ${this.x.toString()}\n${this.getTargetValueLabel()}` diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 0427531..72f9dee 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -144,8 +144,10 @@ export class ObjectType extends PropertyType { } export(value) { - if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) - return value + if(value == null && this.allowNull) + return null + else if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) + return value.name else throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`) } From 665906ecb34244816c81db4f54e2bc71e8b3bcda Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:11:54 +0200 Subject: [PATCH 011/249] New preferences panel. --- LogarithmPlotter/i18n/lp_de.ts | 148 +++-- LogarithmPlotter/i18n/lp_en.ts | 156 ++++-- LogarithmPlotter/i18n/lp_es.ts | 462 ++++++++-------- LogarithmPlotter/i18n/lp_fr.ts | 148 +++-- LogarithmPlotter/i18n/lp_hu.ts | 150 +++-- LogarithmPlotter/i18n/lp_nb_NO.ts | 376 +++++++------ LogarithmPlotter/i18n/lp_template.ts | 519 +++++++++--------- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 8 +- .../LogarithmPlotter/LogarithmPlotter.qml | 14 +- .../LogarithmPlotter/Popup/Preferences.qml | 187 +++++++ .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 1 + .../LogarithmPlotter/icons/settings/color.svg | 1 + .../eu/ad5001/LogarithmPlotter/js/autoload.js | 3 +- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 4 + .../LogarithmPlotter/js/setting/common.mjs | 67 +++ .../js/setting/expression.mjs | 54 ++ .../LogarithmPlotter/js/setting/general.mjs | 49 ++ .../ad5001/LogarithmPlotter/js/settings.mjs | 39 ++ 18 files changed, 1504 insertions(+), 882 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 4d9a064..2e8b5fe 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -186,6 +186,14 @@ Schließen + + BoolSetting + + + Check for updates on startup + Beim Starten auf Updates prüfen + + Changelog @@ -437,14 +445,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter + Objects Objekte + Settings Einstellungen + History Verlauf @@ -473,14 +484,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Geladene Datei '%1'. + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! + &Update &Aktualisieren + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -599,100 +613,105 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Settings - + X Zoom Zoom auf X - + Y Zoom Zoom auf Y - + Min X Minimum X - + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern - + Save plot as Grafik speichern unter - + Load plot Grafik laden + + + Done + Schließen + ThanksTo @@ -790,12 +809,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -1075,6 +1094,22 @@ Ausdruck analysiert: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Fehler + + Automatically close parenthesises and brackets + Klammern automatisch schließen + + + Enable syntax highlighting + Syntaxhervorhebung einschalten + + + Enable autocompletion + Automatische Vervollständigung einschalten + + + Color Scheme + Syntaktische Färbung + function @@ -1106,6 +1141,21 @@ Ausdruck analysiert: %3 Hochpass + + general + + Check for updates on startup + Beim Starten auf Updates prüfen + + + Reset redo stack automaticly + Wiederherstellen-Stapel automatisch zurücksetzen + + + Enable LaTeX rendering + LaTeX-Rendering aktivieren + + historylib @@ -1136,64 +1186,52 @@ Ausdruck analysiert: %3 io - Objects - Objekte + Objekte - Settings - Einstellungen + Einstellungen - History - Verlauf + Verlauf - Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. - Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. - Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. - Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. - Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: - Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. - Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! - &Update - &Aktualisieren + &Aktualisieren - &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -1226,7 +1264,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1505,6 +1543,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Folgen + + settingCategory + + + general + + + sommegainsbode @@ -1533,22 +1579,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde update - + An update for LogarithPlotter (v{}) is available. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f565fe7..998d124 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -186,6 +186,14 @@ Close + + BoolSetting + + + Check for updates on startup + Check for updates on startup + + Changelog @@ -437,14 +445,17 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter + Objects Objects + Settings Settings + History History @@ -473,14 +484,17 @@ These settings can be changed at any time from the "Settings" menu.Loaded file '%1'. + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! + &Update &Update + &Update LogarithmPlotter &Update LogarithmPlotter @@ -599,100 +613,105 @@ These settings can be changed at any time from the "Settings" menu. Settings - + X Zoom X Zoom - + Y Zoom Y Zoom - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot - + Save plot as Save plot as - + Load plot Open plot + + + Done + Done + ThanksTo @@ -790,12 +809,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -1075,6 +1094,22 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error + + Automatically close parenthesises and brackets + Automatically close parentheses and brackets + + + Enable syntax highlighting + Enable syntax highlighting + + + Enable autocompletion + Enable autocompletion + + + Color Scheme + Color Scheme + function @@ -1106,6 +1141,21 @@ Evaluated expression: %3 high-pass + + general + + Check for updates on startup + Check for updates on startup + + + Reset redo stack automaticly + Reset redo stack automatically + + + Enable LaTeX rendering + Enable LaTeX rendering + + historylib @@ -1136,64 +1186,52 @@ Evaluated expression: %3 io - Objects - Objects + Objects - Settings - Settings + Settings - History - History + History - Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. - Loading file '%1'. - Loading file '%1'. + Loading file '%1'. - Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. - Invalid file provided. - Invalid file provided. + Invalid file provided. - Could not save file: - Could not save file: + Could not save file: - Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. - Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! - &Update - &Update + &Update - &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -1226,7 +1264,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1505,6 +1543,22 @@ Please make sure your LaTeX installation is correct and report a bug if so.Sequences + + settingCategory + + + general + General + + + editor + Expression Editor + + + default + Default Graph + + sommegainsbode @@ -1533,22 +1587,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. update - + An update for LogarithPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index c8f4310..ef9e33a 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -105,27 +105,27 @@ Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + @@ -175,7 +175,7 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + Comprobación de las actualizaciones al arrancar @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value - + @@ -261,32 +269,32 @@ Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects - + @@ -294,12 +302,12 @@ Export Logarithm Plot file - + Import Logarithm Plot file - + @@ -307,68 +315,68 @@ Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -376,22 +384,22 @@ These settings can be changed at any time from the "Settings" menu. Filter... - + Redo > - + > Now - + < Undo - + @@ -399,6 +407,39 @@ These settings can be changed at any time from the "Settings" menu. + Add Entry + + + + + LogarithmPlotter + + + Objects + + + + + Settings + + + + + History + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter @@ -407,7 +448,7 @@ These settings can be changed at any time from the "Settings" menu. + Create new: - + @@ -415,12 +456,12 @@ These settings can be changed at any time from the "Settings" menu. Hide all %1 - + Show all %1 - + @@ -428,27 +469,27 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 - + @@ -456,135 +497,140 @@ These settings can be changed at any time from the "Settings" menu. Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom - + - + Y Zoom - + - + Min X - + - + Max Y - + - + Max X - + - + Min Y - + - + X Axis Step - + - + Y Axis Step - + - + Line width - + - + Text size (px) - + - + X Label - + - + Y Label - + - + X Log scale - + - + Show X graduation - + - + Show Y graduation - + - + Copy to clipboard - + - + Save plot - + - + Save plot as - + - + Load plot - + + + + + Done + @@ -592,27 +638,27 @@ These settings can be changed at any time from the "Settings" menu. Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -621,76 +667,76 @@ These settings can be changed at any time from the "Settings" menu. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -702,7 +748,7 @@ These settings can be changed at any time from the "Settings" menu. %1: - + @@ -711,152 +757,152 @@ These settings can be changed at any time from the "Settings" menu. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -864,7 +910,7 @@ These settings can be changed at any time from the "Settings" menu. - + @@ -872,7 +918,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -881,7 +927,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -889,75 +935,27 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + - io + general - - Objects - + Check for updates on startup + Comprobación de las actualizaciones al arrancar - - Settings - + Reset redo stack automaticly + Restablecer la pila de rehacer automáticamente - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - + Enable LaTeX rendering + Activar el renderizado de LaTeX @@ -967,12 +965,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -981,38 +979,46 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + + + + + settingCategory + + + general + update - + An update for LogarithPlotter (v{}) is available. - + - + No update available. - + - + Could not fetch update information: Server error {}. - + - + Could not fetch update information: {}. - + @@ -1021,7 +1027,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1029,27 +1035,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index f9671dc..40a761b 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -187,6 +187,14 @@ Fermer + + BoolSetting + + + Check for updates on startup + Vérifier la présence de mise à jour au démarrage + + Changelog @@ -445,14 +453,17 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter + Objects Objets + Settings Paramètres + History Historique @@ -481,14 +492,17 @@ These settings can always be changed at any time from the "Settings" m Fichier '%1' chargé. + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! + &Update &Mise à jour + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -607,100 +621,105 @@ These settings can always be changed at any time from the "Settings" m Settings - + X Zoom Zoom en X - + Y Zoom Zoom en Y - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe - + Save plot as Sauvegarder le graphe sous - + Load plot Ouvrir un graphe + + + Done + Fermer + ThanksTo @@ -798,12 +817,12 @@ These settings can always be changed at any time from the "Settings" m changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -1084,6 +1103,22 @@ Formule analysée : %3 LogarithmPlotter - Drawing error LogarithmPlotter - Erreur + + Automatically close parenthesises and brackets + Fermer automatiquement les parenthèses et les crochets + + + Enable syntax highlighting + Activer la coloration syntaxique + + + Enable autocompletion + Activer l'autocomplétion + + + Color Scheme + Coloration Syntaxique + function @@ -1115,6 +1150,21 @@ Formule analysée : %3 passe-haut + + general + + Check for updates on startup + Vérifier la présence de mise à jour au démarrage + + + Reset redo stack automaticly + Réinitialiser la pile d'action "Rétablir" automatiquement + + + Enable LaTeX rendering + Activer le rendu LaTeX + + historylib @@ -1145,64 +1195,52 @@ Formule analysée : %3 io - Objects - Objets + Objets - Settings - Paramètres + Paramètres - History - Historique + Historique - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. - Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. - Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. - Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. - Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : - Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. - Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! - &Update - &Mise à jour + &Mise à jour - &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -1235,7 +1273,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1514,6 +1552,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Suites + + settingCategory + + + general + + + sommegainsbode @@ -1542,22 +1588,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c update - + An update for LogarithPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index d263236..34f6fc4 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -186,6 +186,14 @@ Bezárás + + BoolSetting + + + Check for updates on startup + Frissítések keresése indításkor + + Changelog @@ -437,14 +445,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter + Objects Tárgyak + Settings Beállítások + History Előzmények @@ -473,14 +484,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltve. + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! + &Update &Frissítés + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -599,100 +613,105 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Settings - + X Zoom X-nagyítás - + Y Zoom Y-nagyítás - + Min X Legkisebb X - + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése - + Save plot as Ábra mentése másként - + Load plot Ábra betöltése + + + Done + Kész + ThanksTo @@ -790,12 +809,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -1075,6 +1094,22 @@ Kiértékelt kifejezés: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba + + Automatically close parenthesises and brackets + Zárójelek automatikus bezárása + + + Enable syntax highlighting + Mondattani kiemelés engedélyezése + + + Enable autocompletion + Automatikus befejezés engedélyezése + + + Color Scheme + Színséma + function @@ -1106,6 +1141,21 @@ Kiértékelt kifejezés: %3 felüláteresztő + + general + + Check for updates on startup + Frissítések keresése indításkor + + + Reset redo stack automaticly + Ismétlési verem önműködő visszaállítása + + + Enable LaTeX rendering + LaTeX-megjelenítés engedélyezése + + historylib @@ -1132,64 +1182,48 @@ Kiértékelt kifejezés: %3 io - - Objects - - - - Settings - Beállítások + Beállítások - History - Előzmények + Előzmények - Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. - Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. - Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. - Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. - Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: - Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. - Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! - &Update - &Frissítés + &Frissítés - &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -1222,7 +1256,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1497,6 +1531,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Sorozatok + + settingCategory + + + general + + + sommegainsbode @@ -1525,22 +1567,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents update - + An update for LogarithPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 369aa32..ae1af4e 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -17,7 +17,7 @@ 2D plotter software to make BODE plots, sequences and repartition functions. - 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. + 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. @@ -27,7 +27,7 @@ Official website - + @@ -95,37 +95,37 @@ Reset redo stack automaticly - Tilbakestill angrehistorikk automatisk + Tilbakestill angrehistorikk automatisk Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + @@ -135,32 +135,32 @@ &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + @@ -170,12 +170,12 @@ Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + Se etter nye versjoner ved programstart @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri @@ -292,32 +300,32 @@ Object Properties - + Variables - + Constants - + Functions - Funksjoner + Funksjoner Executable Objects - + Objects - Objekter + Objekter @@ -325,7 +333,7 @@ Export Logarithm Plot file - Eksporter logaritmeplott-fil + Eksporter logaritmeplott-fil @@ -365,42 +373,42 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -408,7 +416,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Filter... - + @@ -431,20 +439,23 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + Add Entry - + LogarithmPlotter + Objects Objekter + Settings Innstillinger + History Historikk @@ -473,14 +484,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Lastet inn filen «%1». + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! + &Update &Oppdater + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -531,27 +545,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position - Sett %1 %2 posisjon + Sett %1 %2 posisjon Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -568,158 +582,163 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom X-forstørrelse - + Y Zoom Y-forstørrelse - + Min X Min. X - + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation - Vis X-inndeling + Vis X-inndeling - + Show Y graduation - Vis Y-inndeling + Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott + + + Done + + ThanksTo Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -728,76 +747,76 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -809,7 +828,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. %1: - + @@ -839,152 +858,152 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -992,7 +1011,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + @@ -1000,7 +1019,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -1009,7 +1028,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -1017,12 +1036,12 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + @@ -1055,6 +1074,17 @@ Evaluated expression: %3 høypass + + general + + Check for updates on startup + Se etter nye versjoner ved programstart + + + Reset redo stack automaticly + Tilbakestill angrehistorikk automatisk + + historylib @@ -1081,64 +1111,52 @@ Evaluated expression: %3 io - Objects - Objekter + Objekter - Settings - Innstillinger + Innstillinger - History - Historikk + Historikk - Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». - Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. - Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. - Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. - Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: - Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». - Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! - &Update - &Oppdater + &Oppdater - &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -1148,12 +1166,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -1162,15 +1180,15 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + @@ -1217,6 +1235,14 @@ Please make sure your latex installation is correct and report a bug if so.Følger + + settingCategory + + + general + + + sommegainsbode @@ -1245,22 +1271,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. @@ -1271,7 +1297,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1279,27 +1305,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 3e4a80b..dcd8d44 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,29 +5,29 @@ About - + About LogarithmPlotter - + LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. - + Report a bug - + Official website - + @@ -35,147 +35,147 @@ &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value - + @@ -261,32 +269,32 @@ Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects - + @@ -294,12 +302,12 @@ Export Logarithm Plot file - + Import Logarithm Plot file - + @@ -307,68 +315,68 @@ Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -376,22 +384,22 @@ These settings can be changed at any time from the "Settings" menu. Filter... - + Redo > - + > Now - + < Undo - + @@ -399,6 +407,39 @@ These settings can be changed at any time from the "Settings" menu. + Add Entry + + + + + LogarithmPlotter + + + Objects + + + + + Settings + + + + + History + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter @@ -407,7 +448,7 @@ These settings can be changed at any time from the "Settings" menu. + Create new: - + @@ -415,12 +456,12 @@ These settings can be changed at any time from the "Settings" menu. Hide all %1 - + Show all %1 - + @@ -428,27 +469,27 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 - + @@ -456,135 +497,140 @@ These settings can be changed at any time from the "Settings" menu. Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom - + - + Y Zoom - + - + Min X - + - + Max Y - + - + Max X - + - + Min Y - + - + X Axis Step - + - + Y Axis Step - + - + Line width - + - + Text size (px) - + - + X Label - + - + Y Label - + - + X Log scale - + - + Show X graduation - + - + Show Y graduation - + - + Copy to clipboard - + - + Save plot - + - + Save plot as - + - + Load plot - + + + + + Done + @@ -592,27 +638,27 @@ These settings can be changed at any time from the "Settings" menu. Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -621,76 +667,76 @@ These settings can be changed at any time from the "Settings" menu. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -702,7 +748,7 @@ These settings can be changed at any time from the "Settings" menu. %1: - + @@ -711,152 +757,152 @@ These settings can be changed at any time from the "Settings" menu. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -864,7 +910,7 @@ These settings can be changed at any time from the "Settings" menu. - + @@ -872,7 +918,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -881,7 +927,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -889,75 +935,12 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - - - - io - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - + @@ -967,12 +950,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -981,38 +964,46 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + + + + + settingCategory + + + general + update - + An update for LogarithPlotter (v{}) is available. - + - + No update available. - + - + Could not fetch update information: Server error {}. - + - + Could not fetch update information: {}. - + @@ -1021,7 +1012,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1029,27 +1020,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 3de96ca..944c18a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -90,13 +90,19 @@ MenuBar { icon.color: enabled ? sysPalette.windowText : sysPaletteIn.windowText enabled: history.redoCount > 0 } - MenuSeparator { } Action { text: qsTr("&Copy plot") shortcut: StandardKey.Copy onTriggered: root.copyDiagramToClipboard() icon.name: 'edit-copy' } + MenuSeparator { } + Action { + text: qsTr("&Preferences") + shortcut: StandardKey.Copy + onTriggered: preferences.open() + icon.name: 'settings' + } } Menu { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 388264c..2e24d53 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -55,6 +55,8 @@ ApplicationWindow { Popup.GreetScreen {} + Popup.Preferences {id: preferences} + Popup.Changelog {id: changelog} Popup.About {id: about} @@ -86,19 +88,19 @@ ApplicationWindow { width: parent.width anchors.top: parent.top TabButton { - text: qsTranslate('io', "Objects") + text: qsTr("Objects") icon.name: 'polygon-add-nodes' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTranslate('io', "Settings") + text: qsTr("Settings") icon.name: 'preferences-system-symbolic' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTranslate('io', "History") + text: qsTr("History") icon.name: 'view-history' icon.color: sysPalette.windowText //height: 24 @@ -227,7 +229,7 @@ ApplicationWindow { var file = Helper.gettmpfile() drawCanvas.save(file) Helper.copyImageToClipboard() - alert.show(qsTranslate('io', "Copied plot screenshot to clipboard!")) + alert.show(qsTr("Copied plot screenshot to clipboard!")) } /*! @@ -242,9 +244,9 @@ ApplicationWindow { Menu { id: updateMenu - title: qsTranslate('io', "&Update") + title: qsTr("&Update") Action { - text: qsTranslate('io', "&Update LogarithmPlotter") + text: qsTr("&Update LogarithmPlotter") icon.name: 'update' onTriggered: Qt.openUrlExternally("https://apps.ad5001.eu/logarithmplotter/") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml new file mode 100644 index 0000000..6218fb9 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -0,0 +1,187 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../js/setting/common.mjs" as S + +/*! + \qmltype Preferences + \inqmlmodule eu.ad5001.LogarithmPlotter.Popup + \brief Popup to change global application preferences. + + \sa LogarithmPlotter, GreetScreen +*/ +Popup { + id: preferencesPopup + x: (parent.width-width)/2 + y: Math.max(20, (parent.height-height)/2) + width: settingPopupRow.width + 30 + height: settingPopupRow.height + 20 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + // Components for the preferences + Component { + id: boolSettingComponent + + CheckBox { + height: 20 + text: setting.displayName + checked: setting.value() + onClicked: setting.set(this.checked) + } + } + + Component { + id: enumIntSettingComponent + + // Setting when selecting data from an enum, or an object of a certain type. + Setting.ComboBoxSetting { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + currentIndex: setting.value() + model: setting.values() + onActivated: function(newIndex) { setting.set(newIndex) } + } + } + + Row { + id: settingPopupRow + height: 300 + width: categories.width + categorySeparator.width + settingView.width + 70 + spacing: 15 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + topMargin: 10 + bottomMargin: 10 + rightMargin: 15 + leftMargin: 15 + } + + ColumnLayout { + id: categories + width: 150 + height: parent.height + spacing: 0 + clip: true + + Repeater { + model: Object.keys(Modules.Settings.categories) + + Button { + // width: 150 + Layout.fillWidth: true + text: qsTranslate('settingCategory', modelData) + + onClicked: { + settingList.model = Modules.Settings.categories[modelData] + settingCategoryName.text = text + } + } + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + + Button { + id: closeButton + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + text: qsTr('Done') + onClicked: preferencesPopup.close() + } + } + } + + Rectangle { + id: categorySeparator + anchors { + top: parent.top + topMargin: 5 + } + opacity: 0.3 + color: sysPalette.windowText + height: parent.height - 10 + width: 1 + } + + ScrollView { + id: settingView + clip: true + width: 500 + height: parent.height + + Column { + spacing: 10 + clip: true + width: settingView.width + + Text { + id: settingCategoryName + font.pixelSize: 32 + color: sysPalette.windowText + text: qsTranslate('settingCategory', 'general') + + Rectangle { + id: bottomSeparator + anchors.top: parent.bottom + opacity: 0.3 + color: sysPalette.windowText + width: settingView.width + height: 1 + } + } + + Repeater { + id: settingList + model: Modules.Settings.categories.general + + delegate: Component { + Loader { + width: settingView.width + property var setting: modelData + sourceComponent: { + if(setting instanceof S.BoolSetting) + return boolSettingComponent + else if(setting instanceof S.EnumIntSetting) + return enumIntSettingComponent + else + console.log('Unknown setting type!', modelData.constructor) + } + } + } + } + } + } + } + + Component.onCompleted: open() +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index 9306fae..8c0859f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -8,3 +8,4 @@ GreetScreen 1.0 GreetScreen.qml Changelog 1.0 Changelog.qml ThanksTo 1.0 ThanksTo.qml InsertCharacter 1.0 InsertCharacter.qml +Preferences 1.0 Preferences.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg new file mode 120000 index 0000000..41b711b --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg @@ -0,0 +1 @@ +../common/appearance.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 9f207a0..211aa9e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -6,4 +6,5 @@ .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon .import "canvas.mjs" as CanvasAPI -.import "io.mjs" as IOAPI \ No newline at end of file +.import "io.mjs" as IOAPI +.import "settings.mjs" as SettingsAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index d68bd9d..9649634 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -144,6 +144,10 @@ class CanvasAPI extends Module { // Methods to draw the canvas // + requestPaint() { + this._canvas.requestPaint() + } + /** * Redraws the entire canvas */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs new file mode 100644 index 0000000..2e395c6 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs @@ -0,0 +1,67 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class Setting { + constructor(name, nameInConfig, icon) { + this.name = name + this.displayName = qsTr(name) + this.nameInConfig = nameInConfig + this.icon = icon + } + + /** + * Returns the value of the setting. + * @returns {string|boolean|number} + */ + value() { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + /** + * Sets the value of the setting + * @param {string|boolean|number} value + */ + set(value) { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } +} + +export class BoolSetting extends Setting { + value() { + return Helper.getSettingBool(this.nameInConfig) + } + + set(value) { + Helper.setSettingBool(this.nameInConfig, value) + } +} + +export class IntSetting extends Setting { + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class EnumIntSetting extends IntSetting { + values() { + throw new TypeError(`enumerations of ${this.constructor} not implemented.`) + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs new file mode 100644 index 0000000..0fab509 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs @@ -0,0 +1,54 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, EnumIntSetting} from "common.mjs" + +class AutocloseFormula extends BoolSetting { + constructor() { + super(qsTr("Automatically close parenthesises and brackets"), 'expression_editor.autoclose', 'Text') + } +} + +class EnableSyntaxHighlighting extends BoolSetting { + constructor() { + super(qsTr("Enable syntax highlighting"), 'expression_editor.colorize', 'appearance') + } +} + +class EnableAutocomplete extends BoolSetting { + constructor() { + super(qsTr("Enable autocompletion"), 'autocompletion.enabled', 'label') + } +} + +class PickColorScheme extends EnumIntSetting { + constructor() { + super(qsTr("Color Scheme"), 'expression_editor.color_scheme', 'color') + } + + values() { + return ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + } +} + +export default [ + new AutocloseFormula(), + new EnableAutocomplete(), + new EnableSyntaxHighlighting(), + new PickColorScheme() +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs new file mode 100644 index 0000000..2430b52 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs @@ -0,0 +1,49 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting} from "common.mjs" + +class CheckForUpdates extends BoolSetting { + constructor() { + super(QT_TR_NOOP("Check for updates on startup"), 'check_for_updates', 'update') + } +} + +class ResetRedoStack extends BoolSetting { + constructor() { + super(qsTr("Reset redo stack automaticly"), 'reset_redo_stack', 'timeline') + } +} + +class EnableLatex extends BoolSetting { + constructor() { + super(qsTr("Enable LaTeX rendering"), 'enable_latex', 'Expression') + } + + set(value) { + super.set(value) + Modules.Latex.enabled = value + Modules.Canvas.requestPaint() + } +} + +export default [ + new CheckForUpdates(), + new ResetRedoStack(), + new EnableLatex() +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs new file mode 100644 index 0000000..8fff543 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs @@ -0,0 +1,39 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import {Module} from "modules.mjs" +import General from "setting/general.mjs" +import Editor from "setting/expression.mjs" + +class SettingsAPI extends Module { + constructor() { + super('Settings', [ + Modules.Canvas, + Modules.Latex + ]) + + this.categories = { + [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, + [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor, + [QT_TRANSLATE_NOOP('settingCategory', 'default')]: [], + } + } +} + +/** @type {CanvasAPI} */ +Modules.Settings = Modules.Settings || new SettingsAPI() +export const API = Modules.Settings \ No newline at end of file From fefb0f92b0ac19a63311a539d466c17b8cc9208b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:49:56 +0200 Subject: [PATCH 012/249] New, rewamped Greet Screen. --- LogarithmPlotter/i18n/lp_de.ts | 6 +- LogarithmPlotter/i18n/lp_en.ts | 12 +- LogarithmPlotter/i18n/lp_es.ts | 6 +- LogarithmPlotter/i18n/lp_fr.ts | 6 +- LogarithmPlotter/i18n/lp_hu.ts | 6 +- LogarithmPlotter/i18n/lp_nb_NO.ts | 6 +- LogarithmPlotter/i18n/lp_template.ts | 6 +- .../LogarithmPlotter/Popup/Changelog.qml | 2 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 287 +++++++----------- .../LogarithmPlotter/Popup/Preferences.qml | 4 +- .../LogarithmPlotter/icons/common/close.svg | 48 +++ .../LogarithmPlotter/icons/common/manual.svg | 1 + .../LogarithmPlotter/icons/common/new.svg | 1 + .../LogarithmPlotter/icons/history/delete.svg | 49 +-- 14 files changed, 182 insertions(+), 258 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg mode change 100644 => 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 2e8b5fe..393e01f 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -203,7 +203,7 @@ - Done + Close Schließen @@ -407,7 +407,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - Done + Close Schließen @@ -709,7 +709,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - Done + Close Schließen diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 998d124..dbc3714 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -203,8 +203,8 @@ - Done - Done + Close + Close @@ -407,8 +407,8 @@ These settings can be changed at any time from the "Settings" menu. - Done - Done + Close + Close @@ -709,8 +709,8 @@ These settings can be changed at any time from the "Settings" menu. - Done - Done + Close + Close diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index ef9e33a..37c6da8 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -203,7 +203,7 @@ - Done + Close @@ -375,7 +375,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close @@ -629,7 +629,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 40a761b..3dd5482 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -204,7 +204,7 @@ - Done + Close Fermer @@ -399,7 +399,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P - Done + Close Fermer @@ -717,7 +717,7 @@ These settings can always be changed at any time from the "Settings" m - Done + Close Fermer diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 34f6fc4..d9933cc 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -203,7 +203,7 @@ - Done + Close Kész @@ -407,7 +407,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Done + Close Kész @@ -709,7 +709,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Done + Close Kész diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index ae1af4e..314a690 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -203,7 +203,7 @@ - Done + Close @@ -407,7 +407,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Done + Close @@ -709,7 +709,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Done + Close diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index dcd8d44..426049e 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -203,7 +203,7 @@ - Done + Close @@ -375,7 +375,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close @@ -629,7 +629,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index f86af07..844e22a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -96,7 +96,7 @@ Popup { Button { id: doneBtn - text: qsTr("Done") + text: qsTr("Close") font.pixelSize: 18 anchors.bottom: parent.bottom anchors.bottomMargin: 7 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 9ddfa0f..09e16e5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -18,6 +18,7 @@ import QtQuick import QtQuick.Controls +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! \qmltype GreetScreen @@ -32,202 +33,122 @@ Popup { id: greetingPopup x: (parent.width-width)/2 y: Math.max(20, (parent.height-height)/2) - width: Math.max(welcome.width+70, checkForUpdatesSetting.width, resetRedoStackSetting.width)+20 + width: greetingLayout.width+20 height: Math.min(parent.height-40, 700) modal: true focus: true clip: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - ScrollView { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.bottomMargin: bottomButtons.height + 20 - clip: true - - Column { - width: greetingPopup.width - 25 - spacing: 10 - clip: true - topPadding: 35 - - Row { - id: welcome - height: logo.height - spacing: 10 - anchors.horizontalCenter: parent.horizontalCenter - - Image { - id: logo - source: "../icons/logarithmplotter.svg" - sourceSize.width: 48 - sourceSize.height: 48 - width: 48 - height: 48 - } - - Label { - id: welcomeText - anchors.verticalCenter: parent.verticalCenter - wrapMode: Text.WordWrap - font.pixelSize: 32 - text: qsTr("Welcome to LogarithmPlotter") - } - } - - Label { - id: versionText - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - width: implicitWidth - font.pixelSize: 18 - font.italic: true - text: qsTr("Version %1").arg(Helper.getVersion()) - } - - Label { - id: helpText - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - font.pixelSize: 14 - width: parent.width - 50 - text: qsTr("Take a few seconds to configure LogarithmPlotter.\nThese settings can be changed at any time from the \"Settings\" menu.") - } - - CheckBox { - id: checkForUpdatesSetting - anchors.left: parent.left - checked: Helper.getSettingBool("check_for_updates") - text: qsTr('Check for updates on startup (requires online connectivity)') - onClicked: { - Helper.setSettingBool("check_for_updates", checked) - // Set in the menu bar - appMenu.settingsMenu.children[0].checked = checked - } - } - - CheckBox { - id: resetRedoStackSetting - anchors.left: parent.left - checked: Helper.getSettingBool("reset_redo_stack") - text: qsTr('Reset redo stack when a new action is added to history') - onClicked: { - Helper.setSettingBool("reset_redo_stack", checked) - appMenu.settingsMenu.children[1].checked = checked - } - } - - CheckBox { - id: enableLatexSetting - anchors.left: parent.left - checked: Helper.getSettingBool("enable_latex") - text: qsTr('Enable LaTeX rendering') - onClicked: { - Helper.setSettingBool("enable_latex", checked) - appMenu.settingsMenu.children[2].checked = checked - } - } - - CheckBox { - id: autocloseFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("expression_editor.autoclose") - text: qsTr('Automatically close parenthesises and brackets in expressions') - onClicked: { - Helper.setSettingBool("expression_editor.autoclose", checked) - appMenu.settingsMenu.children[3].children[0].checked = checked - } - } - - CheckBox { - id: colorizeFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("expression_editor.colorize") - text: qsTr('Enable syntax highlighting for expressions') - onClicked: { - Helper.setSettingBool("expression_editor.colorize", checked) - appMenu.settingsMenu.children[3].children[1].checked = checked - } - } - - CheckBox { - id: autocompleteFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("autocompletion.enabled") - text: qsTr('Enable autocompletion interface in expression editor') - onClicked: { - Helper.setSettingBool("autocompletion.enabled", checked) - appMenu.settingsMenu.children[3].children[2].checked = checked - } - } - - Row { - anchors.left: parent.left - anchors.leftMargin: 10 - spacing: 10 - - Label { - id: colorSchemeLabel - anchors.verticalCenter: parent.verticalCenter - wrapMode: Text.WordWrap - text: qsTr("Color scheme:") - } - - ComboBox { - model: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - currentIndex: Helper.getSettingInt("expression_editor.color_scheme") - - onActivated: function(index) { - Helper.setSettingInt("expression_editor.color_scheme", index) - } - } - } - } - } - - Rectangle { - id: bottomSeparator - opacity: 0.3 - color: sysPalette.windowText - width: parent.width * 2 / 3 - height: 1 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: bottomButtons.top - anchors.bottomMargin: 9 - } - - Row { - id: bottomButtons - anchors.bottom: parent.bottom - anchors.bottomMargin: 7 + Column { + id: greetingLayout + width: 600 spacing: 10 - anchors.horizontalCenter: parent.horizontalCenter + clip: true + topPadding: 35 - Button { - id: userManualBtn - text: qsTr("User manual") - font.pixelSize: 18 - onClicked: Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_Sidebar") + Row { + id: welcome + height: logo.height + spacing: 10 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: logo + source: "../icons/logarithmplotter.svg" + sourceSize.width: 48 + sourceSize.height: 48 + width: 48 + height: 48 + } + + Label { + id: welcomeText + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 32 + text: qsTr("Welcome to LogarithmPlotter") + } } - - Button { - id: changelogBtn - text: qsTr("Changelog") + + Label { + id: versionText + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + width: implicitWidth font.pixelSize: 18 - onClicked: changelog.open() - } - - Button { - id: doneBtn - text: qsTr("Done") - font.pixelSize: 18 - onClicked: greetingPopup.close() + font.italic: true + text: qsTr("Version %1").arg(Helper.getVersion()) } } + + Grid { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: greetingLayout.bottom + anchors.topMargin: 50 + columns: 2 + spacing: 10 + + Repeater { + model: [{ + name: qsTr("Changelog"), + icon: 'common/new.svg', + onClicked: () => changelog.open() + },{ + name: qsTr("Preferences"), + icon: 'common/settings.svg', + onClicked: () => preferences.open() + },{ + name: qsTr("User manual"), + icon: 'common/manual.svg', + onClicked: () => Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_Sidebar") + },{ + name: qsTr("Close"), + icon: 'common/close.svg', + onClicked: () => greetingPopup.close() + }] + + Button { + id: createBtn + width: 96 + height: 96 + onClicked: modelData.onClicked() - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { + Setting.Icon { + id: icon + width: 24 + height: 24 + anchors { + left: parent.left + leftMargin: (parent.width-width)/2 + top: parent.top + topMargin: (label.y-height)/2 + } + color: sysPalette.windowText + source: '../icons/' + modelData.icon + } + + Label { + id: label + anchors { + bottom: parent.bottom + bottomMargin: 5 + left: parent.left + leftMargin: 4 + right: parent.right + rightMargin: 4 + } + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 14 + text: modelData.name + wrapMode: Text.WordWrap + clip: true + } + } + } + } + + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()+1) { greetingPopup.open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 6218fb9..6f5ac7e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -115,7 +115,7 @@ Popup { right: parent.right bottom: parent.bottom } - text: qsTr('Done') + text: qsTr('Close') onClicked: preferencesPopup.close() } } @@ -183,5 +183,5 @@ Popup { } } - Component.onCompleted: open() + // Component.onCompleted: open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg new file mode 100644 index 0000000..d1bf741 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg @@ -0,0 +1,48 @@ + + + + + + + + + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg new file mode 100644 index 0000000..9ca9b8e --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg new file mode 100644 index 0000000..7c7f6fd --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg deleted file mode 100644 index d1bf741..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg new file mode 120000 index 0000000..dca0794 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg @@ -0,0 +1 @@ +../common/close.svg \ No newline at end of file From 997a1645a0c3fdd7504abd526acebdcd77b94176 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:50:43 +0200 Subject: [PATCH 013/249] Removing Settings submenu. --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 99 ------------------- 1 file changed, 99 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 944c18a..81dbd57 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -127,105 +127,6 @@ MenuBar { } } - Menu { - id: settingsSubMenu - title: qsTr("&Settings") - Action { - id: checkForUpdatesMenuSetting - text: qsTr("Check for updates on startup") - checkable: true - checked: Helper.getSettingBool("check_for_updates") - onTriggered: Helper.setSettingBool("check_for_updates", checked) - icon.name: 'update' - icon.color: sysPalette.buttonText - } - - Action { - id: resetRedoStackMenuSetting - text: qsTr("Reset redo stack automaticly") - checkable: true - checked: Helper.getSettingBool("reset_redo_stack") - onTriggered: Helper.setSettingBool("reset_redo_stack", checked) - icon.name: 'timeline' - icon.color: sysPalette.buttonText - } - - Action { - id: enableLatexJSSetting - text: qsTr("Enable LaTeX rendering") - checkable: true - checked: Helper.getSettingBool("enable_latex") - onTriggered: { - Helper.setSettingBool("enable_latex", checked) - Modules.Latex.enabled = checked - drawCanvas.requestPaint() - } - icon.name: 'Expression' - icon.color: sysPalette.buttonText - } - - Menu { - title: qsTr("Expression editor") - - Action { - id: autocloseFormulaSetting - text: qsTr("Automatically close parenthesises and brackets") - checkable: true - checked: Helper.getSettingBool("expression_editor.autoclose") - onTriggered: { - Helper.setSettingBool("expression_editor.autoclose", checked) - } - icon.name: 'Text' - icon.color: sysPalette.buttonText - } - - Action { - id: colorizeFormulaSetting - text: qsTr("Enable syntax highlighting") - checkable: true - checked: Helper.getSettingBool("expression_editor.colorize") - onTriggered: { - Helper.setSettingBool("expression_editor.colorize", checked) - } - icon.name: 'appearance' - icon.color: sysPalette.buttonText - } - - Action { - id: autocompleteFormulaSetting - text: qsTr("Enable autocompletion") - checkable: true - checked: Helper.getSettingBool("autocompletion.enabled") - onTriggered: { - Helper.setSettingBool("autocompletion.enabled", checked) - } - icon.name: 'label' - icon.color: sysPalette.buttonText - } - - Menu { - id: colorSchemeSetting - title: qsTr("Color Scheme") - property var schemes: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - - Repeater { - model: colorSchemeSetting.schemes - - MenuItem { - text: modelData - checkable: true - checked: Helper.getSettingInt("expression_editor.color_scheme") == index - onTriggered: { - parent.children[Helper.getSettingInt("expression_editor.color_scheme")].checked = false - checked = true - Helper.setSettingInt("expression_editor.color_scheme", index) - } - } - } - } - } - } - Menu { title: qsTr("&Help") Action { From 54f980297531a03ea258984951a795e69c69a0ee Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 3 Apr 2024 21:39:06 +0200 Subject: [PATCH 014/249] Adding default canvas settings + Getting rid of Qt5COmpat for Icon. + Fixing some (non production) bugs. --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 1 - .../LogarithmPlotter/LogGraphCanvas.qml | 41 +++++ .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../LogarithmPlotter/Popup/Preferences.qml | 158 +++++++++++++----- .../Setting/ComboBoxSetting.qml | 1 + .../Setting/ExpressionEditor.qml | 20 ++- .../ad5001/LogarithmPlotter/Setting/Icon.qml | 18 +- .../LogarithmPlotter/Setting/TextSetting.qml | 10 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 37 ++-- .../icons/common/{Text.svg => text.svg} | 0 .../LogarithmPlotter/icons/settings/label.svg | 1 + .../LogarithmPlotter/icons/settings/text.svg | 1 + .../eu/ad5001/LogarithmPlotter/js/autoload.js | 2 +- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 13 +- .../js/{settings.mjs => preferences.mjs} | 15 +- .../js/preferences/common.mjs | 137 +++++++++++++++ .../js/preferences/default.mjs | 120 +++++++++++++ .../js/preferences/expression.mjs | 51 ++++++ .../js/{setting => preferences}/general.mjs | 24 +-- .../LogarithmPlotter/js/setting/common.mjs | 67 -------- .../js/setting/expression.mjs | 54 ------ LogarithmPlotter/util/config.py | 15 ++ LogarithmPlotter/util/helper.py | 5 +- 23 files changed, 558 insertions(+), 235 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/{Text.svg => text.svg} (100%) create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{settings.mjs => preferences.mjs} (74%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{setting => preferences}/general.mjs (75%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 81dbd57..59c7973 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -33,7 +33,6 @@ import "js/historylib.mjs" as HistoryLib \sa LogarithmPlotter */ MenuBar { - property var settingsMenu: settingsSubMenu Menu { title: qsTr("&File") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 973142f..fd9a737 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -168,4 +168,45 @@ Canvas { } }) } + + /*! + \qmlmethod double LogGraphCanvas::x2px(double x) + Converts an \c x coordinate to it's relative position on the canvas. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function x2px(x) { + if(logscalex) { + var logxmin = Math.log(xmin) + return (Math.log(x)-logxmin)*xzoom + } else return (x - xmin)*xzoom + } + + /*! + \qmlmethod double LogGraphCanvas::y2px(double y) + Converts an \c y coordinate to it's relative position on the canvas. + The y axis not supporting logarithmic scale, it only support linear convertion. + */ + function y2px(y) { + return (ymax-y)*yzoom + } + + /*! + \qmlmethod double LogGraphCanvas::px2x(double px) + Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function px2x(px) { + if(logscalex) { + return Math.exp(px/xzoom+Math.log(xmin)) + } else return (px/xzoom+xmin) + } + + /*! + \qmlmethod double LogGraphCanvas::px2x(double px) + Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function px2y(px) { + return -(px/yzoom-ymax) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index a6f57d6..0fd529c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -90,7 +90,7 @@ Repeater { root.changed() } } - } + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 6f5ac7e..aece6aa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -20,7 +20,8 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/setting/common.mjs" as S +import "../js/preferences/common.mjs" as S +import "../js/utils.mjs" as Utils /*! \qmltype Preferences @@ -60,11 +61,75 @@ Popup { label: setting.displayName icon: `settings/${setting.icon}.svg` currentIndex: setting.value() - model: setting.values() + model: setting.values onActivated: function(newIndex) { setting.set(newIndex) } } } + Component { + id: stringSettingComponent + + Setting.ComboBoxSetting { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + editable: true + currentIndex: find(setting.value()) + model: setting.defaultValues + onAccepted: function() { + editText = Utils.parseName(editText, false) + if(find(editText) === -1) model.append(editText) + setting.set(editText) + } + onActivated: function(selectedId) { + setting.set(model[selectedId]) + } + Component.onCompleted: editText = setting.value() + } + } + + Component { + id: numberSettingComponent + + Setting.TextSetting { + height: 30 + isDouble: true + label: setting.displayName + min: setting.min() + icon: `settings/${setting.icon}.svg` + value: setting.value() + onChanged: function(newValue) { + if(newValue < setting.max()) + setting.set(newValue) + else { + value = setting.max() + setting.set(setting.max()) + } + } + } + } + + Component { + id: expressionSettingComponent + + Setting.ExpressionEditor { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + defValue: Utils.simplifyExpression(setting.value()) + variables: setting.variables + allowGraphObjects: false + property string propertyName: setting.displayName + onChanged: function(newExpr) { + try { + setting.set(newExpr) + } catch(e) { + errorDialog.showDialog(propertyName, newExpr, e.message) + } + } + } + } + Row { id: settingPopupRow height: 300 @@ -90,7 +155,7 @@ Popup { clip: true Repeater { - model: Object.keys(Modules.Settings.categories) + model: Object.keys(Modules.Preferences.categories) Button { // width: 150 @@ -98,8 +163,8 @@ Popup { text: qsTranslate('settingCategory', modelData) onClicked: { - settingList.model = Modules.Settings.categories[modelData] - settingCategoryName.text = text + settingView.model = Modules.Preferences.categories[modelData] + settingView.name = text } } } @@ -133,50 +198,55 @@ Popup { width: 1 } - ScrollView { + ListView { id: settingView clip: true width: 500 - height: parent.height + spacing: 10 + model: Modules.Preferences.categories.general + anchors { + top: parent.top + bottom: parent.bottom + } + ScrollBar.vertical: ScrollBar { } + property string name: qsTranslate('settingCategory', 'general') + - Column { - spacing: 10 - clip: true - width: settingView.width - - Text { - id: settingCategoryName - font.pixelSize: 32 - color: sysPalette.windowText - text: qsTranslate('settingCategory', 'general') - - Rectangle { - id: bottomSeparator - anchors.top: parent.bottom - opacity: 0.3 - color: sysPalette.windowText - width: settingView.width - height: 1 - } - } + header: Text { + id: settingCategoryName + font.pixelSize: 32 + height: 48 + color: sysPalette.windowText + text: settingView.name - Repeater { - id: settingList - model: Modules.Settings.categories.general - - delegate: Component { - Loader { - width: settingView.width - property var setting: modelData - sourceComponent: { - if(setting instanceof S.BoolSetting) - return boolSettingComponent - else if(setting instanceof S.EnumIntSetting) - return enumIntSettingComponent - else - console.log('Unknown setting type!', modelData.constructor) - } - } + Rectangle { + id: bottomSeparator + anchors.bottom: parent.bottom + anchors.bottomMargin: 8 + opacity: 0.3 + color: sysPalette.windowText + width: settingView.width + height: 1 + } + } + + delegate: Component { + Loader { + width: settingView.width * 2 / 3 + property var setting: modelData + sourceComponent: { + if(setting instanceof S.BoolSetting) + return boolSettingComponent + else if(setting instanceof S.EnumIntSetting) + return enumIntSettingComponent + else if(setting instanceof S.NumberSetting) + return numberSettingComponent + else if(setting instanceof S.ExpressionSetting) + return expressionSettingComponent + else if(setting instanceof S.StringSetting) + return stringSettingComponent + else + console.log('Unknown setting type!', modelData.constructor) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index d701661..d29ab7c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -114,6 +114,7 @@ Item { anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 height: 30 + width: Math.max(85, implicitWidth) anchors.top: parent.top verticalAlignment: TextInput.AlignVCenter text: qsTranslate("control", "%1: ").arg(control.label) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index ad7e67c..d121781 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -80,6 +80,17 @@ Item { Icon path of the editor. */ property string icon: "" + /*! + \qmlproperty bool ExpressionEditor::allowGraphObjects + If true, allows graph objects to be used as part of the expression. + */ + property bool allowGraphObjects: true + + /*! + \qmlproperty var ExpressionEditor::errorDialog + Allows to summon the error dialog when using additional external parsing. + */ + readonly property alias errorDialog: parsingErrorDialog /*! \qmlproperty string ExpressionEditor::openAndCloseMatches @@ -177,8 +188,9 @@ Item { id: labelItem anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 - height: parent.height anchors.top: parent.top + height: parent.height + width: Math.max(85, implicitWidth) verticalAlignment: TextInput.AlignVCenter //color: sysPalette.windowText text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" @@ -380,7 +392,7 @@ Item { id: objectPropertiesList category: qsTr("Object Properties") - visbilityCondition: doesObjectExist + visbilityCondition: control.allowGraphObjects && doesObjectExist itemStartIndex: 0 itemSelected: parent.itemSelected property bool isEnteringProperty: ( @@ -457,7 +469,7 @@ Item { id: executableObjectsList category: qsTr("Executable Objects") - visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot + visbilityCondition: control.allowGraphObjects && parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected categoryItems: Modules.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) @@ -472,7 +484,7 @@ Item { id: objectsList category: qsTr("Objects") - visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot + visbilityCondition: control.allowGraphObjects && parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected categoryItems: Object.keys(Modules.Objects.currentObjectsByName).filter(obj => obj != self) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index f845eb9..aeffe53 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -17,7 +17,7 @@ */ import QtQuick import QtQuick.Window -import Qt5Compat.GraphicalEffects +import QtQuick.Controls.impl /*! \qmltype Icon @@ -41,20 +41,16 @@ Item { \qmlproperty string Icon::source Path of the icon image source. */ - property alias sourceSize: img.sourceSize.width + property alias sourceSize: img.sourceS - Image { + ColorImage { id: img height: parent.height width: parent.width - visible: false - sourceSize.width: width*Screen.devicePixelRatio - sourceSize.height: width*Screen.devicePixelRatio - } - - ColorOverlay { - anchors.fill: img - source: img + // visible: false + property int sourceS: width*Screen.devicePixelRatio + sourceSize.width: sourceS + sourceSize.height: sourceS color: parent.color } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index d1c4c9d..c795037 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -100,14 +100,14 @@ Item { id: labelItem anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 - height: parent.height anchors.top: parent.top + height: parent.height + width: Math.max(85, implicitWidth) verticalAlignment: TextInput.AlignVCenter //color: sysPalette.windowText text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" visible: control.label != "" } - TextField { id: input @@ -128,8 +128,10 @@ Item { onEditingFinished: function() { if(insertButton.focus || insertPopup.focus) return var value = text - if(control.isInt) value = Math.max(control.min,parseInt(value).toString()=="NaN"?control.min:parseInt(value)) - if(control.isDouble) value = Math.max(control.min,parseFloat(value).toString()=="NaN"?control.min:parseFloat(value)) + if(control.isInt) + value = isNaN(parseInt(value)) ? control.min : Math.max(control.min,parseInt(value)) + if(control.isDouble) + value = isNaN(parseFloat(value)) ? control.min : Math.max(control.min,parseFloat(value)) if(value != "" && value.toString() != defValue) { control.changed(value) defValue = value.toString() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index cf09695..067c70d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -44,83 +44,83 @@ ScrollView { Zoom on the x axis of the diagram, provided from settings. \sa Settings */ - property double xzoom: 100 + property double xzoom: Helper.getSettingInt('default_graph.xzoom') /*! \qmlproperty double Settings::yzoom Zoom on the y axis of the diagram, provided from settings. \sa Settings */ - property double yzoom: 10 + property double yzoom: Helper.getSettingInt('default_graph.yzoom') /*! \qmlproperty double Settings::xmin Minimum x of the diagram, provided from settings. \sa Settings */ - property double xmin: 5/10 + property double xmin: Helper.getSettingInt('default_graph.xmin') /*! \qmlproperty double Settings::ymax Maximum y of the diagram, provided from settings. \sa Settings */ - property double ymax: 25 + property double ymax: Helper.getSettingInt('default_graph.ymax') /*! \qmlproperty string Settings::xaxisstep Step of the x axis graduation, provided from settings. \note: Only available in non-logarithmic mode. \sa Settings */ - property string xaxisstep: "4" + property string xaxisstep: Helper.getSetting('default_graph.xaxisstep') /*! \qmlproperty string Settings::yaxisstep Step of the y axis graduation, provided from settings. \sa Settings */ - property string yaxisstep: "4" + property string yaxisstep: Helper.getSetting('default_graph.yaxisstep') /*! \qmlproperty string Settings::xlabel Label used on the x axis, provided from settings. \sa Settings */ - property string xlabel: "" + property string xlabel: Helper.getSetting('default_graph.xlabel') /*! \qmlproperty string Settings::ylabel Label used on the y axis, provided from settings. \sa Settings */ - property string ylabel: "" + property string ylabel: Helper.getSetting('default_graph.ylabel') /*! \qmlproperty double Settings::linewidth Width of lines that will be drawn into the canvas, provided from settings. \sa Settings */ - property double linewidth: 1 + property double linewidth: Helper.getSettingInt('default_graph.linewidth') /*! \qmlproperty double Settings::textsize Font size of the text that will be drawn into the canvas, provided from settings. \sa Settings */ - property double textsize: 18 + property double textsize: Helper.getSettingInt('default_graph.textsize') /*! \qmlproperty bool Settings::logscalex true if the canvas should be in logarithmic mode, false otherwise. Provided from settings. \sa Settings */ - property bool logscalex: true + property bool logscalex: Helper.getSettingBool('default_graph.logscalex') /*! \qmlproperty bool Settings::showxgrad true if the x graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showxgrad: true + property bool showxgrad: Helper.getSettingBool('default_graph.showxgrad') /*! \qmlproperty bool Settings::showygrad true if the y graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showygrad: true + property bool showygrad: Helper.getSettingBool('default_graph.showygrad') /*! \qmlproperty bool Settings::saveFilename Path of the currently opened file. Empty if no file is opened. @@ -159,7 +159,7 @@ ScrollView { height: 30 isDouble: true label: qsTr("X Zoom") - min: 1 + min: 0.1 icon: "settings/xzoom.svg" width: settings.settingWidth value: settings.xzoom.toFixed(2) @@ -173,6 +173,7 @@ ScrollView { id: zoomY height: 30 isDouble: true + min: 0.1 label: qsTr("Y Zoom") icon: "settings/yzoom.svg" width: settings.settingWidth @@ -226,10 +227,10 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - value: Modules.Canvas.px2x(canvas.width).toFixed(2) + defValue: canvas.px2x(canvas.width).toFixed(2) onChanged: function(xvaluemax) { if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.xzoom = settings.xzoom * canvas.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") @@ -245,10 +246,10 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) + defValue: canvas.px2y(canvas.height).toFixed(2) onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.yzoom = settings.yzoom * canvas.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/Text.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/Text.svg rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg new file mode 120000 index 0000000..280f9ad --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg @@ -0,0 +1 @@ +../common/label.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg new file mode 120000 index 0000000..a705389 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg @@ -0,0 +1 @@ +../common/text.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 211aa9e..5763db0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -7,4 +7,4 @@ .import "history/common.mjs" as HistoryCommon .import "canvas.mjs" as CanvasAPI .import "io.mjs" as IOAPI -.import "settings.mjs" as SettingsAPI \ No newline at end of file +.import "preferences.mjs" as PreferencesAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 9649634..cdd0777 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -377,10 +377,7 @@ class CanvasAPI extends Module { * @returns {number} */ x2px(x) { - if(this.logscalex) { - let logxmin = Math.log(this.xmin) - return (Math.log(x)-logxmin)*this.xzoom - } else return (x - this.xmin)*this.xzoom + return this._canvas.x2px(x) } /** @@ -390,7 +387,7 @@ class CanvasAPI extends Module { * @returns {number} */ y2px(y) { - return (this.ymax-y)*this.yzoom + return this._canvas.y2px(y) } /** @@ -400,9 +397,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2x(px) { - if(this.logscalex) { - return Math.exp(px/this.xzoom+Math.log(this.xmin)) - } else return (px/this.xzoom+this.xmin) + return this._canvas.px2x(px) } /** @@ -412,7 +407,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2y(px) { - return -(px/this.yzoom-this.ymax) + return this._canvas.px2y(px) } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs similarity index 74% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs index 8fff543..0407ee1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs @@ -16,12 +16,13 @@ * along with this program. If not, see . */ import {Module} from "modules.mjs" -import General from "setting/general.mjs" -import Editor from "setting/expression.mjs" +import General from "preferences/general.mjs" +import Editor from "preferences/expression.mjs" +import DefaultGraph from "preferences/default.mjs" -class SettingsAPI extends Module { +class PreferencesAPI extends Module { constructor() { - super('Settings', [ + super('Preferences', [ Modules.Canvas, Modules.Latex ]) @@ -29,11 +30,11 @@ class SettingsAPI extends Module { this.categories = { [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor, - [QT_TRANSLATE_NOOP('settingCategory', 'default')]: [], + [QT_TRANSLATE_NOOP('settingCategory', 'default')]: DefaultGraph, } } } /** @type {CanvasAPI} */ -Modules.Settings = Modules.Settings || new SettingsAPI() -export const API = Modules.Settings \ No newline at end of file +Modules.Preferences = Modules.Preferences || new PreferencesAPI() +export const API = Modules.Preferences \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs new file mode 100644 index 0000000..48cd1de --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -0,0 +1,137 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Expression} from "../mathlib.mjs" + +class Setting { + constructor(type, name, nameInConfig, icon) { + this.type = type + this.name = name + this.displayName = qsTr(name) + this.nameInConfig = nameInConfig + this.icon = icon + } + + /** + * Returns the value of the setting. + * @returns {string|boolean|number} + */ + value() { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + /** + * Sets the value of the setting + * @param {string|boolean|number|Expression} value + */ + set(value) { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + toString() { + return `Setting<${this.type} ${this.name}>` + } +} + +export class BoolSetting extends Setting { + constructor(name, nameInConfig, icon) { + super('bool', name, nameInConfig, icon) + } + + value() { + return Helper.getSettingBool(this.nameInConfig) + } + + set(value) { + Helper.setSettingBool(this.nameInConfig, value) + } +} + +export class NumberSetting extends Setting { + constructor(name, nameInConfig, icon, min = -Infinity, max = +Infinity) { + super('number', name, nameInConfig, icon) + this.min = typeof min == 'number' ? () => min : min + this.max = typeof max == 'number' ? () => max : max + } + + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class EnumIntSetting extends Setting { + constructor(name, nameInConfig, icon, values = []) { + super('enum', name, nameInConfig, icon) + this.values = values + } + + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class ExpressionSetting extends Setting { + constructor(name, nameInConfig, icon, variables = []) { + super('expression', name, nameInConfig, icon) + this.variables = variables + } + + value() { + return Helper.getSetting(this.nameInConfig) + } + + /** + * + * @param {Expression} value + */ + set(value) { + let vars = value.calc.variables() + if(vars.length === this.variables.length && vars.every(x => this.variables.includes(x))) + Helper.setSetting(this.nameInConfig, value) + else { + let undefinedVars = vars.filter(x => !this.variables.includes(x)) + let allowed = '' + if(this.variables.length > 0) + allowed = `Allowed variables: ${this.variables.join(', ')}.` + throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(', or ')} to define ${this.displayName}. ${allowed}`) + } + } +} + +export class StringSetting extends Setting { + constructor(name, nameInConfig, icon, defaultValues = []) { + super('string', name, nameInConfig, icon) + this.defaultValues = defaultValues + } + + value() { + return Helper.getSetting(this.nameInConfig) + } + + set(value) { + Helper.setSetting(this.nameInConfig, value) + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs new file mode 100644 index 0000000..1546729 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs @@ -0,0 +1,120 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "common.mjs" + + +const XZOOM = new NumberSetting( + QT_TR_NOOP("X Zoom"), + "default_graph.xzoom", + "xzoom", + 0.1 +) + +const YZOOM = new NumberSetting( + QT_TR_NOOP("Y Zoom"), + "default_graph.xzoom", + "yzoom", + 0.1 +) + +const XMIN = new NumberSetting( + QT_TR_NOOP("Min X"), + "default_graph.xmin", + "xmin", + () => Helper.getSettingBool("default_graph.logscalex") ? 1e-100 : -Infinity +) + +const YMAX = new NumberSetting( + QT_TR_NOOP("Max Y"), + "default_graph.ymax", + "ymax" +) + +const XAXISSTEP = new ExpressionSetting( + QT_TR_NOOP("X Axis Step"), + "default_graph.xaxisstep", + "xaxisstep", +) + +const YAXISSTEP = new ExpressionSetting( + QT_TR_NOOP("Y Axis Step"), + "default_graph.yaxisstep", + "yaxisstep", +) + +const LINE_WIDTH = new NumberSetting( + QT_TR_NOOP("Line width"), + "default_graph.linewidth", + "linewidth", + 1 +) + +const TEXT_SIZE = new NumberSetting( + QT_TR_NOOP("Text size (px)"), + "default_graph.textsize", + "textsize" +) + +const X_LABEL = new StringSetting( + QT_TR_NOOP('X Label'), + "default_graph.xlabel", + "xlabel", + ["", "x", "ω (rad/s)"] +) + +const Y_LABEL = new StringSetting( + QT_TR_NOOP('Y Label'), + "default_graph.ylabel", + "xlabel", + ["", "y", "G (dB)", "φ (°)", "φ (deg)", "φ (rad)"] +) + +const LOG_SCALE_X = new BoolSetting( + QT_TR_NOOP('X Log scale'), + "default_graph.logscalex", + "logscalex" +) + +const SHOW_X_GRAD = new BoolSetting( + QT_TR_NOOP('Show X graduation'), + "default_graph.showxgrad", + "showxgrad" +) + +const SHOW_Y_GRAD = new BoolSetting( + QT_TR_NOOP('Show Y graduation'), + "default_graph.showygrad", + "showygrad" +) + +export default [ + XZOOM, + YZOOM, + XMIN, + YMAX, + XAXISSTEP, + YAXISSTEP, + LINE_WIDTH, + TEXT_SIZE, + X_LABEL, + Y_LABEL, + LOG_SCALE_X, + SHOW_X_GRAD, + SHOW_Y_GRAD +] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs new file mode 100644 index 0000000..92990b8 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs @@ -0,0 +1,51 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, EnumIntSetting} from "common.mjs" + +const AUTOCLOSE_FORMULA = new BoolSetting( + QT_TR_NOOP("Automatically close parenthesises and brackets"), + 'expression_editor.autoclose', + 'text' +) + +const ENABLE_SYNTAX_HIGHLIGHTING = new BoolSetting( + QT_TR_NOOP("Enable syntax highlighting"), + 'expression_editor.colorize', + 'appearance' +) + +const ENABLE_AUTOCOMPLETE = new BoolSetting( + QT_TR_NOOP("Enable autocompletion"), + 'autocompletion.enabled', + 'label' +) + +const PICK_COLOR_SCHEME = new EnumIntSetting( + QT_TR_NOOP("Color Scheme"), + 'expression_editor.color_scheme', + 'color', + ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] +) + +export default [ + AUTOCLOSE_FORMULA, + ENABLE_AUTOCOMPLETE, + ENABLE_SYNTAX_HIGHLIGHTING, + PICK_COLOR_SCHEME +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs similarity index 75% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 2430b52..0954f67 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -18,17 +18,17 @@ import {BoolSetting} from "common.mjs" -class CheckForUpdates extends BoolSetting { - constructor() { - super(QT_TR_NOOP("Check for updates on startup"), 'check_for_updates', 'update') - } -} +const CHECK_FOR_UPDATES = new BoolSetting( + QT_TR_NOOP("Check for updates on startup"), + 'check_for_updates', + 'update' +) -class ResetRedoStack extends BoolSetting { - constructor() { - super(qsTr("Reset redo stack automaticly"), 'reset_redo_stack', 'timeline') - } -} +const RESET_REDO_STACK = new BoolSetting( + QT_TR_NOOP("Reset redo stack automaticly"), + 'reset_redo_stack', + 'timeline' +) class EnableLatex extends BoolSetting { constructor() { @@ -43,7 +43,7 @@ class EnableLatex extends BoolSetting { } export default [ - new CheckForUpdates(), - new ResetRedoStack(), + CHECK_FOR_UPDATES, + RESET_REDO_STACK, new EnableLatex() ] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs deleted file mode 100644 index 2e395c6..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs +++ /dev/null @@ -1,67 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -class Setting { - constructor(name, nameInConfig, icon) { - this.name = name - this.displayName = qsTr(name) - this.nameInConfig = nameInConfig - this.icon = icon - } - - /** - * Returns the value of the setting. - * @returns {string|boolean|number} - */ - value() { - throw new TypeError(`value of ${this.constructor} not implemented.`) - } - - /** - * Sets the value of the setting - * @param {string|boolean|number} value - */ - set(value) { - throw new TypeError(`value of ${this.constructor} not implemented.`) - } -} - -export class BoolSetting extends Setting { - value() { - return Helper.getSettingBool(this.nameInConfig) - } - - set(value) { - Helper.setSettingBool(this.nameInConfig, value) - } -} - -export class IntSetting extends Setting { - value() { - return Helper.getSettingInt(this.nameInConfig) - } - - set(value) { - Helper.setSettingInt(this.nameInConfig, value) - } -} - -export class EnumIntSetting extends IntSetting { - values() { - throw new TypeError(`enumerations of ${this.constructor} not implemented.`) - } -} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs deleted file mode 100644 index 0fab509..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs +++ /dev/null @@ -1,54 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import {BoolSetting, EnumIntSetting} from "common.mjs" - -class AutocloseFormula extends BoolSetting { - constructor() { - super(qsTr("Automatically close parenthesises and brackets"), 'expression_editor.autoclose', 'Text') - } -} - -class EnableSyntaxHighlighting extends BoolSetting { - constructor() { - super(qsTr("Enable syntax highlighting"), 'expression_editor.colorize', 'appearance') - } -} - -class EnableAutocomplete extends BoolSetting { - constructor() { - super(qsTr("Enable autocompletion"), 'autocompletion.enabled', 'label') - } -} - -class PickColorScheme extends EnumIntSetting { - constructor() { - super(qsTr("Color Scheme"), 'expression_editor.color_scheme', 'color') - } - - values() { - return ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - } -} - -export default [ - new AutocloseFormula(), - new EnableAutocomplete(), - new EnableSyntaxHighlighting(), - new PickColorScheme() -] \ No newline at end of file diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index bdd11b7..5c2c653 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -34,6 +34,21 @@ DEFAULT_SETTINGS = { }, "autocompletion": { "enabled": True + }, + "default_graph": { + "xzoom": 100, + "yzoom": 10, + "xmin": 5/10, + "ymax": 25, + "xaxisstep": "4", + "yaxisstep": "4", + "xlabel": "", + "ylabel": "", + "linewidth": 1, + "textsize": 18, + "logscalex": True, + "showxgrad": True, + "showygrad": True } } diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index e6e9dfb..47e7395 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -129,8 +129,9 @@ class Helper(QObject): def getSetting(self, namespace): return config.getSetting(namespace) - @Slot(str, result=int) + @Slot(str, result=float) def getSettingInt(self, namespace): + print('Getting', namespace, config.getSetting(namespace)) return config.getSetting(namespace) @Slot(str, result=bool) @@ -145,7 +146,7 @@ class Helper(QObject): def setSettingBool(self, namespace, value): return config.setSetting(namespace, value) - @Slot(str, int) + @Slot(str, float) def setSettingInt(self, namespace, value): return config.setSetting(namespace, value) From 915c6b5246f34f63f618e75acfd273cf09194bae Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 3 Apr 2024 22:05:57 +0200 Subject: [PATCH 015/249] Setting version to v0.6.0 --- LogarithmPlotter/__init__.py | 2 +- mac/Info.plist | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index d8bb713..9c675a2 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.5.1" +__VERSION__ = "0.6.0" is_release = False diff --git a/mac/Info.plist b/mac/Info.plist index d7c0c50..1ba304b 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.6.0 NSHighResolutionCapable UTExportedTypeDeclarations diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index f7e9cbe..745f05b 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.5.0 +VERSION=0.6.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index c6632f9..e8c8628 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.5.0' +version: '0.6.0' summary: Create and edit Bode plots confinement: strict base: core22 diff --git a/win/installer.nsi b/win/installer.nsi index 7c5b248..58261ff 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.5.0" +!define VERSION_SHORT "0.6.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2021-2024" !define DESCRIPTION "Create graphs with logarithm scales." From 87d8882db10e10f25f1d013a58b875b361f1916a Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Tue, 2 Apr 2024 21:16:37 +0000 Subject: [PATCH 016/249] Translated using Weblate (Spanish) Currently translated at 80.2% (244 of 304 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 343 +++++++++++++++++++++++++++++---- 1 file changed, 310 insertions(+), 33 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 37c6da8..46b9a2e 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -110,22 +110,22 @@ Automatically close parenthesises and brackets - + Cerrar automáticamente paréntesis y corchetes Enable syntax highlighting - + Activar el resaltado sintáctico Enable autocompletion - + Activar autocompletar Color Scheme - + Esquema de colores @@ -175,7 +175,7 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -183,7 +183,7 @@ Close - + Cerrar @@ -199,12 +199,12 @@ Fetching changelog... - + Obteniendo el registro de cambios… Close - + Cerrar @@ -213,12 +213,12 @@ + Create new %1 - + + Crear nuevo %1 Pick on graph - + Elegir en el gráfico @@ -226,17 +226,17 @@ Edit properties of %1 %2 - + Editar las propiedades de %1 %2 LogarithmPlotter - Invalid object name - + LogarithmPlotter - Nombre de objeto no válido An object with the name '%1' already exists. - + Ya existe un objeto con el nombre '%1'. @@ -261,7 +261,7 @@ name + value - + nombre + valor @@ -269,7 +269,7 @@ Object Properties - + Propiedades de los objetos @@ -279,12 +279,12 @@ Constants - + Constantes Functions - + Funciones @@ -389,17 +389,17 @@ These settings can be changed at any time from the "Settings" menu. Redo > - + Rehacer > > Now - + > Ahora < Undo - + < Deshacer @@ -415,32 +415,56 @@ These settings can be changed at any time from the "Settings" menu. Objects - + Objetos Settings - + Ajustes History - + Historial Copied plot screenshot to clipboard! - + ¡Captura de pantalla del gráfico copiada al portapapeles! &Update - + &Actualizar &Update LogarithmPlotter - + &Actualizar LogarithmPlotter + + + Unknown object type: %1. + Tipo de objeto desconocido: %1 . + + + Saved plot to '%1'. + Gráfico guardado en '%1'. + + + Loading file '%1'. + Cargando el archivo '%1'. + + + Invalid file provided. + Se ha proporcionado un archivo no válido. + + + Could not save file: + No se ha podido guardar el archivo: + + + Loaded file '%1'. + Archivo cargado '%1'. @@ -463,6 +487,26 @@ These settings can be changed at any time from the "Settings" menu.Show all %1 + + Delete %1 %2 + Borrar %1 %2 + + + Hide %1 %2 + Ocultar %1 %2 + + + Show %1 %2 + Mostrar %1 %2 + + + Set %1 %2 position + Fijar la posición %1 %2 + + + Pick new color for %1 %2 + Elegir nuevo color para %1 %2 + ObjectRow @@ -529,6 +573,10 @@ These settings can be changed at any time from the "Settings" menu.(no pick selected) + + Snap to grid + Ajustar a la cuadrícula + Settings @@ -920,6 +968,14 @@ Evaluated expression: %3 Undoing last change. + + Function definition is not permitted. + No se permite la definición de las funciones. + + + Expected variable for assignment. + Variable de asignación esperada. + expression @@ -1003,22 +1059,22 @@ Please make sure your latex installation is correct and report a bug if so. An update for LogarithPlotter (v{}) is available. - + Una actualización para LogarithmPlotter (v{}) está disponible. No update available. - + No hay ninguna actualización disponible. Could not fetch update information: Server error {}. - + No se ha podido obtener la información de la actualización: Error del servidor {}. Could not fetch update information: {}. - + No se pudo obtener información de la actualización: {}. @@ -1027,7 +1083,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + Uso: %1 @@ -1035,12 +1091,13 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + Uso: %1 o +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) @@ -1058,4 +1115,224 @@ Please make sure your latex installation is correct and report a bug if so. + + io + + History + Historial + + + Copied plot screenshot to clipboard! + ¡Captura de pantalla del gráfico copiada al portapapeles! + + + &Update + &Actualizar + + + &Update LogarithmPlotter + &Actualizar LogarithmPlotter + + + Settings + Ajustes + + + Objects + Objetos + + + + color + + %1 %2's color changed from %3 to %4. + El color de %1 %2 cambió de %3 a %4. + + + + create + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + + editproperty + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + %1 of %2 changed from %3 to %4. + %1 de %2 ha cambiado de %3 a %4. + + + + function + + Function + Función + + + Functions + Funciones + + + + gainbode + + high-pass + Filtro paso alto + + + low-pass + Filtro paso bajo + + + Bode Magnitude + Magnitud de Bode + + + Bode Magnitudes + Magnitudes de Bode + + + + historylib + + %1 %2 deleted. + %1 %2 borrados. + + + %1 %2 shown. + Se muestra %1 %2. + + + %1 %2 hidden. + Se oculta %1 %2. + + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + Name of %1 %2 changed to %3. + El nombre de %1 %2 se ha cambiado por %3. + + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + + parameters + + below + ↓ Abajo + + + left + ← Izquierda + + + above-left + ↖ Arriba a la izquierda + + + below-left + ↙ Abajo a la izquierda + + + below-right + ↘ Arriba a la derecha + + + center + >|< Centro + + + top + ↑ Arriba + + + above + ↑ Arriba + + + right + → Derecha + + + above-right + ↗ Arriba a la derecha + + + + EditorDialog + + Label content + Contenido de la etiqueta + + + null + nulo + + + name + nombre + + + name + value + nombre + valor + + + + Create new %1 + + Crear nuevo %1 + + + Edit properties of %1 %2 + Editar propiedades de %1 %2 + + + Name + Nombre + + + + comment + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) + + + Note: Specify the probability for each value. + Nota: Especifique la probabilidad para cada valor. + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. + + + + delete + + %1 %2 deleted. + %1 %2 borrados. + + + + name + + %1 %2 renamed to %3. + %1 %2 ha sido renombrado a %3. + + From 136ac4c7bc960fcaeb5bb14c54e6b20a599ff28a Mon Sep 17 00:00:00 2001 From: ovari Date: Sat, 20 Apr 2024 05:46:53 +0000 Subject: [PATCH 017/249] Translated using Weblate (Hungarian) Currently translated at 100.0% (304 of 304 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index d9933cc..a7d3804 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1178,6 +1178,10 @@ Kiértékelt kifejezés: %3 %1 %2 hidden. %1 %2 rejtve. + + Name of %1 %2 changed to %3. + %1 %2 neve a következőre módosult: %3. + io @@ -1225,6 +1229,10 @@ Kiértékelt kifejezés: %3 &Update LogarithmPlotter A LogarithmPlotter &frissítése + + Objects + Objektumok + latex @@ -1508,6 +1516,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents baseValues Kezdeményezési értékek + + color + Szín + repartition @@ -1538,6 +1550,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents general + + editor + Kifejezésszerkesztő + + + default + Alapértelmezett ábra + sommegainsbode From 606ec428abfae73f716f78ca9898540cf3a566ea Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 15 Sep 2024 21:30:44 +0200 Subject: [PATCH 018/249] Fixing issue with setting JS objects being serialized into ListViews. + Fixing broken links on Linux --- .../LogarithmPlotter/Popup/Preferences.qml | 23 ++++--- .../LogarithmPlotter/js/preferences.mjs | 2 +- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 66 +++++++++---------- linux/generate-appstream-changelog.sh | 18 ++--- 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index aece6aa..9d7b9c0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -163,8 +163,7 @@ Popup { text: qsTranslate('settingCategory', modelData) onClicked: { - settingView.model = Modules.Preferences.categories[modelData] - settingView.name = text + settingView.modelName = modelData } } } @@ -203,13 +202,13 @@ Popup { clip: true width: 500 spacing: 10 - model: Modules.Preferences.categories.general + model: Modules.Preferences.categories[modelName] anchors { top: parent.top bottom: parent.bottom } ScrollBar.vertical: ScrollBar { } - property string name: qsTranslate('settingCategory', 'general') + property string modelName: 'general' header: Text { @@ -217,7 +216,7 @@ Popup { font.pixelSize: 32 height: 48 color: sysPalette.windowText - text: settingView.name + text: qsTranslate('settingCategory', settingView.modelName) Rectangle { id: bottomSeparator @@ -233,20 +232,20 @@ Popup { delegate: Component { Loader { width: settingView.width * 2 / 3 - property var setting: modelData + property var setting: Modules.Preferences.categories[settingView.modelName][index] sourceComponent: { - if(setting instanceof S.BoolSetting) + if(setting.type === "bool") return boolSettingComponent - else if(setting instanceof S.EnumIntSetting) + else if(setting.type === "enum") return enumIntSettingComponent - else if(setting instanceof S.NumberSetting) + else if(setting.type === "number") return numberSettingComponent - else if(setting instanceof S.ExpressionSetting) + else if(setting.type === "expression") return expressionSettingComponent - else if(setting instanceof S.StringSetting) + else if(setting.type === "string") return stringSettingComponent else - console.log('Unknown setting type!', modelData.constructor) + console.log('Unknown setting type!', setting.constructor.name, setting.constructor) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs index 0407ee1..40ac532 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs @@ -37,4 +37,4 @@ class PreferencesAPI extends Module { /** @type {CanvasAPI} */ Modules.Preferences = Modules.Preferences || new PreferencesAPI() -export const API = Modules.Preferences \ No newline at end of file +export const API = Modules.Preferences diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 259edb1..76922ed 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -149,13 +149,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-v0.5.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-v0.5.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/LogarithmPlotter-v0.5.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/LogarithmPlotter-v0.5.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-0.5.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-0.5.0.tar.gz @@ -198,13 +198,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-v0.4.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-v0.4.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/LogarithmPlotter-v0.4.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/LogarithmPlotter-v0.4.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-0.4.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-0.4.0.tar.gz @@ -264,13 +264,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-v0.3.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-v0.3.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/LogarithmPlotter-v0.3.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/LogarithmPlotter-v0.3.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-0.3.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-0.3.0.tar.gz @@ -317,13 +317,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-v0.2.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-v0.2.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/LogarithmPlotter-v0.2.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/LogarithmPlotter-v0.2.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-0.2.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-0.2.0.tar.gz @@ -362,13 +362,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/LogarithmPlotter-v0.1.8-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/LogarithmPlotter-v0.1.8-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-0.1.8.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-0.1.8.tar.gz @@ -418,13 +418,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/LogarithmPlotter-v0.1.7-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/LogarithmPlotter-v0.1.7-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-0.1.7.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-0.1.7.tar.gz @@ -459,13 +459,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6.tar.gz @@ -489,13 +489,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5.tar.gz @@ -520,13 +520,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4.tar.gz @@ -541,13 +541,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3.tar.gz @@ -565,13 +565,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2.tar.gz diff --git a/linux/generate-appstream-changelog.sh b/linux/generate-appstream-changelog.sh index 331239f..c72e0d4 100644 --- a/linux/generate-appstream-changelog.sh +++ b/linux/generate-appstream-changelog.sh @@ -11,13 +11,13 @@ BEGIN { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " @@ -58,13 +58,13 @@ BEGIN { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " @@ -74,13 +74,13 @@ END { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " From 88797d00be9bd30f83a8d07be2ef49f6c2e911f1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:34:35 +0200 Subject: [PATCH 019/249] Adding new translations for v0.6.0 + adding Spanish credits --- LogarithmPlotter/i18n/lp_de.ts | 172 ++++--- LogarithmPlotter/i18n/lp_en.ts | 165 +++---- LogarithmPlotter/i18n/lp_es.ts | 641 +++++++++++++-------------- LogarithmPlotter/i18n/lp_fr.ts | 172 ++++--- LogarithmPlotter/i18n/lp_hu.ts | 169 ++++--- LogarithmPlotter/i18n/lp_nb_NO.ts | 220 ++++----- LogarithmPlotter/i18n/lp_template.ts | 252 ++++------- README.md | 3 +- 8 files changed, 806 insertions(+), 988 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 393e01f..8fa02e1 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + + &Preferences + + + + &Create &Erstellen - &Settings &Einstellungen - Check for updates on startup Beim Starten auf Updates prüfen - Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - Enable LaTeX rendering LaTeX-Rendering aktivieren - Expression editor Ausdruckseditor - Automatically close parenthesises and brackets Klammern automatisch schließen - Enable syntax highlighting Syntaxhervorhebung einschalten - Enable autocompletion Automatische Vervollständigung einschalten - Color Scheme Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Beim Starten auf Updates prüfen @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - Enable LaTeX rendering LaTeX-Rendering aktivieren - Automatically close parenthesises and brackets in expressions Automatisches Schließen von Klammern in Ausdrücken - Enable syntax highlighting for expressions Syntaxhervorhebung für Ausdrücke einschalten - Enable autocompletion interface in expression editor Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren - Color scheme: Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + + Preferences + + + + Close Schließen @@ -610,6 +602,14 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" (keine Auswahl ausgewählt) + + Preferences + + + Close + Schließen + + Settings @@ -618,97 +618,96 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zoom auf X - + Y Zoom Zoom auf Y - + Min X Minimum X - + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern - + Save plot as Grafik speichern unter - + Load plot Grafik laden - Close Schließen @@ -853,10 +852,10 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. @@ -1074,12 +1073,12 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.o DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1543,14 +1547,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Folgen - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index dbc3714..2f4ea77 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + + &Preferences + + + + &Create &Create - &Settings &Settings - Check for updates on startup Check for updates on startup - Reset redo stack automaticly Reset redo stack automatically - Enable LaTeX rendering Enable LaTeX rendering - Expression editor Expression editor - Automatically close parenthesises and brackets Automatically close parentheses and brackets - Enable syntax highlighting Enable syntax highlighting - Enable autocompletion Enable autocompletion - Color Scheme Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Check for updates on startup @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - Enable LaTeX rendering Enable LaTeX rendering - Automatically close parenthesises and brackets in expressions Automatically close parentheses and brackets in expressions - Enable syntax highlighting for expressions Enable syntax highlighting for expressions - Enable autocompletion interface in expression editor Enable autocompletion interface in expression editor - Color scheme: Color scheme: - + User manual User manual - + Changelog Changelog - + + Preferences + + + + Close Close @@ -610,6 +602,14 @@ These settings can be changed at any time from the "Settings" menu.(no pick selected) + + Preferences + + + Close + Close + + Settings @@ -618,97 +618,96 @@ These settings can be changed at any time from the "Settings" menu.X Zoom - + Y Zoom Y Zoom - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot - + Save plot as Save plot as - + Load plot Open plot - Close Close @@ -853,10 +852,10 @@ These settings can be changed at any time from the "Settings" menu.control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ These settings can be changed at any time from the "Settings" menu.End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. @@ -1074,12 +1073,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.or DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1546,7 +1550,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory - general General diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 46b9a2e..bb33fbe 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -33,147 +33,139 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + + &Preferences + + + + &Create &Crear - &Settings &Ajustes - Check for updates on startup Comprobación de las actualizaciones al arrancar - Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - Enable LaTeX rendering Activar el renderizado de LaTeX - - Expression editor - - - - Automatically close parenthesises and brackets Cerrar automáticamente paréntesis y corchetes - Enable syntax highlighting Activar el resaltado sintáctico - Enable autocompletion Activar autocompletar - Color Scheme Esquema de colores - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -189,7 +181,6 @@ BoolSetting - Check for updates on startup Comprobación de las actualizaciones al arrancar @@ -264,35 +255,66 @@ nombre + valor + + EditorDialog + + Label content + Contenido de la etiqueta + + + null + nulo + + + name + nombre + + + name + value + nombre + valor + + + + Create new %1 + + Crear nuevo %1 + + + Edit properties of %1 %2 + Editar propiedades de %1 %2 + + + Name + Nombre + + ExpressionEditor - + Object Properties Propiedades de los objetos - + Variables - + Constants Constantes - + Functions Funciones - + Executable Objects - + Objects @@ -313,68 +335,36 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - - Take a few seconds to configure LogarithmPlotter. -These settings can be changed at any time from the "Settings" menu. - - - - - Check for updates on startup (requires online connectivity) - - - - - Reset redo stack when a new action is added to history - - - - Enable LaTeX rendering Activar el renderizado de LaTeX - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -578,6 +568,14 @@ These settings can be changed at any time from the "Settings" menu.Ajustar a la cuadrícula + + Preferences + + + Close + Cerrar + + Settings @@ -586,100 +584,95 @@ These settings can be changed at any time from the "Settings" menu. - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot - - - Close - - ThanksTo @@ -787,18 +780,73 @@ These settings can be changed at any time from the "Settings" menu. + + color + + %1 %2's color changed from %3 to %4. + El color de %1 %2 cambió de %3 a %4. + + + + comment + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) + + + Note: Specify the probability for each value. + Nota: Especifique la probabilidad para cada valor. + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. + + control - - + + - + %1: + + create + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + + delete + + %1 %2 deleted. + %1 %2 borrados. + + + + editproperty + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + %1 of %2 changed from %3 to %4. + %1 de %2 ha cambiado de %3 a %4. + + error @@ -928,27 +976,27 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -981,12 +1029,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -999,6 +1047,36 @@ Evaluated expression: %3 + + function + + Function + Función + + + Functions + Funciones + + + + gainbode + + high-pass + Filtro paso alto + + + low-pass + Filtro paso bajo + + + Bode Magnitude + Magnitud de Bode + + + Bode Magnitudes + Magnitudes de Bode + + general @@ -1014,6 +1092,60 @@ Evaluated expression: %3 Activar el renderizado de LaTeX + + historylib + + %1 %2 deleted. + %1 %2 borrados. + + + %1 %2 shown. + Se muestra %1 %2. + + + %1 %2 hidden. + Se oculta %1 %2. + + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + Name of %1 %2 changed to %3. + El nombre de %1 %2 se ha cambiado por %3. + + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + + io + + History + Historial + + + Copied plot screenshot to clipboard! + ¡Captura de pantalla del gráfico copiada al portapapeles! + + + &Update + &Actualizar + + + &Update LogarithmPlotter + &Actualizar LogarithmPlotter + + + Settings + Ajustes + + + Objects + Objetos + + latex @@ -1029,7 +1161,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1038,7 +1170,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1047,11 +1184,53 @@ Please make sure your latex installation is correct and report a bug if so. - settingCategory + name - - general - + %1 %2 renamed to %3. + %1 %2 ha sido renombrado a %3. + + + + parameters + + below + ↓ Abajo + + + left + ← Izquierda + + + above-left + ↖ Arriba a la izquierda + + + below-left + ↙ Abajo a la izquierda + + + below-right + ↘ Arriba a la derecha + + + center + >|< Centro + + + top + ↑ Arriba + + + above + ↑ Arriba + + + right + → Derecha + + + above-right + ↗ Arriba a la derecha @@ -1115,224 +1294,4 @@ Please make sure your latex installation is correct and report a bug if so. - - io - - History - Historial - - - Copied plot screenshot to clipboard! - ¡Captura de pantalla del gráfico copiada al portapapeles! - - - &Update - &Actualizar - - - &Update LogarithmPlotter - &Actualizar LogarithmPlotter - - - Settings - Ajustes - - - Objects - Objetos - - - - color - - %1 %2's color changed from %3 to %4. - El color de %1 %2 cambió de %3 a %4. - - - - create - - New %1 %2 created. - Se ha creado un nuevo %1 %2. - - - - editproperty - - %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 cambió de "%4" a "%5". - - - %1 of %2 changed from %3 to %4. - %1 de %2 ha cambiado de %3 a %4. - - - - function - - Function - Función - - - Functions - Funciones - - - - gainbode - - high-pass - Filtro paso alto - - - low-pass - Filtro paso bajo - - - Bode Magnitude - Magnitud de Bode - - - Bode Magnitudes - Magnitudes de Bode - - - - historylib - - %1 %2 deleted. - %1 %2 borrados. - - - %1 %2 shown. - Se muestra %1 %2. - - - %1 %2 hidden. - Se oculta %1 %2. - - - New %1 %2 created. - Se ha creado un nuevo %1 %2. - - - Name of %1 %2 changed to %3. - El nombre de %1 %2 se ha cambiado por %3. - - - %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 cambió de "%4" a "%5". - - - - parameters - - below - ↓ Abajo - - - left - ← Izquierda - - - above-left - ↖ Arriba a la izquierda - - - below-left - ↙ Abajo a la izquierda - - - below-right - ↘ Arriba a la derecha - - - center - >|< Centro - - - top - ↑ Arriba - - - above - ↑ Arriba - - - right - → Derecha - - - above-right - ↗ Arriba a la derecha - - - - EditorDialog - - Label content - Contenido de la etiqueta - - - null - nulo - - - name - nombre - - - name + value - nombre + valor - - - + Create new %1 - + Crear nuevo %1 - - - Edit properties of %1 %2 - Editar propiedades de %1 %2 - - - Name - Nombre - - - - comment - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) - - - Note: Specify the probability for each value. - Nota: Especifique la probabilidad para cada valor. - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. - - - - delete - - %1 %2 deleted. - %1 %2 borrados. - - - - name - - %1 %2 renamed to %3. - %1 %2 ha sido renombrado a %3. - - diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 3dd5482..aa78b8f 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -33,148 +33,144 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + + &Preferences + + + + &Create &Créer - &Settings &Paramètres - Check for updates on startup Vérifier la présence de mise à jour au démarrage - Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - Enable LaTeX rendering Activer le rendu LaTeX - Expression editor Éditeur de formule - Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - Enable syntax highlighting Activer la coloration syntaxique - Enable autocompletion Activer l'autocomplétion - Color Scheme Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -190,7 +186,6 @@ BoolSetting - Check for updates on startup Vérifier la présence de mise à jour au démarrage @@ -300,32 +295,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -346,59 +341,58 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - Enable LaTeX rendering Activer le rendu LaTeX - Automatically close parenthesises and brackets in expressions Fermer automatiquement les parenthèses et les crochets dans les formules - Enable syntax highlighting for expressions Activer la coloration syntaxique des formules - Enable autocompletion interface in expression editor Activer l'interface d'autocomplétion dans l'éditeur de formules - Color scheme: Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + + Preferences + + + + Close Fermer @@ -409,12 +403,10 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -618,6 +610,14 @@ These settings can always be changed at any time from the "Settings" m (aucun axe sélectionné) + + Preferences + + + Close + Fermer + + Settings @@ -626,97 +626,96 @@ These settings can always be changed at any time from the "Settings" m Zoom en X - + Y Zoom Zoom en Y - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe - + Save plot as Sauvegarder le graphe sous - + Load plot Ouvrir un graphe - Close Fermer @@ -862,10 +861,10 @@ These settings can always be changed at any time from the "Settings" m control - - + + - + %1: %1 : @@ -1032,27 +1031,27 @@ These settings can always be changed at any time from the "Settings" m Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. @@ -1083,12 +1082,12 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1260,7 +1259,7 @@ Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l&apos DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1273,7 +1272,12 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1552,14 +1556,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Suites - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index a7d3804..0252785 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + + &Preferences + + + + &Create &Létrehozás - &Settings &Beállítások - Check for updates on startup Frissítések keresése indításkor - Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - Expression editor Kifejezésszerkesztő - Automatically close parenthesises and brackets Zárójelek automatikus bezárása - Enable syntax highlighting Mondattani kiemelés engedélyezése - Enable autocompletion Automatikus befejezés engedélyezése - Color Scheme Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Frissítések keresése indításkor @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - Automatically close parenthesises and brackets in expressions Zárójelek automatikus bezárása a kifejezésekben - Enable syntax highlighting for expressions Mondattani kiemelés engedélyezése a kifejezésekhez - Enable autocompletion interface in expression editor Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben - Color scheme: Színséma: - + User manual Használati utasítás - + Changelog Változásnapló - + + Preferences + + + + Close Kész @@ -610,6 +602,14 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. (nincs kijelölés kiválasztva) + + Preferences + + + Close + + + Settings @@ -618,97 +618,96 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. X-nagyítás - + Y Zoom Y-nagyítás - + Min X Legkisebb X - + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése - + Save plot as Ábra mentése másként - + Load plot Ábra betöltése - Close Kész @@ -853,10 +852,10 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. @@ -1074,12 +1073,12 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1545,11 +1549,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory - - - general - - editor Kifejezésszerkesztő diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 314a690..99b3698 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -33,147 +33,119 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + + &Preferences + + + + &Create &Opprett - &Settings &Innstillinger - Check for updates on startup Se etter nye versjoner ved programstart - Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - - Enable LaTeX rendering - - - - - Expression editor - - - - - Automatically close parenthesises and brackets - - - - - Enable syntax highlighting - - - - - Enable autocompletion - - - - - Color Scheme - - - - + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -189,7 +161,6 @@ BoolSetting - Check for updates on startup Se etter nye versjoner ved programstart @@ -298,32 +269,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -344,69 +315,46 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - - Enable LaTeX rendering - - - - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -610,6 +558,14 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + Preferences + + + Close + + + Settings @@ -618,100 +574,95 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.X-forstørrelse - + Y Zoom Y-forstørrelse - + Min X Min. X - + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation Vis X-inndeling - + Show Y graduation Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott - - - Close - - ThanksTo @@ -823,10 +774,10 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.control - - + + - + %1: @@ -981,27 +932,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -1026,12 +977,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1174,7 +1125,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1183,7 +1134,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1235,14 +1191,6 @@ Please make sure your latex installation is correct and report a bug if so.Følger - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 426049e..55e57b6 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -33,147 +33,107 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + + &Preferences + + + + &Create - - &Settings - - - - - Check for updates on startup - - - - - Reset redo stack automaticly - - - - - Enable LaTeX rendering - - - - - Expression editor - - - - - Automatically close parenthesises and brackets - - - - - Enable syntax highlighting - - - - - Enable autocompletion - - - - - Color Scheme - - - - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -186,14 +146,6 @@ - - BoolSetting - - - Check for updates on startup - - - Changelog @@ -267,32 +219,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -313,68 +265,32 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - - Take a few seconds to configure LogarithmPlotter. -These settings can be changed at any time from the "Settings" menu. - - - - - Check for updates on startup (requires online connectivity) - - - - - Reset redo stack when a new action is added to history - - - - - Enable LaTeX rendering - - - - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -530,6 +446,14 @@ These settings can be changed at any time from the "Settings" menu. + + Preferences + + + Close + + + Settings @@ -538,100 +462,95 @@ These settings can be changed at any time from the "Settings" menu. - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot - - - Close - - ThanksTo @@ -743,10 +662,10 @@ These settings can be changed at any time from the "Settings" menu.control - - + + - + %1: @@ -880,27 +799,27 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -925,12 +844,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -958,7 +877,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -967,7 +886,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -975,14 +899,6 @@ Please make sure your latex installation is correct and report a bug if so. - - settingCategory - - - general - - - update diff --git a/README.md b/README.md index 026528f..a60a9a5 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,9 @@ There are several ways to contribute to LogarithmPlotter. along with this program. If not, see . Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their original authors. See LICENSE.md for more details: -- 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) - 🇭🇺 Hungarian translation by [Óvári](https://github.com/ovari) +- 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) +- 🇪🇸 Spanish translation by gallegonovato and [IngrownMink4](https://github.com/IngrownMink4) ### Libraries used From 4b1cf2cd9d1b933e8cb54cd3a9c68f59021ba65c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 20:00:56 +0200 Subject: [PATCH 020/249] Improving linux metainfo generation. --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 162 ++++++++++-------- linux/generate-appstream-changelog.sh | 2 +- 2 files changed, 89 insertions(+), 75 deletions(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 76922ed..6b5847b 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,77 +1,66 @@ - - + + eu.ad5001.LogarithmPlotter - eu.ad5001.LogarithmPlotter.desktop logarithmplotter.desktop CC0-1.0 GPL-3.0+ LogarithmPlotter - http://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg + https://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg Create and edit Bode plots Erstellen und Bearbeiten von Bode-Diagrammen Créez et éditez des diagrammes de Bode Bode-diagramok létrehozása és szerkesztése Opprette og redigere Bode-diagrammer -

LogarithmPlotter is, as it's name suggests, a plotter made with logarithm scales in mind. With an object system similar to Geogebra's, it allows dynamic creation of both logarithmic-scaled and non logarithmic-scaled plots with very few limitations.

+

+ LogarithmPlotter est, comme son nom l'indique, un créateur de graphes et diagrammes 2D réalisé avec l'échelle logarithmique en tête. Avec un système d'objets similaire à Geogebra, ce qui lui permet de créer des graphes à échelle logarithmique et non logarithmique avec peu de limitations. +

+

+ A LogarithmPlotter egy logaritmus-ábrázoló, amely logaritmikus léptékek figyelembevételével készült. A Geogebrához hasonló objektumrendszerrel dinamikus parcellák létrehozását teszi lehetővé, nagyon kevés korlátozással. +

It's primary use is to quickly create asymptotic Bode plots, but it's extensible nature and ability to switch to non-logarithmic scales allow it to create other things with it, like sequences or statistical repartition functions.

+

+ Son intérêt principal est de permettre de créer des diagrammes asymptotiques de Bode, mais sa nature extensible et sa capacité à passer à une échelle non-logarithmique lui permet de créer d'autres choses. +

+

+ Elsődleges felhasználása az aszimptotikus Bode-ábrák gyors létrehozása, de bővíthető jellege és a nem logaritmikus skálákra váltás lehetősége lehetővé teszi, hogy más dolgokat is létrehozzon vele, például sorozatokat vagy statisztikai újraosztási függvényeket. +

Features:

+

Fonctionnalités:

  • Graphical objects (points, fonctions, Bode magnitudes...) management system
  • Complete object edition
  • Advanced history system
  • Diagram looks customisation
  • +
  • Système de gestion des objets graphiques (points, fonctions, gains de Bode...)
  • +
  • Modification complète des objets
  • +
  • Système d'historique avancé
  • +
  • Personnalisation de l'apparence des diagrammes

LogarithmPlotter is available in:

+

LogarithmPlotter est disponible en:

  • 🇬🇧 English
  • 🇫🇷 French
  • 🇩🇪 German
  • 🇭🇺 Hungarian
  • 🇳🇴 Norwergian
  • +
  • 🇪🇸 Spanish
  • +
  • 🇬🇧 Anglais
  • +
  • 🇫🇷 Français
  • +
  • 🇩🇪 Allemand
  • +
  • 🇭🇺 Hongrois
  • +
  • 🇳🇴 Norvégien
  • +
  • 🇪🇸 Espagnol
-

Learn more: https://apps.ad5001.eu/logarithmplotter/

-

- LogarithmPlotter est, comme son nom l'indique, un créateur de graphes et diagrammes 2D réalisé avec l'échelle logarithmique en tête. Avec un système d'objets similaire à Geogebra, ce qui lui permet de créer des graphes à échelle logarithmique et non logarithmique avec peu de limitations. -

-

- Son intérêt principal est de permettre de créer des diagrammes asymptotiques de Bode, mais sa nature extensible et sa capacité à passer à une échelle non-logarithmique lui permet de créer d'autres choses. -

-

Fonctionnalités:

-
    -
  • Système de gestion des objets graphiques (points, fonctions, gains de Bode...)
  • -
  • Modification complète des objets
  • -
  • Système d'historique avancé
  • -
  • Personnalisation de l'apparence des diagrammes
  • -
-

LogarithmPlotter est disponible en:

-
    -
  • 🇬🇧 Anglais
  • -
  • 🇫🇷 Français
  • -
  • 🇩🇪 Allemand
  • -
  • 🇭🇺 Hongrois
  • -
  • 🇳🇴 Norvégien
  • -
-

En savoir plus: https://apps.ad5001.eu/fr/logarithmplotter/

-

- A LogarithmPlotter egy logaritmus-ábrázoló, amely logaritmikus léptékek figyelembevételével készült. A Geogebrához hasonló objektumrendszerrel dinamikus parcellák létrehozását teszi lehetővé, nagyon kevés korlátozással. -

-

- Elsődleges felhasználása az aszimptotikus Bode-ábrák gyors létrehozása, de bővíthető jellege és a nem logaritmikus skálákra váltás lehetősége lehetővé teszi, hogy más dolgokat is létrehozzon vele, például sorozatokat vagy statisztikai újraosztási függvényeket. -

@@ -84,40 +73,62 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues/ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ + - https://apps.ad5001.eu/img/en/gain.png?v=0.5 - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/de/gain.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/fr/gain.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/hu/gain.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/no/gain.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 + + https://apps.ad5001.eu/img/en/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/gain.png?v=0.5 + Main view of LogarithmPlotter showing an asymptotic Bode magnitude plot. + Die Hauptansicht des LogarithmPlotters zeigt eine asymptotische Bode-Magnitude-Darstellung. + Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une magnitude de Bode. + A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-magnitúdó ábrát mutat. + Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-størrelsesplott. + + + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 + Main view of LogarithmPlotter showing an asymptotic Bode phase plot. + Hauptansicht des LogarithmPlotters mit einer asymptotischen Bode-Phasendarstellung. + Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une phase de Bode. + A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-fázis ábrát mutat. + Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-fasediagram. + + + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 + LogarithmPlotter's welcome page. + LogarithmPlotter's Willkommensseite. + Page d'accueil de LogarithmPlotter. + LogarithmPlotter üdvözlő oldala. + LogarithmPlotters velkomstside. + - + - medium + 768 - xlarge - xsmall + 3840 + 360 - + -

Changes for v0.5.0:

+

Changes for v0.5.0:

New

  • New, reworked application icon.
  • @@ -161,7 +172,7 @@ -

    Changes for v0.4.0:

    +

    Changes for v0.4.0:

    Changes

    • Fully ported to PySide6 (Qt6).
    • @@ -210,7 +221,7 @@ -

      Changes for v0.3.0:

      +

      Changes for v0.3.0:

      New

      • New completely revamped expression editor:
      • @@ -276,7 +287,7 @@ -

        Changes for v0.2.0:

        +

        Changes for v0.2.0:

        New

        • (EXPERIMENTAL) LogarithmPlotter now has an optional LaTeX integration.
        • @@ -329,7 +340,7 @@ -

          Changes for v0.1.8:

          +

          Changes for v0.1.8:

          New

          • There is now a user manual for LogarithmPlotter! Contributions apprecriated.
          • @@ -374,7 +385,7 @@ -

            Changes for v0.1.7:

            +

            Changes for v0.1.7:

            New

            • The history browser has been completly redesigned, improving UX.
            • @@ -430,7 +441,7 @@ -

              Changes for v0.1.6:

              +

              Changes for v0.1.6:

              New

              • A new changelog popup is available at startup and in the help menu.
              • @@ -471,7 +482,7 @@ -

                Changes for v0.1.5:

                +

                Changes for v0.1.5:

                New

                • LogarithmPlotter has now better handling of very high values in logarithmic scale.
                • @@ -501,7 +512,7 @@ -

                  Changes for v0.1.4:

                  +

                  Changes for v0.1.4:

                  New

                  • LogarithmPlotter detects unsaved changes.
                  • @@ -532,7 +543,7 @@ -

                    Changes for v0.1.3:

                    +

                    Changes for v0.1.3:

                    Fixed bugs

                    • Sandboxed packages (snapcraft and flatpak) won't show error messages related to update checks.
                    • @@ -553,7 +564,7 @@ -

                      Changes for v0.1.2:

                      +

                      Changes for v0.1.2:

                      Fixed bugs

                      • Unable to move Bode diagrams elements when having deleted the sum element.
                      • @@ -577,7 +588,7 @@ -

                        Changes for v0.1:

                        +

                        Changes for v0.1:

                        • Initial release.
                        @@ -586,8 +597,10 @@ - Ad5001 - mail@ad5001.eu + + Ad5001 + https://ad5001.eu + Plot @@ -602,7 +615,8 @@ Phase Sequence Distribution + Qt - + diff --git a/linux/generate-appstream-changelog.sh b/linux/generate-appstream-changelog.sh index c72e0d4..e37c9fa 100644 --- a/linux/generate-appstream-changelog.sh +++ b/linux/generate-appstream-changelog.sh @@ -28,7 +28,7 @@ BEGIN { version = substr($2,2,5) print " " print " " - print "

                        Changes for "$2":

                        " + print "

                        Changes for "$2":

                        " } /^\s*\*\*/ { if(listBegan) { From 7b76a8fe08edf74f627c5b6e709f5d152249ec4a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 20:01:35 +0200 Subject: [PATCH 021/249] Improving testing of LaTeX configuration. --- LogarithmPlotter/logarithmplotter.py | 2 +- .../js/preferences/general.mjs | 10 +++-- LogarithmPlotter/util/latex.py | 40 ++++++++++++++----- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index d4fd4aa..1af01d1 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -142,7 +142,7 @@ def run(): # Check for LaTeX installation if LaTeX support is enabled if config.getSetting("enable_latex"): - latex.check_latex_install() + latex.checkLatexInstallation() # Check for updates if config.getSetting("check_for_updates"): diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 0954f67..3d2b7cf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -36,9 +36,11 @@ class EnableLatex extends BoolSetting { } set(value) { - super.set(value) - Modules.Latex.enabled = value - Modules.Canvas.requestPaint() + if(!value || Latex.checkLatexInstallation()) { + super.set(value) + Modules.Latex.enabled = value + Modules.Canvas.requestPaint() + } } } @@ -46,4 +48,4 @@ export default [ CHECK_FOR_UPDATES, RESET_REDO_STACK, new EnableLatex() -] \ No newline at end of file +] diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index c670e1e..7567c56 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -64,23 +64,34 @@ class Latex(QObject): QObject.__init__(self) self.tempdir = tempdir - def check_latex_install(self): + @Property(bool) + def latexSupported(self): + return LATEX_PATH is not None and DVIPNG_PATH is not None + + @Slot(result=bool) + def checkLatexInstallation(self): """ Checks if the current latex installation is valid. """ + valid_install = True if LATEX_PATH is None: print("No Latex installation found.") if "--test-build" not in argv: QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + valid_install = False elif DVIPNG_PATH is None: print("DVIPNG not found.") if "--test-build" not in argv: QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) - - @Property(bool) - def latexSupported(self): - return LATEX_PATH is not None and DVIPNG_PATH is not None + valid_install = False + else: + try: + self.render("", 14, QColor(0, 0, 0, 255)) + except Exception as e: + valid_install = False # Should have sent an error message if failed to render + return valid_install + @Slot(str, float, QColor, result=str) def render(self, latex_markup: str, font_size: float, color: QColor) -> str: @@ -156,19 +167,26 @@ class Latex(QObject): out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: # Process errored + output = str(out, 'utf8') + "\n" + str(err, 'utf8') QMessageBox.warning(None, "LogarithmPlotter - Latex", QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), proc.returncode, - str(out, 'utf8') + "\n" + str(err, 'utf8'))) + .format(" ".join(process), proc.returncode, output)) raise Exception("{0} process exited with return code {1}:\n{2}\n{3}".format(" ".join(process), str(proc.returncode), str(out, 'utf8'), str(err, 'utf8'))) except TimeoutExpired as e: # Process timed out proc.kill() out, err = proc.communicate() - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), str(out, 'utf8') + "\n" + str(err, 'utf8'))) - raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8') + "\n" + str(err, 'utf8')) + output = str(out, 'utf8') + "\n" + str(err, 'utf8') + if 'calligra.sty' in output and 'not found' in output: + # Calligra package not installed. + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") + .format('calligra')) + else: + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), output)) + raise Exception(" ".join(process) + " process timed out:\n" + output) def cleanup(self, export_path): """ From e3eea751cbd42967a95f7b598442903c6d4125ca Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 20:05:57 +0200 Subject: [PATCH 022/249] Improving ThanksTo (to add scrolling) --- .../LogarithmPlotter/Popup/ThanksTo.qml | 497 +++++++++--------- 1 file changed, 260 insertions(+), 237 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index 4c6d29c..c97bffb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -28,12 +28,13 @@ import QtQuick.Controls \sa LogarithmPlotter */ BaseDialog { - id: about + id: thanks title: qsTr("Thanks and Contributions - LogarithmPlotter") width: 450 - minimumHeight: 710 + minimumHeight: 600 - Column { + ScrollView { + anchors { top: parent.top; left: parent.left; @@ -41,289 +42,311 @@ BaseDialog { right: parent.right; topMargin: margin; leftMargin: margin; - bottomMargin: margin; - rightMargin: margin; + bottomMargin: margin+30; } - spacing: 10 - - ListView { - id: librariesListView - anchors.left: parent.left - width: parent.width - //height: parent.height - implicitHeight: contentItem.childrenRect.height - interactive: false + Column { - model: ListModel { - Component.onCompleted: { - append({ - libName: 'expr-eval', - license: 'MIT', - licenseLink: 'https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt', - linkName: qsTr('Source code'), - link: 'https://github.com/silentmatt/expr-eval', - authors: [{ - authorLine: qsTr('Original library by Raphael Graf'), - email: 'r@undefined.ch', - website: 'https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html', - websiteName: qsTr('Source') - }, { - authorLine: qsTr('Ported to Javascript by Matthew Crumley'), - email: 'email@matthewcrumley.com', - website: 'https://silentmatt.com/', - websiteName: qsTr('Website') - }, { - authorLine: qsTr('Ported to QMLJS by Ad5001'), - email: 'mail@ad5001.eu', - website: 'https://ad5001.eu/', - websiteName: qsTr('Website') - }] - }) - } + anchors { + left: parent.left; } - header: Label { - id: librariesUsedHeader - wrapMode: Text.WordWrap - font.pixelSize: 25 - text: qsTr("Libraries included") - height: implicitHeight + 10 - } + width: thanks.width - 2*margin + spacing: 10 - delegate: Column { - id: libClmn - width: librariesListView.width - spacing: 10 + ListView { + id: librariesListView + anchors.left: parent.left + width: parent.width + //height: parent.height + implicitHeight: contentItem.childrenRect.height + interactive: false - Item { - height: libraryHeader.height - width: parent.width - - Label { - id: libraryHeader - anchors.left: parent.left - wrapMode: Text.WordWrap - font.pixelSize: 18 - text: libName - } - - Row { - anchors.right: parent.right - height: parent.height - spacing: 10 - - Button { - height: parent.height - text: license - icon.name: 'license' - onClicked: Qt.openUrlExternally(licenseLink) - } - - Button { - height: parent.height - text: linkName - icon.name: 'web-browser' - onClicked: Qt.openUrlExternally(link) - } + model: ListModel { + Component.onCompleted: { + append({ + libName: 'expr-eval', + license: 'MIT', + licenseLink: 'https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt', + linkName: qsTr('Source code'), + link: 'https://github.com/silentmatt/expr-eval', + authors: [{ + authorLine: qsTr('Original library by Raphael Graf'), + email: 'r@undefined.ch', + website: 'https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html', + websiteName: qsTr('Source') + }, { + authorLine: qsTr('Ported to Javascript by Matthew Crumley'), + email: 'email@matthewcrumley.com', + website: 'https://silentmatt.com/', + websiteName: qsTr('Website') + }, { + authorLine: qsTr('Ported to QMLJS by Ad5001'), + email: 'mail@ad5001.eu', + website: 'https://ad5001.eu/', + websiteName: qsTr('Website') + }] + }) } } - ListView { - id: libAuthors - anchors.left: parent.left - anchors.leftMargin: 10 - model: authors - width: parent.width - 10 - implicitHeight: contentItem.childrenRect.height - interactive: false + header: Label { + id: librariesUsedHeader + wrapMode: Text.WordWrap + font.pixelSize: 25 + text: qsTr("Libraries included") + height: implicitHeight + 10 + } + + delegate: Column { + id: libClmn + width: librariesListView.width + spacing: 10 - delegate: Item { - id: libAuthor - width: librariesListView.width - 10 - height: 50 + Item { + height: libraryHeader.height + width: parent.width Label { - id: libAuthorName + id: libraryHeader anchors.left: parent.left - anchors.right: buttons.left - anchors.verticalCenter: parent.verticalCenter wrapMode: Text.WordWrap - font.pixelSize: 14 - text: authorLine + font.pixelSize: 18 + text: libName } Row { - id: buttons anchors.right: parent.right height: parent.height spacing: 10 - + Button { - anchors.verticalCenter: parent.verticalCenter - text: websiteName + height: parent.height + text: license + icon.name: 'license' + onClicked: Qt.openUrlExternally(licenseLink) + } + + Button { + height: parent.height + text: linkName icon.name: 'web-browser' - height: parent.height - 10 - onClicked: Qt.openUrlExternally(website) - } - - Button { - anchors.verticalCenter: parent.verticalCenter - text: qsTr('Email') - icon.name: 'email' - height: parent.height - 10 - onClicked: Qt.openUrlExternally('mailto:' + email) + onClicked: Qt.openUrlExternally(link) } } } - } - - Rectangle { - id: libSeparator - opacity: 0.3 - color: sysPalette.windowText - width: parent.width - height: 1 - } - } - } - - ListView { - id: translationsListView - anchors.left: parent.left - width: parent.width - implicitHeight: contentItem.childrenRect.height - interactive: false - spacing: 3 - - - model: ListModel { - Component.onCompleted: { - append({ - tranName: '🇬🇧 ' + qsTr('English'), - link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/', - authors: [{ - authorLine: 'Ad5001', - email: 'mail@ad5001.eu', - website: 'https://ad5001.eu', - websiteName: qsTr('Website') - }] - }) - append({ - tranName: '🇫🇷 ' + qsTr('French'), - link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/', - authors: [{ - authorLine: 'Ad5001', - website: 'https://ad5001.eu', - websiteName: qsTr('Website') - }] - }) - append({ - tranName: '🇩🇪 ' + qsTr('German'), - link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/', - authors: [{ - authorLine: 'Ad5001', - website: 'https://ad5001.eu', - websiteName: qsTr('Website') - }] - }) - append({ - tranName: '🇭🇺 ' + qsTr('Hungarian'), - link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/', - authors: [{ - authorLine: 'Óvári', - website: 'https://github.com/ovari', - websiteName: qsTr('Github') - }] - }) - append({ - tranName: '🇳🇴 ' + qsTr('Norwegian'), - link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/no/', - authors: [{ - authorLine: 'Allan Nordhøy', - website: 'https://github.com/comradekingu', - websiteName: qsTr('Github') - }] - }) - } - } - - header: Label { - id: translationsHeader - wrapMode: Text.WordWrap - font.pixelSize: 25 - text: qsTr("Translations included") - height: implicitHeight + 10 - } - - delegate: Column { - id: tranClmn - width: translationsListView.width - - Item { - width: parent.width - height: translationHeader.height + 10 - Label { - id: translationHeader + ListView { + id: libAuthors anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - wrapMode: Text.WordWrap - font.pixelSize: 18 - text: tranName + anchors.leftMargin: 10 + model: authors + width: parent.width - 10 + implicitHeight: contentItem.childrenRect.height + interactive: false + + delegate: Item { + id: libAuthor + width: librariesListView.width - 10 + height: 50 + + Label { + id: libAuthorName + anchors.left: parent.left + anchors.right: buttons.left + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 14 + text: authorLine + } + + Row { + id: buttons + anchors.right: parent.right + height: parent.height + spacing: 10 + + Button { + anchors.verticalCenter: parent.verticalCenter + text: websiteName + icon.name: 'web-browser' + height: parent.height - 10 + onClicked: Qt.openUrlExternally(website) + } + + Button { + anchors.verticalCenter: parent.verticalCenter + text: qsTr('Email') + icon.name: 'email' + height: parent.height - 10 + onClicked: Qt.openUrlExternally('mailto:' + email) + } + } + } } - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - height: 30 - spacing: 10 - - Button { - height: parent.height - text: qsTr('Improve') - icon.name: 'web-browser' - onClicked: Qt.openUrlExternally(link) + Rectangle { + id: libSeparator + opacity: 0.3 + color: sysPalette.windowText + width: parent.width + height: 1 + } + } + } + + ListView { + id: translationsListView + anchors.left: parent.left + width: parent.width + implicitHeight: contentItem.childrenRect.height + interactive: false + spacing: 3 + + + model: ListModel { + Component.onCompleted: { + const authors = { + Ad5001: { + authorLine: 'Ad5001', + email: 'mail@ad5001.eu', + website: 'https://ad5001.eu', + websiteName: qsTr('Website') + }, + Ovari: { + authorLine: 'Óvári', + website: 'https://github.com/ovari', + websiteName: qsTr('Github') + }, + comradekingu: { + authorLine: 'Allan Nordhøy', + website: 'https://github.com/comradekingu', + websiteName: qsTr('Github') + }, + IngrownMink4: { + authorLine: 'IngrownMink4', + website: 'https://github.com/IngrownMink4', + websiteName: qsTr('Github') + }, + gallegonovato: { + authorLine: 'gallegonovato', + website: '', + websiteName: '' + } } + + append({ + tranName: '🇬🇧 ' + qsTr('English'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/', + authors: [authors.Ad5001] + }) + append({ + tranName: '🇫🇷 ' + qsTr('French'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/', + authors: [authors.Ad5001] + }) + append({ + tranName: '🇩🇪 ' + qsTr('German'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/', + authors: [authors.Ad5001] + }) + append({ + tranName: '🇭🇺 ' + qsTr('Hungarian'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/', + authors: [authors.Ovari] + }) + append({ + tranName: '🇳🇴 ' + qsTr('Norwegian'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/no/', + authors: [authors.comradekingu, authors.Ad5001] + }) + append({ + tranName: '🇳🇴 ' + qsTr('Spanish'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/', + authors: [authors.IngrownMink4, authors.gallegonovato] + }) } } - ListView { - id: tranAuthors - anchors.left: parent.left - anchors.leftMargin: 10 - model: authors - width: parent.width - 10 - implicitHeight: contentItem.childrenRect.height - interactive: false + header: Label { + id: translationsHeader + wrapMode: Text.WordWrap + font.pixelSize: 25 + text: qsTr("Translations included") + height: implicitHeight + 10 + } + + delegate: Column { + id: tranClmn + width: translationsListView.width - delegate: Item { - id: tranAuthor - width: tranAuthors.width - height: 40 + Item { + width: parent.width + height: translationHeader.height + 10 Label { - id: tranAuthorName + id: translationHeader anchors.left: parent.left - anchors.right: buttons.left anchors.verticalCenter: parent.verticalCenter wrapMode: Text.WordWrap - font.pixelSize: 14 - text: authorLine + font.pixelSize: 18 + text: tranName } Row { - id: buttons anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter height: 30 spacing: 10 - + Button { - text: websiteName - icon.name: 'web-browser' height: parent.height - onClicked: Qt.openUrlExternally(website) + text: qsTr('Improve') + icon.name: 'web-browser' + onClicked: Qt.openUrlExternally(link) + } + } + } + + ListView { + id: tranAuthors + anchors.left: parent.left + anchors.leftMargin: 10 + model: authors + width: parent.width - 10 + implicitHeight: contentItem.childrenRect.height + interactive: false + + delegate: Item { + id: tranAuthor + width: tranAuthors.width + height: 40 + + Label { + id: tranAuthorName + anchors.left: parent.left + //anchors.right: buttons.left + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 14 + text: authorLine + } + + Row { + id: buttons + anchors.left: tranAuthorName.right + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + height: 30 + spacing: 10 + + Button { + text: websiteName + visible: websiteName !== "" + icon.name: 'web-browser' + height: parent.height + onClicked: Qt.openUrlExternally(website) + } } } } From 7b0bc4469f105c4750ed8e56c525914a839bd7d9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 20:15:57 +0200 Subject: [PATCH 023/249] Improving message for missing packages in LaTeX. --- LogarithmPlotter/i18n/lp_de.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_en.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_es.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_fr.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_hu.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_nb_NO.ts | 62 ++++++++++++++++------------ LogarithmPlotter/i18n/lp_template.ts | 62 ++++++++++++++++------------ LogarithmPlotter/util/latex.py | 23 ++++++----- 8 files changed, 258 insertions(+), 199 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 8fa02e1..4f567f9 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -720,87 +720,91 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Danksagungen und Beiträge - LogarithmPlotter - + Source code Quellcode - + Original library by Raphael Graf Originalbibliothek von Raphael Graf - + Source Quelle - + Ported to Javascript by Matthew Crumley Portiert auf Javascript von Matthew Crumley - - - - - + + + Website Website - + Ported to QMLJS by Ad5001 Portiert auf QMLJS von Ad5001 - + Libraries included Einschließlich Bibliotheken - + Email E-Mail - + English Englisch - + French Französisch - + German Deutsch - + Hungarian Ungarisch - - + + + Github Github - + Norwegian Norwegisch - + + Spanish + + + + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -1236,7 +1240,7 @@ Ausdruck analysiert: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1245,12 +1249,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1263,12 +1267,16 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 2f4ea77..5d2e492 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -720,87 +720,91 @@ These settings can be changed at any time from the "Settings" menu.Thanks and Contributions - LogarithmPlotter - + Source code Source code - + Original library by Raphael Graf Original library by Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Ported to Javascript by Matthew Crumley - - - - - + + + Website Website - + Ported to QMLJS by Ad5001 Ported to QMLJS by Ad5001 - + Libraries included Libraries included - + Email Email - + English English - + French French - + German German - + Hungarian Hungarian - - + + + Github Github - + Norwegian Norwegian - + + Spanish + + + + Translations included Translations included - + Improve Improve @@ -1236,7 +1240,7 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1245,12 +1249,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1263,12 +1267,16 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index bb33fbe..2d8cee0 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -682,87 +682,91 @@ - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + + Github - + Norwegian - + + Spanish + + + + Translations included - + Improve @@ -1149,19 +1153,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1170,12 +1174,16 @@ Please make sure your latex installation is correct and report a bug if so. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index aa78b8f..c920c5d 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -728,87 +728,91 @@ These settings can always be changed at any time from the "Settings" m Remerciements et contributions - LogarithmPlotter - + Source code Code source - + Original library by Raphael Graf Bibliothèque originale de Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Porté en Javascript par Matthew Crumley - - - - - + + + Website Site web - + Ported to QMLJS by Ad5001 Porté à QMLJS par Ad5001 - + Libraries included Bibliothèques incluses - + Email Email - + English Anglais - + French Français - + German Allemand - + Hungarian Hongrois - - + + + Github Github - + Norwegian Norvégien - + + Spanish + + + + Translations included Traductions incluses - + Improve Améliorer @@ -1245,7 +1249,7 @@ Formule analysée : %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1254,12 +1258,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1272,12 +1276,16 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 0252785..2829421 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -720,87 +720,91 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Köszönet és hozzájárulás - LogarithmPlotter - + Source code Forráskód - + Original library by Raphael Graf Eredeti könyvtár: Graf Raphael - + Source Forrás - + Ported to Javascript by Matthew Crumley JavaScript-átalakítás: Crumley Máté - - - - - + + + Website Honlap - + Ported to QMLJS by Ad5001 QMLJS-átalakítás: Ad5001 - + Libraries included Tartalmazott könyvtárak - + Email E-mail - + English angol - + French francia - + German német - + Hungarian magyar - - + + + Github GitHub - + Norwegian norvég - + + Spanish + + + + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -1236,7 +1240,7 @@ Kiértékelt kifejezés: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1245,12 +1249,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1263,12 +1267,16 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 99b3698..1f8f3b8 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -672,87 +672,91 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + + Github - + Norwegian - + + Spanish + + + + Translations included - + Improve @@ -1113,19 +1117,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1134,12 +1138,16 @@ Please make sure your latex installation is correct and report a bug if so. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 55e57b6..92ee723 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -560,87 +560,91 @@ - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + + Github - + Norwegian - + + Spanish + + + + Translations included - + Improve @@ -865,19 +869,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -886,12 +890,16 @@ Please make sure your latex installation is correct and report a bug if so. - - Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 7567c56..9ebb1c4 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -35,6 +35,7 @@ If not found, it will send an alert to the user. """ LATEX_PATH = which('latex') DVIPNG_PATH = which('dvipng') +PACKAGES = ["calligra", "amsfonts", "inputenc"] DEFAULT_LATEX_DOC = Template(r""" \documentclass[]{minimal} @@ -177,16 +178,18 @@ class Latex(QObject): proc.kill() out, err = proc.communicate() output = str(out, 'utf8') + "\n" + str(err, 'utf8') - if 'calligra.sty' in output and 'not found' in output: - # Calligra package not installed. - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") - .format('calligra')) - else: - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), output)) - raise Exception(" ".join(process) + " process timed out:\n" + output) + if 'not found' in output: + for pkg in PACKAGES: + if f'{pkg}.sty' in output: + # Package missing. + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") + .format(pkg, pkg)) + raise Exception("Latex: Missing package " + pkg) + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), output)) + raise Exception(" ".join(process) + " process timed out:\n" + output) def cleanup(self, export_path): """ From 107cea13081ccedbf62ba975bdd607ac377664a9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 18:18:54 +0000 Subject: [PATCH 024/249] Translated using Weblate (English) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 5d2e492..595c241 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -80,7 +80,7 @@ &Preferences - + &Preferences @@ -395,7 +395,7 @@ These settings can be changed at any time from the "Settings" menu. Preferences - + Preferences @@ -607,7 +607,7 @@ These settings can be changed at any time from the "Settings" menu. Close - Close + Close @@ -796,7 +796,7 @@ These settings can be changed at any time from the "Settings" menu. Spanish - + Spanish @@ -1273,7 +1273,11 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. From 6626362d2377e6d76605bce37fd4082cc1f8b7a4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 18:58:38 +0000 Subject: [PATCH 025/249] Translated using Weblate (German) Currently translated at 99.6% (308 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 4f567f9..c29a268 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -80,7 +80,7 @@ &Preferences - + &Einstellung @@ -395,7 +395,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Preferences - + Einstellung @@ -796,7 +796,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Spanish - + Spanisch @@ -1273,7 +1273,11 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde - {} (https://ctan.org/pkg/{}) Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + Ihre LaTeX-Installation enthält einige erforderliche Pakete nicht: + +- {} (https://ctan.org/pkg/{}) + +Stellen Sie sicher, dass diese Pakete installiert sind, oder deaktivieren Sie das LaTeX-Rendering in LogarithmPlotter. @@ -1663,4 +1667,19 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde X Zeiger + + settingCategory + + default + Standardeinstellungen + + + general + Allgemeine + + + editor + Ausdruckseditor + + From 6a1f0013d6443e4765ae71541283c310fd670b77 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 16 Sep 2024 19:01:10 +0000 Subject: [PATCH 026/249] Translated using Weblate (Spanish) Currently translated at 75.7% (234 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 2d8cee0..727847f 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -80,7 +80,7 @@ &Preferences - + &Preferencias @@ -169,6 +169,10 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? + + Expression editor + Editor de expresiones + BaseDialog From f1e22786955b6cbbeb4dd1134231af1c3fb84009 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 18:59:34 +0000 Subject: [PATCH 027/249] Translated using Weblate (Spanish) Currently translated at 75.7% (234 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 727847f..67ca5c8 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -315,7 +315,7 @@ Executable Objects - + @@ -341,7 +341,7 @@ Welcome to LogarithmPlotter - + @@ -370,7 +370,7 @@ Close - + Cerrar From 35fef4cb1eae08aa555ee958ace091e47f69c106 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 18:49:44 +0000 Subject: [PATCH 028/249] Translated using Weblate (French) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index c920c5d..56be041 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -80,7 +80,7 @@ &Preferences - + &Préférences @@ -389,7 +389,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Preferences - + Préférences @@ -615,7 +615,7 @@ These settings can always be changed at any time from the "Settings" m Close - Fermer + Fermer @@ -804,7 +804,7 @@ These settings can always be changed at any time from the "Settings" m Spanish - + Espagnol @@ -1282,7 +1282,11 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c - {} (https://ctan.org/pkg/{}) Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + Votre installation de LaTeX n'inclut pas certains paquets nécessaires : + +- {} (https://ctan.org/pkg/{}) + +Assurez-vous que ce paquetage est installé, ou désactivez le rendu LaTeX dans LogarithmPlotter. @@ -1672,4 +1676,19 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Curseurs X + + settingCategory + + general + Général + + + editor + Éditeur de formule + + + default + Paramètres par défaut + + From 53124fc8d7f3bc55a34bcbb3c92eb768332030aa Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 18:59:14 +0000 Subject: [PATCH 029/249] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 69.9% (216 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/nb_NO/ --- LogarithmPlotter/i18n/lp_nb_NO.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 1f8f3b8..9b08143 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -291,7 +291,7 @@ Executable Objects - + @@ -356,7 +356,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Close - + Lukk From 3994d8d49d0d001ee73696aeec5871435a760c90 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:07:54 +0000 Subject: [PATCH 030/249] Translated using Weblate (German) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c29a268..de3c10c 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -310,7 +310,7 @@ Functions - Funktion + Funktionen @@ -607,7 +607,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Close - Schließen + Schließen From 9ca48bbcfabc38fa55f2ce850fedd1a6cd50204a Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 16 Sep 2024 19:17:00 +0000 Subject: [PATCH 031/249] Translated using Weblate (Spanish) Currently translated at 80.5% (249 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 54 ++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 67ca5c8..81eab3d 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -315,7 +315,7 @@ Executable Objects - + Objetos de función @@ -341,7 +341,7 @@ Welcome to LogarithmPlotter - + Bienvenid@ a LogarithmPlotter @@ -365,13 +365,43 @@ Preferences - + Preferencias Close Cerrar + + Color scheme: + Esquema de colores: + + + Take a few seconds to configure LogarithmPlotter. +These settings can be changed at any time from the "Settings" menu. + Tómate unos segundos para configurar LogarithmPlotter. +Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes”. + + + Check for updates on startup (requires online connectivity) + Buscar actualizaciones al iniciar (requiere conexión a Internet) + + + Reset redo stack when a new action is added to history + Restablecer el historial de deshacer cuando se agrega una nueva acción + + + Automatically close parenthesises and brackets in expressions + Cerrar automáticamente paréntesis y corchetes en expresiones + + + Enable autocompletion interface in expression editor + Habilitar el autocompletado en el editor de expresiones + + + Enable syntax highlighting for expressions + Habilitar el resaltado de sintaxis para expresiones + HistoryBrowser @@ -577,7 +607,7 @@ Close - Cerrar + Cerrar @@ -677,6 +707,10 @@ Load plot + + Close + Cerrar + ThanksTo @@ -762,7 +796,7 @@ Spanish - + Español @@ -1184,7 +1218,11 @@ Please make sure your latex installation is correct and report a bug if so. - + Tu instalación de LaTeX no incluye algunos paquetes necesarios: + +- {} (https://ctan.org/pkg/{}) + +Asegúrate de que dicho paquete está instalado, o desactive el renderizado LaTeX en LogarithmPlotter. @@ -1244,6 +1282,10 @@ Please make sure your latex installation is correct and report a bug if so.above-right ↗ Arriba a la derecha + + bottom + ↓ Abajo + update From 59d4d2f728193e611e76a9baced6847fa2a4b338 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:02:51 +0000 Subject: [PATCH 032/249] Translated using Weblate (Spanish) Currently translated at 80.5% (249 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 81eab3d..c4de048 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -431,7 +431,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + Add Entry - + + Añadir entrada From c1a468148defc86543efc52685711f4243ba6ae0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:06:17 +0000 Subject: [PATCH 033/249] Translated using Weblate (French) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 56be041..86d982b 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1435,7 +1435,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c prop expression - Expression + Formule definitionDomain @@ -1535,7 +1535,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c defaultExpression - Expression + Formule par défaut baseValues From c9a597ea826770503d2ec2a9dbb13635328f5e4b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:12:48 +0000 Subject: [PATCH 034/249] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 69.2% (214 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/nb_NO/ --- LogarithmPlotter/i18n/lp_nb_NO.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 9b08143..3b84451 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -112,7 +112,7 @@ &Report a bug - + &Rapporter en feil @@ -122,17 +122,17 @@ &Changelog - + &Endringslogg &Help translating! - + &Hjelp til å oversette! &Thanks - + &Erkjennelser @@ -142,12 +142,12 @@ Save unsaved changes? - + Lagre ikke-lagrede endringer? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? @@ -155,7 +155,7 @@ Close - + Lukk @@ -170,12 +170,12 @@ Fetching changelog... - + Henter endringslogg… Close - + Lukk @@ -202,12 +202,12 @@ LogarithmPlotter - Invalid object name - + LogarithmPlotter - Ugyldig objektnavn An object with the name '%1' already exists. - + Et objekt med navnet '%1' finnes allerede. @@ -387,7 +387,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + Add Entry - + From 8d6891c4f095a8ab77e854203f1b64d536270d07 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 22:05:17 +0200 Subject: [PATCH 035/249] Starting async LaTeX rendering. --- .../ObjectLists/ObjectRow.qml | 8 +-- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 40 ++++++------ .../LogarithmPlotter/js/history/common.mjs | 6 +- .../ad5001/LogarithmPlotter/js/math/latex.mjs | 63 +++++++++++++++++-- LogarithmPlotter/util/latex.py | 26 +++++++- 5 files changed, 110 insertions(+), 33 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 0772da8..f1292cd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -100,10 +100,10 @@ Item { anchors.left: parent.left visible: Modules.Latex.enabled property double depth: Screen.devicePixelRatio - property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] - source: visible ? ltxInfo[0] : "" - width: parseInt(ltxInfo[1])/depth - height: parseInt(ltxInfo[2])/depth + property var ltxInfo: visible ? Modules.Latex.renderSync(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color) : { source: "", width: 0, height: 0 } + source: visible ? ltxInfo.source : "" + width: ltxInfo.width/depth + height: ltxInfo.height/depth } MouseArea { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index cdd0777..cff8ae9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -16,9 +16,10 @@ * along with this program. If not, see . */ -import {Module} from "./modules.mjs" -import {textsup} from "./utils.mjs" -import {Expression} from "./mathlib.mjs" +import { Module } from "./modules.mjs" +import { textsup } from "./utils.mjs" +import { Expression } from "./mathlib.mjs" +import Latex from "./math/latex.mjs" class CanvasAPI extends Module { @@ -168,6 +169,8 @@ class CanvasAPI extends Module { obj.draw(this) } catch(e) { // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) + console.error(e) + console.log(e.stack) this._drawingErrorDialog.showDialog(objType, obj.name, e.message) Modules.History.undo() } @@ -452,23 +455,24 @@ class CanvasAPI extends Module { * Renders latex markup ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. * @param {string} ltxText * @param {string} color - * @param {function({width: number, height: number, source: string})} callback + * @param {function(LatexRenderResult|{width: number, height: number, source: string})} callback */ renderLatexImage(ltxText, color, callback) { - let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, this.textsize, color).split(",") - let imgData = { - "source": ltxSrc, - "width": parseFloat(ltxWidth), - "height": parseFloat(ltxHeight) - }; - if(!this._canvas.isImageLoaded(ltxSrc) && !this._canvas.isImageLoading(ltxSrc)){ - // Wait until the image is loaded to callback. - this._canvas.loadImage(ltxSrc) - this._canvas.imageLoaders[ltxSrc] = [callback, imgData] - } else { - // Callback directly - callback(imgData) + const onRendered = (imgData) => { + if(!this._canvas.isImageLoaded(imgData.source) && !this._canvas.isImageLoading(imgData.source)){ + // Wait until the image is loaded to callback. + this._canvas.loadImage(imgData.source) + this._canvas.imageLoaders[imgData.source] = [callback, imgData] + } else { + // Callback directly + callback(imgData) + } } + const prerendered = Latex.findPrerendered(ltxText, this.textsize, color) + if(prerendered !== null) + onRendered(prerendered) + else + Latex.requestAsyncRender(ltxText, this.textsize, color).then(onRendered) } // @@ -519,4 +523,4 @@ class CanvasAPI extends Module { /** @type {CanvasAPI} */ Modules.Canvas = Modules.Canvas || new CanvasAPI() -export const API = Modules.Canvas \ No newline at end of file +export const API = Modules.Canvas diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 229a294..3df3a77 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -115,12 +115,12 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") let imgDepth = Modules.History.imageDepth - let [src, width, height] = Latex.render( + let { source, width, height } = Latex.renderSync( latexString, imgDepth * (Modules.History.fontSize + 2), Modules.History.themeTextColor - ).split(",") - return `` + ) + return `` } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index 7418b9c..306f5be 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -39,6 +39,20 @@ const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", "\\pi", "\\infty"] +/** + * Class containing the result of a LaTeX render. + * + * @property {string} source - Exported PNG file + * @property {number} width + * @property {number} height + */ +class LatexRenderResult { + constructor(source, width, height) { + this.source = source + this.width = parseFloat(width) + this.height = parseFloat(height) + } +} class LatexAPI extends Module { constructor() { @@ -50,11 +64,50 @@ class LatexAPI extends Module { * true if latex has been enabled by the user, false otherwise. */ this.enabled = Helper.getSettingBool("enable_latex") - /** - * Mirror method for Python object. - * @type {function(string, number, string): string}. - */ - this.render = Latex.render + } + + /** + * Prepares and renders a latex string into a png file. + * + * @param {string} markup - LaTeX markup to render. + * @param {number} fontSize - Font size (in pt) to render. + * @param {color} color - Color of the text to render. + * @returns {LatexRenderResult} + */ + renderSync(markup, fontSize, color) { + let args = Latex.render(markup, fontSize, color).split(",") + return new LatexRenderResult(...args) + } + + /** + * Checks if the given markup (with given font size and color) has already been + * rendered, and if so, returns its data. Otherwise, returns null. + * + * @param {string} markup - LaTeX markup to render. + * @param {number} fontSize - Font size (in pt) to render. + * @param {color} color - Color of the text to render. + * @returns {LatexRenderResult|null} + */ + findPrerendered(markup, fontSize, color) { + const data = Latex.findPrerendered(markup, fontSize, color) + let ret = null + if(data !== "") + ret = new LatexRenderResult(...data.split(",")) + return ret + } + + /** + * Prepares and renders a latex string into a png file asynchronously. + * + * @param {string} markup - LaTeX markup to render. + * @param {number} fontSize - Font size (in pt) to render. + * @param {color} color - Color of the text to render. + * @returns {Promize} + */ + requestAsyncRender(markup, fontSize, color) { + return new Promise(resolve => { + resolve(this.renderSync(markup, fontSize, color)) + }) } /** diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 9ebb1c4..166e224 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -92,15 +92,13 @@ class Latex(QObject): except Exception as e: valid_install = False # Should have sent an error message if failed to render return valid_install - @Slot(str, float, QColor, result=str) def render(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Prepares and renders a latex string into a png file. """ - markup_hash = "render" + str(hash(latex_markup)) - export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') + markup_hash, export_path = self.create_export_path(latex_markup, font_size, color) if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file @@ -121,6 +119,28 @@ class Latex(QObject): img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' + + @Slot(str, float, QColor, result=str) + def findPrerendered(self, latex_markup: str, font_size: float, color: QColor): + """ + Finds a prerendered image and returns its data if possible, and an empty string if not. + """ + markup_hash, export_path = self.create_export_path(latex_markup, font_size, color) + data = "" + if path.exists(export_path + ".png"): + img = QImage(export_path) + data = f'{export_path}.png,{img.width()},{img.height()}' + return data + + + def create_export_path(self, latex_markup: str, font_size: float, color: QColor): + """ + Standardizes export path for renders. + """ + markup_hash = "render" + str(hash(latex_markup)) + export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') + return markup_hash, export_path + def create_latex_doc(self, export_path: str, latex_markup: str): """ From 70f1c03cb67c799e79b2afc768471408ebd593b9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 22:56:54 +0200 Subject: [PATCH 036/249] Making history items being rendered with LaTeX (e.g. positions and properties) asynchronous. --- .../LogarithmPlotter/History/HistoryItem.qml | 15 ++++++++- .../LogarithmPlotter/js/history/common.mjs | 22 ++++++++----- .../js/history/editproperty.mjs | 33 ++++++++++++++----- .../LogarithmPlotter/js/history/position.mjs | 28 ++++++++++++---- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 3e9b906..41d0015 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -116,10 +116,23 @@ Button { anchors.verticalCenter: parent.verticalCenter visible: !hidden font.pixelSize: 14 - text: historyAction.getHTMLString().replace(/\$\{tag_color\}/g, clr) + text: "" textFormat: Text.RichText clip: true wrapMode: Text.WordWrap + + Component.onCompleted: function() { + // Render HTML, might be string, but could also be a promise + const html = historyAction.getHTMLString() + if(typeof html === "string") { + label.text = html.replace(/\$\{tag_color\}/g, clr) + } else { + // Promise! We need to way to wait for it to be completed. + html.then(rendered => { + label.text = rendered.replace(/\$\{tag_color\}/g, clr) + }) + } + } } Rectangle { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 3df3a77..db2d5dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -109,24 +109,28 @@ export class Action { * Renders a LaTeX-formatted string to an image and wraps it in an HTML tag in a string. * * @param {string} latexString - Source string of the latex. - * @returns {string} + * @returns {Promise} */ renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let imgDepth = Modules.History.imageDepth - let { source, width, height } = Latex.renderSync( - latexString, - imgDepth * (Modules.History.fontSize + 2), - Modules.History.themeTextColor - ) - return `` + return new Promise(resolve => { + let imgDepth = Modules.History.imageDepth + Latex.requestAsyncRender( + latexString, + imgDepth * (Modules.History.fontSize + 2), + Modules.History.themeTextColor + ).then((imgData) => { + const { source, width, height } = imgData + resolve(``) + }) + }) } /** * Returns a string with the HTML-formatted description of the action. * - * @returns {string} + * @returns {string|Promise} */ getHTMLString() { return this.getReadableString() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 3540cfe..3c6bcda 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -85,8 +85,9 @@ export default class EditedProperty extends Action { } setReadableValues() { - this.prevString = ""; - this.nextString = ""; + this.prevString = "" + this.nextString = "" + this._renderPromises = [] if(this.propertyType instanceof Object) { switch(this.propertyType.type) { case "Enum": @@ -118,8 +119,11 @@ export default class EditedProperty extends Action { this.prevHTML = ' '+this.prevString+' ' this.nextHTML = ' '+this.nextString+' ' if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { - this.prevHTML= this.renderLatexAsHtml(this.previousValue.latexMarkup) - this.nextHTML= this.renderLatexAsHtml(this.newValue.latexMarkup) + // Store promises so that querying can wait for them to finish. + this._renderPromises = [ + this.renderLatexAsHtml(this.previousValue.latexMarkup).then(prev => this.prevHTML = prev), + this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = prev) + ] } } @@ -131,10 +135,21 @@ export default class EditedProperty extends Action { } getHTMLString() { - return qsTr('%1 of %2 changed from %3 to %4.') - .arg(this.targetPropertyReadable) - .arg(' ' + this.targetName + ' ') - .arg(this.prevHTML) - .arg(this.nextHTML) + return new Promise(resolve => { + const translation = qsTr('%1 of %2 changed from %3 to %4.') + .arg(this.targetPropertyReadable) + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML !== undefined && this.nextHTML !== undefined) + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + else + Promise.all(this._renderPromises).then((rendered) => { + // Rendered are (potentially) two HTML strings which are defined during rendering + this.prevHTML = this.prevHTML ?? rendered[0] + this.nextHTML = this.prevHTML ?? rendered[1] + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + }) + }) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index eaf4b65..15c3583 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -61,10 +61,15 @@ export default class EditedPosition extends Action { setReadableValues() { this.prevString = `(${this.previousXValue.toString()},${this.previousYValue.toString()})` this.nextString = `(${this.newXValue.toString()},${this.newYValue.toString()})` + this._renderPromises = [] // Render as LaTeX if(Latex.enabled) { - this.prevHTML = this.renderLatexAsHtml(`\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)`) - this.nextHTML = this.renderLatexAsHtml(`\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)`) + const prevMarkup = `\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)` + const nextMarkup = `\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)` + this._renderPromises = [ // Will be taken in promise.all + this.renderLatexAsHtml(prevMarkup), + this.renderLatexAsHtml(nextMarkup) + ] } else { this.prevHTML = ' '+escapeHTML(this.prevString)+' ' this.nextHTML = ' '+escapeHTML(this.nextString)+' ' @@ -85,9 +90,20 @@ export default class EditedPosition extends Action { } getHTMLString() { - return qsTr('Position of %1 set from %2 to %3.') - .arg(' ' + this.targetName + ' ') - .arg(this.prevHTML) - .arg(this.nextHTML) + return new Promise(resolve => { + const translation = qsTr('Position of %1 set from %2 to %3.') + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML !== undefined && this.nextHTML !== undefined) + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + else + Promise.all(this._renderPromises).then((rendered) => { + // Rendered are (potentially) two HTML strings which are defined during rendering + this.prevHTML = this.prevHTML ?? rendered[0] + this.nextHTML = this.prevHTML ?? rendered[1] + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + }) + }) + } } From 7e0262e4fe3418f744a4d1e608ffe11e714db190 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 23:33:08 +0200 Subject: [PATCH 037/249] Making Objects List Latex render async --- .../ObjectLists/ObjectRow.qml | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index f1292cd..f846490 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -100,10 +100,26 @@ Item { anchors.left: parent.left visible: Modules.Latex.enabled property double depth: Screen.devicePixelRatio - property var ltxInfo: visible ? Modules.Latex.renderSync(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color) : { source: "", width: 0, height: 0 } - source: visible ? ltxInfo.source : "" - width: ltxInfo.width/depth - height: ltxInfo.height/depth + source: "" + width: 0/depth + height: 0/depth + + Component.onCompleted: function() { + if(Modules.Latex.enabled) { + const args = [obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color] + const prerendered = Modules.Latex.findPrerendered(...args) + if(prerendered !== null) { + source = prerendered.source + width = prerendered.width/depth + height = prerendered.height/depth + } else + Modules.Latex.requestAsyncRender(...args).then(info => { + source = info.source + width = info.width/depth + height = info.height/depth + }) + } + } } MouseArea { From ef14db8bbb16d7edf7481f715c3fb10f74650e20 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 23:33:59 +0200 Subject: [PATCH 038/249] Fixing issue with object's execution category --- .../qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index d121781..aa91018 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -474,7 +474,7 @@ Item { itemSelected: parent.itemSelected categoryItems: Modules.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Modules.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), + 'text': item, 'annotation': Modules.Objects.currentObjectsByName[item] == null ? '' : Modules.Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" From 51807a80d05bbcc48cd756b03e52a560a3724067 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 23:41:34 +0200 Subject: [PATCH 039/249] Fixing position of filter item --- .../qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml | 1 + .../qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index b7a79c8..3fa37f8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -53,6 +53,7 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top + anchors.rightMargin: 5 placeholderText: qsTr("Filter...") category: "all" } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index c795037..706281e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -102,7 +102,7 @@ Item { anchors.leftMargin: icon == "" ? 0 : 5 anchors.top: parent.top height: parent.height - width: Math.max(85, implicitWidth) + width: visible ? Math.max(85, implicitWidth) : 0 verticalAlignment: TextInput.AlignVCenter //color: sysPalette.windowText text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" From 601efc61224b2a7fdc50efb622519fb89acb08d6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 23:52:42 +0200 Subject: [PATCH 040/249] Fixing issue with LocationPickOverlay snap to grid. --- .../eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index d8a6ac3..0139c5b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -282,10 +282,9 @@ Item { x: picker.mouseX - width - 5 y: picker.mouseY - height - 5 color: 'black' - property double axisX: Modules.Canvas.axesStep.x.value - property double axisY: Modules.Canvas.axesStep.y.value property double mouseX: { - let xpos = Modules.Canvas.px2x(picker.mouseX) + const axisX = Modules.Canvas.axesSteps.x.value + const xpos = Modules.Canvas.px2x(picker.mouseX) if(snapToGridCheckbox.checked) { if(canvas.logscalex) { // Calculate the logged power @@ -299,7 +298,8 @@ Item { } } property double mouseY: { - let ypos = Modules.Canvas.px2y(picker.mouseY) + const axisY = Modules.Canvas.axesSteps.y.value + const ypos = Modules.Canvas.px2y(picker.mouseY) if(snapToGridCheckbox.checked) { return axisY*Math.round(ypos/axisY) } else { From a16f02fd5f18f902557a097451ea0fc301707599 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:44:14 +0200 Subject: [PATCH 041/249] Refractoring the magnitude sum object cache calculation which should (hopefully) reduce bugs and improve maintainability. --- .../LogarithmPlotter/js/objs/gainbode.mjs | 13 ++- .../js/objs/sommegainsbode.mjs | 94 ++++++++++--------- 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index a4a6416..938aa33 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -133,10 +133,19 @@ export default class GainBode extends ExecutableObject { update() { super.update() - if(Objects.currentObjects['Somme gains Bode'] !== undefined && Objects.currentObjects['Somme gains Bode'].length > 0) { - Objects.currentObjects['Somme gains Bode'][0].recalculateCache() + let sumObjs = Objects.currentObjects['Somme gains Bode'] + if(sumObjs !== undefined && sumObjs.length > 0) { + sumObjs[0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme gains Bode') } } + + delete() { + super.delete() + let sumObjs = Objects.currentObjects['Somme gains Bode'] + if(sumObjs !== undefined && sumObjs.length > 0) { + sumObjs[0].recalculateCache() + } + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index 236c3d4..9226eee 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { parseDomain, Expression, Domain } from "../mathlib.mjs" +import { Range, Expression, Domain } from "../mathlib.mjs" import * as P from "../parameters.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" @@ -53,9 +53,9 @@ export default class SommeGainsBode extends ExecutableObject { } execute(x = 0) { - for(let [dbfn, inDrawDom] of this.cachedParts) { + for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { - return dbfn.execute(x) + return limitedDrawFunction.execute(x) } } return null @@ -66,9 +66,9 @@ export default class SommeGainsBode extends ExecutableObject { } simplify(x = 1) { - for(let [dbfn, inDrawDom] of this.cachedParts) { + for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { - return dbfn.simplify(x) + return limitedDrawFunction.simplify(x) } } return '' @@ -77,61 +77,65 @@ export default class SommeGainsBode extends ExecutableObject { recalculateCache() { this.cachedParts = [] // Calculating this is fairly resource expansive so it's cached. - if(Objects.currentObjects['Gain Bode'] !== undefined) { + let magnitudeObjects = Objects.currentObjects['Gain Bode'] + if(magnitudeObjects === undefined || magnitudeObjects.length < 1) { + Objects.deleteObject(this.name) + } else { console.log('Recalculating cache gain') // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - let drawMin = 0.001 - + const MIN_DRAW = 1e-20 + // Format: [[x value of where the filter transitions, magnitude, high-pass (bool)]] + const magnitudes = [] + const XVALUE = 0 + const MAGNITUDE = 1 + const PASS = 2 + magnitudes.push([Number.MAX_VALUE, 0, true]) // Draw the ending section + // Collect data from current magnitude (or gain in French) objects. let baseY = 0 - let om0xGains = {1000000000: 0} // To draw the last part - let om0xPass = {1000000000: 'high'} // To draw the last part - for(/** @type {GainBode} */ let gainObj of Objects.currentObjects['Gain Bode']) { // Sorting by their om_0 position. - let om0x = gainObj.om_0.x.execute() - if(om0xGains[om0x] === undefined) { - om0xGains[om0x] = gainObj.gain.execute() - om0xPass[om0x] = gainObj.pass === 'high' - } else { - om0xGains[om0x+0.001] = gainObj.gain.execute() - om0xPass[om0x+0.001] = gainObj.pass === 'high' - } - baseY += gainObj.execute(drawMin) + for(/** @type {GainBode} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position. + const om0x = magnitudeObj.om_0.x.execute() + magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === 'high']) + baseY += magnitudeObj.execute(MIN_DRAW) } - // Sorting the om_0x - let om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... - om0xList.sort((a,b) => a - b) + // Sorting the data by their x transitions value + magnitudes.sort((a,b) => a[XVALUE] - b[XVALUE]) // Adding the total gains. - let gainsBeforeP = [] - let gainsAfterP = [] - let gainTotal = 0 - for(let om0x of om0xList){ - if(om0xPass[om0x]) { // High-pass - gainsBeforeP.push(om0xGains[om0x]) - gainsAfterP.push(0) - gainTotal += om0xGains[om0x] // Gain at first + let magnitudesBeforeTransition = [] + let magnitudesAfterTransition = [] + let totalMagnitudeAtStart = 0 // Magnitude at the lowest x value (sum of all high-pass magnitudes) + for(let [om0x, magnitude, highpass] of magnitudes){ + if(highpass) { + magnitudesBeforeTransition.push(magnitude) + magnitudesAfterTransition.push(0) + totalMagnitudeAtStart += magnitude } else { - gainsBeforeP.push(0) - gainsAfterP.push(om0xGains[om0x]) + magnitudesBeforeTransition.push(0) + magnitudesAfterTransition.push(magnitude) } } // Calculating parts - let previousPallier = drawMin - for(let pallier = 0; pallier < om0xList.length; pallier++) { - let dbfn = new Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) - let inDrawDom = parseDomain(`]${previousPallier};${om0xList[pallier]}]`) - this.cachedParts.push([dbfn, inDrawDom]) - previousPallier = om0xList[pallier] - baseY = dbfn.execute(om0xList[pallier]) - gainTotal += gainsAfterP[pallier] - gainsBeforeP[pallier] + let previousTransitionX = MIN_DRAW + let currentMagnitude = totalMagnitudeAtStart + for(let transitionID = 0; transitionID < magnitudes.length; transitionID++) { + const transitionX = magnitudes[transitionID][XVALUE] + // Create draw function that will be used during drawing. + const limitedDrawFunction = new Expression(`${currentMagnitude}*(ln(x)-ln(${previousTransitionX}))/ln(10)+${baseY}`) + const drawDomain = new Range(previousTransitionX, transitionX, true, false) + this.cachedParts.push([limitedDrawFunction, drawDomain]) + // Prepare default values for next function. + previousTransitionX = transitionX + baseY = limitedDrawFunction.execute(transitionX) + currentMagnitude += magnitudesAfterTransition[transitionID] - magnitudesBeforeTransition[transitionID] } } } draw(canvas) { if(this.cachedParts.length > 0) { - for(let [dbfn, inDrawDom] of this.cachedParts) { - Function.drawFunction(canvas, dbfn, inDrawDom, Domain.R) - if(inDrawDom.includes(this.labelX)) { - // Label + for(let [limitedDrawFunction, drawDomain] of this.cachedParts) { + Function.drawFunction(canvas, limitedDrawFunction, drawDomain, Domain.R) + // Check if necessary to draw label + if(drawDomain.includes(this.labelX)) { this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } From d7fe7609000cab22d8ba0552fcc736d7b227c537 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 01:01:46 +0200 Subject: [PATCH 042/249] Slightly improving phases sum cleanness. Didn't have quite as many bugs, but isn't quite as clean as the magnitude one as of now --- .../LogarithmPlotter/js/objs/phasebode.mjs | 14 +++++++-- .../js/objs/sommephasesbode.mjs | 31 ++++++++++--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index bee6ee6..97fdae2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -114,11 +114,21 @@ export default class PhaseBode extends ExecutableObject { } update() { - if(Objects.currentObjects['Somme phases Bode'] !== undefined && Objects.currentObjects['Somme phases Bode'].length > 0) { - Objects.currentObjects['Somme phases Bode'][0].recalculateCache() + super.update() + let sumObjs = Objects.currentObjects['Somme phases Bode'] + if(sumObjs !== undefined && sumObjs.length > 0) { + sumObjs[0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme phases Bode') } } + + delete() { + super.update() + let sumObjs = Objects.currentObjects['Somme phases Bode'] + if(sumObjs !== undefined && sumObjs.length > 0) { + sumObjs[0].recalculateCache() + } + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index 1483788..3bb6a3c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -74,25 +74,28 @@ export default class SommePhasesBode extends ExecutableObject { recalculateCache() { // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - let drawMin = 0.001 - let drawMax = 100000 + let drawMin = 1e-20 + let drawMax = 1e20 this.om0xList = [drawMin, drawMax] this.phasesList = [0] this.phasesExprList = ['0'] - let phasesDict = {} - let phasesExprDict = {} - phasesDict[drawMax] = 0 + let phasesDict = new Map() + let phasesExprDict = new Map() + phasesDict.set(drawMax, 0) - if(Objects.currentObjects['Phase Bode'] !== undefined) { + let phaseObjects = Objects.currentObjects['Phase Bode'] + if(phaseObjects === undefined || phaseObjects.length < 1) { + Objects.deleteObject(this.name) + } else { console.log('Recalculating cache phase') - for(/** @type {PhaseBode} */ let obj of Objects.currentObjects['Phase Bode']) { + for(/** @type {PhaseBode} */ let obj of phaseObjects) { this.om0xList.push(obj.om_0.x.execute()) - if(phasesDict[obj.om_0.x.execute()] === undefined) { - phasesDict[obj.om_0.x.execute()] = obj.phase.execute() - phasesExprDict[obj.om_0.x.execute()] = obj.phase.toEditableString() + if(!phasesDict.has(obj.om_0.x.execute())) { + phasesDict.set(obj.om_0.x.execute(), obj.phase.execute()) + phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString()) } else { - phasesDict[obj.om_0.x.execute()] += obj.phase.execute() - phasesExprDict[obj.om_0.x.execute()] += '+' + obj.phase.toEditableString() + phasesDict.set(obj.om_0.x.execute(), obj.phase.execute() + phasesDict.get(obj.om_0.x.execute())) + phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString() + '+' + phasesExprDict.get(obj.om_0.x.execute())) } this.phasesList[0] += obj.om_0.y.execute() this.phasesExprList[0] += '+' + obj.om_0.y.toEditableString() @@ -100,8 +103,8 @@ export default class SommePhasesBode extends ExecutableObject { this.om0xList.sort((a,b) => a - b) let totalAdded = this.phasesList[0] for(let i = 1; i < this.om0xList.length; i++) { - this.phasesList[i] = this.phasesList[i-1] + phasesDict[this.om0xList[i]] - this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict[this.om0xList[i]] + this.phasesList[i] = this.phasesList[i-1] + phasesDict.get(this.om0xList[i]) + this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict.get(this.om0xList[i]) } } } From 91e422039733796db7ac6112c6a41e99907ec6db Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 01:35:47 +0200 Subject: [PATCH 043/249] Upping logarithmic graduation limit to 309 (maximum before Infinity, probably some dragons to be had there) --- .../eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml | 6 ------ .../qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs | 12 ++++++++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index fd9a737..2f7f259 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -120,12 +120,6 @@ Canvas { */ property bool showygrad: false - /*! - \qmlproperty int LogGraphCanvas::maxgradx - Max power of the logarithmic scaled on the x axis in logarithmic mode. - */ - property int maxgradx: 20 - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index cff8ae9..2892303 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -17,7 +17,7 @@ */ import { Module } from "./modules.mjs" -import { textsup } from "./utils.mjs" +import { textsup, roundAwayFromZero } from "./utils.mjs" import { Expression } from "./mathlib.mjs" import Latex from "./math/latex.mjs" @@ -139,7 +139,15 @@ class CanvasAPI extends Module { * Max power of the logarithmic scaled on the x axis in logarithmic mode. * @returns {number} */ - get maxgradx() { return this._canvas.maxgradx } + get maxgradx() { + return Math.min( + 309, // 10e309 = Infinity (beyond this land be dragons) + Math.max( + Math.ceil(Math.abs(Math.log10(this.xmin))), + Math.ceil(Math.abs(Math.log10(this.px2x(this.width)))) + ) + ) + } // // Methods to draw the canvas From a2fa16949ad10d096a361a53bc3bb49a5af5e0cb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 01:58:34 +0200 Subject: [PATCH 044/249] Fixing some bugs, including outzooming too much. --- .../LogarithmPlotter/LogGraphCanvas.qml | 6 ++++++ .../ViewPositionChangeOverlay.qml | 21 ++++++++++++------- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 2f7f259..8d4b2f2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -120,6 +120,12 @@ Canvas { */ property bool showygrad: false + /*! + \qmlproperty int LogGraphCanvas::maxgradx + Max power of the logarithmic scaled on the x axis in logarithmic mode. + */ + property int maxgradx: 90 + /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 3d5ff68..6ba180e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -94,9 +94,13 @@ Item { property int positionChangeTimer: 0 function updatePosition(deltaX, deltaY) { - settingsInstance.xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) - settingsInstance.ymax += deltaY/canvas.yzoom - settingsInstance.ymax = settingsInstance.ymax.toFixed(4) + const unauthorized = [NaN, Infinity, -Infinity] + const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) + const ymax = settingsInstance.ymax + deltaY/canvas.yzoom + if(!unauthorized.includes(xmin)) + settingsInstance.xmin = xmin + if(!unauthorized.includes(ymax)) + settingsInstance.ymax = ymax.toFixed(4) settingsInstance.changed() parent.positionChanged(deltaX, deltaY) @@ -140,12 +144,15 @@ Item { } let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) - if(newXZoom == settingsInstance.xzoom) // No change, allow more precision. + // Check if we need to have more precision + if(newXZoom < 10) newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) - if(newYZoom == settingsInstance.yzoom) // No change, allow more precision. + if(newYZoom < 10) newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) - settingsInstance.xzoom = newXZoom - settingsInstance.yzoom = newYZoom + if(newXZoom > 0.5) + settingsInstance.xzoom = newXZoom + if(newYZoom > 0.5) + settingsInstance.yzoom = newYZoom settingsInstance.changed() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 2892303..2a03677 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -17,7 +17,7 @@ */ import { Module } from "./modules.mjs" -import { textsup, roundAwayFromZero } from "./utils.mjs" +import { textsup } from "./utils.mjs" import { Expression } from "./mathlib.mjs" import Latex from "./math/latex.mjs" From d4e97f28609a558a4fdc886ae70e8dddf2bd1536 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 02:14:47 +0200 Subject: [PATCH 045/249] Moving last methods from LogGraphCanvas to Canvas JS module. --- .../LogarithmPlotter/LogGraphCanvas.qml | 41 ------------------- .../eu/ad5001/LogarithmPlotter/Settings.qml | 8 ++-- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 15 +++++-- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 8d4b2f2..c2d9f60 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -168,45 +168,4 @@ Canvas { } }) } - - /*! - \qmlmethod double LogGraphCanvas::x2px(double x) - Converts an \c x coordinate to it's relative position on the canvas. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function x2px(x) { - if(logscalex) { - var logxmin = Math.log(xmin) - return (Math.log(x)-logxmin)*xzoom - } else return (x - xmin)*xzoom - } - - /*! - \qmlmethod double LogGraphCanvas::y2px(double y) - Converts an \c y coordinate to it's relative position on the canvas. - The y axis not supporting logarithmic scale, it only support linear convertion. - */ - function y2px(y) { - return (ymax-y)*yzoom - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2x(px) { - if(logscalex) { - return Math.exp(px/xzoom+Math.log(xmin)) - } else return (px/xzoom+xmin) - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2y(px) { - return -(px/yzoom-ymax) - } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 067c70d..c94bef1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -227,10 +227,10 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - defValue: canvas.px2x(canvas.width).toFixed(2) + defValue: Modules.Canvas.px2x(canvas.width).toFixed(2) onChanged: function(xvaluemax) { if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") @@ -246,10 +246,10 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: canvas.px2y(canvas.height).toFixed(2) + defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 2a03677..1e85788 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -388,7 +388,11 @@ class CanvasAPI extends Module { * @returns {number} */ x2px(x) { - return this._canvas.x2px(x) + if(this.logscalex) { + const logxmin = Math.log(this.xmin) + return (Math.log(x)-logxmin)*this.xzoom + } else + return (x - this.xmin)*this.xzoom } /** @@ -398,7 +402,7 @@ class CanvasAPI extends Module { * @returns {number} */ y2px(y) { - return this._canvas.y2px(y) + return (this.ymax - y) * this.yzoom } /** @@ -408,7 +412,10 @@ class CanvasAPI extends Module { * @returns {number} */ px2x(px) { - return this._canvas.px2x(px) + if(this.logscalex) { + return Math.exp(px/this.xzoom+Math.log(this.xmin)) + } else + return (px/this.xzoom+this.xmin) } /** @@ -418,7 +425,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2y(px) { - return this._canvas.px2y(px) + return -(px/this.yzoom-this.ymax) } /** From 0f39930b882f6fd7c0effb7dc5ff6049e80fc415 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:31 +0000 Subject: [PATCH 046/249] Translated using Weblate (English) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 595c241..c7faea3 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1571,7 +1571,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. default - Default Graph + Default settings From 207a2254f3bf0800a7cbabde8f01d6ad3754505e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:31 +0000 Subject: [PATCH 047/249] Translated using Weblate (German) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index de3c10c..390d1dc 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1671,7 +1671,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory default - Standardeinstellungen + Standardeinstellungen general From bcf76dcd28277311a1b573cc9722f3f68773abb5 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 16 Sep 2024 19:59:28 +0000 Subject: [PATCH 048/249] Translated using Weblate (Spanish) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 448 +++++++++++++++++++++++++++------ 1 file changed, 371 insertions(+), 77 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index c4de048..9daf35d 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -17,7 +17,7 @@ 2D plotter software to make BODE plots, sequences and repartition functions. - Software de trazado 2D para diagramas de Bode, secuencias y funciones de distribución. + Software de trazado 2D para realizar gráficos de Bode, secuencias y funciones de distribución. @@ -320,7 +320,7 @@ Objects - + Objetos @@ -328,12 +328,12 @@ Export Logarithm Plot file - + Exportar archivo de gráfico de logaritmos Import Logarithm Plot file - + Importar archivo de gráfico de logaritmos @@ -360,7 +360,7 @@ Changelog - + Registro de cambios @@ -496,7 +496,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + Create new: - + + Crear nuevo: @@ -504,12 +504,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Hide all %1 - + Ocultar todo %1 Show all %1 - + Mostrar todo %1 Delete %1 %2 @@ -537,12 +537,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Hide %1 %2 - + Ocultar %1 %2 Show %1 %2 - + Mostrar %1 %2 @@ -557,7 +557,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Pick new color for %1 %2 - + Elegir nuevo color para %1 %2 @@ -565,37 +565,37 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Pointer precision: - + Precisión del puntero: Snap to grid: - + Ajustar a la cuadrícula: Pick X - + Elige X Pick Y - + Elige Y Open picker settings - + Abrir los ajustes del selector Hide picker settings - + Ocultar ajustes del selector (no pick selected) - + (sin selección) Snap to grid @@ -645,22 +645,22 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes X Axis Step - + Paso por eje X Y Axis Step - + Paso por eje Y Line width - + Anchura de la línea Text size (px) - + Tamaño del texto (px) @@ -675,37 +675,37 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes X Log scale - + Escala logarítmica en X Show X graduation - + Mostrar graduación del eje X Show Y graduation - + Mostrar graduación del eje Y Copy to clipboard - + Copiar al portapapeles Save plot - + Guardar gráfico Save plot as - + Guardar gráfico como Load plot - + Abrir gráfico Close @@ -717,7 +717,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Thanks and Contributions - LogarithmPlotter - + Agradecimientos y colaboraciones - LogarithmPlotter @@ -727,7 +727,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Original library by Raphael Graf - + Biblioteca original de Raphael Graf @@ -737,7 +737,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Ported to Javascript by Matthew Crumley - + Portado a Javascript por Matthew Crumley @@ -749,12 +749,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Ported to QMLJS by Ad5001 - + Portado a QMLJS por Ad5001 Libraries included - + Bibliotecas incluidas @@ -801,12 +801,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Translations included - + Traducciones incluidas Improve - + Mejorar @@ -814,12 +814,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Could not fetch changelog: Server error {}. - + No se ha podido recuperar el registro de cambios: Error del servidor {}. Could not fetch update: {}. - + No se pudo obtener el registro de cambios: {}. @@ -895,17 +895,17 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Cannot find property %1 of object %2. - + No se puede encontrar la propiedad %1 del objeto %2. Undefined variable %1. - + Variable %1 no definida. In order to be executed, object %1 must have at least one argument. - + Para ser ejecutado, el objeto %1 debe tener al menos un argumento. @@ -917,100 +917,100 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Invalid expression. - + Expresión incorrecta. Invalid expression (parity). - + Expresión no válida (paridad). Unknown character "%1". - + Carácter "%1" desconocido. Illegal escape sequence: %1. - + Secuencia de salida no válida: %1 . Parse error [%1:%2]: %3 - + Error de análisis [%1:%2]: %3 Expected %1 - + Previsto %1 Unexpected %1 - + Inesperado %1 Unexpected ".": member access is not permitted - + "." Inesperado: el acceso de miembros no está permitido Unexpected "[]": arrays are disabled. - + "[]" inesperado: las matrices están desactivadas. Unexpected symbol: %1. - + Símbolo inesperado: %1. Function %1 must have at least one argument. - + La función %1 debe tener al menos un argumento. First argument to map is not a function. - + El primer argumento de map no es una función. Second argument to map is not an array. - + El segundo argumento de map no es una matriz. First argument to fold is not a function. - + El primer argumento de fold no es una función. Second argument to fold is not an array. - + El segundo argumento de fold no es una matriz. First argument to filter is not a function. - + El primer argumento del filtro no es una función. Second argument to filter is not an array. - + El segundo argumento del filtro no es una matriz. Second argument to indexOf is not a string or array. - + El segundo argumento de indexOf no es una cadena ni una matriz. Second argument to join is not an array. - + El segundo argumento para unirse no es una matriz. @@ -1020,27 +1020,27 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes No object found with names %1. - + No se ha encontrado ningún objeto con el nombre %1. No object found with name %1. - + Ningún objeto con el nombre %1 encontrado. Object cannot be dependent on itself. - + El objeto no puede depender de sí mismo. Circular dependency detected. Object %1 depends on %2. - + Dependencia circular detectada. El objeto %1 depende de %2. Circular dependency detected. Objects %1 depend on %2. - + Dependencia circular detectada. Los objetos %1 dependen de %2. @@ -1048,7 +1048,10 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes %2 Evaluated expression: %3 - + Error al analizar la expresión de la propiedad %1: +%2 + +Expresión evaluada: %3 @@ -1056,7 +1059,10 @@ Evaluated expression: %3 %3 Undoing last change. - + Error al intentar dibujar %1 %2: +%3 + +Deshaciendo el último cambio. Function definition is not permitted. @@ -1073,7 +1079,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + LogarithmPlotter - Error de procesamiento @@ -1081,7 +1087,10 @@ Undoing last change. %2 Evaluated expression: %3 - + Error al analizar la expresión de la propiedad %1: +%2 + +Expresión evaluada: %3 @@ -1195,12 +1204,14 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + No se ha encontrado ninguna instalación de LaTeX. +Si ya tiene instalada una distribución de LaTeX, asegúrese de que está instalada en su ruta. +De lo contrario, puede descargar una distribución de LaTeX como TeX Live en https://tug.org/texlive/. DVIPNG was not found. Make sure you include it from your Latex distribution. - + No se ha encontrado DVIPNG. Asegúrese de incluirlo en tu distribución LaTeX. @@ -1209,7 +1220,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + Se ha producido una excepción durante la creación de la fórmula LaTeX. +El proceso '{}' terminó con un código de retorno distinto de cero {}: + +{} +Por favor, asegúrate de que tu instalación de LaTeX es correcta e informe de un error si es así. @@ -1230,7 +1245,10 @@ Asegúrate de que dicho paquete está instalado, o desactive el renderizado LaTe Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + Se ha producido una excepción durante la creación de la fórmula LaTeX. +El proceso '{}' tardó demasiado en finalizar: +{} +Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de un error si es así. @@ -1284,7 +1302,51 @@ Please make sure your latex installation is correct and report a bug if so. bottom - ↓ Abajo + ↓ Bajar + + + top-right + ↗ Arriba a la derecha + + + application + Aplicación + + + Next to target + Próximo al objetivo + + + top-left + ↖ Arriba a la izquierda + + + bottom-left + ↙ Abajo a la izquierda + + + bottom-right + ↘ Abajo a la derecha + + + function + Función + + + high + Alto + + + low + Bajo + + + With label + Con etiqueta + + + Hidden + Oculto @@ -1335,17 +1397,249 @@ Please make sure your latex installation is correct and report a bug if so. integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) derivative(<f: ExecutableObject>, <x: number>) - + derivada(<f: ExecutableObject>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) - + derivada(<f: string>, <variable: string>, <x: number>) + + + + position + + Position of %1 %2 set from "%3" to "%4". + %1 %2 movido de "%3" a "%4". + + + Position of %1 set from %2 to %3. + %1 movido de %2 a %3. + + + + prop + + expression + Expresión + + + definitionDomain + Dominio + + + om_0 + ω₀ + + + disableLatex + Desactivar el renderizado LaTeX para este texto + + + rounding + Redondeo + + + labelX + Posición de la etiqueta en X + + + drawPoints + Mostrar puntos + + + drawDashedLines + Mostrar líneas discontinuas + + + destinationDomain + Rango + + + labelPosition + Posición de la etiqueta + + + displayMode + Modo de visualización + + + pass + Pasar + + + gain + Incremento de magnitud + + + unit + Unidad a usar + + + y + Y + + + omGraduation + Mostrar la graduación en ω₀ + + + phase + Fase + + + x + X + + + pointStyle + Estilo de puntos + + + text + Contenido + + + probabilities + Lista de probabilidades + + + targetElement + Objeto de destino + + + approximate + Mostrar valor aproximado + + + displayStyle + Estilo de visualización + + + targetValuePosition + Posición del valor del objetivo + + + defaultExpression + Expresión predeterminada + + + color + Color + + + baseValues + Valores de inicialización + + + + phasebode + + Bode Phase + Fase de Bode + + + Bode Phases + Fases de Bode + + + + point + + Point + Punto + + + Points + Puntos + + + + settingCategory + + general + General + + + editor + Editor de expresiones + + + default + Gráfico por defecto + + + + repartition + + Repartition + Distribución + + + Repartition functions + Funciones de distribución + + + + sequence + + Sequences + Secuencias + + + Sequence + Secuencia + + + + sommegainsbode + + Bode Magnitudes Sum + Suma de las Magnitudes de Bode + + + + sommephasesbode + + Bode Phases Sum + Suma de las fases de Bode + + + + text + + Texts + Textos + + + Text + Texto + + + + xcursor + + X Cursor + Cursor X + + + X Cursors + Cursores X + + + + visibility + + %1 %2 shown. + Se muestra %1 %2. + + + %1 %2 hidden. + Se oculta %1 %2. From 6b4da2b061d2f75262f3b75000df07b832726158 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:31 +0000 Subject: [PATCH 049/249] Translated using Weblate (French) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 86d982b..1b15a28 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1688,7 +1688,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c default - Paramètres par défaut + Paramètres par défaut From 214dd687b13de7b7ea15c8e9cb78a49c90f791a3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:31 +0000 Subject: [PATCH 050/249] Translated using Weblate (Hungarian) Currently translated at 98.0% (303 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 2829421..dfdbcaf 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1563,7 +1563,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents default - Alapértelmezett ábra + Alapértelmezett ábra From b52cc1de29940b0809816746f5ebe049684bbaf0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:20:02 +0000 Subject: [PATCH 051/249] Translated using Weblate (German) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 390d1dc..de3c10c 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1671,7 +1671,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory default - Standardeinstellungen + Standardeinstellungen general From 1bc3aaf53bf9cf80f60da5694e1549b0ca21ce5a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:33 +0000 Subject: [PATCH 052/249] Translated using Weblate (Spanish) Currently translated at 99.6% (308 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 9daf35d..ed3ce99 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1570,7 +1570,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u default - Gráfico por defecto + Gráfico por defecto From 12b48a2e7414961e33241581e9ffeb62fc21c586 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 00:19:51 +0000 Subject: [PATCH 053/249] Translated using Weblate (French) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 1b15a28..86d982b 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1688,7 +1688,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c default - Paramètres par défaut + Paramètres par défaut From ab451092069994d4641fad809506fda5d4fdd4c0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 19:21:29 +0200 Subject: [PATCH 054/249] Fixing typos. --- README.md | 4 ++-- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a60a9a5..7f092e3 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,14 @@ You can find more screenshots on the [app website](https://apps.ad5001.eu/logari You can simply run LogarithmPlotter using `python3 run.py`. -In order to test translations, you can use the `--lang=` command line option to force the detected locale of LogarithmPlotter. +In order to test translations, you can use the `--lang=` commandline option to force the locale of LogarithmPlotter. ## Install ### Generate installers: All scripts noted here can be found in the `scripts` directory. -You can generate installers from LogarithmPlotter after installing all the dependencies: +You can generate installers for LogarithmPlotter after installing all the dependencies: For all builds, you need [Python 3](https://python.org) with [PySide6](https://pypi.org/project/PySide6/) installable with `pip install PySide6`. - Windows installer: - You need `pyinstaller`. You can install it using `pip install pyinstaller`. diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 6b5847b..6f90a1f 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -16,7 +16,7 @@

                        - LogarithmPlotter is, as it's name suggests, a plotter made with logarithm scales in mind. With an object system similar to Geogebra's, it allows dynamic creation of both logarithmic-scaled and non logarithmic-scaled plots with very few limitations. + LogarithmPlotter is, as its name suggests, a plotter made with logarithm scales in mind. With an object system similar to Geogebra's, it allows dynamic creation of both logarithmic-scaled and non logarithmic-scaled plots with very few limitations.

                        LogarithmPlotter est, comme son nom l'indique, un créateur de graphes et diagrammes 2D réalisé avec l'échelle logarithmique en tête. Avec un système d'objets similaire à Geogebra, ce qui lui permet de créer des graphes à échelle logarithmique et non logarithmique avec peu de limitations. @@ -25,7 +25,7 @@ A LogarithmPlotter egy logaritmus-ábrázoló, amely logaritmikus léptékek figyelembevételével készült. A Geogebrához hasonló objektumrendszerrel dinamikus parcellák létrehozását teszi lehetővé, nagyon kevés korlátozással.

                        - It's primary use is to quickly create asymptotic Bode plots, but it's extensible nature and ability to switch to non-logarithmic scales allow it to create other things with it, like sequences or statistical repartition functions. + Its primary use is to quickly create asymptotic Bode plots, but its extensible nature and ability to switch to non-logarithmic scales allow it to create other things with it, like sequences or statistical repartition functions.

                        Son intérêt principal est de permettre de créer des diagrammes asymptotiques de Bode, mais sa nature extensible et sa capacité à passer à une échelle non-logarithmique lui permet de créer d'autres choses. From 78d7e6f310041a98e8755b30b5ae2480bf14b4bc Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 20:36:46 +0200 Subject: [PATCH 055/249] Bumping required Python version to v3.9 + adding new Polyfills for IDEs. --- .../qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs | 6 +++++- setup.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index bf0661e..daefa6c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -67,4 +67,8 @@ const Helper = { const Latex = { /** @type {function(string, number, string): string} */ render: (latex_markup, font_size, color) => '', -} \ No newline at end of file + /** @type {function(string, number, string): string} */ + findPrerendered: (latex_markup, font_size, color) => '', + /** @type {function(): boolean} */ + checkLatexInstallation: () => true, +} diff --git a/setup.py b/setup.py index 8a7408c..7f81314 100644 --- a/setup.py +++ b/setup.py @@ -123,7 +123,7 @@ if sys.platform == 'linux': setuptools.setup( install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials"]), - python_requires='>=3.8', + python_requires='>=3.9', name='logarithmplotter', version=pkg_version, From 8b36ad81abb35081718eecd44fb080ede5cb456a Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Tue, 17 Sep 2024 07:28:12 +0000 Subject: [PATCH 056/249] Translated using Weblate (Spanish) Currently translated at 100.0% (309 of 309 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index ed3ce99..c26b7db 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1570,7 +1570,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u default - Gráfico por defecto + Ajustes por defecto From 769ad22ea677108a8d41370c0285a85c9f79d803 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 21:44:23 +0200 Subject: [PATCH 057/249] Cleaning up and update Linux data + Removing (no longer working) local install for linux. + Moving appstream changelog generation to scripts. + Updating debian package information. --- linux/debian/control | 6 ++-- linux/debian/copyright | 2 +- linux/debian/depends | 2 +- linux/install_local.sh | 36 ------------------- .../generate-appstream-changelog.sh | 0 scripts/package-linux.sh | 2 +- 6 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 linux/install_local.sh rename {linux => scripts}/generate-appstream-changelog.sh (100%) diff --git a/linux/debian/control b/linux/debian/control index 15e0846..57281bc 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,11 +1,11 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.5.0 +Version: 0.6.0 Architecture: all Maintainer: Ad5001 -Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.4.0), texlive-latex-base, dvipng +Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng -Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.6) +Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.9) Section: science Priority: optional Homepage: https://apps.ad5001.eu/logarithmplotter/ diff --git a/linux/debian/copyright b/linux/debian/copyright index 6d05e77..138dae9 100644 --- a/linux/debian/copyright +++ b/linux/debian/copyright @@ -3,6 +3,6 @@ Upstream-Name: logarithmplotter Upstream-Contact: Ad5001 Files: * -Copyright: 2023, Ad5001 +Copyright: 2024, Ad5001 License: GPL-3.0+ diff --git a/linux/debian/depends b/linux/debian/depends index fb79d69..5eea4fd 100644 --- a/linux/debian/depends +++ b/linux/debian/depends @@ -1 +1 @@ -python3, python3-pip, python3-pyside6-essentials (>= 6.4.0), texlive-latex-base, dvipng +python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng diff --git a/linux/install_local.sh b/linux/install_local.sh deleted file mode 100644 index 714cc0b..0000000 --- a/linux/install_local.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# AccountFree - Browse and use online services, free of account. -# Copyright (C) 2022 Ad5001 -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# This script installs the desktop file & mime type for development environment, linking it directly to run.py. - -APPROOT="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -echo "Adding desktop file..." -sed "s+ROOTFOLDER+$APPROOT/+g" "$APPROOT/linux/logplotter.desktop" > "$APPROOT/linux/logarithmplotter-local.desktop" -xdg-desktop-menu install "$APPROOT/linux/logarithmplotter-local.desktop" -echo "Installing mime-type..." -xdg-mime install "$APPROOT/linux/x-logarithm-plot.xml" -echo "Installing icons..." -mkdir -p ~/.local/share/icons/hicolor/scalable/mimetypes -cp "$APPROOT/linux/application-x-logarithm-plot.svg" ~/.local/share/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg -mkdir -p ~/.local/share/icons/hicolor/scalable/apps -cp "$APPROOT/logplotter.svg" ~/.local/share/icons/hicolor/scalable/apps/logarithmplotter.svg -# xdg-icon-resource does not work with SVG yet. See https://bugs.launchpad.net/ubuntu/+source/xdg-utils/+bug/790449. -#xdg-icon-resource install --context mimetypes --novendor "$APPROOT/linux/application-x-logarithm-plot.svg" "application-x-logarithm-plot" -#xdg-icon-resource install --context apps --novendor "$APPROOT/logplotter.svg" "logarithmplotter" -update-mime-database ~/.local/share/mime/ -update-icon-caches ~/.local/share/icons/hicolor diff --git a/linux/generate-appstream-changelog.sh b/scripts/generate-appstream-changelog.sh similarity index 100% rename from linux/generate-appstream-changelog.sh rename to scripts/generate-appstream-changelog.sh diff --git a/scripts/package-linux.sh b/scripts/package-linux.sh index af79276..ca2bcf7 100755 --- a/scripts/package-linux.sh +++ b/scripts/package-linux.sh @@ -8,7 +8,7 @@ cd ../../ # Deb sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ - --package logarithmplotter --copyright-file linux/debian/copyright --suite jammy --depends3 "$(cat linux/debian/depends)" --section science \ + --package logarithmplotter --copyright-file linux/debian/copyright --suite noble --depends3 "$(cat linux/debian/depends)" --section science \ bdist_deb # Flatpak building From 1bf175b09ce6210c2467c6f790c12507fc9750e2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 22:26:17 +0200 Subject: [PATCH 058/249] Adding type hints --- LogarithmPlotter/util/latex.py | 6 +++--- LogarithmPlotter/util/update.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 166e224..bdae13e 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -66,11 +66,11 @@ class Latex(QObject): self.tempdir = tempdir @Property(bool) - def latexSupported(self): + def latexSupported(self) -> bool: return LATEX_PATH is not None and DVIPNG_PATH is not None @Slot(result=bool) - def checkLatexInstallation(self): + def checkLatexInstallation(self) -> bool: """ Checks if the current latex installation is valid. """ @@ -121,7 +121,7 @@ class Latex(QObject): return f'{export_path}.png,{img.width()},{img.height()}' @Slot(str, float, QColor, result=str) - def findPrerendered(self, latex_markup: str, font_size: float, color: QColor): + def findPrerendered(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Finds a prerendered image and returns its data if possible, and an empty string if not. """ diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index dbacbfe..1fec256 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -54,7 +54,7 @@ class UpdateCheckerRunnable(QRunnable): is_version_newer = version_tuple > current_version_tuple if is_version_newer: msg_text = QCoreApplication.translate("update", - "An update for LogarithPlotter (v{}) is available.").format( + "An update for LogarithmPlotter (v{}) is available.").format( version) update_available = True else: From b50d56d511dce4c25c390055c6a5d696c38148a7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 17 Sep 2024 22:43:24 +0200 Subject: [PATCH 059/249] Improving python coding format --- LogarithmPlotter/__init__.py | 3 +- LogarithmPlotter/logarithmplotter.py | 9 +++--- LogarithmPlotter/util/config.py | 6 ++-- LogarithmPlotter/util/helper.py | 17 ++++++------ LogarithmPlotter/util/js.py | 2 +- LogarithmPlotter/util/latex.py | 41 +++++++++++++++------------- LogarithmPlotter/util/update.py | 13 ++++----- 7 files changed, 47 insertions(+), 44 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 9c675a2..b3140ad 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -20,13 +20,13 @@ from shutil import which __VERSION__ = "0.6.0" is_release = False - # Check if development version, if so get the date of the latest git patch # and append it to the version string. if not is_release and which('git') is not None: from os.path import realpath, join, dirname, exists from subprocess import check_output from datetime import datetime + # Command to check date of latest git commit cmd = ['git', 'log', '--format=%ci', '-n 1'] cwd = realpath(join(dirname(__file__), '..')) # Root AccountFree directory. @@ -41,4 +41,5 @@ if not is_release and which('git') is not None: if __name__ == "__main__": from .logarithmplotter import run + run() diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 1af01d1..ae908f5 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -87,7 +87,6 @@ def run(): icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) QIcon.setFallbackSearchPaths(icon_fallbacks); - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") @@ -104,10 +103,10 @@ def run(): app.installTranslator(translator); # Installing macOS file handler. - macOSFileOpenHandler = None + macos_file_open_handler = None if platform == "darwin": - macOSFileOpenHandler = native.MacOSFileOpenHandler() - app.installEventFilter(macOSFileOpenHandler) + macos_file_open_handler = native.MacOSFileOpenHandler() + app.installEventFilter(macos_file_open_handler) engine = QQmlApplicationEngine() global tmpfile @@ -138,7 +137,7 @@ def run(): chdir(path.dirname(path.realpath(__file__))) if platform == "darwin": - macOSFileOpenHandler.init_io(js_globals.Modules.IO) + macos_file_open_handler.init_io(js_globals.Modules.IO) # Check for LaTeX installation if LaTeX support is enabled if config.getSetting("enable_latex"): diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 5c2c653..8ab83b2 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -54,7 +54,9 @@ DEFAULT_SETTINGS = { # Create config directory CONFIG_PATH = { - "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") if "XDG_CONFIG_HOME" in environ else path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), + "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") + if "XDG_CONFIG_HOME" in environ else + path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "config"), "Darwin": path.join(path.expanduser("~"), "Library", "Application Support", "LogarithmPlotter"), }[system()] @@ -79,7 +81,7 @@ def init(): setSetting(setting_name+"."+setting_name2, cfg_data[setting_name][setting_name2]) else: setSetting(setting_name, cfg_data[setting_name]) - + def save(): """ Saves the config to the path. diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 47e7395..a802cc4 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -94,16 +94,16 @@ class Helper(QObject): pass elif data[:3] == "LPF": # More recent version of LogarithmPlotter file, but incompatible with the current format - raise Exception(QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__))) + msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__)) + raise Exception(msg) else: raise Exception("Invalid LogarithmPlotter file.") except Exception as e: # If file can't be loaded - QMessageBox.warning(None, 'LogarithmPlotter', - QCoreApplication.translate('main', 'Could not open file "{}":\n{}').format(filename, - e), - QMessageBox.Ok) # Cannot parse file + msg = QCoreApplication.translate('main', 'Could not open file "{}":\n{}') + QMessageBox.warning(None, 'LogarithmPlotter', msg.format(filename, e), QMessageBox.Ok) # Cannot parse file else: - QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.').format(filename), QMessageBox.Ok) # Cannot parse file + msg = QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.') + QMessageBox.warning(None, 'LogarithmPlotter', msg.format(filename), QMessageBox.Ok) # Cannot parse file try: chdir(path.dirname(path.realpath(__file__))) except NotADirectoryError as e: @@ -159,9 +159,8 @@ class Helper(QObject): """ Returns the version info about Qt, PySide6 & Python """ - return QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, - sys_version.split( - "\n")[0]) + msg = QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}") + return msg.format(PySide6_version, sys_version.split("\n")[0]) @Slot() def fetchChangelog(self): diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index 4514a42..6cdd0b2 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -23,6 +23,7 @@ class PyJSValue: """ Wrapper to provide easy way to interact with JavaScript values in Python directly. """ + def __init__(self, js_value: QJSValue, parent: QJSValue = None): self.qjs_value = js_value self._parent = parent @@ -49,4 +50,3 @@ class PyJSValue: return self.qjs_value.callWithInstance(self._parent, args) else: raise ValueError('Cannot call non-function JS value.') - diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index bdae13e..6b31359 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -78,19 +78,22 @@ class Latex(QObject): if LATEX_PATH is None: print("No Latex installation found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", - QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + msg = QCoreApplication.translate("latex", + "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.") + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", msg) valid_install = False elif DVIPNG_PATH is None: print("DVIPNG not found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) + msg = QCoreApplication.translate("latex", + "DVIPNG was not found. Make sure you include it from your Latex distribution.") + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", msg) valid_install = False else: try: self.render("", 14, QColor(0, 0, 0, 255)) except Exception as e: - valid_install = False # Should have sent an error message if failed to render + valid_install = False # Should have sent an error message if failed to render return valid_install @Slot(str, float, QColor, result=str) @@ -119,7 +122,7 @@ class Latex(QObject): img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' - + @Slot(str, float, QColor, result=str) def findPrerendered(self, latex_markup: str, font_size: float, color: QColor) -> str: """ @@ -131,8 +134,7 @@ class Latex(QObject): img = QImage(export_path) data = f'{export_path}.png,{img.width()},{img.height()}' return data - - + def create_export_path(self, latex_markup: str, font_size: float, color: QColor): """ Standardizes export path for renders. @@ -140,7 +142,6 @@ class Latex(QObject): markup_hash = "render" + str(hash(latex_markup)) export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') return markup_hash, export_path - def create_latex_doc(self, export_path: str, latex_markup: str): """ @@ -183,16 +184,18 @@ class Latex(QObject): """ Runs a subprocess and handles exceptions and messages them to the user. """ + cmd = " ".join(process) proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) try: out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: # Process errored output = str(out, 'utf8') + "\n" + str(err, 'utf8') - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), proc.returncode, output)) - raise Exception("{0} process exited with return code {1}:\n{2}\n{3}".format(" ".join(process), str(proc.returncode), str(out, 'utf8'), str(err, 'utf8'))) + msg = QCoreApplication.translate("latex", + "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + msg = msg.format(cmd, proc.returncode, output) + QMessageBox.warning(None, "LogarithmPlotter - Latex", msg) + raise Exception(f"{cmd} process exited with return code {str(proc.returncode)}:\n{str(out, 'utf8')}\n{str(err, 'utf8')}") except TimeoutExpired as e: # Process timed out proc.kill() @@ -202,14 +205,14 @@ class Latex(QObject): for pkg in PACKAGES: if f'{pkg}.sty' in output: # Package missing. - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") - .format(pkg, pkg)) + msg = QCoreApplication.translate("latex", + "Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") + QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(pkg, pkg)) raise Exception("Latex: Missing package " + pkg) - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), output)) - raise Exception(" ".join(process) + " process timed out:\n" + output) + msg = QCoreApplication.translate("latex", + "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(cmd, output)) + raise Exception(f"{cmd} process timed out:\n{output}") def cleanup(self, export_path): """ diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 1fec256..ed2b5ba 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -53,9 +53,8 @@ class UpdateCheckerRunnable(QRunnable): current_version_tuple = self.current_version.split(".") is_version_newer = version_tuple > current_version_tuple if is_version_newer: - msg_text = QCoreApplication.translate("update", - "An update for LogarithmPlotter (v{}) is available.").format( - version) + msg_text = QCoreApplication.translate("update", "An update for LogarithmPlotter (v{}) is available.") + msg_text = msg_text.format(version) update_available = True else: show_alert = False @@ -63,11 +62,11 @@ class UpdateCheckerRunnable(QRunnable): except HTTPError as e: msg_text = QCoreApplication.translate("update", - "Could not fetch update information: Server error {}.").format( - str(e.code)) + "Could not fetch update information: Server error {}.") + msg_text = msg_text.format(str(e.code)) except URLError as e: - msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.").format( - str(e.reason)) + msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.") + msg_text = msg_text.format(str(e.reason)) self.callback.got_update_info.emit(show_alert, msg_text, update_available) From 9072e94d14dc3ce0105b4c85e598ff5ad9a492f3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 00:30:58 +0200 Subject: [PATCH 060/249] Starting python tests --- .gitignore | 7 +++---- LogarithmPlotter/util/config.py | 28 +++++++++++++++++----------- LogarithmPlotter/util/helper.py | 8 +++++--- LogarithmPlotter/util/js.py | 28 +++++++++++++++++++++++----- README.md | 13 ++++++++----- tests/python/test_config.py | 10 ++++++++++ tests/python/test_helper.py | 0 tests/python/test_pyjs.py | 0 8 files changed, 66 insertions(+), 28 deletions(-) create mode 100644 tests/python/test_config.py create mode 100644 tests/python/test_helper.py create mode 100644 tests/python/test_pyjs.py diff --git a/.gitignore b/.gitignore index 8802201..a60c4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,15 +22,14 @@ linux/flatpak/.flatpak-builder **/__pycache__/ .ropeproject .vscode +*.kdev4 +.kdev4 +.coverage build docs/html .directory -*.kdev4 *.lpf *.lgg *.spec -.kdev4 -AccountFree.pro -AccountFree.pro.user *.egg-info/ *.tar.gz diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 8ab83b2..d295caa 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -21,7 +21,6 @@ from platform import system from json import load, dumps from PySide6.QtCore import QLocale, QTranslator - DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, @@ -38,7 +37,7 @@ DEFAULT_SETTINGS = { "default_graph": { "xzoom": 100, "yzoom": 10, - "xmin": 5/10, + "xmin": 5 / 10, "ymax": 25, "xaxisstep": "4", "yaxisstep": "4", @@ -55,41 +54,47 @@ DEFAULT_SETTINGS = { # Create config directory CONFIG_PATH = { "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") - if "XDG_CONFIG_HOME" in environ else - path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), + if "XDG_CONFIG_HOME" in environ else + path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "config"), "Darwin": path.join(path.expanduser("~"), "Library", "Application Support", "LogarithmPlotter"), }[system()] CONFIG_FILE = path.join(CONFIG_PATH, "config.json") -initialized = False current_config = DEFAULT_SETTINGS +class UnknownNamespaceError(Exception): pass + + def init(): """ Initializes the config and loads all possible settings from the file if needs be. """ + global current_config + current_config = DEFAULT_SETTINGS makedirs(CONFIG_PATH, exist_ok=True) if path.exists(CONFIG_FILE): - cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8')) + cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8')) for setting_name in cfg_data: if type(cfg_data[setting_name]) == dict: for setting_name2 in cfg_data[setting_name]: - setSetting(setting_name+"."+setting_name2, cfg_data[setting_name][setting_name2]) + setSetting(setting_name + "." + setting_name2, cfg_data[setting_name][setting_name2]) else: setSetting(setting_name, cfg_data[setting_name]) -def save(): + +def save(file=CONFIG_FILE): """ Saves the config to the path. """ - write_file = open(CONFIG_FILE, 'w', -1, 'utf8') + write_file = open(file, 'w', -1, 'utf8') write_file.write(dumps(current_config)) write_file.close() + def getSetting(namespace): """ Returns a setting from a namespace. @@ -103,9 +108,10 @@ def getSetting(namespace): setting = setting[name] else: # return namespace # Return original name - raise ValueError('Setting ' + namespace + ' doesn\'t exist. Debug: ', setting, name) + raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") return setting + def setSetting(namespace, data): """ Sets a setting at a namespace with data. @@ -119,6 +125,6 @@ def setSetting(namespace, data): if name in setting: setting = setting[name] else: - raise ValueError('Setting {} doesn\'t exist. Debug: {}, {}'.format(namespace, setting, name)) + raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") else: setting[name] = data diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index a802cc4..c7c92d8 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -32,6 +32,9 @@ from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config +class InvalidFileException(Exception): pass + + class ChangelogFetcher(QRunnable): def __init__(self, helper): QRunnable.__init__(self) @@ -94,8 +97,8 @@ class Helper(QObject): pass elif data[:3] == "LPF": # More recent version of LogarithmPlotter file, but incompatible with the current format - msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__)) - raise Exception(msg) + msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.") + raise InvalidFileException(msg.format(__VERSION__)) else: raise Exception("Invalid LogarithmPlotter file.") except Exception as e: # If file can't be loaded @@ -131,7 +134,6 @@ class Helper(QObject): @Slot(str, result=float) def getSettingInt(self, namespace): - print('Getting', namespace, config.getSetting(namespace)) return config.getSetting(namespace) @Slot(str, result=bool) diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index 6cdd0b2..b00c645 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -18,6 +18,7 @@ from PySide6.QtQml import QJSValue +class InvalidAttributeValueException(Exception): pass class PyJSValue: """ @@ -38,15 +39,32 @@ class PyJSValue: elif isinstance(value, PyJSValue): # Set property self.qjs_value.setProperty(key, value.qjs_value) - else: - print('Setting', key, value) + elif isinstance(value, QJSValue): self.qjs_value.setProperty(key, value) + elif type(value) in (int, float, str, bool): + self.qjs_value.setProperty(key, QJSValue(value)) + else: + raise InvalidAttributeValueException(f"Invalid value {value} of type {type(value)} being set to {key}.") + + def __eq__(self, other): + if isinstance(other, PyJSValue): + return self.qjs_value.equals(other.qjs_value) + elif isinstance(other, QJSValue): + return self.qjs_value.equals(other) + elif type(other) in (int, float, str, bool): + return self.qjs_value.equals(QJSValue(other)) + else: + return False def __call__(self, *args, **kwargs): + value = None if self.qjs_value.isCallable(): if self._parent is None: - return self.qjs_value.call(args) + value = self.qjs_value.call(args) else: - return self.qjs_value.callWithInstance(self._parent, args) + value = self.qjs_value.callWithInstance(self._parent, args) else: - raise ValueError('Cannot call non-function JS value.') + raise InvalidAttributeValueException('Cannot call non-function JS value.') + if isinstance(value, QJSValue): + value = PyJSValue(value) + return value diff --git a/README.md b/README.md index 7f092e3..0745682 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,6 @@ For all builds, you need [Python 3](https://python.org) with [PySide6](https://p - To build the snap, you need [snapcraft](https://snapcraft.io) installed. - Run `package-linux.sh`. - -### Linux - -Run `bash linux/install_local.sh` - ## Contribute There are several ways to contribute to LogarithmPlotter. @@ -54,6 +49,14 @@ There are several ways to contribute to LogarithmPlotter. - You can help the development of LogarithmPlotter. In order to get started, take a look at the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages). +## Tests + +To run LogarithmPlotter's test, use the following: + +- Python + - Install `pytest` and `pytest-cov` + - Run `pytest --cov` + ## Legal notice LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions. Copyright (C) 2021-2024 Ad5001 diff --git a/tests/python/test_config.py b/tests/python/test_config.py new file mode 100644 index 0000000..493b0f1 --- /dev/null +++ b/tests/python/test_config.py @@ -0,0 +1,10 @@ +import unittest + + +class MyTestCase(unittest.TestCase): + def test_something(self): + self.assertEqual(True, False) # add assertion here + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py new file mode 100644 index 0000000..e69de29 From 4759bdcd334d8501902330b6d621ae38cd99c5c7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 00:31:17 +0200 Subject: [PATCH 061/249] Continuing python tests --- tests/python/test_config.py | 44 ++++++++++++++++++++++++++++++++----- tests/python/test_helper.py | 13 +++++++++++ tests/python/test_pyjs.py | 34 ++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/tests/python/test_config.py b/tests/python/test_config.py index 493b0f1..c919c6f 100644 --- a/tests/python/test_config.py +++ b/tests/python/test_config.py @@ -1,10 +1,42 @@ -import unittest +import pytest +from LogarithmPlotter.util import config +from tempfile import TemporaryDirectory +from os.path import join -class MyTestCase(unittest.TestCase): - def test_something(self): - self.assertEqual(True, False) # add assertion here +@pytest.fixture() +def resource(): + directory = TemporaryDirectory() + config.CONFIG_FILE = join(directory.name, "config.json") + config.init() + yield config.CONFIG_FILE + directory.cleanup() -if __name__ == '__main__': - unittest.main() +class TestConfig: + + def test_init(self, resource): + assert config.current_config == config.DEFAULT_SETTINGS + + def test_get(self, resource): + assert config.getSetting("expression_editor.autoclose") == True + with pytest.raises(config.UnknownNamespaceError): + config.getSetting("unknown_setting") + + def test_set(self, resource): + assert config.setSetting("expression_editor.autoclose", False) is None + assert config.getSetting("expression_editor.autoclose") == False # Ensure set is working. + with pytest.raises(config.UnknownNamespaceError): + config.setSetting("unknown_dict.unknown_setting", False) + + def test_reinit(self, resource): + default_value = config.getSetting("expression_editor.autoclose") + config.setSetting("expression_editor.autoclose", not default_value) + config.init() + assert config.getSetting("expression_editor.autoclose") != default_value # Ensure setting has been reset. + + def test_save(self, resource): + config.setSetting("expression_editor.autoclose", False) + config.save(resource) + config.init() + assert config.getSetting("expression_editor.autoclose") == False # Ensure setting has been saved. diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py index e69de29..e57ec61 100644 --- a/tests/python/test_helper.py +++ b/tests/python/test_helper.py @@ -0,0 +1,13 @@ +import pytest +from os.path import join +from tempfile import TemporaryDirectory +from LogarithmPlotter.util import config + + +@pytest.fixture() +def resource(): + directory = TemporaryDirectory() + config.CONFIG_PATH = join(directory.name, "config.json") + tmpfile = join(directory.name, 'graph.png') + yield tmpfile + directory.cleanup() \ No newline at end of file diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py index e69de29..7765f30 100644 --- a/tests/python/test_pyjs.py +++ b/tests/python/test_pyjs.py @@ -0,0 +1,34 @@ + +import pytest +from PySide6.QtQml import QJSEngine, QJSValue +from PySide6.QtWidgets import QApplication + +from LogarithmPlotter.util.js import PyJSValue, InvalidAttributeValueException + +app = QApplication() +engine = QJSEngine() +obj = PyJSValue(engine.globalObject()) + +class TestPyJS: + def test_set(self): + obj.num1 = 2 + obj.num2 = QJSValue(2) + with pytest.raises(InvalidAttributeValueException): + obj.num3 = object() + + def test_eq(self): + obj.num = QJSValue(2) + assert obj.num == 2 + assert obj.num == QJSValue(2) + assert obj.num != object() + + def test_function(self): + function = PyJSValue(engine.evaluate("(function(argument) {return argument*2})")) + assert function(3) == 6 + assert function(10) == 20 + function2 = PyJSValue(engine.evaluate("(function(argument) {return argument+3})"), obj.qjs_value) + assert function2(3) == 6 + assert function2(10) == 13 + function3 = PyJSValue(engine.evaluate("2+2")) + with pytest.raises(InvalidAttributeValueException): + function3() From 29e48e284c27407b12ad434f889c73fd029f16ba Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 18:01:51 +0200 Subject: [PATCH 062/249] Adding pytest to drone ci --- ci/drone.yml | 26 +++++--------------------- tests/python/test_helper.py | 9 ++++++--- tests/python/test_pyjs.py | 2 ++ 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 3bcf9f2..de4165e 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -11,35 +11,19 @@ steps: commands: - git submodule update --init --recursive -- name: Linux test - image: ad5001/ubuntu-pyside6-xvfb:jammy-6.6.1 +- name: Tests + image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2 commands: + - pytest --cov --cov-report term-missing - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf when: event: [ push, tag ] -# - name: Windows test -# image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0-rev1 -# commands: -# - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. -# - xvfb-run python run.py --test-build --no-check-for-updates -# - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test1.lpf -# - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test2.lpf -# when: -# event: [ push, tag ] -# - name: Linux packaging -# image: ad5001/ubuntu-pyside6-xvfb:jammy-6.5.0 -# commands: -# - bash scripts/package-linux.sh -# when: -# event: [ push, tag ] - - -- name: Windows building - image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.6.1 +- name: Windows build + image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.7.2 commands: - bash scripts/build-wine.sh - bash scripts/package-wine.sh diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py index e57ec61..3e3975e 100644 --- a/tests/python/test_helper.py +++ b/tests/python/test_helper.py @@ -1,13 +1,16 @@ import pytest +from os import getcwd from os.path import join from tempfile import TemporaryDirectory from LogarithmPlotter.util import config +pwd = getcwd() + @pytest.fixture() -def resource(): +def temporary(): directory = TemporaryDirectory() config.CONFIG_PATH = join(directory.name, "config.json") - tmpfile = join(directory.name, 'graph.png') + tmpfile = join(directory.name, "graph.png") yield tmpfile - directory.cleanup() \ No newline at end of file + directory.cleanup() diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py index 7765f30..2e632af 100644 --- a/tests/python/test_pyjs.py +++ b/tests/python/test_pyjs.py @@ -13,6 +13,7 @@ class TestPyJS: def test_set(self): obj.num1 = 2 obj.num2 = QJSValue(2) + obj.num3 = PyJSValue(QJSValue(2)) with pytest.raises(InvalidAttributeValueException): obj.num3 = object() @@ -20,6 +21,7 @@ class TestPyJS: obj.num = QJSValue(2) assert obj.num == 2 assert obj.num == QJSValue(2) + assert obj.num == PyJSValue(QJSValue(2)) assert obj.num != object() def test_function(self): From 5211821a843cdd725e27695730fefa6874c4ae43 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 18:15:30 +0200 Subject: [PATCH 063/249] Setting up Poetry for dependency management. --- poetry.lock | 405 ++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 22 +++ scripts/build-macosx.sh | 1 - scripts/build-wine.sh | 1 - setup.py | 2 +- 5 files changed, 428 insertions(+), 3 deletions(-) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..e874544 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,405 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "altgraph" +version = "0.17.4" +description = "Python graph (network) package" +optional = false +python-versions = "*" +files = [ + {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, + {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.6.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "macholib" +version = "1.16.3" +description = "Mach-O header analysis and editing" +optional = false +python-versions = "*" +files = [ + {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, + {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, +] + +[package.dependencies] +altgraph = ">=0.17" + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pefile" +version = "2024.8.26" +description = "Python PE parsing module" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"}, + {file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"}, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pyinstaller" +version = "6.10.0" +description = "PyInstaller bundles a Python application and all its dependencies into a single package." +optional = false +python-versions = "<3.14,>=3.8" +files = [ + {file = "pyinstaller-6.10.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d60fb22859e11483af735aec115fdde09467cdbb29edd9844839f2c920b748c0"}, + {file = "pyinstaller-6.10.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:46d75359668993ddd98630a3669dc5249f3c446e35239b43bc7f4155bc574748"}, + {file = "pyinstaller-6.10.0-py3-none-manylinux2014_i686.whl", hash = "sha256:3398a98fa17d47ccb31f8779ecbdacec025f7adb2f22757a54b706ac8b4fe906"}, + {file = "pyinstaller-6.10.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e9989f354ae4ed8a3bec7bdb37ae0d170751d6520e500f049c7cd0632d31d5c3"}, + {file = "pyinstaller-6.10.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b7c90c91921b3749083115b28f30f40abf2bb481ceff196d2b2ce0eaa2b3d429"}, + {file = "pyinstaller-6.10.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf876d7d93b8b4f28d1ad57fa24645cf43119c79e985dd5e5f7a801245e6f53"}, + {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:db05e3f2f10f9f78c56f1fb163d9cb453433429fe4281218ebaf1ebfd39ba942"}, + {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:28eca3817f176fdc19747e1afcf434f13bb9f17a644f611be2c5a61b1f498ed7"}, + {file = "pyinstaller-6.10.0-py3-none-win32.whl", hash = "sha256:703e041718987e46ba0568a2c71ecf2459fddef57cf9edf3efeed4a53e3dae3f"}, + {file = "pyinstaller-6.10.0-py3-none-win_amd64.whl", hash = "sha256:95b55966e563e8b8f31a43882aea10169e9a11fdf38e626d86a2907b640c0701"}, + {file = "pyinstaller-6.10.0-py3-none-win_arm64.whl", hash = "sha256:308e0a8670c9c9ac0cebbf1bbb492e71b6675606f2ec78bc4adfc830d209e087"}, + {file = "pyinstaller-6.10.0.tar.gz", hash = "sha256:143840f8056ff7b910bf8f16f6cd92cc10a6c2680bb76d0a25d558d543d21270"}, +] + +[package.dependencies] +altgraph = "*" +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} +packaging = ">=22.0" +pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} +pyinstaller-hooks-contrib = ">=2024.8" +pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} +setuptools = ">=42.0.0" + +[package.extras] +completion = ["argcomplete"] +hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] + +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2024.8" +description = "Community maintained hooks for PyInstaller" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyinstaller_hooks_contrib-2024.8-py3-none-any.whl", hash = "sha256:0057fe9a5c398d3f580e73e58793a1d4a8315ca91c3df01efea1c14ed557825a"}, + {file = "pyinstaller_hooks_contrib-2024.8.tar.gz", hash = "sha256:29b68d878ab739e967055b56a93eb9b58e529d5b054fbab7a2f2bacf80cef3e2"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +packaging = ">=22.0" +setuptools = ">=42.0.0" + +[[package]] +name = "pyside6-essentials" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "PySide6_Essentials-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d13666e796ec140ecfb432c4f3d7baef6dfafc11929985a83b22c0025532fb7"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a1a4c09f1e916b9cfe53151fe4a503a6acb1f6621ba28204d1bfe636f80d6780"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:9135513e1c4c6e2fbb1e4f9afcb3d42e54708b0d9ed870cb3213ea4874cafa1e"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:0111d5fa8cf826de3ca9d82fed54726cce116d57f454f88a6467578652032d69"}, +] + +[package.dependencies] +shiboken6 = "6.7.2" + +[[package]] +name = "pytest" +version = "8.3.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, + {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, +] + +[[package]] +name = "setuptools" +version = "75.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, + {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] + +[[package]] +name = "shiboken6" +version = "6.7.2" +description = "Python/C++ bindings helper module" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "shiboken6-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:50c33ac6317b673a1eb97a9abaafccb162c4ba0c9ca658a8e449c49a8aadc379"}, + {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:70e80737b27cd5d83504b373013b55e70462bd4a27217d919ff9a83958731990"}, + {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:98bedf9a15f1d8ba1af3e4d1e7527f7946ce36da541e08074fd9dc9ab5ff1adf"}, + {file = "shiboken6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:9024e6afb2af1568ebfc8a5d07e4ff6c8829f40923eeb28901f535463e2b6b65"}, +] + +[[package]] +name = "stdeb" +version = "0.10.0" +description = "Python to Debian source package conversion utility" +optional = false +python-versions = "*" +files = [ + {file = "stdeb-0.10.0.tar.gz", hash = "sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "zipp" +version = "3.20.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.9,<3.13" +content-hash = "8ce304f6a3fbab24428232c1a7d0b59ea412094e82d6b8ce47e4d93462cc235a" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0aff704 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "LogarithmPlotter" +version = "0.6.0" +description = "Create and edit Bode plots" +authors = ["Ad5001 "] +license = "GPL-3.0-or-later" +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = ">=3.9,<3.13" +PySide6-Essentials = "^6.7.2" + +[tool.poetry.group.dev.dependencies] +pyinstaller = "^6.10.0" +pytest = "^8.3.3" +pytest-cov = "^5.0.0" +stdeb = "^0.10.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 1946ad3..a8f0783 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -5,7 +5,6 @@ cd "$DIR/.." rm $(find . -name "*.qmlc") rm $(find . -name "*.pyc") -python3 -m pip install -U "pyinstaller<6.0" # Building translations cd "LogarithmPlotter/i18n/" diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 638ba1d..062e471 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -5,7 +5,6 @@ rm -rf dist rm $(find . -name "*.qmlc") rm -rf $(find . -name "*.pyc") -wine python -m pip install -U pyinstaller # Building translations cd "LogarithmPlotter/i18n/" diff --git a/setup.py b/setup.py index 7f81314..5d1aae7 100644 --- a/setup.py +++ b/setup.py @@ -128,7 +128,7 @@ setuptools.setup( name='logarithmplotter', version=pkg_version, - description='2D plotter software to make BODE plots, sequences and repartition functions.', + description='Create and edit Bode plots.', long_description=read_file("README.md"), keywords='logarithm plotter graph creator bode diagram', From 4ac7de48b05527a07d0ab1e25d2f1662120f0785 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 22:51:23 +0200 Subject: [PATCH 064/249] Latex tests --- LogarithmPlotter/util/latex.py | 76 +++++++++++++++++++--------------- ci/drone.yml | 1 + poetry.lock | 21 +++++++++- pyproject.toml | 5 +-- scripts/run-tests.sh | 7 ++++ tests/python/test_latex.py | 68 ++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 39 deletions(-) create mode 100644 scripts/run-tests.sh create mode 100644 tests/python/test_latex.py diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 6b31359..2c650ce 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -18,13 +18,12 @@ from PySide6.QtCore import QObject, Slot, Property, QCoreApplication from PySide6.QtGui import QImage, QColor -from PySide6.QtWidgets import QApplication, QMessageBox +from PySide6.QtWidgets import QMessageBox from os import path, remove from string import Template from tempfile import TemporaryDirectory from subprocess import Popen, TimeoutExpired, PIPE -from platform import system from shutil import which from sys import argv @@ -36,6 +35,7 @@ If not found, it will send an alert to the user. LATEX_PATH = which('latex') DVIPNG_PATH = which('dvipng') PACKAGES = ["calligra", "amsfonts", "inputenc"] +SHOW_GUI_MESSAGES = "--test-build" not in argv DEFAULT_LATEX_DOC = Template(r""" \documentclass[]{minimal} @@ -54,6 +54,20 @@ $$$$ $markup $$$$ """) +def show_message(msg: str) -> None: + """ + Shows a GUI message if GUI messages are enabled + """ + if SHOW_GUI_MESSAGES: + QMessageBox.warning(None, "LogarithmPlotter - Latex", msg) + + +class MissingPackageException(Exception): pass + + +class RenderError(Exception): pass + + class Latex(QObject): """ Base class to convert Latex equations into PNG images with custom font color and size. @@ -77,22 +91,20 @@ class Latex(QObject): valid_install = True if LATEX_PATH is None: print("No Latex installation found.") - if "--test-build" not in argv: - msg = QCoreApplication.translate("latex", - "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.") - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", msg) + msg = QCoreApplication.translate("latex", + "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.") + show_message(msg) valid_install = False elif DVIPNG_PATH is None: print("DVIPNG not found.") - if "--test-build" not in argv: - msg = QCoreApplication.translate("latex", - "DVIPNG was not found. Make sure you include it from your Latex distribution.") - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", msg) + msg = QCoreApplication.translate("latex", + "DVIPNG was not found. Make sure you include it from your Latex distribution.") + show_message(msg) valid_install = False else: try: self.render("", 14, QColor(0, 0, 0, 255)) - except Exception as e: + except MissingPackageException: valid_install = False # Should have sent an error message if failed to render return valid_install @@ -105,20 +117,17 @@ class Latex(QObject): if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file - try: - latex_path = path.join(self.tempdir.name, str(markup_hash)) - # If the formula is just recolored or the font is just changed, no need to recreate the DVI. - if not path.exists(latex_path + ".dvi"): - self.create_latex_doc(latex_path, latex_markup) - self.convert_latex_to_dvi(latex_path) - self.cleanup(latex_path) - # Creating four pictures of different sizes to better handle dpi. - self.convert_dvi_to_png(latex_path, export_path, font_size, color) - # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) - # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) - # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) - except Exception as e: # One of the processes failed. A message will be sent every time. - raise e + latex_path = path.join(self.tempdir.name, str(markup_hash)) + # If the formula is just recolored or the font is just changed, no need to recreate the DVI. + if not path.exists(latex_path + ".dvi"): + self.create_latex_doc(latex_path, latex_markup) + self.convert_latex_to_dvi(latex_path) + self.cleanup(latex_path) + # Creating four pictures of different sizes to better handle dpi. + self.convert_dvi_to_png(latex_path, export_path, font_size, color) + # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) + # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) + # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -147,7 +156,6 @@ class Latex(QObject): """ Creates a temporary latex document with base file_hash as file name and a given expression markup latex_markup. """ - ltx_path = export_path + ".tex" f = open(export_path + ".tex", 'w') f.write(DEFAULT_LATEX_DOC.substitute(markup=latex_markup)) f.close() @@ -193,10 +201,10 @@ class Latex(QObject): output = str(out, 'utf8') + "\n" + str(err, 'utf8') msg = QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - msg = msg.format(cmd, proc.returncode, output) - QMessageBox.warning(None, "LogarithmPlotter - Latex", msg) - raise Exception(f"{cmd} process exited with return code {str(proc.returncode)}:\n{str(out, 'utf8')}\n{str(err, 'utf8')}") - except TimeoutExpired as e: + show_message(msg.format(cmd, proc.returncode, output)) + raise RenderError( + f"{cmd} process exited with return code {str(proc.returncode)}:\n{str(out, 'utf8')}\n{str(err, 'utf8')}") + except TimeoutExpired: # Process timed out proc.kill() out, err = proc.communicate() @@ -207,12 +215,12 @@ class Latex(QObject): # Package missing. msg = QCoreApplication.translate("latex", "Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.") - QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(pkg, pkg)) - raise Exception("Latex: Missing package " + pkg) + show_message(msg.format(pkg, pkg)) + raise MissingPackageException("Latex: Missing package " + pkg) msg = QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(cmd, output)) - raise Exception(f"{cmd} process timed out:\n{output}") + show_message(msg.format(cmd, output)) + raise RenderError(f"{cmd} process timed out:\n{output}") def cleanup(self, export_path): """ diff --git a/ci/drone.yml b/ci/drone.yml index de4165e..5ef917d 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,6 +14,7 @@ steps: - name: Tests image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2 commands: + - apt install -y texlive-base dvipng texlive-latex-extra # Install latex dependencies. - pytest --cov --cov-report term-missing - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf diff --git a/poetry.lock b/poetry.lock index e874544..cf83dea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -315,6 +315,25 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "pytest-qt" +version = "4.4.0" +description = "pytest support for PyQt and PySide applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-qt-4.4.0.tar.gz", hash = "sha256:76896142a940a4285339008d6928a36d4be74afec7e634577e842c9cc5c56844"}, + {file = "pytest_qt-4.4.0-py3-none-any.whl", hash = "sha256:001ed2f8641764b394cf286dc8a4203e40eaf9fff75bf0bfe5103f7f8d0c591d"}, +] + +[package.dependencies] +pluggy = ">=1.1" +pytest = "*" + +[package.extras] +dev = ["pre-commit", "tox"] +doc = ["sphinx", "sphinx-rtd-theme"] + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -402,4 +421,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "8ce304f6a3fbab24428232c1a7d0b59ea412094e82d6b8ce47e4d93462cc235a" +content-hash = "4693a671e927103ceeb946f688b84fdc56b8b39b2cd772d8d32475e1236d8a07" diff --git a/pyproject.toml b/pyproject.toml index 0aff704..bf23573 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,8 +15,5 @@ PySide6-Essentials = "^6.7.2" pyinstaller = "^6.10.0" pytest = "^8.3.3" pytest-cov = "^5.0.0" +pytest-qt = "^4.4.0" stdeb = "^0.10.0" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh new file mode 100644 index 0000000..b1a1ec4 --- /dev/null +++ b/scripts/run-tests.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." + +# Run python tests +pytest --cov --cov-report term-missing + + diff --git a/tests/python/test_latex.py b/tests/python/test_latex.py new file mode 100644 index 0000000..8f1d8a2 --- /dev/null +++ b/tests/python/test_latex.py @@ -0,0 +1,68 @@ +import pytest +from tempfile import TemporaryDirectory +from shutil import which +from os.path import exists +from re import match +from PySide6.QtGui import QColor + +from LogarithmPlotter.util import latex + +latex.SHOW_GUI_MESSAGES = False + + +@pytest.fixture() +def latex_obj(): + directory = TemporaryDirectory() + obj = latex.Latex(directory) + if not obj.checkLatexInstallation(): + raise Exception("Cannot run LaTeX tests without a proper LaTeX installation. Make sure to install a LaTeX distribution, DVIPNG, and the calligra package, and run the tests again.") + yield obj + directory.cleanup() + + +class TestLatex: + def test_check_install(self, latex_obj: latex.Latex) -> None: + assert latex_obj.latexSupported == True + assert latex_obj.checkLatexInstallation() == True + bkp = [latex.DVIPNG_PATH, latex.LATEX_PATH] + # Check what happens when one is missing. + latex.DVIPNG_PATH = None + assert latex_obj.latexSupported == False + assert latex_obj.checkLatexInstallation() == False + latex.DVIPNG_PATH = bkp[0] + latex.LATEX_PATH = None + assert latex_obj.latexSupported == False + assert latex_obj.checkLatexInstallation() == False + # Reset + [latex.DVIPNG_PATH, latex.LATEX_PATH] = bkp + + def test_render(self, latex_obj: latex.Latex) -> None: + result = latex_obj.render(r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)) + # Ensure result format + assert type(result) == str + [path, width, height] = result.split(",") + assert exists(path) + assert match(r"\d+", width) + assert match(r"\d+", height) + # Ensure it returns errors on invalid latex. + with pytest.raises(latex.RenderError): + latex_obj.render(r"\nonexistant", 14, QColor(0, 0, 0, 255)) + # Replace latex bin with one that returns errors + bkp = latex.LATEX_PATH + latex.LATEX_PATH = which("false") + with pytest.raises(latex.RenderError): + latex_obj.render(r"\mathrm{f}(x)", 14, QColor(0, 0, 0, 255)) + latex.LATEX_PATH = bkp + + def test_prerendered(self, latex_obj: latex.Latex) -> None: + args = [r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)] + latex_obj.render(*args) + prerendered = latex_obj.findPrerendered(*args) + assert type(prerendered) == str + [path, width, height] = prerendered.split(",") + assert exists(path) + assert match(r"\d+", width) + assert match(r"\d+", height) + prerendered2 = latex_obj.findPrerendered(args[0], args[1]+2, args[2]) + assert prerendered2 == "" + From cb0db7fae1f18b20c1ee63d09ba68979cba9cedb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 22:52:53 +0200 Subject: [PATCH 065/249] Running tests from script --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 5ef917d..5760b95 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -15,7 +15,7 @@ steps: image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2 commands: - apt install -y texlive-base dvipng texlive-latex-extra # Install latex dependencies. - - pytest --cov --cov-report term-missing + - bash scripts/run-tests.sh - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf From 3104dea91852743e8733a57cce0815e0a785cd1e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 23:03:44 +0200 Subject: [PATCH 066/249] Trying to fix building --- ci/drone.yml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 5760b95..879d651 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -6,28 +6,28 @@ platform: arch: amd64 steps: -- name: submodules - image: alpine/git - commands: - - git submodule update --init --recursive + - name: submodules + image: alpine/git + commands: + - git submodule update --init --recursive -- name: Tests - image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2 - commands: - - apt install -y texlive-base dvipng texlive-latex-extra # Install latex dependencies. - - bash scripts/run-tests.sh - - xvfb-run python3 run.py --test-build --no-check-for-updates - - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf - when: - event: [ push, tag ] + - name: Tests + image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex + commands: + - ls -la + - bash scripts/run-tests.sh + - xvfb-run python3 run.py --test-build --no-check-for-updates + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf + when: + event: [ push, tag ] -- name: Windows build - image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.7.2 - commands: - - bash scripts/build-wine.sh - - bash scripts/package-wine.sh - when: - event: [ push, tag ] + - name: Windows build + image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.7.2 + commands: + - bash scripts/build-wine.sh + - bash scripts/package-wine.sh + when: + event: [ push, tag ] From 2ee7da7995171eeb36dd4649f2514227fbe86713 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 23:11:44 +0200 Subject: [PATCH 067/249] Fixing CI building --- ci/drone.yml | 10 +++++++--- scripts/run-tests.sh | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 879d651..4b4ce7b 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -11,18 +11,22 @@ steps: commands: - git submodule update --init --recursive - - name: Tests + - name: Unit Tests image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex commands: - - ls -la - bash scripts/run-tests.sh + when: + event: [ push, tag ] + + - name: File Tests + image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex + commands: - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf when: event: [ push, tag ] - - name: Windows build image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.7.2 commands: diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index b1a1ec4..4eb7cef 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,7 +1,7 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/" # Run python tests -pytest --cov --cov-report term-missing +PYTHONPATH="$PYTHONPATH:.." pytest --cov --cov-report term-missing .. From a3cf99f3af82e7db0bc7a557aa9cbb524bf18fab Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 23:19:00 +0200 Subject: [PATCH 068/249] Filtering report paths --- scripts/run-tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 4eb7cef..52d4413 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,7 +1,7 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/" +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." # Run python tests -PYTHONPATH="$PYTHONPATH:.." pytest --cov --cov-report term-missing .. +PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . From 9712ff15bbbe4b64e9867e9f75f31bbb89004924 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 23:20:00 +0200 Subject: [PATCH 069/249] Giving script a GUI env lest Qt dumps --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 4b4ce7b..ce10ce6 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,7 +14,7 @@ steps: - name: Unit Tests image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex commands: - - bash scripts/run-tests.sh + - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] From 8f95479689cef694132426c3c9166b77ce67b914 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Sep 2024 23:26:07 +0200 Subject: [PATCH 070/249] Making pyinstaller command multiline. --- scripts/build-wine.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 062e471..39b2312 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -11,7 +11,13 @@ cd "LogarithmPlotter/i18n/" bash release.sh cd ../../ -wine pyinstaller --add-data "logplotter.svg;." --add-data "LogarithmPlotter/qml;qml" --add-data "LogarithmPlotter/i18n;i18n" --noconsole LogarithmPlotter/logarithmplotter.py --icon=win/logarithmplotter.ico -n logarithmplotter +wine pyinstaller --add-data "logplotter.svg;." \ + --add-data "LogarithmPlotter/qml;qml" \ + --add-data "LogarithmPlotter/i18n;i18n" \ + --noconsole \ + LogarithmPlotter/logarithmplotter.py \ + --icon=win/logarithmplotter.ico \ + -n logarithmplotter # Copy Qt6ShaderTools, a required library for for Qt5Compat PYSIDE6PATH="$(wine python -c "import PySide6; from os import path; print(path.dirname(PySide6.__file__));")" From 7dd64c8e31abb0ed08ea6ae97d861001a3faf9fe Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:22:03 +0200 Subject: [PATCH 071/249] Fixing issue with Settings no longer being translated. --- LogarithmPlotter/i18n/lp_de.ts | 72 +++--- LogarithmPlotter/i18n/lp_en.ts | 42 ++-- LogarithmPlotter/i18n/lp_es.ts | 216 +++++++++--------- LogarithmPlotter/i18n/lp_fr.ts | 100 ++++---- LogarithmPlotter/i18n/lp_hu.ts | 44 ++-- LogarithmPlotter/i18n/lp_nb_NO.ts | 44 ++-- LogarithmPlotter/i18n/lp_template.ts | 40 ++-- .../LogarithmPlotter/Popup/Preferences.qml | 4 +- .../js/preferences/default.mjs | 26 +-- .../js/preferences/expression.mjs | 10 +- .../js/preferences/general.mjs | 6 +- linux/logplotter.desktop | 20 -- 12 files changed, 314 insertions(+), 310 deletions(-) delete mode 100644 linux/logplotter.desktop diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index de3c10c..c158a4d 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -406,22 +406,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" HistoryBrowser - + Filter... Filtern… - + Redo > Wiederherstellen > - + > Now > Aktueller Stand - + < Undo < Rückgängig @@ -545,17 +545,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Anzeigen %1 %2 - + Set %1 %2 position Position von %1 %2 einstellen - + Delete %1 %2 %1 %2 löschen - + Pick new color for %1 %2 Neue Farbe für %1 %2 auswählen @@ -812,12 +812,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -1240,7 +1240,7 @@ Ausdruck analysiert: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1249,12 +1249,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1267,7 +1267,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1280,7 +1280,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Stellen Sie sicher, dass diese Pakete installiert sind, oder deaktivieren Sie das LaTeX-Rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1559,6 +1559,21 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Folgen + + settingCategory + + default + Standardeinstellungen + + + general + Allgemeine + + + editor + Ausdruckseditor + + sommegainsbode @@ -1587,22 +1602,26 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde update - An update for LogarithPlotter (v{}) is available. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + + An update for LogarithmPlotter (v{}) is available. + + + + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. @@ -1667,19 +1686,4 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde X Zeiger - - settingCategory - - default - Standardeinstellungen - - - general - Allgemeine - - - editor - Ausdruckseditor - - diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index c7faea3..4ce11d3 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -406,22 +406,22 @@ These settings can be changed at any time from the "Settings" menu. HistoryBrowser - + Filter... Filter… - + Redo > Redo > - + > Now > Now - + < Undo < Undo @@ -545,17 +545,17 @@ These settings can be changed at any time from the "Settings" menu.Show %1 %2 - + Set %1 %2 position Set %1 %2 position - + Delete %1 %2 Delete %1 %2 - + Pick new color for %1 %2 Pick new color for %1 %2 @@ -812,12 +812,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -1240,7 +1240,7 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1249,12 +1249,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1267,7 +1267,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1280,7 +1280,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1602,22 +1602,26 @@ Please make sure your LaTeX installation is correct and report a bug if so. update - An update for LogarithPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + + An update for LogarithmPlotter (v{}) is available. + + + + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index c26b7db..ae2702e 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -406,22 +406,22 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes HistoryBrowser - + Filter... - + Redo > Rehacer > - + > Now > Ahora - + < Undo < Deshacer @@ -545,17 +545,17 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Mostrar %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 Elegir nuevo color para %1 %2 @@ -812,12 +812,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes changelog - + Could not fetch changelog: Server error {}. No se ha podido recuperar el registro de cambios: Error del servidor {}. - + Could not fetch update: {}. No se pudo obtener el registro de cambios: {}. @@ -1200,7 +1200,7 @@ Expresión evaluada: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1209,12 +1209,12 @@ Si ya tiene instalada una distribución de LaTeX, asegúrese de que está instal De lo contrario, puede descargar una distribución de LaTeX como TeX Live en https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. No se ha encontrado DVIPNG. Asegúrese de incluirlo en tu distribución LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1227,7 +1227,7 @@ El proceso '{}' terminó con un código de retorno distinto de cero {} Por favor, asegúrate de que tu instalación de LaTeX es correcta e informe de un error si es así. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1240,7 +1240,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Asegúrate de que dicho paquete está instalado, o desactive el renderizado LaTeX en LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1350,64 +1350,25 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u - update + phasebode - - An update for LogarithPlotter (v{}) is available. - Una actualización para LogarithmPlotter (v{}) está disponible. + Bode Phase + Fase de Bode - - No update available. - No hay ninguna actualización disponible. - - - - Could not fetch update information: Server error {}. - No se ha podido obtener la información de la actualización: Error del servidor {}. - - - - Could not fetch update information: {}. - No se pudo obtener información de la actualización: {}. + Bode Phases + Fases de Bode - usage + point - - - Usage: %1 - Uso: %1 + Point + Punto - - - - Usage: %1 or -%2 - Uso: %1 o -%2 - - - - integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) - - - - integral(<from: number>, <to: number>, <f: string>, <variable: string>) - integral(<from: number>, <to: number>, <f: string>, <variable: string>) - - - - derivative(<f: ExecutableObject>, <x: number>) - derivada(<f: ExecutableObject>, <x: number>) - - - - derivative(<f: string>, <variable: string>, <x: number>) - derivada(<f: string>, <variable: string>, <x: number>) + Points + Puntos @@ -1536,43 +1497,6 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Valores de inicialización - - phasebode - - Bode Phase - Fase de Bode - - - Bode Phases - Fases de Bode - - - - point - - Point - Punto - - - Points - Puntos - - - - settingCategory - - general - General - - - editor - Editor de expresiones - - - default - Ajustes por defecto - - repartition @@ -1595,6 +1519,21 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Secuencia + + settingCategory + + general + General + + + editor + Editor de expresiones + + + default + Ajustes por defecto + + sommegainsbode @@ -1621,14 +1560,68 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u - xcursor + update - X Cursor - Cursor X + An update for LogarithPlotter (v{}) is available. + Una actualización para LogarithmPlotter (v{}) está disponible. - X Cursors - Cursores X + + An update for LogarithmPlotter (v{}) is available. + + + + + No update available. + No hay ninguna actualización disponible. + + + + Could not fetch update information: Server error {}. + No se ha podido obtener la información de la actualización: Error del servidor {}. + + + + Could not fetch update information: {}. + No se pudo obtener información de la actualización: {}. + + + + usage + + + + Usage: %1 + Uso: %1 + + + + + + Usage: %1 or +%2 + Uso: %1 o +%2 + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + derivative(<f: ExecutableObject>, <x: number>) + derivada(<f: ExecutableObject>, <x: number>) + + + + derivative(<f: string>, <variable: string>, <x: number>) + derivada(<f: string>, <variable: string>, <x: number>) @@ -1642,4 +1635,15 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Se oculta %1 %2. + + xcursor + + X Cursor + Cursor X + + + X Cursors + Cursores X + + diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 86d982b..145c89e 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -399,7 +399,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Take a few seconds to configure LogarithmPlotter. These settings can always be changed at any time from the "Settings" menu. - Take a few seconds to configure LogarithmPlotter. + Take a few seconds to configure LogarithmPlotter. These settings can always be changed at any time from the "Settings" menu. @@ -414,22 +414,22 @@ These settings can always be changed at any time from the "Settings" m HistoryBrowser - + Filter... Filtrer… - + Redo > Rétablir > - + > Now > État actuel - + < Undo < Annuler @@ -553,17 +553,17 @@ These settings can always be changed at any time from the "Settings" m Montrer l'objet %1 %2 - + Set %1 %2 position Définir la position de l'objet %1 %2 - + Delete %1 %2 Supprimer l'objet %1 %2 - + Pick new color for %1 %2 Choisissez une nouvelle couleur pour %1 %2 @@ -820,12 +820,12 @@ These settings can always be changed at any time from the "Settings" m changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -1108,19 +1108,19 @@ Formule analysée : %3 Automatically close parenthesises and brackets - Fermer automatiquement les parenthèses et les crochets + Fermer automatiquement les parenthèses et les crochets Enable syntax highlighting - Activer la coloration syntaxique + Activer la coloration syntaxique Enable autocompletion - Activer l'autocomplétion + Activer l'autocomplétion Color Scheme - Coloration Syntaxique + Coloration Syntaxique @@ -1157,15 +1157,15 @@ Formule analysée : %3 general Check for updates on startup - Vérifier la présence de mise à jour au démarrage + Vérifier la présence de mise à jour au démarrage Reset redo stack automaticly - Réinitialiser la pile d'action "Rétablir" automatiquement + Réinitialiser la pile d'action "Rétablir" automatiquement Enable LaTeX rendering - Activer le rendu LaTeX + Activer le rendu LaTeX @@ -1211,27 +1211,27 @@ Formule analysée : %3 Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. Copied plot screenshot to clipboard! @@ -1249,7 +1249,7 @@ Formule analysée : %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1258,12 +1258,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1276,7 +1276,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1289,7 +1289,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Assurez-vous que ce paquetage est installé, ou désactivez le rendu LaTeX dans LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1568,6 +1568,21 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Suites + + settingCategory + + general + Général + + + editor + Éditeur de formule + + + default + Paramètres par défaut + + sommegainsbode @@ -1596,22 +1611,26 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c update - An update for LogarithPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + + An update for LogarithmPlotter (v{}) is available. + + + + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. @@ -1676,19 +1695,4 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Curseurs X - - settingCategory - - general - Général - - - editor - Éditeur de formule - - - default - Paramètres par défaut - - diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index dfdbcaf..e21aa92 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -406,22 +406,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. HistoryBrowser - + Filter... Szűrő… - + Redo > Ismétlés > - + > Now > Most - + < Undo < Visszavonás @@ -545,17 +545,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1 %2 megjelenítése - + Set %1 %2 position %1 %2 helye beállítása - + Delete %1 %2 %1 %2 törlése - + Pick new color for %1 %2 Válasszon új színt a következőhöz: %1 %2 @@ -812,12 +812,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -1240,7 +1240,7 @@ Kiértékelt kifejezés: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1249,12 +1249,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1267,7 +1267,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1276,7 +1276,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1563,7 +1563,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents default - Alapértelmezett ábra + Alapértelmezett ábra @@ -1594,22 +1594,26 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents update - An update for LogarithPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + + An update for LogarithmPlotter (v{}) is available. + + + + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 3b84451..ca36bf7 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -362,22 +362,22 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. HistoryBrowser - + Filter... - + Redo > Angre > - + > Now > Nå - + < Undo < Angre @@ -501,17 +501,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Vis %1 %2 - + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 Slett %1 %2 - + Pick new color for %1 %2 Velg ny farge for %1 %2 @@ -563,7 +563,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Close - + Lukk @@ -764,12 +764,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -1117,19 +1117,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1138,7 +1138,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1147,7 +1147,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1227,22 +1227,26 @@ Please make sure your latex installation is correct and report a bug if so. update - An update for LogarithPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + + An update for LogarithmPlotter (v{}) is available. + + + + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 92ee723..3d31e6b 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter @@ -298,22 +298,22 @@ HistoryBrowser - + Filter... - + Redo > - + > Now - + < Undo @@ -393,17 +393,17 @@ - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -652,12 +652,12 @@ changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -869,19 +869,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -890,7 +890,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -899,7 +899,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -911,21 +911,21 @@ Please make sure your latex installation is correct and report a bug if so.update - An update for LogarithPlotter (v{}) is available. - + An update for LogarithmPlotter (v{}) is available. + - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 9d7b9c0..7d801ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -231,7 +231,7 @@ Popup { delegate: Component { Loader { - width: settingView.width * 2 / 3 + width: settingView.width - 20 property var setting: Modules.Preferences.categories[settingView.modelName][index] sourceComponent: { if(setting.type === "bool") @@ -245,7 +245,7 @@ Popup { else if(setting.type === "string") return stringSettingComponent else - console.log('Unknown setting type!', setting.constructor.name, setting.constructor) + console.log('Unknown setting type!', setting.constructor.nameInConfig, setting.constructor) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs index 1546729..230c71a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs @@ -20,85 +20,85 @@ import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "comm const XZOOM = new NumberSetting( - QT_TR_NOOP("X Zoom"), + qsTranslate("Settings", "X Zoom"), "default_graph.xzoom", "xzoom", 0.1 ) const YZOOM = new NumberSetting( - QT_TR_NOOP("Y Zoom"), + qsTranslate("Settings", "Y Zoom"), "default_graph.xzoom", "yzoom", 0.1 ) const XMIN = new NumberSetting( - QT_TR_NOOP("Min X"), + qsTranslate("Settings", "Min X"), "default_graph.xmin", "xmin", () => Helper.getSettingBool("default_graph.logscalex") ? 1e-100 : -Infinity ) const YMAX = new NumberSetting( - QT_TR_NOOP("Max Y"), + qsTranslate("Settings", "Max Y"), "default_graph.ymax", "ymax" ) const XAXISSTEP = new ExpressionSetting( - QT_TR_NOOP("X Axis Step"), + qsTranslate("Settings", "X Axis Step"), "default_graph.xaxisstep", "xaxisstep", ) const YAXISSTEP = new ExpressionSetting( - QT_TR_NOOP("Y Axis Step"), + qsTranslate("Settings", "Y Axis Step"), "default_graph.yaxisstep", "yaxisstep", ) const LINE_WIDTH = new NumberSetting( - QT_TR_NOOP("Line width"), + qsTranslate("Settings", "Line width"), "default_graph.linewidth", "linewidth", 1 ) const TEXT_SIZE = new NumberSetting( - QT_TR_NOOP("Text size (px)"), + qsTranslate("Settings", "Text size (px)"), "default_graph.textsize", "textsize" ) const X_LABEL = new StringSetting( - QT_TR_NOOP('X Label'), + qsTranslate("Settings", 'X Label'), "default_graph.xlabel", "xlabel", ["", "x", "ω (rad/s)"] ) const Y_LABEL = new StringSetting( - QT_TR_NOOP('Y Label'), + qsTranslate("Settings", 'Y Label'), "default_graph.ylabel", "xlabel", ["", "y", "G (dB)", "φ (°)", "φ (deg)", "φ (rad)"] ) const LOG_SCALE_X = new BoolSetting( - QT_TR_NOOP('X Log scale'), + qsTranslate("Settings", 'X Log scale'), "default_graph.logscalex", "logscalex" ) const SHOW_X_GRAD = new BoolSetting( - QT_TR_NOOP('Show X graduation'), + qsTranslate("Settings", 'Show X graduation'), "default_graph.showxgrad", "showxgrad" ) const SHOW_Y_GRAD = new BoolSetting( - QT_TR_NOOP('Show Y graduation'), + qsTranslate("Settings", 'Show Y graduation'), "default_graph.showygrad", "showygrad" ) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs index 92990b8..4493c77 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs @@ -19,25 +19,25 @@ import {BoolSetting, EnumIntSetting} from "common.mjs" const AUTOCLOSE_FORMULA = new BoolSetting( - QT_TR_NOOP("Automatically close parenthesises and brackets"), + qsTranslate("expression", "Automatically close parenthesises and brackets"), 'expression_editor.autoclose', 'text' ) const ENABLE_SYNTAX_HIGHLIGHTING = new BoolSetting( - QT_TR_NOOP("Enable syntax highlighting"), + qsTranslate("expression", "Enable syntax highlighting"), 'expression_editor.colorize', 'appearance' ) const ENABLE_AUTOCOMPLETE = new BoolSetting( - QT_TR_NOOP("Enable autocompletion"), + qsTranslate("expression", "Enable autocompletion"), 'autocompletion.enabled', 'label' ) const PICK_COLOR_SCHEME = new EnumIntSetting( - QT_TR_NOOP("Color Scheme"), + qsTranslate("expression", "Color Scheme"), 'expression_editor.color_scheme', 'color', ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] @@ -48,4 +48,4 @@ export default [ ENABLE_AUTOCOMPLETE, ENABLE_SYNTAX_HIGHLIGHTING, PICK_COLOR_SCHEME -] \ No newline at end of file +] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 3d2b7cf..eb47e4a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -19,20 +19,20 @@ import {BoolSetting} from "common.mjs" const CHECK_FOR_UPDATES = new BoolSetting( - QT_TR_NOOP("Check for updates on startup"), + qsTranslate("general", "Check for updates on startup"), 'check_for_updates', 'update' ) const RESET_REDO_STACK = new BoolSetting( - QT_TR_NOOP("Reset redo stack automaticly"), + qsTranslate("general", "Reset redo stack automaticly"), 'reset_redo_stack', 'timeline' ) class EnableLatex extends BoolSetting { constructor() { - super(qsTr("Enable LaTeX rendering"), 'enable_latex', 'Expression') + super(qsTranslate("general","Enable LaTeX rendering"), 'enable_latex', 'Expression') } set(value) { diff --git a/linux/logplotter.desktop b/linux/logplotter.desktop deleted file mode 100644 index 1c46f8f..0000000 --- a/linux/logplotter.desktop +++ /dev/null @@ -1,20 +0,0 @@ -[Desktop Entry] -Version=1.0 -Type=Application -Name=LogarithmPlotter -GenericName=2D plotter software -GenericName[fr]=Logiciel de traçage 2D -GenericName[de]=2D-Grafiksoftware -GenericName[no]=2D-plotterprogramvare -GenericName[hu]=Síkbeli ábrázolásszoftver -Comment=Create BODE diagrams, sequences and distribution functions -Comment[fr]=Créer des diagrammes de BODE, des suites et des fonctions de répartition -Comment[de]=Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen -Comment[hu]=Bode-ábrák, sorozatok és újraosztási függvények létrehozása - -Exec=/usr/bin/python3 ROOTFOLDER/run.py %f -Icon=logarithmplotter -MimeType=application/x-logarithm-plot; -Terminal=false -StartupNotify=false -Categories=Science From b55b2a11fec0dee560c2722451f500a22f7c9714 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:50:47 +0200 Subject: [PATCH 072/249] Starting main tests --- LogarithmPlotter/logarithmplotter.py | 101 +++++++++++------- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 2 +- tests/python/test_main.py | 16 +++ 3 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 tests/python/test_main.py diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index ae908f5..975f471 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -16,18 +16,18 @@ * along with this program. If not, see . """ +from os import getcwd, chdir, environ, path +from platform import release as os_release +from sys import path as sys_path +from sys import platform, argv, exit +from tempfile import TemporaryDirectory from time import time -from PySide6.QtWidgets import QApplication -from PySide6.QtQml import QQmlApplicationEngine -from PySide6.QtCore import Qt, QTranslator, QLocale +from PySide6.QtCore import QTranslator, QLocale from PySide6.QtGui import QIcon - -from tempfile import TemporaryDirectory -from os import getcwd, chdir, environ, path, remove, close -from platform import release as os_release -from sys import platform, argv, version as sys_version, exit -from sys import path as sys_path +from PySide6.QtQml import QQmlApplicationEngine +from PySide6.QtQuickControls2 import QQuickStyle +from PySide6.QtWidgets import QApplication start_time = time() @@ -48,10 +48,7 @@ from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex from LogarithmPlotter.util.js import PyJSValue -config.init() - - -def get_linux_theme(): +def get_linux_theme() -> str: des = { "KDE": "Fusion", "gnome": "Basic", @@ -59,59 +56,59 @@ def get_linux_theme(): "mate": "Fusion", } if "XDG_SESSION_DESKTOP" in environ: - return des[environ["XDG_SESSION_DESKTOP"]] if environ["XDG_SESSION_DESKTOP"] in des else "Fusion" + if environ["XDG_SESSION_DESKTOP"] in des: + return des[environ["XDG_SESSION_DESKTOP"]] + return "Fusion" else: # Android return "Material" -def run(): - if not 'QT_QUICK_CONTROLS_STYLE' in environ: - environ["QT_QUICK_CONTROLS_STYLE"] = { - "linux": get_linux_theme(), - "freebsd": get_linux_theme(), - "win32": "Universal" if os_release == "10" else "Fusion", - "cygwin": "Fusion", - "darwin": "macOS" - }[platform] +def get_platform_qt_style(os) -> str: + return { + "linux": get_linux_theme(), + "freebsd": get_linux_theme(), + "win32": "Universal" if os_release() in ["10", "11", "12", "13", "14"] else "Windows", + "cygwin": "Fusion", + "darwin": "macOS" + }[os] - dep_time = time() - print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") - icon_fallbacks = QIcon.fallbackSearchPaths(); +def register_icon_directories() -> None: + icon_fallbacks = QIcon.fallbackSearchPaths() base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") icon_fallbacks.append(path.realpath(path.join(base_icon_path, "common"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "objects"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "history"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) - QIcon.setFallbackSearchPaths(icon_fallbacks); + QIcon.setFallbackSearchPaths(icon_fallbacks) + +def create_qapp() -> QApplication: app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) + return app + +def install_translation(app: QApplication) -> QTranslator: # Installing translators translator = QTranslator() # Check if lang is forced. forcedlang = [p for p in argv if p[:7] == "--lang="] locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() if translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): - app.installTranslator(translator); + app.installTranslator(translator) + return translator - # Installing macOS file handler. - macos_file_open_handler = None - if platform == "darwin": - macos_file_open_handler = native.MacOSFileOpenHandler() - app.installEventFilter(macos_file_open_handler) - engine = QQmlApplicationEngine() +def create_engine(helper: Helper, latex: Latex, dep_time: float) -> tuple[QQmlApplicationEngine, PyJSValue]: global tmpfile - helper = Helper(pwd, tmpfile) - latex = Latex(tempdir) + engine = QQmlApplicationEngine() js_globals = PyJSValue(engine.globalObject()) js_globals.Modules = engine.newObject() js_globals.Helper = engine.newQObject(helper) @@ -119,15 +116,37 @@ def run(): engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) - app.translate("About", "About LogarithmPlotter") - # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. - engine.addImportPath(path.realpath(path.join(getcwd(), "qml"))) engine.load(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) - if not engine.rootObjects(): + return engine, js_globals + + +def run(): + config.init() + + if not 'QT_QUICK_CONTROLS_STYLE' in environ: + QQuickStyle.setStyle(get_platform_qt_style(platform)) + + dep_time = time() + print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") + + register_icon_directories() + app = create_qapp() + translator = install_translation(app) + + # Installing macOS file handler. + macos_file_open_handler = None + if platform == "darwin": + macos_file_open_handler = native.MacOSFileOpenHandler() + app.installEventFilter(macos_file_open_handler) + + helper = Helper(pwd, tmpfile) + latex = Latex(tempdir) + engine, js_globals = create_engine(helper, latex, dep_time) + + if len(engine.rootObjects()) == 0: # No root objects loaded print("No root object", path.realpath(path.join(getcwd(), "qml"))) - print(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) exit(-1) # Open the current diagram diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index 396ada8..4bc76b5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -34,7 +34,7 @@ class IOAPI extends Module { /** * Initializes module with QML elements. - * @param {LogarithmPlotter} rootElement + * @param {{width: number, height: number, updateObjectsLists: function()}} rootElement * @param {Settings} settings * @param {{show: function(string)}} alert */ diff --git a/tests/python/test_main.py b/tests/python/test_main.py new file mode 100644 index 0000000..1dfbcbb --- /dev/null +++ b/tests/python/test_main.py @@ -0,0 +1,16 @@ +import pytest + +from LogarithmPlotter.logarithmplotter import get_linux_theme + +THEMES = [ + "Basic", + "Universal", + "Material", + "Fusion", + "Windows", + "macOS" +] + +class TestMain: + def test_themes(self): + get_linux_theme() \ No newline at end of file From e68411e93c5b2b1538de305acb30a0cf8709865b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:51:16 +0200 Subject: [PATCH 073/249] Fixing typos --- linux/logarithmplotter.desktop | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/logarithmplotter.desktop b/linux/logarithmplotter.desktop index 56a0b14..00c871f 100644 --- a/linux/logarithmplotter.desktop +++ b/linux/logarithmplotter.desktop @@ -7,9 +7,9 @@ GenericName[de]=2D-Grafiksoftware mit logarithmischer Skalierung GenericName[fr]=Logiciel de traçage à l'échelle logarithmique GenericName[hu]=Síkbeli ábrázolásszoftver GenericName[no]=2D-plotterprogramvare -Comment=Create BODE diagrams, sequences and distribution functions +Comment=Create Bode diagrams, sequences and distribution functions Comment[de]=Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen -Comment[fr]=Créer des diagrammes de BODE, des suites et des fonctions de répartition +Comment[fr]=Créer des diagrammes de Bode, des suites et des fonctions de répartition Comment[hu]=Bode-ábrák, sorozatok és újraosztási függvények létrehozása TryExec=logarithmplotter From a250f532d9c9e3322b9fa2ea03ab532339a067d3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 00:51:28 +0200 Subject: [PATCH 074/249] Adding pyside6-addons as dependency until https://bugreports.qt.io/browse/PYSIDE-2871 is resolved. --- poetry.lock | 19 ++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index cf83dea..e2ba8cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -259,6 +259,23 @@ importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} packaging = ">=22.0" setuptools = ">=42.0.0" +[[package]] +name = "pyside6-addons" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "PySide6_Addons-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:90b995efce61058d995c603ea480a9a3054fe8206739dcbc273fc3b53d40650f"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:94b9bf6a2a4a7ac671e1776633e50d51326c86f4184f1c6e556f4dd5498fd52a"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:22979b1aa09d9cf1d7a86c8a9aa0cb4791d6bd1cc94f96c5b6780c5ef8a9e34e"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:ebf549eb25998665d8e4ec24014fbbd37bebc5ecdcb050b34db1e1c03e1bf81d"}, +] + +[package.dependencies] +PySide6-Essentials = "6.7.2" +shiboken6 = "6.7.2" + [[package]] name = "pyside6-essentials" version = "6.7.2" @@ -421,4 +438,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "4693a671e927103ceeb946f688b84fdc56b8b39b2cd772d8d32475e1236d8a07" +content-hash = "083111ed37f3ef23de75a56eaf4c6fdda954b6005c5ee0922aad4470e2a36738" diff --git a/pyproject.toml b/pyproject.toml index bf23573..a7aa8cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ package-mode = false [tool.poetry.dependencies] python = ">=3.9,<3.13" PySide6-Essentials = "^6.7.2" +pyside6-addons = "^6.7.2" [tool.poetry.group.dev.dependencies] pyinstaller = "^6.10.0" From 4a5756f24ddb777b7736f63dc15d1a733b33ee37 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 18 Sep 2024 22:22:47 +0000 Subject: [PATCH 075/249] Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/ --- LogarithmPlotter/i18n/lp_fr.ts | 58 ---------------------------------- 1 file changed, 58 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 145c89e..5794777 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -396,12 +396,6 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Close Fermer - - Take a few seconds to configure LogarithmPlotter. -These settings can always be changed at any time from the "Settings" menu. - Take a few seconds to configure LogarithmPlotter. -These settings can always be changed at any time from the "Settings" menu. - Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) @@ -1106,22 +1100,6 @@ Formule analysée : %3 LogarithmPlotter - Drawing error LogarithmPlotter - Erreur - - Automatically close parenthesises and brackets - Fermer automatiquement les parenthèses et les crochets - - - Enable syntax highlighting - Activer la coloration syntaxique - - - Enable autocompletion - Activer l'autocomplétion - - - Color Scheme - Coloration Syntaxique - function @@ -1155,18 +1133,6 @@ Formule analysée : %3 general - - Check for updates on startup - Vérifier la présence de mise à jour au démarrage - - - Reset redo stack automaticly - Réinitialiser la pile d'action "Rétablir" automatiquement - - - Enable LaTeX rendering - Activer le rendu LaTeX - historylib @@ -1209,30 +1175,6 @@ Formule analysée : %3 History Historique - - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. - - - Loading file '%1'. - Chargement du fichier '%1'. - - - Unknown object type: %1. - Type d'objet inconnu : %1. - - - Invalid file provided. - Fichier fourni invalide. - - - Could not save file: - Impossible de sauvegarder le fichier : - - - Loaded file '%1'. - Fichier '%1' chargé. - Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! From a9e47dbc176cdb9f6db1b813f6b79fefcfc43a54 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 01:52:23 +0200 Subject: [PATCH 076/249] Adding main tests (note: full main app may not be completely tested though) --- LogarithmPlotter/logarithmplotter.py | 51 +++++++---- LogarithmPlotter/util/js.py | 6 +- .../__main__.py => tests/python/globals.py | 12 +-- tests/python/test_helper.py | 18 ++++ tests/python/test_latex.py | 18 ++++ tests/python/test_main.py | 90 ++++++++++++++++++- tests/python/test_pyjs.py | 36 ++++++-- 7 files changed, 194 insertions(+), 37 deletions(-) rename LogarithmPlotter/__main__.py => tests/python/globals.py (90%) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 975f471..d528c02 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -48,16 +48,31 @@ from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex from LogarithmPlotter.util.js import PyJSValue +LINUX_THEMES = { # See https://specifications.freedesktop.org/menu-spec/latest/onlyshowin-registry.html + "COSMIC": "Basic", + "GNOME": "Basic", + "GNOME-Classic": "Basic", + "GNOME-Flashback": "Basic", + "KDE": "Fusion", + "LXDE": "Basic", + "LXQt": "Fusion", + "MATE": "Fusion", + "TDE": "Fusion", + "Unity": "Basic", + "XFCE": "Basic", + "Cinnamon": "Fusion", + "Pantheon": "Basic", + "DDE": "Basic", + "EDE": "Fusion", + "Endless": "Basic", + "Old": "Fusion", +} + + def get_linux_theme() -> str: - des = { - "KDE": "Fusion", - "gnome": "Basic", - "lxqt": "Fusion", - "mate": "Fusion", - } if "XDG_SESSION_DESKTOP" in environ: - if environ["XDG_SESSION_DESKTOP"] in des: - return des[environ["XDG_SESSION_DESKTOP"]] + if environ["XDG_SESSION_DESKTOP"] in LINUX_THEMES: + return LINUX_THEMES[environ["XDG_SESSION_DESKTOP"]] return "Fusion" else: # Android @@ -77,18 +92,18 @@ def get_platform_qt_style(os) -> str: def register_icon_directories() -> None: icon_fallbacks = QIcon.fallbackSearchPaths() base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") - icon_fallbacks.append(path.realpath(path.join(base_icon_path, "common"))) - icon_fallbacks.append(path.realpath(path.join(base_icon_path, "objects"))) - icon_fallbacks.append(path.realpath(path.join(base_icon_path, "history"))) - icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings"))) - icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) + paths = [["common"], ["objects"], ["history"], ["settings"], ["settings", "custom"]] + for p in paths: + icon_fallbacks.append(path.realpath(path.join(base_icon_path, *p))) QIcon.setFallbackSearchPaths(icon_fallbacks) def create_qapp() -> QApplication: app = QApplication(argv) app.setApplicationName("LogarithmPlotter") - app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") + app.setApplicationDisplayName("LogarithmPlotter") + app.setApplicationVersion(f"v{__VERSION__}") + app.setDesktopFileName("eu.ad5001.LogarithmPlotter") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) @@ -101,8 +116,10 @@ def install_translation(app: QApplication) -> QTranslator: # Check if lang is forced. forcedlang = [p for p in argv if p[:7] == "--lang="] locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() - if translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): - app.installTranslator(translator) + if not translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): + # Load default translation + translator.load(QLocale("en"), "lp", "_", path.realpath(path.join(getcwd(), "i18n"))) + app.installTranslator(translator) return translator @@ -145,7 +162,7 @@ def run(): latex = Latex(tempdir) engine, js_globals = create_engine(helper, latex, dep_time) - if len(engine.rootObjects()) == 0: # No root objects loaded + if len(engine.rootObjects()) == 0: # No root objects loaded print("No root object", path.realpath(path.join(getcwd(), "qml"))) exit(-1) diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index b00c645..53ba4eb 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -48,11 +48,11 @@ class PyJSValue: def __eq__(self, other): if isinstance(other, PyJSValue): - return self.qjs_value.equals(other.qjs_value) + return self.qjs_value.strictlyEquals(other.qjs_value) elif isinstance(other, QJSValue): - return self.qjs_value.equals(other) + return self.qjs_value.strictlyEquals(other) elif type(other) in (int, float, str, bool): - return self.qjs_value.equals(QJSValue(other)) + return self.qjs_value.strictlyEquals(QJSValue(other)) else: return False diff --git a/LogarithmPlotter/__main__.py b/tests/python/globals.py similarity index 90% rename from LogarithmPlotter/__main__.py rename to tests/python/globals.py index 6c86e82..def1415 100644 --- a/LogarithmPlotter/__main__.py +++ b/tests/python/globals.py @@ -1,20 +1,20 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -if __name__ == "__main__": - from .logarithmplotter import run - run() +from LogarithmPlotter.logarithmplotter import create_qapp + +app = create_qapp() \ No newline at end of file diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py index 3e3975e..c4f6ea7 100644 --- a/tests/python/test_helper.py +++ b/tests/python/test_helper.py @@ -1,3 +1,21 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + import pytest from os import getcwd from os.path import join diff --git a/tests/python/test_latex.py b/tests/python/test_latex.py index 8f1d8a2..f02832e 100644 --- a/tests/python/test_latex.py +++ b/tests/python/test_latex.py @@ -1,3 +1,21 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + import pytest from tempfile import TemporaryDirectory from shutil import which diff --git a/tests/python/test_main.py b/tests/python/test_main.py index 1dfbcbb..d96bb4a 100644 --- a/tests/python/test_main.py +++ b/tests/python/test_main.py @@ -1,6 +1,33 @@ -import pytest +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" -from LogarithmPlotter.logarithmplotter import get_linux_theme +import pytest +from os import environ +from os.path import exists, join +from PySide6.QtGui import QIcon +from tempfile import TemporaryDirectory + +from LogarithmPlotter.logarithmplotter import get_linux_theme, LINUX_THEMES, get_platform_qt_style, \ + register_icon_directories, install_translation, create_engine +from LogarithmPlotter.util import config +from LogarithmPlotter.util.helper import Helper +from LogarithmPlotter.util.latex import Latex +from globals import app THEMES = [ "Basic", @@ -11,6 +38,61 @@ THEMES = [ "macOS" ] +OS_PLATFORMS = [ + "linux", + "freebsd", + "win32", + "cygwin", + "darwin" +] + +@pytest.fixture() +def temporary(): + directory = TemporaryDirectory() + config.CONFIG_PATH = join(directory.name, "config.json") + tmpfile = join(directory.name, "graph.png") + yield tmpfile, directory + directory.cleanup() + class TestMain: - def test_themes(self): - get_linux_theme() \ No newline at end of file + def test_linux_themes(self): + # Check without a desktop + if "XDG_SESSION_DESKTOP" in environ: + del environ["XDG_SESSION_DESKTOP"] + assert get_linux_theme() in THEMES + # Test various environments. + environ["XDG_SESSION_DESKTOP"] = "GNOME" + assert get_linux_theme() in THEMES + # Test various environments. + environ["XDG_SESSION_DESKTOP"] = "NON-EXISTENT" + assert get_linux_theme() in THEMES + # Check all linux themes are in list + for desktop, theme in LINUX_THEMES.items(): + assert theme in THEMES + + def test_os_themes(self): + for platform in OS_PLATFORMS: + assert get_platform_qt_style(platform) in THEMES + + def test_icon_directories(self): + base_paths = QIcon.fallbackSearchPaths() + register_icon_directories() + # Check if registered + assert len(base_paths) < len(QIcon.fallbackSearchPaths()) + # Check if all exists + for p in QIcon.fallbackSearchPaths(): + assert exists(p) + + def test_app(self, temporary): + assert not app.windowIcon().isNull() + # Translations + translator = install_translation(app) + assert not translator.isEmpty() + # Engine + tmpfile, tempdir = temporary + helper = Helper(".", tmpfile) + latex = Latex(tempdir) + engine, js_globals = create_engine(helper, latex, 0) + assert len(engine.rootObjects()) > 0 # QML File loaded. + assert type(engine.rootContext().contextProperty("TestBuild")) is bool + assert engine.rootContext().contextProperty("StartTime") == 0 \ No newline at end of file diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py index 2e632af..18c52eb 100644 --- a/tests/python/test_pyjs.py +++ b/tests/python/test_pyjs.py @@ -1,30 +1,52 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" import pytest from PySide6.QtQml import QJSEngine, QJSValue -from PySide6.QtWidgets import QApplication from LogarithmPlotter.util.js import PyJSValue, InvalidAttributeValueException +from globals import app -app = QApplication() -engine = QJSEngine() -obj = PyJSValue(engine.globalObject()) +@pytest.fixture() +def data(): + engine = QJSEngine() + obj = PyJSValue(engine.globalObject()) + yield engine, obj class TestPyJS: - def test_set(self): + def test_set(self, data): + engine, obj = data obj.num1 = 2 obj.num2 = QJSValue(2) obj.num3 = PyJSValue(QJSValue(2)) with pytest.raises(InvalidAttributeValueException): obj.num3 = object() - def test_eq(self): + def test_eq(self, data): + engine, obj = data obj.num = QJSValue(2) assert obj.num == 2 assert obj.num == QJSValue(2) assert obj.num == PyJSValue(QJSValue(2)) assert obj.num != object() - def test_function(self): + def test_function(self, data): + engine, obj = data function = PyJSValue(engine.evaluate("(function(argument) {return argument*2})")) assert function(3) == 6 assert function(10) == 20 From d566c285fdb694f6b34da63d7c20200bb8c725df Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 02:20:42 +0200 Subject: [PATCH 077/249] Adding values and types to PyJS --- LogarithmPlotter/util/js.py | 39 ++++++++++++++++++++++++++++++++++++- tests/python/test_pyjs.py | 21 +++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index 53ba4eb..ffdab5c 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -15,10 +15,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ - +from re import Pattern +from PySide6.QtCore import QMetaObject, QObject from PySide6.QtQml import QJSValue class InvalidAttributeValueException(Exception): pass +class NotAPrimitiveException(Exception): pass + +class Function: pass +class Date: pass +class URL: pass class PyJSValue: """ @@ -68,3 +74,34 @@ class PyJSValue: if isinstance(value, QJSValue): value = PyJSValue(value) return value + + def type(self) -> any: + matcher = [ + (lambda: self.qjs_value.isArray(), list), + (lambda: self.qjs_value.isBool(), bool), + (lambda: self.qjs_value.isCallable(), Function), + (lambda: self.qjs_value.isDate(), Date), + (lambda: self.qjs_value.isError(), Exception), + (lambda: self.qjs_value.isNull(), None), + (lambda: self.qjs_value.isNumber(), float), + (lambda: self.qjs_value.isQMetaObject(), QMetaObject), + (lambda: self.qjs_value.isQObject(), QObject), + (lambda: self.qjs_value.isRegExp(), Pattern), + (lambda: self.qjs_value.isUndefined(), None), + (lambda: self.qjs_value.isUrl(), URL), + (lambda: self.qjs_value.isString(), str), + (lambda: self.qjs_value.isObject(), object), + ] + for (test, value) in matcher: + if test(): + return value + return None + + def primitive(self): + """ + Returns the pythonic value of the given primitive data. + Raises a NotAPrimitiveException() if this JS value is not a primitive. + """ + if self.type() not in [bool, float, str, None]: + raise NotAPrimitiveException() + return self.qjs_value.toPrimitive().toVariant() \ No newline at end of file diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py index 18c52eb..5742cfc 100644 --- a/tests/python/test_pyjs.py +++ b/tests/python/test_pyjs.py @@ -17,9 +17,10 @@ """ import pytest +from re import Pattern from PySide6.QtQml import QJSEngine, QJSValue -from LogarithmPlotter.util.js import PyJSValue, InvalidAttributeValueException +from LogarithmPlotter.util.js import PyJSValue, InvalidAttributeValueException, NotAPrimitiveException from globals import app @pytest.fixture() @@ -56,3 +57,21 @@ class TestPyJS: function3 = PyJSValue(engine.evaluate("2+2")) with pytest.raises(InvalidAttributeValueException): function3() + + def test_type(self, data): + engine, obj = data + assert PyJSValue(engine.evaluate("[]")).type() == list + assert PyJSValue(engine.evaluate("undefined")).type() is None + assert PyJSValue(engine.evaluate("/[a-z]/g")).type() == Pattern + assert PyJSValue(QJSValue(2)).type() == float + assert PyJSValue(QJSValue("3")).type() == str + assert PyJSValue(QJSValue(True)).type() == bool + + def test_primitive(self, data): + engine, obj = data + assert PyJSValue(QJSValue(2)).primitive() == 2 + assert PyJSValue(QJSValue("string")).primitive() == "string" + assert PyJSValue(QJSValue(True)).primitive() == True + assert PyJSValue(engine.evaluate("undefined")).primitive() is None + with pytest.raises(NotAPrimitiveException): + assert PyJSValue(engine.evaluate("[]")).primitive() == [] From c3daa9228084a6508f6e3315095eacdf8a5612e3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 02:34:49 +0200 Subject: [PATCH 078/249] Testing for modules existance in globals. --- LogarithmPlotter/util/js.py | 5 ++--- tests/python/test_main.py | 13 ++++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index ffdab5c..dbe60bc 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -16,14 +16,13 @@ * along with this program. If not, see . """ from re import Pattern -from PySide6.QtCore import QMetaObject, QObject +from PySide6.QtCore import QMetaObject, QObject, QDateTime from PySide6.QtQml import QJSValue class InvalidAttributeValueException(Exception): pass class NotAPrimitiveException(Exception): pass class Function: pass -class Date: pass class URL: pass class PyJSValue: @@ -80,7 +79,7 @@ class PyJSValue: (lambda: self.qjs_value.isArray(), list), (lambda: self.qjs_value.isBool(), bool), (lambda: self.qjs_value.isCallable(), Function), - (lambda: self.qjs_value.isDate(), Date), + (lambda: self.qjs_value.isDate(), QDateTime), (lambda: self.qjs_value.isError(), Exception), (lambda: self.qjs_value.isNull(), None), (lambda: self.qjs_value.isNumber(), float), diff --git a/tests/python/test_main.py b/tests/python/test_main.py index d96bb4a..b15ee02 100644 --- a/tests/python/test_main.py +++ b/tests/python/test_main.py @@ -95,4 +95,15 @@ class TestMain: engine, js_globals = create_engine(helper, latex, 0) assert len(engine.rootObjects()) > 0 # QML File loaded. assert type(engine.rootContext().contextProperty("TestBuild")) is bool - assert engine.rootContext().contextProperty("StartTime") == 0 \ No newline at end of file + assert engine.rootContext().contextProperty("StartTime") == 0 + assert js_globals.Latex.type() is not None + assert js_globals.Helper.type() is not None + assert js_globals.Modules.type() is not None + # Check if modules have loaded + assert js_globals.Modules.History.type() is not None + assert js_globals.Modules.Latex.type() is not None + assert js_globals.Modules.ObjectsCommon.type() is not None + assert js_globals.Modules.Canvas.type() is not None + assert js_globals.Modules.IO.type() is not None + assert js_globals.Modules.Objects.type() is not None + assert js_globals.Modules.Preferences.type() is not None \ No newline at end of file From 836d13386e900a2ff461545adafb2695a63c79dc Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 18:19:35 +0200 Subject: [PATCH 079/249] Adding building translations in CI. --- ci/drone.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/drone.yml b/ci/drone.yml index ce10ce6..c846ad5 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,6 +14,8 @@ steps: - name: Unit Tests image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex commands: + - apt install -y qt6-l10n-tools + - cd LogarithmPlotter/i18n && bash release.sh - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] From fceb5e711c58ca97b0a00a21fb8326331b8acb9b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 20:21:04 +0200 Subject: [PATCH 080/249] Upgrading CI images --- ci/drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index c846ad5..2c225a5 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -12,7 +12,7 @@ steps: - git submodule update --init --recursive - name: Unit Tests - image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: - apt install -y qt6-l10n-tools - cd LogarithmPlotter/i18n && bash release.sh @@ -21,7 +21,7 @@ steps: event: [ push, tag ] - name: File Tests - image: ad5001/ubuntu-pyside6-xvfb:noble-6.7.2-latex + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf @@ -30,7 +30,7 @@ steps: event: [ push, tag ] - name: Windows build - image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.7.2 + image: ad5001/ubuntu-pyside-xvfb:wine-6-latest commands: - bash scripts/build-wine.sh - bash scripts/package-wine.sh From 48427b79235e0e112e91296a3b90f7563b25b400 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 21:33:29 +0200 Subject: [PATCH 081/249] Fixing lrelease installation --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 2c225a5..598d5ec 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,7 +14,7 @@ steps: - name: Unit Tests image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: - - apt install -y qt6-l10n-tools + - apt install -y qtchooser qttools5-dev-tools - cd LogarithmPlotter/i18n && bash release.sh - xvfb-run bash scripts/run-tests.sh when: From 956de5f9e34375a02d12fea42119bd65fed8e720 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 19 Sep 2024 21:57:41 +0200 Subject: [PATCH 082/249] FIxing building location --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 598d5ec..60fadf8 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -15,7 +15,7 @@ steps: image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: - apt install -y qtchooser qttools5-dev-tools - - cd LogarithmPlotter/i18n && bash release.sh + - cd LogarithmPlotter/i18n && bash release.sh && cd ../.. - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] From 325eef57e243b85f39e0908a84d29669138ceb47 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 17:40:42 +0200 Subject: [PATCH 083/249] Fixing ES flag in Thanks --- .../qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index c97bffb..107eac5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -261,7 +261,7 @@ BaseDialog { authors: [authors.comradekingu, authors.Ad5001] }) append({ - tranName: '🇳🇴 ' + qsTr('Spanish'), + tranName: '🇪🇸 ' + qsTr('Spanish'), link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/', authors: [authors.IngrownMink4, authors.gallegonovato] }) From 7f57ed13c767a3cd7dae542fac6560caafaad022 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 17:56:59 +0200 Subject: [PATCH 084/249] Removing ObjectsCommon API --- .../eu/ad5001/LogarithmPlotter/js/objects.mjs | 22 ++++++++ .../LogarithmPlotter/js/objs/autoload.mjs | 39 +++++++++----- .../LogarithmPlotter/js/objs/common.mjs | 53 ------------------- .../LogarithmPlotter/js/objs/function.mjs | 5 +- .../LogarithmPlotter/js/objs/gainbode.mjs | 6 +-- .../LogarithmPlotter/js/objs/phasebode.mjs | 10 ++-- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 6 ++- .../LogarithmPlotter/js/objs/repartition.mjs | 6 ++- .../LogarithmPlotter/js/objs/sequence.mjs | 5 +- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 5 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 4 +- 11 files changed, 76 insertions(+), 85 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs index c45b65e..039ba49 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -36,6 +36,28 @@ class ObjectsAPI extends Module { this.currentObjectsByName = {} } + /** + * Creates a new name for an object, based on the allowedLetters. + * If variables with each of the allowedLetters is created, a subscript + * number is added to the name. + * @param {string} allowedLetters + * @param {string} prefix - Prefix to the name. + * @return {string} New unused name for a new object. + */ + getNewName(allowedLetters, prefix='') { + // Allows to get a new name, based on the allowed letters, + // as well as adding a sub number when needs be. + let newid = 0 + let ret + do { + let letter = allowedLetters[newid % allowedLetters.length] + let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) + ret = prefix + letter + (num > 0 ? textsub(num-1) : '') + newid += 1 + } while(ret in this.currentObjectsByName) + return ret + } + /** * Renames an object from its old name to the new one. * @param {string} oldName - Current name of the object. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index f29710b..dc84bb0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -16,7 +16,8 @@ * along with this program. If not, see . */ -import { API as ObjectsCommonAPI } from "common.mjs" +import Objects from "../objects.mjs" +import { DrawableObject } from "common.mjs" import Point from "point.mjs" import Text from "text.mjs" import Function from "function.mjs" @@ -28,15 +29,29 @@ import XCursor from "xcursor.mjs" import Sequence from "sequence.mjs" import RepartitionFunction from "repartition.mjs" +/** + * Registers the object obj in the object list. + * @param {DrawableObject} obj - Object to be registered. + */ +function registerObject(obj) { + // Registers an object to be used in LogarithmPlotter. + if(obj.prototype instanceof DrawableObject) { + if(!Objects.types[obj.type()]) + Objects.types[obj.type()] = obj + } else { + console.error("Could not register object " + (obj?.type() ?? obj.constructor.name) + ", as it isn't a DrawableObject.") + } +} + if(Object.keys(Modules.Objects.types).length === 0) { - ObjectsCommonAPI.registerObject(Point) - ObjectsCommonAPI.registerObject(Text) - ObjectsCommonAPI.registerObject(Function) - ObjectsCommonAPI.registerObject(GainBode) - ObjectsCommonAPI.registerObject(PhaseBode) - ObjectsCommonAPI.registerObject(SommeGainsBode) - ObjectsCommonAPI.registerObject(SommePhasesBode) - ObjectsCommonAPI.registerObject(XCursor) - ObjectsCommonAPI.registerObject(Sequence) - ObjectsCommonAPI.registerObject(RepartitionFunction) -} \ No newline at end of file + registerObject(Point) + registerObject(Text) + registerObject(Function) + registerObject(GainBode) + registerObject(PhaseBode) + registerObject(SommeGainsBode) + registerObject(SommePhasesBode) + registerObject(XCursor) + registerObject(Sequence) + registerObject(RepartitionFunction) +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 173aef4..2c6270a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -24,59 +24,6 @@ import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" // This file contains the default data to be imported from all other objects -class ObjectsCommonAPI extends Module { - - constructor() { - super('ObjectsCommon', [ - Modules.Objects, - Modules.ExprParser, - Modules.Latex - ]) - } - - /** - * Creates a new name for an object, based on the allowedLetters. - * If variables with each of the allowedLetters is created, a subscript - * number is added to the name. - * @param {string} allowedLetters - * @param {string} prefix - Prefix to the name. - * @return {string} New unused name for a new object. - */ - getNewName(allowedLetters, prefix='') { - // Allows to get a new name, based on the allowed letters, - // as well as adding a sub number when needs be. - let newid = 0 - let ret - do { - let letter = allowedLetters[newid % allowedLetters.length] - let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) - ret = prefix + letter + (num > 0 ? textsub(num-1) : '') - newid += 1 - } while(ret in Objects.currentObjectsByName) - return ret - } - - /** - * Registers the object obj in the object list. - * @param {DrawableObject} obj - Object to be registered. - */ - registerObject(obj) { - // Registers an object to be used in LogarithmPlotter. - // This function is called from autoload.mjs - if(obj.prototype instanceof DrawableObject) { - if(!Objects.types[obj.type()]) - Objects.types[obj.type()] = obj - } else { - console.error("Could not register object " + (obj.type()) + ", as it isn't a DrawableObject.") - } - } -} - -/** @type {ObjectsCommonAPI} */ -Modules.ObjectsCommon = Modules.ObjectsCommon || new ObjectsCommonAPI() - -export const API = Modules.ObjectsCommon - /** * Class to extend for every type of object that * can be drawn on the canvas. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index fb9e93c..2448d50 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -17,7 +17,8 @@ */ import { textsub } from "../utils.mjs" -import { API as Common, ExecutableObject } from "common.mjs" +import Objects from "../objects.mjs" +import { ExecutableObject } from "common.mjs" import { parseDomain, Expression, SpecialDomain } from "../mathlib.mjs" import * as P from "../parameters.mjs" import Latex from "../math/latex.mjs" @@ -50,7 +51,7 @@ export default class Function extends ExecutableObject { expression = 'x', definitionDomain = 'RPE', destinationDomain = 'R', displayMode = 'application', labelPosition = 'above', labelX = 1, drawPoints = true, drawDashedLines = true) { - if(name == null) name = Common.getNewName('fghjqlmnopqrstuvwabcde') + if(name == null) name = Objects.getNewName('fghjqlmnopqrstuvwabcde') super(name, visible, color, labelContent) if(typeof expression == 'number' || typeof expression == 'string') expression = new Expression(expression.toString()) this.expression = expression diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index 938aa33..f86d747 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import { API as Common, ExecutableObject } from "common.mjs" +import { ExecutableObject } from "common.mjs" import Function from "function.mjs" import { API as HistoryAPI } from "../history/common.mjs" @@ -43,7 +43,7 @@ export default class GainBode extends ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { - if(name == null) name = Common.getNewName('G') + if(name == null) name = Objects.getNewName('G') if(name === 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). super(name, visible, color, labelContent) if(typeof om_0 == "string") { @@ -51,7 +51,7 @@ export default class GainBode extends ExecutableObject { om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) + om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), true, this.color, 'name']) HistoryAPI.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index 97fdae2..dcdd615 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -19,11 +19,11 @@ import { executeExpression, Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" - -import { API as Common, ExecutableObject } from "common.mjs" import { API as HistoryAPI } from "../history/common.mjs" import { CreateNewObject } from "../historylib.mjs" +import Latex from "../math/latex.mjs" + +import { ExecutableObject } from "common.mjs" export default class PhaseBode extends ExecutableObject { @@ -40,7 +40,7 @@ export default class PhaseBode extends ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) { - if(name == null) name = Common.getNewName('φ') + if(name == null) name = Objects.getNewName('φ') if(name === 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). super(name, visible, color, labelContent) if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString()) @@ -50,7 +50,7 @@ export default class PhaseBode extends ExecutableObject { om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), this.color, 'name']) + om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), this.color, 'name']) om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index f53eb72..66a493c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -18,8 +18,10 @@ import { Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import { API as Common, DrawableObject } from "common.mjs" + +import { DrawableObject } from "common.mjs" export default class Point extends DrawableObject { @@ -36,7 +38,7 @@ export default class Point extends DrawableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', x = 1, y = 0, labelPosition = 'above', pointStyle = '●') { - if(name == null) name = Common.getNewName('ABCDEFJKLMNOPQRSTUVW') + if(name == null) name = Objects.getNewName('ABCDEFJKLMNOPQRSTUVW') super(name, visible, color, labelContent) if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 2dd632d..89db16d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -16,10 +16,12 @@ * along with this program. If not, see . */ -import { API as Common, ExecutableObject } from "common.mjs" import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" +import { ExecutableObject } from "common.mjs" + export default class RepartitionFunction extends ExecutableObject { static type(){return 'Repartition'} @@ -46,7 +48,7 @@ export default class RepartitionFunction extends ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { - if(name == null) name = Common.getNewName('XYZUVW', "F_") + if(name == null) name = Objects.getNewName('XYZUVW', "F_") super(name, visible, color, labelContent) this.probabilities = probabilities this.labelPosition = labelPosition diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 10cb154..11f1be7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -19,8 +19,9 @@ import { Sequence as MathSequence, Domain } from "../mathlib.mjs" import * as P from "../parameters.mjs" import Latex from "../math/latex.mjs" +import Objects from "../objects.mjs" -import { API as Common, ExecutableObject } from "common.mjs" +import { ExecutableObject } from "common.mjs" import Function from "function.mjs" @@ -45,7 +46,7 @@ export default class Sequence extends ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', drawPoints = true, drawDashedLines = true, defaultExp = {1: "n"}, baseValues = {0: 0}, labelPosition = 'above', labelX = 1) { - if(name == null) name = Common.getNewName('uvwPSUVWabcde') + if(name == null) name = Objects.getNewName('uvwPSUVWabcde') super(name, visible, color, labelContent) this.drawPoints = drawPoints this.drawDashedLines = drawDashedLines diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index dfd0d27..fab2818 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -18,9 +18,10 @@ import { Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import { API as Common, DrawableObject } from "common.mjs" +import { DrawableObject } from "common.mjs" export default class Text extends DrawableObject { @@ -41,7 +42,7 @@ export default class Text extends DrawableObject { constructor(name = null, visible = true, color = null, labelContent = 'null', x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { - if(name == null) name = Common.getNewName('t') + if(name == null) name = Objects.getNewName('t') super(name, visible, color, labelContent) if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 2e3c6e0..4ab8b3d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Latex from "../math/latex.mjs" import Objects from "../objects.mjs" -import { API as Common, DrawableObject } from "common.mjs" +import { DrawableObject } from "common.mjs" export default class XCursor extends DrawableObject { @@ -45,7 +45,7 @@ export default class XCursor extends DrawableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', x = 1, targetElement = null, labelPosition = 'left', approximate = true, rounding = 3, displayStyle = '— — — — — — —', targetValuePosition = 'Next to target') { - if(name == null) name = Common.getNewName('X') + if(name == null) name = Objects.getNewName('X') super(name, visible, color, labelContent) this.approximate = approximate this.rounding = rounding From 370402f30370e49ae99719ddf53519b2a2cd0073 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 19:02:10 +0200 Subject: [PATCH 085/249] Fixing a particularly smelly bug in regard to X Cursor targetting causing issues with certain functions. --- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 4 +-- .../LogarithmPlotter/js/math/domain.mjs | 7 +++++ .../LogarithmPlotter/js/math/expression.mjs | 31 ++++++++++--------- .../LogarithmPlotter/js/math/sequence.mjs | 7 ++--- .../LogarithmPlotter/js/objs/common.mjs | 2 +- .../LogarithmPlotter/js/objs/phasebode.mjs | 2 +- .../LogarithmPlotter/js/objs/repartition.mjs | 2 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/js/utils.mjs | 2 -- 9 files changed, 32 insertions(+), 27 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 1e85788..d214be3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -291,7 +291,7 @@ class CanvasAPI extends Module { } else { for(let x = 1; x < this.axesSteps.x.maxDraw; x += 1) { let drawX = x*this.axesSteps.x.value - let txtX = this.axesSteps.x.expression.simplify(x).replace(/^\((.+)\)$/, '$1') + let txtX = this.axesSteps.x.expression.simplify(x).toString().replace(/^\((.+)\)$/, '$1') let textHeight = this.measureText(txtX).height this.drawVisibleText(txtX, this.x2px(drawX)-4, axisxpx+this.textsize/2+textHeight) this.drawVisibleText('-'+txtX, this.x2px(-drawX)-4, axisxpx+this.textsize/2+textHeight) @@ -301,7 +301,7 @@ class CanvasAPI extends Module { if(this.showygrad) { for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { let drawY = y*this.axesSteps.y.value - let txtY = this.axesSteps.y.expression.simplify(y).replace(/^\((.+)\)$/, '$1') + let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, '$1') textWidth = this._ctx.measureText(txtY).width this.drawVisibleText(txtY, axisypx-6-textWidth, this.y2px(drawY)+4+(10*(y===0))) if(y !== 0) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index e2606c4..22b0154 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -199,6 +199,7 @@ export class Range extends Domain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) @@ -257,16 +258,19 @@ export class SpecialDomain extends Domain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.isValid(x) } next(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.nextValue(x) } previous(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.prevValue(x) } @@ -315,6 +319,7 @@ export class DomainSet extends SpecialDomain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) for(let value of this.values) if(x === value.execute()) return true @@ -322,6 +327,7 @@ export class DomainSet extends SpecialDomain { } next(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) if(x < this.executedValues[0]) return this.executedValues[0] for(let i = 1; i < this.values.length; i++) { @@ -333,6 +339,7 @@ export class DomainSet extends SpecialDomain { } previous(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) if(x > this.executedValues[this.executedValues.length-1]) return this.executedValues[this.executedValues.length-1] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 66cd044..3a0ebb4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -29,8 +29,14 @@ export class Expression { throw new Error('Expression parser not initialized.') if(!Modules.Objects) throw new Error('Objects API not initialized.') - this.expr = Utils.exponentsToExpression(expr) - this.calc = Modules.ExprParser.parse(this.expr).simplify() + if(typeof expr === "string") { + this.expr = Utils.exponentsToExpression(expr) + this.calc = Modules.ExprParser.parse(this.expr).simplify() + } else { + // Passed an expression here directly. + this.calc = expr.simplify() + this.expr = expr.toString() + } this.cached = this.isConstant() this.cachedValue = null if(this.cached && this.allRequirementsFullfilled()) @@ -72,19 +78,8 @@ export class Expression { simplify(x) { let expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate() === 0) return '0' - let str = Utils.makeExpressionReadable(expr.toString()); - if(str !== undefined && str.match(/^\d*\.\d+$/)) { - if(str.split('.')[1].split('0').length > 7) { - // Likely rounding error - str = parseFloat(str.substring(0, str.length-1)).toString(); - } - } - return str - } - - duplicate() { - return new Expression(this.toEditableString()) + if(expr.evaluate() === 0) expr = '0' + return new Expression(expr) } toEditableString() { @@ -93,6 +88,12 @@ export class Expression { toString(forceSign=false) { let str = Utils.makeExpressionReadable(this.calc.toString()) + if(str !== undefined && str.match(/^\d*\.\d+$/)) { + if(str.split('.')[1].split('0').length > 7) { + // Likely rounding error + str = parseFloat(str.substring(0, str.length-1)).toString(); + } + } if(str[0] !== '-' && forceSign) str = '+' + str return str } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index a1a96cd..677d68e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -52,10 +52,9 @@ export class Sequence extends Expr.Expression { } simplify(n = 1) { - if(n in this.calcValues) - return Utils.makeExpressionReadable(this.calcValues[n].toString()) - this.cache(n) - return Utils.makeExpressionReadable(this.calcValues[n].toString()) + if(!(n in this.calcValues)) + this.cache(n) + return this.calcValues[n].toString() } cache(n = 1) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 2c6270a..01ab8eb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -380,7 +380,7 @@ export class ExecutableObject extends DrawableObject { * Returns the simplified expression string for a given x. * * @param {number} x - * @returns {string} + * @returns {string|Expression} */ simplify(x = 1) {return '0'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index dcdd615..09895d9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -88,7 +88,7 @@ export default class PhaseBode extends ExecutableObject { return this.om_0.y.toString() } else { let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() - return (new Expression(newExp)).toString() + return new Expression(newExp) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 89db16d..aeaf6e1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -81,7 +81,7 @@ export default class RepartitionFunction extends ExecutableObject { // Simplify returns the simplified string of the expression. simplify(x = 1) { - return this.execute(x) + return this.execute(x).toString() } getLabel() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 4ab8b3d..df8219b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -92,7 +92,7 @@ export default class XCursor extends DrawableObject { approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) } let simpl = t.simplify(this.x.toEditableString()) - return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.tokens ? Latex.expression(simpl.tokens) : simpl}` + + return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.latexMarkup ? simpl.latexMarkup : Latex.variable(simpl)}` + (this.approximate ? ' \\simeq ' + approx : '') } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs index 162e751..2e82be4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs @@ -272,8 +272,6 @@ export function makeExpressionReadable(str) { [/_([\d\w+-]+)/g, function(match, p1) { return textsub(p1) }], [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], [/(\d|\))×/g, '$1'], - //[/×(\d|\()/g, '$1'], - [/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], [/integral\((.+),\s?(.+),\s?["'](.+)["'],\s?["'](.+)["']\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` From 9b5356f8e7bf3e33b3eb457cd79ed43a1e18871a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 19:28:11 +0200 Subject: [PATCH 086/249] Fixing another bug with X Cursor relating to rounding to a superior precision than what the number originally has. --- .../ObjectLists/Editor/CustomPropertyList.qml | 10 +++++++--- .../LogarithmPlotter/Setting/TextSetting.qml | 15 +++++++++------ .../ad5001/LogarithmPlotter/js/objs/xcursor.mjs | 14 +++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 0fd529c..8f36f66 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -49,7 +49,7 @@ Repeater { */ property var positionPicker - readonly property var textTypes: ['Domain', 'string', 'number'] + readonly property var textTypes: ['Domain', 'string', 'number', 'int'] readonly property var comboBoxTypes: ['ObjectType', 'Enum'] readonly property var listTypes: ['List', 'Dict'] @@ -102,13 +102,16 @@ Repeater { height: 30 label: propertyLabel icon: `settings/custom/${propertyIcon}.svg` + min: propertyType == "int" ? 0 : -Infinity + isInt: propertyType == "int" isDouble: propertyType == "number" defValue: obj[propertyName] == null ? '' : obj[propertyName].toString() category: { return { "Domain": "domain", "string": "all", - "number": "all" + "number": "all", + "int": "all", }[propertyType] } onChanged: function(newValue) { @@ -116,7 +119,8 @@ Repeater { var newValueParsed = { "Domain": () => MathLib.parseDomain(newValue), "string": () => newValue, - "number": () => parseFloat(newValue) + "number": () => newValue, + "int": () => newValue }[propertyType]() // Ensuring old and new values are different to prevent useless adding to history. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 706281e..b0a054a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -127,12 +127,15 @@ Item { selectByMouse: true onEditingFinished: function() { if(insertButton.focus || insertPopup.focus) return - var value = text - if(control.isInt) - value = isNaN(parseInt(value)) ? control.min : Math.max(control.min,parseInt(value)) - if(control.isDouble) - value = isNaN(parseFloat(value)) ? control.min : Math.max(control.min,parseFloat(value)) - if(value != "" && value.toString() != defValue) { + let value = text + if(control.isInt) { + let parsed = parseInt(value) + value = isNaN(parsed) ? control.min : Math.max(control.min,parsed) + } else if(control.isDouble) { + let parsed = parseFloat(value) + value = isNaN(parsed) ? control.min : Math.max(control.min,parsed) + } + if(value !== "" && value.toString() != defValue) { control.changed(value) defValue = value.toString() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index df8219b..20732ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -33,7 +33,7 @@ export default class XCursor extends DrawableObject { [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject', true), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','approximate')]: 'boolean', - [QT_TRANSLATE_NOOP('prop','rounding')]: 'number', + [QT_TRANSLATE_NOOP('prop','rounding')]: 'int', [QT_TRANSLATE_NOOP('prop','displayStyle')]: new P.Enum( '— — — — — — —', '⸺⸺⸺⸺⸺⸺', @@ -77,8 +77,10 @@ export default class XCursor extends DrawableObject { var t = this.targetElement var approx = '' if(this.approximate) { - approx = t.execute(this.x.execute()) - approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) + approx = (t.execute(this.x.execute())) + let intLength = Math.round(approx).toString().length + let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1) + approx = approx.toPrecision(rounding + intLength) } return `${t.name}(${this.name}) = ${t.simplify(this.x.toEditableString())}` + (this.approximate ? ' ≈ ' + approx : '') @@ -88,8 +90,10 @@ export default class XCursor extends DrawableObject { let t = this.targetElement let approx = '' if(this.approximate) { - approx = t.execute(this.x.execute()) - approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) + approx = (t.execute(this.x.execute())) + let intLength = Math.round(approx).toString().length + let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1) + approx = approx.toPrecision(rounding + intLength) } let simpl = t.simplify(this.x.toEditableString()) return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.latexMarkup ? simpl.latexMarkup : Latex.variable(simpl)}` + From 8ab461ff72f4e453f85caea9a31b199e89205fab Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 19:29:02 +0200 Subject: [PATCH 087/249] Removing ObjectsCommon tests --- tests/python/test_main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/python/test_main.py b/tests/python/test_main.py index b15ee02..d8a56b6 100644 --- a/tests/python/test_main.py +++ b/tests/python/test_main.py @@ -102,8 +102,7 @@ class TestMain: # Check if modules have loaded assert js_globals.Modules.History.type() is not None assert js_globals.Modules.Latex.type() is not None - assert js_globals.Modules.ObjectsCommon.type() is not None assert js_globals.Modules.Canvas.type() is not None assert js_globals.Modules.IO.type() is not None assert js_globals.Modules.Objects.type() is not None - assert js_globals.Modules.Preferences.type() is not None \ No newline at end of file + assert js_globals.Modules.Preferences.type() is not None From 67190e1b4c27e12860b62925fa8a78c67b154780 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 22:14:52 +0200 Subject: [PATCH 088/249] Fixing rendering of LaTeX for position changing. --- .../qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index 15c3583..a376e2f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -100,7 +100,7 @@ export default class EditedPosition extends Action { Promise.all(this._renderPromises).then((rendered) => { // Rendered are (potentially) two HTML strings which are defined during rendering this.prevHTML = this.prevHTML ?? rendered[0] - this.nextHTML = this.prevHTML ?? rendered[1] + this.nextHTML = this.nextHTML ?? rendered[1] resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) }) }) From 2fc9bdee8652e75845344adf7a20094349e6cd20 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 22:58:37 +0200 Subject: [PATCH 089/249] Fixing import of Objects --- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs | 1 + .../qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs index 039ba49..ef45429 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -17,6 +17,7 @@ */ import { Module } from './modules.mjs' +import { textsub } from './utils.mjs' class ObjectsAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 01ab8eb..58a2d8d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -19,7 +19,6 @@ import { getRandomColor, textsub } from "../utils.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import {Module} from "../modules.mjs" import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" // This file contains the default data to be imported from all other objects From dd2ae7a2c844cdee66fe9fd18efc284976462cf7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 23:44:29 +0200 Subject: [PATCH 090/249] Implemented workaround for QTBUG-123819 (lupdate not parsing *.mjs files) Woohoo! No longer any duplicate and vanished translations (might cause a few that need to be checked, but translations should be properlerly reused). --- LogarithmPlotter/i18n/lp_de.ts | 303 +++++++++---- LogarithmPlotter/i18n/lp_en.ts | 303 +++++++++---- LogarithmPlotter/i18n/lp_es.ts | 320 +++++++++++--- LogarithmPlotter/i18n/lp_fr.ts | 331 +++++++++++--- LogarithmPlotter/i18n/lp_hu.ts | 309 +++++++++---- LogarithmPlotter/i18n/lp_nb_NO.ts | 564 +++++++++++++++++++++--- LogarithmPlotter/i18n/lp_template.ts | 634 ++++++++++++++++++++++++++- LogarithmPlotter/i18n/update.sh | 39 +- 8 files changed, 2372 insertions(+), 431 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c158a4d..51c132c 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter Über LogarithmPlotter @@ -89,39 +88,39 @@ &Settings - &Einstellungen + &Einstellungen Check for updates on startup - Beim Starten auf Updates prüfen + Beim Starten auf Updates prüfen Reset redo stack automaticly - Wiederherstellen-Stapel automatisch zurücksetzen + Wiederherstellen-Stapel automatisch zurücksetzen Enable LaTeX rendering - LaTeX-Rendering aktivieren + LaTeX-Rendering aktivieren Expression editor - Ausdruckseditor + Ausdruckseditor Automatically close parenthesises and brackets - Klammern automatisch schließen + Klammern automatisch schließen Enable syntax highlighting - Syntaxhervorhebung einschalten + Syntaxhervorhebung einschalten Enable autocompletion - Automatische Vervollständigung einschalten + Automatische Vervollständigung einschalten Color Scheme - Syntaktische Färbung + Syntaktische Färbung @@ -186,7 +185,7 @@ BoolSetting Check for updates on startup - Beim Starten auf Updates prüfen + Beim Starten auf Updates prüfen @@ -205,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -263,31 +262,31 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -351,36 +350,36 @@ Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. + Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. Check for updates on startup (requires online connectivity) - Beim Start nach Updates suchen (Online-Verbindung erforderlich) + Beim Start nach Updates suchen (Online-Verbindung erforderlich) Reset redo stack when a new action is added to history - Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird + Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird Enable LaTeX rendering - LaTeX-Rendering aktivieren + LaTeX-Rendering aktivieren Automatically close parenthesises and brackets in expressions - Automatisches Schließen von Klammern in Ausdrücken + Automatisches Schließen von Klammern in Ausdrücken Enable syntax highlighting for expressions - Syntaxhervorhebung für Ausdrücke einschalten + Syntaxhervorhebung für Ausdrücke einschalten Enable autocompletion interface in expression editor - Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren + Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren Color scheme: - Syntaktische Färbung Thema: + Syntaktische Färbung Thema: @@ -453,27 +452,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. @@ -513,23 +512,23 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -569,7 +568,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid - Am Gitter einrasten + Am Gitter einrasten @@ -613,21 +612,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Settings + X Zoom Zoom auf X + Y Zoom Zoom auf Y + Min X Minimum X + Max Y Maximum Y @@ -643,46 +646,55 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Minimum Y + X Axis Step X-Achsen-Schritt + Y Axis Step Y-Achsen-Schritt + Line width Linienbreite + Text size (px) Textgröße (px) + X Label Etikett der X-Achse + Y Label Etikett der Y-Achse + X Log scale Logarithmische Skala in X + Show X graduation X-Teilung anzeigen + Show Y graduation Y-Teilung anzeigen @@ -709,7 +721,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Close - Schließen + Schließen @@ -825,6 +837,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color + + %1 %2's color changed from %3 to %4. %1 %2 wurde von %3 bis %4 umgefärbt. @@ -832,22 +846,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) + Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + If you have latex enabled, you can use use latex markup in between $$ to create equations. Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -867,6 +886,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create + + New %1 %2 created. Neu %1 %2 erstellt. @@ -874,6 +895,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete + + %1 %2 deleted. %1 %2 gelöscht. @@ -881,10 +904,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty + %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -953,11 +978,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. @@ -982,41 +1007,49 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" + First argument to map is not a function. Der erste Parameter von map ist keine Formel. + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. @@ -1051,7 +1084,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1076,7 +1109,7 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler @@ -1098,29 +1131,35 @@ Ausdruck analysiert: %3 LogarithmPlotter - Fehler + Automatically close parenthesises and brackets - Klammern automatisch schließen + Klammern automatisch schließen + Enable syntax highlighting - Syntaxhervorhebung einschalten + Syntaxhervorhebung einschalten + Enable autocompletion - Automatische Vervollständigung einschalten + Automatische Vervollständigung einschalten + Color Scheme - Syntaktische Färbung + Syntaktische Färbung function + Function Funktion + Functions Funktionen @@ -1128,18 +1167,24 @@ Ausdruck analysiert: %3 gainbode + Bode Magnitude Bode-Magnitude + Bode Magnitudes Bode-Magnituden + + low-pass Tiefpass + + high-pass Hochpass @@ -1147,94 +1192,103 @@ Ausdruck analysiert: %3 general + Check for updates on startup - Beim Starten auf Updates prüfen + Beim Starten auf Updates prüfen + Reset redo stack automaticly - Wiederherstellen-Stapel automatisch zurücksetzen + Wiederherstellen-Stapel automatisch zurücksetzen + Enable LaTeX rendering - LaTeX-Rendering aktivieren + LaTeX-Rendering aktivieren historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. io Objects - Objekte + Objekte Settings - Einstellungen + Einstellungen History - Verlauf + Verlauf + Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. + Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. + Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. + Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. + Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: + Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! &Update - &Aktualisieren + &Aktualisieren &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -1294,6 +1348,8 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde name + + %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -1301,90 +1357,114 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters + above ↑ Über + below ↓ Unter + + left ← Links + + right → Rechts + above-left ↖ Oben links + above-right ↗ Oben rechts + below-left ↙ Unten links + below-right ↘ Unten rechts + center >|< Zentrum + top ↑ Über + bottom ↓ Unter + top-left ↖ Oben links + top-right ↗ Oben rechts + bottom-left ↙ Unten links + bottom-right ↘ Unten rechts + application Anwendung + function Funktion + high Hoch + low Tief + Next to target Neben dem Ziel + With label Mit Etikett + Hidden Versteckt @@ -1392,10 +1472,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde phasebode + Bode Phase Bode-Phase + Bode Phases Bode-Phasen @@ -1403,10 +1485,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde point + Point Punkt + Points Punkte @@ -1414,10 +1498,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde position + Position of %1 %2 set from "%3" to "%4". %1 %2 wurde von "%3" nach "%4" verschoben. + Position of %1 set from %2 to %3. %1 wurde von %2 nach %3 verschoben. @@ -1425,125 +1511,175 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde prop + expression Ausdruck + definitionDomain Definitionsbereich + destinationDomain Reichweite + + + + + + + + + + labelPosition Position des Etiketts + displayMode Anzeigemodus + + + + + + + labelX X-Position des Etiketts + + drawPoints Unentschiedene Punkte + + drawDashedLines Gestrichelte Linien anzeigen + + om_0 ω₀ + pass Pass + gain Größenordnung + omGraduation Teilung auf ω zeigen + phase Phase + unit Einheit + + + x X + + y Y + pointStyle Punkt-Stil + probabilities Wahrscheinlichkeiten + text Inhalt + disableLatex LaTeX-Rendering für diesen Text deaktivieren + targetElement Zielobjekt + approximate Ungefähren Wert anzeigen + rounding Rundung + displayStyle Stil + targetValuePosition Wertposition des Ziels + defaultExpression Standardausdruck + baseValues Initialisierungswerte color - Farbe + Farbe repartition + Repartition Verteilungsfunktion + Repartition functions Verteilungsfunktionen @@ -1551,10 +1687,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sequence + Sequence Folge + Sequences Folgen @@ -1562,14 +1700,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory + default Standardeinstellungen + general Allgemeine + editor Ausdruckseditor @@ -1577,6 +1718,8 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommegainsbode + + Bode Magnitudes Sum Bode-Magnituden Summe @@ -1584,6 +1727,8 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommephasesbode + + Bode Phases Sum Bode-Phasen Summe @@ -1591,24 +1736,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde text + Text Text + Texts Texte update - - An update for LogarithPlotter (v{}) is available. - Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - An update for LogarithmPlotter (v{}) is available. - + Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. @@ -1667,10 +1810,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility + + %1 %2 shown. %1 %2 angezeigt. + + %1 %2 hidden. %1 %2 ausgeblendet. @@ -1678,10 +1825,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde xcursor + X Cursor X Zeiger + X Cursors X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 4ce11d3..1febb33 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter About LogarithmPlotter @@ -89,39 +88,39 @@ &Settings - &Settings + &Settings Check for updates on startup - Check for updates on startup + Check for updates on startup Reset redo stack automaticly - Reset redo stack automatically + Reset redo stack automatically Enable LaTeX rendering - Enable LaTeX rendering + Enable LaTeX rendering Expression editor - Expression editor + Expression editor Automatically close parenthesises and brackets - Automatically close parentheses and brackets + Automatically close parentheses and brackets Enable syntax highlighting - Enable syntax highlighting + Enable syntax highlighting Enable autocompletion - Enable autocompletion + Enable autocompletion Color Scheme - Color Scheme + Color Scheme @@ -186,7 +185,7 @@ BoolSetting Check for updates on startup - Check for updates on startup + Check for updates on startup @@ -205,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -263,31 +262,31 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 @@ -351,36 +350,36 @@ Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Take a few seconds to configure LogarithmPlotter. + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Check for updates on startup (requires online connectivity) - Check for updates on startup (requires online connectivity) + Check for updates on startup (requires online connectivity) Reset redo stack when a new action is added to history - Reset redo stack when a new action is added to history + Reset redo stack when a new action is added to history Enable LaTeX rendering - Enable LaTeX rendering + Enable LaTeX rendering Automatically close parenthesises and brackets in expressions - Automatically close parentheses and brackets in expressions + Automatically close parentheses and brackets in expressions Enable syntax highlighting for expressions - Enable syntax highlighting for expressions + Enable syntax highlighting for expressions Enable autocompletion interface in expression editor - Enable autocompletion interface in expression editor + Enable autocompletion interface in expression editor Color scheme: - Color scheme: + Color scheme: @@ -453,27 +452,27 @@ These settings can be changed at any time from the "Settings" menu. Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. Loading file '%1'. - Loading file '%1'. + Loading file '%1'. Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. Invalid file provided. - Invalid file provided. + Invalid file provided. Could not save file: - Could not save file: + Could not save file: Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. @@ -513,23 +512,23 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -569,7 +568,7 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid - Snap to grid + Snap to grid @@ -613,21 +612,25 @@ These settings can be changed at any time from the "Settings" menu. Settings + X Zoom X Zoom + Y Zoom Y Zoom + Min X Min X + Max Y Max Y @@ -643,46 +646,55 @@ These settings can be changed at any time from the "Settings" menu.Min Y + X Axis Step X Axis Step + Y Axis Step Y Axis Step + Line width Line width + Text size (px) Text size (px) + X Label X Label + Y Label Y Label + X Log scale X Log scale + Show X graduation Show X graduation + Show Y graduation Show Y graduation @@ -709,7 +721,7 @@ These settings can be changed at any time from the "Settings" menu. Close - Close + Close @@ -825,6 +837,8 @@ These settings can be changed at any time from the "Settings" menu. color + + %1 %2's color changed from %3 to %4. %1 %2's color changed from %3 to %4. @@ -832,22 +846,27 @@ These settings can be changed at any time from the "Settings" menu. comment + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) + Note: Specify the probability for each value. Note: Specify the probability for each value. + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + If you have latex enabled, you can use use latex markup in between $$ to create equations. If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -867,6 +886,8 @@ These settings can be changed at any time from the "Settings" menu. create + + New %1 %2 created. New %1 %2 created. @@ -874,6 +895,8 @@ These settings can be changed at any time from the "Settings" menu. delete + + %1 %2 deleted. %1 %2 deleted. @@ -881,10 +904,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -953,11 +978,11 @@ These settings can be changed at any time from the "Settings" menu. Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. @@ -982,41 +1007,49 @@ These settings can be changed at any time from the "Settings" menu. + First argument to map is not a function. First argument to map is not a function. + Second argument to map is not an array. Second argument to map is not an array. + First argument to fold is not a function. First argument to fold is not a function. + Second argument to fold is not an array. Second argument to fold is not an array. + First argument to filter is not a function. First argument to filter is not a function. + Second argument to filter is not an array. Second argument to filter is not an array. + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. + Second argument to join is not an array. Second argument to join is not an array. @@ -1051,7 +1084,7 @@ These settings can be changed at any time from the "Settings" menu.Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1076,7 +1109,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error @@ -1098,29 +1131,35 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error + Automatically close parenthesises and brackets - Automatically close parentheses and brackets + Automatically close parentheses and brackets + Enable syntax highlighting - Enable syntax highlighting + Enable syntax highlighting + Enable autocompletion - Enable autocompletion + Enable autocompletion + Color Scheme - Color Scheme + Color Scheme function + Function Function + Functions Functions @@ -1128,18 +1167,24 @@ Evaluated expression: %3 gainbode + Bode Magnitude Bode Magnitude + Bode Magnitudes Bode Magnitudes + + low-pass low-pass + + high-pass high-pass @@ -1147,94 +1192,103 @@ Evaluated expression: %3 general + Check for updates on startup - Check for updates on startup + Check for updates on startup + Reset redo stack automaticly - Reset redo stack automatically + Reset redo stack automatically + Enable LaTeX rendering - Enable LaTeX rendering + Enable LaTeX rendering historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. io Objects - Objects + Objects Settings - Settings + Settings History - History + History + Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. + Loading file '%1'. - Loading file '%1'. + Loading file '%1'. + Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. + Invalid file provided. - Invalid file provided. + Invalid file provided. + Could not save file: - Could not save file: + Could not save file: + Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! &Update - &Update + &Update &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -1294,6 +1348,8 @@ Please make sure your LaTeX installation is correct and report a bug if so. name + + %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -1301,90 +1357,114 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters + above ↑ Above + below ↓ Below + + left ← Left + + right → Right + above-left ↖ Above left + above-right ↗ Above right + below-left ↙ Below left + below-right ↘ Below right + center >|< Center + top ↑ Top + bottom ↓ Bottom + top-left ↖ Top left + top-right ↗ Top right + bottom-left ↙ Bottom left + bottom-right ↘ Bottom right + application Application + function Function + high High + low Low + Next to target Next to target + With label With label + Hidden Hidden @@ -1392,10 +1472,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. phasebode + Bode Phase Bode Phase + Bode Phases Bode Phases @@ -1403,10 +1485,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. point + Point Point + Points Points @@ -1414,10 +1498,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. position + Position of %1 %2 set from "%3" to "%4". %1 %2 moved from "%3" to "%4". + Position of %1 set from %2 to %3. %1 moved from %2 to %3. @@ -1425,125 +1511,175 @@ Please make sure your LaTeX installation is correct and report a bug if so. prop + expression Expression + definitionDomain Domain + destinationDomain Range + + + + + + + + + + labelPosition Label position + displayMode Display mode + + + + + + + labelX Label's X position + + drawPoints Show points + + drawDashedLines Show dashed lines + + om_0 ω₀ + pass Pass + gain Magnitude gain + omGraduation Show graduation on ω₀ + phase Phase + unit Unit to use + + + x X + + y Y + pointStyle Point style + probabilities Probabilities list + text Content + disableLatex Disable LaTeX rendering for this text + targetElement Object to target + approximate Show approximate value + rounding Rounding + displayStyle Display style + targetValuePosition Target's value position + defaultExpression Default expression + baseValues Initialisation values color - Color + Color repartition + Repartition Distribution + Repartition functions Distribution functions @@ -1551,10 +1687,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. sequence + Sequence Sequence + Sequences Sequences @@ -1562,14 +1700,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory + general General + editor Expression Editor + default Default settings @@ -1577,6 +1718,8 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommegainsbode + + Bode Magnitudes Sum Bode Magnitudes Sum @@ -1584,6 +1727,8 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommephasesbode + + Bode Phases Sum Bode Phases Sum @@ -1591,24 +1736,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. text + Text Text + Texts Texts update - - An update for LogarithPlotter (v{}) is available. - An update for LogarithmPlotter (v{}) is available. - An update for LogarithmPlotter (v{}) is available. - + An update for LogarithmPlotter (v{}) is available. @@ -1667,10 +1810,14 @@ Please make sure your LaTeX installation is correct and report a bug if so. visibility + + %1 %2 shown. %1 %2 shown. + + %1 %2 hidden. %1 %2 hidden. @@ -1678,10 +1825,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. xcursor + X Cursor X Cursor + X Cursors X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index ae2702e..4806934 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter Sobre LogarithmPlotter @@ -89,35 +88,35 @@ &Settings - &Ajustes + &Ajustes Check for updates on startup - Comprobación de las actualizaciones al arrancar + Comprobación de las actualizaciones al arrancar Reset redo stack automaticly - Restablecer la pila de rehacer automáticamente + Restablecer la pila de rehacer automáticamente Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX Automatically close parenthesises and brackets - Cerrar automáticamente paréntesis y corchetes + Cerrar automáticamente paréntesis y corchetes Enable syntax highlighting - Activar el resaltado sintáctico + Activar el resaltado sintáctico Enable autocompletion - Activar autocompletar + Activar autocompletar Color Scheme - Esquema de colores + Esquema de colores @@ -171,7 +170,7 @@ Expression editor - Editor de expresiones + Editor de expresiones @@ -186,7 +185,7 @@ BoolSetting Check for updates on startup - Comprobación de las actualizaciones al arrancar + Comprobación de las actualizaciones al arrancar @@ -205,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Crear nuevo %1 - + Pick on graph Elegir en el gráfico @@ -263,31 +262,31 @@ EditorDialog Label content - Contenido de la etiqueta + Contenido de la etiqueta null - nulo + nulo name - nombre + nombre name + value - nombre + valor + nombre + valor + Create new %1 - + Crear nuevo %1 + + Crear nuevo %1 Edit properties of %1 %2 - Editar propiedades de %1 %2 + Editar propiedades de %1 %2 Name - Nombre + Nombre @@ -350,7 +349,7 @@ Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX @@ -374,33 +373,33 @@ Color scheme: - Esquema de colores: + Esquema de colores: Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Tómate unos segundos para configurar LogarithmPlotter. + Tómate unos segundos para configurar LogarithmPlotter. Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes”. Check for updates on startup (requires online connectivity) - Buscar actualizaciones al iniciar (requiere conexión a Internet) + Buscar actualizaciones al iniciar (requiere conexión a Internet) Reset redo stack when a new action is added to history - Restablecer el historial de deshacer cuando se agrega una nueva acción + Restablecer el historial de deshacer cuando se agrega una nueva acción Automatically close parenthesises and brackets in expressions - Cerrar automáticamente paréntesis y corchetes en expresiones + Cerrar automáticamente paréntesis y corchetes en expresiones Enable autocompletion interface in expression editor - Habilitar el autocompletado en el editor de expresiones + Habilitar el autocompletado en el editor de expresiones Enable syntax highlighting for expressions - Habilitar el resaltado de sintaxis para expresiones + Habilitar el resaltado de sintaxis para expresiones @@ -468,27 +467,27 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Unknown object type: %1. - Tipo de objeto desconocido: %1 . + Tipo de objeto desconocido: %1 . Saved plot to '%1'. - Gráfico guardado en '%1'. + Gráfico guardado en '%1'. Loading file '%1'. - Cargando el archivo '%1'. + Cargando el archivo '%1'. Invalid file provided. - Se ha proporcionado un archivo no válido. + Se ha proporcionado un archivo no válido. Could not save file: - No se ha podido guardar el archivo: + No se ha podido guardar el archivo: Loaded file '%1'. - Archivo cargado '%1'. + Archivo cargado '%1'. @@ -513,23 +512,23 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Delete %1 %2 - Borrar %1 %2 + Borrar %1 %2 Hide %1 %2 - Ocultar %1 %2 + Ocultar %1 %2 Show %1 %2 - Mostrar %1 %2 + Mostrar %1 %2 Set %1 %2 position - Fijar la posición %1 %2 + Fijar la posición %1 %2 Pick new color for %1 %2 - Elegir nuevo color para %1 %2 + Elegir nuevo color para %1 %2 @@ -599,7 +598,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Snap to grid - Ajustar a la cuadrícula + Ajustar a la cuadrícula @@ -613,21 +612,25 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Settings + X Zoom + Y Zoom + Min X + Max Y @@ -643,46 +646,55 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + X Axis Step Paso por eje X + Y Axis Step Paso por eje Y + Line width Anchura de la línea + Text size (px) Tamaño del texto (px) + X Label + Y Label + X Log scale Escala logarítmica en X + Show X graduation Mostrar graduación del eje X + Show Y graduation Mostrar graduación del eje Y @@ -709,7 +721,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Close - Cerrar + Cerrar @@ -825,6 +837,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes color + + %1 %2's color changed from %3 to %4. El color de %1 %2 cambió de %3 a %4. @@ -832,22 +846,27 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes comment + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) + Note: Specify the probability for each value. Nota: Especifique la probabilidad para cada valor. + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… + If you have latex enabled, you can use use latex markup in between $$ to create equations. Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. @@ -867,6 +886,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes create + + New %1 %2 created. Se ha creado un nuevo %1 %2. @@ -874,6 +895,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes delete + + %1 %2 deleted. %1 %2 borrados. @@ -881,10 +904,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes editproperty + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 cambió de "%4" a "%5". + %1 of %2 changed from %3 to %4. %1 de %2 ha cambiado de %3 a %4. @@ -974,41 +999,49 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + First argument to map is not a function. El primer argumento de map no es una función. + Second argument to map is not an array. El segundo argumento de map no es una matriz. + First argument to fold is not a function. El primer argumento de fold no es una función. + Second argument to fold is not an array. El segundo argumento de fold no es una matriz. + First argument to filter is not a function. El primer argumento del filtro no es una función. + Second argument to filter is not an array. El segundo argumento del filtro no es una matriz. + Second argument to indexOf is not a string or array. El segundo argumento de indexOf no es una cadena ni una matriz. + Second argument to join is not an array. El segundo argumento para unirse no es una matriz. @@ -1043,7 +1076,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Dependencia circular detectada. Los objetos %1 dependen de %2. - + Error while parsing expression for property %1: %2 @@ -1066,17 +1099,17 @@ Deshaciendo el último cambio. Function definition is not permitted. - No se permite la definición de las funciones. + No se permite la definición de las funciones. Expected variable for assignment. - Variable de asignación esperada. + Variable de asignación esperada. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Error de procesamiento @@ -1097,14 +1130,36 @@ Expresión evaluada: %3 LogarithmPlotter - Drawing error + + + Automatically close parenthesises and brackets + Cerrar automáticamente paréntesis y corchetes + + + + Enable syntax highlighting + Activar el resaltado sintáctico + + + + Enable autocompletion + Activar autocompletar + + + + Color Scheme + Esquema de colores + function + Function Función + Functions Funciones @@ -1112,18 +1167,24 @@ Expresión evaluada: %3 gainbode + + high-pass Filtro paso alto + + low-pass Filtro paso bajo + Bode Magnitude Magnitud de Bode + Bode Magnitudes Magnitudes de Bode @@ -1131,70 +1192,103 @@ Expresión evaluada: %3 general + Check for updates on startup - Comprobación de las actualizaciones al arrancar + Comprobación de las actualizaciones al arrancar + Reset redo stack automaticly - Restablecer la pila de rehacer automáticamente + Restablecer la pila de rehacer automáticamente + Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX historylib %1 %2 deleted. - %1 %2 borrados. + %1 %2 borrados. %1 %2 shown. - Se muestra %1 %2. + Se muestra %1 %2. %1 %2 hidden. - Se oculta %1 %2. + Se oculta %1 %2. New %1 %2 created. - Se ha creado un nuevo %1 %2. + Se ha creado un nuevo %1 %2. Name of %1 %2 changed to %3. - El nombre de %1 %2 se ha cambiado por %3. + El nombre de %1 %2 se ha cambiado por %3. %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 cambió de "%4" a "%5". + %1 de %2 %3 cambió de "%4" a "%5". io History - Historial + Historial Copied plot screenshot to clipboard! - ¡Captura de pantalla del gráfico copiada al portapapeles! + ¡Captura de pantalla del gráfico copiada al portapapeles! &Update - &Actualizar + &Actualizar &Update LogarithmPlotter - &Actualizar LogarithmPlotter + &Actualizar LogarithmPlotter Settings - Ajustes + Ajustes Objects - Objetos + Objetos + + + + Saved plot to '%1'. + Gráfico guardado en '%1'. + + + + Loading file '%1'. + Cargando el archivo '%1'. + + + + Unknown object type: %1. + Tipo de objeto desconocido: %1 . + + + + Invalid file provided. + Se ha proporcionado un archivo no válido. + + + + Could not save file: + No se ha podido guardar el archivo: + + + + Loaded file '%1'. + Archivo cargado '%1'. @@ -1254,6 +1348,8 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u name + + %1 %2 renamed to %3. %1 %2 ha sido renombrado a %3. @@ -1261,90 +1357,114 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u parameters + below ↓ Abajo + + left ← Izquierda + above-left ↖ Arriba a la izquierda + below-left ↙ Abajo a la izquierda + below-right ↘ Arriba a la derecha + center >|< Centro + top ↑ Arriba + above ↑ Arriba + + right → Derecha + above-right ↗ Arriba a la derecha + bottom ↓ Bajar + top-right ↗ Arriba a la derecha + application Aplicación + Next to target Próximo al objetivo + top-left ↖ Arriba a la izquierda + bottom-left ↙ Abajo a la izquierda + bottom-right ↘ Abajo a la derecha + function Función + high Alto + low Bajo + With label Con etiqueta + Hidden Oculto @@ -1352,10 +1472,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u phasebode + Bode Phase Fase de Bode + Bode Phases Fases de Bode @@ -1363,10 +1485,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u point + Point Punto + Points Puntos @@ -1374,10 +1498,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u position + Position of %1 %2 set from "%3" to "%4". %1 %2 movido de "%3" a "%4". + Position of %1 set from %2 to %3. %1 movido de %2 a %3. @@ -1385,114 +1511,162 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u prop + expression Expresión + definitionDomain Dominio + + om_0 ω₀ + disableLatex Desactivar el renderizado LaTeX para este texto + rounding Redondeo + + + + + + + labelX Posición de la etiqueta en X + + drawPoints Mostrar puntos + + drawDashedLines Mostrar líneas discontinuas + destinationDomain Rango + + + + + + + + + + labelPosition Posición de la etiqueta + displayMode Modo de visualización + pass Pasar + gain Incremento de magnitud + unit Unidad a usar + + y Y + omGraduation Mostrar la graduación en ω₀ + phase Fase + + + x X + pointStyle Estilo de puntos + text Contenido + probabilities Lista de probabilidades + targetElement Objeto de destino + approximate Mostrar valor aproximado + displayStyle Estilo de visualización + targetValuePosition Posición del valor del objetivo + defaultExpression Expresión predeterminada color - Color + Color + baseValues Valores de inicialización @@ -1500,10 +1674,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u repartition + Repartition Distribución + Repartition functions Funciones de distribución @@ -1511,10 +1687,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u sequence + Sequences Secuencias + Sequence Secuencia @@ -1522,14 +1700,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u settingCategory + general General + editor Editor de expresiones + default Ajustes por defecto @@ -1537,6 +1718,8 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u sommegainsbode + + Bode Magnitudes Sum Suma de las Magnitudes de Bode @@ -1544,6 +1727,8 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u sommephasesbode + + Bode Phases Sum Suma de las fases de Bode @@ -1551,10 +1736,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u text + Texts Textos + Text Texto @@ -1563,12 +1750,11 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u update An update for LogarithPlotter (v{}) is available. - Una actualización para LogarithmPlotter (v{}) está disponible. An update for LogarithmPlotter (v{}) is available. - + Una actualización para LogarithmPlotter (v{}) está disponible. @@ -1627,10 +1813,14 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u visibility + + %1 %2 shown. Se muestra %1 %2. + + %1 %2 hidden. Se oculta %1 %2. @@ -1638,10 +1828,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u xcursor + X Cursor Cursor X + X Cursors Cursores X diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 5794777..b5eb9e0 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter À propos de LogarithmPlotter @@ -89,40 +88,40 @@ &Settings - &Paramètres + &Paramètres Check for updates on startup - Vérifier la présence de mise à jour au démarrage + Vérifier la présence de mise à jour au démarrage Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. - Réinitialiser la pile d'action "Rétablir" automatiquement + Réinitialiser la pile d'action "Rétablir" automatiquement Enable LaTeX rendering - Activer le rendu LaTeX + Activer le rendu LaTeX Expression editor - Éditeur de formule + Éditeur de formule Automatically close parenthesises and brackets - Fermer automatiquement les parenthèses et les crochets + Fermer automatiquement les parenthèses et les crochets Enable syntax highlighting - Activer la coloration syntaxique + Activer la coloration syntaxique Enable autocompletion - Activer l'autocomplétion + Activer l'autocomplétion Color Scheme - Coloration Syntaxique + Coloration Syntaxique @@ -187,7 +186,7 @@ BoolSetting Check for updates on startup - Vérifier la présence de mise à jour au démarrage + Vérifier la présence de mise à jour au démarrage @@ -206,13 +205,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -264,32 +263,32 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -353,28 +352,28 @@ Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Prenez quelques secondes pour configurer LogarithmPlotter. + Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". Enable LaTeX rendering - Activer le rendu LaTeX + Activer le rendu LaTeX Automatically close parenthesises and brackets in expressions - Fermer automatiquement les parenthèses et les crochets dans les formules + Fermer automatiquement les parenthèses et les crochets dans les formules Enable syntax highlighting for expressions - Activer la coloration syntaxique des formules + Activer la coloration syntaxique des formules Enable autocompletion interface in expression editor - Activer l'interface d'autocomplétion dans l'éditeur de formules + Activer l'interface d'autocomplétion dans l'éditeur de formules Color scheme: - Thème de coloration syntaxique : + Thème de coloration syntaxique : @@ -398,11 +397,11 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Check for updates on startup (requires online connectivity) - Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) + Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) Reset redo stack when a new action is added to history - Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique + Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -455,27 +454,27 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. @@ -515,23 +514,23 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -571,12 +570,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Snap to grid - Placement sur la grille + Placement sur la grille Snap to grid: - Aligner sur la grille : + Placer sur la grille : @@ -615,21 +614,25 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Settings + X Zoom Zoom en X + Y Zoom Zoom en Y + Min X Min X + Max Y Max Y @@ -645,46 +648,55 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Min Y + X Axis Step Pas de l'axe X + Y Axis Step Pas de l'axe Y + Line width Taille des lignes + Text size (px) Taille du texte (px) + X Label Label de l'axe X + Y Label Label de l'axe Y + X Log scale Échelle logarithmique en X + Show X graduation Montrer la graduation de l'axe X + Show Y graduation Montrer la graduation de l'axe Y @@ -711,7 +723,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Close - Fermer + Fermer @@ -827,6 +839,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P color + + %1 %2's color changed from %3 to %4. %1 %2 a été re colorisé du %3 au %4. @@ -834,23 +848,28 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P comment + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) + Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + If you have latex enabled, you can use use latex markup in between $$ to create equations. Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -870,6 +889,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P create + + New %1 %2 created. Nouvel objet %1 %2 créé. @@ -877,6 +898,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P delete + + %1 %2 deleted. %1 %2 supprimé(e). @@ -884,10 +907,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P editproperty + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -956,11 +981,11 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. @@ -985,41 +1010,49 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P + First argument to map is not a function. Le premier argument de map n'est pas une fonction. + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. @@ -1054,7 +1087,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1079,7 +1112,7 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe @@ -1100,14 +1133,36 @@ Formule analysée : %3 LogarithmPlotter - Drawing error LogarithmPlotter - Erreur + + + Automatically close parenthesises and brackets + Fermer automatiquement les parenthèses et les crochets + + + + Enable syntax highlighting + Activer la coloration syntaxique + + + + Enable autocompletion + Activer l'autocomplétion + + + + Color Scheme + Coloration Syntaxique + function + Function Fonction + Functions Fonctions @@ -1115,77 +1170,128 @@ Formule analysée : %3 gainbode + Bode Magnitude Gain de Bode + Bode Magnitudes Gains de Bode + + low-pass passe-bas + + high-pass passe-haut general + + + Check for updates on startup + Vérifier la présence de mise à jour au démarrage + + + + Reset redo stack automaticly + Réinitialiser la pile d'action "Rétablir" automatiquement + + + + Enable LaTeX rendering + Activer le rendu LaTeX + historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. io Objects - Objets + Objets Settings - Paramètres + Paramètres History - Historique + Historique Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! &Update - &Mise à jour + &Mise à jour &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter + + + + Saved plot to '%1'. + Graphe sauvegardé dans '%1'. + + + + Loading file '%1'. + Chargement du fichier '%1'. + + + + Unknown object type: %1. + Type d'objet inconnu : %1. + + + + Invalid file provided. + Fichier fourni invalide. + + + + Could not save file: + Impossible de sauvegarder le fichier : + + + + Loaded file '%1'. + Fichier '%1' chargé. @@ -1245,6 +1351,8 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c name + + %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -1252,90 +1360,114 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters + above ↑ Au dessus + below ↓ En dessous + + left ← À gauche + + right → À droite + above-left ↖ Au dessus à gauche + above-right ↗ Au dessus à droite + below-left ↙ En dessous à gauche + below-right ↘ En dessous à droite + center >|< Centré + top ↑ Au dessus + bottom ↓ En dessous + top-left ↖ Au dessus à gauche + top-right ↗ Au dessus à droite + bottom-left ↙ En dessous à gauche + bottom-right ↘ En dessous à droite + application Application + function Fonction + high Haut + low Bas + Next to target A côté de la cible + With label Avec l'étiquette + Hidden Caché @@ -1343,10 +1475,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c phasebode + Bode Phase Phase de Bode + Bode Phases Phases de Bode @@ -1354,10 +1488,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c point + Point Point + Points Points @@ -1365,10 +1501,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c position + Position of %1 %2 set from "%3" to "%4". %1 %2 a été déplacé depuis "%3" vers "%4". + Position of %1 set from %2 to %3. %1 a été déplacé depuis %2 vers %3. @@ -1376,125 +1514,175 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c prop + expression Formule + definitionDomain Domaine de définition + destinationDomain Portée + + + + + + + + + + labelPosition Position de l'étiquette + displayMode Mode d'affichage + + + + + + + labelX Position en X de l'étiquette + + drawPoints Afficher les points + + drawDashedLines Afficher les pointillés + + om_0 ω₀ + pass Passe + gain Gain + omGraduation Afficher la graduation sur ω₀ + phase Phase + unit Unité de la phase + + + x X + + y Y + pointStyle Style du point + probabilities Liste de probabilités + text Contenu + disableLatex Désactiver le rendu LaTeX pour ce texte + targetElement Objet à cibler + approximate Afficher la valeur approximative + rounding Arrondi + displayStyle Style d'affichage + targetValuePosition Position de la valeur de la cible + defaultExpression Formule par défaut + baseValues Valeurs d'initialisation color - Couleur + Couleur repartition + Repartition Répartition + Repartition functions Fonctions de répartition @@ -1502,10 +1690,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sequence + Sequence Suite + Sequences Suites @@ -1513,14 +1703,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c settingCategory + general Général + editor Éditeur de formule + default Paramètres par défaut @@ -1528,6 +1721,8 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommegainsbode + + Bode Magnitudes Sum Sommes des gains de Bode @@ -1535,6 +1730,8 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommephasesbode + + Bode Phases Sum Somme des phases de Bode @@ -1542,24 +1739,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c text + Text Texte + Texts Textes update - - An update for LogarithPlotter (v{}) is available. - Une mise à jour de LogarithmPlotter (v{}) est disponible. - An update for LogarithmPlotter (v{}) is available. - + Une mise à jour de LogarithmPlotter (v{}) est disponible. @@ -1618,10 +1813,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility + + %1 %2 shown. %1 %2 affiché(e). + + %1 %2 hidden. %1 %2 cachée(e). @@ -1629,10 +1828,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c xcursor + X Cursor Curseur X + X Cursors Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index e21aa92..7f5fcea 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter LogarithmPlotter névjegye @@ -89,39 +88,39 @@ &Settings - &Beállítások + &Beállítások Check for updates on startup - Frissítések keresése indításkor + Frissítések keresése indításkor Reset redo stack automaticly - Ismétlési verem önműködő visszaállítása + Ismétlési verem önműködő visszaállítása Enable LaTeX rendering - LaTeX-megjelenítés engedélyezése + LaTeX-megjelenítés engedélyezése Expression editor - Kifejezésszerkesztő + Kifejezésszerkesztő Automatically close parenthesises and brackets - Zárójelek automatikus bezárása + Zárójelek automatikus bezárása Enable syntax highlighting - Mondattani kiemelés engedélyezése + Mondattani kiemelés engedélyezése Enable autocompletion - Automatikus befejezés engedélyezése + Automatikus befejezés engedélyezése Color Scheme - Színséma + Színséma @@ -186,7 +185,7 @@ BoolSetting Check for updates on startup - Frissítések keresése indításkor + Frissítések keresése indításkor @@ -205,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -263,31 +262,31 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -351,36 +350,36 @@ Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Szánjon néhány másodpercet a LogarithmPlotter beállításához. + Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Check for updates on startup (requires online connectivity) - Frissítések keresése indításkor (online kapcsolat szükséges) + Frissítések keresése indításkor (online kapcsolat szükséges) Reset redo stack when a new action is added to history - Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez + Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez Enable LaTeX rendering - LaTeX-megjelenítés engedélyezése + LaTeX-megjelenítés engedélyezése Automatically close parenthesises and brackets in expressions - Zárójelek automatikus bezárása a kifejezésekben + Zárójelek automatikus bezárása a kifejezésekben Enable syntax highlighting for expressions - Mondattani kiemelés engedélyezése a kifejezésekhez + Mondattani kiemelés engedélyezése a kifejezésekhez Enable autocompletion interface in expression editor - Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben + Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben Color scheme: - Színséma: + Színséma: @@ -453,27 +452,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. @@ -513,23 +512,23 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -569,7 +568,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid - Rácshoz illesztés + Rácshoz illesztés @@ -613,21 +612,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Settings + X Zoom X-nagyítás + Y Zoom Y-nagyítás + Min X Legkisebb X + Max Y Legnagyobb Y @@ -643,46 +646,55 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Legkisebb Y + X Axis Step X tengely lépésköze + Y Axis Step Y tengely lépésköze + Line width Vonalvastagság + Text size (px) Szövegméret (képpont) + X Label X címke + Y Label Y címke + X Log scale X tengely logaritmikus skálával + Show X graduation X érettségi megjelenítése + Show Y graduation Y érettségi megjelenítése @@ -709,7 +721,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Close - Kész + Kész @@ -825,6 +837,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color + + %1 %2's color changed from %3 to %4. %1 %2 színe %3-ról %4-re változott. @@ -832,22 +846,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) + Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + If you have latex enabled, you can use use latex markup in between $$ to create equations. Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -867,6 +886,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create + + New %1 %2 created. Új %1 %2 létrehozva. @@ -874,6 +895,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. delete + + %1 %2 deleted. %1 %2 törölve. @@ -881,10 +904,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty + %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -953,11 +978,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. @@ -982,41 +1007,49 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. + First argument to map is not a function. Az első leképezési argumentum nem függvény. + Second argument to map is not an array. A második leképezési argumentum nem tömb. + First argument to fold is not a function. Az első behajtási argumentum nem függvény. + Second argument to fold is not an array. A második behajtási argumentum nem tömb. + First argument to filter is not a function. Az első szűrési argumentum nem függvény. + Second argument to filter is not an array. A második szűrési argumentum nem tömb. + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. @@ -1051,7 +1084,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1076,7 +1109,7 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba @@ -1098,29 +1131,35 @@ Kiértékelt kifejezés: %3 LogarithmPlotter - Rajzolási hiba + Automatically close parenthesises and brackets - Zárójelek automatikus bezárása + Zárójelek automatikus bezárása + Enable syntax highlighting - Mondattani kiemelés engedélyezése + Mondattani kiemelés engedélyezése + Enable autocompletion - Automatikus befejezés engedélyezése + Automatikus befejezés engedélyezése + Color Scheme - Színséma + Színséma function + Function Függvény + Functions Függvények @@ -1128,18 +1167,24 @@ Kiértékelt kifejezés: %3 gainbode + Bode Magnitude Bode-nagyságrend + Bode Magnitudes Bode-nagyságrendek + + low-pass aluláteresztő + + high-pass felüláteresztő @@ -1147,94 +1192,103 @@ Kiértékelt kifejezés: %3 general + Check for updates on startup - Frissítések keresése indításkor + Frissítések keresése indításkor + Reset redo stack automaticly - Ismétlési verem önműködő visszaállítása + Ismétlési verem önműködő visszaállítása + Enable LaTeX rendering - LaTeX-megjelenítés engedélyezése + LaTeX-megjelenítés engedélyezése historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. Name of %1 %2 changed to %3. - %1 %2 neve a következőre módosult: %3. + %1 %2 neve a következőre módosult: %3. io Settings - Beállítások + Beállítások History - Előzmények + Előzmények + Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. + Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. + Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. + Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. + Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: + Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! &Update - &Frissítés + &Frissítés &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése Objects - Objektumok + Objektumok @@ -1290,6 +1344,8 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents name + + %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -1297,90 +1353,114 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters + above ↑ Felett + below ↓ Alatt + + left ← Balra + + right → Jobbra + above-left ↖ Felett, balra + above-right ↗ Felett, jobbra + below-left ↙ Alatt, balra + below-right ↘ Alatt, jobbra + center >|< Középre + top ↑ Felső + bottom ↓ Alsó + top-left ↖ Bal felső + top-right ↗ Jobb felső + bottom-left ↙ Bal alsó + bottom-right ↘ Jobb alsó + application Alkalmazás + function Függvény + high Magas + low Alul + Next to target Cél mellé + With label Címkével + Hidden Rejtett @@ -1388,10 +1468,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents phasebode + Bode Phase Bode-fázis + Bode Phases Bode-fázisok @@ -1399,10 +1481,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents point + Point Pont + Points Pontok @@ -1410,10 +1494,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents position + Position of %1 %2 set from "%3" to "%4". %1 %2 áthelyezve innen: „%3” ide: „%4”. + Position of %1 set from %2 to %3. %1 áthelyezve innen: %2 ide: %3. @@ -1421,125 +1507,175 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents prop + expression Kifejezés + definitionDomain Abszcissza tartomány + destinationDomain Ordináta tartomány + + + + + + + + + + labelPosition Címke helyzete + displayMode Megjelenítési mód + + + + + + + labelX Címke X helyzete + + drawPoints Pontok megjelenítése + + drawDashedLines Szaggatott vonalak megjelenítése + + om_0 ω₀ + pass Áteresztő + gain Nagyságrend nyeresége + omGraduation ω₀ érettségi megjelenítése + phase Fázis + unit Egység használata + + + x X + + y Y + pointStyle Pontstílus + probabilities Valószínűségek listája + text Tartalom + disableLatex LaTeX-megjelenítés letiltása ennél a szövegnél + targetElement Tárgycél + approximate Hozzávetőleges érték megjelenítése + rounding Kerekítés + displayStyle Megjelenítési stílus + targetValuePosition Cél értékpozíciója + defaultExpression Alapértelmezett kifejezés + baseValues Kezdeményezési értékek color - Szín + Szín repartition + Repartition Elosztás + Repartition functions Elosztási függvények @@ -1547,10 +1683,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sequence + Sequence Sorozat + Sequences Sorozatok @@ -1558,17 +1696,26 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory + + general + + + + editor Kifejezésszerkesztő + default - Alapértelmezett ábra + Alapértelmezett ábra sommegainsbode + + Bode Magnitudes Sum Bode-nagyságrendek összege @@ -1576,6 +1723,8 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommephasesbode + + Bode Phases Sum Bode-fázisok összege @@ -1583,24 +1732,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents text + Text Szöveg + Texts Szövegek update - - An update for LogarithPlotter (v{}) is available. - Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - An update for LogarithmPlotter (v{}) is available. - + Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. @@ -1659,10 +1806,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility + + %1 %2 shown. %1 %2 megjelenítve. + + %1 %2 hidden. %1 %2 rejtve. @@ -1670,10 +1821,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents xcursor + X Cursor X kurzor + X Cursors X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index ca36bf7..4f7ce95 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter Om @@ -89,15 +88,15 @@ &Settings - &Innstillinger + &Innstillinger Check for updates on startup - Se etter nye versjoner ved programstart + Se etter nye versjoner ved programstart Reset redo stack automaticly - Tilbakestill angrehistorikk automatisk + Tilbakestill angrehistorikk automatisk @@ -162,7 +161,7 @@ BoolSetting Check for updates on startup - Se etter nye versjoner ved programstart + Se etter nye versjoner ved programstart @@ -181,13 +180,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -239,31 +238,31 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -327,16 +326,16 @@ Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Sett opp LogarithmPlotter. + Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Check for updates on startup (requires online connectivity) - Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) + Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) Reset redo stack when a new action is added to history - Tilbakesitll angrehistorikk når en ny handling legges til + Tilbakesitll angrehistorikk når en ny handling legges til @@ -409,27 +408,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». @@ -469,11 +468,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -481,11 +480,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -525,7 +524,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid - Fest til rutenett + Fest til rutenett @@ -569,21 +568,25 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Settings + X Zoom X-forstørrelse + Y Zoom Y-forstørrelse + Min X Min. X + Max Y Maks. Y @@ -599,46 +602,55 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Min. Y + X Axis Step X-aksesteg + Y Axis Step Y-aksesteg + Line width Linjebredde + Text size (px) Tekststørrelse (piksler) + X Label Navn på X-akse + Y Label Navn på Y-akse + X Log scale Logaritmisk skala i x + Show X graduation Vis X-inndeling + Show Y graduation Vis Y-inndeling @@ -774,6 +786,43 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + color + + + + %1 %2's color changed from %3 to %4. + + + + + comment + + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + + + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + + + + + Note: Specify the probability for each value. + + + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + + control @@ -789,22 +838,32 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create + + New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. delete + + %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. editproperty + %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». + + + + %1 of %2 changed from %3 to %4. + @@ -892,41 +951,49 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + First argument to map is not a function. + Second argument to map is not an array. + First argument to fold is not a function. + Second argument to fold is not an array. + First argument to filter is not a function. + Second argument to filter is not an array. + Second argument to indexOf is not a string or array. + Second argument to join is not an array. @@ -961,7 +1028,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Error while parsing expression for property %1: %2 @@ -980,7 +1047,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -998,14 +1065,36 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + + Color Scheme + + function + Function Funksjon + Functions Funksjoner @@ -1013,18 +1102,24 @@ Evaluated expression: %3 gainbode + Bode Magnitude Bode-magnitude + Bode Magnitudes Bode-magnituder + + low-pass lavpass + + high-pass høypass @@ -1032,86 +1127,99 @@ Evaluated expression: %3 general + Check for updates on startup - Se etter nye versjoner ved programstart + Se etter nye versjoner ved programstart + Reset redo stack automaticly - Tilbakestill angrehistorikk automatisk + Tilbakestill angrehistorikk automatisk + + + + Enable LaTeX rendering + historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. io Objects - Objekter + Objekter Settings - Innstillinger + Innstillinger History - Historikk + Historikk + Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». + Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. + Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. + Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. + Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: + Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! &Update - &Oppdater + &Oppdater &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -1155,13 +1263,139 @@ Please make sure your latex installation is correct and report a bug if so. + + name + + + + %1 %2 renamed to %3. + + + + + parameters + + + above + + + + + below + + + + + + left + + + + + + right + + + + + above-left + + + + + above-right + + + + + below-left + + + + + below-right + + + + + center + + + + + top + + + + + bottom + + + + + top-left + + + + + top-right + + + + + bottom-left + + + + + bottom-right + + + + + application + + + + + function + + + + + high + + + + + low + + + + + Next to target + + + + + With label + + + + + Hidden + + + phasebode + Bode Phase Bode-fase + Bode Phases Bode-faser @@ -1169,21 +1403,197 @@ Please make sure your latex installation is correct and report a bug if so. point + Point Punkt + Points Punkter + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + + + prop + + + expression + + + + + definitionDomain + + + + + destinationDomain + + + + + displayMode + + + + + + + + + + + + + + labelPosition + + + + + + + + + + + labelX + + + + + + drawPoints + + + + + + drawDashedLines + + + + + + om_0 + + + + + pass + + + + + gain + + + + + omGraduation + + + + + phase + + + + + unit + + + + + + + x + + + + + + y + + + + + pointStyle + + + + + probabilities + + + + + defaultExpression + + + + + baseValues + + + + + text + + + + + disableLatex + + + + + targetElement + + + + + approximate + + + + + rounding + + + + + displayStyle + + + + + targetValuePosition + + + repartition + Repartition Distribusjon + Repartition functions Distribusjonsfunksjoner @@ -1191,17 +1601,39 @@ Please make sure your latex installation is correct and report a bug if so. sequence + Sequence Følge + Sequences - Følger + Følger + + + + settingCategory + + + general + + + + + editor + + + + + default + sommegainsbode + + Bode Magnitudes Sum Bode-magnitudesum @@ -1209,6 +1641,8 @@ Please make sure your latex installation is correct and report a bug if so. sommephasesbode + + Bode Phases Sum Bode-fasesum @@ -1216,24 +1650,22 @@ Please make sure your latex installation is correct and report a bug if so. text + Text Tekst + Texts Tekster update - - An update for LogarithPlotter (v{}) is available. - En ny versjon av LogartimePlotter (v{}) er tilgjengelig - An update for LogarithmPlotter (v{}) is available. - + En ny versjon av LogartimePlotter (v{}) er tilgjengelig @@ -1291,23 +1723,29 @@ Please make sure your latex installation is correct and report a bug if so. visibility + + %1 %2 shown. - %1 %2 vist. + %1 %2 vist. + + %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. xcursor + X Cursor - X-peker + X-peker + X Cursors - X-pekere + X-pekere diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 3d31e6b..cb5e7b7 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,7 +5,6 @@ About - About LogarithmPlotter @@ -162,13 +161,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -457,21 +456,25 @@ Settings + X Zoom + Y Zoom + Min X + Max Y @@ -487,46 +490,55 @@ + X Axis Step + Y Axis Step + Line width + Text size (px) + X Label + Y Label + X Log scale + Show X graduation + Show Y graduation @@ -662,6 +674,43 @@ + + color + + + + %1 %2's color changed from %3 to %4. + + + + + comment + + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + + + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + + + + + Note: Specify the probability for each value. + + + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + + control @@ -674,6 +723,37 @@ + + create + + + + New %1 %2 created. + + + + + delete + + + + %1 %2 deleted. + + + + + editproperty + + + %1 of %2 %3 changed from "%4" to "%5". + + + + + %1 of %2 changed from %3 to %4. + + + error @@ -759,41 +839,49 @@ + First argument to map is not a function. + Second argument to map is not an array. + First argument to fold is not a function. + Second argument to fold is not an array. + First argument to filter is not a function. + Second argument to filter is not an array. + Second argument to indexOf is not a string or array. + Second argument to join is not an array. @@ -828,7 +916,7 @@ - + Error while parsing expression for property %1: %2 @@ -847,7 +935,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -865,6 +953,115 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + + Color Scheme + + + + + function + + + Function + + + + + Functions + + + + + gainbode + + + Bode Magnitude + + + + + Bode Magnitudes + + + + + + low-pass + + + + + + high-pass + + + + + general + + + Check for updates on startup + + + + + Reset redo stack automaticly + + + + + Enable LaTeX rendering + + + + + io + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save file: + + + + + Loaded file '%1'. + + latex @@ -907,6 +1104,403 @@ Please make sure your latex installation is correct and report a bug if so. + + name + + + + %1 %2 renamed to %3. + + + + + parameters + + + above + + + + + below + + + + + + left + + + + + + right + + + + + above-left + + + + + above-right + + + + + below-left + + + + + below-right + + + + + center + + + + + top + + + + + bottom + + + + + top-left + + + + + top-right + + + + + bottom-left + + + + + bottom-right + + + + + application + + + + + function + + + + + high + + + + + low + + + + + Next to target + + + + + With label + + + + + Hidden + + + + + phasebode + + + Bode Phase + + + + + Bode Phases + + + + + point + + + Point + + + + + Points + + + + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + + + prop + + + expression + + + + + definitionDomain + + + + + destinationDomain + + + + + displayMode + + + + + + + + + + + + + + labelPosition + + + + + + + + + + + labelX + + + + + + drawPoints + + + + + + drawDashedLines + + + + + + om_0 + + + + + pass + + + + + gain + + + + + omGraduation + + + + + phase + + + + + unit + + + + + + + x + + + + + + y + + + + + pointStyle + + + + + probabilities + + + + + defaultExpression + + + + + baseValues + + + + + text + + + + + disableLatex + + + + + targetElement + + + + + approximate + + + + + rounding + + + + + displayStyle + + + + + targetValuePosition + + + + + repartition + + + Repartition + + + + + Repartition functions + + + + + sequence + + + Sequence + + + + + Sequences + + + + + settingCategory + + + general + + + + + editor + + + + + default + + + + + sommegainsbode + + + + Bode Magnitudes Sum + + + + + sommephasesbode + + + + Bode Phases Sum + + + + + text + + + Text + + + + + Texts + + + update @@ -967,4 +1561,32 @@ Please make sure your latex installation is correct and report a bug if so. + + visibility + + + + %1 %2 shown. + + + + + + %1 %2 hidden. + + + + + xcursor + + + X Cursor + + + + + X Cursors + + + diff --git a/LogarithmPlotter/i18n/update.sh b/LogarithmPlotter/i18n/update.sh index b8c4716..c20d7a7 100755 --- a/LogarithmPlotter/i18n/update.sh +++ b/LogarithmPlotter/i18n/update.sh @@ -1,2 +1,39 @@ #!/bin/bash -lupdate -extensions mjs,js,qs,qml,py -recursive .. -ts lp_*.ts +# +# This file automatically renames .mjs files to js, and (tries) to fix most common ECMAScript +# specificities so that lupdate doesn't cry out in pain. +# See also: https://bugreports.qt.io/browse/QTBUG-123819 +# + +files=$(find .. -name *.mjs) +for file in $files; do + echo "Moving '$file' to '${file%.*}.js'..." + mv "$file" "${file%.*}.js" + # Replacements to make it valid js + sed -i 's/^import/\/\/import/g' "${file%.*}.js" + sed -i 's/^export default/\/*export default*\//g' "${file%.*}.js" + sed -i 's/^export/\/*export*\//g' "${file%.*}.js" +done + +echo "------------------------" +echo "Updating translations..." +echo "------------------------" +lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts +# Updating locations in files +for lp in *.ts; do + echo "Replacing locations in $lp..." + for file in $files; do + echo " > Replacing for file $file..." + f="${file//\//\\/}" # Escape slashes + sed -i "s/${f%.*}.js/$f/g" "$lp" + done +done + +for file in $files; do + echo "Moving '${file%.*}.js' to '$file'..." + mv "${file%.*}.js" "$file" + # Resetting changes + sed -i 's/^\/\/import/import/g' "$file" + sed -i 's/^\/\*export default\*\//export default/g' "$file" + sed -i 's/^\/\*export\*\//export/g' "$file" +done From 2321a1076c9c7bb314f3d4358f06376f0543eff4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 18:57:07 +0000 Subject: [PATCH 091/249] Translated using Weblate (English) Currently translated at 100.0% (310 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 1febb33..038db64 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -707,17 +707,17 @@ These settings can be changed at any time from the "Settings" menu. Save plot - Save plot + Save plot… Save plot as - Save plot as + Save plot as… Load plot - Open plot + Open plot… Close @@ -749,7 +749,7 @@ These settings can be changed at any time from the "Settings" menu. Ported to Javascript by Matthew Crumley - Ported to Javascript by Matthew Crumley + Ported to JavaScript by Matthew Crumley @@ -798,7 +798,7 @@ These settings can be changed at any time from the "Settings" menu. Github - Github + GitHub @@ -1639,7 +1639,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. approximate - Show approximate value + Show rounded calculated value From 6d3f4ba372f273367d81935f128d981523215dc3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 16:56:37 +0000 Subject: [PATCH 092/249] Translated using Weblate (German) Currently translated at 100.0% (310 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 51c132c..7cdff41 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -707,17 +707,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Save plot - Grafik speichern + Grafik speichern… Save plot as - Grafik speichern unter + Grafik speichern unter… Load plot - Grafik laden + Grafik laden… Close @@ -749,7 +749,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Ported to Javascript by Matthew Crumley - Portiert auf Javascript von Matthew Crumley + Portiert auf JavaScript von Matthew Crumley @@ -798,7 +798,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Github - Github + GitHub @@ -1639,7 +1639,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde approximate - Ungefähren Wert anzeigen + Berechneten Wert gerundet anzeigen @@ -1751,7 +1751,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde An update for LogarithmPlotter (v{}) is available. - Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. + Ein Update für LogarithmPlotter (v{}) ist verfügbar. From 4e265b66c24413881364e97d4a75e397038c625a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 16:53:46 +0000 Subject: [PATCH 093/249] Translated using Weblate (Spanish) Currently translated at 98.3% (305 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 4806934..bb1d184 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -707,17 +707,17 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Save plot - Guardar gráfico + Guardar gráfico Save plot as - Guardar gráfico como + Guardar gráfico como Load plot - Abrir gráfico + Abrir gráfico Close @@ -749,7 +749,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Ported to Javascript by Matthew Crumley - Portado a Javascript por Matthew Crumley + Portado a JavaScript por Matthew Crumley @@ -798,7 +798,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Github - + GitHub @@ -1644,7 +1644,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u approximate - Mostrar valor aproximado + Mostrar valor aproximado From 484888f80f9e7d5529b4c0b7b62dced35d4bd324 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 16:56:15 +0000 Subject: [PATCH 094/249] Translated using Weblate (French) Currently translated at 100.0% (310 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index b5eb9e0..6ff3ca6 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -709,17 +709,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Save plot - Sauvegarder le graphe + Sauvegarder le graphe… Save plot as - Sauvegarder le graphe sous + Sauvegarder le graphe sous… Load plot - Ouvrir un graphe + Ouvrir un graphe… Close @@ -751,7 +751,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Ported to Javascript by Matthew Crumley - Porté en Javascript par Matthew Crumley + Porté en JavaScript par Matthew Crumley @@ -800,7 +800,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Github - Github + GitHub @@ -1642,7 +1642,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c approximate - Afficher la valeur approximative + Afficher la valeur arrondie calculée From 7c12b757ee7790297fc4b15725d61fdd25e406cd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 18:57:07 +0000 Subject: [PATCH 095/249] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 68.0% (211 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/nb_NO/ --- LogarithmPlotter/i18n/lp_nb_NO.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 4f7ce95..1a00182 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -663,17 +663,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Save plot - Lagre plott + Lagre plott Save plot as - Lagre plott som + Lagre plott som Load plot - Last inn plott + Last inn plott @@ -701,7 +701,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Ported to Javascript by Matthew Crumley - + Overført til JavaScript av Matthew Crumley @@ -750,7 +750,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Github - + GitHub From 1ef1d274522a65ca1cad77e89375613253468826 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 16:53:46 +0000 Subject: [PATCH 096/249] Translated using Weblate (Hungarian) Currently translated at 96.1% (298 of 310 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 7f5fcea..2ab1d50 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -707,17 +707,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Save plot - Ábra mentése + Ábra mentése Save plot as - Ábra mentése másként + Ábra mentése másként Load plot - Ábra betöltése + Ábra betöltése Close @@ -1635,7 +1635,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents approximate - Hozzávetőleges érték megjelenítése + Hozzávetőleges érték megjelenítése From b18e1ca56e7e65b097eb8dd926e3743cfbb6d74c Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 20 Sep 2024 23:51:37 +0200 Subject: [PATCH 097/249] Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/ --- LogarithmPlotter/i18n/lp_es.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index bb1d184..41b644f 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1748,9 +1748,6 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u update - - An update for LogarithPlotter (v{}) is available. - An update for LogarithmPlotter (v{}) is available. From 6e92c428f9cce004729f7d45a1576f55110b751f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 23:52:05 +0200 Subject: [PATCH 098/249] Removing vanished translation from Spanish file --- LogarithmPlotter/i18n/lp_es.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index bb1d184..41b644f 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1748,9 +1748,6 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u update - - An update for LogarithPlotter (v{}) is available. - An update for LogarithmPlotter (v{}) is available. From 7e698eda3228f95ceca51d7d6626ff85ad43e375 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:52:52 +0000 Subject: [PATCH 099/249] Translated using Weblate (English) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 038db64..5be7fae 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1133,22 +1133,22 @@ Evaluated expression: %3 Automatically close parenthesises and brackets - Automatically close parentheses and brackets + Automatically close parentheses and brackets Enable syntax highlighting - Enable syntax highlighting + Enable syntax highlighting Enable autocompletion - Enable autocompletion + Enable autocompletion Color Scheme - Color Scheme + Color Scheme @@ -1194,17 +1194,17 @@ Evaluated expression: %3 Check for updates on startup - Check for updates on startup + Check for updates on startup Reset redo stack automaticly - Reset redo stack automatically + Reset redo stack automatically Enable LaTeX rendering - Enable LaTeX rendering + Enable LaTeX rendering @@ -1251,32 +1251,32 @@ Evaluated expression: %3 Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. Loading file '%1'. - Loading file '%1'. + Loading file '%1'. Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. Invalid file provided. - Invalid file provided. + Invalid file provided. Could not save file: - Could not save file: + Could not save file: Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. Copied plot screenshot to clipboard! From 0e23d9181ef5e40993ea273e470bc4e6e6cb8075 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:54:27 +0000 Subject: [PATCH 100/249] Translated using Weblate (German) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 7cdff41..c5cd4cb 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1133,22 +1133,22 @@ Ausdruck analysiert: %3 Automatically close parenthesises and brackets - Klammern automatisch schließen + Klammern automatisch schließen Enable syntax highlighting - Syntaxhervorhebung einschalten + Syntaxhervorhebung einschalten Enable autocompletion - Automatische Vervollständigung einschalten + Automatische Vervollständigung einschalten Color Scheme - Syntaktische Färbung + Syntaktische Färbung @@ -1194,17 +1194,17 @@ Ausdruck analysiert: %3 Check for updates on startup - Beim Starten auf Updates prüfen + Beim Starten auf Updates prüfen Reset redo stack automaticly - Wiederherstellen-Stapel automatisch zurücksetzen + Wiederherstellen-Stapel automatisch zurücksetzen Enable LaTeX rendering - LaTeX-Rendering aktivieren + LaTeX-Rendering aktivieren @@ -1251,32 +1251,32 @@ Ausdruck analysiert: %3 Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. Copied plot screenshot to clipboard! From 2bf7df12a88fd1d388e60ba3d3c2fb5e3b46f015 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:56:36 +0000 Subject: [PATCH 101/249] Translated using Weblate (Spanish) Currently translated at 98.5% (265 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 41b644f..ef6ba19 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1133,22 +1133,22 @@ Expresión evaluada: %3 Automatically close parenthesises and brackets - Cerrar automáticamente paréntesis y corchetes + Cerrar automáticamente paréntesis y corchetes Enable syntax highlighting - Activar el resaltado sintáctico + Activar el resaltado sintáctico Enable autocompletion - Activar autocompletar + Activar autocompletar Color Scheme - Esquema de colores + Esquema de colores @@ -1194,17 +1194,17 @@ Expresión evaluada: %3 Check for updates on startup - Comprobación de las actualizaciones al arrancar + Comprobación de las actualizaciones al arrancar Reset redo stack automaticly - Restablecer la pila de rehacer automáticamente + Restablecer la pila de rehacer automáticamente Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX @@ -1263,32 +1263,32 @@ Expresión evaluada: %3 Saved plot to '%1'. - Gráfico guardado en '%1'. + Gráfico guardado en '%1'. Loading file '%1'. - Cargando el archivo '%1'. + Cargando el archivo '%1'. Unknown object type: %1. - Tipo de objeto desconocido: %1 . + Tipo de objeto desconocido: %1 . Invalid file provided. - Se ha proporcionado un archivo no válido. + Se ha proporcionado un archivo no válido. Could not save file: - No se ha podido guardar el archivo: + No se ha podido guardar el archivo: Loaded file '%1'. - Archivo cargado '%1'. + Archivo cargado '%1'. From ed5b7e95a63a25d2cb233b40a80a09f92e01ec66 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:53:39 +0000 Subject: [PATCH 102/249] Translated using Weblate (French) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 6ff3ca6..3fb86f4 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1136,22 +1136,22 @@ Formule analysée : %3 Automatically close parenthesises and brackets - Fermer automatiquement les parenthèses et les crochets + Fermer automatiquement les parenthèses et les crochets Enable syntax highlighting - Activer la coloration syntaxique + Activer la coloration syntaxique Enable autocompletion - Activer l'autocomplétion + Activer l'autocomplétion Color Scheme - Coloration Syntaxique + Coloration Syntaxique @@ -1197,17 +1197,17 @@ Formule analysée : %3 Check for updates on startup - Vérifier la présence de mise à jour au démarrage + Vérifier la présence de mise à jour au démarrage Reset redo stack automaticly - Réinitialiser la pile d'action "Rétablir" automatiquement + Réinitialiser la pile d'action "Rétablir" automatiquement Enable LaTeX rendering - Activer le rendu LaTeX + Activer le rendu LaTeX @@ -1266,32 +1266,32 @@ Formule analysée : %3 Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. From 77d03e5837e81459ed171554f3df77c0e798b17d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:57:53 +0000 Subject: [PATCH 103/249] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 71.7% (193 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/nb_NO/ --- LogarithmPlotter/i18n/lp_nb_NO.ts | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 1a00182..d52d13b 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -146,7 +146,7 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? + Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? @@ -562,7 +562,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Close - Lukk + Lukk @@ -841,7 +841,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. @@ -850,7 +850,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. @@ -858,7 +858,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». @@ -1129,12 +1129,12 @@ Evaluated expression: %3 Check for updates on startup - Se etter nye versjoner ved programstart + Se etter nye versjoner ved programstart Reset redo stack automaticly - Tilbakestill angrehistorikk automatisk + Tilbakestill angrehistorikk automatisk @@ -1182,32 +1182,32 @@ Evaluated expression: %3 Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». Copied plot screenshot to clipboard! @@ -1608,7 +1608,7 @@ Please make sure your latex installation is correct and report a bug if so. Sequences - Følger + Følger @@ -1665,7 +1665,7 @@ Please make sure your latex installation is correct and report a bug if so. An update for LogarithmPlotter (v{}) is available. - En ny versjon av LogartimePlotter (v{}) er tilgjengelig + En ny versjon av LogartimePlotter (v{}) er tilgjengelig. @@ -1726,13 +1726,13 @@ Please make sure your latex installation is correct and report a bug if so. %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. @@ -1740,12 +1740,12 @@ Please make sure your latex installation is correct and report a bug if so. X Cursor - X-peker + X-peker X Cursors - X-pekere + X-pekere From 3c57f207b6b5b8586b18c001ffcf8617b5d23079 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 21:55:39 +0000 Subject: [PATCH 104/249] Translated using Weblate (Hungarian) Currently translated at 96.2% (259 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 2ab1d50..1571ab4 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1133,22 +1133,22 @@ Kiértékelt kifejezés: %3 Automatically close parenthesises and brackets - Zárójelek automatikus bezárása + Zárójelek automatikus bezárása Enable syntax highlighting - Mondattani kiemelés engedélyezése + Mondattani kiemelés engedélyezése Enable autocompletion - Automatikus befejezés engedélyezése + Automatikus befejezés engedélyezése Color Scheme - Színséma + Színséma @@ -1194,17 +1194,17 @@ Kiértékelt kifejezés: %3 Check for updates on startup - Frissítések keresése indításkor + Frissítések keresése indításkor Reset redo stack automaticly - Ismétlési verem önműködő visszaállítása + Ismétlési verem önműködő visszaállítása Enable LaTeX rendering - LaTeX-megjelenítés engedélyezése + LaTeX-megjelenítés engedélyezése @@ -1247,32 +1247,32 @@ Kiértékelt kifejezés: %3 Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. Copied plot screenshot to clipboard! @@ -1708,7 +1708,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents default - Alapértelmezett ábra + Alapértelmezett ábra From 43a0aa35291f137e33fb48792e0937f94746df5a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 21 Sep 2024 00:34:26 +0000 Subject: [PATCH 105/249] Translated using Weblate (English) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 5be7fae..3a86bcf 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1664,7 +1664,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. baseValues - Initialisation values + Initialization values color From c8ada7977665e1b8d7f67e5cb02d2cb668e36e0e Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Fri, 20 Sep 2024 22:29:25 +0000 Subject: [PATCH 106/249] Translated using Weblate (Spanish) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index ef6ba19..7d9a37b 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -707,17 +707,17 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Save plot - Guardar gráfico + Guardar gráfico… Save plot as - Guardar gráfico como + Guardar gráfico como… Load plot - Abrir gráfico + Abrir gráfico… Close @@ -1644,7 +1644,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u approximate - Mostrar valor aproximado + Mostrar el resultado redondeado From 5d0f3eec56235711e5b133bef8c36b7073a76b03 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 21 Sep 2024 00:34:26 +0000 Subject: [PATCH 107/249] Translated using Weblate (Hungarian) Currently translated at 95.9% (258 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 1571ab4..8d3f5b3 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1660,7 +1660,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents baseValues - Kezdeményezési értékek + Kezdeményezési értékek color From 1299fe469d3f8665eea4a50c5676ed581c627b55 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 21 Sep 2024 03:21:49 +0200 Subject: [PATCH 108/249] Updating README --- README.md | 24 +++++++++++------------- poetry.lock | 2 +- pyproject.toml | 6 ++++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0745682..3dd1378 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ ![Phase example](https://apps.ad5001.eu/img/en/logarithmplotter/phase.png) ![Object settings](https://apps.ad5001.eu/img/en/logarithmplotter/object-settings.webp) -You can find more screenshots on the [app website](https://apps.ad5001.eu/logarithmplotter/). +You can find more screenshots on the [app's website](https://apps.ad5001.eu/logarithmplotter/). ## Run You can simply run LogarithmPlotter using `python3 run.py`. -In order to test translations, you can use the `--lang=` commandline option to force the locale of LogarithmPlotter. +In order to test translations, you can use the `--lang=` commandline option to force the locale. ## Install @@ -25,18 +25,15 @@ In order to test translations, you can use the `--lang=` commandline All scripts noted here can be found in the `scripts` directory. You can generate installers for LogarithmPlotter after installing all the dependencies: -For all builds, you need [Python 3](https://python.org) with [PySide6](https://pypi.org/project/PySide6/) installable with `pip install PySide6`. +For all builds, you will need [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and `poetry install --with packaging`. - Windows installer: - - You need `pyinstaller`. You can install it using `pip install pyinstaller`. - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an exe for LogarithmPlotter. - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (Linux users can install the [nsis](https://pkgs.org/download/nsis) package). - - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a logarithmplotter-setup.exe installer in the dist/accountfree/ folder. + - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a logarithmplotter-setup.exe installer in the dist/logarithmplotter/ folder. - MacOS Archive creator installer: - - You need `pyinstaller`. You can install it using `pip install pyinstaller`. - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the dist directory. - - Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v0.1-dev-setup.dmg installer in the dist/ folder. + - Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v<version>-setup.dmg installer in the dist/ folder. - Linux packages: - - To build a DEB, you need DPKG and stdeb. You can install the later by using `pip install stdeb`. - To build and install the flatpak, you need [flatpak-builder](https://docs.flatpak.org/en/latest/flatpak-builder.html) installed. - To build the snap, you need [snapcraft](https://snapcraft.io) installed. - Run `package-linux.sh`. @@ -51,14 +48,15 @@ There are several ways to contribute to LogarithmPlotter. ## Tests -To run LogarithmPlotter's test, use the following: +To run LogarithmPlotter's tests, follow these steps: - Python - - Install `pytest` and `pytest-cov` - - Run `pytest --cov` + - Install python3 and [poetry](https://python-poetry.org/) + - Run `poetry install --with test` + - Run `scripts/run-tests.sh` ## Legal notice - LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions. + LogarithmPlotter - 2D plotter software to make Bode plots, sequences and repartition functions. Copyright (C) 2021-2024 Ad5001 This program is free software: you can redistribute it and/or modify @@ -83,4 +81,4 @@ Language files translations located at LogarithmPlotter/i18n are licensed under LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf <r@undefined.ch>, ported to javascript by Matthew Crumley <email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. -The specific file (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js) is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). +The specific file (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js) is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). diff --git a/poetry.lock b/poetry.lock index e2ba8cf..0c25a10 100644 --- a/poetry.lock +++ b/poetry.lock @@ -438,4 +438,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "083111ed37f3ef23de75a56eaf4c6fdda954b6005c5ee0922aad4470e2a36738" +content-hash = "3db79d8b611fd2e37486fbd8e10c6d454b293cc7156d83b05c1a8459cb9b33e6" diff --git a/pyproject.toml b/pyproject.toml index a7aa8cc..f705e04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,9 +12,11 @@ python = ">=3.9,<3.13" PySide6-Essentials = "^6.7.2" pyside6-addons = "^6.7.2" -[tool.poetry.group.dev.dependencies] +[tool.poetry.group.packaging.dependencies] pyinstaller = "^6.10.0" +stdeb = "^0.10.0" + +[tool.poetry.group.test.dependencies] pytest = "^8.3.3" pytest-cov = "^5.0.0" pytest-qt = "^4.4.0" -stdeb = "^0.10.0" From cc0f277da7a5e8e636c11947ca3b05cbb0569a1f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 05:57:36 +0200 Subject: [PATCH 109/249] Nearly rewrote expr-eval to be compatible as an ECMAScript module, the last blocker for many bugs and JS tests! commit f91538de446ef0e497ec7e87e2729f504a4172cb Author: Ad5001 Date: Sun Sep 22 05:55:12 2024 +0200 Converted expr-eval back to regular JS! commit 23c346f6c65b5b5c4bb4ad610f0554bd1d9a3700 Author: Ad5001 Date: Sun Sep 22 05:06:59 2024 +0200 Reformatting commit 66608c980fd44f26ae8e6855ecd5fc3e7db55a7b Author: Ad5001 Date: Sun Sep 22 05:04:27 2024 +0200 Removed all 'var's commit 545886fd38c99cf11bc576caa40bec0d7fe0ac30 Author: Ad5001 Date: Sun Sep 22 04:53:32 2024 +0200 Removing function definition commit 489602b24bb70cb6ad782871e269a22c92fcf072 Author: Ad5001 Date: Sun Sep 22 04:51:21 2024 +0200 Removing semicolons commit 3ee069edbeb8ebfb5c7d15d319014f7a085ff623 Author: Ad5001 Date: Sun Sep 22 04:49:32 2024 +0200 Converting all classes to ECMAScript classes --- .../LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../eu/ad5001/LogarithmPlotter/js/autoload.js | 10 - .../ad5001/LogarithmPlotter/js/autoload.mjs | 27 + .../js/lib/expr-eval/expr-eval.js | 1852 ----------------- .../js/lib/expr-eval/expression.mjs | 540 +++++ .../js/lib/expr-eval/instruction.mjs | 82 + .../{integration.js => integration.mjs} | 49 +- .../js/lib/expr-eval/parser.mjs | 172 ++ .../js/lib/expr-eval/parserstate.mjs | 398 ++++ .../js/lib/expr-eval/polyfill.mjs | 371 ++++ .../js/lib/expr-eval/tokens.mjs | 575 +++++ .../ad5001/LogarithmPlotter/js/math/latex.mjs | 311 ++- 12 files changed, 2340 insertions(+), 2049 deletions(-) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/{integration.js => integration.mjs} (68%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 2e24d53..1a44958 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/autoload.js" as ModulesAutoload +import "js/autoload.mjs" as ModulesAutoload import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js deleted file mode 100644 index 5763db0..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ /dev/null @@ -1,10 +0,0 @@ - -// Loading modules in order -.import "objects.mjs" as Objects -.import "lib/expr-eval/integration.js" as ExprParser -.import "objs/autoload.mjs" as Autoload -.import "math/latex.mjs" as Latex -.import "history/common.mjs" as HistoryCommon -.import "canvas.mjs" as CanvasAPI -.import "io.mjs" as IOAPI -.import "preferences.mjs" as PreferencesAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs new file mode 100644 index 0000000..dcdaedb --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs @@ -0,0 +1,27 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Loading modules in order +import * as Objects from "./objects.mjs" +import * as ExprParser from "./lib/expr-eval/integration.mjs" +import * as ObjsAutoload from "./objs/autoload.mjs" +import * as Latex from "./math/latex.mjs" +import * as HistoryCommon from "./history/common.mjs" +import * as CanvasAPI from "./canvas.mjs" +import * as IOAPI from "./io.mjs" +import * as PreferencesAPI from "./preferences.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js deleted file mode 100644 index 1afd66b..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js +++ /dev/null @@ -1,1852 +0,0 @@ -// https://silentmatt.com/javascript-expression-evaluator/ - -.pragma library - -var INUMBER = 'INUMBER'; -var IOP1 = 'IOP1'; -var IOP2 = 'IOP2'; -var IOP3 = 'IOP3'; -var IVAR = 'IVAR'; -var IVARNAME = 'IVARNAME'; -var IFUNCALL = 'IFUNCALL'; -var IFUNDEF = 'IFUNDEF'; -var IEXPR = 'IEXPR'; -var IEXPREVAL = 'IEXPREVAL'; -var IMEMBER = 'IMEMBER'; -var IENDSTATEMENT = 'IENDSTATEMENT'; -var IARRAY = 'IARRAY'; - -// Additional variable characters. -var ADDITIONAL_VARCHARS = [ - "α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀", - "∞","π" -] - -function Instruction(type, value) { - this.type = type; - this.value = (value !== undefined && value !== null) ? value : 0; -} - -Instruction.prototype.toString = function () { - switch (this.type) { - case INUMBER: - case IOP1: - case IOP2: - case IOP3: - case IVAR: - case IVARNAME: - case IENDSTATEMENT: - return this.value; - case IFUNCALL: - return 'CALL ' + this.value; - case IFUNDEF: - return 'DEF ' + this.value; - case IARRAY: - return 'ARRAY ' + this.value; - case IMEMBER: - return '.' + this.value; - default: - return 'Invalid Instruction'; - } -}; - -function unaryInstruction(value) { - return new Instruction(IOP1, value); -} - -function binaryInstruction(value) { - return new Instruction(IOP2, value); -} - -function ternaryInstruction(value) { - return new Instruction(IOP3, value); -} - -function simplify(tokens, unaryOps, binaryOps, ternaryOps, values) { - var nstack = []; - var newexpression = []; - var n1, n2, n3; - var f; - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - var type = item.type; - if (type === INUMBER || type === IVARNAME) { - if (Array.isArray(item.value)) { - nstack.push.apply(nstack, simplify(item.value.map(function (x) { - return new Instruction(INUMBER, x); - }).concat(new Instruction(IARRAY, item.value.length)), unaryOps, binaryOps, ternaryOps, values)); - } else { - nstack.push(item); - } - } else if (type === IVAR && values.hasOwnProperty(item.value)) { - item = new Instruction(INUMBER, values[item.value]); - nstack.push(item); - } else if (type === IOP2 && nstack.length > 1) { - n2 = nstack.pop(); - n1 = nstack.pop(); - f = binaryOps[item.value]; - item = new Instruction(INUMBER, f(n1.value, n2.value)); - nstack.push(item); - } else if (type === IOP3 && nstack.length > 2) { - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - if (item.value === '?') { - nstack.push(n1.value ? n2.value : n3.value); - } else { - f = ternaryOps[item.value]; - item = new Instruction(INUMBER, f(n1.value, n2.value, n3.value)); - nstack.push(item); - } - } else if (type === IOP1 && nstack.length > 0) { - n1 = nstack.pop(); - f = unaryOps[item.value]; - item = new Instruction(INUMBER, f(n1.value)); - nstack.push(item); - } else if (type === IEXPR) { - while (nstack.length > 0) { - newexpression.push(nstack.shift()); - } - newexpression.push(new Instruction(IEXPR, simplify(item.value, unaryOps, binaryOps, ternaryOps, values))); - } else if (type === IMEMBER && nstack.length > 0) { - n1 = nstack.pop(); - //console.log("Getting property ", item.value, "of", n1) - if(item.value in n1.value) - nstack.push(new Instruction(INUMBER, n1.value[item.value])); - else - throw new Error(qsTranslate('error', 'Cannot find property %1 of object %2.').arg(item.value).arg(n1)) - } /* else if (type === IARRAY && nstack.length >= item.value) { - var length = item.value; - while (length-- > 0) { - newexpression.push(nstack.pop()); - } - newexpression.push(new Instruction(IARRAY, item.value)); - } */ else { - while (nstack.length > 0) { - newexpression.push(nstack.shift()); - } - newexpression.push(item); - } - } - while (nstack.length > 0) { - newexpression.push(nstack.shift()); - } - return newexpression; -} - -function substitute(tokens, variable, expr) { - var newexpression = []; - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - var type = item.type; - if (type === IVAR && item.value === variable) { - for (var j = 0; j < expr.tokens.length; j++) { - var expritem = expr.tokens[j]; - var replitem; - if (expritem.type === IOP1) { - replitem = unaryInstruction(expritem.value); - } else if (expritem.type === IOP2) { - replitem = binaryInstruction(expritem.value); - } else if (expritem.type === IOP3) { - replitem = ternaryInstruction(expritem.value); - } else { - replitem = new Instruction(expritem.type, expritem.value); - } - newexpression.push(replitem); - } - } else if (type === IEXPR) { - newexpression.push(new Instruction(IEXPR, substitute(item.value, variable, expr))); - } else { - newexpression.push(item); - } - } - return newexpression; -} - -function evaluate(tokens, expr, values) { - var nstack = []; - var n1, n2, n3; - var f, args, argCount; - - if (isExpressionEvaluator(tokens)) { - return resolveExpression(tokens, values); - } - - var numTokens = tokens.length; - - for (var i = 0; i < numTokens; i++) { - var item = tokens[i]; - var type = item.type; - if (type === INUMBER || type === IVARNAME) { - nstack.push(item.value); - } else if (type === IOP2) { - n2 = nstack.pop(); - n1 = nstack.pop(); - if (item.value === 'and') { - nstack.push(n1 ? !!evaluate(n2, expr, values) : false); - } else if (item.value === 'or') { - nstack.push(n1 ? true : !!evaluate(n2, expr, values)); - } else if (item.value === '=') { - f = expr.binaryOps[item.value]; - nstack.push(f(n1, evaluate(n2, expr, values), values)); - } else { - f = expr.binaryOps[item.value]; - nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values))); - } - } else if (type === IOP3) { - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - if (item.value === '?') { - nstack.push(evaluate(n1 ? n2 : n3, expr, values)); - } else { - f = expr.ternaryOps[item.value]; - nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values), resolveExpression(n3, values))); - } - } else if (type === IVAR) { - // Check for variable value - if (/^__proto__|prototype|constructor$/.test(item.value)) { - throw new Error('WARNING: Prototype access detected and denied. If you downloaded this file from the internet, this file might be a virus.'); - } else if (item.value in expr.functions) { - nstack.push(expr.functions[item.value]); - } else if (item.value in expr.unaryOps && expr.parser.isOperatorEnabled(item.value)) { - nstack.push(expr.unaryOps[item.value]); - } else { - var v = values[item.value]; - if (v !== undefined) { - nstack.push(v); - } else { - throw new Error(qsTranslate('error', 'Undefined variable %1.').arg(item.value)); - } - } - } else if (type === IOP1) { - n1 = nstack.pop(); - f = expr.unaryOps[item.value]; - nstack.push(f(resolveExpression(n1, values))); - } else if (type === IFUNCALL) { - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(resolveExpression(nstack.pop(), values)); - } - f = nstack.pop(); - if (f.apply && f.call) { - nstack.push(f.apply(undefined, args)); - } else if(f.execute) { - // Objects & expressions execution - if(args.length >= 1) - nstack.push(f.execute.apply(f, args)); - else - throw new Error(qsTranslate('error', 'In order to be executed, object %1 must have at least one argument.').arg(f)) - } else { - throw new Error(qsTranslate('error', '%1 cannot be executed.').arg(f)); - } - } else if (type === IFUNDEF) { - // Create closure to keep references to arguments and expression - nstack.push((function () { - var n2 = nstack.pop(); - var args = []; - var argCount = item.value; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - var n1 = nstack.pop(); - var f = function () { - var scope = Object.assign({}, values); - for (var i = 0, len = args.length; i < len; i++) { - scope[args[i]] = arguments[i]; - } - return evaluate(n2, expr, scope); - }; - // f.name = n1 - Object.defineProperty(f, 'name', { - value: n1, - writable: false - }); - values[n1] = f; - return f; - })()); - } else if (type === IEXPR) { - nstack.push(createExpressionEvaluator(item, expr)); - } else if (type === IEXPREVAL) { - nstack.push(item); - } else if (type === IMEMBER) { - n1 = nstack.pop(); - //console.log("Getting property", item.value, "of", n1,":",n1[item.value]) - if(item.value in n1) - if(n1[item.value].execute && n1[item.value].cached) - nstack.push(n1[item.value].execute()) - else - nstack.push(n1[item.value]); - else - throw new Error(qsTranslate('error', 'Cannot find property %1 of object %2.').arg(item.value).arg(n1)) - } else if (type === IENDSTATEMENT) { - nstack.pop(); - } else if (type === IARRAY) { - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - nstack.push(args); - } else { - throw new Error(qsTranslate('error', 'Invalid expression.')); - } - } - if (nstack.length > 1) { - throw new Error(qsTranslate('error', 'Invalid expression (parity).')); - } - // Explicitly return zero to avoid test issues caused by -0 - return nstack[0] === 0 ? 0 : resolveExpression(nstack[0], values); -} - -function createExpressionEvaluator(token, expr, values) { - if (isExpressionEvaluator(token)) return token; - return { - type: IEXPREVAL, - value: function (scope) { - return evaluate(token.value, expr, scope); - } - }; -} - -function isExpressionEvaluator(n) { - return n && n.type === IEXPREVAL; -} - -function resolveExpression(n, values) { - return isExpressionEvaluator(n) ? n.value(values) : n; -} - -function expressionToString(tokens, toJS) { - var nstack = []; - var n1, n2, n3; - var f, args, argCount; - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - var type = item.type; - if (type === INUMBER) { - if (typeof item.value === 'number' && item.value < 0) { - nstack.push('(' + item.value + ')'); - } else if (Array.isArray(item.value)) { - nstack.push('[' + item.value.map(escapeValue).join(', ') + ']'); - } else { - nstack.push(escapeValue(item.value)); - } - } else if (type === IOP2) { - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - if (toJS) { - if (f === '^') { - nstack.push('Math.pow(' + n1 + ', ' + n2 + ')'); - } else if (f === 'and') { - nstack.push('(!!' + n1 + ' && !!' + n2 + ')'); - } else if (f === 'or') { - nstack.push('(!!' + n1 + ' || !!' + n2 + ')'); - } else if (f === '||') { - nstack.push('(function(a,b){ return Array.isArray(a) && Array.isArray(b) ? a.concat(b) : String(a) + String(b); }((' + n1 + '),(' + n2 + ')))'); - } else if (f === '==') { - nstack.push('(' + n1 + ' === ' + n2 + ')'); - } else if (f === '!=') { - nstack.push('(' + n1 + ' !== ' + n2 + ')'); - } else if (f === '[') { - nstack.push(n1 + '[(' + n2 + ') | 0]'); - } else { - nstack.push('(' + n1 + ' ' + f + ' ' + n2 + ')'); - } - } else { - if (f === '[') { - nstack.push(n1 + '[' + n2 + ']'); - } else { - nstack.push('(' + n1 + ' ' + f + ' ' + n2 + ')'); - } - } - } else if (type === IOP3) { - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - if (f === '?') { - nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); - } else { - throw new Error(qsTranslate('error', 'Invalid expression.')); - } - } else if (type === IVAR || type === IVARNAME) { - nstack.push(item.value); - } else if (type === IOP1) { - n1 = nstack.pop(); - f = item.value; - if (f === '-' || f === '+') { - nstack.push('(' + f + n1 + ')'); - } else if (toJS) { - if (f === 'not') { - nstack.push('(' + '!' + n1 + ')'); - } else if (f === '!') { - nstack.push('fac(' + n1 + ')'); - } else { - nstack.push(f + '(' + n1 + ')'); - } - } else if (f === '!') { - nstack.push('(' + n1 + '!)'); - } else { - nstack.push('(' + f + ' ' + n1 + ')'); - } - } else if (type === IFUNCALL) { - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - f = nstack.pop(); - nstack.push(f + '(' + args.join(', ') + ')'); - } else if (type === IFUNDEF) { - n2 = nstack.pop(); - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - n1 = nstack.pop(); - if (toJS) { - nstack.push('(' + n1 + ' = function(' + args.join(', ') + ') { return ' + n2 + ' })'); - } else { - nstack.push('(' + n1 + '(' + args.join(', ') + ') = ' + n2 + ')'); - } - } else if (type === IMEMBER) { - n1 = nstack.pop(); - nstack.push(n1 + '.' + item.value); - } else if (type === IARRAY) { - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - nstack.push('[' + args.join(', ') + ']'); - } else if (type === IEXPR) { - nstack.push('(' + expressionToString(item.value, toJS) + ')'); - } else if (type === IENDSTATEMENT) ; else { - throw new Error(qsTranslate('error', 'Invalid expression.')); - } - } - if (nstack.length > 1) { - if (toJS) { - nstack = [ nstack.join(',') ]; - } else { - nstack = [ nstack.join(';') ]; - } - } - return String(nstack[0]); -} - -function escapeValue(v) { - if (typeof v === 'string') { - return JSON.stringify(v).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); - } - return v; -} - -function contains(array, obj) { - for (var i = 0; i < array.length; i++) { - if (array[i] === obj) { - return true; - } - } - return false; -} - -function getSymbols(tokens, symbols, options) { - options = options || {}; - var withMembers = !!options.withMembers; - var prevVar = null; - - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - if (item.type === IVAR || item.type === IVARNAME) { - if (!withMembers && !contains(symbols, item.value)) { - symbols.push(item.value); - } else if (prevVar !== null) { - if (!contains(symbols, prevVar)) { - symbols.push(prevVar); - } - prevVar = item.value; - } else { - prevVar = item.value; - } - } else if (item.type === IMEMBER && withMembers && prevVar !== null) { - prevVar += '.' + item.value; - } else if (item.type === IEXPR) { - getSymbols(item.value, symbols, options); - } else if (prevVar !== null) { - if (!contains(symbols, prevVar)) { - symbols.push(prevVar); - } - prevVar = null; - } - } - - if (prevVar !== null && !contains(symbols, prevVar)) { - symbols.push(prevVar); - } -} - -function Expression(tokens, parser) { - this.tokens = tokens; - this.parser = parser; - this.unaryOps = parser.unaryOps; - this.binaryOps = parser.binaryOps; - this.ternaryOps = parser.ternaryOps; - this.functions = parser.functions; -} - -Expression.prototype.simplify = function (values) { - values = values || {}; - return new Expression(simplify(this.tokens, this.unaryOps, this.binaryOps, this.ternaryOps, values), this.parser); -}; - -Expression.prototype.substitute = function (variable, expr) { - if (!(expr instanceof Expression)) { - expr = this.parser.parse(String(expr)); - } - - return new Expression(substitute(this.tokens, variable, expr), this.parser); -}; - -Expression.prototype.evaluate = function (values) { - values = Object.assign({}, values, this.parser.consts) - return evaluate(this.tokens, this, values); -}; - -Expression.prototype.toString = function () { - return expressionToString(this.tokens, false); -}; - -Expression.prototype.symbols = function (options) { - options = options || {}; - var vars = []; - getSymbols(this.tokens, vars, options); - return vars; -}; - -Expression.prototype.variables = function (options) { - options = options || {}; - var vars = []; - getSymbols(this.tokens, vars, options); - var functions = this.functions; - var consts = this.parser.consts - return vars.filter(function (name) { - return !(name in functions) && !(name in consts); - }); -}; - -Expression.prototype.toJSFunction = function (param, variables) { - var expr = this; - var f = new Function(param, 'with(this.functions) with (this.ternaryOps) with (this.binaryOps) with (this.unaryOps) { return ' + expressionToString(this.simplify(variables).tokens, true) + '; }'); // eslint-disable-line no-new-func - return function () { - return f.apply(expr, arguments); - }; -}; - -var TEOF = 'TEOF'; -var TOP = 'TOP'; -var TNUMBER = 'TNUMBER'; -var TSTRING = 'TSTRING'; -var TPAREN = 'TPAREN'; -var TBRACKET = 'TBRACKET'; -var TCOMMA = 'TCOMMA'; -var TNAME = 'TNAME'; -var TSEMICOLON = 'TSEMICOLON'; - -function Token(type, value, index) { - this.type = type; - this.value = value; - this.index = index; -} - -Token.prototype.toString = function () { - return this.type + ': ' + this.value; -}; - -function TokenStream(parser, expression) { - this.pos = 0; - this.current = null; - this.unaryOps = parser.unaryOps; - this.binaryOps = parser.binaryOps; - this.ternaryOps = parser.ternaryOps; - this.builtinConsts = parser.builtinConsts; - this.expression = expression; - this.savedPosition = 0; - this.savedCurrent = null; - this.options = parser.options; - this.parser = parser; -} - -TokenStream.prototype.newToken = function (type, value, pos) { - return new Token(type, value, pos != null ? pos : this.pos); -}; - -TokenStream.prototype.save = function () { - this.savedPosition = this.pos; - this.savedCurrent = this.current; -}; - -TokenStream.prototype.restore = function () { - this.pos = this.savedPosition; - this.current = this.savedCurrent; -}; - -TokenStream.prototype.next = function () { - if (this.pos >= this.expression.length) { - return this.newToken(TEOF, 'EOF'); - } - - if (this.isWhitespace() || this.isComment()) { - return this.next(); - } else if (this.isRadixInteger() || - this.isNumber() || - this.isOperator() || - this.isString() || - this.isParen() || - this.isBracket() || - this.isComma() || - this.isSemicolon() || - this.isNamedOp() || - this.isConst() || - this.isName()) { - return this.current; - } else { - this.parseError(qsTranslate('error', 'Unknown character "%1".').arg(this.expression.charAt(this.pos))); - } -}; - -TokenStream.prototype.isString = function () { - var r = false; - var startPos = this.pos; - var quote = this.expression.charAt(startPos); - - if (quote === '\'' || quote === '"') { - var index = this.expression.indexOf(quote, startPos + 1); - while (index >= 0 && this.pos < this.expression.length) { - this.pos = index + 1; - if (this.expression.charAt(index - 1) !== '\\') { - var rawString = this.expression.substring(startPos + 1, index); - this.current = this.newToken(TSTRING, this.unescape(rawString), startPos); - r = true; - break; - } - index = this.expression.indexOf(quote, index + 1); - } - } - return r; -}; - -TokenStream.prototype.isParen = function () { - var c = this.expression.charAt(this.pos); - if (c === '(' || c === ')') { - this.current = this.newToken(TPAREN, c); - this.pos++; - return true; - } - return false; -}; - -TokenStream.prototype.isBracket = function () { - var c = this.expression.charAt(this.pos); - if ((c === '[' || c === ']') && this.isOperatorEnabled('[')) { - this.current = this.newToken(TBRACKET, c); - this.pos++; - return true; - } - return false; -}; - -TokenStream.prototype.isComma = function () { - var c = this.expression.charAt(this.pos); - if (c === ',') { - this.current = this.newToken(TCOMMA, ','); - this.pos++; - return true; - } - return false; -}; - -TokenStream.prototype.isSemicolon = function () { - var c = this.expression.charAt(this.pos); - if (c === ';') { - this.current = this.newToken(TSEMICOLON, ';'); - this.pos++; - return true; - } - return false; -}; - -TokenStream.prototype.isConst = function () { - var startPos = this.pos; - var i = startPos; - for (; i < this.expression.length; i++) { - var c = this.expression.charAt(i); - if (c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { - if (i === this.pos || (c !== '_' && c !== '.' && (c < '0' || c > '9'))) { - break; - } - } - } - if (i > startPos) { - var str = this.expression.substring(startPos, i); - if (str in this.builtinConsts) { - this.current = this.newToken(TNUMBER, this.builtinConsts[str]); - this.pos += str.length; - return true; - } - } - return false; -}; - -TokenStream.prototype.isNamedOp = function () { - var startPos = this.pos; - var i = startPos; - for (; i < this.expression.length; i++) { - var c = this.expression.charAt(i); - if (c.toUpperCase() === c.toLowerCase()) { - if (i === this.pos || (c !== '_' && (c < '0' || c > '9'))) { - break; - } - } - } - if (i > startPos) { - var str = this.expression.substring(startPos, i); - if (this.isOperatorEnabled(str) && (str in this.binaryOps || str in this.unaryOps || str in this.ternaryOps)) { - this.current = this.newToken(TOP, str); - this.pos += str.length; - return true; - } - } - return false; -}; - -TokenStream.prototype.isName = function () { - var startPos = this.pos; - var i = startPos; - var hasLetter = false; - for (; i < this.expression.length; i++) { - var c = this.expression.charAt(i); - if (c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { - if (i === this.pos && (c === '$' || c === '_')) { - if (c === '_') { - hasLetter = true; - } - continue; - } else if (i === this.pos || !hasLetter || (c !== '_' && (c < '0' || c > '9'))) { - break; - } - } else { - hasLetter = true; - } - } - if (hasLetter) { - var str = this.expression.substring(startPos, i); - this.current = this.newToken(TNAME, str); - this.pos += str.length; - return true; - } - return false; -}; - -TokenStream.prototype.isWhitespace = function () { - var r = false; - var c = this.expression.charAt(this.pos); - while (c === ' ' || c === '\t' || c === '\n' || c === '\r') { - r = true; - this.pos++; - if (this.pos >= this.expression.length) { - break; - } - c = this.expression.charAt(this.pos); - } - return r; -}; - -var codePointPattern = /^[0-9a-f]{4}$/i; - -TokenStream.prototype.unescape = function (v) { - var index = v.indexOf('\\'); - if (index < 0) { - return v; - } - - var buffer = v.substring(0, index); - while (index >= 0) { - var c = v.charAt(++index); - switch (c) { - case '\'': - buffer += '\''; - break; - case '"': - buffer += '"'; - break; - case '\\': - buffer += '\\'; - break; - case '/': - buffer += '/'; - break; - case 'b': - buffer += '\b'; - break; - case 'f': - buffer += '\f'; - break; - case 'n': - buffer += '\n'; - break; - case 'r': - buffer += '\r'; - break; - case 't': - buffer += '\t'; - break; - case 'u': - // interpret the following 4 characters as the hex of the unicode code point - var codePoint = v.substring(index + 1, index + 5); - if (!codePointPattern.test(codePoint)) { - this.parseError(qsTranslate('error', 'Illegal escape sequence: %1.').arg("\\u" + codePoint)); - } - buffer += String.fromCharCode(parseInt(codePoint, 16)); - index += 4; - break; - default: - throw this.parseError(qsTranslate('error', 'Illegal escape sequence: %1.').arg('\\' + c)); - } - ++index; - var backslash = v.indexOf('\\', index); - buffer += v.substring(index, backslash < 0 ? v.length : backslash); - index = backslash; - } - - return buffer; -}; - -TokenStream.prototype.isComment = function () { - var c = this.expression.charAt(this.pos); - if (c === '/' && this.expression.charAt(this.pos + 1) === '*') { - this.pos = this.expression.indexOf('*/', this.pos) + 2; - if (this.pos === 1) { - this.pos = this.expression.length; - } - return true; - } - return false; -}; - -TokenStream.prototype.isRadixInteger = function () { - var pos = this.pos; - - if (pos >= this.expression.length - 2 || this.expression.charAt(pos) !== '0') { - return false; - } - ++pos; - - var radix; - var validDigit; - if (this.expression.charAt(pos) === 'x') { - radix = 16; - validDigit = /^[0-9a-f]$/i; - ++pos; - } else if (this.expression.charAt(pos) === 'b') { - radix = 2; - validDigit = /^[01]$/i; - ++pos; - } else { - return false; - } - - var valid = false; - var startPos = pos; - - while (pos < this.expression.length) { - var c = this.expression.charAt(pos); - if (validDigit.test(c)) { - pos++; - valid = true; - } else { - break; - } - } - - if (valid) { - this.current = this.newToken(TNUMBER, parseInt(this.expression.substring(startPos, pos), radix)); - this.pos = pos; - } - return valid; -}; - -TokenStream.prototype.isNumber = function () { - var valid = false; - var pos = this.pos; - var startPos = pos; - var resetPos = pos; - var foundDot = false; - var foundDigits = false; - var c; - - while (pos < this.expression.length) { - c = this.expression.charAt(pos); - if ((c >= '0' && c <= '9') || (!foundDot && c === '.')) { - if (c === '.') { - foundDot = true; - } else { - foundDigits = true; - } - pos++; - valid = foundDigits; - } else { - break; - } - } - - if (valid) { - resetPos = pos; - } - - if (c === 'e' || c === 'E') { - pos++; - var acceptSign = true; - var validExponent = false; - while (pos < this.expression.length) { - c = this.expression.charAt(pos); - if (acceptSign && (c === '+' || c === '-')) { - acceptSign = false; - } else if (c >= '0' && c <= '9') { - validExponent = true; - acceptSign = false; - } else { - break; - } - pos++; - } - - if (!validExponent) { - pos = resetPos; - } - } - - if (valid) { - this.current = this.newToken(TNUMBER, parseFloat(this.expression.substring(startPos, pos))); - this.pos = pos; - } else { - this.pos = resetPos; - } - return valid; -}; - -TokenStream.prototype.isOperator = function () { - var startPos = this.pos; - var c = this.expression.charAt(this.pos); - - if (c === '+' || c === '-' || c === '*' || c === '/' || c === '%' || c === '^' || c === '?' || c === ':' || c === '.') { - this.current = this.newToken(TOP, c); - } else if (c === '∙' || c === '•') { - this.current = this.newToken(TOP, '*'); - } else if (c === '>') { - if (this.expression.charAt(this.pos + 1) === '=') { - this.current = this.newToken(TOP, '>='); - this.pos++; - } else { - this.current = this.newToken(TOP, '>'); - } - } else if (c === '<') { - if (this.expression.charAt(this.pos + 1) === '=') { - this.current = this.newToken(TOP, '<='); - this.pos++; - } else { - this.current = this.newToken(TOP, '<'); - } - } else if (c === '|') { - if (this.expression.charAt(this.pos + 1) === '|') { - this.current = this.newToken(TOP, '||'); - this.pos++; - } else { - return false; - } - } else if (c === '=') { - if (this.expression.charAt(this.pos + 1) === '=') { - this.current = this.newToken(TOP, '=='); - this.pos++; - } else { - this.current = this.newToken(TOP, c); - } - } else if (c === '!') { - if (this.expression.charAt(this.pos + 1) === '=') { - this.current = this.newToken(TOP, '!='); - this.pos++; - } else { - this.current = this.newToken(TOP, c); - } - } else { - return false; - } - this.pos++; - - if (this.isOperatorEnabled(this.current.value)) { - return true; - } else { - this.pos = startPos; - return false; - } -}; - -TokenStream.prototype.isOperatorEnabled = function (op) { - return this.parser.isOperatorEnabled(op); -}; - -TokenStream.prototype.getCoordinates = function () { - var line = 0; - var column; - var newline = -1; - do { - line++; - column = this.pos - newline; - newline = this.expression.indexOf('\n', newline + 1); - } while (newline >= 0 && newline < this.pos); - - return { - line: line, - column: column - }; -}; - -TokenStream.prototype.parseError = function (msg) { - var coords = this.getCoordinates(); - throw new Error(qsTranslate('error', 'Parse error [%1:%2]: %3').arg(coords.line).arg(coords.column).arg(msg)); -}; - -function ParserState(parser, tokenStream, options) { - this.parser = parser; - this.tokens = tokenStream; - this.current = null; - this.nextToken = null; - this.next(); - this.savedCurrent = null; - this.savedNextToken = null; - this.allowMemberAccess = options.allowMemberAccess !== false; -} - -ParserState.prototype.next = function () { - this.current = this.nextToken; - return (this.nextToken = this.tokens.next()); -}; - -ParserState.prototype.tokenMatches = function (token, value) { - if (typeof value === 'undefined') { - return true; - } else if (Array.isArray(value)) { - return contains(value, token.value); - } else if (typeof value === 'function') { - return value(token); - } else { - return token.value === value; - } -}; - -ParserState.prototype.save = function () { - this.savedCurrent = this.current; - this.savedNextToken = this.nextToken; - this.tokens.save(); -}; - -ParserState.prototype.restore = function () { - this.tokens.restore(); - this.current = this.savedCurrent; - this.nextToken = this.savedNextToken; -}; - -ParserState.prototype.accept = function (type, value) { - if (this.nextToken.type === type && this.tokenMatches(this.nextToken, value)) { - this.next(); - return true; - } - return false; -}; - -ParserState.prototype.expect = function (type, value) { - if (!this.accept(type, value)) { - var coords = this.tokens.getCoordinates(); - throw new Error(qsTranslate('error', 'Parse error [%1:%2]: %3') - .arg(coords.line).arg(coords.column) - .arg(qsTranslate('error', 'Expected %1').arg(value || type))); - } -}; - -ParserState.prototype.parseAtom = function (instr) { - var unaryOps = this.tokens.unaryOps; - function isPrefixOperator(token) { - return token.value in unaryOps; - } - - if (this.accept(TNAME) || this.accept(TOP, isPrefixOperator)) { - instr.push(new Instruction(IVAR, this.current.value)); - } else if (this.accept(TNUMBER)) { - instr.push(new Instruction(INUMBER, this.current.value)); - } else if (this.accept(TSTRING)) { - instr.push(new Instruction(INUMBER, this.current.value)); - } else if (this.accept(TPAREN, '(')) { - this.parseExpression(instr); - this.expect(TPAREN, ')'); - } else if (this.accept(TBRACKET, '[')) { - if (this.accept(TBRACKET, ']')) { - instr.push(new Instruction(IARRAY, 0)); - } else { - var argCount = this.parseArrayList(instr); - instr.push(new Instruction(IARRAY, argCount)); - } - } else { - throw new Error(qsTranslate('error', 'Unexpected %1').arg(this.nextToken)); - } -}; - -ParserState.prototype.parseExpression = function (instr) { - var exprInstr = []; - if (this.parseUntilEndStatement(instr, exprInstr)) { - return; - } - this.parseConditionalExpression(exprInstr); - if (this.parseUntilEndStatement(instr, exprInstr)) { - return; - } - this.pushExpression(instr, exprInstr); -}; - -ParserState.prototype.pushExpression = function (instr, exprInstr) { - for (var i = 0, len = exprInstr.length; i < len; i++) { - instr.push(exprInstr[i]); - } -}; - -ParserState.prototype.parseUntilEndStatement = function (instr, exprInstr) { - if (!this.accept(TSEMICOLON)) return false; - if (this.nextToken && this.nextToken.type !== TEOF && !(this.nextToken.type === TPAREN && this.nextToken.value === ')')) { - exprInstr.push(new Instruction(IENDSTATEMENT)); - } - if (this.nextToken.type !== TEOF) { - this.parseExpression(exprInstr); - } - instr.push(new Instruction(IEXPR, exprInstr)); - return true; -}; - -ParserState.prototype.parseArrayList = function (instr) { - var argCount = 0; - - while (!this.accept(TBRACKET, ']')) { - this.parseExpression(instr); - ++argCount; - while (this.accept(TCOMMA)) { - this.parseExpression(instr); - ++argCount; - } - } - - return argCount; -}; - -ParserState.prototype.parseConditionalExpression = function (instr) { - this.parseOrExpression(instr); - while (this.accept(TOP, '?')) { - var trueBranch = []; - var falseBranch = []; - this.parseConditionalExpression(trueBranch); - this.expect(TOP, ':'); - this.parseConditionalExpression(falseBranch); - instr.push(new Instruction(IEXPR, trueBranch)); - instr.push(new Instruction(IEXPR, falseBranch)); - instr.push(ternaryInstruction('?')); - } -}; - -ParserState.prototype.parseOrExpression = function (instr) { - this.parseAndExpression(instr); - while (this.accept(TOP, 'or')) { - var falseBranch = []; - this.parseAndExpression(falseBranch); - instr.push(new Instruction(IEXPR, falseBranch)); - instr.push(binaryInstruction('or')); - } -}; - -ParserState.prototype.parseAndExpression = function (instr) { - this.parseComparison(instr); - while (this.accept(TOP, 'and')) { - var trueBranch = []; - this.parseComparison(trueBranch); - instr.push(new Instruction(IEXPR, trueBranch)); - instr.push(binaryInstruction('and')); - } -}; - -var COMPARISON_OPERATORS = ['==', '!=', '<', '<=', '>=', '>', 'in']; - -ParserState.prototype.parseComparison = function (instr) { - this.parseAddSub(instr); - while (this.accept(TOP, COMPARISON_OPERATORS)) { - var op = this.current; - this.parseAddSub(instr); - instr.push(binaryInstruction(op.value)); - } -}; - -var ADD_SUB_OPERATORS = ['+', '-', '||']; - -ParserState.prototype.parseAddSub = function (instr) { - this.parseTerm(instr); - while (this.accept(TOP, ADD_SUB_OPERATORS)) { - var op = this.current; - this.parseTerm(instr); - instr.push(binaryInstruction(op.value)); - } -}; - -var TERM_OPERATORS = ['*', '/', '%']; - -ParserState.prototype.parseTerm = function (instr) { - this.parseFactor(instr); - while (this.accept(TOP, TERM_OPERATORS)) { - var op = this.current; - this.parseFactor(instr); - instr.push(binaryInstruction(op.value)); - } -}; - -ParserState.prototype.parseFactor = function (instr) { - var unaryOps = this.tokens.unaryOps; - function isPrefixOperator(token) { - return token.value in unaryOps; - } - - this.save(); - if (this.accept(TOP, isPrefixOperator)) { - if (this.current.value !== '-' && this.current.value !== '+') { - if (this.nextToken.type === TPAREN && this.nextToken.value === '(') { - this.restore(); - this.parseExponential(instr); - return; - } else if (this.nextToken.type === TSEMICOLON || this.nextToken.type === TCOMMA || this.nextToken.type === TEOF || (this.nextToken.type === TPAREN && this.nextToken.value === ')')) { - this.restore(); - this.parseAtom(instr); - return; - } - } - - var op = this.current; - this.parseFactor(instr); - instr.push(unaryInstruction(op.value)); - } else { - this.parseExponential(instr); - } -}; - -ParserState.prototype.parseExponential = function (instr) { - this.parsePostfixExpression(instr); - while (this.accept(TOP, '^')) { - this.parseFactor(instr); - instr.push(binaryInstruction('^')); - } -}; - -ParserState.prototype.parsePostfixExpression = function (instr) { - this.parseFunctionCall(instr); - while (this.accept(TOP, '!')) { - instr.push(unaryInstruction('!')); - } -}; - -ParserState.prototype.parseFunctionCall = function (instr) { - var unaryOps = this.tokens.unaryOps; - function isPrefixOperator(token) { - return token.value in unaryOps; - } - - if (this.accept(TOP, isPrefixOperator)) { - var op = this.current; - this.parseAtom(instr); - instr.push(unaryInstruction(op.value)); - } else { - this.parseMemberExpression(instr); - while (this.accept(TPAREN, '(')) { - if (this.accept(TPAREN, ')')) { - instr.push(new Instruction(IFUNCALL, 0)); - } else { - var argCount = this.parseArgumentList(instr); - instr.push(new Instruction(IFUNCALL, argCount)); - } - } - } -}; - -ParserState.prototype.parseArgumentList = function (instr) { - var argCount = 0; - - while (!this.accept(TPAREN, ')')) { - this.parseExpression(instr); - ++argCount; - while (this.accept(TCOMMA)) { - this.parseExpression(instr); - ++argCount; - } - } - - return argCount; -}; - -ParserState.prototype.parseMemberExpression = function (instr) { - this.parseAtom(instr); - while (this.accept(TOP, '.') || this.accept(TBRACKET, '[')) { - var op = this.current; - - if (op.value === '.') { - if (!this.allowMemberAccess) { - throw new Error(qsTranslate('error', 'Unexpected ".": member access is not permitted')); - } - - this.expect(TNAME); - instr.push(new Instruction(IMEMBER, this.current.value)); - } else if (op.value === '[') { - if (!this.tokens.isOperatorEnabled('[')) { - throw new Error(qsTranslate('error', 'Unexpected "[]": arrays are disabled.')); - } - - this.parseExpression(instr); - this.expect(TBRACKET, ']'); - instr.push(binaryInstruction('[')); - } else { - throw new Error(qsTranslate('error', 'Unexpected symbol: %1.').arg(op.value)); - } - } -}; - -function add(a, b) { - return Number(a) + Number(b); -} - -function sub(a, b) { - return a - b; -} - -function mul(a, b) { - return a * b; -} - -function div(a, b) { - return a / b; -} - -function mod(a, b) { - return a % b; -} - -function concat(a, b) { - if (Array.isArray(a) && Array.isArray(b)) { - return a.concat(b); - } - return '' + a + b; -} - -function equal(a, b) { - return a === b; -} - -function notEqual(a, b) { - return a !== b; -} - -function greaterThan(a, b) { - return a > b; -} - -function lessThan(a, b) { - return a < b; -} - -function greaterThanEqual(a, b) { - return a >= b; -} - -function lessThanEqual(a, b) { - return a <= b; -} - -function andOperator(a, b) { - return Boolean(a && b); -} - -function orOperator(a, b) { - return Boolean(a || b); -} - -function inOperator(a, b) { - return contains(b, a); -} - -function sinh(a) { - return ((Math.exp(a) - Math.exp(-a)) / 2); -} - -function cosh(a) { - return ((Math.exp(a) + Math.exp(-a)) / 2); -} - -function tanh(a) { - if (a === Infinity) return 1; - if (a === -Infinity) return -1; - return (Math.exp(a) - Math.exp(-a)) / (Math.exp(a) + Math.exp(-a)); -} - -function asinh(a) { - if (a === -Infinity) return a; - return Math.log(a + Math.sqrt((a * a) + 1)); -} - -function acosh(a) { - return Math.log(a + Math.sqrt((a * a) - 1)); -} - -function atanh(a) { - return (Math.log((1 + a) / (1 - a)) / 2); -} - -function log10(a) { - return Math.log(a) * Math.LOG10E; -} - -function neg(a) { - return -a; -} - -function not(a) { - return !a; -} - -function trunc(a) { - return a < 0 ? Math.ceil(a) : Math.floor(a); -} - -function random(a) { - return Math.random() * (a || 1); -} - -function factorial(a) { // a! - return gamma(a + 1); -} - -function isInteger(value) { - return isFinite(value) && (value === Math.round(value)); -} - -var GAMMA_G = 4.7421875; -var GAMMA_P = [ - 0.99999999999999709182, - 57.156235665862923517, -59.597960355475491248, - 14.136097974741747174, -0.49191381609762019978, - 0.33994649984811888699e-4, - 0.46523628927048575665e-4, -0.98374475304879564677e-4, - 0.15808870322491248884e-3, -0.21026444172410488319e-3, - 0.21743961811521264320e-3, -0.16431810653676389022e-3, - 0.84418223983852743293e-4, -0.26190838401581408670e-4, - 0.36899182659531622704e-5 -]; - -// Gamma function from math.js -function gamma(n) { - var t, x; - - if (isInteger(n)) { - if (n <= 0) { - return isFinite(n) ? Infinity : NaN; - } - - if (n > 171) { - return Infinity; // Will overflow - } - - var value = n - 2; - var res = n - 1; - while (value > 1) { - res *= value; - value--; - } - - if (res === 0) { - res = 1; // 0! is per definition 1 - } - - return res; - } - - if (n < 0.5) { - return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)); - } - - if (n >= 171.35) { - return Infinity; // will overflow - } - - if (n > 85.0) { // Extended Stirling Approx - var twoN = n * n; - var threeN = twoN * n; - var fourN = threeN * n; - var fiveN = fourN * n; - return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) * - (1 + (1 / (12 * n)) + (1 / (288 * twoN)) - (139 / (51840 * threeN)) - - (571 / (2488320 * fourN)) + (163879 / (209018880 * fiveN)) + - (5246819 / (75246796800 * fiveN * n))); - } - - --n; - x = GAMMA_P[0]; - for (var i = 1; i < GAMMA_P.length; ++i) { - x += GAMMA_P[i] / (n + i); - } - - t = n + GAMMA_G + 0.5; - return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x; -} - -function stringOrArrayLength(s) { - if (Array.isArray(s)) { - return s.length; - } - return String(s).length; -} - -function hypot() { - var sum = 0; - var larg = 0; - for (var i = 0; i < arguments.length; i++) { - var arg = Math.abs(arguments[i]); - var div; - if (larg < arg) { - div = larg / arg; - sum = (sum * div * div) + 1; - larg = arg; - } else if (arg > 0) { - div = arg / larg; - sum += div * div; - } else { - sum += arg; - } - } - return larg === Infinity ? Infinity : larg * Math.sqrt(sum); -} - -function condition(cond, yep, nope) { - return cond ? yep : nope; -} - -/** -* Decimal adjustment of a number. -* From @escopecz. -* -* @param {Number} value The number. -* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base). -* @return {Number} The adjusted value. -*/ -function roundTo(value, exp) { - // If the exp is undefined or zero... - if (typeof exp === 'undefined' || +exp === 0) { - return Math.round(value); - } - value = +value; - exp = -(+exp); - // If the value is not a number or the exp is not an integer... - if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { - return NaN; - } - // Shift - value = value.toString().split('e'); - value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); - // Shift back - value = value.toString().split('e'); - return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); -} - -function setVar(name, value, variables) { - if (variables) variables[name] = value; - return value; -} - -function arrayIndex(array, index) { - return array[index | 0]; -} - -function max(array) { - if (arguments.length === 1 && Array.isArray(array)) { - return Math.max.apply(Math, array); - } else if(arguments.length >= 1) { - return Math.max.apply(Math, arguments); - } else { - throw new EvalError(qsTranslate('error', 'Function %1 must have at least one argument.').arg('max')) - } -} - -function min(array) { - if (arguments.length === 1 && Array.isArray(array)) { - return Math.min.apply(Math, array); - } else if(arguments.length >= 1) { - return Math.min.apply(Math, arguments); - } else { - throw new EvalError(qsTranslate('error', 'Function %1 must have at least one argument.').arg('min')) - } -} - -function arrayMap(f, a) { - if (typeof f !== 'function') { - throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')); - } - if (!Array.isArray(a)) { - throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.')); - } - return a.map(function (x, i) { - return f(x, i); - }); -} - -function arrayFold(f, init, a) { - if (typeof f !== 'function') { - throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')); - } - if (!Array.isArray(a)) { - throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.')); - } - return a.reduce(function (acc, x, i) { - return f(acc, x, i); - }, init); -} - -function arrayFilter(f, a) { - if (typeof f !== 'function') { - throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')); - } - if (!Array.isArray(a)) { - throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')); - } - return a.filter(function (x, i) { - return f(x, i); - }); -} - -function stringOrArrayIndexOf(target, s) { - if (!(Array.isArray(s) || typeof s === 'string')) { - throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')); - } - - return s.indexOf(target); -} - -function arrayJoin(sep, a) { - if (!Array.isArray(a)) { - throw new Error(qsTranslate('error', 'Second argument to join is not an array.')); - } - - return a.join(sep); -} - -function sign(x) { - return ((x > 0) - (x < 0)) || +x; -} - -var ONE_THIRD = 1/3; -function cbrt(x) { - return x < 0 ? -Math.pow(-x, ONE_THIRD) : Math.pow(x, ONE_THIRD); -} - -function expm1(x) { - return Math.exp(x) - 1; -} - -function log1p(x) { - return Math.log(1 + x); -} - -function log2(x) { - return Math.log(x) / Math.LN2; -} - -class Parser { - constructor(options) { - this.options = options || {}; - this.unaryOps = { - sin: Math.sin, - cos: Math.cos, - tan: Math.tan, - asin: Math.asin, - acos: Math.acos, - atan: Math.atan, - sinh: Math.sinh || sinh, - cosh: Math.cosh || cosh, - tanh: Math.tanh || tanh, - asinh: Math.asinh || asinh, - acosh: Math.acosh || acosh, - atanh: Math.atanh || atanh, - sqrt: Math.sqrt, - cbrt: Math.cbrt || cbrt, - log: Math.log, - log2: Math.log2 || log2, - ln: Math.log, - lg: Math.log10 || log10, - log10: Math.log10 || log10, - expm1: Math.expm1 || expm1, - log1p: Math.log1p || log1p, - abs: Math.abs, - ceil: Math.ceil, - floor: Math.floor, - round: Math.round, - trunc: Math.trunc || trunc, - '-': neg, - '+': Number, - exp: Math.exp, - not: not, - length: stringOrArrayLength, - '!': factorial, - sign: Math.sign || sign - }; - - this.binaryOps = { - '+': add, - '-': sub, - '*': mul, - '/': div, - '%': mod, - '^': Math.pow, - '||': concat, - '==': equal, - '!=': notEqual, - '>': greaterThan, - '<': lessThan, - '>=': greaterThanEqual, - '<=': lessThanEqual, - and: andOperator, - or: orOperator, - 'in': inOperator, - '=': setVar, - '[': arrayIndex - }; - - this.ternaryOps = { - '?': condition - }; - - this.functions = { - random: random, - fac: factorial, - min: min, - max: max, - hypot: Math.hypot || hypot, - pyt: Math.hypot || hypot, // backward compat - pow: Math.pow, - atan2: Math.atan2, - 'if': condition, - gamma: gamma, - 'Γ': gamma, - roundTo: roundTo, - map: arrayMap, - fold: arrayFold, - filter: arrayFilter, - indexOf: stringOrArrayIndexOf, - join: arrayJoin - }; - - // These constants will automatically be replaced the MOMENT they are parsed. - // (Original consts from the parser) - this.builtinConsts = {}; - // These consts will only be replaced when the expression is evaluated. - this.consts = {} - - } - - parse(expr) { - var instr = []; - var parserState = new ParserState( - this, - new TokenStream(this, expr), - { allowMemberAccess: this.options.allowMemberAccess } - ); - - parserState.parseExpression(instr); - parserState.expect(TEOF, QT_TRANSLATE_NOOP('error','EOF')); - - return new Expression(instr, this); - } - - evaluate(expr, variables) { - return this.parse(expr).evaluate(variables); - } -}; - - -var sharedParser = new Parser(); - -Parser.parse = function (expr) { - return sharedParser.parse(expr); -}; - -Parser.evaluate = function (expr, variables) { - return sharedParser.parse(expr).evaluate(variables); -}; - -var optionNameMap = { - '+': 'add', - '-': 'subtract', - '*': 'multiply', - '/': 'divide', - '%': 'remainder', - '^': 'power', - '!': 'factorial', - '<': 'comparison', - '>': 'comparison', - '<=': 'comparison', - '>=': 'comparison', - '==': 'comparison', - '!=': 'comparison', - '||': 'concatenate', - 'and': 'logical', - 'or': 'logical', - 'not': 'logical', - '?': 'conditional', - ':': 'conditional', - //'=': 'assignment', // Disable assignment - '[': 'array', - //'()=': 'fndef' // Diable function definition -}; - -function getOptionName(op) { - return optionNameMap.hasOwnProperty(op) ? optionNameMap[op] : op; -} - -Parser.prototype.isOperatorEnabled = function (op) { - var optionName = getOptionName(op); - var operators = this.options.operators || {}; - - return !(optionName in operators) || !!operators[optionName]; -}; - -/*! - Based on ndef.parser, by Raphael Graf - http://www.undefined.ch/mparser/index.html - - Ported to JavaScript and modified by Matthew Crumley (http://silentmatt.com/) - - Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) - - You are free to use and modify this code in anyway you find useful. Please leave this comment in the code - to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, - but don't feel like you have to let me know or ask permission. -*/ - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs new file mode 100644 index 0000000..d7aba35 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs @@ -0,0 +1,540 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +import { + Instruction, + IOP3, IOP2, IOP1, + INUMBER, IARRAY, + IVAR, IVARNAME, + IEXPR, IEXPREVAL, + IMEMBER, IFUNCALL, + IENDSTATEMENT, + unaryInstruction, binaryInstruction, ternaryInstruction +} from "./instruction.mjs" + +/** + * Simplifies the given instructions + * @param {Instruction[]} tokens + * @param {Record.} unaryOps + * @param {Record.} binaryOps + * @param {Record.} ternaryOps + * @param {Record.} values + * @return {Instruction[]} + */ +function simplify(tokens, unaryOps, binaryOps, ternaryOps, values) { + const nstack = [] + const newexpression = [] + let n1, n2, n3 + let f + for(let i = 0; i < tokens.length; i++) { + let item = tokens[i] + const type = item.type + if(type === INUMBER || type === IVARNAME) { + if(Array.isArray(item.value)) { + nstack.push.apply(nstack, simplify(item.value.map(function(x) { + return new Instruction(INUMBER, x) + }).concat(new Instruction(IARRAY, item.value.length)), unaryOps, binaryOps, ternaryOps, values)) + } else { + nstack.push(item) + } + } else if(type === IVAR && values.hasOwnProperty(item.value)) { + item = new Instruction(INUMBER, values[item.value]) + nstack.push(item) + } else if(type === IOP2 && nstack.length > 1) { + n2 = nstack.pop() + n1 = nstack.pop() + f = binaryOps[item.value] + item = new Instruction(INUMBER, f(n1.value, n2.value)) + nstack.push(item) + } else if(type === IOP3 && nstack.length > 2) { + n3 = nstack.pop() + n2 = nstack.pop() + n1 = nstack.pop() + if(item.value === "?") { + nstack.push(n1.value ? n2.value : n3.value) + } else { + f = ternaryOps[item.value] + item = new Instruction(INUMBER, f(n1.value, n2.value, n3.value)) + nstack.push(item) + } + } else if(type === IOP1 && nstack.length > 0) { + n1 = nstack.pop() + f = unaryOps[item.value] + item = new Instruction(INUMBER, f(n1.value)) + nstack.push(item) + } else if(type === IEXPR) { + while(nstack.length > 0) { + newexpression.push(nstack.shift()) + } + newexpression.push(new Instruction(IEXPR, simplify(item.value, unaryOps, binaryOps, ternaryOps, values))) + } else if(type === IMEMBER && nstack.length > 0) { + n1 = nstack.pop() + if(item.value in n1.value) + nstack.push(new Instruction(INUMBER, n1.value[item.value])) + else + throw new Error(qsTranslate("error", "Cannot find property %1 of object %2.").arg(item.value).arg(n1)) + } else { + while(nstack.length > 0) { + newexpression.push(nstack.shift()) + } + newexpression.push(item) + } + } + while(nstack.length > 0) { + newexpression.push(nstack.shift()) + } + return newexpression +} + +/** + * In the given instructions, replaces variable by expr. + * @param {Instruction[]} tokens + * @param {string} variable + * @param {number} expr + * @return {Instruction[]} + */ +function substitute(tokens, variable, expr) { + const newexpression = [] + for(let i = 0; i < tokens.length; i++) { + let item = tokens[i] + const type = item.type + if(type === IVAR && item.value === variable) { + for(let j = 0; j < expr.tokens.length; j++) { + const expritem = expr.tokens[j] + let replitem + if(expritem.type === IOP1) { + replitem = unaryInstruction(expritem.value) + } else if(expritem.type === IOP2) { + replitem = binaryInstruction(expritem.value) + } else if(expritem.type === IOP3) { + replitem = ternaryInstruction(expritem.value) + } else { + replitem = new Instruction(expritem.type, expritem.value) + } + newexpression.push(replitem) + } + } else if(type === IEXPR) { + newexpression.push(new Instruction(IEXPR, substitute(item.value, variable, expr))) + } else { + newexpression.push(item) + } + } + return newexpression +} + +/** + * Evaluates the given instructions for a given Expression with given values. + * @param {Instruction[]} tokens + * @param {Expression} expr + * @param {Record.} values + * @return {number} + */ +function evaluate(tokens, expr, values) { + const nstack = [] + let n1, n2, n3 + let f, args, argCount + + if(isExpressionEvaluator(tokens)) { + return resolveExpression(tokens, values) + } + + for(let i = 0; i < tokens.length; i++) { + const item = tokens[i] + const type = item.type + if(type === INUMBER || type === IVARNAME) { + nstack.push(item.value) + } else if(type === IOP2) { + n2 = nstack.pop() + n1 = nstack.pop() + if(item.value === "and") { + nstack.push(n1 ? !!evaluate(n2, expr, values) : false) + } else if(item.value === "or") { + nstack.push(n1 ? true : !!evaluate(n2, expr, values)) + } else if(item.value === "=") { + f = expr.binaryOps[item.value] + nstack.push(f(n1, evaluate(n2, expr, values), values)) + } else { + f = expr.binaryOps[item.value] + nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values))) + } + } else if(type === IOP3) { + n3 = nstack.pop() + n2 = nstack.pop() + n1 = nstack.pop() + if(item.value === "?") { + nstack.push(evaluate(n1 ? n2 : n3, expr, values)) + } else { + f = expr.ternaryOps[item.value] + nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values), resolveExpression(n3, values))) + } + } else if(type === IVAR) { + // Check for variable value + if(/^__proto__|prototype|constructor$/.test(item.value)) { + throw new Error("WARNING: Prototype access detected and denied. If you downloaded this file from the internet, this file might be a virus.") + } else if(item.value in expr.functions) { + nstack.push(expr.functions[item.value]) + } else if(item.value in expr.unaryOps && expr.parser.isOperatorEnabled(item.value)) { + nstack.push(expr.unaryOps[item.value]) + } else { + const v = values[item.value] + if(v !== undefined) { + nstack.push(v) + } else { + throw new Error(qsTranslate("error", "Undefined variable %1.").arg(item.value)) + } + } + } else if(type === IOP1) { + n1 = nstack.pop() + f = expr.unaryOps[item.value] + nstack.push(f(resolveExpression(n1, values))) + } else if(type === IFUNCALL) { + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(resolveExpression(nstack.pop(), values)) + } + f = nstack.pop() + if(f.apply && f.call) { + nstack.push(f.apply(undefined, args)) + } else if(f.execute) { + // Objects & expressions execution + if(args.length >= 1) + nstack.push(f.execute.apply(f, args)) + else + throw new Error(qsTranslate("error", "In order to be executed, object %1 must have at least one argument.").arg(f)) + } else { + throw new Error(qsTranslate("error", "%1 cannot be executed.").arg(f)) + } + } else if(type === IEXPR) { + nstack.push(createExpressionEvaluator(item, expr)) + } else if(type === IEXPREVAL) { + nstack.push(item) + } else if(type === IMEMBER) { + n1 = nstack.pop() + if(item.value in n1) + if(n1[item.value].execute && n1[item.value].cached) + nstack.push(n1[item.value].execute()) + else + nstack.push(n1[item.value]) + else + throw new Error(qsTranslate("error", "Cannot find property %1 of object %2.").arg(item.value).arg(n1)) + } else if(type === IENDSTATEMENT) { + nstack.pop() + } else if(type === IARRAY) { + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(nstack.pop()) + } + nstack.push(args) + } else { + throw new Error(qsTranslate("error", "Invalid expression.")) + } + } + if(nstack.length > 1) { + throw new Error(qsTranslate("error", "Invalid expression (parity).")) + } + // Explicitly return zero to avoid test issues caused by -0 + return nstack[0] === 0 ? 0 : resolveExpression(nstack[0], values) +} + +function createExpressionEvaluator(token, expr) { + if(isExpressionEvaluator(token)) return token + return { + type: IEXPREVAL, + value: function(scope) { + return evaluate(token.value, expr, scope) + } + } +} + +function isExpressionEvaluator(n) { + return n && n.type === IEXPREVAL +} + +function resolveExpression(n, values) { + return isExpressionEvaluator(n) ? n.value(values) : n +} + +/** + * Converts the given instructions to a string + * If toJS is active, can be evaluated with eval, otherwise it can be reparsed by the parser. + * @param {Instruction[]} tokens + * @param {boolean} toJS + * @return {string} + */ +function expressionToString(tokens, toJS) { + let nstack = [] + let n1, n2, n3 + let f, args, argCount + for(let i = 0; i < tokens.length; i++) { + const item = tokens[i] + const type = item.type + if(type === INUMBER) { + if(typeof item.value === "number" && item.value < 0) { + nstack.push("(" + item.value + ")") + } else if(Array.isArray(item.value)) { + nstack.push("[" + item.value.map(escapeValue).join(", ") + "]") + } else { + nstack.push(escapeValue(item.value)) + } + } else if(type === IOP2) { + n2 = nstack.pop() + n1 = nstack.pop() + f = item.value + if(toJS) { + if(f === "^") { + nstack.push("Math.pow(" + n1 + ", " + n2 + ")") + } else if(f === "and") { + nstack.push("(!!" + n1 + " && !!" + n2 + ")") + } else if(f === "or") { + nstack.push("(!!" + n1 + " || !!" + n2 + ")") + } else if(f === "||") { + nstack.push("(function(a,b){ return Array.isArray(a) && Array.isArray(b) ? a.concat(b) : String(a) + String(b); }((" + n1 + "),(" + n2 + ")))") + } else if(f === "==") { + nstack.push("(" + n1 + " === " + n2 + ")") + } else if(f === "!=") { + nstack.push("(" + n1 + " !== " + n2 + ")") + } else if(f === "[") { + nstack.push(n1 + "[(" + n2 + ") | 0]") + } else { + nstack.push("(" + n1 + " " + f + " " + n2 + ")") + } + } else { + if(f === "[") { + nstack.push(n1 + "[" + n2 + "]") + } else { + nstack.push("(" + n1 + " " + f + " " + n2 + ")") + } + } + } else if(type === IOP3) { + n3 = nstack.pop() + n2 = nstack.pop() + n1 = nstack.pop() + f = item.value + if(f === "?") { + nstack.push("(" + n1 + " ? " + n2 + " : " + n3 + ")") + } else { + throw new Error(qsTranslate("error", "Invalid expression.")) + } + } else if(type === IVAR || type === IVARNAME) { + nstack.push(item.value) + } else if(type === IOP1) { + n1 = nstack.pop() + f = item.value + if(f === "-" || f === "+") { + nstack.push("(" + f + n1 + ")") + } else if(toJS) { + if(f === "not") { + nstack.push("(" + "!" + n1 + ")") + } else if(f === "!") { + nstack.push("fac(" + n1 + ")") + } else { + nstack.push(f + "(" + n1 + ")") + } + } else if(f === "!") { + nstack.push("(" + n1 + "!)") + } else { + nstack.push("(" + f + " " + n1 + ")") + } + } else if(type === IFUNCALL) { + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(nstack.pop()) + } + f = nstack.pop() + nstack.push(f + "(" + args.join(", ") + ")") + } else if(type === IMEMBER) { + n1 = nstack.pop() + nstack.push(n1 + "." + item.value) + } else if(type === IARRAY) { + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(nstack.pop()) + } + nstack.push("[" + args.join(", ") + "]") + } else if(type === IEXPR) { + nstack.push("(" + expressionToString(item.value, toJS) + ")") + } else if(type === IENDSTATEMENT) { + + } else { + throw new Error(qsTranslate("error", "Invalid expression.")) + } + } + if(nstack.length > 1) { + if(toJS) { + nstack = [nstack.join(",")] + } else { + nstack = [nstack.join(";")] + } + } + return String(nstack[0]) +} + +export function escapeValue(v) { + if(typeof v === "string") { + return JSON.stringify(v).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029") + } + return v +} + +/** + * Pushes all symbols from tokens into the symbols array. + * @param {Instruction[]} tokens + * @param {string[]} symbols + * @param {{withMembers: (boolean|undefined)}}options + */ +function getSymbols(tokens, symbols, options) { + options = options || {} + const withMembers = !!options.withMembers + let prevVar = null + + for(let i = 0; i < tokens.length; i++) { + const item = tokens[i] + if(item.type === IVAR || item.type === IVARNAME) { + if(!withMembers && !symbols.includes(item.value)) { + symbols.push(item.value) + } else if(prevVar !== null) { + if(!symbols.includes(prevVar)) { + symbols.push(prevVar) + } + prevVar = item.value + } else { + prevVar = item.value + } + } else if(item.type === IMEMBER && withMembers && prevVar !== null) { + prevVar += "." + item.value + } else if(item.type === IEXPR) { + getSymbols(item.value, symbols, options) + } else if(prevVar !== null) { + if(!symbols.includes(prevVar)) { + symbols.push(prevVar) + } + prevVar = null + } + } + + if(prevVar !== null && !symbols.includes(prevVar)) { + symbols.push(prevVar) + } +} + +export class Expression { + /** + * @param {Instruction[]} tokens + * @param {Parser} parser + */ + constructor(tokens, parser) { + this.tokens = tokens + this.parser = parser + this.unaryOps = parser.unaryOps + this.binaryOps = parser.binaryOps + this.ternaryOps = parser.ternaryOps + this.functions = parser.functions + } + + /** + * Simplifies the expression. + * @param {Object|undefined} values + * @returns {Expression} + */ + simplify(values) { + values = values || {} + return new Expression(simplify(this.tokens, this.unaryOps, this.binaryOps, this.ternaryOps, values), this.parser) + } + + /** + * Creates a new expression where the variable is substituted by the given expression. + * @param {string} variable + * @param {string|Expression} expr + * @returns {Expression} + */ + substitute(variable, expr) { + if(!(expr instanceof Expression)) { + expr = this.parser.parse(String(expr)) + } + + return new Expression(substitute(this.tokens, variable, expr), this.parser) + } + + /** + * Calculates the value of the expression by giving all variables and their corresponding values. + * @param {Object} values + * @returns {number} + */ + evaluate(values) { + values = Object.assign({}, values, this.parser.consts) + return evaluate(this.tokens, this, values) + } + + /** + * Returns a list of symbols (string of characters) in the expressions. + * Can be functions, constants, or variables. + * @returns {string[]} + */ + symbols(options) { + options = options || {} + const vars = [] + getSymbols(this.tokens, vars, options) + return vars + } + + toString() { + return expressionToString(this.tokens, false) + } + + + /** + * Returns the list of symbols (string of characters) which are not defined + * as constants or functions. + * @returns {string[]} + */ + variables(options) { + options = options || {} + const vars = [] + getSymbols(this.tokens, vars, options) + const functions = this.functions + const consts = this.parser.consts + return vars.filter((name) => { + return !(name in functions) && !(name in consts) + }) + } + + + /** + * Converts the expression to a JS function. + * @param {string} param - Parsed variables for the function. + * @param {Object.} variables - Default variables to provide. + * @returns {function(...any)} + */ + toJSFunction(param, variables) { + const expr = this + const f = new Function(param, "with(this.functions) with (this.ternaryOps) with (this.binaryOps) with (this.unaryOps) { return " + expressionToString(this.simplify(variables).tokens, true) + "; }") // eslint-disable-line no-new-func + return function() { + return f.apply(expr, arguments) + } + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs new file mode 100644 index 0000000..df0e2d7 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs @@ -0,0 +1,82 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +export const INUMBER = "INUMBER" +export const IOP1 = "IOP1" +export const IOP2 = "IOP2" +export const IOP3 = "IOP3" +export const IVAR = "IVAR" +export const IVARNAME = "IVARNAME" +export const IFUNCALL = "IFUNCALL" +export const IEXPR = "IEXPR" +export const IEXPREVAL = "IEXPREVAL" +export const IMEMBER = "IMEMBER" +export const IENDSTATEMENT = "IENDSTATEMENT" +export const IARRAY = "IARRAY" + + +export class Instruction { + /** + * + * @param {string} type + * @param {any} value + */ + constructor(type, value) { + this.type = type + this.value = (value !== undefined && value !== null) ? value : 0 + } + + toString() { + switch(this.type) { + case INUMBER: + case IOP1: + case IOP2: + case IOP3: + case IVAR: + case IVARNAME: + case IENDSTATEMENT: + return this.value + case IFUNCALL: + return "CALL " + this.value + case IARRAY: + return "ARRAY " + this.value + case IMEMBER: + return "." + this.value + default: + return "Invalid Instruction" + } + } +} + +export function unaryInstruction(value) { + return new Instruction(IOP1, value) +} + +export function binaryInstruction(value) { + return new Instruction(IOP2, value) +} + +export function ternaryInstruction(value) { + return new Instruction(IOP3, value) +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs similarity index 68% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs index 998ed32..244194f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs @@ -1,25 +1,23 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -.pragma library - -.import "expr-eval.js" as ExprEval -.import "../../modules.mjs" as M +import { Module } from "../../modules.mjs" +import { Parser } from "./parser.mjs" const evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually @@ -36,15 +34,14 @@ const evalVariables = { "false": false } -class ExprParserAPI extends M.Module { +export class ExprParserAPI extends Module { constructor() { - super('ExprParser', [ + super("ExprParser", [ /** @type {ObjectsAPI} */ Modules.Objects ]) this.currentVars = {} - this.Internals = ExprEval - this._parser = new ExprEval.Parser() + this._parser = new Parser() this._parser.consts = Object.assign({}, this._parser.consts, evalVariables) @@ -65,18 +62,18 @@ class ExprParserAPI extends M.Module { if(args.length === 1) { // Parse object f = args[0] - if(typeof f !== 'object' || !f.execute) - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) + if(typeof f !== "object" || !f.execute) + throw EvalError(qsTranslate("usage", "Usage: %1").arg(usage1)) let target = f f = (x) => target.execute(x) } else if(args.length === 2) { // Parse variable - [f,variable] = args - if(typeof f !== 'string' || typeof variable !== 'string') - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) + [f, variable] = args + if(typeof f !== "string" || typeof variable !== "string") + throw EvalError(qsTranslate("usage", "Usage: %1").arg(usage2)) f = this._parser.parse(f).toJSFunction(variable, this.currentVars) } else - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) return f } @@ -88,27 +85,27 @@ class ExprParserAPI extends M.Module { } integral(a, b, ...args) { - let usage1 = qsTranslate('usage', 'integral(, , )') - let usage2 = qsTranslate('usage', 'integral(, , , )') + let usage1 = qsTranslate("usage", "integral(, , )") + let usage2 = qsTranslate("usage", "integral(, , , )") let f = this.parseArgumentsForFunction(args, usage1, usage2) if(a == null || b == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) // https://en.wikipedia.org/wiki/Simpson%27s_rule // Simpler, faster than tokenizing the expression - return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) + return (b - a) / 6 * (f(a) + 4 * f((a + b) / 2) + f(b)) } derivative(...args) { - let usage1 = qsTranslate('usage', 'derivative(, )') - let usage2 = qsTranslate('usage', 'derivative(, , )') + let usage1 = qsTranslate("usage", "derivative(, )") + let usage2 = qsTranslate("usage", "derivative(, , )") let x = args.pop() let f = this.parseArgumentsForFunction(args, usage1, usage2) if(x == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) - let derivative_precision = x/10 - return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision + let derivative_precision = x / 10 + return (f(x + derivative_precision / 2) - f(x - derivative_precision / 2)) / derivative_precision } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs new file mode 100644 index 0000000..3336fcf --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs @@ -0,0 +1,172 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +import * as Polyfill from "./polyfill.mjs" +import { ParserState } from "./parserstate.mjs" +import { TEOF, TokenStream } from "./tokens.mjs" +import { Expression } from "./expression.mjs" + +const optionNameMap = { + "+": "add", + "-": "subtract", + "*": "multiply", + "/": "divide", + "%": "remainder", + "^": "power", + "!": "factorial", + "<": "comparison", + ">": "comparison", + "<=": "comparison", + ">=": "comparison", + "==": "comparison", + "!=": "comparison", + "||": "concatenate", + "and": "logical", + "or": "logical", + "not": "logical", + "?": "conditional", + ":": "conditional", + //'=': 'assignment', // Disable assignment + "[": "array" + //'()=': 'fndef' // Diable function definition +} + +export class Parser { + constructor(options) { + this.options = options || {} + this.unaryOps = { + sin: Math.sin, + cos: Math.cos, + tan: Math.tan, + asin: Math.asin, + acos: Math.acos, + atan: Math.atan, + sinh: Math.sinh || Polyfill.sinh, + cosh: Math.cosh || Polyfill.cosh, + tanh: Math.tanh || Polyfill.tanh, + asinh: Math.asinh || Polyfill.asinh, + acosh: Math.acosh || Polyfill.acosh, + atanh: Math.atanh || Polyfill.atanh, + sqrt: Math.sqrt, + cbrt: Math.cbrt || Polyfill.cbrt, + log: Math.log, + log2: Math.log2 || Polyfill.log2, + ln: Math.log, + lg: Math.log10 || Polyfill.log10, + log10: Math.log10 || Polyfill.log10, + expm1: Math.expm1 || Polyfill.expm1, + log1p: Math.log1p || Polyfill.log1p, + abs: Math.abs, + ceil: Math.ceil, + floor: Math.floor, + round: Math.round, + trunc: Math.trunc || Polyfill.trunc, + "-": Polyfill.neg, + "+": Number, + exp: Math.exp, + not: Polyfill.not, + length: Polyfill.stringOrArrayLength, + "!": Polyfill.factorial, + sign: Math.sign || Polyfill.sign + } + this.unaryOpsList = Object.keys(this.unaryOps) + + this.binaryOps = { + "+": Polyfill.add, + "-": Polyfill.sub, + "*": Polyfill.mul, + "/": Polyfill.div, + "%": Polyfill.mod, + "^": Math.pow, + "||": Polyfill.concat, + "==": Polyfill.equal, + "!=": Polyfill.notEqual, + ">": Polyfill.greaterThan, + "<": Polyfill.lessThan, + ">=": Polyfill.greaterThanEqual, + "<=": Polyfill.lessThanEqual, + and: Polyfill.andOperator, + or: Polyfill.orOperator, + "in": Polyfill.inOperator, + "=": Polyfill.setVar, + "[": Polyfill.arrayIndex + } + + this.ternaryOps = { + "?": Polyfill.condition + } + + this.functions = { + random: Polyfill.random, + fac: Polyfill.factorial, + min: Polyfill.min, + max: Polyfill.max, + hypot: Math.hypot || Polyfill.hypot, + pyt: Math.hypot || Polyfill.hypot, // backward compat + pow: Math.pow, + atan2: Math.atan2, + "if": Polyfill.condition, + gamma: Polyfill.gamma, + "Γ": Polyfill.gamma, + roundTo: Polyfill.roundTo, + map: Polyfill.arrayMap, + fold: Polyfill.arrayFold, + filter: Polyfill.arrayFilter, + indexOf: Polyfill.stringOrArrayIndexOf, + join: Polyfill.arrayJoin + } + + // These constants will automatically be replaced the MOMENT they are parsed. + // (Original consts from the parser) + this.builtinConsts = {} + // These consts will only be replaced when the expression is evaluated. + this.consts = {} + + } + + parse(expr) { + const instr = [] + const parserState = new ParserState( + this, + new TokenStream(this, expr), + { allowMemberAccess: this.options.allowMemberAccess } + ) + + parserState.parseExpression(instr) + parserState.expect(TEOF, QT_TRANSLATE_NOOP("error", "EOF")) + + return new Expression(instr, this) + } + + evaluate(expr, variables) { + return this.parse(expr).evaluate(variables) + } + + isOperatorEnabled(op) { + const optionName = optionNameMap.hasOwnProperty(op) ? optionNameMap[op] : op + const operators = this.options.operators || {} + + return !(optionName in operators) || !!operators[optionName] + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs new file mode 100644 index 0000000..801c424 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs @@ -0,0 +1,398 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +import { TBRACKET, TCOMMA, TEOF, TNAME, TNUMBER, TOP, TPAREN, TSTRING } from "./tokens.mjs" +import { + Instruction, + IARRAY, IEXPR, IFUNCALL, IMEMBER, + INUMBER, IVAR, + ternaryInstruction, binaryInstruction, unaryInstruction +} from "./instruction.mjs" + +const COMPARISON_OPERATORS = ["==", "!=", "<", "<=", ">=", ">", "in"] +const ADD_SUB_OPERATORS = ["+", "-", "||"] +const TERM_OPERATORS = ["*", "/", "%"] + +export class ParserState { + /** + * + * @param {Parser} parser + * @param {TokenStream} tokenStream + * @param {{[operators]: Object., [allowMemberAccess]: boolean}} options + */ + constructor(parser, tokenStream, options) { + this.parser = parser + this.tokens = tokenStream + this.current = null + this.nextToken = null + this.next() + this.savedCurrent = null + this.savedNextToken = null + this.allowMemberAccess = options.allowMemberAccess !== false + } + + /** + * Queries the next token for parsing. + * @return {Token} + */ + next() { + this.current = this.nextToken + this.nextToken = this.tokens.next() + return this.nextToken + } + + /** + * Checks if a given Token matches a condition (called if function, one of if array, and exact match otherwise) + * @param {Token} token + * @param {Array|function(Token): boolean|string|number|boolean} [value] + * @return {boolean} + */ + tokenMatches(token, value) { + if(typeof value === "undefined") { + return true + } else if(Array.isArray(value)) { + return value.includes(token.value) + } else if(typeof value === "function") { + return value(token) + } else { + return token.value === value + } + } + + /** + * Saves the current state (current and next token) to be restored later. + */ + save() { + this.savedCurrent = this.current + this.savedNextToken = this.nextToken + this.tokens.save() + } + + /** + * Restores a previous state (current and next token) from last save. + */ + restore() { + this.tokens.restore() + this.current = this.savedCurrent + this.nextToken = this.savedNextToken + } + + /** + * Checks if the next token matches the given type and value, and if so, consume the current token. + * Returns true if the check matches. + * @param {string} type + * @param {any} [value] + * @return {boolean} + */ + accept(type, value) { + if(this.nextToken.type === type && this.tokenMatches(this.nextToken, value)) { + this.next() + return true + } + return false + } + + /** + * Throws an error if the next token does not match the given type and value. Otherwise, consumes the current token. + * @param {string} type + * @param {any} [value] + */ + expect(type, value) { + if(!this.accept(type, value)) { + throw new Error(qsTranslate("error", "Parse error [position %1]: %2") + .arg(this.tokens.pos) + .arg(qsTranslate("error", "Expected %1").arg(value || type))) + } + } + + /** + * Converts enough Tokens to form an expression atom (generally the next part of the expression) into an instruction + * and pushes it to the instruction list. + * Throws an error if an unexpected token gets parsed. + * @param {Instruction[]} instr + */ + parseAtom(instr) { + const prefixOperators = this.tokens.unaryOpsList + + if(this.accept(TNAME) || this.accept(TOP, prefixOperators)) { + instr.push(new Instruction(IVAR, this.current.value)) + } else if(this.accept(TNUMBER)) { + instr.push(new Instruction(INUMBER, this.current.value)) + } else if(this.accept(TSTRING)) { + instr.push(new Instruction(INUMBER, this.current.value)) + } else if(this.accept(TPAREN, "(")) { + this.parseExpression(instr) + this.expect(TPAREN, ")") + } else if(this.accept(TBRACKET, "[")) { + if(this.accept(TBRACKET, "]")) { + instr.push(new Instruction(IARRAY, 0)) + } else { + const argCount = this.parseArrayList(instr) + instr.push(new Instruction(IARRAY, argCount)) + } + } else { + throw new Error(qsTranslate("error", "Unexpected %1").arg(this.nextToken)) + } + } + + /** + * Consumes the next tokens to compile a general expression which should return a value, and compiles + * the instructions into the list. + * @param {Instruction[]} instr + */ + parseExpression(instr) { + const exprInstr = [] + this.parseConditionalExpression(exprInstr) + instr.push(...exprInstr) + } + + /** + * Parses an array indice, and return the number of arguments found at the end. + * @param {Instruction[]} instr + * @return {number} + */ + parseArrayList(instr) { + let argCount = 0 + + while(!this.accept(TBRACKET, "]")) { + this.parseExpression(instr) + ++argCount + while(this.accept(TCOMMA)) { + this.parseExpression(instr) + ++argCount + } + } + + return argCount + } + + /** + * Parses a tertiary statement ( ? : ) and pushes it into the instruction + * list. + * @param {Instruction[]} instr + */ + parseConditionalExpression(instr) { + this.parseOrExpression(instr) + while(this.accept(TOP, "?")) { + const trueBranch = [] + const falseBranch = [] + this.parseConditionalExpression(trueBranch) + this.expect(TOP, ":") + this.parseConditionalExpression(falseBranch) + instr.push(new Instruction(IEXPR, trueBranch)) + instr.push(new Instruction(IEXPR, falseBranch)) + instr.push(ternaryInstruction("?")) + } + } + + /** + * Parses a binary or statement ( or ) and pushes it into the instruction list. + * @param {Instruction[]} instr + */ + parseOrExpression(instr) { + this.parseAndExpression(instr) + while(this.accept(TOP, "or")) { + const falseBranch = [] + this.parseAndExpression(falseBranch) + instr.push(new Instruction(IEXPR, falseBranch)) + instr.push(binaryInstruction("or")) + } + } + + /** + * Parses a binary and statement ( and ) and pushes it into the instruction list. + * @param {Instruction[]} instr + */ + parseAndExpression(instr) { + this.parseComparison(instr) + while(this.accept(TOP, "and")) { + const trueBranch = [] + this.parseComparison(trueBranch) + instr.push(new Instruction(IEXPR, trueBranch)) + instr.push(binaryInstruction("and")) + } + } + + /** + * Parses a binary equality statement ( == and so on) and pushes it into the instruction list. + * @param {Instruction[]} instr + */ + parseComparison(instr) { + this.parseAddSub(instr) + while(this.accept(TOP, COMPARISON_OPERATORS)) { + const op = this.current + this.parseAddSub(instr) + instr.push(binaryInstruction(op.value)) + } + } + + /** + * Parses add, minus and concat operations and pushes them into the instruction list. + * @param {Instruction[]} instr + */ + parseAddSub(instr) { + this.parseTerm(instr) + while(this.accept(TOP, ADD_SUB_OPERATORS)) { + const op = this.current + this.parseTerm(instr) + instr.push(binaryInstruction(op.value)) + } + } + + /** + * Parses times, divide and modulo operations and pushes them into the instruction list. + * @param {Instruction[]} instr + */ + parseTerm(instr) { + this.parseFactor(instr) + while(this.accept(TOP, TERM_OPERATORS)) { + const op = this.current + this.parseFactor(instr) + instr.push(binaryInstruction(op.value)) + } + } + + /** + * Parses prefix operations (+, -, but also functions like sin or cos which don't need parentheses) + * @param {Instruction[]} instr + */ + parseFactor(instr) { + const prefixOperators = this.tokens.unaryOpsList + + this.save() + if(this.accept(TOP, prefixOperators)) { + if(this.current.value !== "-" && this.current.value !== "+") { + if(this.nextToken.type === TPAREN && this.nextToken.value === "(") { + this.restore() + this.parseExponential(instr) + return + } else if(this.nextToken.type === TCOMMA || this.nextToken.type === TEOF || (this.nextToken.type === TPAREN && this.nextToken.value === ")")) { + this.restore() + this.parseAtom(instr) + return + } + } + + const op = this.current + this.parseFactor(instr) + instr.push(unaryInstruction(op.value)) + } else { + this.parseExponential(instr) + } + } + + /** + * + * @param {Instruction[]} instr + */ + parseExponential(instr) { + this.parsePostfixExpression(instr) + while(this.accept(TOP, "^")) { + this.parseFactor(instr) + instr.push(binaryInstruction("^")) + } + } + + + /** + * Parses factorial '!' (after the expression to apply it to). + * @param {Instruction[]} instr + */ + parsePostfixExpression(instr) { + this.parseFunctionCall(instr) + while(this.accept(TOP, "!")) { + instr.push(unaryInstruction("!")) + } + } + + /** + * Parse a function (name + parentheses + arguments). + * @param {Instruction[]} instr + */ + parseFunctionCall(instr) { + const prefixOperators = this.tokens.unaryOpsList + + if(this.accept(TOP, prefixOperators)) { + const op = this.current + this.parseAtom(instr) + instr.push(unaryInstruction(op.value)) + } else { + this.parseMemberExpression(instr) + while(this.accept(TPAREN, "(")) { + if(this.accept(TPAREN, ")")) { + instr.push(new Instruction(IFUNCALL, 0)) + } else { + const argCount = this.parseArgumentList(instr) + instr.push(new Instruction(IFUNCALL, argCount)) + } + } + } + } + + /** + * Parses a list of arguments, return their quantity. + * @param {Instruction[]} instr + * @return {number} + */ + parseArgumentList(instr) { + let argCount = 0 + + while(!this.accept(TPAREN, ")")) { + this.parseExpression(instr) + ++argCount + while(this.accept(TCOMMA)) { + this.parseExpression(instr) + ++argCount + } + } + + return argCount + } + + parseMemberExpression(instr) { + this.parseAtom(instr) + while(this.accept(TOP, ".") || this.accept(TBRACKET, "[")) { + const op = this.current + + if(op.value === ".") { + if(!this.allowMemberAccess) { + throw new Error(qsTranslate("error", "Unexpected \".\": member access is not permitted")) + } + + this.expect(TNAME) + instr.push(new Instruction(IMEMBER, this.current.value)) + } else if(op.value === "[") { + if(!this.tokens.isOperatorEnabled("[")) { + throw new Error(qsTranslate("error", "Unexpected \"[]\": arrays are disabled.")) + } + + this.parseExpression(instr) + this.expect(TBRACKET, "]") + instr.push(binaryInstruction("[")) + } else { + throw new Error(qsTranslate("error", "Unexpected symbol: %1.").arg(op.value)) + } + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs new file mode 100644 index 0000000..9e8e885 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs @@ -0,0 +1,371 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +export function add(a, b) { + return Number(a) + Number(b) +} + +export function sub(a, b) { + return a - b +} + +export function mul(a, b) { + return a * b +} + +export function div(a, b) { + return a / b +} + +export function mod(a, b) { + return a % b +} + +export function concat(a, b) { + if(Array.isArray(a) && Array.isArray(b)) { + return a.concat(b) + } + return "" + a + b +} + +export function equal(a, b) { + return a === b +} + +export function notEqual(a, b) { + return a !== b +} + +export function greaterThan(a, b) { + return a > b +} + +export function lessThan(a, b) { + return a < b +} + +export function greaterThanEqual(a, b) { + return a >= b +} + +export function lessThanEqual(a, b) { + return a <= b +} + +export function andOperator(a, b) { + return Boolean(a && b) +} + +export function orOperator(a, b) { + return Boolean(a || b) +} + +export function inOperator(a, b) { + return b.includes(a) +} + +export function sinh(a) { + return ((Math.exp(a) - Math.exp(-a)) / 2) +} + +export function cosh(a) { + return ((Math.exp(a) + Math.exp(-a)) / 2) +} + +export function tanh(a) { + if(a === Infinity) return 1 + if(a === -Infinity) return -1 + return (Math.exp(a) - Math.exp(-a)) / (Math.exp(a) + Math.exp(-a)) +} + +export function asinh(a) { + if(a === -Infinity) return a + return Math.log(a + Math.sqrt((a * a) + 1)) +} + +export function acosh(a) { + return Math.log(a + Math.sqrt((a * a) - 1)) +} + +export function atanh(a) { + return (Math.log((1 + a) / (1 - a)) / 2) +} + +export function log10(a) { + return Math.log(a) * Math.LOG10E +} + +export function neg(a) { + return -a +} + +export function not(a) { + return !a +} + +export function trunc(a) { + return a < 0 ? Math.ceil(a) : Math.floor(a) +} + +export function random(a) { + return Math.random() * (a || 1) +} + +export function factorial(a) { // a! + return gamma(a + 1) +} + +export function isInteger(value) { + return isFinite(value) && (value === Math.round(value)) +} + +const GAMMA_G = 4.7421875 +const GAMMA_P = [ + 0.99999999999999709182, + 57.156235665862923517, -59.597960355475491248, + 14.136097974741747174, -0.49191381609762019978, + 0.33994649984811888699e-4, + 0.46523628927048575665e-4, -0.98374475304879564677e-4, + 0.15808870322491248884e-3, -0.21026444172410488319e-3, + 0.21743961811521264320e-3, -0.16431810653676389022e-3, + 0.84418223983852743293e-4, -0.26190838401581408670e-4, + 0.36899182659531622704e-5 +] + +// Gamma function from math.js +export function gamma(n) { + let t, x + + if(isInteger(n)) { + if(n <= 0) { + return isFinite(n) ? Infinity : NaN + } + + if(n > 171) { + return Infinity // Will overflow + } + + let value = n - 2 + let res = n - 1 + while(value > 1) { + res *= value + value-- + } + + if(res === 0) { + res = 1 // 0! is per definition 1 + } + + return res + } + + if(n < 0.5) { + return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)) + } + + if(n >= 171.35) { + return Infinity // will overflow + } + + if(n > 85.0) { // Extended Stirling Approx + const twoN = n * n + const threeN = twoN * n + const fourN = threeN * n + const fiveN = fourN * n + return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) * + (1 + (1 / (12 * n)) + (1 / (288 * twoN)) - (139 / (51840 * threeN)) - + (571 / (2488320 * fourN)) + (163879 / (209018880 * fiveN)) + + (5246819 / (75246796800 * fiveN * n))) + } + + --n + x = GAMMA_P[0] + for(let i = 1; i < GAMMA_P.length; ++i) { + x += GAMMA_P[i] / (n + i) + } + + t = n + GAMMA_G + 0.5 + return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x +} + +export function stringOrArrayLength(s) { + if(Array.isArray(s)) { + return s.length + } + return String(s).length +} + +export function hypot() { + let sum = 0 + let larg = 0 + for(let i = 0; i < arguments.length; i++) { + const arg = Math.abs(arguments[i]) + let div + if(larg < arg) { + div = larg / arg + sum = (sum * div * div) + 1 + larg = arg + } else if(arg > 0) { + div = arg / larg + sum += div * div + } else { + sum += arg + } + } + return larg === Infinity ? Infinity : larg * Math.sqrt(sum) +} + +export function condition(cond, yep, nope) { + return cond ? yep : nope +} + +/** + * Decimal adjustment of a number. + * From @escopecz. + * + * @param {number} value - The number. + * @param {Integer} exp - The exponent (the 10 logarithm of the adjustment base). + * @return {number} - The adjusted value. + */ +export function roundTo(value, exp) { + // If the exp is undefined or zero... + if(typeof exp === "undefined" || +exp === 0) { + return Math.round(value) + } + value = +value + exp = -(+exp) + // If the value is not a number or the exp is not an integer... + if(isNaN(value) || !(typeof exp === "number" && exp % 1 === 0)) { + return NaN + } + // Shift + value = value.toString().split("e") + value = Math.round(+(value[0] + "e" + (value[1] ? (+value[1] - exp) : -exp))) + // Shift back + value = value.toString().split("e") + return +(value[0] + "e" + (value[1] ? (+value[1] + exp) : exp)) +} + +export function setVar(name, value, variables) { + if(variables) variables[name] = value + return value +} + +export function arrayIndex(array, index) { + return array[index | 0] +} + +export function max(array) { + if(arguments.length === 1 && Array.isArray(array)) { + return Math.max.apply(Math, array) + } else if(arguments.length >= 1) { + return Math.max.apply(Math, arguments) + } else { + throw new EvalError(qsTranslate("error", "Function %1 must have at least one argument.").arg("max")) + } +} + +export function min(array) { + if(arguments.length === 1 && Array.isArray(array)) { + return Math.min.apply(Math, array) + } else if(arguments.length >= 1) { + return Math.min.apply(Math, arguments) + } else { + throw new EvalError(qsTranslate("error", "Function %1 must have at least one argument.").arg("min")) + } +} + +export function arrayMap(f, a) { + if(typeof f !== "function") { + throw new EvalError(qsTranslate("error", "First argument to map is not a function.")) + } + if(!Array.isArray(a)) { + throw new EvalError(qsTranslate("error", "Second argument to map is not an array.")) + } + return a.map(function(x, i) { + return f(x, i) + }) +} + +export function arrayFold(f, init, a) { + if(typeof f !== "function") { + throw new EvalError(qsTranslate("error", "First argument to fold is not a function.")) + } + if(!Array.isArray(a)) { + throw new EvalError(qsTranslate("error", "Second argument to fold is not an array.")) + } + return a.reduce(function(acc, x, i) { + return f(acc, x, i) + }, init) +} + +export function arrayFilter(f, a) { + if(typeof f !== "function") { + throw new EvalError(qsTranslate("error", "First argument to filter is not a function.")) + } + if(!Array.isArray(a)) { + throw new EvalError(qsTranslate("error", "Second argument to filter is not an array.")) + } + return a.filter(function(x, i) { + return f(x, i) + }) +} + +export function stringOrArrayIndexOf(target, s) { + if(!(Array.isArray(s) || typeof s === "string")) { + throw new Error(qsTranslate("error", "Second argument to indexOf is not a string or array.")) + } + + return s.indexOf(target) +} + +export function arrayJoin(sep, a) { + if(!Array.isArray(a)) { + throw new Error(qsTranslate("error", "Second argument to join is not an array.")) + } + + return a.join(sep) +} + +export function sign(x) { + return ((x > 0) - (x < 0)) || +x +} + +const ONE_THIRD = 1 / 3 + +export function cbrt(x) { + return x < 0 ? -Math.pow(-x, ONE_THIRD) : Math.pow(x, ONE_THIRD) +} + +export function expm1(x) { + return Math.exp(x) - 1 +} + +export function log1p(x) { + return Math.log(1 + x) +} + +export function log2(x) { + return Math.log(x) / Math.LN2 +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs new file mode 100644 index 0000000..919433c --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs @@ -0,0 +1,575 @@ +/** + * Based on ndef.parser, by Raphael Graf + * http://www.undefined.ch/mparser/index.html + * + * Ported to JavaScript and modified by Matthew Crumley + * https://silentmatt.com/javascript-expression-evaluator/ + * + * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) + * + * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * You are free to use and modify this code in anyway you find useful. Please leave this comment in the code + * to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, + * but don't feel like you have to let me know or ask permission. + */ + +export const TEOF = "TEOF" +export const TOP = "TOP" +export const TNUMBER = "TNUMBER" +export const TSTRING = "TSTRING" +export const TPAREN = "TPAREN" +export const TBRACKET = "TBRACKET" +export const TCOMMA = "TCOMMA" +export const TNAME = "TNAME" + + +// Additional variable characters. +export const ADDITIONAL_VARCHARS = [ + "α", "β", "γ", "δ", "ε", "ζ", "η", + "π", "θ", "κ", "λ", "μ", "ξ", "ρ", + "ς", "σ", "τ", "φ", "χ", "ψ", "ω", + "Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Σ", + "Φ", "Ψ", "Ω", "ₐ", "ₑ", "ₒ", "ₓ", + "ₕ", "ₖ", "ₗ", "ₘ", "ₙ", "ₚ", "ₛ", + "ₜ", "¹", "²", "³", "⁴", "⁵", "⁶", + "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", + "₄", "₅", "₆", "₇", "₈", "₉", "₀", + "∞", "π" +] + +export class Token { + /** + * + * @param {string} type - Type of the token (see above). + * @param {any} value - Value of the token. + * @param {number} index - Index in the string of the token. + */ + constructor(type, value, index) { + this.type = type + this.value = value + this.index = index + } + + toString() { + return this.type + ": " + this.value + } +} + +const unicodeCodePointPattern = /^[0-9a-f]{4}$/i + +export class TokenStream { + /** + * + * @param {Parser} parser + * @param {string} expression + */ + constructor(parser, expression) { + this.pos = 0 + this.current = null + this.unaryOps = parser.unaryOps + this.unaryOpsList = parser.unaryOpsList + this.binaryOps = parser.binaryOps + this.ternaryOps = parser.ternaryOps + this.builtinConsts = parser.builtinConsts + this.expression = expression + this.savedPosition = 0 + this.savedCurrent = null + this.options = parser.options + this.parser = parser + } + + /** + * + * @param {string} type - Type of the token (see above). + * @param {any} value - Value of the token. + * @param {number} [pos] - Index in the string of the token. + */ + newToken(type, value, pos) { + return new Token(type, value, pos != null ? pos : this.pos) + } + + /** + * Saves the current position and token into the object. + */ + save() { + this.savedPosition = this.pos + this.savedCurrent = this.current + } + + + /** + * Restored the saved position and token into the current. + */ + restore() { + this.pos = this.savedPosition + this.current = this.savedCurrent + } + + /** + * Consumes the character at the current position and advance it + * until it makes a valid token, and returns it. + * @returns {Token} + */ + next() { + if(this.pos >= this.expression.length) { + return this.newToken(TEOF, "EOF") + } + + if(this.isWhitespace()) { + return this.next() + } else if(this.isRadixInteger() || + this.isNumber() || + this.isOperator() || + this.isString() || + this.isParen() || + this.isBracket() || + this.isComma() || + this.isNamedOp() || + this.isConst() || + this.isName()) { + return this.current + } else { + this.parseError(qsTranslate("error", "Unknown character \"%1\".").arg(this.expression.charAt(this.pos))) + } + } + + /** + * Checks if the character at the current position starts a string, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isString() { + const startPos = this.pos + const quote = this.expression.charAt(startPos) + let r = false + + if(quote === "'" || quote === "\"") { + let index = this.expression.indexOf(quote, startPos + 1) + while(index >= 0 && this.pos < this.expression.length) { + this.pos = index + 1 + if(this.expression.charAt(index - 1) !== "\\") { + const rawString = this.expression.substring(startPos + 1, index) + this.current = this.newToken(TSTRING, this.unescape(rawString), startPos) + r = true + break + } + index = this.expression.indexOf(quote, index + 1) + } + } + return r + } + + /** + * Checks if the character at the current pos is a parenthesis, and if so consumes it into current + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isParen() { + const c = this.expression.charAt(this.pos) + if(c === "(" || c === ")") { + this.current = this.newToken(TPAREN, c) + this.pos++ + return true + } + return false + } + + /** + * Checks if the character at the current pos is a bracket, and if so consumes it into current + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isBracket() { + const c = this.expression.charAt(this.pos) + if((c === "[" || c === "]") && this.isOperatorEnabled("[")) { + this.current = this.newToken(TBRACKET, c) + this.pos++ + return true + } + return false + } + + /** + * Checks if the character at the current pos is a comma, and if so consumes it into current + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isComma() { + const c = this.expression.charAt(this.pos) + if(c === ",") { + this.current = this.newToken(TCOMMA, ",") + this.pos++ + return true + } + return false + } + + /** + * Checks if the current character is an identifier and makes a const, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isConst() { + const startPos = this.pos + let i = startPos + for(; i < this.expression.length; i++) { + const c = this.expression.charAt(i) + if(c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { + if(i === this.pos || (c !== "_" && c !== "." && (c < "0" || c > "9"))) { + break + } + } + } + if(i > startPos) { + const str = this.expression.substring(startPos, i) + if(str in this.builtinConsts) { + this.current = this.newToken(TNUMBER, this.builtinConsts[str]) + this.pos += str.length + return true + } + } + return false + } + + /** + * Checks if the current character is an identifier and makes a function or an operator, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isNamedOp() { + const startPos = this.pos + let i = startPos + for(; i < this.expression.length; i++) { + const c = this.expression.charAt(i) + if(c.toUpperCase() === c.toLowerCase()) { + if(i === this.pos || (c !== "_" && (c < "0" || c > "9"))) { + break + } + } + } + if(i > startPos) { + const str = this.expression.substring(startPos, i) + if(this.isOperatorEnabled(str) && (str in this.binaryOps || str in this.unaryOps || str in this.ternaryOps)) { + this.current = this.newToken(TOP, str) + this.pos += str.length + return true + } + } + return false + } + + /** + * Checks if the current character is an identifier and makes a variable, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isName() { + const startPos = this.pos + let i = startPos + let hasLetter = false + for(; i < this.expression.length; i++) { + const c = this.expression.charAt(i) + if(c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { + if(i === this.pos && (c === "$" || c === "_")) { + if(c === "_") { + hasLetter = true + } + } else if(i === this.pos || !hasLetter || (c !== "_" && (c < "0" || c > "9"))) { + break + } + } else { + hasLetter = true + } + } + if(hasLetter) { + const str = this.expression.substring(startPos, i) + this.current = this.newToken(TNAME, str) + this.pos += str.length + return true + } + return false + } + + /** + * Checks if the character at the current position is a whitespace, and if so, consumes all consecutive whitespaces + * and returns true. Otherwise, returns false. + * @returns {boolean} + * + */ + isWhitespace() { + let r = false + let c = this.expression.charAt(this.pos) + while(c === " " || c === "\t" || c === "\n" || c === "\r") { + r = true + this.pos++ + if(this.pos >= this.expression.length) { + break + } + c = this.expression.charAt(this.pos) + } + return r + } + + /** + * Checks if the current character is a zero, and checks whether it forms a radix number, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isRadixInteger() { + let pos = this.pos + + if(pos >= this.expression.length - 2 || this.expression.charAt(pos) !== "0") { + return false + } + ++pos + + let radix + let validDigit + if(this.expression.charAt(pos) === "x") { + radix = 16 + validDigit = /^[0-9a-f]$/i + pos++ + } else if(this.expression.charAt(pos) === "b") { + radix = 2 + validDigit = /^[01]$/i + pos++ + } else { + return false + } + + let valid = false + const startPos = pos + + while(pos < this.expression.length) { + const c = this.expression.charAt(pos) + if(validDigit.test(c)) { + pos++ + valid = true + } else { + break + } + } + + if(valid) { + this.current = this.newToken(TNUMBER, parseInt(this.expression.substring(startPos, pos), radix)) + this.pos = pos + } + return valid + } + + /** + * Checks if the current character is a digit, and checks whether it forms a number, and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @returns {boolean} + */ + isNumber() { + const startPos = this.pos + let valid = false + let pos = startPos + let resetPos = startPos + let foundDot = false + let foundDigits = false + let c + + // Check for digit with dot. + while(pos < this.expression.length) { + c = this.expression.charAt(pos) + if((c >= "0" && c <= "9") || (!foundDot && c === ".")) { + if(c === ".") { + foundDot = true + } else { + foundDigits = true + } + pos++ + valid = foundDigits + } else { + break + } + } + + if(valid) { + resetPos = pos + } + + // Check for e exponents. + if(c === "e" || c === "E") { + pos++ + let acceptSign = true + let validExponent = false + while(pos < this.expression.length) { + c = this.expression.charAt(pos) + if(acceptSign && (c === "+" || c === "-")) { + acceptSign = false + } else if(c >= "0" && c <= "9") { + validExponent = true + acceptSign = false + } else { + break + } + pos++ + } + + if(!validExponent) { + pos = resetPos + } + } + + // Use parseFloat now that we've identified the number. + if(valid) { + this.current = this.newToken(TNUMBER, parseFloat(this.expression.substring(startPos, pos))) + this.pos = pos + } else { + this.pos = resetPos + } + return valid + } + + /** + * Checks if the current character is an operator, checks whether it's enabled and if so, consumes it as the current token + * and returns true. Otherwise, returns false. + * @return {boolean} + */ + isOperator() { + const startPos = this.pos + const c = this.expression.charAt(this.pos) + + if(c === "+" || c === "-" || c === "*" || c === "/" || c === "%" || c === "^" || c === "?" || c === ":" || c === ".") { + this.current = this.newToken(TOP, c) + } else if(c === "∙" || c === "•") { + this.current = this.newToken(TOP, "*") + } else if(c === ">") { + if(this.expression.charAt(this.pos + 1) === "=") { + this.current = this.newToken(TOP, ">=") + this.pos++ + } else { + this.current = this.newToken(TOP, ">") + } + } else if(c === "<") { + if(this.expression.charAt(this.pos + 1) === "=") { + this.current = this.newToken(TOP, "<=") + this.pos++ + } else { + this.current = this.newToken(TOP, "<") + } + } else if(c === "|") { + if(this.expression.charAt(this.pos + 1) === "|") { + this.current = this.newToken(TOP, "||") + this.pos++ + } else { + return false + } + } else if(c === "=") { + if(this.expression.charAt(this.pos + 1) === "=") { + this.current = this.newToken(TOP, "==") + this.pos++ + } else { + this.current = this.newToken(TOP, c) + } + } else if(c === "!") { + if(this.expression.charAt(this.pos + 1) === "=") { + this.current = this.newToken(TOP, "!=") + this.pos++ + } else { + this.current = this.newToken(TOP, c) + } + } else { + return false + } + this.pos++ + + if(this.isOperatorEnabled(this.current.value)) { + return true + } else { + this.pos = startPos + return false + } + } + + /** + * Replaces a backslash and a character by its unescaped value. + * @param {string} v - string to un escape. + */ + unescape(v) { + let index = v.indexOf("\\") + if(index < 0) { + return v + } + + let buffer = v.substring(0, index) + while(index >= 0) { + const c = v.charAt(++index) + switch(c) { + case "'": + buffer += "'" + break + case "\"": + buffer += "\"" + break + case "\\": + buffer += "\\" + break + case "/": + buffer += "/" + break + case "b": + buffer += "\b" + break + case "f": + buffer += "\f" + break + case "n": + buffer += "\n" + break + case "r": + buffer += "\r" + break + case "t": + buffer += "\t" + break + case "u": + // interpret the following 4 characters as the hex of the unicode code point + const codePoint = v.substring(index + 1, index + 5) + if(!unicodeCodePointPattern.test(codePoint)) { + this.parseError(qsTranslate("error", "Illegal escape sequence: %1.").arg("\\u" + codePoint)) + } + buffer += String.fromCharCode(parseInt(codePoint, 16)) + index += 4 + break + default: + throw this.parseError(qsTranslate("error", "Illegal escape sequence: %1.").arg("\\" + c)) + } + ++index + const backslash = v.indexOf("\\", index) + buffer += v.substring(index, backslash < 0 ? v.length : backslash) + index = backslash + } + + return buffer + } + + /** + * Shorthand for the parser's method to check if an operator is enabled. + * @param {string} op + * @return {boolean} + */ + isOperatorEnabled(op) { + return this.parser.isOperatorEnabled(op) + } + + /** + * Throws a translated error. + * @param {string} msg + */ + parseError(msg) { + throw new Error(qsTranslate("error", "Parse error [position %1]: %2").arg(this.pos).arg(msg)) + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index 306f5be..ad4c1f2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -1,50 +1,52 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import { Module } from '../modules.mjs' +import { Module } from "../modules.mjs" +import * as Instruction from "../lib/expr-eval/instruction.mjs" +import { escapeValue } from "../lib/expr-eval/expression.mjs" -const unicodechars = ["α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀", +const unicodechars = ["α", "β", "γ", "δ", "ε", "ζ", "η", + "π", "θ", "κ", "λ", "μ", "ξ", "ρ", + "ς", "σ", "τ", "φ", "χ", "ψ", "ω", + "Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Σ", + "Φ", "Ψ", "Ω", "ₐ", "ₑ", "ₒ", "ₓ", + "ₕ", "ₖ", "ₗ", "ₘ", "ₙ", "ₚ", "ₛ", + "ₜ", "¹", "²", "³", "⁴", "⁵", "⁶", + "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", + "₄", "₅", "₆", "₇", "₈", "₉", "₀", "pi", "∞"] -const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", - "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", - "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", - "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", - "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", - "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", - "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", - "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", - "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", +const equivalchars = ["\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", + "\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho", + "\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega", + "\\Gamma", "\\Delta", "\\Theta", "\\Lambda", "\\Xi", "\\Pi", "\\Sigma", + "\\Phy", "\\Psi", "\\Omega", "{}_{a}", "{}_{e}", "{}_{o}", "{}_{x}", + "{}_{h}", "{}_{k}", "{}_{l}", "{}_{m}", "{}_{n}", "{}_{p}", "{}_{s}", + "{}_{t}", "{}^{1}", "{}^{2}", "{}^{3}", "{}^{4}", "{}^{5}", "{}^{6}", + "{}^{7}", "{}^{8}", "{}^{9}", "{}^{0}", "{}_{1}", "{}_{2}", "{}_{3}", + "{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}", "\\pi", "\\infty"] /** * Class containing the result of a LaTeX render. - * + * * @property {string} source - Exported PNG file - * @property {number} width - * @property {number} height + * @property {number} width + * @property {number} height */ class LatexRenderResult { constructor(source, width, height) { @@ -56,7 +58,7 @@ class LatexRenderResult { class LatexAPI extends Module { constructor() { - super('Latex', [ + super("Latex", [ /** @type {ExprParserAPI} */ Modules.ExprParser ]) @@ -65,10 +67,10 @@ class LatexAPI extends Module { */ this.enabled = Helper.getSettingBool("enable_latex") } - + /** * Prepares and renders a latex string into a png file. - * + * * @param {string} markup - LaTeX markup to render. * @param {number} fontSize - Font size (in pt) to render. * @param {color} color - Color of the text to render. @@ -78,11 +80,11 @@ class LatexAPI extends Module { let args = Latex.render(markup, fontSize, color).split(",") return new LatexRenderResult(...args) } - + /** * Checks if the given markup (with given font size and color) has already been * rendered, and if so, returns its data. Otherwise, returns null. - * + * * @param {string} markup - LaTeX markup to render. * @param {number} fontSize - Font size (in pt) to render. * @param {color} color - Color of the text to render. @@ -95,14 +97,14 @@ class LatexAPI extends Module { ret = new LatexRenderResult(...data.split(",")) return ret } - + /** * Prepares and renders a latex string into a png file asynchronously. - * + * * @param {string} markup - LaTeX markup to render. * @param {number} fontSize - Font size (in pt) to render. * @param {color} color - Color of the text to render. - * @returns {Promize} + * @returns {Promise} */ requestAsyncRender(markup, fontSize, color) { return new Promise(resolve => { @@ -113,11 +115,11 @@ class LatexAPI extends Module { /** * Puts element within parenthesis. * - * @param {string} elem - element to put within parenthesis. + * @param {string|number} elem - element to put within parenthesis. * @returns {string} */ par(elem) { - return '(' + elem + ')' + return `(${elem})` } /** @@ -125,16 +127,16 @@ class LatexAPI extends Module { * the string array contents, but not at the first position of the string, * and returns the parenthesis version if so. * - * @param {string} elem - element to put within parenthesis. + * @param {string|number} elem - element to put within parenthesis. * @param {Array} contents - Array of elements to put within parenthesis. * @returns {string} */ parif(elem, contents) { elem = elem.toString() - if(elem[0] !== "(" && elem[elem.length-1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) + if(elem[0] !== "(" && elem[elem.length - 1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) return this.par(elem) - if(elem[0] === "(" && elem[elem.length-1] === ")") - return elem.substr(1, elem.length-2) + if(elem[0] === "(" && elem[elem.length - 1] === ")") + return elem.substr(1, elem.length - 2) return elem } @@ -149,31 +151,24 @@ class LatexAPI extends Module { switch(f) { case "derivative": if(args.length === 3) - return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; + return "\\frac{d" + args[0].substr(1, args[0].length - 2).replace(new RegExp(args[1].substr(1, args[1].length - 2), "g"), "x") + "}{dx}" else - return '\\frac{d' + args[0] + '}{dx}(x)'; - break; + return "\\frac{d" + args[0] + "}{dx}(x)" case "integral": if(args.length === 4) - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); + return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2].substr(1, args[2].length - 2) + " d" + args[3].substr(1, args[3].length - 2) else - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; - break; + return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2] + "(t) dt" case "sqrt": - return '\\sqrt\\left(' + args.join(', ') + '\\right)'; - break; + return "\\sqrt\\left(" + args.join(", ") + "\\right)" case "abs": - return '\\left|' + args.join(', ') + '\\right|'; - break; + return "\\left|" + args.join(", ") + "\\right|" case "floor": - return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; - break; + return "\\left\\lfloor" + args.join(", ") + "\\right\\rfloor" case "ceil": - return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; - break; + return "\\left\\lceil" + args.join(", ") + "\\right\\rceil" default: - return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; - break; + return "\\mathrm{" + f + "}\\left(" + args.join(", ") + "\\right)" } } @@ -188,150 +183,146 @@ class LatexAPI extends Module { if(wrapIn$) for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') + vari = vari.replace(new RegExp(unicodechars[i], "g"), "$" + equivalchars[i] + "$") } else for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) + vari = vari.replace(new RegExp(unicodechars[i], "g"), equivalchars[i]) } - return vari; + return vari } /** - * Converts expr-eval tokens to a latex string. + * Converts expr-eval instructions to a latex string. * - * @param {Array} tokens - expr-eval tokens list + * @param {Instruction[]} instructions - expr-eval tokens list * @returns {string} */ - expression(tokens) { + expression(instructions) { let nstack = [] let n1, n2, n3 let f, args, argCount - for (let i = 0; i < tokens.length; i++) { - let item = tokens[i] + for(let item of instructions) { let type = item.type switch(type) { - case Modules.ExprParser.Internals.INUMBER: + case Instruction.INUMBER: if(item.value === Infinity) { nstack.push("\\infty") - } else if(typeof item.value === 'number' && item.value < 0) { - nstack.push(this.par(item.value)); + } else if(typeof item.value === "number" && item.value < 0) { + nstack.push(this.par(item.value)) } else if(Array.isArray(item.value)) { - nstack.push('[' + item.value.map(Modules.ExprParser.Internals.escapeValue).join(', ') + ']'); + nstack.push("[" + item.value.map(escapeValue).join(", ") + "]") } else { - nstack.push(Modules.ExprParser.Internals.escapeValue(item.value)); + nstack.push(escapeValue(item.value)) } - break; - case Modules.ExprParser.Internals.IOP2: - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; + break + case Instruction.IOP2: + n2 = nstack.pop() + n1 = nstack.pop() + f = item.value switch(f) { - case '-': - case '+': - nstack.push(n1 + f + n2); - break; - case '||': - case 'or': - case '&&': - case 'and': - case '==': - case '!=': - nstack.push(this.par(n1) + f + this.par(n2)); - break; - case '*': - if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") - nstack.push(this.parif(n1,['+','-']) + n2) + case "-": + case "+": + nstack.push(n1 + f + n2) + break + case "||": + case "or": + case "&&": + case "and": + case "==": + case "!=": + nstack.push(this.par(n1) + f + this.par(n2)) + break + case "*": + if(n2 === "\\pi" || n2 === "e" || n2 === "x" || n2 === "n") + nstack.push(this.parif(n1, ["+", "-"]) + n2) else - nstack.push(this.parif(n1,['+','-']) + " \\times " + this.parif(n2,['+','-'])); - break; - case '/': - nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); - break; - case '^': - nstack.push(this.parif(n1,['+','-','*','/','!']) + "^{" + n2 + "}"); - break; - case '%': - nstack.push(this.parif(n1,['+','-','*','/','!','^']) + " \\mathrm{mod} " + parif(n2,['+','-','*','/','!','^'])); - break; - case '[': - nstack.push(n1 + '[' + n2 + ']'); - break; + nstack.push(this.parif(n1, ["+", "-"]) + " \\times " + this.parif(n2, ["+", "-"])) + break + case "/": + nstack.push("\\frac{" + n1 + "}{" + n2 + "}") + break + case "^": + nstack.push(this.parif(n1, ["+", "-", "*", "/", "!"]) + "^{" + n2 + "}") + break + case "%": + nstack.push(this.parif(n1, ["+", "-", "*", "/", "!", "^"]) + " \\mathrm{mod} " + this.parif(n2, ["+", "-", "*", "/", "!", "^"])) + break + case "[": + nstack.push(n1 + "[" + n2 + "]") + break default: - throw new EvalError("Unknown operator " + ope + "."); + throw new EvalError("Unknown operator " + item.value + ".") } - break; - case Modules.ExprParser.Internals.IOP3: // Thirdiary operator - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - if (f === '?') { - nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); + break + case Instruction.IOP3: // Thirdiary operator + n3 = nstack.pop() + n2 = nstack.pop() + n1 = nstack.pop() + f = item.value + if(f === "?") { + nstack.push("(" + n1 + " ? " + n2 + " : " + n3 + ")") } else { - throw new EvalError('Unknown operator ' + ope + '.'); + throw new EvalError("Unknown operator " + item.value + ".") } - break; - case Modules.ExprParser.Internals.IVAR: - case Modules.ExprParser.Internals.IVARNAME: - nstack.push(this.variable(item.value.toString())); - break; - case Modules.ExprParser.Internals.IOP1: // Unary operator - n1 = nstack.pop(); - f = item.value; + break + case Instruction.IVAR: + case Instruction.IVARNAME: + nstack.push(this.variable(item.value.toString())) + break + case Instruction.IOP1: // Unary operator + n1 = nstack.pop() + f = item.value switch(f) { - case '-': - case '+': - nstack.push(this.par(f + n1)); - break; - case '!': - nstack.push(this.parif(n1,['+','-','*','/','^']) + '!'); - break; + case "-": + case "+": + nstack.push(this.par(f + n1)) + break + case "!": + nstack.push(this.parif(n1, ["+", "-", "*", "/", "^"]) + "!") + break default: - nstack.push(f + this.parif(n1,['+','-','*','/','^'])); - break; + nstack.push(f + this.parif(n1, ["+", "-", "*", "/", "^"])) + break } - break; - case Modules.ExprParser.Internals.IFUNCALL: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); + break + case Instruction.IFUNCALL: + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(nstack.pop()) } - f = nstack.pop(); + f = nstack.pop() // Handling various functions nstack.push(this.functionToLatex(f, args)) - break; - case Modules.ExprParser.Internals.IFUNDEF: - nstack.push(this.par(n1 + '(' + args.join(', ') + ') = ' + n2)); - break; - case Modules.ExprParser.Internals.IMEMBER: - n1 = nstack.pop(); - nstack.push(n1 + '.' + item.value); - break; - case Modules.ExprParser.Internals.IARRAY: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); + break + case Instruction.IMEMBER: + n1 = nstack.pop() + nstack.push(n1 + "." + item.value) + break + case Instruction.IARRAY: + argCount = item.value + args = [] + while(argCount-- > 0) { + args.unshift(nstack.pop()) } - nstack.push('[' + args.join(', ') + ']'); - break; - case Modules.ExprParser.Internals.IEXPR: - nstack.push('(' + this.expression(item.value) + ')'); - break; - case Modules.ExprParser.Internals.IENDSTATEMENT: - break; + nstack.push("[" + args.join(", ") + "]") + break + case Instruction.IEXPR: + nstack.push("(" + this.expression(item.value) + ")") + break + case Instruction.IENDSTATEMENT: + break default: - throw new EvalError('invalid Expression'); + throw new EvalError("invalid Expression") } } - if (nstack.length > 1) { - nstack = [ nstack.join(';') ] + if(nstack.length > 1) { + nstack = [nstack.join(";")] } - return String(nstack[0]); + return String(nstack[0]) } } From 3c42cbb6d0712ce70aef9235e16959ddf1c90e13 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 18:28:36 +0200 Subject: [PATCH 110/249] Updating translations for new expr-eval --- LogarithmPlotter/i18n/lp_de.ts | 84 ++++---- LogarithmPlotter/i18n/lp_en.ts | 84 ++++---- LogarithmPlotter/i18n/lp_es.ts | 94 +++++---- LogarithmPlotter/i18n/lp_fr.ts | 84 ++++---- LogarithmPlotter/i18n/lp_hu.ts | 84 ++++---- LogarithmPlotter/i18n/lp_nb_NO.ts | 298 +++++++++++++-------------- LogarithmPlotter/i18n/lp_template.ts | 298 +++++++++++++-------------- LogarithmPlotter/i18n/update.sh | 37 +++- 8 files changed, 549 insertions(+), 514 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c5cd4cb..f868490 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -917,62 +917,60 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - - + + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - Parse error [%1:%2]: %3 - Analysefehler [%1:%2]: %3 + Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 @@ -985,76 +983,82 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Erwartete Variable für Zuweisung. - + + + Parse error [position %1]: %2 + + + + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks @@ -1772,37 +1776,37 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 or %2 Verwendung: %1 oder %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 3a86bcf..a2051a8 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -917,62 +917,60 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - Parse error [%1:%2]: %3 - Parse error [%1:%2]: %3 + Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 @@ -985,76 +983,82 @@ These settings can be changed at any time from the "Settings" menu.Expected variable for assignment. - + + + Parse error [position %1]: %2 + + + + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - + First argument to map is not a function. First argument to map is not a function. - + Second argument to map is not an array. Second argument to map is not an array. - + First argument to fold is not a function. First argument to fold is not a function. - + Second argument to fold is not an array. Second argument to fold is not an array. - + First argument to filter is not a function. First argument to filter is not a function. - + Second argument to filter is not an array. Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression @@ -1772,37 +1776,37 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 or %2 Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 7d9a37b..d89e4b1 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -917,139 +917,138 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes error - - + + Cannot find property %1 of object %2. No se puede encontrar la propiedad %1 del objeto %2. - + Undefined variable %1. Variable %1 no definida. - + In order to be executed, object %1 must have at least one argument. Para ser ejecutado, el objeto %1 debe tener al menos un argumento. - + %1 cannot be executed. - + - - - + + + Invalid expression. Expresión incorrecta. - + Invalid expression (parity). Expresión no válida (paridad). - + Unknown character "%1". Carácter "%1" desconocido. - - + + Illegal escape sequence: %1. Secuencia de salida no válida: %1 . - - Parse error [%1:%2]: %3 - Error de análisis [%1:%2]: %3 + Error de análisis [%1:%2]: %3 - + + + Parse error [position %1]: %2 + + + + Expected %1 Previsto %1 - + Unexpected %1 Inesperado %1 - + Unexpected ".": member access is not permitted "." Inesperado: el acceso de miembros no está permitido - + Unexpected "[]": arrays are disabled. "[]" inesperado: las matrices están desactivadas. - + Unexpected symbol: %1. Símbolo inesperado: %1. - - + + Function %1 must have at least one argument. La función %1 debe tener al menos un argumento. - + First argument to map is not a function. El primer argumento de map no es una función. - + Second argument to map is not an array. El segundo argumento de map no es una matriz. - + First argument to fold is not a function. El primer argumento de fold no es una función. - + Second argument to fold is not an array. El segundo argumento de fold no es una matriz. - + First argument to filter is not a function. El primer argumento del filtro no es una función. - + Second argument to filter is not an array. El segundo argumento del filtro no es una matriz. - + Second argument to indexOf is not a string or array. El segundo argumento de indexOf no es una cadena ni una matriz. - + Second argument to join is not an array. El segundo argumento para unirse no es una matriz. - - - EOF - - No object found with names %1. @@ -1105,6 +1104,11 @@ Deshaciendo el último cambio. Expected variable for assignment. Variable de asignación esperada. + + + EOF + + expression @@ -1772,37 +1776,37 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u usage - - + + Usage: %1 Uso: %1 - - - + + + Usage: %1 or %2 Uso: %1 o %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivada(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivada(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 3fb86f4..7a7eaf1 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -920,62 +920,60 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P error - - + + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - Parse error [%1:%2]: %3 - Erreur de syntaxe [%1:%2] : %3 + Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu @@ -988,76 +986,82 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Une variable est attendue pour l'affectation. - + + + Parse error [position %1]: %2 + + + + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule @@ -1775,37 +1779,37 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 or %2 Emploi : %1 ou %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 8d3f5b3..4b4e57f 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -917,62 +917,60 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - - + + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - Parse error [%1:%2]: %3 - Elemzési hiba [%1:%2]: %3 + Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 @@ -985,76 +983,82 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A hozzárendeléshez várt változó. - + + + Parse error [position %1]: %2 + + + + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - + First argument to map is not a function. Az első leképezési argumentum nem függvény. - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége @@ -1768,37 +1772,37 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 or %2 Használat: %1 vagy %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index d52d13b..bfbe130 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -868,140 +868,6 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. error - - - - Cannot find property %1 of object %2. - - - - - Undefined variable %1. - - - - - In order to be executed, object %1 must have at least one argument. - - - - - %1 cannot be executed. - - - - - - - Invalid expression. - - - - - Invalid expression (parity). - - - - - Unknown character "%1". - - - - - - Illegal escape sequence: %1. - - - - - - Parse error [%1:%2]: %3 - - - - - Expected %1 - - - - - Unexpected %1 - - - - - Unexpected ".": member access is not permitted - - - - - Unexpected "[]": arrays are disabled. - - - - - Unexpected symbol: %1. - - - - - - Function %1 must have at least one argument. - - - - - - First argument to map is not a function. - - - - - - Second argument to map is not an array. - - - - - - First argument to fold is not a function. - - - - - - Second argument to fold is not an array. - - - - - - First argument to filter is not a function. - - - - - - Second argument to filter is not an array. - - - - - - Second argument to indexOf is not a string or array. - - - - - - Second argument to join is not an array. - - - - - EOF - - No object found with names %1. @@ -1043,6 +909,140 @@ Evaluated expression: %3 Undoing last change. + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + In order to be executed, object %1 must have at least one argument. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + EOF + + + + + + Parse error [position %1]: %2 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + + Function %1 must have at least one argument. + + + + + + First argument to map is not a function. + + + + + + Second argument to map is not an array. + + + + + + First argument to fold is not a function. + + + + + + Second argument to fold is not an array. + + + + + + First argument to filter is not a function. + + + + + + Second argument to filter is not an array. + + + + + + Second argument to indexOf is not a string or array. + + + + + + Second argument to join is not an array. + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + expression @@ -1686,38 +1686,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - + - - - + + + Usage: %1 or %2 - + - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + - + derivative(<f: ExecutableObject>, <x: number>) - + - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index cb5e7b7..e9b6d6e 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -756,140 +756,6 @@ error - - - - Cannot find property %1 of object %2. - - - - - Undefined variable %1. - - - - - In order to be executed, object %1 must have at least one argument. - - - - - %1 cannot be executed. - - - - - - - Invalid expression. - - - - - Invalid expression (parity). - - - - - Unknown character "%1". - - - - - - Illegal escape sequence: %1. - - - - - - Parse error [%1:%2]: %3 - - - - - Expected %1 - - - - - Unexpected %1 - - - - - Unexpected ".": member access is not permitted - - - - - Unexpected "[]": arrays are disabled. - - - - - Unexpected symbol: %1. - - - - - - Function %1 must have at least one argument. - - - - - - First argument to map is not a function. - - - - - - Second argument to map is not an array. - - - - - - First argument to fold is not a function. - - - - - - Second argument to fold is not an array. - - - - - - First argument to filter is not a function. - - - - - - Second argument to filter is not an array. - - - - - - Second argument to indexOf is not a string or array. - - - - - - Second argument to join is not an array. - - - - - EOF - - No object found with names %1. @@ -931,6 +797,140 @@ Evaluated expression: %3 Undoing last change. + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + In order to be executed, object %1 must have at least one argument. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + EOF + + + + + + Parse error [position %1]: %2 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + + Function %1 must have at least one argument. + + + + + + First argument to map is not a function. + + + + + + Second argument to map is not an array. + + + + + + First argument to fold is not a function. + + + + + + Second argument to fold is not an array. + + + + + + First argument to filter is not a function. + + + + + + Second argument to filter is not an array. + + + + + + Second argument to indexOf is not a string or array. + + + + + + Second argument to join is not an array. + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + expression @@ -1527,38 +1527,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - + - - - + + + Usage: %1 or %2 - + - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + - + derivative(<f: ExecutableObject>, <x: number>) - + - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/update.sh b/LogarithmPlotter/i18n/update.sh index c20d7a7..3a01e14 100755 --- a/LogarithmPlotter/i18n/update.sh +++ b/LogarithmPlotter/i18n/update.sh @@ -5,27 +5,41 @@ # See also: https://bugreports.qt.io/browse/QTBUG-123819 # +escape() { + str="$1" + str="${str//\//\\/}" # Escape slashes + str="${str//\*/\\*}" # Escape asterixes + echo "$str" +} + +replace() { + file="$1" + from="$(escape "$2")" + to="$(escape "$3")" + sed -i "s/${from}/${to}/g" "$file" +} + files=$(find .. -name *.mjs) for file in $files; do echo "Moving '$file' to '${file%.*}.js'..." mv "$file" "${file%.*}.js" # Replacements to make it valid js - sed -i 's/^import/\/\/import/g' "${file%.*}.js" - sed -i 's/^export default/\/*export default*\//g' "${file%.*}.js" - sed -i 's/^export/\/*export*\//g' "${file%.*}.js" + replace "${file%.*}.js" "^import" "/*import" + replace "${file%.*}.js" '.mjs"$' '.mjs"*/' + replace "${file%.*}.js" "^export default" "/*export default*/" + replace "${file%.*}.js" "^export" "/*export*/" done -echo "------------------------" -echo "Updating translations..." -echo "------------------------" +echo "----------------------------" +echo "| Updating translations... |" +echo "----------------------------" lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts # Updating locations in files for lp in *.ts; do echo "Replacing locations in $lp..." for file in $files; do echo " > Replacing for file $file..." - f="${file//\//\\/}" # Escape slashes - sed -i "s/${f%.*}.js/$f/g" "$lp" + replace "$lp" "${file%.*}.js" "$file" done done @@ -33,7 +47,8 @@ for file in $files; do echo "Moving '${file%.*}.js' to '$file'..." mv "${file%.*}.js" "$file" # Resetting changes - sed -i 's/^\/\/import/import/g' "$file" - sed -i 's/^\/\*export default\*\//export default/g' "$file" - sed -i 's/^\/\*export\*\//export/g' "$file" + replace "$file" "^/*import" "import" + replace "$file" '.mjs"*/$' '.mjs"' + replace "$file" "^/*export default*/" "export default" + replace "$file" "^/*export*/" "export" done From e0601379ba5e430c896f88869e1e621e2ddb8c09 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 18:44:45 +0200 Subject: [PATCH 111/249] Update README --- README.md | 55 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3dd1378..e368435 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # ![icon](https://git.ad5001.eu/Ad5001/LogarithmPlotter/raw/branch/master/logplotter.svg) LogarithmPlotter + [![Build Status](https://ci.ad5001.eu/api/badges/Ad5001/LogarithmPlotter/status.svg)](https://ci.ad5001.eu/Ad5001/LogarithmPlotter) [![Translation status](https://hosted.weblate.org/widgets/logarithmplotter/-/logarithmplotter/svg-badge.svg)](https://hosted.weblate.org/engage/logarithmplotter/) [![On flathub](https://img.shields.io/flathub/v/eu.ad5001.LogarithmPlotter?label=on%20flathub&logo=Flathub&logoColor=white&color=4A86CF)](https://flathub.org/apps/details/eu.ad5001.LogarithmPlotter) @@ -7,6 +8,7 @@ 2D plotter software to make Bode plots, sequences and distribution functions. ## Screenshots + ![Magnitude example](https://apps.ad5001.eu/img/full/logarithmplotter.png) ![Phase example](https://apps.ad5001.eu/img/en/logarithmplotter/phase.png) ![Object settings](https://apps.ad5001.eu/img/en/logarithmplotter/object-settings.webp) @@ -22,40 +24,51 @@ In order to test translations, you can use the `--lang=` commandline ## Install ### Generate installers: + All scripts noted here can be found in the `scripts` directory. You can generate installers for LogarithmPlotter after installing all the dependencies: -For all builds, you will need [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and `poetry install --with packaging`. -- Windows installer: - - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an exe for LogarithmPlotter. - - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (Linux users can install the [nsis](https://pkgs.org/download/nsis) package). - - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a logarithmplotter-setup.exe installer in the dist/logarithmplotter/ folder. -- MacOS Archive creator installer: +For all builds, you will need [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and +`poetry install --with packaging`. + +- Windows installer: + - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an + exe for LogarithmPlotter. + - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (Linux users can install + the [nsis](https://pkgs.org/download/nsis) package). + - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a + logarithmplotter-setup.exe installer in the dist/logarithmplotter/ folder. +- MacOS Archive creator installer: - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the dist directory. - - Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v<version>-setup.dmg installer in the dist/ folder. + - Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v<version>-setup.dmg installer in the + dist/ folder. - Linux packages: - - To build and install the flatpak, you need [flatpak-builder](https://docs.flatpak.org/en/latest/flatpak-builder.html) installed. + - To build and install the flatpak, you + need [flatpak-builder](https://docs.flatpak.org/en/latest/flatpak-builder.html) installed. - To build the snap, you need [snapcraft](https://snapcraft.io) installed. - Run `package-linux.sh`. ## Contribute -There are several ways to contribute to LogarithmPlotter. -- You can help to translate [the project on Hosted Weblate](https://hosted.weblate.org/engage/logarithmplotter/): -[![Translation status](https://hosted.weblate.org/widgets/logarithmplotter/-/logarithmplotter/multi-auto.svg)](https://hosted.weblate.org/engage/logarithmplotter/) +There are several ways you can contribute to LogarithmPlotter. -- You can help the development of LogarithmPlotter. In order to get started, take a look at the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages). +- You can help to translate [the project on Hosted Weblate](https://hosted.weblate.org/engage/logarithmplotter/): + [![Translation status](https://hosted.weblate.org/widgets/logarithmplotter/-/logarithmplotter/multi-auto.svg)](https://hosted.weblate.org/engage/logarithmplotter/) + +- You can help the development of LogarithmPlotter. In order to get started, take a look at + the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages). ## Tests To run LogarithmPlotter's tests, follow these steps: - Python - - Install python3 and [poetry](https://python-poetry.org/) - - Run `poetry install --with test` - - Run `scripts/run-tests.sh` + - Install python3 and [poetry](https://python-poetry.org/) + - Run `poetry install --with test` + - Run `scripts/run-tests.sh` ## Legal notice + LogarithmPlotter - 2D plotter software to make Bode plots, sequences and repartition functions. Copyright (C) 2021-2024 Ad5001 @@ -72,13 +85,19 @@ To run LogarithmPlotter's tests, follow these steps: You should have received a copy of the GNU General Public License along with this program. If not, see . -Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their original authors. See LICENSE.md for more details: +Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their +original authors. See LICENSE.md for more details: + - 🇭🇺 Hungarian translation by [Óvári](https://github.com/ovari) - 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) - 🇪🇸 Spanish translation by gallegonovato and [IngrownMink4](https://github.com/IngrownMink4) ### Libraries used -LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf <r@undefined.ch>, ported to javascript by Matthew Crumley <email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. +LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port +of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf +<r@undefined.ch>, ported to javascript by Matthew Crumley +<email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. -The specific file (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js) is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). +All files in (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/) except integration.mjs are licensed +under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). From a32d480b43d4b7e310ef3887c77affb2bbfa6343 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 18:58:19 +0200 Subject: [PATCH 112/249] Renaming objects to their proper english names. --- .../LogarithmPlotter/js/objs/autoload.mjs | 20 +++++++++---------- .../objs/{gainbode.mjs => bodemagnitude.mjs} | 2 +- ...ommegainsbode.mjs => bodemagnitudesum.mjs} | 4 ++-- .../js/objs/{phasebode.mjs => bodephase.mjs} | 2 +- .../{sommephasesbode.mjs => bodephasesum.mjs} | 4 ++-- .../LogarithmPlotter/js/objs/common.mjs | 2 +- .../{repartition.mjs => distribution.mjs} | 2 +- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{gainbode.mjs => bodemagnitude.mjs} (99%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommegainsbode.mjs => bodemagnitudesum.mjs} (97%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{phasebode.mjs => bodephase.mjs} (98%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommephasesbode.mjs => bodephasesum.mjs} (97%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{repartition.mjs => distribution.mjs} (98%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index dc84bb0..cf0df63 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -21,13 +21,13 @@ import { DrawableObject } from "common.mjs" import Point from "point.mjs" import Text from "text.mjs" import Function from "function.mjs" -import GainBode from "gainbode.mjs" -import PhaseBode from "phasebode.mjs" -import SommeGainsBode from "sommegainsbode.mjs" -import SommePhasesBode from "sommephasesbode.mjs" +import BodeMagnitude from "bodemagnitude.mjs" +import BodePhase from "bodephase.mjs" +import BodeMagnitudeSum from "bodemagnitudesum.mjs" +import BodePhaseSum from "bodephasesum.mjs" import XCursor from "xcursor.mjs" import Sequence from "sequence.mjs" -import RepartitionFunction from "repartition.mjs" +import DistributionFunction from "distribution.mjs" /** * Registers the object obj in the object list. @@ -47,11 +47,11 @@ if(Object.keys(Modules.Objects.types).length === 0) { registerObject(Point) registerObject(Text) registerObject(Function) - registerObject(GainBode) - registerObject(PhaseBode) - registerObject(SommeGainsBode) - registerObject(SommePhasesBode) + registerObject(BodeMagnitude) + registerObject(BodePhase) + registerObject(BodeMagnitudeSum) + registerObject(BodePhaseSum) registerObject(XCursor) registerObject(Sequence) - registerObject(RepartitionFunction) + registerObject(DistributionFunction) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs similarity index 99% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index f86d747..9b0085f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -28,7 +28,7 @@ import { API as HistoryAPI } from "../history/common.mjs" import { CreateNewObject } from "../historylib.mjs" -export default class GainBode extends ExecutableObject { +export default class BodeMagnitude extends ExecutableObject { static type(){return 'Gain Bode'} static displayType(){return qsTr('Bode Magnitude')} static displayTypeMultiple(){return qsTr('Bode Magnitudes')} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs similarity index 97% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index 9226eee..bc4713a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -25,7 +25,7 @@ import { ExecutableObject } from "common.mjs" import Function from "function.mjs" -export default class SommeGainsBode extends ExecutableObject { +export default class BodeMagnitudeSum extends ExecutableObject { static type(){return 'Somme gains Bode'} static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} @@ -92,7 +92,7 @@ export default class SommeGainsBode extends ExecutableObject { magnitudes.push([Number.MAX_VALUE, 0, true]) // Draw the ending section // Collect data from current magnitude (or gain in French) objects. let baseY = 0 - for(/** @type {GainBode} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position. + for(/** @type {Bodemagnitude} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position. const om0x = magnitudeObj.om_0.x.execute() magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === 'high']) baseY += magnitudeObj.execute(MIN_DRAW) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs similarity index 98% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index 09895d9..eaf48d3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -26,7 +26,7 @@ import Latex from "../math/latex.mjs" import { ExecutableObject } from "common.mjs" -export default class PhaseBode extends ExecutableObject { +export default class BodePhase extends ExecutableObject { static type(){return 'Phase Bode'} static displayType(){return qsTr('Bode Phase')} static displayTypeMultiple(){return qsTr('Bode Phases')} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs similarity index 97% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index 3bb6a3c..8e91784 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -23,7 +23,7 @@ import Latex from "../math/latex.mjs" import { ExecutableObject } from "common.mjs" -export default class SommePhasesBode extends ExecutableObject { +export default class BodePhaseSum extends ExecutableObject { static type(){return 'Somme phases Bode'} static displayType(){return qsTr('Bode Phases Sum')} static displayTypeMultiple(){return qsTr('Bode Phases Sum')} @@ -88,7 +88,7 @@ export default class SommePhasesBode extends ExecutableObject { Objects.deleteObject(this.name) } else { console.log('Recalculating cache phase') - for(/** @type {PhaseBode} */ let obj of phaseObjects) { + for(/** @type {Bodephase} */ let obj of phaseObjects) { this.om0xList.push(obj.om_0.x.execute()) if(!phasesDict.has(obj.om_0.x.execute())) { phasesDict.set(obj.om_0.x.execute(), obj.phase.execute()) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 58a2d8d..b27cbf3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -98,7 +98,7 @@ export class DrawableObject { * @param {string} name - Name of the object * @param {boolean} visible - true if the object is visible, false otherwise. * @param {color|string} color - Color of the object (can be string or QColor) - * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. + * @param {'null'|'name'|'name + value'} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. * @constructor */ constructor(name, visible = true, color = null, labelContent = 'name + value') { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs similarity index 98% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs index aeaf6e1..b77189f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs @@ -23,7 +23,7 @@ import Latex from "../math/latex.mjs" import { ExecutableObject } from "common.mjs" -export default class RepartitionFunction extends ExecutableObject { +export default class DistributionFunction extends ExecutableObject { static type(){return 'Repartition'} static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 66a493c..503026e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -26,8 +26,8 @@ import { DrawableObject } from "common.mjs" export default class Point extends DrawableObject { static type(){return 'Point'} - static displayType(){return qsTr('Point')} - static displayTypeMultiple(){return qsTr('Points')} + static displayType(){return qsTranslate("point", 'Point')} + static displayTypeMultiple(){return qsTranslate("point", 'Points')} static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), From dcc47104ef488cdf5c9b8d5e3c9f36bcc92ce2b6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 19:10:23 +0200 Subject: [PATCH 113/249] Changing all JS qsTr to qsTranslate (better compatibility moving forward) --- .../LogarithmPlotter/Popup/Preferences.qml | 12 +- .../LogarithmPlotter/js/history/color.mjs | 4 +- .../LogarithmPlotter/js/history/create.mjs | 6 +- .../LogarithmPlotter/js/history/delete.mjs | 6 +- .../js/history/editproperty.mjs | 10 +- .../LogarithmPlotter/js/history/name.mjs | 4 +- .../LogarithmPlotter/js/history/position.mjs | 4 +- .../js/history/visibility.mjs | 4 +- .../js/objs/bodemagnitude.mjs | 8 +- .../js/objs/bodemagnitudesum.mjs | 4 +- .../LogarithmPlotter/js/objs/bodephase.mjs | 6 +- .../LogarithmPlotter/js/objs/bodephasesum.mjs | 4 +- .../LogarithmPlotter/js/objs/distribution.mjs | 4 +- .../LogarithmPlotter/js/objs/function.mjs | 4 +- .../LogarithmPlotter/js/objs/sequence.mjs | 4 +- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 4 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 4 +- .../ad5001/LogarithmPlotter/js/parameters.mjs | 50 +++---- .../LogarithmPlotter/js/parsing/polyfill.mjs | 125 ------------------ .../LogarithmPlotter/js/parsing/reference.mjs | 2 +- .../js/preferences/common.mjs | 1 - 21 files changed, 76 insertions(+), 194 deletions(-) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 7d801ca..44b1c8f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -46,7 +46,7 @@ Popup { CheckBox { height: 20 - text: setting.displayName + text: setting.name checked: setting.value() onClicked: setting.set(this.checked) } @@ -58,7 +58,7 @@ Popup { // Setting when selecting data from an enum, or an object of a certain type. Setting.ComboBoxSetting { height: 30 - label: setting.displayName + label: setting.name icon: `settings/${setting.icon}.svg` currentIndex: setting.value() model: setting.values @@ -71,7 +71,7 @@ Popup { Setting.ComboBoxSetting { height: 30 - label: setting.displayName + label: setting.name icon: `settings/${setting.icon}.svg` editable: true currentIndex: find(setting.value()) @@ -94,7 +94,7 @@ Popup { Setting.TextSetting { height: 30 isDouble: true - label: setting.displayName + label: setting.name min: setting.min() icon: `settings/${setting.icon}.svg` value: setting.value() @@ -114,12 +114,12 @@ Popup { Setting.ExpressionEditor { height: 30 - label: setting.displayName + label: setting.name icon: `settings/${setting.icon}.svg` defValue: Utils.simplifyExpression(setting.value()) variables: setting.variables allowGraphObjects: false - property string propertyName: setting.displayName + property string propertyName: setting.name onChanged: function(newExpr) { try { setting.set(newExpr) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index c8bb577..12a8793 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -37,7 +37,7 @@ export default class ColorChanged extends EditedProperty { color(darkVer=false){return darkVer ? 'purple' : 'plum'} getReadableString() { - return qsTr("%1 %2's color changed from %3 to %4.") + return qsTranslate("color", "%1 %2's color changed from %3 to %4.") .arg(Objects.types[this.targetType].displayType()).arg(this.targetName) .arg(this.previousValue).arg(this.newValue) } @@ -47,7 +47,7 @@ export default class ColorChanged extends EditedProperty { } getHTMLString() { - return qsTr("%1 %2's color changed from %3 to %4.") + return qsTranslate("color", "%1 %2's color changed from %3 to %4.") .arg(Objects.types[this.targetType].displayType()) .arg(' ' + this.targetName + " ") .arg(this.formatColor(this.previousValue)).arg(this.formatColor(this.newValue)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index e474133..b2c7f2d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -47,11 +47,13 @@ export default class CreateNewObject extends Action { } getReadableString() { - return qsTr("New %1 %2 created.").arg(Objects.types[this.targetType].displayType()).arg(this.targetName) + return qsTranslate("create", "New %1 %2 created.") + .arg(Objects.types[this.targetType].displayType()) + .arg(this.targetName) } getHTMLString() { - return qsTr("New %1 %2 created.") + return qsTranslate("create", "New %1 %2 created.") .arg(Objects.types[this.targetType].displayType()) .arg('' + this.targetName + "") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index ea1deb1..7fa855d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -39,11 +39,13 @@ export default class DeleteObject extends CreateNewObject { } getReadableString() { - return qsTr("%1 %2 deleted.").arg(Objects.types[this.targetType].displayType()).arg(this.targetName) + return qsTranslate("delete", "%1 %2 deleted.") + .arg(Objects.types[this.targetType].displayType()) + .arg(this.targetName) } getHTMLString() { - return qsTr("%1 %2 deleted.") + return qsTranslate("delete", "%1 %2 deleted.") .arg(Objects.types[this.targetType].displayType()) .arg('' + this.targetName + "") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 3c6bcda..1280e54 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -128,15 +128,19 @@ export default class EditedProperty extends Action { } getReadableString() { - return qsTr('%1 of %2 %3 changed from "%4" to "%5".') + return qsTranslate("editproperty", '%1 of %2 %3 changed from "%4" to "%5".') .arg(this.targetPropertyReadable) .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName).arg(this.prevString).arg(this.nextString) } - + + /** + * + * @return {Promise|string} + */ getHTMLString() { return new Promise(resolve => { - const translation = qsTr('%1 of %2 changed from %3 to %4.') + const translation = qsTranslate("editproperty", '%1 of %2 changed from %3 to %4.') .arg(this.targetPropertyReadable) .arg(' ' + this.targetName + ' ') // Check if we need to wait for LaTeX HTML to be rendered. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index 7698adf..13417da 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -45,13 +45,13 @@ export default class NameChanged extends EditedProperty { } getReadableString() { - return qsTr('%1 %2 renamed to %3.') + return qsTranslate("name", '%1 %2 renamed to %3.') .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName).arg(this.newValue) } getHTMLString() { - return qsTr('%1 %2 renamed to %3.') + return qsTranslate("name", '%1 %2 renamed to %3.') .arg(Objects.types[this.targetType].displayType()) .arg('' + this.targetName + "").arg(''+this.newValue+'') } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index a376e2f..b071cc7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -84,14 +84,14 @@ export default class EditedPosition extends Action { } getReadableString() { - return qsTr('Position of %1 %2 set from "%3" to "%4".') + return qsTranslate("position", 'Position of %1 %2 set from "%3" to "%4".') .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName).arg(this.prevString).arg(this.nextString) } getHTMLString() { return new Promise(resolve => { - const translation = qsTr('Position of %1 set from %2 to %3.') + const translation = qsTranslate("position", 'Position of %1 set from %2 to %3.') .arg(' ' + this.targetName + ' ') // Check if we need to wait for LaTeX HTML to be rendered. if(this.prevHTML !== undefined && this.nextHTML !== undefined) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index d38b33f..ebcb4fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -41,13 +41,13 @@ export default class EditedVisibility extends EditedProperty { } getReadableString() { - return (this.newValue ? qsTr('%1 %2 shown.') : qsTr('%1 %2 hidden.')) + return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.')) .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName) } getHTMLString() { - return (this.newValue ? qsTr('%1 %2 shown.') : qsTr('%1 %2 hidden.')) + return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.')) .arg(Objects.types[this.targetType].displayType()) .arg('' + this.targetName + "") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index 9b0085f..c01bcae 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -30,8 +30,8 @@ import { CreateNewObject } from "../historylib.mjs" export default class BodeMagnitude extends ExecutableObject { static type(){return 'Gain Bode'} - static displayType(){return qsTr('Bode Magnitude')} - static displayTypeMultiple(){return qsTr('Bode Magnitudes')} + static displayType(){return qsTranslate("bodemagnitude", 'Bode Magnitude')} + static displayTypeMultiple(){return qsTranslate("bodemagnitude", 'Bode Magnitudes')} static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), [QT_TRANSLATE_NOOP('prop','pass')]: P.Enum.BodePass, @@ -69,12 +69,12 @@ export default class BodeMagnitude extends ExecutableObject { } getReadableString() { - let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass"); return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec` } getLatexString() { - let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass"); return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} \\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ ${this.gain.latexMarkup}\\textsf{ dB/dec} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index bc4713a..82bf6b6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -27,8 +27,8 @@ import Function from "function.mjs" export default class BodeMagnitudeSum extends ExecutableObject { static type(){return 'Somme gains Bode'} - static displayType(){return qsTr('Bode Magnitudes Sum')} - static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} + static displayType(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')} + static displayTypeMultiple(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')} static createable() {return false} static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index eaf48d3..23119ef 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -28,8 +28,8 @@ import { ExecutableObject } from "common.mjs" export default class BodePhase extends ExecutableObject { static type(){return 'Phase Bode'} - static displayType(){return qsTr('Bode Phase')} - static displayTypeMultiple(){return qsTr('Bode Phases')} + static displayType(){return qsTranslate("bodephase", 'Bode Phase')} + static displayTypeMultiple(){return qsTranslate("bodephase", 'Bode Phases')} static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), [QT_TRANSLATE_NOOP('prop','phase')]: new P.Expression(), @@ -41,7 +41,7 @@ export default class BodePhase extends ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) { if(name == null) name = Objects.getNewName('φ') - if(name === 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). + if(name === 'φ') name = 'φ₀' // φ is reserved for sum of Bode phases. super(name, visible, color, labelContent) if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString()) this.phase = phase diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index 8e91784..1f1a0fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -25,8 +25,8 @@ import { ExecutableObject } from "common.mjs" export default class BodePhaseSum extends ExecutableObject { static type(){return 'Somme phases Bode'} - static displayType(){return qsTr('Bode Phases Sum')} - static displayTypeMultiple(){return qsTr('Bode Phases Sum')} + static displayType(){return qsTranslate("bodephasesum", 'Bode Phases Sum')} + static displayTypeMultiple(){return qsTranslate("bodephasesum", 'Bode Phases Sum')} static createable() {return false} static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs index b77189f..e0fe698 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs @@ -25,8 +25,8 @@ import { ExecutableObject } from "common.mjs" export default class DistributionFunction extends ExecutableObject { static type(){return 'Repartition'} - static displayType(){return qsTr('Repartition')} - static displayTypeMultiple(){return qsTr('Repartition functions')} + static displayType(){return qsTranslate("distribution", 'Repartition')} + static displayTypeMultiple(){return qsTranslate("distribution", 'Repartition functions')} static properties() {return { 'comment1': QT_TRANSLATE_NOOP( 'comment', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 2448d50..eb3f081 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -26,8 +26,8 @@ import Latex from "../math/latex.mjs" export default class Function extends ExecutableObject { static type(){return 'Function'} - static displayType(){return qsTr('Function')} - static displayTypeMultiple(){return qsTr('Functions')} + static displayType(){return qsTranslate("function", 'Function')} + static displayTypeMultiple(){return qsTranslate("function", 'Functions')} static properties() {return { [QT_TRANSLATE_NOOP('prop','expression')]: new P.Expression('x'), [QT_TRANSLATE_NOOP('prop','definitionDomain')]: 'Domain', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 11f1be7..b05a66e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -27,8 +27,8 @@ import Function from "function.mjs" export default class Sequence extends ExecutableObject { static type(){return 'Sequence'} - static displayType(){return qsTr('Sequence')} - static displayTypeMultiple(){return qsTr('Sequences')} + static displayType(){return qsTranslate("sequence", 'Sequence')} + static displayTypeMultiple(){return qsTranslate("sequence", 'Sequences')} static properties() {return { [QT_TRANSLATE_NOOP('prop','drawPoints')]: 'boolean', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index fab2818..3ad1e82 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -26,8 +26,8 @@ import { DrawableObject } from "common.mjs" export default class Text extends DrawableObject { static type(){return 'Text'} - static displayType(){return qsTr('Text')} - static displayTypeMultiple(){return qsTr('Texts')} + static displayType(){return qsTranslate("text", 'Text')} + static displayTypeMultiple(){return qsTranslate("text", 'Texts')} static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 20732ba..f377a74 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -26,8 +26,8 @@ import { DrawableObject } from "common.mjs" export default class XCursor extends DrawableObject { static type(){return 'X Cursor'} - static displayType(){return qsTr('X Cursor')} - static displayTypeMultiple(){return qsTr('X Cursors')} + static displayType(){return qsTranslate("xcursor", 'X Cursor')} + static displayTypeMultiple(){return qsTranslate("xcursor", 'X Cursors')} static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject', true), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 72f9dee..f59c322 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -88,7 +88,7 @@ export class Enum extends PropertyType { this.type = 'Enum' this.values = values this.legacyValues = {} - this.translatedValues = values.map(x => qsTr(x)) + this.translatedValues = values.map(x => qsTranslate('parameters', x)) } toString() { @@ -246,14 +246,14 @@ export class Dictionary extends PropertyType { // Common parameters for Enums Enum.Position = new Enum( - QT_TR_NOOP('above'), - QT_TR_NOOP('below'), - QT_TR_NOOP('left'), - QT_TR_NOOP('right'), - QT_TR_NOOP('above-left'), - QT_TR_NOOP('above-right'), - QT_TR_NOOP('below-left'), - QT_TR_NOOP('below-right') + QT_TRANSLATE_NOOP('parameters', 'above'), + QT_TRANSLATE_NOOP('parameters', 'below'), + QT_TRANSLATE_NOOP('parameters', 'left'), + QT_TRANSLATE_NOOP('parameters', 'right'), + QT_TRANSLATE_NOOP('parameters', 'above-left'), + QT_TRANSLATE_NOOP('parameters', 'above-right'), + QT_TRANSLATE_NOOP('parameters', 'below-left'), + QT_TRANSLATE_NOOP('parameters', 'below-right') ) Enum.Position.legacyValues = { 'top': 'above', @@ -265,32 +265,32 @@ Enum.Position.legacyValues = { } Enum.Positioning = new Enum( - QT_TR_NOOP('center'), - QT_TR_NOOP('top'), - QT_TR_NOOP('bottom'), - QT_TR_NOOP('left'), - QT_TR_NOOP('right'), - QT_TR_NOOP('top-left'), - QT_TR_NOOP('top-right'), - QT_TR_NOOP('bottom-left'), - QT_TR_NOOP('bottom-right') + QT_TRANSLATE_NOOP('parameters', 'center'), + QT_TRANSLATE_NOOP('parameters', 'top'), + QT_TRANSLATE_NOOP('parameters', 'bottom'), + QT_TRANSLATE_NOOP('parameters', 'left'), + QT_TRANSLATE_NOOP('parameters', 'right'), + QT_TRANSLATE_NOOP('parameters', 'top-left'), + QT_TRANSLATE_NOOP('parameters', 'top-right'), + QT_TRANSLATE_NOOP('parameters', 'bottom-left'), + QT_TRANSLATE_NOOP('parameters', 'bottom-right') ) Enum.FunctionDisplayType = new Enum( - QT_TR_NOOP('application'), - QT_TR_NOOP('function') + QT_TRANSLATE_NOOP('parameters', 'application'), + QT_TRANSLATE_NOOP('parameters', 'function') ) Enum.BodePass = new Enum( - QT_TR_NOOP('high'), - QT_TR_NOOP('low') + QT_TRANSLATE_NOOP('parameters', 'high'), + QT_TRANSLATE_NOOP('parameters', 'low') ) Enum.XCursorValuePosition = new Enum( - QT_TR_NOOP('Next to target'), - QT_TR_NOOP('With label'), - QT_TR_NOOP('Hidden') + QT_TRANSLATE_NOOP('parameters', 'Next to target'), + QT_TRANSLATE_NOOP('parameters', 'With label'), + QT_TRANSLATE_NOOP('parameters', 'Hidden') ) /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs deleted file mode 100644 index ac845ce..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs +++ /dev/null @@ -1,125 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// Contains polyfill math functions used for reference. -export function factorial(x) { - if (x < 0) // Integrating by less than 0 - if(isFinite(n)) - return Infinity - else - throw new EvalError("Cannot calculate the factorial of -∞.") - - return gamma(x+1) -} - -let GAMMA_G = 4.7421875 -let GAMMA_P = [ - 0.99999999999999709182, - 57.156235665862923517, -59.597960355475491248, - 14.136097974741747174, -0.49191381609762019978, - 0.33994649984811888699e-4, - 0.46523628927048575665e-4, -0.98374475304879564677e-4, - 0.15808870322491248884e-3, -0.21026444172410488319e-3, - 0.21743961811521264320e-3, -0.16431810653676389022e-3, - 0.84418223983852743293e-4, -0.26190838401581408670e-4, - 0.36899182659531622704e-5 -] - -export function gamma(n) { - if(n <= 0) // Integrating by less than 0 - if(isFinite(n)) - return Infinity - else - throw new EvalError("Cannot calculate Γ(-∞).") - - if(n >= 171.35) - return Infinity // Would return more than 2^1024 - 1 (aka Number.INT_MAX) - - if(n === Math.round(n) && isFinite(n)) { - // Calculating (n-1)! - let res = n - 1 - - for(let i = n - 2; i > 1; i++) - res *= i - - if(res === 0) - res = 1 // 0! is per definition 1 - - return res - } - - // Section below adapted function adapted from math.js - if(n < 0.5) - return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)) - - if(n > 85.0) { // Extended Stirling Approx - let twoN = n * n - let threeN = twoN * n - let fourN = threeN * n - let fiveN = fourN * n - return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) * - (1 + (1 / (12 * n)) + (1 / (288 * twoN)) - (139 / (51840 * threeN)) - - (571 / (2488320 * fourN)) + (163879 / (209018880 * fiveN)) + - (5246819 / (75246796800 * fiveN * n))) - } - - --n - let x = GAMMA_P[0] - for (let i = 1; i < GAMMA_P.length; ++i) { - x += GAMMA_P[i] / (n + i) - } - - let t = n + GAMMA_G + 0.5 - return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x -} - -export function arrayMap(f, arr) { - if (typeof f != 'function') - throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')) - if (!Array.isArray(arr)) - throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.')) - return arr.map(f) -} - -export function arrayFold(f, init, arr) { - if (typeof f != 'function') - throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')) - if (!Array.isArray(arr)) - throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.')) - return arr.reduce(f, init) -} - -export function arrayFilter(f, arr) { - if (typeof f != 'function') - throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) - if (!Array.isArray(arr)) - throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')) - return arr.filter(f) -} - -export function arrayJoin(sep, arr) { - if (!Array.isArray(arr)) - throw new Error(qsTranslate('error', 'Second argument to join is not an array.')) - return arr.join(sep) -} - -export function indexOf(target, s) { - if (!(Array.isArray(s) || typeof s === 'string')) - throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')) - return s.indexOf(target) -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs index d6ce9dc..9c30991 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import * as Polyfill from "polyfill.mjs" +import * as Polyfill from "../lib/expr-eval/polyfill.mjs" export const CONSTANTS = { "π": Math.PI, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs index 48cd1de..4503113 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -22,7 +22,6 @@ class Setting { constructor(type, name, nameInConfig, icon) { this.type = type this.name = name - this.displayName = qsTr(name) this.nameInConfig = nameInConfig this.icon = icon } From dcb63c48e9c544508be2b9b5ed3db7e9f1ce2721 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 16:48:51 +0000 Subject: [PATCH 114/249] Translated using Weblate (English) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index a2051a8..d161a6c 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -986,7 +986,7 @@ These settings can be changed at any time from the "Settings" menu. Parse error [position %1]: %2 - + Parse error [position %1]: %2 From 976088ad03703610f58c8d55c45dbc559f9332f1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 16:51:04 +0000 Subject: [PATCH 115/249] Translated using Weblate (German) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index f868490..1cc2c48 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -986,7 +986,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Parse error [position %1]: %2 - + Analysefehler [Posten %1]: %2 From 8eac624bb2efa219a20bfe4a7aaf014f7cc14515 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sun, 22 Sep 2024 17:00:15 +0000 Subject: [PATCH 116/249] Translated using Weblate (Spanish) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index d89e4b1..fbcfc72 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -935,7 +935,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes %1 cannot be executed. - + %1 no es una función. @@ -968,7 +968,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Parse error [position %1]: %2 - + Error en el análisis [posición%1 ]:%2 @@ -1107,7 +1107,7 @@ Deshaciendo el último cambio. EOF - + Fin de la expresión From 1f2b8e5c4b515b22b5baa168ec7a6d90e1a99106 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 16:49:51 +0000 Subject: [PATCH 117/249] Translated using Weblate (French) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 7a7eaf1..b3d5c75 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -842,7 +842,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P %1 %2's color changed from %3 to %4. - %1 %2 a été re colorisé du %3 au %4. + La couleur du %1 %2 a été changée du %3 au %4. @@ -989,7 +989,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Parse error [position %1]: %2 - + Erreur de syntaxe [position %1] : %2 From 4baf4f8aa602aba9c9a5c62b1a56cc6274c47974 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 19:17:24 +0200 Subject: [PATCH 118/249] Updating some keys (should be the last time) --- LogarithmPlotter/i18n/lp_de.ts | 155 ++++++++++++++-------- LogarithmPlotter/i18n/lp_en.ts | 155 ++++++++++++++-------- LogarithmPlotter/i18n/lp_es.ts | 157 ++++++++++++++-------- LogarithmPlotter/i18n/lp_fr.ts | 155 ++++++++++++++-------- LogarithmPlotter/i18n/lp_hu.ts | 155 ++++++++++++++-------- LogarithmPlotter/i18n/lp_nb_NO.ts | 155 ++++++++++++++-------- LogarithmPlotter/i18n/lp_template.ts | 190 +++++++++++++-------------- 7 files changed, 698 insertions(+), 424 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index f868490..9c7d1ca 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -821,6 +821,62 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Verbessern + + bodemagnitude + + + Bode Magnitude + Bode-Magnitude + + + + Bode Magnitudes + Bode-Magnituden + + + + + low-pass + Tiefpass + + + + + high-pass + Hochpass + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Bode-Magnituden Summe + + + + bodephase + + + Bode Phase + Bode-Phase + + + + Bode Phases + Bode-Phasen + + + + bodephasesum + + + + Bode Phases Sum + Bode-Phasen Summe + + changelog @@ -856,7 +912,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - + Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. @@ -887,7 +943,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - + New %1 %2 created. Neu %1 %2 erstellt. @@ -896,11 +952,24 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete - + %1 %2 deleted. %1 %2 gelöscht. + + distribution + + + Repartition + Verteilungsfunktion + + + + Repartition functions + Verteilungsfunktionen + + editproperty @@ -909,7 +978,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" %1 von %2 %3 wurde von "%4" auf "%5" geändert. - + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -1011,49 +1080,41 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - First argument to map is not a function. Der erste Parameter von map ist keine Formel. - Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - Second argument to join is not an array. Der zweite Parameter von join ist kein Array. @@ -1171,26 +1232,20 @@ Ausdruck analysiert: %3 gainbode - Bode Magnitude - Bode-Magnitude + Bode-Magnitude - Bode Magnitudes - Bode-Magnituden + Bode-Magnituden - - low-pass - Tiefpass + Tiefpass - - high-pass - Hochpass + Hochpass @@ -1476,14 +1531,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde phasebode - Bode Phase - Bode-Phase + Bode-Phase - Bode Phases - Bode-Phasen + Bode-Phasen @@ -1530,14 +1583,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Reichweite + + + + + - - - - - labelPosition @@ -1549,13 +1602,13 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Anzeigemodus + + + + + - - - - - labelX X-Position des Etiketts @@ -1572,33 +1625,33 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Gestrichelte Linien anzeigen - - + + om_0 ω₀ - + pass Pass - + gain Größenordnung - + omGraduation Teilung auf ω zeigen - + phase Phase - + unit Einheit @@ -1621,7 +1674,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Punkt-Stil - + probabilities Wahrscheinlichkeiten @@ -1678,14 +1731,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde repartition - Repartition - Verteilungsfunktion + Verteilungsfunktion - Repartition functions - Verteilungsfunktionen + Verteilungsfunktionen @@ -1722,19 +1773,15 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommegainsbode - - Bode Magnitudes Sum - Bode-Magnituden Summe + Bode-Magnituden Summe sommephasesbode - - Bode Phases Sum - Bode-Phasen Summe + Bode-Phasen Summe diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index a2051a8..0fd68a6 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -821,6 +821,62 @@ These settings can be changed at any time from the "Settings" menu.Improve + + bodemagnitude + + + Bode Magnitude + Bode Magnitude + + + + Bode Magnitudes + Bode Magnitudes + + + + + low-pass + low-pass + + + + + high-pass + high-pass + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Bode Magnitudes Sum + + + + bodephase + + + Bode Phase + Bode Phase + + + + Bode Phases + Bode Phases + + + + bodephasesum + + + + Bode Phases Sum + Bode Phases Sum + + changelog @@ -856,7 +912,7 @@ These settings can be changed at any time from the "Settings" menu.The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - + Note: Specify the probability for each value. Note: Specify the probability for each value. @@ -887,7 +943,7 @@ These settings can be changed at any time from the "Settings" menu.create - + New %1 %2 created. New %1 %2 created. @@ -896,11 +952,24 @@ These settings can be changed at any time from the "Settings" menu.delete - + %1 %2 deleted. %1 %2 deleted. + + distribution + + + Repartition + Distribution + + + + Repartition functions + Distribution functions + + editproperty @@ -909,7 +978,7 @@ These settings can be changed at any time from the "Settings" menu.%1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -1011,49 +1080,41 @@ These settings can be changed at any time from the "Settings" menu. - First argument to map is not a function. First argument to map is not a function. - Second argument to map is not an array. Second argument to map is not an array. - First argument to fold is not a function. First argument to fold is not a function. - Second argument to fold is not an array. Second argument to fold is not an array. - First argument to filter is not a function. First argument to filter is not a function. - Second argument to filter is not an array. Second argument to filter is not an array. - Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - Second argument to join is not an array. Second argument to join is not an array. @@ -1171,26 +1232,20 @@ Evaluated expression: %3 gainbode - Bode Magnitude - Bode Magnitude + Bode Magnitude - Bode Magnitudes - Bode Magnitudes + Bode Magnitudes - - low-pass - low-pass + low-pass - - high-pass - high-pass + high-pass @@ -1476,14 +1531,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. phasebode - Bode Phase - Bode Phase + Bode Phase - Bode Phases - Bode Phases + Bode Phases @@ -1530,14 +1583,14 @@ Please make sure your LaTeX installation is correct and report a bug if so.Range + + + + + - - - - - labelPosition @@ -1549,13 +1602,13 @@ Please make sure your LaTeX installation is correct and report a bug if so.Display mode + + + + + - - - - - labelX Label's X position @@ -1572,33 +1625,33 @@ Please make sure your LaTeX installation is correct and report a bug if so.Show dashed lines - - + + om_0 ω₀ - + pass Pass - + gain Magnitude gain - + omGraduation Show graduation on ω₀ - + phase Phase - + unit Unit to use @@ -1621,7 +1674,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.Point style - + probabilities Probabilities list @@ -1678,14 +1731,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. repartition - Repartition - Distribution + Distribution - Repartition functions - Distribution functions + Distribution functions @@ -1722,19 +1773,15 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommegainsbode - - Bode Magnitudes Sum - Bode Magnitudes Sum + Bode Magnitudes Sum sommephasesbode - - Bode Phases Sum - Bode Phases Sum + Bode Phases Sum diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index d89e4b1..3e1dfd1 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -821,6 +821,62 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Mejorar + + bodemagnitude + + + Bode Magnitude + Magnitud de Bode + + + + Bode Magnitudes + Magnitudes de Bode + + + + + low-pass + Filtro paso bajo + + + + + high-pass + Filtro paso alto + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Suma de las Magnitudes de Bode + + + + bodephase + + + Bode Phase + Fase de Bode + + + + Bode Phases + Fases de Bode + + + + bodephasesum + + + + Bode Phases Sum + Suma de las fases de Bode + + changelog @@ -856,7 +912,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) - + Note: Specify the probability for each value. Nota: Especifique la probabilidad para cada valor. @@ -887,7 +943,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes create - + New %1 %2 created. Se ha creado un nuevo %1 %2. @@ -896,11 +952,24 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes delete - + %1 %2 deleted. %1 %2 borrados. + + distribution + + + Repartition + Distribución + + + + Repartition functions + Funciones de distribución + + editproperty @@ -909,7 +978,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes %1 de %2 %3 cambió de "%4" a "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 ha cambiado de %3 a %4. @@ -935,7 +1004,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes %1 cannot be executed. - + @@ -1003,49 +1072,41 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes - First argument to map is not a function. El primer argumento de map no es una función. - Second argument to map is not an array. El segundo argumento de map no es una matriz. - First argument to fold is not a function. El primer argumento de fold no es una función. - Second argument to fold is not an array. El segundo argumento de fold no es una matriz. - First argument to filter is not a function. El primer argumento del filtro no es una función. - Second argument to filter is not an array. El segundo argumento del filtro no es una matriz. - Second argument to indexOf is not a string or array. El segundo argumento de indexOf no es una cadena ni una matriz. - Second argument to join is not an array. El segundo argumento para unirse no es una matriz. @@ -1171,26 +1232,20 @@ Expresión evaluada: %3 gainbode - - high-pass - Filtro paso alto + Filtro paso alto - - low-pass - Filtro paso bajo + Filtro paso bajo - Bode Magnitude - Magnitud de Bode + Magnitud de Bode - Bode Magnitudes - Magnitudes de Bode + Magnitudes de Bode @@ -1476,14 +1531,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u phasebode - Bode Phase - Fase de Bode + Fase de Bode - Bode Phases - Fases de Bode + Fases de Bode @@ -1525,8 +1578,8 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Dominio - - + + om_0 ω₀ @@ -1541,13 +1594,13 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Redondeo + + + + + - - - - - labelX Posición de la etiqueta en X @@ -1569,14 +1622,14 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Rango + + + + + - - - - - labelPosition @@ -1588,17 +1641,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Modo de visualización - + pass Pasar - + gain Incremento de magnitud - + unit Unidad a usar @@ -1609,12 +1662,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Y - + omGraduation Mostrar la graduación en ω₀ - + phase Fase @@ -1636,7 +1689,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Contenido - + probabilities Lista de probabilidades @@ -1678,14 +1731,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u repartition - Repartition - Distribución + Distribución - Repartition functions - Funciones de distribución + Funciones de distribución @@ -1722,19 +1773,15 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u sommegainsbode - - Bode Magnitudes Sum - Suma de las Magnitudes de Bode + Suma de las Magnitudes de Bode sommephasesbode - - Bode Phases Sum - Suma de las fases de Bode + Suma de las fases de Bode diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 7a7eaf1..08c4bfd 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -823,6 +823,62 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Améliorer + + bodemagnitude + + + Bode Magnitude + Gain de Bode + + + + Bode Magnitudes + Gains de Bode + + + + + low-pass + passe-bas + + + + + high-pass + passe-haut + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Sommes des gains de Bode + + + + bodephase + + + Bode Phase + Phase de Bode + + + + Bode Phases + Phases de Bode + + + + bodephasesum + + + + Bode Phases Sum + Somme des phases de Bode + + changelog @@ -858,7 +914,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - + Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. @@ -890,7 +946,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P create - + New %1 %2 created. Nouvel objet %1 %2 créé. @@ -899,11 +955,24 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P delete - + %1 %2 deleted. %1 %2 supprimé(e). + + distribution + + + Repartition + Répartition + + + + Repartition functions + Fonctions de répartition + + editproperty @@ -912,7 +981,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P %1 de %2 %3 modifiée de "%4" à "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -1014,49 +1083,41 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P - First argument to map is not a function. Le premier argument de map n'est pas une fonction. - Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. @@ -1174,26 +1235,20 @@ Formule analysée : %3 gainbode - Bode Magnitude - Gain de Bode + Gain de Bode - Bode Magnitudes - Gains de Bode + Gains de Bode - - low-pass - passe-bas + passe-bas - - high-pass - passe-haut + passe-haut @@ -1479,14 +1534,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c phasebode - Bode Phase - Phase de Bode + Phase de Bode - Bode Phases - Phases de Bode + Phases de Bode @@ -1533,14 +1586,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Portée + + + + + - - - - - labelPosition @@ -1552,13 +1605,13 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Mode d'affichage + + + + + - - - - - labelX Position en X de l'étiquette @@ -1575,33 +1628,33 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Afficher les pointillés - - + + om_0 ω₀ - + pass Passe - + gain Gain - + omGraduation Afficher la graduation sur ω₀ - + phase Phase - + unit Unité de la phase @@ -1624,7 +1677,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Style du point - + probabilities Liste de probabilités @@ -1681,14 +1734,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c repartition - Repartition - Répartition + Répartition - Repartition functions - Fonctions de répartition + Fonctions de répartition @@ -1725,19 +1776,15 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommegainsbode - - Bode Magnitudes Sum - Sommes des gains de Bode + Sommes des gains de Bode sommephasesbode - - Bode Phases Sum - Somme des phases de Bode + Somme des phases de Bode diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 4b4e57f..c0b4924 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -821,6 +821,62 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Fejlesztés + + bodemagnitude + + + Bode Magnitude + Bode-nagyságrend + + + + Bode Magnitudes + Bode-nagyságrendek + + + + + low-pass + aluláteresztő + + + + + high-pass + felüláteresztő + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Bode-nagyságrendek összege + + + + bodephase + + + Bode Phase + Bode-fázis + + + + Bode Phases + Bode-fázisok + + + + bodephasesum + + + + Bode Phases Sum + Bode-fázisok összege + + changelog @@ -856,7 +912,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - + Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. @@ -887,7 +943,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create - + New %1 %2 created. Új %1 %2 létrehozva. @@ -896,11 +952,24 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. delete - + %1 %2 deleted. %1 %2 törölve. + + distribution + + + Repartition + Elosztás + + + + Repartition functions + Elosztási függvények + + editproperty @@ -909,7 +978,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -1011,49 +1080,41 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - First argument to map is not a function. Az első leképezési argumentum nem függvény. - Second argument to map is not an array. A második leképezési argumentum nem tömb. - First argument to fold is not a function. Az első behajtási argumentum nem függvény. - Second argument to fold is not an array. A második behajtási argumentum nem tömb. - First argument to filter is not a function. Az első szűrési argumentum nem függvény. - Second argument to filter is not an array. A második szűrési argumentum nem tömb. - Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - Second argument to join is not an array. A második csatlakozási argumentum nem tömb. @@ -1171,26 +1232,20 @@ Kiértékelt kifejezés: %3 gainbode - Bode Magnitude - Bode-nagyságrend + Bode-nagyságrend - Bode Magnitudes - Bode-nagyságrendek + Bode-nagyságrendek - - low-pass - aluláteresztő + aluláteresztő - - high-pass - felüláteresztő + felüláteresztő @@ -1472,14 +1527,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents phasebode - Bode Phase - Bode-fázis + Bode-fázis - Bode Phases - Bode-fázisok + Bode-fázisok @@ -1526,14 +1579,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Ordináta tartomány + + + + + - - - - - labelPosition @@ -1545,13 +1598,13 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Megjelenítési mód + + + + + - - - - - labelX Címke X helyzete @@ -1568,33 +1621,33 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Szaggatott vonalak megjelenítése - - + + om_0 ω₀ - + pass Áteresztő - + gain Nagyságrend nyeresége - + omGraduation ω₀ érettségi megjelenítése - + phase Fázis - + unit Egység használata @@ -1617,7 +1670,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Pontstílus - + probabilities Valószínűségek listája @@ -1674,14 +1727,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents repartition - Repartition - Elosztás + Elosztás - Repartition functions - Elosztási függvények + Elosztási függvények @@ -1718,19 +1769,15 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommegainsbode - - Bode Magnitudes Sum - Bode-nagyságrendek összege + Bode-nagyságrendek összege sommephasesbode - - Bode Phases Sum - Bode-fázisok összege + Bode-fázisok összege diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index bfbe130..904af86 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -773,6 +773,62 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + bodemagnitude + + + Bode Magnitude + Bode-magnitude + + + + Bode Magnitudes + Bode-magnituder + + + + + low-pass + lavpass + + + + + high-pass + høypass + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + Bode-magnitudesum + + + + bodephase + + + Bode Phase + Bode-fase + + + + Bode Phases + Bode-faser + + + + bodephasesum + + + + Bode Phases Sum + Bode-fasesum + + changelog @@ -808,7 +864,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Note: Specify the probability for each value. @@ -839,7 +895,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.create - + New %1 %2 created. Ny %1 %2 opprettet. @@ -848,11 +904,24 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.delete - + %1 %2 deleted. %1 %2 slettet. + + distribution + + + Repartition + Distribusjon + + + + Repartition functions + Distribusjonsfunksjoner + + editproperty @@ -861,7 +930,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.%1 av %2 %3 endret fra «%4» til «%5». - + %1 of %2 changed from %3 to %4. @@ -986,49 +1055,41 @@ Undoing last change. - First argument to map is not a function. - Second argument to map is not an array. - First argument to fold is not a function. - Second argument to fold is not an array. - First argument to filter is not a function. - Second argument to filter is not an array. - Second argument to indexOf is not a string or array. - Second argument to join is not an array. @@ -1102,26 +1163,20 @@ Evaluated expression: %3 gainbode - Bode Magnitude - Bode-magnitude + Bode-magnitude - Bode Magnitudes - Bode-magnituder + Bode-magnituder - - low-pass - lavpass + lavpass - - high-pass - høypass + høypass @@ -1390,14 +1445,12 @@ Please make sure your latex installation is correct and report a bug if so. phasebode - Bode Phase - Bode-fase + Bode-fase - Bode Phases - Bode-faser + Bode-faser @@ -1449,27 +1502,27 @@ Please make sure your latex installation is correct and report a bug if so. + + + + + - - - - - labelPosition + + + + + - - - - - labelX @@ -1486,33 +1539,33 @@ Please make sure your latex installation is correct and report a bug if so. - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit @@ -1535,7 +1588,7 @@ Please make sure your latex installation is correct and report a bug if so. - + probabilities @@ -1588,14 +1641,12 @@ Please make sure your latex installation is correct and report a bug if so. repartition - Repartition - Distribusjon + Distribusjon - Repartition functions - Distribusjonsfunksjoner + Distribusjonsfunksjoner @@ -1632,19 +1683,15 @@ Please make sure your latex installation is correct and report a bug if so. sommegainsbode - - Bode Magnitudes Sum - Bode-magnitudesum + Bode-magnitudesum sommephasesbode - - Bode Phases Sum - Bode-fasesum + Bode-fasesum diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index e9b6d6e..511c6c2 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -661,6 +661,62 @@ + + bodemagnitude + + + Bode Magnitude + + + + + Bode Magnitudes + + + + + + low-pass + + + + + + high-pass + + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + + + + + bodephase + + + Bode Phase + + + + + Bode Phases + + + + + bodephasesum + + + + Bode Phases Sum + + + changelog @@ -696,7 +752,7 @@ - + Note: Specify the probability for each value. @@ -727,7 +783,7 @@ create - + New %1 %2 created. @@ -736,11 +792,24 @@ delete - + %1 %2 deleted. + + distribution + + + Repartition + + + + + Repartition functions + + + editproperty @@ -749,7 +818,7 @@ - + %1 of %2 changed from %3 to %4. @@ -874,49 +943,41 @@ Undoing last change. - First argument to map is not a function. - Second argument to map is not an array. - First argument to fold is not a function. - Second argument to fold is not an array. - First argument to filter is not a function. - Second argument to filter is not an array. - Second argument to indexOf is not a string or array. - Second argument to join is not an array. @@ -987,31 +1048,6 @@ Evaluated expression: %3 - - gainbode - - - Bode Magnitude - - - - - Bode Magnitudes - - - - - - low-pass - - - - - - high-pass - - - general @@ -1228,19 +1264,6 @@ Please make sure your latex installation is correct and report a bug if so. - - phasebode - - - Bode Phase - - - - - Bode Phases - - - point @@ -1290,27 +1313,27 @@ Please make sure your latex installation is correct and report a bug if so. + + + + + - - - - - labelPosition + + + + + - - - - - labelX @@ -1327,33 +1350,33 @@ Please make sure your latex installation is correct and report a bug if so. - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit @@ -1376,7 +1399,7 @@ Please make sure your latex installation is correct and report a bug if so. - + probabilities @@ -1426,19 +1449,6 @@ Please make sure your latex installation is correct and report a bug if so. - - repartition - - - Repartition - - - - - Repartition functions - - - sequence @@ -1470,24 +1480,6 @@ Please make sure your latex installation is correct and report a bug if so. - - sommegainsbode - - - - Bode Magnitudes Sum - - - - - sommephasesbode - - - - Bode Phases Sum - - - text From a4e9ad7f5a22a239b43cbea4dfe6fe8c0c9862d2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 19:35:40 +0200 Subject: [PATCH 119/249] Removing usage of "Modules" to refer to modules in JavaScript (using imports instead) --- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 12 +- .../LogarithmPlotter/js/history/common.mjs | 36 +----- .../LogarithmPlotter/js/history/module.mjs | 46 ++++++++ .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 103 +++++++++--------- .../js/lib/expr-eval/integration.mjs | 2 +- .../LogarithmPlotter/js/math/expression.mjs | 22 ++-- .../LogarithmPlotter/js/math/sequence.mjs | 14 ++- .../LogarithmPlotter/js/objs/autoload.mjs | 2 +- .../ad5001/LogarithmPlotter/js/parameters.mjs | 5 +- .../js/preferences/general.mjs | 6 +- 10 files changed, 139 insertions(+), 109 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index d214be3..3736a11 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -20,6 +20,8 @@ import { Module } from "./modules.mjs" import { textsup } from "./utils.mjs" import { Expression } from "./mathlib.mjs" import Latex from "./math/latex.mjs" +import Objects from "./objects.mjs" +import History from "./history/module.mjs" class CanvasAPI extends Module { @@ -168,8 +170,8 @@ class CanvasAPI extends Module { this._drawAxes() this._drawLabels() this._ctx.lineWidth = this.linewidth - for(let objType in Modules.Objects.currentObjects) { - for(let obj of Modules.Objects.currentObjects[objType]){ + for(let objType in Objects.currentObjects) { + for(let obj of Objects.currentObjects[objType]){ this._ctx.strokeStyle = obj.color this._ctx.fillStyle = obj.color if(obj.visible) @@ -180,7 +182,7 @@ class CanvasAPI extends Module { console.error(e) console.log(e.stack) this._drawingErrorDialog.showDialog(objType, obj.name, e.message) - Modules.History.undo() + History.undo() } } } @@ -188,7 +190,7 @@ class CanvasAPI extends Module { } /** - * Calculates informations for drawing gradations for axes. + * Calculates information for drawing gradations for axes. * @private */ _computeAxes() { @@ -538,4 +540,4 @@ class CanvasAPI extends Module { /** @type {CanvasAPI} */ Modules.Canvas = Modules.Canvas || new CanvasAPI() -export const API = Modules.Canvas +export default Modules.Canvas diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index db2d5dc..a9d7d60 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,35 +16,9 @@ * along with this program. If not, see . */ -import { Module } from "../modules.mjs" +import History from "./module.mjs" import Latex from "../math/latex.mjs" - -class HistoryCommonAPI extends Module { - constructor() { - super('History', [ - Modules.Latex - ]) - // History QML object - this.history = null; - this.themeTextColor = "#ff0000"; - this.imageDepth = 2; - this.fontSize = 14; - } - - undo() { this.history.undo() } - redo() { this.history.redo() } - clear() { this.history.clear() } - addToHistory(action) { this.history.addToHistory(action) } - unserialize(...data) { this.history.unserialize(...data) } - serialize() { return this.history.serialize() } -} - -/** @type {HistoryCommonAPI} */ -Modules.History = Modules.History || new HistoryCommonAPI() - -export const API = Modules.History - export class Action { /** * Type of the action. @@ -102,7 +76,7 @@ export class Action { * @returns {string} */ getIconRichText(type) { - return `` + return `` } /** @@ -115,11 +89,11 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") return new Promise(resolve => { - let imgDepth = Modules.History.imageDepth + let imgDepth = History.imageDepth Latex.requestAsyncRender( latexString, - imgDepth * (Modules.History.fontSize + 2), - Modules.History.themeTextColor + imgDepth * (History.fontSize + 2), + History.themeTextColor ).then((imgData) => { const { source, width, height } = imgData resolve(``) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs new file mode 100644 index 0000000..873502a --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs @@ -0,0 +1,46 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { Module } from "../modules.mjs" +import Latex from "../math/latex.mjs" + + +class HistoryAPI extends Module { + constructor() { + super('History', [ + Modules.Latex + ]) + // History QML object + this.history = null; + this.themeTextColor = "#ff0000"; + this.imageDepth = 2; + this.fontSize = 14; + } + + undo() { this.history.undo() } + redo() { this.history.redo() } + clear() { this.history.clear() } + addToHistory(action) { this.history.addToHistory(action) } + unserialize(...data) { this.history.unserialize(...data) } + serialize() { return this.history.serialize() } +} + +/** @type {HistoryAPI} */ +Modules.History = Modules.History || new HistoryAPI() + +export default Modules.History \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index 4bc76b5..0186321 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -16,12 +16,15 @@ * along with this program. If not, see . */ -import {Module} from "./modules.mjs" +import { Module } from "./modules.mjs" +import Objects from "./objects.mjs" +import History from "./history/module.mjs" +import Canvas from "./canvas.mjs" class IOAPI extends Module { constructor() { - super('IO', [ + super("IO", [ Modules.Objects, Modules.History ]) @@ -50,39 +53,39 @@ class IOAPI extends Module { */ saveDiagram(filename) { // Add extension if necessary - if(['lpf'].indexOf(filename.split('.')[filename.split('.').length-1]) === -1) - filename += '.lpf' + if(["lpf"].indexOf(filename.split(".")[filename.split(".").length - 1]) === -1) + filename += ".lpf" this.saveFilename = filename let objs = {} - for(let objType in Modules.Objects.currentObjects){ + for(let objType in Objects.currentObjects) { objs[objType] = [] - for(let obj of Modules.Objects.currentObjects[objType]) { + for(let obj of Objects.currentObjects[objType]) { objs[objType].push(obj.export()) } } let settings = { - "xzoom": this.settings.xzoom, - "yzoom": this.settings.yzoom, - "xmin": this.settings.xmin, - "ymax": this.settings.ymax, - "xaxisstep": this.settings.xaxisstep, - "yaxisstep": this.settings.yaxisstep, - "xaxislabel": this.settings.xlabel, - "yaxislabel": this.settings.ylabel, - "logscalex": this.settings.logscalex, - "linewidth": this.settings.linewidth, - "showxgrad": this.settings.showxgrad, - "showygrad": this.settings.showygrad, - "textsize": this.settings.textsize, - "history": Modules.History.serialize(), - "width": this.rootElement.width, - "height": this.rootElement.height, - "objects": objs, - "type": "logplotv1" + "xzoom": this.settings.xzoom, + "yzoom": this.settings.yzoom, + "xmin": this.settings.xmin, + "ymax": this.settings.ymax, + "xaxisstep": this.settings.xaxisstep, + "yaxisstep": this.settings.yaxisstep, + "xaxislabel": this.settings.xlabel, + "yaxislabel": this.settings.ylabel, + "logscalex": this.settings.logscalex, + "linewidth": this.settings.linewidth, + "showxgrad": this.settings.showxgrad, + "showygrad": this.settings.showygrad, + "textsize": this.settings.textsize, + "history": History.serialize(), + "width": this.rootElement.width, + "height": this.rootElement.height, + "objects": objs, + "type": "logplotv1" } Helper.write(filename, JSON.stringify(settings)) - this.alert.show(qsTranslate('io', "Saved plot to '%1'.").arg(filename.split("/").pop())) - Modules.History.history.saved = true + this.alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) + History.history.saved = true } /** @@ -91,16 +94,16 @@ class IOAPI extends Module { */ loadDiagram(filename) { let basename = filename.split("/").pop() - this.alert.show(qsTranslate('io', "Loading file '%1'.").arg(basename)) + this.alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename)) let data = JSON.parse(Helper.load(filename)) - let error = ""; + let error = "" if(Object.keys(data).includes("type") && data["type"] === "logplotv1") { - Modules.History.clear() + History.clear() // Importing settings this.settings.saveFilename = filename this.settings.xzoom = parseFloat(data["xzoom"]) || 100 this.settings.yzoom = parseFloat(data["yzoom"]) || 10 - this.settings.xmin = parseFloat(data["xmin"]) || 5/10 + this.settings.xmin = parseFloat(data["xmin"]) || 5 / 10 this.settings.ymax = parseFloat(data["ymax"]) || 24 this.settings.xaxisstep = data["xaxisstep"] || "4" this.settings.yaxisstep = data["yaxisstep"] || "4" @@ -119,51 +122,53 @@ class IOAPI extends Module { this.rootElement.width = parseFloat(data["width"]) || 1000 // Importing objects - Modules.Objects.currentObjects = {} - for(let key of Object.keys(Modules.Objects.currentObjectsByName)) { - delete Modules.Objects.currentObjectsByName[key]; + Objects.currentObjects = {} + for(let key of Object.keys(Objects.currentObjectsByName)) { + delete Objects.currentObjectsByName[key] // Required to keep the same reference for the copy of the object used in expression variable detection. // Another way would be to change the reference as well, but I feel like the code would be less clean. } - for(let objType in data['objects']) { - if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { - Modules.Objects.currentObjects[objType] = [] - for(let objData of data['objects'][objType]) { + for(let objType in data["objects"]) { + if(Object.keys(Objects.types).indexOf(objType) > -1) { + Objects.currentObjects[objType] = [] + for(let objData of data["objects"][objType]) { /** @type {DrawableObject} */ - let obj = Modules.Objects.types[objType].import(...objData) - Modules.Objects.currentObjects[objType].push(obj) - Modules.Objects.currentObjectsByName[obj.name] = obj + let obj = Objects.types[objType].import(...objData) + Objects.currentObjects[objType].push(obj) + Objects.currentObjectsByName[obj.name] = obj } } else { - error += qsTranslate('io', "Unknown object type: %1.").arg(objType) + "\n"; + error += qsTranslate("io", "Unknown object type: %1.").arg(objType) + "\n" } } // Updating object dependencies. - for(let objName in Modules.Objects.currentObjectsByName) - Modules.Objects.currentObjectsByName[objName].update() + for(let objName in Objects.currentObjectsByName) + Objects.currentObjectsByName[objName].update() // Importing history if("history" in data) - Modules.History.unserialize(...data["history"]) + History.unserialize(...data["history"]) // Refreshing sidebar this.rootElement.updateObjectsLists() } else { - error = qsTranslate('io', "Invalid file provided.") + error = qsTranslate("io", "Invalid file provided.") } if(error !== "") { console.log(error) - this.alert.show(qsTranslate('io', "Could not save file: ") + error) + this.alert.show(qsTranslate("io", "Could not save file: ") + error) // TODO: Error handling return } - Modules.Canvas.redraw() - this.alert.show(qsTranslate('io', "Loaded file '%1'.").arg(basename)) - Modules.History.history.saved = true + Canvas.redraw() + this.alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) + History.history.saved = true } } /** @type {IOAPI} */ Modules.IO = Modules.IO || new IOAPI() + +export default Modules.IO \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs index 244194f..2b99c9a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs @@ -112,5 +112,5 @@ export class ExprParserAPI extends Module { /** @type {ExprParserAPI} */ Modules.ExprParser = Modules.ExprParser || new ExprParserAPI() - +export default Modules.ExprParser diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 3a0ebb4..eb8ac8a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -19,19 +19,17 @@ import Latex from "latex.mjs" import * as Utils from "../utils.mjs" +import ExprParser from "../lib/expr-eval/integration.mjs" +import Objects from "../objects.mjs" /** * Represents any kind of x-based or non variable based expression. */ export class Expression { constructor(expr) { - if(!Modules.ExprParser) - throw new Error('Expression parser not initialized.') - if(!Modules.Objects) - throw new Error('Objects API not initialized.') if(typeof expr === "string") { this.expr = Utils.exponentsToExpression(expr) - this.calc = Modules.ExprParser.parse(this.expr).simplify() + this.calc = ExprParser.parse(this.expr).simplify() } else { // Passed an expression here directly. this.calc = expr.simplify() @@ -40,7 +38,7 @@ export class Expression { this.cached = this.isConstant() this.cachedValue = null if(this.cached && this.allRequirementsFullfilled()) - this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -54,26 +52,26 @@ export class Expression { } allRequirementsFullfilled() { - return this.requiredObjects().every(objName => objName in Modules.Objects.currentObjectsByName) + return this.requiredObjects().every(objName => objName in Objects.currentObjectsByName) } undefinedVariables() { - return this.requiredObjects().filter(objName => !(objName in Modules.Objects.currentObjectsByName)) + return this.requiredObjects().filter(objName => !(objName in Objects.currentObjectsByName)) } recache() { if(this.cached) - this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) } execute(x = 1) { if(this.cached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) return this.cachedValue } - Modules.ExprParser.currentVars = Object.assign({'x': x}, Modules.Objects.currentObjectsByName) - return this.calc.evaluate(Modules.ExprParser.currentVars) + ExprParser.currentVars = Object.assign({'x': x}, Objects.currentObjectsByName) + return this.calc.evaluate(ExprParser.currentVars) } simplify(x) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index 677d68e..abc04c1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -18,7 +18,9 @@ import * as Expr from "expression.mjs" import * as Utils from "../utils.mjs" -import Latex from "../math/latex.mjs" +import Latex from "./latex.mjs" +import Objects from "../objects.mjs" +import ExprParser from "../lib/expr-eval/integration.mjs" /** * Represents mathematical object for sequences. @@ -33,7 +35,7 @@ export class Sequence extends Expr.Expression { this.latexValues = Object.assign({}, baseValues) for(let n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { - let parsed = Modules.ExprParser.parse(this.calcValues[n].toString()).simplify() + let parsed = ExprParser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate() } @@ -59,17 +61,17 @@ export class Sequence extends Expr.Expression { cache(n = 1) { let str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - let expr = Modules.ExprParser.parse(str).simplify() + let expr = ExprParser.parse(str).simplify() // Cache values required for this one. if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) this.cache(n-this.valuePlus) // Setting current variables - Modules.ExprParser.currentVars = Object.assign( + ExprParser.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - Modules.Objects.currentObjectsByName, + Objects.currentObjectsByName, {[this.name]: this.calcValues} ) - this.calcValues[n] = expr.evaluate(Modules.ExprParser.currentVars) + this.calcValues[n] = expr.evaluate(ExprParser.currentVars) } toString(forceSign=false) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index cf0df63..6173faf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -43,7 +43,7 @@ function registerObject(obj) { } } -if(Object.keys(Modules.Objects.types).length === 0) { +if(Object.keys(Objects.types).length === 0) { registerObject(Point) registerObject(Text) registerObject(Function) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index f59c322..477e3d5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -16,6 +16,7 @@ * along with this program. If not, see . */ import {parseDomain, Expression as Expr, Domain} from "./mathlib.mjs" +import { Objects } from "./objects.mjs" const NONE = class Empty {} @@ -129,8 +130,8 @@ export class ObjectType extends PropertyType { parse(name) { let result = NONE - if(typeof name == 'string' && name in Modules.Objects.currentObjectsByName) { - let obj = Modules.Objects.currentObjectsByName[name] + if(typeof name == 'string' && name in Objects.currentObjectsByName) { + let obj = Objects.currentObjectsByName[name] if (obj.type === this.objType || (this.objType === 'ExecutableObject' && obj.execute)) { result = obj } else { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index eb47e4a..d5f2fb5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -17,6 +17,8 @@ */ import {BoolSetting} from "common.mjs" +import Canvas from "../canvas.mjs" +import LatexAPI from "../math/latex.mjs" const CHECK_FOR_UPDATES = new BoolSetting( qsTranslate("general", "Check for updates on startup"), @@ -38,8 +40,8 @@ class EnableLatex extends BoolSetting { set(value) { if(!value || Latex.checkLatexInstallation()) { super.set(value) - Modules.Latex.enabled = value - Modules.Canvas.requestPaint() + LatexAPI.enabled = value + Canvas.requestPaint() } } } From c66d08b3522ded83b03da42aa4df55456131725e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 22 Sep 2024 21:59:11 +0200 Subject: [PATCH 120/249] Moving Modules to separate directory --- .../qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs | 14 +++++++------- .../ad5001/LogarithmPlotter/js/history/color.mjs | 2 +- .../ad5001/LogarithmPlotter/js/history/common.mjs | 4 ++-- .../ad5001/LogarithmPlotter/js/history/create.mjs | 2 +- .../ad5001/LogarithmPlotter/js/history/delete.mjs | 2 +- .../LogarithmPlotter/js/history/editproperty.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/history/name.mjs | 2 +- .../LogarithmPlotter/js/history/position.mjs | 4 ++-- .../LogarithmPlotter/js/history/visibility.mjs | 2 +- .../ad5001/LogarithmPlotter/js/math/expression.mjs | 6 +++--- .../ad5001/LogarithmPlotter/js/math/sequence.mjs | 6 +++--- .../LogarithmPlotter/js/{ => module}/canvas.mjs | 10 +++++----- .../js/{modules.mjs => module/common.mjs} | 0 .../integration.mjs => module/expreval.mjs} | 4 ++-- .../js/{history/module.mjs => module/history.mjs} | 4 ++-- .../ad5001/LogarithmPlotter/js/{ => module}/io.mjs | 4 ++-- .../LogarithmPlotter/js/{math => module}/latex.mjs | 2 +- .../LogarithmPlotter/js/{ => module}/objects.mjs | 4 ++-- .../js/{ => module}/preferences.mjs | 8 ++++---- .../ad5001/LogarithmPlotter/js/objs/autoload.mjs | 2 +- .../LogarithmPlotter/js/objs/bodemagnitude.mjs | 12 +++++------- .../LogarithmPlotter/js/objs/bodemagnitudesum.mjs | 4 ++-- .../ad5001/LogarithmPlotter/js/objs/bodephase.mjs | 10 +++++----- .../LogarithmPlotter/js/objs/bodephasesum.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/objs/common.mjs | 4 ++-- .../LogarithmPlotter/js/objs/distribution.mjs | 4 ++-- .../ad5001/LogarithmPlotter/js/objs/function.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/objs/point.mjs | 4 ++-- .../ad5001/LogarithmPlotter/js/objs/sequence.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/objs/text.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/parameters.mjs | 8 ++++---- .../LogarithmPlotter/js/preferences/general.mjs | 4 ++-- 33 files changed, 77 insertions(+), 79 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => module}/canvas.mjs (98%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{modules.mjs => module/common.mjs} (100%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{lib/expr-eval/integration.mjs => module/expreval.mjs} (97%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{history/module.mjs => module/history.mjs} (93%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => module}/io.mjs (98%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{math => module}/latex.mjs (99%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => module}/objects.mjs (98%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => module}/preferences.mjs (87%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs index dcdaedb..085a5c5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs @@ -17,11 +17,11 @@ */ // Loading modules in order -import * as Objects from "./objects.mjs" -import * as ExprParser from "./lib/expr-eval/integration.mjs" +import * as Objects from "./module/objects.mjs" +import * as ExprParser from "./module/expreval.mjs" import * as ObjsAutoload from "./objs/autoload.mjs" -import * as Latex from "./math/latex.mjs" -import * as HistoryCommon from "./history/common.mjs" -import * as CanvasAPI from "./canvas.mjs" -import * as IOAPI from "./io.mjs" -import * as PreferencesAPI from "./preferences.mjs" +import * as Latex from "./module/latex.mjs" +import * as History from "./module/history.mjs" +import * as CanvasAPI from "./module/canvas.mjs" +import * as IOAPI from "./module/io.mjs" +import * as PreferencesAPI from "./module/preferences.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index 12a8793..067da0c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -17,7 +17,7 @@ */ import EditedProperty from "editproperty.mjs" -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" export default class ColorChanged extends EditedProperty { // Action used everytime when an object's color is changed diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index a9d7d60..41d28ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import History from "./module.mjs" -import Latex from "../math/latex.mjs" +import History from "../module/history.mjs" +import Latex from "../module/latex.mjs" export class Action { /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index b2c7f2d..bd3dafd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" import { Action } from "common.mjs" export default class CreateNewObject extends Action { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index 7fa855d..c348c41 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" import CreateNewObject from "create.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 1280e54..febed9a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import * as MathLib from "../mathlib.mjs" import { Action } from "common.mjs" import { DrawableObject } from "../objs/common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index 13417da..a852923 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -17,7 +17,7 @@ */ import EditedProperty from "editproperty.mjs" -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" export default class NameChanged extends EditedProperty { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index b071cc7..14b5bac 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import * as MathLib from "../mathlib.mjs" import { escapeHTML } from "../utils.mjs" import { Action } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index ebcb4fa..c04e0a4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -17,7 +17,7 @@ */ import EditedProperty from "editproperty.mjs" -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" export default class EditedVisibility extends EditedProperty { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index eb8ac8a..8a7bf77 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -17,10 +17,10 @@ */ -import Latex from "latex.mjs" import * as Utils from "../utils.mjs" -import ExprParser from "../lib/expr-eval/integration.mjs" -import Objects from "../objects.mjs" +import Latex from "../module/latex.mjs" +import ExprParser from "../module/expreval.mjs" +import Objects from "../module/objects.mjs" /** * Represents any kind of x-based or non variable based expression. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index abc04c1..d524e44 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -18,9 +18,9 @@ import * as Expr from "expression.mjs" import * as Utils from "../utils.mjs" -import Latex from "./latex.mjs" -import Objects from "../objects.mjs" -import ExprParser from "../lib/expr-eval/integration.mjs" +import Latex from "../module/latex.mjs" +import Objects from "../module/objects.mjs" +import ExprParser from "../module/expreval.mjs" /** * Represents mathematical object for sequences. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs similarity index 98% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs index 3736a11..cd86c6e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -import { Module } from "./modules.mjs" -import { textsup } from "./utils.mjs" -import { Expression } from "./mathlib.mjs" -import Latex from "./math/latex.mjs" +import { Module } from "./common.mjs" +import { textsup } from "../utils.mjs" +import { Expression } from "../mathlib.mjs" +import Latex from "./latex.mjs" import Objects from "./objects.mjs" -import History from "./history/module.mjs" +import History from "./history.mjs" class CanvasAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs similarity index 97% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index 2b99c9a..9ad06d5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { Module } from "../../modules.mjs" -import { Parser } from "./parser.mjs" +import { Module } from "./common.mjs" +import { Parser } from "../lib/expr-eval/parser.mjs" const evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs index 873502a..27eedcb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/module.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { Module } from "../modules.mjs" -import Latex from "../math/latex.mjs" +import { Module } from "./common.mjs" +import Latex from "./latex.mjs" class HistoryAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs similarity index 98% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index 0186321..bc9a1db 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import { Module } from "./modules.mjs" +import { Module } from "./common.mjs" import Objects from "./objects.mjs" -import History from "./history/module.mjs" +import History from "./history.mjs" import Canvas from "./canvas.mjs" class IOAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs similarity index 99% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs index ad4c1f2..32f048b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Module } from "../modules.mjs" +import { Module } from "./common.mjs" import * as Instruction from "../lib/expr-eval/instruction.mjs" import { escapeValue } from "../lib/expr-eval/expression.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs similarity index 98% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs index ef45429..5a63386 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { Module } from './modules.mjs' -import { textsub } from './utils.mjs' +import { Module } from './common.mjs' +import { textsub } from '../utils.mjs' class ObjectsAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs similarity index 87% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs index 40ac532..e76596e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs @@ -15,10 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import {Module} from "modules.mjs" -import General from "preferences/general.mjs" -import Editor from "preferences/expression.mjs" -import DefaultGraph from "preferences/default.mjs" +import {Module} from "./common.mjs" +import General from "../preferences/general.mjs" +import Editor from "../preferences/expression.mjs" +import DefaultGraph from "../preferences/default.mjs" class PreferencesAPI extends Module { constructor() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index 6173faf..a7351b5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" import { DrawableObject } from "common.mjs" import Point from "point.mjs" import Text from "text.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index c01bcae..05e1150 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -17,17 +17,15 @@ */ import { parseDomain, executeExpression, Expression, EmptySet, Domain } from "../mathlib.mjs" +import { CreateNewObject } from "../historylib.mjs" import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" +import History from "../module/history.mjs" import { ExecutableObject } from "common.mjs" import Function from "function.mjs" -import { API as HistoryAPI } from "../history/common.mjs" -import { CreateNewObject } from "../historylib.mjs" - - export default class BodeMagnitude extends ExecutableObject { static type(){return 'Gain Bode'} static displayType(){return qsTranslate("bodemagnitude", 'Bode Magnitude')} @@ -52,7 +50,7 @@ export default class BodeMagnitude extends ExecutableObject { if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), true, this.color, 'name']) - HistoryAPI.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) + History.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index 82bf6b6..4531bee 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -18,8 +18,8 @@ import { Range, Expression, Domain } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import { ExecutableObject } from "common.mjs" import Function from "function.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index 23119ef..cce63fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -17,11 +17,11 @@ */ import { executeExpression, Expression } from "../mathlib.mjs" -import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import { API as HistoryAPI } from "../history/common.mjs" import { CreateNewObject } from "../historylib.mjs" -import Latex from "../math/latex.mjs" +import * as P from "../parameters.mjs" +import Objects from "../module/objects.mjs" +import History from "../module/history.mjs" +import Latex from "../module/latex.mjs" import { ExecutableObject } from "common.mjs" @@ -52,7 +52,7 @@ export default class BodePhase extends ExecutableObject { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), this.color, 'name']) om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' - HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) + History.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' } om_0.requiredBy.push(this) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index 1f1a0fa..d55a29c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -18,8 +18,8 @@ import { executeExpression, Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import { ExecutableObject } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index b27cbf3..9b13fbd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -17,8 +17,8 @@ */ import { getRandomColor, textsub } from "../utils.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" // This file contains the default data to be imported from all other objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs index e0fe698..1ad9a7e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs @@ -17,8 +17,8 @@ */ import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import { ExecutableObject } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index eb3f081..31afc37 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -17,11 +17,11 @@ */ import { textsub } from "../utils.mjs" -import Objects from "../objects.mjs" +import Objects from "../module/objects.mjs" import { ExecutableObject } from "common.mjs" import { parseDomain, Expression, SpecialDomain } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Latex from "../math/latex.mjs" +import Latex from "../module/latex.mjs" export default class Function extends ExecutableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 503026e..7264894 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -18,8 +18,8 @@ import { Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import { DrawableObject } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index b05a66e..5d431af 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -18,8 +18,8 @@ import { Sequence as MathSequence, Domain } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Latex from "../math/latex.mjs" -import Objects from "../objects.mjs" +import Latex from "../module/latex.mjs" +import Objects from "../module/objects.mjs" import { ExecutableObject } from "common.mjs" import Function from "function.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index 3ad1e82..a819d7a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -18,8 +18,8 @@ import { Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Objects from "../objects.mjs" -import Latex from "../math/latex.mjs" +import Objects from "../module/objects.mjs" +import Latex from "../module/latex.mjs" import { DrawableObject } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index f377a74..63c85d3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -18,8 +18,8 @@ import { Expression } from "../mathlib.mjs" import * as P from "../parameters.mjs" -import Latex from "../math/latex.mjs" -import Objects from "../objects.mjs" +import Latex from "../module/latex.mjs" +import Objects from "../module/objects.mjs" import { DrawableObject } from "common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 477e3d5..6cd9e04 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ import {parseDomain, Expression as Expr, Domain} from "./mathlib.mjs" -import { Objects } from "./objects.mjs" +import Objects from "./module/objects.mjs" const NONE = class Empty {} @@ -175,15 +175,15 @@ export class List extends PropertyType { parse(value) { let result = NONE if(typeof value == 'object' && value.__proto__ === Array) { - let list = [] + let valid = 0 for(let v of value) { if (this.format.test(v)) { v = stringValuesValidators[this.valueType][0](v) if(stringValuesValidators[this.valueType][1](v)) - list.append(v) + valid++ } } - if(list.length === value.length) + if(valid === value.length) // Ensure every value is valid. result = value } return result diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index d5f2fb5..2c5ef17 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -17,8 +17,8 @@ */ import {BoolSetting} from "common.mjs" -import Canvas from "../canvas.mjs" -import LatexAPI from "../math/latex.mjs" +import Canvas from "../module/canvas.mjs" +import LatexAPI from "../module/latex.mjs" const CHECK_FOR_UPDATES = new BoolSetting( qsTranslate("general", "Check for updates on startup"), From 5bdf81b2ed809d29b117fe08cfdf4fe9018e832a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 04:35:10 +0200 Subject: [PATCH 121/249] Adding new python --- LogarithmPlotter/__init__.py | 4 --- tests/python/test_native.py | 57 ++++++++++++++++++++++++++++++++ tests/python/test_update.py | 63 ++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 tests/python/test_native.py create mode 100644 tests/python/test_update.py diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index b3140ad..2bd4967 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -39,7 +39,3 @@ if not is_release and which('git') is not None: # Date cannot be parsed, not git root? pass -if __name__ == "__main__": - from .logarithmplotter import run - - run() diff --git a/tests/python/test_native.py b/tests/python/test_native.py new file mode 100644 index 0000000..edaf88e --- /dev/null +++ b/tests/python/test_native.py @@ -0,0 +1,57 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +import pytest +from os.path import exists + +from PySide6.QtCore import QEvent, QObject, QUrl +from PySide6.QtGui import QActionEvent, QFileOpenEvent + +from LogarithmPlotter.util.native import MacOSFileOpenHandler + + +class LoadDiagramCalledSuccessfully(Exception): pass + + +class MockIO: + def loadDiagram(self, file_name): + assert type(file_name) == str + raise LoadDiagramCalledSuccessfully() + + +class MockFileOpenEvent(QEvent): + def __init__(self, file): + super(QEvent.FileOpen) + self._file = file + + def file(self): + return self._file + + +def test_native(): + event_filter = MacOSFileOpenHandler() + # Nothing should happen here. The module hasn't been initialized + event_filter.eventFilter(None, QFileOpenEvent(QUrl.fromLocalFile("ci/test1.lpf"))) + with pytest.raises(LoadDiagramCalledSuccessfully): + event_filter.init_io(MockIO()) # Now that we've initialized, the loadDiagram function should be called. + with pytest.raises(LoadDiagramCalledSuccessfully): + # And now it will do so every time an event is loaded. + event_filter.eventFilter(None, QFileOpenEvent(QUrl.fromLocalFile("ci/test1.lpf"))) + # Check what happens when a non file open qevent is launched against it. + event_filter.eventFilter(QObject(), QEvent(QEvent.ActionAdded)) + diff --git a/tests/python/test_update.py b/tests/python/test_update.py new file mode 100644 index 0000000..385d12a --- /dev/null +++ b/tests/python/test_update.py @@ -0,0 +1,63 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from sys import argv + +import pytest +from PySide6.QtCore import QThreadPool + +from LogarithmPlotter import __VERSION__ as version +from LogarithmPlotter.util.update import UpdateInformation, UpdateCheckerRunnable, check_for_updates + + +class MockWindow: + def showAlert(self, msg): raise Exception(msg) + def showUpdateMenu(self, msg): pass + +def check_update_callback_type(show_alert, msg_text, update_available): + assert type(show_alert) == bool + assert type(msg_text) == str + assert type(update_available) == bool + +def test_update(): + def check_older(show_alert, msg_text, update_available): + check_update_callback_type(show_alert, msg_text, update_available) + assert update_available + assert show_alert + + def check_newer(show_alert, msg_text, update_available): + check_update_callback_type(show_alert, msg_text, update_available) + assert not update_available + assert not show_alert + + update_info_older = UpdateInformation() + update_info_older.got_update_info.connect(check_older) + update_info_newer = UpdateInformation() + update_info_newer.got_update_info.connect(check_newer) + runnable = UpdateCheckerRunnable('1.0.0', update_info_newer) + runnable.run() + runnable = UpdateCheckerRunnable('0.1.0', update_info_older) + runnable.run() + runnable = UpdateCheckerRunnable('0.5.0+dev0+git20240101', update_info_older) + runnable.run() + +def test_update_checker(): + check_for_updates('0.6.0', MockWindow()) + assert QThreadPool.globalInstance().activeThreadCount() == 1 + argv.append("--no-check-for-updates") + check_for_updates('0.6.0', MockWindow()) + assert QThreadPool.globalInstance().activeThreadCount() < 2 # No new update checks where added From 84a65cd1fc0c7925c18ba12655cadd793a190d35 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 05:58:29 +0200 Subject: [PATCH 122/249] Testing the Helper. We're now getting to 88% coverage on python. I don't think I can get it much higher between the statements that pytest doesn't count, the ones which aren't easy to reproduce in test env (eg no internet connection), and the ones essential to the app's startup workflow. --- LogarithmPlotter/logarithmplotter.py | 18 ++-- LogarithmPlotter/util/helper.py | 54 +++++----- LogarithmPlotter/util/update.py | 1 + tests/python/test_helper.py | 156 ++++++++++++++++++++++++++- tests/python/test_native.py | 2 +- tests/python/test_update.py | 12 ++- 6 files changed, 201 insertions(+), 42 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index d528c02..bc4d895 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -36,7 +36,8 @@ tempdir = TemporaryDirectory() tmpfile = path.join(tempdir.name, 'graph.png') pwd = getcwd() -chdir(path.dirname(path.realpath(__file__))) +logarithmplotter_path = path.dirname(path.realpath(__file__)) +chdir(logarithmplotter_path) if path.realpath(path.join(getcwd(), "..")) not in sys_path: sys_path.append(path.realpath(path.join(getcwd(), ".."))) @@ -91,7 +92,7 @@ def get_platform_qt_style(os) -> str: def register_icon_directories() -> None: icon_fallbacks = QIcon.fallbackSearchPaths() - base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") + base_icon_path = path.join(logarithmplotter_path, "qml", "eu", "ad5001", "LogarithmPlotter", "icons") paths = [["common"], ["objects"], ["history"], ["settings"], ["settings", "custom"]] for p in paths: icon_fallbacks.append(path.realpath(path.join(base_icon_path, *p))) @@ -106,7 +107,7 @@ def create_qapp() -> QApplication: app.setDesktopFileName("eu.ad5001.LogarithmPlotter") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) - app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) + app.setWindowIcon(QIcon(path.realpath(path.join(logarithmplotter_path, "logarithmplotter.svg")))) return app @@ -115,10 +116,12 @@ def install_translation(app: QApplication) -> QTranslator: translator = QTranslator() # Check if lang is forced. forcedlang = [p for p in argv if p[:7] == "--lang="] + i18n_path = path.realpath(path.join(logarithmplotter_path, "i18n")) locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() - if not translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): + if not translator.load(locale, "lp", "_", i18n_path): # Load default translation - translator.load(QLocale("en"), "lp", "_", path.realpath(path.join(getcwd(), "i18n"))) + print("Loading default language en...") + translator.load(QLocale("en"), "lp", "_", i18n_path) app.installTranslator(translator) return translator @@ -133,8 +136,9 @@ def create_engine(helper: Helper, latex: Latex, dep_time: float) -> tuple[QQmlAp engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) - engine.addImportPath(path.realpath(path.join(getcwd(), "qml"))) - engine.load(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) + qml_path = path.realpath(path.join(logarithmplotter_path, "qml")) + engine.addImportPath(qml_path) + engine.load(path.join(qml_path, "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml")) return engine, js_globals diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index c7c92d8..d2fe631 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -24,16 +24,29 @@ from PySide6 import __version__ as PySide6_version from os import chdir, path from json import loads -from sys import version as sys_version +from sys import version as sys_version, argv from urllib.request import urlopen from urllib.error import HTTPError, URLError from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config +SHOW_GUI_MESSAGES = "--test-build" not in argv +CHANGELOG_VERSION = __VERSION__ + class InvalidFileException(Exception): pass +def show_message(msg: str) -> None: + """ + Shows a GUI message if GUI messages are enabled + """ + if SHOW_GUI_MESSAGES: + QMessageBox.warning(None, "LogarithmPlotter", msg, QMessageBox.OK) + else: + raise InvalidFileException(msg) + + class ChangelogFetcher(QRunnable): def __init__(self, helper): @@ -44,7 +57,7 @@ class ChangelogFetcher(QRunnable): msg_text = "Unknown changelog error." try: # Fetching version - r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + __VERSION__) + r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + CHANGELOG_VERSION) lines = r.readlines() r.close() msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() @@ -53,21 +66,16 @@ class ChangelogFetcher(QRunnable): str(e.code)) except URLError as e: msg_text = QCoreApplication.translate("changelog", "Could not fetch update: {}.").format(str(e.reason)) - self.helper.gotChangelog.emit(msg_text) + self.helper.changelogFetched.emit(msg_text) class Helper(QObject): changelogFetched = Signal(str) - gotChangelog = Signal(str) def __init__(self, cwd: str, tmpfile: str): QObject.__init__(self) self.cwd = cwd self.tmpfile = tmpfile - self.gotChangelog.connect(self.fetched) - - def fetched(self, changelog: str): - self.changelogFetched.emit(changelog) @Slot(str, str) def write(self, filename, filedata): @@ -93,20 +101,19 @@ class Helper(QObject): if data[:5] == "LPFv1": # V1 version of the file data = data[5:] - elif data[0] == "{" and "type" in loads(data) and loads(data)["type"] == "logplotv1": - pass elif data[:3] == "LPF": # More recent version of LogarithmPlotter file, but incompatible with the current format - msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.") + msg = QCoreApplication.translate('main', + "This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.") raise InvalidFileException(msg.format(__VERSION__)) else: - raise Exception("Invalid LogarithmPlotter file.") - except Exception as e: # If file can't be loaded + raise InvalidFileException("Invalid LogarithmPlotter file.") + except InvalidFileException as e: # If file can't be loaded msg = QCoreApplication.translate('main', 'Could not open file "{}":\n{}') - QMessageBox.warning(None, 'LogarithmPlotter', msg.format(filename, e), QMessageBox.Ok) # Cannot parse file + show_message(msg.format(filename, e)) # Cannot parse file else: msg = QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.') - QMessageBox.warning(None, 'LogarithmPlotter', msg.format(filename), QMessageBox.Ok) # Cannot parse file + show_message(msg.format(filename)) # Cannot parse file try: chdir(path.dirname(path.realpath(__file__))) except NotADirectoryError as e: @@ -130,31 +137,27 @@ class Helper(QObject): @Slot(str, result=str) def getSetting(self, namespace): - return config.getSetting(namespace) + return str(config.getSetting(namespace)) @Slot(str, result=float) def getSettingInt(self, namespace): - return config.getSetting(namespace) + return float(config.getSetting(namespace)) @Slot(str, result=bool) def getSettingBool(self, namespace): - return config.getSetting(namespace) + return bool(config.getSetting(namespace)) @Slot(str, str) def setSetting(self, namespace, value): - return config.setSetting(namespace, value) + return config.setSetting(namespace, str(value)) @Slot(str, bool) def setSettingBool(self, namespace, value): - return config.setSetting(namespace, value) + return config.setSetting(namespace, bool(value)) @Slot(str, float) def setSettingInt(self, namespace, value): - return config.setSetting(namespace, value) - - @Slot(str) - def setLanguage(self, new_lang): - config.setSetting("language", new_lang) + return config.setSetting(namespace, float(value)) @Slot(result=str) def getDebugInfos(self): @@ -167,7 +170,6 @@ class Helper(QObject): @Slot() def fetchChangelog(self): changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") - print(changelog_cache_path) if path.exists(changelog_cache_path): # We have a cached version of the changelog, for env that don't have access to the internet. f = open(changelog_cache_path); diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index ed2b5ba..32017d5 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -89,3 +89,4 @@ def check_for_updates(current_version, window): runnable = UpdateCheckerRunnable(current_version, update_info) QThreadPool.globalInstance().start(runnable) + return update_info diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py index c4f6ea7..412eac3 100644 --- a/tests/python/test_helper.py +++ b/tests/python/test_helper.py @@ -17,18 +17,166 @@ """ import pytest -from os import getcwd +from os import getcwd, remove from os.path import join from tempfile import TemporaryDirectory -from LogarithmPlotter.util import config +from json import loads +from shutil import copy2 + +from PySide6.QtCore import QObject, Signal, QThreadPool +from PySide6.QtGui import QImage +from PySide6.QtWidgets import QApplication + +from LogarithmPlotter import __VERSION__ as version +from LogarithmPlotter.util import config, helper +from LogarithmPlotter.util.helper import ChangelogFetcher, Helper, InvalidFileException pwd = getcwd() - +helper.SHOW_GUI_MESSAGES = False @pytest.fixture() def temporary(): directory = TemporaryDirectory() config.CONFIG_PATH = join(directory.name, "config.json") tmpfile = join(directory.name, "graph.png") - yield tmpfile + yield tmpfile, directory directory.cleanup() + + +class MockHelperSignals(QObject): + changelogFetched = Signal(str) + + def __init__(self, expect_404): + QObject.__init__(self) + self.expect_404 = expect_404 + self.changelogFetched.connect(self.changelog_fetched) + self.changelog = None + + def changelog_fetched(self, changelog): + self.changelog = changelog + + +class TestChangelog: + + def test_exists(self, qtbot): + helper.CHANGELOG_VERSION = '0.5.0' + mock_helper = MockHelperSignals(False) + fetcher = ChangelogFetcher(mock_helper) + fetcher.run() # Does not raise an exception + qtbot.waitSignal(mock_helper.changelogFetched, timeout=10000) + assert type(mock_helper.changelog) == str + assert '404' not in mock_helper.changelog + + def tests_no_exist(self, qtbot): + mock_helper = MockHelperSignals(True) + helper.CHANGELOG_VERSION = '1.0.0' + fetcher = ChangelogFetcher(mock_helper) + fetcher.run() + qtbot.waitSignal(mock_helper.changelogFetched, timeout=10000) + assert type(mock_helper.changelog) == str + assert '404' in mock_helper.changelog + + +class TestHelper: + def test_read(self, temporary): + # Test file reading and information loading. + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + data = obj.load("ci/test1.lpf") + assert type(data) == str + data = loads(data) + assert data['type'] == "logplotv1" + # Checking data['types'] of valid file. + # See https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/LogarithmPlotter-file-format-v1.0 + assert type(data['width']) == int + assert type(data['height']) == int + assert type(data['xzoom']) in (int, float) + assert type(data['yzoom']) in (int, float) + assert type(data['xmin']) in (int, float) + assert type(data['ymax']) in (int, float) + assert type(data['xaxisstep']) == str + assert type(data['yaxisstep']) == str + assert type(data['xaxislabel']) == str + assert type(data['yaxislabel']) == str + assert type(data['logscalex']) == bool + assert type(data['linewidth']) in (int, float) + assert type(data['showxgrad']) == bool + assert type(data['showygrad']) == bool + assert type(data['textsize']) in (int, float) + assert type(data['history']) == list and len(data['history']) == 2 + assert type(data['history'][0]) == list + assert type(data['history'][1]) == list + for action_list in data['history']: + for action in action_list: + assert type(action[0]) == str + assert type(action[1]) == list + assert type(data['objects']) == dict + for obj_type, objects in data['objects'].items(): + assert type(obj_type) == str + assert type(objects) == list + for obj in objects: + assert type(obj) == list + + def test_read_newer(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + newer_file_path = join(directory.name, "newer.lpf") + with open(newer_file_path, "w") as f: + f.write("LPFv2[other invalid data]") + with pytest.raises(InvalidFileException): + obj.load(newer_file_path) + + def test_read_invalid_file(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + with pytest.raises(InvalidFileException): + obj.load("./inexistant.lpf") + with pytest.raises(InvalidFileException): + obj.load("./pyproject.toml") + + def test_write(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + target = join(directory.name, "target.lpf") + data = "example_data" + obj.write(target, data) + with open(target, "r") as f: + read_data = f.read() + # Ensure data has been written. + assert read_data == "LPFv1" + data + + def test_tmp_graphic(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + assert obj.gettmpfile() == tmpfile + obj.copyImageToClipboard() + clipboard = QApplication.clipboard() + assert type(clipboard.image()) == QImage + + def test_strings(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + assert obj.getVersion() == version + assert type(obj.getDebugInfos()) == str + assert type(obj.getSetting("check_for_updates")) == str + assert type(obj.getSettingInt("check_for_updates")) == float + assert type(obj.getSettingBool("check_for_updates")) == bool + + def test_set_config(self, temporary): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + obj.setSetting("last_install_greet", obj.getSetting("last_install_greet")) + obj.setSettingBool("check_for_updates", obj.getSettingBool("check_for_updates")) + obj.setSettingInt("default_graph.xzoom", obj.getSettingInt("default_graph.xzoom")) + + def test_fetch_changelog(self, temporary, qtbot): + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + copy2("../../CHANGELOG.md", "../../LogarithmPlotter/util/CHANGELOG.md") + obj.fetchChangelog() + assert QThreadPool.globalInstance().activeThreadCount() == 0 + qtbot.waitSignal(obj.changelogFetched, timeout=10000) + remove("../../LogarithmPlotter/util/CHANGELOG.md") + obj.fetchChangelog() + assert QThreadPool.globalInstance().activeThreadCount() > 0 + qtbot.waitSignal(obj.changelogFetched, timeout=10000) \ No newline at end of file diff --git a/tests/python/test_native.py b/tests/python/test_native.py index edaf88e..6fc2d65 100644 --- a/tests/python/test_native.py +++ b/tests/python/test_native.py @@ -36,7 +36,7 @@ class MockIO: class MockFileOpenEvent(QEvent): def __init__(self, file): - super(QEvent.FileOpen) + QEvent.__init__(self, QEvent.FileOpen) self._file = file def file(self): diff --git a/tests/python/test_update.py b/tests/python/test_update.py index 385d12a..9f65597 100644 --- a/tests/python/test_update.py +++ b/tests/python/test_update.py @@ -33,7 +33,7 @@ def check_update_callback_type(show_alert, msg_text, update_available): assert type(msg_text) == str assert type(update_available) == bool -def test_update(): +def test_update(qtbot): def check_older(show_alert, msg_text, update_available): check_update_callback_type(show_alert, msg_text, update_available) assert update_available @@ -50,14 +50,18 @@ def test_update(): update_info_newer.got_update_info.connect(check_newer) runnable = UpdateCheckerRunnable('1.0.0', update_info_newer) runnable.run() + qtbot.waitSignal(update_info_newer.got_update_info, timeout=10000) runnable = UpdateCheckerRunnable('0.1.0', update_info_older) runnable.run() + qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) runnable = UpdateCheckerRunnable('0.5.0+dev0+git20240101', update_info_older) runnable.run() + qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) -def test_update_checker(): - check_for_updates('0.6.0', MockWindow()) +def test_update_checker(qtbot): + update_info = check_for_updates('0.6.0', MockWindow()) assert QThreadPool.globalInstance().activeThreadCount() == 1 + qtbot.waitSignal(update_info.got_update_info, timeout=10000) argv.append("--no-check-for-updates") - check_for_updates('0.6.0', MockWindow()) + update_info = check_for_updates('0.6.0', MockWindow()) assert QThreadPool.globalInstance().activeThreadCount() < 2 # No new update checks where added From 9810435456d01d83848a352760038505bf921ba5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 18:18:56 +0200 Subject: [PATCH 123/249] Updating usages --- LogarithmPlotter/i18n/lp_de.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_en.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_es.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_fr.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_hu.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_nb_NO.ts | 142 +++++++++--------- LogarithmPlotter/i18n/lp_template.ts | 142 +++++++++--------- .../LogarithmPlotter/js/module/expreval.mjs | 10 +- 8 files changed, 514 insertions(+), 490 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 1b73dd9..cf2597e 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -824,24 +824,24 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodemagnitude - + Bode Magnitude Bode-Magnitude - + Bode Magnitudes Bode-Magnituden - - + + low-pass Tiefpass - - + + high-pass Hochpass @@ -880,12 +880,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -1251,17 +1251,17 @@ Ausdruck analysiert: %3 general - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + Enable LaTeX rendering LaTeX-Rendering aktivieren @@ -1308,32 +1308,32 @@ Ausdruck analysiert: %3 Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. @@ -1416,114 +1416,114 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - + above ↑ Über - + below ↓ Unter - - + + left ← Links - - + + right → Rechts - + above-left ↖ Oben links - + above-right ↗ Oben rechts - + below-left ↙ Unten links - + below-right ↘ Unten rechts - + center >|< Zentrum - + top ↑ Über - + bottom ↓ Unter - + top-left ↖ Oben links - + top-right ↗ Oben rechts - + bottom-left ↙ Unten links - + bottom-right ↘ Unten rechts - + application Anwendung - + function Funktion - + high Hoch - + low Tief - + Next to target Neben dem Ziel - + With label Mit Etikett - + Hidden Versteckt @@ -1583,7 +1583,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Reichweite - + @@ -1602,7 +1602,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Anzeigemodus - + @@ -1625,23 +1625,23 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Gestrichelte Linien anzeigen - + om_0 ω₀ - + pass Pass - + gain Größenordnung - + omGraduation Teilung auf ω zeigen @@ -1755,17 +1755,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory - + default Standardeinstellungen - + general Allgemeine - + editor Ausdruckseditor @@ -1823,37 +1823,41 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - - - Usage: %1 - Verwendung: %1 - - - - - - Usage: %1 or -%2 - Verwendung: %1 oder -%2 - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + + + Usage: +%1 + Verwendung: +%1 + + + + + + Usage: +%1 +%2 + Verwendung: +%1 +%2 + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index fe1d018..c7fd439 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -824,24 +824,24 @@ These settings can be changed at any time from the "Settings" menu. bodemagnitude - + Bode Magnitude Bode Magnitude - + Bode Magnitudes Bode Magnitudes - - + + low-pass low-pass - - + + high-pass high-pass @@ -880,12 +880,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -1251,17 +1251,17 @@ Evaluated expression: %3 general - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + Enable LaTeX rendering Enable LaTeX rendering @@ -1308,32 +1308,32 @@ Evaluated expression: %3 History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. @@ -1416,114 +1416,114 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - + above ↑ Above - + below ↓ Below - - + + left ← Left - - + + right → Right - + above-left ↖ Above left - + above-right ↗ Above right - + below-left ↙ Below left - + below-right ↘ Below right - + center >|< Center - + top ↑ Top - + bottom ↓ Bottom - + top-left ↖ Top left - + top-right ↗ Top right - + bottom-left ↙ Bottom left - + bottom-right ↘ Bottom right - + application Application - + function Function - + high High - + low Low - + Next to target Next to target - + With label With label - + Hidden Hidden @@ -1583,7 +1583,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.Range - + @@ -1602,7 +1602,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.Display mode - + @@ -1625,23 +1625,23 @@ Please make sure your LaTeX installation is correct and report a bug if so.Show dashed lines - + om_0 ω₀ - + pass Pass - + gain Magnitude gain - + omGraduation Show graduation on ω₀ @@ -1755,17 +1755,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory - + general General - + editor Expression Editor - + default Default settings @@ -1823,37 +1823,41 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - - - Usage: %1 - Usage: %1 - - - - - - Usage: %1 or -%2 - Usage: %1 or -%2 - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + + + Usage: +%1 + Usage: +%1 + + + + + + Usage: +%1 +%2 + Usage: +%1 +%2 + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 2df288e..04db0ae 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -824,24 +824,24 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes bodemagnitude - + Bode Magnitude Magnitud de Bode - + Bode Magnitudes Magnitudes de Bode - - + + low-pass Filtro paso bajo - - + + high-pass Filtro paso alto @@ -880,12 +880,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes changelog - + Could not fetch changelog: Server error {}. No se ha podido recuperar el registro de cambios: Error del servidor {}. - + Could not fetch update: {}. No se pudo obtener el registro de cambios: {}. @@ -1251,17 +1251,17 @@ Expresión evaluada: %3 general - + Check for updates on startup Comprobación de las actualizaciones al arrancar - + Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - + Enable LaTeX rendering Activar el renderizado de LaTeX @@ -1320,32 +1320,32 @@ Expresión evaluada: %3 Objetos - + Saved plot to '%1'. Gráfico guardado en '%1'. - + Loading file '%1'. Cargando el archivo '%1'. - + Unknown object type: %1. Tipo de objeto desconocido: %1 . - + Invalid file provided. Se ha proporcionado un archivo no válido. - + Could not save file: No se ha podido guardar el archivo: - + Loaded file '%1'. Archivo cargado '%1'. @@ -1416,114 +1416,114 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u parameters - + below ↓ Abajo - - + + left ← Izquierda - + above-left ↖ Arriba a la izquierda - + below-left ↙ Abajo a la izquierda - + below-right ↘ Arriba a la derecha - + center >|< Centro - + top ↑ Arriba - + above ↑ Arriba - - + + right → Derecha - + above-right ↗ Arriba a la derecha - + bottom ↓ Bajar - + top-right ↗ Arriba a la derecha - + application Aplicación - + Next to target Próximo al objetivo - + top-left ↖ Arriba a la izquierda - + bottom-left ↙ Abajo a la izquierda - + bottom-right ↘ Abajo a la derecha - + function Función - + high Alto - + low Bajo - + With label Con etiqueta - + Hidden Oculto @@ -1578,7 +1578,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Dominio - + om_0 ω₀ @@ -1594,7 +1594,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Redondeo - + @@ -1622,7 +1622,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Rango - + @@ -1641,12 +1641,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Modo de visualización - + pass Pasar - + gain Incremento de magnitud @@ -1662,7 +1662,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Y - + omGraduation Mostrar la graduación en ω₀ @@ -1755,17 +1755,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u settingCategory - + general General - + editor Editor de expresiones - + default Ajustes por defecto @@ -1823,37 +1823,41 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u usage - - - Usage: %1 - Uso: %1 - - - - - - Usage: %1 or -%2 - Uso: %1 o -%2 - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) - + + + Usage: +%1 + Uso: +%1 + + + + + + Usage: +%1 +%2 + Uso: +%1 +%2 + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivada(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivada(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 35d38c4..4b07050 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -826,24 +826,24 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P bodemagnitude - + Bode Magnitude Gain de Bode - + Bode Magnitudes Gains de Bode - - + + low-pass passe-bas - - + + high-pass passe-haut @@ -882,12 +882,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -1254,17 +1254,17 @@ Formule analysée : %3 general - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Réinitialiser la pile d'action "Rétablir" automatiquement - + Enable LaTeX rendering Activer le rendu LaTeX @@ -1323,32 +1323,32 @@ Formule analysée : %3 &Mettre à jour LogarithmPlotter - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. @@ -1419,114 +1419,114 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - + above ↑ Au dessus - + below ↓ En dessous - - + + left ← À gauche - - + + right → À droite - + above-left ↖ Au dessus à gauche - + above-right ↗ Au dessus à droite - + below-left ↙ En dessous à gauche - + below-right ↘ En dessous à droite - + center >|< Centré - + top ↑ Au dessus - + bottom ↓ En dessous - + top-left ↖ Au dessus à gauche - + top-right ↗ Au dessus à droite - + bottom-left ↙ En dessous à gauche - + bottom-right ↘ En dessous à droite - + application Application - + function Fonction - + high Haut - + low Bas - + Next to target A côté de la cible - + With label Avec l'étiquette - + Hidden Caché @@ -1586,7 +1586,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Portée - + @@ -1605,7 +1605,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Mode d'affichage - + @@ -1628,23 +1628,23 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Afficher les pointillés - + om_0 ω₀ - + pass Passe - + gain Gain - + omGraduation Afficher la graduation sur ω₀ @@ -1758,17 +1758,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c settingCategory - + general Général - + editor Éditeur de formule - + default Paramètres par défaut @@ -1826,37 +1826,41 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - - - Usage: %1 - Emploi : %1 - - - - - - Usage: %1 or -%2 - Emploi : %1 ou -%2 - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + + + Usage: +%1 + Emploi : +%1 + + + + + + Usage: +%1 +%2 + Emploi : +%1 +%2 + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index c0b4924..2536de6 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -824,24 +824,24 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. bodemagnitude - + Bode Magnitude Bode-nagyságrend - + Bode Magnitudes Bode-nagyságrendek - - + + low-pass aluláteresztő - - + + high-pass felüláteresztő @@ -880,12 +880,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -1251,17 +1251,17 @@ Kiértékelt kifejezés: %3 general - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése @@ -1304,32 +1304,32 @@ Kiértékelt kifejezés: %3 Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. @@ -1412,114 +1412,114 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - + above ↑ Felett - + below ↓ Alatt - - + + left ← Balra - - + + right → Jobbra - + above-left ↖ Felett, balra - + above-right ↗ Felett, jobbra - + below-left ↙ Alatt, balra - + below-right ↘ Alatt, jobbra - + center >|< Középre - + top ↑ Felső - + bottom ↓ Alsó - + top-left ↖ Bal felső - + top-right ↗ Jobb felső - + bottom-left ↙ Bal alsó - + bottom-right ↘ Jobb alsó - + application Alkalmazás - + function Függvény - + high Magas - + low Alul - + Next to target Cél mellé - + With label Címkével - + Hidden Rejtett @@ -1579,7 +1579,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Ordináta tartomány - + @@ -1598,7 +1598,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Megjelenítési mód - + @@ -1621,23 +1621,23 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Szaggatott vonalak megjelenítése - + om_0 ω₀ - + pass Áteresztő - + gain Nagyságrend nyeresége - + omGraduation ω₀ érettségi megjelenítése @@ -1751,17 +1751,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory - + general - + editor Kifejezésszerkesztő - + default Alapértelmezett ábra @@ -1819,37 +1819,41 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - - - Usage: %1 - Használat: %1 - - - - - - Usage: %1 or -%2 - Használat: %1 vagy -%2 - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + + + Usage: +%1 + Használat: +%1 + + + + + + Usage: +%1 +%2 + Használat: +%1 +%2 + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 904af86..5e94d77 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -776,24 +776,24 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodemagnitude - + Bode Magnitude Bode-magnitude - + Bode Magnitudes Bode-magnituder - - + + low-pass lavpass - - + + high-pass høypass @@ -832,12 +832,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -1182,17 +1182,17 @@ Evaluated expression: %3 general - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - + Enable LaTeX rendering @@ -1235,32 +1235,32 @@ Evaluated expression: %3 Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». @@ -1330,114 +1330,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - - - below - - - - left + below - right + left - above-left + + right - above-right + above-left - below-left + above-right + below-left + + + + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden @@ -1502,7 +1502,7 @@ Please make sure your latex installation is correct and report a bug if so. - + @@ -1516,7 +1516,7 @@ Please make sure your latex installation is correct and report a bug if so. - + @@ -1539,23 +1539,23 @@ Please make sure your latex installation is correct and report a bug if so. - + om_0 - + pass - + gain - + omGraduation @@ -1665,17 +1665,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1733,36 +1733,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - - Usage: %1 - - - - - - - Usage: %1 or -%2 - - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + + + Usage: +%1 + + + + + + + Usage: +%1 +%2 + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 511c6c2..7626f7b 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -664,24 +664,24 @@ bodemagnitude - + Bode Magnitude - + Bode Magnitudes - - + + low-pass - - + + high-pass @@ -720,12 +720,12 @@ changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -1051,17 +1051,17 @@ Evaluated expression: %3 general - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering @@ -1069,32 +1069,32 @@ Evaluated expression: %3 io - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. @@ -1152,114 +1152,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - - - below - - - - left + below - right + left - above-left + + right - above-right + above-left - below-left + above-right + below-left + + + + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden @@ -1313,7 +1313,7 @@ Please make sure your latex installation is correct and report a bug if so. - + @@ -1327,7 +1327,7 @@ Please make sure your latex installation is correct and report a bug if so. - + @@ -1350,23 +1350,23 @@ Please make sure your latex installation is correct and report a bug if so. - + om_0 - + pass - + gain - + omGraduation @@ -1465,17 +1465,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1519,36 +1519,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - - Usage: %1 - - - - - - - Usage: %1 or -%2 - - - - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + + + Usage: +%1 + + + + + + + Usage: +%1 +%2 + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index 9ad06d5..f936541 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -63,17 +63,17 @@ export class ExprParserAPI extends Module { // Parse object f = args[0] if(typeof f !== "object" || !f.execute) - throw EvalError(qsTranslate("usage", "Usage: %1").arg(usage1)) + throw EvalError(qsTranslate("usage", "Usage:\n%1").arg(usage1)) let target = f f = (x) => target.execute(x) } else if(args.length === 2) { // Parse variable [f, variable] = args if(typeof f !== "string" || typeof variable !== "string") - throw EvalError(qsTranslate("usage", "Usage: %1").arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage:\n%1").arg(usage2)) f = this._parser.parse(f).toJSFunction(variable, this.currentVars) } else - throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) return f } @@ -89,7 +89,7 @@ export class ExprParserAPI extends Module { let usage2 = qsTranslate("usage", "integral(, , , )") let f = this.parseArgumentsForFunction(args, usage1, usage2) if(a == null || b == null) - throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) // https://en.wikipedia.org/wiki/Simpson%27s_rule // Simpler, faster than tokenizing the expression @@ -102,7 +102,7 @@ export class ExprParserAPI extends Module { let x = args.pop() let f = this.parseArgumentsForFunction(args, usage1, usage2) if(x == null) - throw EvalError(qsTranslate("usage", "Usage: %1 or\n%2").arg(usage1).arg(usage2)) + throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) let derivative_precision = x / 10 return (f(x + derivative_precision / 2) - f(x - derivative_precision / 2)) / derivative_precision From 3befff41fa6180e21856e0d7b8896746f351601b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 15:44:49 +0000 Subject: [PATCH 124/249] Translated using Weblate (English) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index fe1d018..bff47ee 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1840,7 +1840,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<from: number>, <to: number>, <f: ExecutableObject>) + integral(<from: number>, <to: number>, <f: Function-like object>) @@ -1850,7 +1850,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. derivative(<f: ExecutableObject>, <x: number>) - derivative(<f: ExecutableObject>, <x: number>) + derivative(<f: Function-like object>, <x: number>) From 8b8a280b376bdc4b1393c918ddf2139f4faf0376 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 16:08:22 +0000 Subject: [PATCH 125/249] Translated using Weblate (German) Currently translated at 99.6% (268 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 1b73dd9..7858e3a 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1840,7 +1840,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) + integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) @@ -1850,7 +1850,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde derivative(<f: ExecutableObject>, <x: number>) - derivative(<f: ExecutableObject>, <x: Zahl>) + derivative(<f: Funktionsähnliches Objekt>, <x: Zahl>) From a998c52eecfd94919ce993e8eb1d56dcea8f150c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 16:07:44 +0000 Subject: [PATCH 126/249] Translated using Weblate (Spanish) Currently translated at 98.8% (266 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 2df288e..055e74f 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1840,17 +1840,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) + integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - integral(<from: number>, <to: number>, <f: string>, <variable: string>) + derivative(<f: ExecutableObject>, <x: number>) - derivada(<f: ExecutableObject>, <x: number>) + derivada(<f: ExecutableObject>, <x: number>) From a27d3109edc61ddda7fab88b3ff575e2b5fa968c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 16:05:45 +0000 Subject: [PATCH 127/249] Translated using Weblate (French) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 35d38c4..f719da6 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1843,7 +1843,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) + integral(<de : nombre>, <à : nombre>, <f : Objet fonction>) @@ -1853,7 +1853,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c derivative(<f: ExecutableObject>, <x: number>) - derivative(<f : Objet exécutable>, <x : nombre>) + derivative(<f : Objet fonction>, <x : nombre>) From cb2ffcf77a2bd62581afc1212d4cd5b76052466b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 15:34:43 +0000 Subject: [PATCH 128/249] Translated using Weblate (Hungarian) Currently translated at 94.7% (255 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index c0b4924..266ad0b 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1836,17 +1836,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents integral(<from: number>, <to: number>, <f: ExecutableObject>) - integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) + integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) + integral(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) derivative(<f: ExecutableObject>, <x: number>) - derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) + derivative(<függvény: VégrehajthatóObjektum>, <x: szám>) From bac802ec5b9178833226d7ccb39dacc0852ab98c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 18:23:45 +0200 Subject: [PATCH 129/249] Using translated property name in usage error messages. --- .../ObjectLists/Editor/CustomPropertyList.qml | 4 +++- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 8f36f66..17ffed9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -145,7 +145,9 @@ Repeater { title: qsTranslate("expression", "LogarithmPlotter - Parsing error") text: "" function showDialog(propName, propValue, error) { - text = qsTranslate("error", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + text = qsTranslate("error", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3") + .arg(qsTranslate('prop', propName)) + .arg(error).arg(propValue) open() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index aa91018..e19fd9d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -202,7 +202,9 @@ Item { title: qsTranslate("expression", "LogarithmPlotter - Parsing error") text: "" function showDialog(propName, propValue, error) { - text = qsTranslate("expression", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + text = qsTranslate("expression", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3") + .arg(qsTranslate('prop', propName)) + .arg(error).arg(propValue) open() } } From 45dff33bb5c3c8cb134d51f1de7e144ed8345b63 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 18:32:11 +0200 Subject: [PATCH 130/249] Moving mathlib and historylib into math/index and history/index --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../ad5001/LogarithmPlotter/History/History.qml | 14 +++++++------- .../ad5001/LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 4 ++-- .../ObjectLists/Editor/Dialog.qml | 4 ++-- .../ObjectLists/ObjectCreationGrid.qml | 2 +- .../LogarithmPlotter/ObjectLists/ObjectRow.qml | 2 +- .../LogarithmPlotter/PickLocationOverlay.qml | 4 ++-- .../Setting/ExpressionEditor.qml | 2 +- .../ViewPositionChangeOverlay.qml | 4 ++-- .../LogarithmPlotter/js/history/editproperty.mjs | 2 +- .../js/{historylib.mjs => history/index.mjs} | 16 ++++++++-------- .../LogarithmPlotter/js/history/position.mjs | 2 +- .../js/{mathlib.mjs => math/index.mjs} | 6 +++--- .../ad5001/LogarithmPlotter/js/module/canvas.mjs | 2 +- .../LogarithmPlotter/js/objs/bodemagnitude.mjs | 4 ++-- .../js/objs/bodemagnitudesum.mjs | 2 +- .../LogarithmPlotter/js/objs/bodephase.mjs | 4 ++-- .../LogarithmPlotter/js/objs/bodephasesum.mjs | 2 +- .../ad5001/LogarithmPlotter/js/objs/function.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/js/objs/point.mjs | 2 +- .../ad5001/LogarithmPlotter/js/objs/sequence.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/js/objs/text.mjs | 2 +- .../ad5001/LogarithmPlotter/js/objs/xcursor.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/js/parameters.mjs | 2 +- .../LogarithmPlotter/js/preferences/common.mjs | 2 +- 26 files changed, 47 insertions(+), 47 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{historylib.mjs => history/index.mjs} (83%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{mathlib.mjs => math/index.mjs} (91%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 59c7973..d0c2621 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -20,7 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import "js/historylib.mjs" as HistoryLib +import "js/history/index.mjs" as HistoryLib /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index afc7281..e1e527d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -19,14 +19,14 @@ import QtQuick import QtQml import QtQuick.Window -import "../js/historylib.mjs" as HistoryLib +import "../js/history/index.mjs" as HistoryLib /*! \qmltype History \inqmlmodule eu.ad5001.LogarithmPlotter.History \brief QObject holding persistantly for undo & redo stacks. - \sa HistoryBrowser, historylib + \sa HistoryBrowser, HistoryLib */ Item { // Using a QtObject is necessary in order to have proper property propagation in QML @@ -107,7 +107,7 @@ Item { /*! \qmlmethod void History::addToHistory(var action) - Adds an instance of historylib.Action to history. + Adds an instance of HistoryLib.Action to history. */ function addToHistory(action) { if(action instanceof HistoryLib.Action) { @@ -124,7 +124,7 @@ Item { /*! \qmlmethod void History::undo(bool updateObjectList = true) - Undoes the historylib.Action at the top of the undo stack and pushes it to the top of the redo stack. + Undoes the HistoryLib.Action at the top of the undo stack and pushes it to the top of the redo stack. By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ function undo(updateObjectList = true) { @@ -142,7 +142,7 @@ Item { /*! \qmlmethod void History::redo(bool updateObjectList = true) - Redoes the historylib.Action at the top of the redo stack and pushes it to the top of the undo stack. + Redoes the HistoryLib.Action at the top of the redo stack and pushes it to the top of the undo stack. By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ function redo(updateObjectList = true) { @@ -160,7 +160,7 @@ Item { /*! \qmlmethod void History::undoMultipleDefered(int toUndoCount) - Undoes several historylib.Action at the top of the undo stack and pushes them to the top of the redo stack. + Undoes several HistoryLib.Action at the top of the undo stack and pushes them to the top of the redo stack. It undoes them deferedly to avoid overwhelming the computer while creating a cool short accelerated summary of all changes. */ function undoMultipleDefered(toUndoCount) { @@ -173,7 +173,7 @@ Item { /*! \qmlmethod void History::redoMultipleDefered(int toRedoCount) - Redoes several historylib.Action at the top of the redo stack and pushes them to the top of the undo stack. + Redoes several HistoryLib.Action at the top of the redo stack and pushes them to the top of the undo stack. It redoes them deferedly to avoid overwhelming the computer while creating a cool short accelerated summary of all changes. */ function redoMultipleDefered(toRedoCount) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index c2d9f60..4159497 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -19,7 +19,7 @@ import QtQuick import Qt.labs.platform as Native import "js/utils.mjs" as Utils -import "js/mathlib.mjs" as MathLib +import "js/math/index.mjs" as MathLib /*! \qmltype LogGraphCanvas diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 17ffed9..361dcbf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -20,9 +20,9 @@ import QtQuick import QtQuick.Controls import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../../js/historylib.mjs" as HistoryLib +import "../../js/history/index.mjs" as HistoryLib import "../../js/utils.mjs" as Utils -import "../../js/mathlib.mjs" as MathLib +import "../../js/math/index.mjs" as MathLib /*! \qmltype CustomPropertyList diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 6f650ef..7a357b3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -22,9 +22,9 @@ import QtQuick.Dialogs as D import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "../../js/historylib.mjs" as HistoryLib +import "../../js/history/index.mjs" as HistoryLib import "../../js/utils.mjs" as Utils -import "../../js/mathlib.mjs" as MathLib +import "../../js/math/index.mjs" as MathLib /*! \qmltype Dialog diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 3e621b0..3d0a56a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -18,7 +18,7 @@ import QtQuick import QtQuick.Controls -import "../js/historylib.mjs" as HistoryLib +import "../js/history/index.mjs" as HistoryLib import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index f846490..2dcd5c0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -21,7 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/historylib.mjs" as HistoryLib +import "../js/history/index.mjs" as HistoryLib /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 0139c5b..cecdf13 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -19,8 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/mathlib.mjs" as MathLib -import "js/historylib.mjs" as HistoryLib +import "js/math/index.mjs" as MathLib +import "js/history/index.mjs" as HistoryLib /*! \qmltype PickLocationOverlay diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index e19fd9d..6a17423 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -20,7 +20,7 @@ import QtQuick.Controls import QtQuick import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P -import "../js/mathlib.mjs" as MathLib +import "../js/math/index.mjs" as MathLib import "../js/utils.mjs" as Utils import "../js/parsing/parsing.mjs" as Parsing diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 6ba180e..b06fbcf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -19,8 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/mathlib.mjs" as MathLib -import "js/historylib.mjs" as HistoryLib +import "js/math/index.mjs" as MathLib +import "js/history/index.mjs" as HistoryLib /*! \qmltype ViewPositionChangeOverlay diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index febed9a..de84449 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -18,7 +18,7 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import * as MathLib from "../mathlib.mjs" +import * as MathLib from "../math/index.mjs" import { Action } from "common.mjs" import { DrawableObject } from "../objs/common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs similarity index 83% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs index 189d59b..aa57307 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs @@ -19,14 +19,14 @@ // This library helps containing actions to be undone or redone (in other words, editing history) // Each type of event is repertoried as an action that can be listed for everything that's undoable. -import { Action as A } from "history/common.mjs" -import Create from "history/create.mjs" -import Delete from "history/delete.mjs" -import EP from "history/editproperty.mjs" -import Pos from "history/position.mjs" -import V from "history/visibility.mjs" -import Name from "history/name.mjs" -import Color from "history/color.mjs" +import { Action as A } from "./common.mjs" +import Create from "./create.mjs" +import Delete from "./delete.mjs" +import EP from "./editproperty.mjs" +import Pos from "./position.mjs" +import V from "./visibility.mjs" +import Name from "./name.mjs" +import Color from "./color.mjs" export const Action = A diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index 14b5bac..c568615 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -18,7 +18,7 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import * as MathLib from "../mathlib.mjs" +import * as MathLib from "../math/index.mjs" import { escapeHTML } from "../utils.mjs" import { Action } from "common.mjs" import { DrawableObject } from "../objs/common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs similarity index 91% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs index 88f9c1e..27be49e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs @@ -17,9 +17,9 @@ */ -import * as Expr from "math/expression.mjs" -import * as Seq from "math/sequence.mjs" -import * as Dom from "math/domain.mjs" +import * as Expr from "./expression.mjs" +import * as Seq from "./sequence.mjs" +import * as Dom from "./domain.mjs" export const Expression = Expr.Expression diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs index cd86c6e..020ff88 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs @@ -18,7 +18,7 @@ import { Module } from "./common.mjs" import { textsup } from "../utils.mjs" -import { Expression } from "../mathlib.mjs" +import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index 05e1150..7ca294d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { parseDomain, executeExpression, Expression, EmptySet, Domain } from "../mathlib.mjs" -import { CreateNewObject } from "../historylib.mjs" +import { parseDomain, executeExpression, Expression, EmptySet, Domain } from "../math/index.mjs" +import { CreateNewObject } from "../history/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index 4531bee..7d5c3e4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Range, Expression, Domain } from "../mathlib.mjs" +import { Range, Expression, Domain } from "../math/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index cce63fa..3cafd52 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { executeExpression, Expression } from "../mathlib.mjs" -import { CreateNewObject } from "../historylib.mjs" +import { executeExpression, Expression } from "../math/index.mjs" +import { CreateNewObject } from "../history/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import History from "../module/history.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index d55a29c..cee3235 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { executeExpression, Expression } from "../mathlib.mjs" +import { executeExpression, Expression } from "../math/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 31afc37..752aa52 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -19,7 +19,7 @@ import { textsub } from "../utils.mjs" import Objects from "../module/objects.mjs" import { ExecutableObject } from "common.mjs" -import { parseDomain, Expression, SpecialDomain } from "../mathlib.mjs" +import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs" import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 7264894..33d3858 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Expression } from "../mathlib.mjs" +import { Expression } from "../math/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 5d431af..0d2c488 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Sequence as MathSequence, Domain } from "../mathlib.mjs" +import { Sequence as MathSequence, Domain } from "../math/index.mjs" import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index a819d7a..bd30dfe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Expression } from "../mathlib.mjs" +import { Expression } from "../math/index.mjs" import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 63c85d3..20dc548 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Expression } from "../mathlib.mjs" +import { Expression } from "../math/index.mjs" import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 6cd9e04..b301997 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import {parseDomain, Expression as Expr, Domain} from "./mathlib.mjs" +import {parseDomain, Expression as Expr, Domain} from "./math/index.mjs" import Objects from "./module/objects.mjs" const NONE = class Empty {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs index 4503113..37c7577 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {Expression} from "../mathlib.mjs" +import {Expression} from "../math/index.mjs" class Setting { constructor(type, name, nameInConfig, icon) { From 8c8964e75e6de52e99358933b11f40ba716f2812 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 18:37:57 +0200 Subject: [PATCH 131/249] Renaming internal ExprEval Expression class to ExprEvalExpression --- .../js/lib/expr-eval/expression.mjs | 20 +++++++++---------- .../js/lib/expr-eval/parser.mjs | 4 ++-- .../LogarithmPlotter/js/math/expression.mjs | 6 +++++- .../LogarithmPlotter/js/module/expreval.mjs | 1 + .../js/preferences/common.mjs | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs index d7aba35..57b4e0e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs @@ -146,7 +146,7 @@ function substitute(tokens, variable, expr) { /** * Evaluates the given instructions for a given Expression with given values. * @param {Instruction[]} tokens - * @param {Expression} expr + * @param {ExprEvalExpression} expr * @param {Record.} values * @return {number} */ @@ -442,7 +442,7 @@ function getSymbols(tokens, symbols, options) { } } -export class Expression { +export class ExprEvalExpression { /** * @param {Instruction[]} tokens * @param {Parser} parser @@ -458,26 +458,26 @@ export class Expression { /** * Simplifies the expression. - * @param {Object|undefined} values - * @returns {Expression} + * @param {Object|undefined} values + * @returns {ExprEvalExpression} */ simplify(values) { values = values || {} - return new Expression(simplify(this.tokens, this.unaryOps, this.binaryOps, this.ternaryOps, values), this.parser) + return new ExprEvalExpression(simplify(this.tokens, this.unaryOps, this.binaryOps, this.ternaryOps, values), this.parser) } /** * Creates a new expression where the variable is substituted by the given expression. * @param {string} variable - * @param {string|Expression} expr - * @returns {Expression} + * @param {string|ExprEvalExpression} expr + * @returns {ExprEvalExpression} */ substitute(variable, expr) { - if(!(expr instanceof Expression)) { + if(!(expr instanceof ExprEvalExpression)) { expr = this.parser.parse(String(expr)) } - return new Expression(substitute(this.tokens, variable, expr), this.parser) + return new ExprEvalExpression(substitute(this.tokens, variable, expr), this.parser) } /** @@ -527,7 +527,7 @@ export class Expression { /** * Converts the expression to a JS function. * @param {string} param - Parsed variables for the function. - * @param {Object.} variables - Default variables to provide. + * @param {Object.} variables - Default variables to provide. * @returns {function(...any)} */ toJSFunction(param, variables) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs index 3336fcf..71a1c95 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs @@ -25,7 +25,7 @@ import * as Polyfill from "./polyfill.mjs" import { ParserState } from "./parserstate.mjs" import { TEOF, TokenStream } from "./tokens.mjs" -import { Expression } from "./expression.mjs" +import { ExprEvalExpression } from "./expression.mjs" const optionNameMap = { "+": "add", @@ -156,7 +156,7 @@ export class Parser { parserState.parseExpression(instr) parserState.expect(TEOF, QT_TRANSLATE_NOOP("error", "EOF")) - return new Expression(instr, this) + return new ExprEvalExpression(instr, this) } evaluate(expr, variables) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 8a7bf77..6505018 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -41,7 +41,11 @@ export class Expression { this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } - + + variables() { + return this.calc.variables() + } + isConstant() { let vars = this.calc.variables() return !vars.includes("x") && !vars.includes("n") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index f936541..5ac849e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -79,6 +79,7 @@ export class ExprParserAPI extends Module { /** * @param {string} expression - Expression to parse + * @returns {ExprEvalExpression} */ parse(expression) { return this._parser.parse(expression) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs index 37c7577..1e708ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -107,7 +107,7 @@ export class ExpressionSetting extends Setting { * @param {Expression} value */ set(value) { - let vars = value.calc.variables() + let vars = value.variables() if(vars.length === this.variables.length && vars.every(x => this.variables.includes(x))) Helper.setSetting(this.nameInConfig, value) else { From 4c1403c983104ece372c6a35b21051c44ea585f8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 23 Sep 2024 20:55:48 +0200 Subject: [PATCH 132/249] Implementing modules requiring interfaces --- .../LogarithmPlotter/History/History.qml | 9 +- .../LogarithmPlotter/LogGraphCanvas.qml | 8 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- .../LogarithmPlotter/js/module/canvas.mjs | 233 ++++++++++++------ .../LogarithmPlotter/js/module/common.mjs | 40 ++- .../LogarithmPlotter/js/module/expreval.mjs | 5 +- .../LogarithmPlotter/js/module/history.mjs | 70 ++++-- .../ad5001/LogarithmPlotter/js/module/io.mjs | 66 ++++- .../LogarithmPlotter/js/module/latex.mjs | 5 +- .../js/module/preferences.mjs | 5 +- 10 files changed, 312 insertions(+), 131 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index e1e527d..85abbc7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -212,8 +212,11 @@ Item { } Component.onCompleted: { - Modules.History.history = historyObj - Modules.History.themeTextColor = sysPalette.windowText - Modules.History.imageDepth = Screen.devicePixelRatio + Modules.History.initialize({ + historyObj, + themeTextColor: sysPalette.windowText.toString(), + imageDepth: Screen.devicePixelRatio, + fontSize: 14 + }) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 4159497..2d7eb08 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -120,12 +120,6 @@ Canvas { */ property bool showygrad: false - /*! - \qmlproperty int LogGraphCanvas::maxgradx - Max power of the logarithmic scaled on the x axis in logarithmic mode. - */ - property int maxgradx: 90 - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. @@ -139,7 +133,7 @@ Canvas { Component.onCompleted: { imageLoaders = {} - Modules.Canvas.initialize(canvas, drawingErrorDialog) + Modules.Canvas.initialize({ canvas, drawingErrorDialog }) } Native.MessageDialog { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index c94bef1..3c6e994 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -128,7 +128,7 @@ ScrollView { property string saveFilename: "" Component.onCompleted: { - Modules.IO.initialize(root, settings, alert) + Modules.IO.initialize({ root, settings, alert }) } Column { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs index 020ff88..75efb04 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs @@ -24,23 +24,53 @@ import Objects from "./objects.mjs" import History from "./history.mjs" +/** + * @typedef {Settings} Canvas + * @property {object} imageLoaders + * @property {function()} requestPaint + * @property {function(string)} getContext + * @property {function(rect)} markDirty + * @property {function(string)} loadImage + */ + class CanvasAPI extends Module { - constructor() { - super('Canvas', [ - Modules.Objects, - Modules.History - ]) + super("Canvas", { + canvas: { + width: "number", + height: "number", + xmin: "number", + ymax: "number", + xzoom: "number", + yzoom: "number", + xaxisstep: "number", + yaxisstep: "number", + xlabel: "string", + ylabel: "string", + linewidth: "number", + textsize: "number", + logscalex: "boolean", + showxgrad: "boolean", + showygrad: "boolean", + imageLoaders: "object", + getContext: Function, + markDirty: Function, + loadImage: Function, + requestPaint: Function, + }, + drawingErrorDialog: { + showDialog: Function, + } + }) - /** @type {HTMLCanvasElement} */ + /** @type {Canvas} */ this._canvas = null /** @type {CanvasRenderingContext2D} */ this._ctx = null /** - * @type {Object} - * @property {function(string, string, string)} showDialog + * @type {{showDialog(string, string, string)}} * @private */ this._drawingErrorDialog = null @@ -62,86 +92,132 @@ class CanvasAPI extends Module { } } - initialize(canvasObject, drawingErrorDialog) { - this._canvas = canvasObject + /** + * Initialize the module. + * @param {Canvas} canvas + * @param {{showDialog(string, string, string)}} drawingErrorDialog + */ + initialize({ canvas, drawingErrorDialog }) { + super.initialize({ canvas, drawingErrorDialog }) + this._canvas = canvas this._drawingErrorDialog = drawingErrorDialog } - get width() { return this._canvas.width } + get width() { + if(!this.initialized) throw new Error("Attempting width before initialize!") + return this._canvas.width + } - get height() { return this._canvas.height } + get height() { + if(!this.initialized) throw new Error("Attempting height before initialize!") + return this._canvas.height + } /** * Minimum x of the diagram, provided from settings. * @returns {number} */ - get xmin() { return this._canvas.xmin } + get xmin() { + if(!this.initialized) throw new Error("Attempting xmin before initialize!") + return this._canvas.xmin + } /** * Zoom on the x-axis of the diagram, provided from settings. * @returns {number} */ - get xzoom() { return this._canvas.xzoom } + get xzoom() { + if(!this.initialized) throw new Error("Attempting xzoom before initialize!") + return this._canvas.xzoom + } /** * Maximum y of the diagram, provided from settings. * @returns {number} */ - get ymax() { return this._canvas.ymax } + get ymax() { + if(!this.initialized) throw new Error("Attempting ymax before initialize!") + return this._canvas.ymax + } /** * Zoom on the y-axis of the diagram, provided from settings. * @returns {number} */ - get yzoom() { return this._canvas.yzoom } + get yzoom() { + if(!this.initialized) throw new Error("Attempting yzoom before initialize!") + return this._canvas.yzoom + } /** * Label used on the x-axis, provided from settings. * @returns {string} */ - get xlabel() { return this._canvas.xlabel } + get xlabel() { + if(!this.initialized) throw new Error("Attempting xlabel before initialize!") + return this._canvas.xlabel + } /** * Label used on the y-axis, provided from settings. * @returns {string} */ - get ylabel() { return this._canvas.ylabel } + get ylabel() { + if(!this.initialized) throw new Error("Attempting ylabel before initialize!") + return this._canvas.ylabel + } /** * Width of lines that will be drawn into the canvas, provided from settings. * @returns {number} */ - get linewidth() { return this._canvas.linewidth } + get linewidth() { + if(!this.initialized) throw new Error("Attempting linewidth before initialize!") + return this._canvas.linewidth + } /** * Font size of the text that will be drawn into the canvas, provided from settings. * @returns {number} */ - get textsize() { return this._canvas.textsize } + get textsize() { + if(!this.initialized) throw new Error("Attempting textsize before initialize!") + return this._canvas.textsize + } /** * True if the canvas should be in logarithmic mode, false otherwise. * @returns {boolean} */ - get logscalex() { return this._canvas.logscalex } + get logscalex() { + if(!this.initialized) throw new Error("Attempting logscalex before initialize!") + return this._canvas.logscalex + } /** * True if the x graduation should be shown, false otherwise. * @returns {boolean} */ - get showxgrad() { return this._canvas.showxgrad } + get showxgrad() { + if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") + return this._canvas.showxgrad + } /** * True if the y graduation should be shown, false otherwise. * @returns {boolean} */ - get showygrad() { return this._canvas.showygrad } + get showygrad() { + if(!this.initialized) throw new Error("Attempting showygrad before initialize!") + return this._canvas.showygrad + } /** * Max power of the logarithmic scaled on the x axis in logarithmic mode. * @returns {number} */ get maxgradx() { + if(!this.initialized) throw new Error("Attempting maxgradx before initialize!") return Math.min( 309, // 10e309 = Infinity (beyond this land be dragons) Math.max( @@ -156,6 +232,7 @@ class CanvasAPI extends Module { // requestPaint() { + if(!this.initialized) throw new Error("Attempting requestPaint before initialize!") this._canvas.requestPaint() } @@ -163,6 +240,7 @@ class CanvasAPI extends Module { * Redraws the entire canvas */ redraw() { + if(!this.initialized) throw new Error("Attempting redraw before initialize!") this._ctx = this._canvas.getContext("2d") this._computeAxes() this._reset() @@ -171,7 +249,7 @@ class CanvasAPI extends Module { this._drawLabels() this._ctx.lineWidth = this.linewidth for(let objType in Objects.currentObjects) { - for(let obj of Objects.currentObjects[objType]){ + for(let obj of Objects.currentObjects[objType]) { this._ctx.strokeStyle = obj.color this._ctx.fillStyle = obj.color if(obj.visible) @@ -202,12 +280,12 @@ class CanvasAPI extends Module { x: { expression: exprX, value: x1, - maxDraw: Math.ceil(Math.max(Math.abs(this.xmin), Math.abs(this.px2x(this.width)))/x1) + maxDraw: Math.ceil(Math.max(Math.abs(this.xmin), Math.abs(this.px2x(this.width))) / x1) }, y: { expression: exprY, value: y1, - maxDraw: Math.ceil(Math.max(Math.abs(this.ymax), Math.abs(this.px2y(this.height)))/y1) + maxDraw: Math.ceil(Math.max(Math.abs(this.ymax), Math.abs(this.px2y(this.height))) / y1) } } } @@ -216,14 +294,14 @@ class CanvasAPI extends Module { * Resets the canvas to a blank one with default setting. * @private */ - _reset(){ + _reset() { // Reset this._ctx.fillStyle = "#FFFFFF" this._ctx.strokeStyle = "#000000" this._ctx.font = `${this.textsize}px sans-serif` - this._ctx.fillRect(0,0,this.width,this.height) + this._ctx.fillRect(0, 0, this.width, this.height) } - + /** * Draws the grid. * @private @@ -233,18 +311,18 @@ class CanvasAPI extends Module { if(this.logscalex) { for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) { for(let xmulti = 1; xmulti < 10; xmulti++) { - this.drawXLine(Math.pow(10, xpow)*xmulti) + this.drawXLine(Math.pow(10, xpow) * xmulti) } } } else { - for(let x = 0; x < this.axesSteps.x.maxDraw; x+=1) { - this.drawXLine(x*this.axesSteps.x.value) - this.drawXLine(-x*this.axesSteps.x.value) + for(let x = 0; x < this.axesSteps.x.maxDraw; x += 1) { + this.drawXLine(x * this.axesSteps.x.value) + this.drawXLine(-x * this.axesSteps.x.value) } } - for(let y = 0; y < this.axesSteps.y.maxDraw; y+=1) { - this.drawYLine(y*this.axesSteps.y.value) - this.drawYLine(-y*this.axesSteps.y.value) + for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { + this.drawYLine(y * this.axesSteps.y.value) + this.drawYLine(-y * this.axesSteps.y.value) } } @@ -260,10 +338,10 @@ class CanvasAPI extends Module { let axisypx = this.x2px(axisypos) // X coordinate of Y axis let axisxpx = this.y2px(0) // Y coordinate of X axis // Drawing arrows - this.drawLine(axisypx, 0, axisypx-10, 10) - this.drawLine(axisypx, 0, axisypx+10, 10) - this.drawLine(this.width, axisxpx, this.width-10, axisxpx-10) - this.drawLine(this.width, axisxpx, this.width-10, axisxpx+10) + this.drawLine(axisypx, 0, axisypx - 10, 10) + this.drawLine(axisypx, 0, axisypx + 10, 10) + this.drawLine(this.width, axisxpx, this.width - 10, axisxpx - 10) + this.drawLine(this.width, axisxpx, this.width - 10, axisxpx + 10) } /** @@ -276,38 +354,38 @@ class CanvasAPI extends Module { // Labels this._ctx.fillStyle = "#000000" this._ctx.font = `${this.textsize}px sans-serif` - this._ctx.fillText(this.ylabel, axisypx+10, 24) + this._ctx.fillText(this.ylabel, axisypx + 10, 24) let textWidth = this._ctx.measureText(this.xlabel).width - this._ctx.fillText(this.xlabel, this.width-14-textWidth, axisxpx-5) + this._ctx.fillText(this.xlabel, this.width - 14 - textWidth, axisxpx - 5) // Axis graduation labels - this._ctx.font = `${this.textsize-4}px sans-serif` + this._ctx.font = `${this.textsize - 4}px sans-serif` - let txtMinus = this._ctx.measureText('-').width + let txtMinus = this._ctx.measureText("-").width if(this.showxgrad) { if(this.logscalex) { - for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow+=1) { - textWidth = this._ctx.measureText("10"+textsup(xpow)).width + for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow += 1) { + textWidth = this._ctx.measureText("10" + textsup(xpow)).width if(xpow !== 0) - this.drawVisibleText("10"+textsup(xpow), this.x2px(Math.pow(10,xpow))-textWidth/2, axisxpx+16+(6*(xpow===1))) + this.drawVisibleText("10" + textsup(xpow), this.x2px(Math.pow(10, xpow)) - textWidth / 2, axisxpx + 16 + (6 * (xpow === 1))) } } else { for(let x = 1; x < this.axesSteps.x.maxDraw; x += 1) { - let drawX = x*this.axesSteps.x.value - let txtX = this.axesSteps.x.expression.simplify(x).toString().replace(/^\((.+)\)$/, '$1') + let drawX = x * this.axesSteps.x.value + let txtX = this.axesSteps.x.expression.simplify(x).toString().replace(/^\((.+)\)$/, "$1") let textHeight = this.measureText(txtX).height - this.drawVisibleText(txtX, this.x2px(drawX)-4, axisxpx+this.textsize/2+textHeight) - this.drawVisibleText('-'+txtX, this.x2px(-drawX)-4, axisxpx+this.textsize/2+textHeight) + this.drawVisibleText(txtX, this.x2px(drawX) - 4, axisxpx + this.textsize / 2 + textHeight) + this.drawVisibleText("-" + txtX, this.x2px(-drawX) - 4, axisxpx + this.textsize / 2 + textHeight) } } } if(this.showygrad) { for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { - let drawY = y*this.axesSteps.y.value - let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, '$1') + let drawY = y * this.axesSteps.y.value + let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, "$1") textWidth = this._ctx.measureText(txtY).width - this.drawVisibleText(txtY, axisypx-6-textWidth, this.y2px(drawY)+4+(10*(y===0))) + this.drawVisibleText(txtY, axisypx - 6 - textWidth, this.y2px(drawY) + 4 + (10 * (y === 0))) if(y !== 0) - this.drawVisibleText('-'+txtY, axisypx-6-textWidth-txtMinus, this.y2px(-drawY)+4) + this.drawVisibleText("-" + txtY, axisypx - 6 - textWidth - txtMinus, this.y2px(-drawY) + 4) } } this._ctx.fillStyle = "#FFFFFF" @@ -348,7 +426,7 @@ class CanvasAPI extends Module { drawVisibleText(text, x, y) { if(x > 0 && x < this.width && y > 0 && y < this.height) { text.toString().split("\n").forEach((txt, i) => { - this._ctx.fillText(txt, x, y+(this.textsize*i)) + this._ctx.fillText(txt, x, y + (this.textsize * i)) }) } } @@ -363,7 +441,7 @@ class CanvasAPI extends Module { * @param {number} height */ drawVisibleImage(image, x, y, width, height) { - this._canvas.markDirty(Qt.rect(x, y, width, height)); + this._canvas.markDirty(Qt.rect(x, y, width, height)) this._ctx.drawImage(image, x, y, width, height) } @@ -380,7 +458,7 @@ class CanvasAPI extends Module { theight += defaultHeight if(this._ctx.measureText(txt).width > twidth) twidth = this._ctx.measureText(txt).width } - return {'width': twidth, 'height': theight} + return { "width": twidth, "height": theight } } /** @@ -392,9 +470,9 @@ class CanvasAPI extends Module { x2px(x) { if(this.logscalex) { const logxmin = Math.log(this.xmin) - return (Math.log(x)-logxmin)*this.xzoom + return (Math.log(x) - logxmin) * this.xzoom } else - return (x - this.xmin)*this.xzoom + return (x - this.xmin) * this.xzoom } /** @@ -415,9 +493,9 @@ class CanvasAPI extends Module { */ px2x(px) { if(this.logscalex) { - return Math.exp(px/this.xzoom+Math.log(this.xmin)) + return Math.exp(px / this.xzoom + Math.log(this.xmin)) } else - return (px/this.xzoom+this.xmin) + return (px / this.xzoom + this.xmin) } /** @@ -427,7 +505,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2y(px) { - return -(px/this.yzoom-this.ymax) + return -(px / this.yzoom - this.ymax) } /** @@ -448,10 +526,10 @@ class CanvasAPI extends Module { * @param {number} y2 */ drawLine(x1, y1, x2, y2) { - this._ctx.beginPath(); - this._ctx.moveTo(x1, y1); - this._ctx.lineTo(x2, y2); - this._ctx.stroke(); + this._ctx.beginPath() + this._ctx.moveTo(x1, y1) + this._ctx.lineTo(x2, y2) + this._ctx.stroke() } /** @@ -463,9 +541,9 @@ class CanvasAPI extends Module { * @param {number} dashPxSize */ drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) { - this._ctx.setLineDash([dashPxSize/2, dashPxSize]); + this._ctx.setLineDash([dashPxSize / 2, dashPxSize]) this.drawLine(x1, y1, x2, y2) - this._ctx.setLineDash([]); + this._ctx.setLineDash([]) } /** @@ -476,7 +554,7 @@ class CanvasAPI extends Module { */ renderLatexImage(ltxText, color, callback) { const onRendered = (imgData) => { - if(!this._canvas.isImageLoaded(imgData.source) && !this._canvas.isImageLoading(imgData.source)){ + if(!this._canvas.isImageLoaded(imgData.source) && !this._canvas.isImageLoading(imgData.source)) { // Wait until the image is loaded to callback. this._canvas.loadImage(imgData.source) this._canvas.imageLoaders[imgData.source] = [callback, imgData] @@ -496,8 +574,13 @@ class CanvasAPI extends Module { // Context methods // - get font() { return this._ctx.font } - set font(value) { return this._ctx.font = value } + get font() { + return this._ctx.font + } + + set font(value) { + return this._ctx.font = value + } /** * Draws an act on the canvas centered on a point. @@ -508,7 +591,7 @@ class CanvasAPI extends Module { * @param {number} endAngle * @param {boolean} counterclockwise */ - arc(x, y, radius, startAngle, endAngle, counterclockwise=false) { + arc(x, y, radius, startAngle, endAngle, counterclockwise = false) { this._ctx.beginPath() this._ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) this._ctx.stroke() @@ -521,9 +604,9 @@ class CanvasAPI extends Module { * @param {number} radius */ disc(x, y, radius) { - this._ctx.beginPath(); + this._ctx.beginPath() this._ctx.arc(x, y, radius, 0, 2 * Math.PI) - this._ctx.fill(); + this._ctx.fill() } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs index 1b68b89..9cd7bef 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs @@ -24,22 +24,44 @@ export class Module { /** * * @param {string} name - Name of the API - * @param {(Module|undefined)[]} requires - List of APIs required to initialize this one. + * @param {Object.|string[]|string|object)>} initializationParameters - List of parameters for the initialize function. */ - constructor(name, requires = []) { + constructor(name, initializationParameters = {}) { console.log(`Loading module ${name}...`) - this.__check_requirements(requires, name) + this.__name = name + this.__initializationParameters = initializationParameters + this.initialized = false } /** * Checks if all requirements are defined. - * @param {(Module|undefined)[]} requires - * @param {string} name + * @param {Object.} options */ - __check_requirements(requires, name) { - for(let requirement of requires) { - if(requirement === undefined) - throw new Error(`Requirement ${requires.indexOf(requirement)} of ${name} has not been initialized.`) + initialize(options) { + if(this.initialized) + throw new Error(`Cannot reinitialize module ${this.__name}.`) + for(const [name, value] of Object.entries(this.__initializationParameters)) { + if(!options.hasOwnProperty(name)) + throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) + if(typeof value === "object") { + if(value instanceof Array) + for(const k in value) + if(!options[name].hasOwnProperty(k)) + throw new Error(`Option '${name}' of initialize of module ${this.__name} does not have the property '${k}'.`) + else + for(const [k, v] in Object.entries(value)) { + if(!options[name].hasOwnProperty(k)) + throw new Error(`Option '${name} of initialize of module ${this.__name} does not have the property '${k}'.`) + else if(typeof (v) === "string" && typeof (options[name][k]) !== v) + throw new Error(`Property '${k}' of initialize option ${name} of module ${this.__name}'s type is not '${v}'.`) + else if(typeof (v) === "object" && !(options[name][k] instanceof v)) + throw new Error(`Property '${k}' of initialize option ${name} of module ${this.__name} is not a '${v}'.`) + } + + + } else if(typeof value === "string" && typeof options[name] !== value) + throw new Error(`Option '${name}' of initialize of module ${this.__name} is not a '${value}' (${typeof options[name]}).`) } + this.initialized = true } } \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index 5ac849e..cc61434 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -36,10 +36,7 @@ const evalVariables = { export class ExprParserAPI extends Module { constructor() { - super("ExprParser", [ - /** @type {ObjectsAPI} */ - Modules.Objects - ]) + super("ExprParser") this.currentVars = {} this._parser = new Parser() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs index 27eedcb..f773402 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs @@ -22,25 +22,67 @@ import Latex from "./latex.mjs" class HistoryAPI extends Module { constructor() { - super('History', [ - Modules.Latex - ]) + super("History", { + historyObj: { + undo: Function, + redo: Function, + clear: Function, + addToHistory: Function, + unserialize: Function, + serialize: Function + }, + themeTextColor: "string", + imageDepth: "number", + fontSize: "number" + }) // History QML object - this.history = null; - this.themeTextColor = "#ff0000"; - this.imageDepth = 2; - this.fontSize = 14; + this.history = null + this.themeTextColor = "#FF0000" + this.imageDepth = 2 + this.fontSize = 28 } - undo() { this.history.undo() } - redo() { this.history.redo() } - clear() { this.history.clear() } - addToHistory(action) { this.history.addToHistory(action) } - unserialize(...data) { this.history.unserialize(...data) } - serialize() { return this.history.serialize() } + initialize({ historyObj, themeTextColor, imageDepth, fontSize }) { + super.initialize({ historyObj, themeTextColor, imageDepth, fontSize }) + console.log("Initializing history...") + this.history = historyObj + this.themeTextColor = themeTextColor + this.imageDepth = imageDepth + this.fontSize = fontSize + } + + undo() { + if(!this.initialized) throw new Error("Attempting undo before initialize!") + this.history.undo() + } + + redo() { + if(!this.initialized) throw new Error("Attempting redo before initialize!") + this.history.redo() + } + + clear() { + if(!this.initialized) throw new Error("Attempting clear before initialize!") + this.history.clear() + } + + addToHistory(action) { + if(!this.initialized) throw new Error("Attempting addToHistory before initialize!") + this.history.addToHistory(action) + } + + unserialize(...data) { + if(!this.initialized) throw new Error("Attempting unserialize before initialize!") + this.history.unserialize(...data) + } + + serialize() { + if(!this.initialized) throw new Error("Attempting serialize before initialize!") + return this.history.serialize() + } } /** @type {HistoryAPI} */ Modules.History = Modules.History || new HistoryAPI() -export default Modules.History \ No newline at end of file +export default Modules.History diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index bc9a1db..9a9d893 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -21,13 +21,55 @@ import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" +/** + * @typedef Settings + * @property {number} width + * @property {number} height + * @property {number} xmin + * @property {number} ymax + * @property {number} xzoom + * @property {number} yzoom + * @property {number} xaxisstep + * @property {number} yaxisstep + * @property {string} xlabel + * @property {string} ylabel + * @property {number} linewidth + * @property {number} textsize + * @property {boolean} logscalex + * @property {boolean} showxgrad + * @property {boolean} showygrad + */ + class IOAPI extends Module { constructor() { - super("IO", [ - Modules.Objects, - Modules.History - ]) + super("IO", { + root: { + width: "number", + height: "number", + updateObjectsLists: Function, + }, + alert: { + show: Function + }, + settings: { + width: "number", + height: "number", + xmin: "number", + ymax: "number", + xzoom: "number", + yzoom: "number", + xaxisstep: "number", + yaxisstep: "number", + xlabel: "string", + ylabel: "string", + linewidth: "number", + textsize: "number", + logscalex: "boolean", + showxgrad: "boolean", + showygrad: "boolean" + } + }) /** * Path of the currently opened file. Empty if no file is opened. * @type {string} @@ -37,12 +79,13 @@ class IOAPI extends Module { /** * Initializes module with QML elements. - * @param {{width: number, height: number, updateObjectsLists: function()}} rootElement + * @param {{width: number, height: number, updateObjectsLists: function()}} root * @param {Settings} settings * @param {{show: function(string)}} alert */ - initialize(rootElement, settings, alert) { - this.rootElement = rootElement + initialize({ root, settings, alert }) { + super.initialize({ root, settings, alert }) + this.rootElement = root this.settings = settings this.alert = alert } @@ -52,6 +95,7 @@ class IOAPI extends Module { * @param {string} filename */ saveDiagram(filename) { + if(!this.initialized) throw new Error("Attempting saveDiagram before initialize!") // Add extension if necessary if(["lpf"].indexOf(filename.split(".")[filename.split(".").length - 1]) === -1) filename += ".lpf" @@ -93,11 +137,13 @@ class IOAPI extends Module { * @param {string} filename */ loadDiagram(filename) { + if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!") + if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!") let basename = filename.split("/").pop() this.alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename)) let data = JSON.parse(Helper.load(filename)) let error = "" - if(Object.keys(data).includes("type") && data["type"] === "logplotv1") { + if(data.hasOwnProperty("type") && data["type"] === "logplotv1") { History.clear() // Importing settings this.settings.saveFilename = filename @@ -129,7 +175,7 @@ class IOAPI extends Module { // Another way would be to change the reference as well, but I feel like the code would be less clean. } for(let objType in data["objects"]) { - if(Object.keys(Objects.types).indexOf(objType) > -1) { + if(Object.keys(Objects.types).includes(objType)) { Objects.currentObjects[objType] = [] for(let objData of data["objects"][objType]) { /** @type {DrawableObject} */ @@ -157,7 +203,7 @@ class IOAPI extends Module { } if(error !== "") { console.log(error) - this.alert.show(qsTranslate("io", "Could not save file: ") + error) + this.alert.show(qsTranslate("io", "Could not load file: ") + error) // TODO: Error handling return } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs index 32f048b..f2e9b0b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs @@ -58,10 +58,7 @@ class LatexRenderResult { class LatexAPI extends Module { constructor() { - super("Latex", [ - /** @type {ExprParserAPI} */ - Modules.ExprParser - ]) + super("Latex") /** * true if latex has been enabled by the user, false otherwise. */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs index e76596e..389a5ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs @@ -22,10 +22,7 @@ import DefaultGraph from "../preferences/default.mjs" class PreferencesAPI extends Module { constructor() { - super('Preferences', [ - Modules.Canvas, - Modules.Latex - ]) + super('Preferences') this.categories = { [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, From 6a1f01ba1fdb410ec491f68db02a8efd9e548ef9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 24 Sep 2024 00:04:11 +0200 Subject: [PATCH 133/249] Better interfaces! --- .../LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../LogarithmPlotter/js/module/canvas.mjs | 46 +------ .../LogarithmPlotter/js/module/common.mjs | 24 +--- .../LogarithmPlotter/js/module/history.mjs | 16 +-- .../LogarithmPlotter/js/module/interface.mjs | 130 ++++++++++++++++++ .../ad5001/LogarithmPlotter/js/module/io.mjs | 51 +------ 6 files changed, 155 insertions(+), 114 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 2d7eb08..e54781f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -140,7 +140,7 @@ Canvas { id: drawingErrorDialog title: qsTranslate("expression", "LogarithmPlotter - Drawing error") text: "" - function showDialog(objType, objName, error) { + function show(objType, objName, error) { text = qsTranslate("error", "Error while attempting to draw %1 %2:\n%3\n\nUndoing last change.").arg(objType).arg(objName).arg(error) open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs index 75efb04..04abf68 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs @@ -17,60 +17,28 @@ */ import { Module } from "./common.mjs" +import { FUNCTION, Interface, CanvasInterface, DialogInterface } from "./interface.mjs" import { textsup } from "../utils.mjs" import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" - -/** - * @typedef {Settings} Canvas - * @property {object} imageLoaders - * @property {function()} requestPaint - * @property {function(string)} getContext - * @property {function(rect)} markDirty - * @property {function(string)} loadImage - */ - class CanvasAPI extends Module { constructor() { super("Canvas", { - canvas: { - width: "number", - height: "number", - xmin: "number", - ymax: "number", - xzoom: "number", - yzoom: "number", - xaxisstep: "number", - yaxisstep: "number", - xlabel: "string", - ylabel: "string", - linewidth: "number", - textsize: "number", - logscalex: "boolean", - showxgrad: "boolean", - showygrad: "boolean", - imageLoaders: "object", - getContext: Function, - markDirty: Function, - loadImage: Function, - requestPaint: Function, - }, - drawingErrorDialog: { - showDialog: Function, - } + canvas: CanvasInterface, + drawingErrorDialog: DialogInterface }) - /** @type {Canvas} */ + /** @type {CanvasInterface} */ this._canvas = null /** @type {CanvasRenderingContext2D} */ this._ctx = null /** - * @type {{showDialog(string, string, string)}} + * @type {{show(string, string, string)}} * @private */ this._drawingErrorDialog = null @@ -94,8 +62,8 @@ class CanvasAPI extends Module { /** * Initialize the module. - * @param {Canvas} canvas - * @param {{showDialog(string, string, string)}} drawingErrorDialog + * @param {CanvasInterface} canvas + * @param {{show(string, string, string)}} drawingErrorDialog */ initialize({ canvas, drawingErrorDialog }) { super.initialize({ canvas, drawingErrorDialog }) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs index 9cd7bef..6902745 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +import { Interface } from "./interface.mjs" + /** * Base class for global APIs in runtime. */ @@ -24,7 +26,7 @@ export class Module { /** * * @param {string} name - Name of the API - * @param {Object.|string[]|string|object)>} initializationParameters - List of parameters for the initialize function. + * @param {Object.} initializationParameters - List of parameters for the initialize function. */ constructor(name, initializationParameters = {}) { console.log(`Loading module ${name}...`) @@ -43,23 +45,9 @@ export class Module { for(const [name, value] of Object.entries(this.__initializationParameters)) { if(!options.hasOwnProperty(name)) throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) - if(typeof value === "object") { - if(value instanceof Array) - for(const k in value) - if(!options[name].hasOwnProperty(k)) - throw new Error(`Option '${name}' of initialize of module ${this.__name} does not have the property '${k}'.`) - else - for(const [k, v] in Object.entries(value)) { - if(!options[name].hasOwnProperty(k)) - throw new Error(`Option '${name} of initialize of module ${this.__name} does not have the property '${k}'.`) - else if(typeof (v) === "string" && typeof (options[name][k]) !== v) - throw new Error(`Property '${k}' of initialize option ${name} of module ${this.__name}'s type is not '${v}'.`) - else if(typeof (v) === "object" && !(options[name][k] instanceof v)) - throw new Error(`Property '${k}' of initialize option ${name} of module ${this.__name} is not a '${v}'.`) - } - - - } else if(typeof value === "string" && typeof options[name] !== value) + if(typeof value === "function" && value.prototype instanceof Interface) + Interface.check_implementation(value, options[name]) + else if(typeof value !== typeof options[name]) throw new Error(`Option '${name}' of initialize of module ${this.__name} is not a '${value}' (${typeof options[name]}).`) } this.initialized = true diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs index f773402..09b45d6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs @@ -18,22 +18,16 @@ import { Module } from "./common.mjs" import Latex from "./latex.mjs" +import { HistoryInterface, NUMBER, STRING } from "./interface.mjs" class HistoryAPI extends Module { constructor() { super("History", { - historyObj: { - undo: Function, - redo: Function, - clear: Function, - addToHistory: Function, - unserialize: Function, - serialize: Function - }, - themeTextColor: "string", - imageDepth: "number", - fontSize: "number" + historyObj: HistoryInterface, + themeTextColor: STRING, + imageDepth: NUMBER, + fontSize: NUMBER }) // History QML object this.history = null diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs new file mode 100644 index 0000000..9da3f4d --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -0,0 +1,130 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export const NUMBER = 0 +export const STRING = "string" +export const BOOLEAN = true +export const OBJECT = {} +export const FUNCTION = () => { +} + + +export class Interface { + /** + * Checks if the class to check implements the given interface. + * Throws an error if the implementation does not conform to the interface. + * @param {typeof Interface} interface_ + * @param {object} classToCheck + * @return {boolean} + */ + static check_implementation(interface_, classToCheck) { + const properties = new interface_() + const interfaceName = interface_.name + const toCheckName = classToCheck.constructor.name + for(const [property, value] of Object.entries(properties)) + if(property !== "implement") { + console.log(classToCheck[property], value) + if(!classToCheck.hasOwnProperty(property)) + // Check if the property exist + throw new Error(`Property '${property}' (${typeof value}) is present in interface ${interfaceName}, but not in implementation ${toCheckName}.`) + else if((typeof value) !== (typeof classToCheck[property])) + // Compare the types + throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is a '${typeof classToCheck[property]}' and not a '${typeof value}'.`) + else if((typeof value) === "object") + // Test type of object. + if(value instanceof Interface) + Interface.check_implementation(value, classToCheck[property]) + else if(value.prototype && !(classToCheck[property] instanceof value)) + throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is not '${value.constructor.name}'.`) + } + } + + /** + * Decorator to automatically check if a class conforms to the current interface. + * @param {object} class_ + */ + implement(class_) { + Interface.check_implementation(this, class_) + return class_ + } +} + + +export class SettingsInterface extends Interface { + constructor() { + super() + this.width = NUMBER + this.height = NUMBER + this.xmin = NUMBER + this.ymax = NUMBER + this.xzoom = NUMBER + this.yzoom = NUMBER + this.xaxisstep = STRING + this.yaxisstep = STRING + this.xlabel = STRING + this.ylabel = STRING + this.linewidth = NUMBER + this.textsize = NUMBER + this.logscalex = BOOLEAN + this.showxgrad = BOOLEAN + this.showygrad = BOOLEAN + } +} + +export class CanvasInterface extends SettingsInterface { + constructor() { + super() + this.imageLoaders = OBJECT + /** @type {function(string): CanvasRenderingContext2D} */ + this.getContext = FUNCTION + /** @type {function(rect)} */ + this.markDirty = FUNCTION + /** @type {function(string)} */ + this.loadImage = FUNCTION + /** @type {function()} */ + this.requestPaint = FUNCTION + } +} + +export class RootInterface extends Interface { + constructor() { + super() + this.width = NUMBER + this.height = NUMBER + this.updateObjectsLists = FUNCTION + } +} + +export class DialogInterface extends Interface { + constructor() { + super() + this.show = FUNCTION + } +} + +export class HistoryInterface extends Interface { + constructor() { + super() + this.undo = FUNCTION + this.redo = FUNCTION + this.clear = FUNCTION + this.addToHistory = FUNCTION + this.unserialize = FUNCTION + this.serialize = FUNCTION + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index 9a9d893..2a540a7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -20,55 +20,16 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" +import { DialogInterface, FUNCTION, Interface, RootInterface, SettingsInterface } from "./interface.mjs" -/** - * @typedef Settings - * @property {number} width - * @property {number} height - * @property {number} xmin - * @property {number} ymax - * @property {number} xzoom - * @property {number} yzoom - * @property {number} xaxisstep - * @property {number} yaxisstep - * @property {string} xlabel - * @property {string} ylabel - * @property {number} linewidth - * @property {number} textsize - * @property {boolean} logscalex - * @property {boolean} showxgrad - * @property {boolean} showygrad - */ class IOAPI extends Module { constructor() { super("IO", { - root: { - width: "number", - height: "number", - updateObjectsLists: Function, - }, - alert: { - show: Function - }, - settings: { - width: "number", - height: "number", - xmin: "number", - ymax: "number", - xzoom: "number", - yzoom: "number", - xaxisstep: "number", - yaxisstep: "number", - xlabel: "string", - ylabel: "string", - linewidth: "number", - textsize: "number", - logscalex: "boolean", - showxgrad: "boolean", - showygrad: "boolean" - } + alert: DialogInterface, + root: RootInterface, + settings: SettingsInterface }) /** * Path of the currently opened file. Empty if no file is opened. @@ -79,8 +40,8 @@ class IOAPI extends Module { /** * Initializes module with QML elements. - * @param {{width: number, height: number, updateObjectsLists: function()}} root - * @param {Settings} settings + * @param {RootInterface} root + * @param {SettingsInterface} settings * @param {{show: function(string)}} alert */ initialize({ root, settings, alert }) { From 937cb07d0b01791df9c532c5a08a929a081c20f0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 24 Sep 2024 05:23:12 +0200 Subject: [PATCH 134/249] Working mjs building --- .gitignore | 16 +- .../LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../LogarithmPlotter/js/history/color.mjs | 2 +- .../LogarithmPlotter/js/history/create.mjs | 2 +- .../LogarithmPlotter/js/history/delete.mjs | 2 +- .../js/history/editproperty.mjs | 2 +- .../LogarithmPlotter/js/history/name.mjs | 2 +- .../LogarithmPlotter/js/history/position.mjs | 2 +- .../js/history/visibility.mjs | 2 +- .../LogarithmPlotter/js/math/domain.mjs | 2 +- .../LogarithmPlotter/js/math/sequence.mjs | 2 +- .../LogarithmPlotter/js/module/interface.mjs | 3 +- .../LogarithmPlotter/js/objs/autoload.mjs | 22 +- .../js/objs/bodemagnitude.mjs | 4 +- .../js/objs/bodemagnitudesum.mjs | 4 +- .../LogarithmPlotter/js/objs/bodephase.mjs | 2 +- .../LogarithmPlotter/js/objs/bodephasesum.mjs | 2 +- .../LogarithmPlotter/js/objs/distribution.mjs | 2 +- .../LogarithmPlotter/js/objs/function.mjs | 2 +- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 2 +- .../LogarithmPlotter/js/objs/sequence.mjs | 4 +- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 2 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 2 +- .../LogarithmPlotter/js/parsing/parsing.mjs | 2 +- .../js/preferences/default.mjs | 2 +- .../js/preferences/expression.mjs | 2 +- .../js/preferences/general.mjs | 2 +- package-lock.json | 719 ++++++++++++++++++ package.json | 21 + rollup.config.mjs | 41 + 30 files changed, 832 insertions(+), 44 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.mjs diff --git a/.gitignore b/.gitignore index a60c4d3..121e497 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +# Building build/ dist/ deb_dist/ @@ -8,6 +9,11 @@ linux/flatpak/.flatpak-builder *.snap *.spec *.zip +*.tar.gz +*.spec +*.egg-info/ + +# Runtime data **/**.qmlc **/**.jsc **/**.pyc @@ -20,16 +26,18 @@ linux/flatpak/.flatpak-builder .DS_Store **/.DS_Store **/__pycache__/ + +# IDE Data .ropeproject .vscode *.kdev4 .kdev4 .coverage -build docs/html .directory *.lpf *.lgg -*.spec -*.egg-info/ -*.tar.gz + +# npm +node_modules +LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs* diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 1a44958..e06aeba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/autoload.mjs" as ModulesAutoload +import "js/index.mjs" as ModulesAutoload import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index 067da0c..51541b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import EditedProperty from "editproperty.mjs" +import EditedProperty from "./editproperty.mjs" import Objects from "../module/objects.mjs" export default class ColorChanged extends EditedProperty { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index bd3dafd..9f0fa52 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -17,7 +17,7 @@ */ import Objects from "../module/objects.mjs" -import { Action } from "common.mjs" +import { Action } from "./common.mjs" export default class CreateNewObject extends Action { // Action used for the creation of an object diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index c348c41..984b5c2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -17,7 +17,7 @@ */ import Objects from "../module/objects.mjs" -import CreateNewObject from "create.mjs" +import CreateNewObject from "./create.mjs" export default class DeleteObject extends CreateNewObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index de84449..c4b9217 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -19,7 +19,7 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" import * as MathLib from "../math/index.mjs" -import { Action } from "common.mjs" +import { Action } from "./common.mjs" import { DrawableObject } from "../objs/common.mjs" export default class EditedProperty extends Action { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index a852923..b2ce9f1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import EditedProperty from "editproperty.mjs" +import EditedProperty from "./editproperty.mjs" import Objects from "../module/objects.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index c568615..1671036 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -20,7 +20,7 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" import * as MathLib from "../math/index.mjs" import { escapeHTML } from "../utils.mjs" -import { Action } from "common.mjs" +import { Action } from "./common.mjs" import { DrawableObject } from "../objs/common.mjs" export default class EditedPosition extends Action { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index c04e0a4..c66ade0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import EditedProperty from "editproperty.mjs" +import EditedProperty from "./editproperty.mjs" import Objects from "../module/objects.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index 22b0154..8ed1d7d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Expression, executeExpression } from "expression.mjs" +import { Expression, executeExpression } from "./expression.mjs" /** * Main abstract domain class diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index d524e44..5394237 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import * as Expr from "expression.mjs" +import * as Expr from "./expression.mjs" import * as Utils from "../utils.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs index 9da3f4d..7bda424 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -38,7 +38,6 @@ export class Interface { const toCheckName = classToCheck.constructor.name for(const [property, value] of Object.entries(properties)) if(property !== "implement") { - console.log(classToCheck[property], value) if(!classToCheck.hasOwnProperty(property)) // Check if the property exist throw new Error(`Property '${property}' (${typeof value}) is present in interface ${interfaceName}, but not in implementation ${toCheckName}.`) @@ -127,4 +126,4 @@ export class HistoryInterface extends Interface { this.unserialize = FUNCTION this.serialize = FUNCTION } -} \ No newline at end of file +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index a7351b5..729e167 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -17,17 +17,17 @@ */ import Objects from "../module/objects.mjs" -import { DrawableObject } from "common.mjs" -import Point from "point.mjs" -import Text from "text.mjs" -import Function from "function.mjs" -import BodeMagnitude from "bodemagnitude.mjs" -import BodePhase from "bodephase.mjs" -import BodeMagnitudeSum from "bodemagnitudesum.mjs" -import BodePhaseSum from "bodephasesum.mjs" -import XCursor from "xcursor.mjs" -import Sequence from "sequence.mjs" -import DistributionFunction from "distribution.mjs" +import { DrawableObject } from "./common.mjs" +import Point from "./point.mjs" +import Text from "./text.mjs" +import Function from "./function.mjs" +import BodeMagnitude from "./bodemagnitude.mjs" +import BodePhase from "./bodephase.mjs" +import BodeMagnitudeSum from "./bodemagnitudesum.mjs" +import BodePhaseSum from "./bodephasesum.mjs" +import XCursor from "./xcursor.mjs" +import Sequence from "./sequence.mjs" +import DistributionFunction from "./distribution.mjs" /** * Registers the object obj in the object list. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index 7ca294d..1534dd5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -23,8 +23,8 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" import History from "../module/history.mjs" -import { ExecutableObject } from "common.mjs" -import Function from "function.mjs" +import { ExecutableObject } from "./common.mjs" +import Function from "./function.mjs" export default class BodeMagnitude extends ExecutableObject { static type(){return 'Gain Bode'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index 7d5c3e4..f268bbe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -21,8 +21,8 @@ import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import { ExecutableObject } from "common.mjs" -import Function from "function.mjs" +import { ExecutableObject } from "./common.mjs" +import Function from "./function.mjs" export default class BodeMagnitudeSum extends ExecutableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index 3cafd52..310bb25 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -23,7 +23,7 @@ import Objects from "../module/objects.mjs" import History from "../module/history.mjs" import Latex from "../module/latex.mjs" -import { ExecutableObject } from "common.mjs" +import { ExecutableObject } from "./common.mjs" export default class BodePhase extends ExecutableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index cee3235..a3de8f6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import { ExecutableObject } from "common.mjs" +import { ExecutableObject } from "./common.mjs" export default class BodePhaseSum extends ExecutableObject { static type(){return 'Somme phases Bode'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs index 1ad9a7e..411e191 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs @@ -20,7 +20,7 @@ import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import { ExecutableObject } from "common.mjs" +import { ExecutableObject } from "./common.mjs" export default class DistributionFunction extends ExecutableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 752aa52..84cf45c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -18,7 +18,7 @@ import { textsub } from "../utils.mjs" import Objects from "../module/objects.mjs" -import { ExecutableObject } from "common.mjs" +import { ExecutableObject } from "./common.mjs" import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs" import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 33d3858..2c07836 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import { DrawableObject } from "common.mjs" +import { DrawableObject } from "./common.mjs" export default class Point extends DrawableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 0d2c488..310444e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -21,8 +21,8 @@ import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" -import { ExecutableObject } from "common.mjs" -import Function from "function.mjs" +import { ExecutableObject } from "./common.mjs" +import Function from "./function.mjs" export default class Sequence extends ExecutableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index bd30dfe..e7f7a05 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import { DrawableObject } from "common.mjs" +import { DrawableObject } from "./common.mjs" export default class Text extends DrawableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 20dc548..7c6d422 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -21,7 +21,7 @@ import * as P from "../parameters.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" -import { DrawableObject } from "common.mjs" +import { DrawableObject } from "./common.mjs" export default class XCursor extends DrawableObject { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs index 71d34d1..a9dba98 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs @@ -18,7 +18,7 @@ import * as Reference from "reference.mjs" import * as T from "./tokenizer.mjs" -import InputExpression from "common.mjs" +import InputExpression from "./common.mjs" export const Input = InputExpression export const TokenType = T.TokenType diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs index 230c71a..c58f4de 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "common.mjs" +import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "./common.mjs" const XZOOM = new NumberSetting( diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs index 4493c77..efd7b40 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {BoolSetting, EnumIntSetting} from "common.mjs" +import {BoolSetting, EnumIntSetting} from "./common.mjs" const AUTOCLOSE_FORMULA = new BoolSetting( qsTranslate("expression", "Automatically close parenthesises and brackets"), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 2c5ef17..8d1e751 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {BoolSetting} from "common.mjs" +import {BoolSetting} from "./common.mjs" import Canvas from "../module/canvas.mjs" import LatexAPI from "../module/latex.mjs" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e26337d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,719 @@ +{ + "name": "logarithmplotter", + "version": "0.6.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "logarithmplotter", + "version": "0.6.0", + "license": "GPL-3.0-or-later", + "dependencies": { + "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-terser": "^0.4.4", + "rollup": "^4.22.4" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", + "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.1.1", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", + "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", + "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "license": "MIT" + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terser": { + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz", + "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4802906 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "logarithmplotter", + "version": "0.6.0", + "description": "2D plotter software to make Bode plots, sequences and distribution functions.", + "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", + "scripts": { + "build": "rollup --config rollup.config.mjs" + }, + "repository": { + "type": "git", + "url": "https://git.ad5001.eu/Ad5001/LogarithmPlotter" + }, + "author": "Ad5001 ", + "license": "GPL-3.0-or-later", + "dependencies": { + "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-terser": "^0.4.4", + "rollup": "^4.22.4" + } +} diff --git a/rollup.config.mjs b/rollup.config.mjs new file mode 100644 index 0000000..0738331 --- /dev/null +++ b/rollup.config.mjs @@ -0,0 +1,41 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { nodeResolve } from "@rollup/plugin-node-resolve" +import commonjs from "@rollup/plugin-commonjs" +import terser from "@rollup/plugin-terser" + +const path = "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js" + +export default { + input: `${path}/autoload.mjs`, + output: { + file: `${path}/index.mjs`, + compact: true, + sourcemap: true, + format: "es", + }, + plugins: [ + nodeResolve(), + commonjs(), + terser({ + ecma: 2015, + }) + ] +} + From 17b6e40d60f3de2ff357c5dec878199452dd0c24 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 23 Sep 2024 17:03:31 +0000 Subject: [PATCH 135/249] Translated using Weblate (Spanish) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 96cb5de..02b39ef 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -1825,7 +1825,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) + integral(<desde: número>, <hasta: número>, <f: Objeto similar a una función>) @@ -1849,17 +1849,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integral(<desde: número>, <hasta: número>, <f: cadena>, <variable: cadena>) derivative(<f: ExecutableObject>, <x: number>) - derivada(<f: ExecutableObject>, <x: number>) + derivative(<f: objeto similar a una función>, <x: número>) derivative(<f: string>, <variable: string>, <x: number>) - derivada(<f: string>, <variable: string>, <x: number>) + derivative(<f: cadena>, <variable: cadena>, <x: número>) From f9af0c34dd4254dc6abef1e70feedfb424ce51e8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 25 Sep 2024 19:18:04 +0200 Subject: [PATCH 136/249] Source mapping and debugging --- LogarithmPlotter/logarithmplotter.py | 3 +- .../LogarithmPlotter/js/math/domain.mjs | 4 +- .../LogarithmPlotter/js/module/expreval.mjs | 2 +- .../ad5001/LogarithmPlotter/js/module/io.mjs | 2 +- LogarithmPlotter/util/debug.py | 80 + babel.config.json | 6 + package-lock.json | 2199 ++++++++++++++++- package.json | 3 + poetry.lock | 13 +- pyproject.toml | 4 + rollup.config.mjs | 16 +- run.py | 1 + 12 files changed, 2313 insertions(+), 20 deletions(-) create mode 100644 LogarithmPlotter/util/debug.py create mode 100644 babel.config.json diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index bc4d895..9aede1b 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -43,7 +43,7 @@ if path.realpath(path.join(getcwd(), "..")) not in sys_path: sys_path.append(path.realpath(path.join(getcwd(), ".."))) from LogarithmPlotter import __VERSION__ -from LogarithmPlotter.util import config, native +from LogarithmPlotter.util import config, native, debug from LogarithmPlotter.util.update import check_for_updates from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex @@ -155,6 +155,7 @@ def run(): register_icon_directories() app = create_qapp() translator = install_translation(app) + debug.setup() # Installing macOS file handler. macos_file_open_handler = None diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index 8ed1d7d..a9cefb5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -155,7 +155,7 @@ export class Domain { return Domain.ZE break; default: - return new EmptySet() + return Domain.EmptySet break; } } @@ -182,6 +182,8 @@ export class EmptySet extends Domain { static import(frm) { return new EmptySet() } } +Domain.EmptySet = new EmptySet() // To prevent use prior to declaration. + /** * Domain classes for ranges (e.g ]0;3[, [1;2[ ...) */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index cc61434..f40489f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -34,7 +34,7 @@ const evalVariables = { "false": false } -export class ExprParserAPI extends Module { +class ExprParserAPI extends Module { constructor() { super("ExprParser") this.currentVars = {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index 2a540a7..11ac25f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -178,4 +178,4 @@ class IOAPI extends Module { /** @type {IOAPI} */ Modules.IO = Modules.IO || new IOAPI() -export default Modules.IO \ No newline at end of file +export default Modules.IO diff --git a/LogarithmPlotter/util/debug.py b/LogarithmPlotter/util/debug.py new file mode 100644 index 0000000..d6474ce --- /dev/null +++ b/LogarithmPlotter/util/debug.py @@ -0,0 +1,80 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from PySide6.QtCore import QtMsgType, qInstallMessageHandler +from math import ceil, log10 +from sourcemap import loads +from os import path + +CURRENT_PATH = path.dirname(path.realpath(__file__)) +SOURECMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map") +SOURCEMAP_INDEX = None + +class LOG_COLORS: + GRAY = "\033[90m" + BLUE = "\033[94m" + ORANGE = "\033[38;5;166m" + RED = "\033[e[38;5;204m" + INVERT = "\033[7m" + RESET_INVERT = "\033[27m" + RESET = "\033[0m" + + + +MODES = { + QtMsgType.QtInfoMsg: ['info', LOG_COLORS.BLUE], + QtMsgType.QtWarningMsg: ['warning', LOG_COLORS.ORANGE], + QtMsgType.QtCriticalMsg: ['critical', LOG_COLORS.RED], + QtMsgType.QtFatalMsg: ['critical', LOG_COLORS.RED] +} + +DEFAULT_MODE = ['debug', LOG_COLORS.GRAY] + +def log_qt_debug(mode, context, message): + """ + Parses and renders qt log messages. + """ + if mode in MODES: + mode = MODES[mode] + else: + mode = DEFAULT_MODE + line = context.line + source_file = context.file + # Remove source and line from emssage + if source_file is not None: + if message.startswith(source_file): + message = message[len(source_file) + 1:] + source_file = source_file.split("/qml")[-1] # We're only interested in that part. + if line is not None and message.startswith(str(line)): + line_length = ceil(log10((line+1) if line > 0 else 1)) + message = message[line_length + 2:] + # Check MJS + if line is not None and source_file is not None and source_file.endswith("index.mjs"): + try: + token = SOURCEMAP_INDEX.lookup(line, 20) + source_file = source_file[:-len("index.mjs")] + token.src + line = token.src_line + except IndexError: + pass # Unable to find source, leave as is. + print(f"{LOG_COLORS.INVERT}{mode[1]}[{mode[0].upper()}]{LOG_COLORS.RESET_INVERT} {message}{LOG_COLORS.RESET} ({context.function} at {source_file}:{line})") + +def setup(): + global SOURCEMAP_INDEX + with open(SOURECMAP_PATH, "r") as f: + SOURCEMAP_INDEX = loads(f.read()) + qInstallMessageHandler(log_qt_debug) diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 0000000..fd63c92 --- /dev/null +++ b/babel.config.json @@ -0,0 +1,6 @@ +{ + "presets": ["@babel/preset-env"], + "targets": { + "esmodules": true + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e26337d..6b68c5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,1688 @@ "version": "0.6.0", "license": "GPL-3.0-or-later", "dependencies": { + "@babel/preset-env": "^7.25.4", + "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", + "install": "^0.13.0", "rollup": "^4.22.4" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.4", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.4", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "license": "MIT" + }, + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -73,6 +1749,32 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "28.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", @@ -423,12 +2125,144 @@ "node": ">=0.4.0" } }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, + "node_modules/caniuse-lite": { + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -441,6 +2275,43 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "license": "MIT" }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT", + "peer": true + }, + "node_modules/core-js-compat": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -450,12 +2321,45 @@ "node": ">=0.10.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", + "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fdir": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", @@ -493,6 +2397,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -505,6 +2437,15 @@ "node": ">= 0.4" } }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-core-module": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", @@ -535,6 +2476,52 @@ "@types/estree": "*" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/magic-string": { "version": "0.30.11", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", @@ -544,12 +2531,30 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "license": "ISC" + }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", @@ -573,6 +2578,76 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "license": "MIT", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -651,6 +2726,15 @@ ], "license": "MIT" }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -666,15 +2750,6 @@ "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "license": "MIT" }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -685,6 +2760,27 @@ "source-map": "^0.6.0" } }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -714,6 +2810,91 @@ "engines": { "node": ">=10" } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" } } } diff --git a/package.json b/package.json index 4802906..54ad9d9 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,12 @@ "author": "Ad5001 ", "license": "GPL-3.0-or-later", "dependencies": { + "@babel/preset-env": "^7.25.4", + "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", + "install": "^0.13.0", "rollup": "^4.22.4" } } diff --git a/poetry.lock b/poetry.lock index 0c25a10..c94f9e7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -395,6 +395,17 @@ files = [ {file = "shiboken6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:9024e6afb2af1568ebfc8a5d07e4ff6c8829f40923eeb28901f535463e2b6b65"}, ] +[[package]] +name = "sourcemap" +version = "0.2.1" +description = "Parse JavaScript source maps." +optional = false +python-versions = "*" +files = [ + {file = "sourcemap-0.2.1-py2.py3-none-any.whl", hash = "sha256:c448a8c48f9482e522e4582106b0c641a83b5dbc7f13927b178848e3ea20967b"}, + {file = "sourcemap-0.2.1.tar.gz", hash = "sha256:be00a90185e7a16b87bbe62a68ffd5e38bc438ef4700806d9b90e44d8027787c"}, +] + [[package]] name = "stdeb" version = "0.10.0" @@ -438,4 +449,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "3db79d8b611fd2e37486fbd8e10c6d454b293cc7156d83b05c1a8459cb9b33e6" +content-hash = "30da53f0a05c06c5f93aa1260217d807ce2ab64debd26f313b47c664931e67c7" diff --git a/pyproject.toml b/pyproject.toml index f705e04..7b5b6f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,3 +20,7 @@ stdeb = "^0.10.0" pytest = "^8.3.3" pytest-cov = "^5.0.0" pytest-qt = "^4.4.0" + +[tool.poetry.group.dev.dependencies] +sourcemap = "^0.2.1" + diff --git a/rollup.config.mjs b/rollup.config.mjs index 0738331..4a32424 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -18,6 +18,7 @@ import { nodeResolve } from "@rollup/plugin-node-resolve" import commonjs from "@rollup/plugin-commonjs" +import { babel } from "@rollup/plugin-babel" import terser from "@rollup/plugin-terser" const path = "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js" @@ -26,16 +27,19 @@ export default { input: `${path}/autoload.mjs`, output: { file: `${path}/index.mjs`, - compact: true, + compact: false, sourcemap: true, - format: "es", + format: "es" }, plugins: [ - nodeResolve(), + nodeResolve({ browser: true }), commonjs(), - terser({ - ecma: 2015, - }) + babel({ + babelHelpers: "bundled" + }), + // terser({ + // ecma: 2015 + // }) ] } diff --git a/run.py b/run.py index 1481dba..7978a15 100644 --- a/run.py +++ b/run.py @@ -21,6 +21,7 @@ def update_translations(): """ from os import system, getcwd, chdir, path pwd = getcwd() + system("npm run build") chdir(path.join("LogarithmPlotter", "i18n")) system("./release.sh") chdir(pwd) From fbb85083c1254eea7bb4d7205f60249289c3f3c3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 24 Sep 2024 19:39:53 +0000 Subject: [PATCH 137/249] Translated using Weblate (German) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 0dbfa98..761283f 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1825,7 +1825,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) + integral(<von: Zahl>, <bis: Zahl>, <f: Funktionsähnliches Objekt>) From 309b0fafb05751a84ee780bec83e6bc1fb7497e3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 00:01:30 +0200 Subject: [PATCH 138/249] Adding tests for debug --- LogarithmPlotter/util/debug.py | 80 ++++++++++++++++++++++------------ README.md | 18 +++++--- tests/python/test_debug.py | 68 +++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 34 deletions(-) create mode 100644 tests/python/test_debug.py diff --git a/LogarithmPlotter/util/debug.py b/LogarithmPlotter/util/debug.py index d6474ce..b093ee0 100644 --- a/LogarithmPlotter/util/debug.py +++ b/LogarithmPlotter/util/debug.py @@ -16,15 +16,15 @@ * along with this program. If not, see . """ -from PySide6.QtCore import QtMsgType, qInstallMessageHandler +from PySide6.QtCore import QtMsgType, qInstallMessageHandler, QMessageLogContext from math import ceil, log10 -from sourcemap import loads from os import path CURRENT_PATH = path.dirname(path.realpath(__file__)) -SOURECMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map") +SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map") SOURCEMAP_INDEX = None + class LOG_COLORS: GRAY = "\033[90m" BLUE = "\033[94m" @@ -35,7 +35,6 @@ class LOG_COLORS: RESET = "\033[0m" - MODES = { QtMsgType.QtInfoMsg: ['info', LOG_COLORS.BLUE], QtMsgType.QtWarningMsg: ['warning', LOG_COLORS.ORANGE], @@ -45,36 +44,59 @@ MODES = { DEFAULT_MODE = ['debug', LOG_COLORS.GRAY] -def log_qt_debug(mode, context, message): + +def map_javascript_source(source_file: str, line: str) -> tuple[str, str]: """ - Parses and renders qt log messages. + Maps a line from the compiled javascript to its source. """ - if mode in MODES: - mode = MODES[mode] - else: - mode = DEFAULT_MODE - line = context.line - source_file = context.file - # Remove source and line from emssage - if source_file is not None: - if message.startswith(source_file): - message = message[len(source_file) + 1:] - source_file = source_file.split("/qml")[-1] # We're only interested in that part. - if line is not None and message.startswith(str(line)): - line_length = ceil(log10((line+1) if line > 0 else 1)) - message = message[line_length + 2:] - # Check MJS - if line is not None and source_file is not None and source_file.endswith("index.mjs"): - try: + try: + if SOURCEMAP_INDEX is not None: token = SOURCEMAP_INDEX.lookup(line, 20) source_file = source_file[:-len("index.mjs")] + token.src line = token.src_line - except IndexError: - pass # Unable to find source, leave as is. - print(f"{LOG_COLORS.INVERT}{mode[1]}[{mode[0].upper()}]{LOG_COLORS.RESET_INVERT} {message}{LOG_COLORS.RESET} ({context.function} at {source_file}:{line})") + except IndexError: + pass # Unable to find source, leave as is. + return source_file, line + + +def create_log_terminal_message(mode: QtMsgType, context: QMessageLogContext, message: str): + """ + Parses a qt log message and returns it. + """ + mode = MODES[mode] if mode in MODES else DEFAULT_MODE + line = context.line + source_file = context.file + # Remove source and line from message + if source_file is not None: + if message.startswith(source_file): + message = message[len(source_file) + 1:] + source_file = "LogarithmPlotter/qml/" + source_file.split("/qml/")[-1] # We're only interested in that part. + if line is not None and message.startswith(str(line)): + line_length = ceil(log10((line + 1) if line > 0 else 1)) + message = message[line_length + 2:] + # Check MJS + if line is not None and source_file is not None and source_file.endswith("index.mjs"): + source_file, line = map_javascript_source(source_file, line) + prefix = f"{LOG_COLORS.INVERT}{mode[1]}[{mode[0].upper()}]{LOG_COLORS.RESET_INVERT}" + message = message + LOG_COLORS.RESET + context = f"{context.function} at {source_file}:{line}" + return f"{prefix} {message} ({context})" + + +def log_qt_debug(mode: QtMsgType, context: QMessageLogContext, message: str): + """ + Parses and renders qt log messages. + """ + print(create_log_terminal_message(mode, context, message)) + def setup(): global SOURCEMAP_INDEX - with open(SOURECMAP_PATH, "r") as f: - SOURCEMAP_INDEX = loads(f.read()) - qInstallMessageHandler(log_qt_debug) + try: + with open(SOURCEMAP_PATH, "r") as f: + from sourcemap import loads + SOURCEMAP_INDEX = loads(f.read()) + except Exception as e: + log_qt_debug(QtMsgType.QtWarningMsg, QMessageLogContext(), + f"Could not setup JavaScript source mapper in logs: {repr(e)}") + qInstallMessageHandler(log_qt_debug) diff --git a/README.md b/README.md index e368435..8402402 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,19 @@ You can find more screenshots on the [app's website](https://apps.ad5001.eu/logarithmplotter/). -## Run +## Build & Run -You can simply run LogarithmPlotter using `python3 run.py`. +First, you'll need to install all the required dependencies: + +- [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and setup a virtual environment and call + `poetry install`. +- [npm](https://npmjs.com) (or [yarn](https://yarnpkg.com/)), and run `npm install` (or `yarn install`). + +You can simply run LogarithmPlotter using `python3 run.py`. It automatically compiles the language files (requires +`lrelease` to be installed and in path), and the JavaScript modules. + +If you do not wish do recompile the files again on every run, you can use +`python3 LogarithmPlotter/logarithmplotter.py`. In order to test translations, you can use the `--lang=` commandline option to force the locale. @@ -27,9 +37,7 @@ In order to test translations, you can use the `--lang=` commandline All scripts noted here can be found in the `scripts` directory. -You can generate installers for LogarithmPlotter after installing all the dependencies: -For all builds, you will need [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and -`poetry install --with packaging`. +You can generate installers for LogarithmPlotter after installing all the dependencies. - Windows installer: - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an diff --git a/tests/python/test_debug.py b/tests/python/test_debug.py new file mode 100644 index 0000000..24261aa --- /dev/null +++ b/tests/python/test_debug.py @@ -0,0 +1,68 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +import pytest + +from os.path import exists +from PySide6.QtCore import QtMsgType, QMessageLogContext + +from LogarithmPlotter.util import debug + + +def test_setup(): + sourcemap_installed = False + try: + import sourcemap + sourcemap_installed = True + except: + pass + if sourcemap_installed: + file = debug.SOURCEMAP_PATH + debug.SOURCEMAP_PATH = None + debug.setup() # Nothing could be setup. + debug.SOURCEMAP_PATH = file + debug.setup() + assert (sourcemap_installed and exists(debug.SOURCEMAP_PATH)) == (debug.SOURCEMAP_INDEX is not None) + + +def test_map_source(): + sourcemap_available = debug.SOURCEMAP_INDEX is not None + if sourcemap_available: + assert debug.map_javascript_source("js/index.mjs", 21) == ("js/module/interface.mjs", 21) + assert debug.map_javascript_source("js/index.mjs", 100000) == ("js/index.mjs", 100000) # Too long, not found + debug.SOURCEMAP_INDEX = None + assert debug.map_javascript_source("js/index.mjs", 21) == ("js/index.mjs", 21) + + +def test_log_terminal_message(): + msg1 = debug.create_log_terminal_message( + QtMsgType.QtWarningMsg, QMessageLogContext(), + "a long and random message" + ) + assert "[WARNING]" in msg1 + assert "a long and random message" in msg1 + msg2 = debug.create_log_terminal_message( + QtMsgType.QtCriticalMsg, + QMessageLogContext("LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Index.qml", 15, "anotherFunctionName", + "aCategoryDifferent"), + "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Index.qml:15: a potentially potential error message" + ) + assert "[CRITICAL]" in msg2 + assert "Index.qml" in msg2 + assert "a potentially potential error message" in msg2 + assert "anotherFunctionName" in msg2 From b5bdbb6294d7357676fccdc828cde7faff96a2e2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 03:24:57 +0200 Subject: [PATCH 139/249] Adding building for JS --- ci/drone.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ci/drone.yml b/ci/drone.yml index 60fadf8..7cab87b 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -11,6 +11,17 @@ steps: commands: - git submodule update --init --recursive + - name: Build + image: node:18-bookworm + commands: + - npm install + - apt install -y qtchooser qttools5-dev-tools + # Start building + - cd LogarithmPlotter/i18n && bash release.sh && cd ../.. + - npm run build + when: + event: [ push, tag ] + - name: Unit Tests image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: From 4a1b333198ce9ec3479b3383ec245272017706f0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 03:26:41 +0200 Subject: [PATCH 140/249] Updating APT before installing in CI --- ci/drone.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/drone.yml b/ci/drone.yml index 7cab87b..828fc79 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -15,6 +15,7 @@ steps: image: node:18-bookworm commands: - npm install + - apt update - apt install -y qtchooser qttools5-dev-tools # Start building - cd LogarithmPlotter/i18n && bash release.sh && cd ../.. From 49aa23de92ac011bc0f8025b194b33e0c838ce77 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 03:28:41 +0200 Subject: [PATCH 141/249] Removing the need for releasing translations after building --- ci/drone.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 828fc79..b79c656 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -26,8 +26,6 @@ steps: - name: Unit Tests image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: - - apt install -y qtchooser qttools5-dev-tools - - cd LogarithmPlotter/i18n && bash release.sh && cd ../.. - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] From 95b47effdf14c62aaa61c2897f5304f61431773e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 22:36:42 +0200 Subject: [PATCH 142/249] Removing unique file dependencies in QML, removing comments from JS Builds (except first one, ~-30% build size) --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 4 +- .../LogarithmPlotter/History/History.qml | 8 +- .../History/HistoryBrowser.qml | 1 - .../LogarithmPlotter/History/HistoryItem.qml | 1 - .../LogarithmPlotter/LogGraphCanvas.qml | 2 - .../LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 25 +++--- .../ObjectLists/Editor/Dialog.qml | 8 +- .../ObjectLists/ObjectCreationGrid.qml | 4 +- .../ObjectLists/ObjectRow.qml | 8 +- .../LogarithmPlotter/PickLocationOverlay.qml | 11 ++- .../LogarithmPlotter/Popup/Preferences.qml | 7 +- .../Setting/ExpressionEditor.qml | 52 ++++++------ .../eu/ad5001/LogarithmPlotter/Settings.qml | 6 +- .../ViewPositionChangeOverlay.qml | 2 - .../ad5001/LogarithmPlotter/js/autoload.mjs | 11 ++- .../LogarithmPlotter/js/module/interface.mjs | 30 ++++--- .../js/parsing/{parsing.mjs => index.mjs} | 2 +- .../LogarithmPlotter/js/parsing/tokenizer.mjs | 2 +- LogarithmPlotter/util/update.py | 1 - package-lock.json | 82 ++++++++++++++++++- package.json | 3 +- rollup.config.mjs | 2 + tests/python/test_debug.py | 2 +- 24 files changed, 176 insertions(+), 100 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{parsing.mjs => index.mjs} (96%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index d0c2621..f26fd5b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -20,7 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import "js/history/index.mjs" as HistoryLib +import "js/index.mjs" as JS /*! @@ -119,7 +119,7 @@ MenuBar { icon.color: sysPalette.buttonText onTriggered: { var newObj = Modules.Objects.createNewRegisteredObject(modelData) - history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) + history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 85abbc7..47db5f3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -19,7 +19,7 @@ import QtQuick import QtQml import QtQuick.Window -import "../js/history/index.mjs" as HistoryLib +import "../js/index.mjs" as JS /*! \qmltype History @@ -97,9 +97,9 @@ Item { function unserialize(undoSt, redoSt) { clear(); for(let i = 0; i < undoSt.length; i++) - undoStack.push(new HistoryLib.Actions[undoSt[i][0]](...undoSt[i][1])) + undoStack.push(new JS.HistoryLib.Actions[undoSt[i][0]](...undoSt[i][1])) for(let i = 0; i < redoSt.length; i++) - redoStack.push(new HistoryLib.Actions[redoSt[i][0]](...redoSt[i][1])) + redoStack.push(new JS.HistoryLib.Actions[redoSt[i][0]](...redoSt[i][1])) undoCount = undoSt.length; redoCount = redoSt.length; objectLists.update() @@ -110,7 +110,7 @@ Item { Adds an instance of HistoryLib.Action to history. */ function addToHistory(action) { - if(action instanceof HistoryLib.Action) { + if(action instanceof JS.HistoryLib.Action) { console.log("Added new entry to history: " + action.getReadableString()) undoStack.push(action) undoCount++; diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 3fa37f8..926b42a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -19,7 +19,6 @@ import QtQuick.Controls import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/utils.mjs" as Utils /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 41d0015..f1e20a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -19,7 +19,6 @@ import QtQuick.Controls import QtQuick import Qt5Compat.GraphicalEffects -import "../js/utils.mjs" as Utils import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index e54781f..38d05be 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -18,8 +18,6 @@ import QtQuick import Qt.labs.platform as Native -import "js/utils.mjs" as Utils -import "js/math/index.mjs" as MathLib /*! \qmltype LogGraphCanvas diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index e06aeba..e41aa24 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/index.mjs" as ModulesAutoload +import "js/index.mjs" as JS import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 361dcbf..57ea4ae 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -20,9 +20,7 @@ import QtQuick import QtQuick.Controls import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../../js/history/index.mjs" as HistoryLib -import "../../js/utils.mjs" as Utils -import "../../js/math/index.mjs" as MathLib +import "../../js/index.mjs" as JS /*! \qmltype CustomPropertyList @@ -77,12 +75,12 @@ Repeater { height: 30 label: propertyLabel icon: `settings/custom/${propertyIcon}.svg` - defValue: Utils.simplifyExpression(obj[propertyName].toEditableString()) + defValue: JS.Utils.simplifyExpression(obj[propertyName].toEditableString()) self: obj.name variables: propertyType.variables onChanged: function(newExpr) { if(obj[propertyName].toString() != newExpr.toString()) { - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newExpr )) @@ -117,7 +115,7 @@ Repeater { onChanged: function(newValue) { try { var newValueParsed = { - "Domain": () => MathLib.parseDomain(newValue), + "Domain": () => JS.MathLib.parseDomain(newValue), "string": () => newValue, "number": () => newValue, "int": () => newValue @@ -125,7 +123,7 @@ Repeater { // Ensuring old and new values are different to prevent useless adding to history. if(obj[propertyName] != newValueParsed) { - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newValueParsed )) @@ -170,7 +168,7 @@ Repeater { return obj[propertyName] } onClicked: { - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], this.checked )) @@ -211,7 +209,7 @@ Repeater { if(selectedObj == null) { // Creating new object. selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType) - history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) + history.addToHistory(new JS.HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) baseModel = Modules.Objects.getObjectsName(propertyType.objType).concat( isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) @@ -221,14 +219,14 @@ Repeater { //Modules.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], selectedObj )) obj[propertyName] = selectedObj } else if(baseModel[newIndex] != obj[propertyName]) { // Ensuring new property is different to not add useless history entries. - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], baseModel[newIndex] )) @@ -258,11 +256,10 @@ Repeater { onChanged: { var exported = exportModel() - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], exported )) - //Modules.Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported root.changed() } @@ -284,7 +281,7 @@ Repeater { property string propertyName: modelData[0] property var propertyType: modelData[1] property string propertyLabel: qsTranslate('prop',propertyName) - property string propertyIcon: Utils.camelCase2readable(propertyName) + property string propertyIcon: JS.Utils.camelCase2readable(propertyName) sourceComponent: { if(propertyName.startsWith('comment')) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 7a357b3..e2b149b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -22,9 +22,7 @@ import QtQuick.Dialogs as D import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "../../js/history/index.mjs" as HistoryLib -import "../../js/utils.mjs" as Utils -import "../../js/math/index.mjs" as MathLib +import "../../js/index.mjs" as JS /*! \qmltype Dialog @@ -109,12 +107,12 @@ Popup.BaseDialog { width: dlgProperties.width value: objEditor.obj.name onChanged: function(newValue) { - let newName = Utils.parseName(newValue) + let newName = JS.Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { if(newName in Modules.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { - history.addToHistory(new HistoryLib.NameChanged( + history.addToHistory(new JS.HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) Modules.Objects.renameObject(obj.name, newName) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 3d0a56a..7aa9574 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -18,8 +18,8 @@ import QtQuick import QtQuick.Controls -import "../js/history/index.mjs" as HistoryLib import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../js/index.mjs" as JS /*! @@ -104,7 +104,7 @@ Column { onClicked: { let newObj = Modules.Objects.createNewRegisteredObject(modelData) - history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) + history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() let hasXProp = newObj.constructor.properties().hasOwnProperty('x') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 2dcd5c0..9118d09 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -21,7 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/history/index.mjs" as HistoryLib +import "../js/index.mjs" as JS /*! @@ -72,7 +72,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 5 onClicked: { - history.addToHistory(new HistoryLib.EditedVisibility( + history.addToHistory(new JS.HistoryLib.EditedVisibility( obj.name, obj.type, this.checked )) obj.visible = this.checked @@ -212,7 +212,7 @@ Item { selectedColor: obj.color title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name) onAccepted: { - history.addToHistory(new HistoryLib.ColorChanged( + history.addToHistory(new JS.HistoryLib.ColorChanged( obj.name, obj.type, obj.color, selectedColor.toString() )) obj.color = selectedColor.toString() @@ -231,7 +231,7 @@ Item { // Object still exists // Temporary fix for objects require not being propertly updated. object.requiredBy = [] - history.addToHistory(new HistoryLib.DeleteObject( + history.addToHistory(new JS.HistoryLib.DeleteObject( object.name, object.type, object.export() )) Modules.Objects.deleteObject(object.name) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index cecdf13..2fb45d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -19,8 +19,7 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/math/index.mjs" as MathLib -import "js/history/index.mjs" as HistoryLib +import "js/index.mjs" as JS /*! \qmltype PickLocationOverlay @@ -116,7 +115,7 @@ Item { let obj = Modules.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { - history.addToHistory(new HistoryLib.EditedPosition( + history.addToHistory(new JS.HistoryLib.EditedPosition( objName, objType, obj[propertyX], newValueX, obj[propertyY], newValueY )) obj[propertyX] = newValueX @@ -125,7 +124,7 @@ Item { objectLists.update() pickerRoot.picked(obj) } else if(parent.userPickX) { - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( objName, objType, propertyX, obj[propertyX], newValueX )) obj[propertyX] = newValueX @@ -133,7 +132,7 @@ Item { objectLists.update() pickerRoot.picked(obj) } else if(parent.userPickY) { - history.addToHistory(new HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValueY )) obj[propertyY] = newValueY @@ -327,6 +326,6 @@ Item { if(Modules.Objects.types[objType].properties()[propertyName] == 'number') return parseFloat(value) else - return new MathLib.Expression(value) + return new JS.MathLib.Expression(value) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 44b1c8f..a76410f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -20,8 +20,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/preferences/common.mjs" as S -import "../js/utils.mjs" as Utils +import "../js/index.mjs" as JS /*! \qmltype Preferences @@ -77,7 +76,7 @@ Popup { currentIndex: find(setting.value()) model: setting.defaultValues onAccepted: function() { - editText = Utils.parseName(editText, false) + editText = JS.Utils.parseName(editText, false) if(find(editText) === -1) model.append(editText) setting.set(editText) } @@ -116,7 +115,7 @@ Popup { height: 30 label: setting.name icon: `settings/${setting.icon}.svg` - defValue: Utils.simplifyExpression(setting.value()) + defValue: JS.Utils.simplifyExpression(setting.value()) variables: setting.variables allowGraphObjects: false property string propertyName: setting.name diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 6a17423..14d78ab 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -20,9 +20,7 @@ import QtQuick.Controls import QtQuick import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P -import "../js/math/index.mjs" as MathLib -import "../js/utils.mjs" as Utils -import "../js/parsing/parsing.mjs" as Parsing +import "../js/index.mjs" as JS /*! @@ -319,9 +317,9 @@ Item { width: parent.width readonly property var identifierTokenTypes: [ - Parsing.TokenType.VARIABLE, - Parsing.TokenType.FUNCTION, - Parsing.TokenType.CONSTANT + JS.Parsing.TokenType.VARIABLE, + JS.Parsing.TokenType.FUNCTION, + JS.Parsing.TokenType.CONSTANT ] property var currentToken: generateTokenInformation(getTokenAt(editor.tokens, editor.cursorPosition)) property var previousToken: generateTokenInformation(getPreviousToken(currentToken.token)) @@ -346,7 +344,7 @@ Item { 'value': exists ? token.value : null, 'type': exists ? token.type : null, 'startPosition': exists ? token.startPosition : 0, - 'dot': exists ? (token.type == Parsing.TokenType.PUNCT && token.value == ".") : false, + 'dot': exists ? (token.type == JS.Parsing.TokenType.PUNCT && token.value == ".") : false, 'identifier': exists ? identifierTokenTypes.includes(token.type) : false } } @@ -385,7 +383,7 @@ Item { */ function getPreviousToken(token) { let newToken = getTokenAt(editor.tokens, token.startPosition) - if(newToken != null && newToken.type == Parsing.TokenType.WHITESPACE) + if(newToken != null && newToken.type == JS.Parsing.TokenType.WHITESPACE) return getPreviousToken(newToken) return newToken } @@ -444,9 +442,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: variablesList.itemStartIndex + variablesList.model.length itemSelected: parent.itemSelected - categoryItems: Parsing.CONSTANTS_LIST + categoryItems: JS.Parsing.CONSTANTS_LIST autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Parsing.CONSTANTS[item], + 'text': item, 'annotation': JS.Parsing.CONSTANTS[item], 'autocomplete': item + " ", 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -459,9 +457,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: constantsList.itemStartIndex + constantsList.model.length itemSelected: parent.itemSelected - categoryItems: Parsing.FUNCTIONS_LIST + categoryItems: JS.Parsing.FUNCTIONS_LIST autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Parsing.FUNCTIONS_USAGE[item].join(', '), + 'text': item, 'annotation': JS.Parsing.FUNCTIONS_USAGE[item].join(', '), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -538,7 +536,7 @@ Item { function parse(newExpression) { let expr = null try { - expr = new MathLib.Expression(value.toString()) + expr = new JS.MathLib.Expression(value.toString()) // Check if the expression is valid, throws error otherwise. if(!expr.allRequirementsFullfilled()) { let undefVars = expr.undefinedVariables() @@ -572,7 +570,7 @@ Item { Generates a list of tokens from the given. */ function tokens(text) { - let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false) + let tokenizer = new JS.Parsing.Tokenizer(new JS.Parsing.Input(text), true, false) let tokenList = [] let token while((token = tokenizer.next()) != null) @@ -605,28 +603,28 @@ Item { let scheme = colorSchemes[Helper.getSettingInt("expression_editor.color_scheme")] for(let token of tokenList) { switch(token.type) { - case Parsing.TokenType.VARIABLE: + case JS.Parsing.TokenType.VARIABLE: parsedText += `${token.value}` break; - case Parsing.TokenType.CONSTANT: + case JS.Parsing.TokenType.CONSTANT: parsedText += `${token.value}` break; - case Parsing.TokenType.FUNCTION: - parsedText += `${Utils.escapeHTML(token.value)}` + case JS.Parsing.TokenType.FUNCTION: + parsedText += `${JS.Utils.escapeHTML(token.value)}` break; - case Parsing.TokenType.OPERATOR: - parsedText += `${Utils.escapeHTML(token.value)}` + case JS.Parsing.TokenType.OPERATOR: + parsedText += `${JS.Utils.escapeHTML(token.value)}` break; - case Parsing.TokenType.NUMBER: - parsedText += `${Utils.escapeHTML(token.value)}` + case JS.Parsing.TokenType.NUMBER: + parsedText += `${JS.Utils.escapeHTML(token.value)}` break; - case Parsing.TokenType.STRING: - parsedText += `${token.limitator}${Utils.escapeHTML(token.value)}${token.limitator}` + case JS.Parsing.TokenType.STRING: + parsedText += `${token.limitator}${JS.Utils.escapeHTML(token.value)}${token.limitator}` break; - case Parsing.TokenType.WHITESPACE: - case Parsing.TokenType.PUNCT: + case JS.Parsing.TokenType.WHITESPACE: + case JS.Parsing.TokenType.PUNCT: default: - parsedText += Utils.escapeHTML(token.value).replace(/ /g, ' ') + parsedText += JS.Utils.escapeHTML(token.value).replace(/ /g, ' ') break; } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 3c6e994..7ba80aa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -20,7 +20,7 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "js/utils.mjs" as Utils +import "js/index.mjs" as JS /*! \qmltype Settings @@ -330,7 +330,7 @@ ScrollView { currentIndex: find(settings.xlabel) editable: true onAccepted: function(){ - editText = Utils.parseName(editText, false) + editText = JS.Utils.parseName(editText, false) if (find(editText) === -1) model.append({text: editText}) settings.xlabel = editText settings.changed() @@ -359,7 +359,7 @@ ScrollView { currentIndex: find(settings.ylabel) editable: true onAccepted: function(){ - editText = Utils.parseName(editText, false) + editText = JS.Utils.parseName(editText, false) if (find(editText) === -1) model.append({text: editText, yaxisstep: root.yaxisstep}) settings.ylabel = editText settings.changed() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index b06fbcf..e8514d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -19,8 +19,6 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/math/index.mjs" as MathLib -import "js/history/index.mjs" as HistoryLib /*! \qmltype ViewPositionChangeOverlay diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs index 085a5c5..2507d88 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -25,3 +25,8 @@ import * as History from "./module/history.mjs" import * as CanvasAPI from "./module/canvas.mjs" import * as IOAPI from "./module/io.mjs" import * as PreferencesAPI from "./module/preferences.mjs" + +export * as MathLib from "./math/index.mjs" +export * as HistoryLib from "./history/index.mjs" +export * as Parsing from "./parsing/index.mjs" +export * as Utils from "./utils.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs index 7bda424..63ba88c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -1,19 +1,23 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 +/*! + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * + * @author Ad5001 + * @license GPL-3.0-or-later + * @copyright (C) 2021-2024 Ad5001 + * @preserve * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ export const NUMBER = 0 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/index.mjs similarity index 96% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/index.mjs index a9dba98..6d0de80 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/index.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import * as Reference from "reference.mjs" +import * as Reference from "./reference.mjs" import * as T from "./tokenizer.mjs" import InputExpression from "./common.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs index bad6e7e..2dd8620 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs @@ -17,7 +17,7 @@ */ -import * as Reference from "reference.mjs" +import * as Reference from "./reference.mjs" const WHITESPACES = " \t\n\r" const STRING_LIMITERS = '"\'`'; diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 32017d5..1d2ecec 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -78,7 +78,6 @@ def check_for_updates(current_version, window): return def cb(show_alert, msg_text, update_available): - pass if show_alert: window.showAlert(msg_text) if update_available: diff --git a/package-lock.json b/package-lock.json index 6b68c5d..1232c01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", "install": "^0.13.0", - "rollup": "^4.22.4" + "rollup": "^4.22.4", + "rollup-plugin-cleanup": "^3.2.1" } }, "node_modules/@ampproject/remapping": { @@ -2476,6 +2477,29 @@ "@types/estree": "*" } }, + "node_modules/js-cleanup": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", + "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==", + "license": "MIT", + "dependencies": { + "magic-string": "^0.25.7", + "perf-regexes": "^1.0.1", + "skip-regex": "^1.0.2" + }, + "engines": { + "node": "^10.14.2 || >=12.0.0" + } + }, + "node_modules/js-cleanup/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2549,6 +2573,15 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/perf-regexes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", + "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", + "license": "MIT", + "engines": { + "node": ">=6.14" + } + }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", @@ -2700,6 +2733,37 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-cleanup": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz", + "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==", + "license": "MIT", + "dependencies": { + "js-cleanup": "^1.2.0", + "rollup-pluginutils": "^2.8.2" + }, + "engines": { + "node": "^10.14.2 || >=12.0.0" + }, + "peerDependencies": { + "rollup": ">=2.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "license": "MIT", + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "license": "MIT" + }, "node_modules/rollup/node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -2744,6 +2808,15 @@ "randombytes": "^2.1.0" } }, + "node_modules/skip-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", + "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", + "license": "MIT", + "engines": { + "node": ">=4.2" + } + }, "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", @@ -2769,6 +2842,13 @@ "node": ">=0.10.0" } }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "license": "MIT" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 54ad9d9..78fad44 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", "install": "^0.13.0", - "rollup": "^4.22.4" + "rollup": "^4.22.4", + "rollup-plugin-cleanup": "^3.2.1" } } diff --git a/rollup.config.mjs b/rollup.config.mjs index 4a32424..4b4a305 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -19,6 +19,7 @@ import { nodeResolve } from "@rollup/plugin-node-resolve" import commonjs from "@rollup/plugin-commonjs" import { babel } from "@rollup/plugin-babel" +import cleanup from "rollup-plugin-cleanup" import terser from "@rollup/plugin-terser" const path = "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js" @@ -34,6 +35,7 @@ export default { plugins: [ nodeResolve({ browser: true }), commonjs(), + cleanup({ comments: 'some' }), babel({ babelHelpers: "bundled" }), diff --git a/tests/python/test_debug.py b/tests/python/test_debug.py index 24261aa..e8fd98c 100644 --- a/tests/python/test_debug.py +++ b/tests/python/test_debug.py @@ -43,7 +43,7 @@ def test_setup(): def test_map_source(): sourcemap_available = debug.SOURCEMAP_INDEX is not None if sourcemap_available: - assert debug.map_javascript_source("js/index.mjs", 21) == ("js/module/interface.mjs", 21) + assert debug.map_javascript_source("js/index.mjs", 22) == ("js/module/interface.mjs", 23) assert debug.map_javascript_source("js/index.mjs", 100000) == ("js/index.mjs", 100000) # Too long, not found debug.SOURCEMAP_INDEX = None assert debug.map_javascript_source("js/index.mjs", 21) == ("js/index.mjs", 21) From 850d0762687ab719ad3c42b7e8997dcfc9db40b0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 23:16:58 +0200 Subject: [PATCH 143/249] Using more modern ECMAScript --- .../LogarithmPlotter/js/history/common.mjs | 20 ++--- .../js/history/editproperty.mjs | 28 +++---- .../LogarithmPlotter/js/history/position.mjs | 25 +++--- .../LogarithmPlotter/js/module/interface.mjs | 83 ++++++++----------- .../ad5001/LogarithmPlotter/js/module/io.mjs | 2 +- .../LogarithmPlotter/js/module/latex.mjs | 20 +---- 6 files changed, 67 insertions(+), 111 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 41d28ce..9e59376 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -85,20 +85,16 @@ export class Action { * @param {string} latexString - Source string of the latex. * @returns {Promise} */ - renderLatexAsHtml(latexString) { + async renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - return new Promise(resolve => { - let imgDepth = History.imageDepth - Latex.requestAsyncRender( - latexString, - imgDepth * (History.fontSize + 2), - History.themeTextColor - ).then((imgData) => { - const { source, width, height } = imgData - resolve(``) - }) - }) + const imgDepth = History.imageDepth + const { source, width, height } = await Latex.requestAsyncRender( + latexString, + imgDepth * (History.fontSize + 2), + History.themeTextColor + ) + return `` } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index c4b9217..93cc680 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -138,22 +138,16 @@ export default class EditedProperty extends Action { * * @return {Promise|string} */ - getHTMLString() { - return new Promise(resolve => { - const translation = qsTranslate("editproperty", '%1 of %2 changed from %3 to %4.') - .arg(this.targetPropertyReadable) - .arg(' ' + this.targetName + ' ') - // Check if we need to wait for LaTeX HTML to be rendered. - if(this.prevHTML !== undefined && this.nextHTML !== undefined) - resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) - else - Promise.all(this._renderPromises).then((rendered) => { - // Rendered are (potentially) two HTML strings which are defined during rendering - this.prevHTML = this.prevHTML ?? rendered[0] - this.nextHTML = this.prevHTML ?? rendered[1] - resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) - }) - }) - + async getHTMLString() { + const translation = qsTranslate("editproperty", '%1 of %2 changed from %3 to %4.') + .arg(this.targetPropertyReadable) + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML === undefined || this.nextHTML === undefined) { + const [prevHTML, nextHTML] = await Promise.all(this._renderPromises) + this.prevHTML = this.prevHTML ?? prevHTML + this.nextHTML = this.nextHTML ?? nextHTML + } + return translation.arg(this.prevHTML).arg(this.nextHTML) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index 1671036..b84c18b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -89,21 +89,16 @@ export default class EditedPosition extends Action { .arg(this.targetName).arg(this.prevString).arg(this.nextString) } - getHTMLString() { - return new Promise(resolve => { - const translation = qsTranslate("position", 'Position of %1 set from %2 to %3.') - .arg(' ' + this.targetName + ' ') - // Check if we need to wait for LaTeX HTML to be rendered. - if(this.prevHTML !== undefined && this.nextHTML !== undefined) - resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) - else - Promise.all(this._renderPromises).then((rendered) => { - // Rendered are (potentially) two HTML strings which are defined during rendering - this.prevHTML = this.prevHTML ?? rendered[0] - this.nextHTML = this.nextHTML ?? rendered[1] - resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) - }) - }) + async getHTMLString() { + const translation = qsTranslate("position", 'Position of %1 set from %2 to %3.') + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML === undefined || this.nextHTML === undefined) { + const [prevHTML, nextHTML] = await Promise.all(this._renderPromises) + this.prevHTML = this.prevHTML ?? prevHTML + this.nextHTML = this.nextHTML ?? nextHTML + } + return translation.arg(this.prevHTML).arg(this.nextHTML) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs index 63ba88c..37f4f5b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -69,65 +69,50 @@ export class Interface { export class SettingsInterface extends Interface { - constructor() { - super() - this.width = NUMBER - this.height = NUMBER - this.xmin = NUMBER - this.ymax = NUMBER - this.xzoom = NUMBER - this.yzoom = NUMBER - this.xaxisstep = STRING - this.yaxisstep = STRING - this.xlabel = STRING - this.ylabel = STRING - this.linewidth = NUMBER - this.textsize = NUMBER - this.logscalex = BOOLEAN - this.showxgrad = BOOLEAN - this.showygrad = BOOLEAN - } + width = NUMBER + height = NUMBER + xmin = NUMBER + ymax = NUMBER + xzoom = NUMBER + yzoom = NUMBER + xaxisstep = STRING + yaxisstep = STRING + xlabel = STRING + ylabel = STRING + linewidth = NUMBER + textsize = NUMBER + logscalex = BOOLEAN + showxgrad = BOOLEAN + showygrad = BOOLEAN } export class CanvasInterface extends SettingsInterface { - constructor() { - super() - this.imageLoaders = OBJECT - /** @type {function(string): CanvasRenderingContext2D} */ - this.getContext = FUNCTION - /** @type {function(rect)} */ - this.markDirty = FUNCTION - /** @type {function(string)} */ - this.loadImage = FUNCTION - /** @type {function()} */ - this.requestPaint = FUNCTION - } + imageLoaders = OBJECT + /** @type {function(string): CanvasRenderingContext2D} */ + getContext = FUNCTION + /** @type {function(rect)} */ + markDirty = FUNCTION + /** @type {function(string)} */ + loadImage = FUNCTION + /** @type {function()} */ + requestPaint = FUNCTION } export class RootInterface extends Interface { - constructor() { - super() - this.width = NUMBER - this.height = NUMBER - this.updateObjectsLists = FUNCTION - } + width = NUMBER + height = NUMBER + updateObjectsLists = FUNCTION } export class DialogInterface extends Interface { - constructor() { - super() - this.show = FUNCTION - } + show = FUNCTION } export class HistoryInterface extends Interface { - constructor() { - super() - this.undo = FUNCTION - this.redo = FUNCTION - this.clear = FUNCTION - this.addToHistory = FUNCTION - this.unserialize = FUNCTION - this.serialize = FUNCTION - } + undo = FUNCTION + redo = FUNCTION + clear = FUNCTION + addToHistory = FUNCTION + unserialize = FUNCTION + serialize = FUNCTION } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index 11ac25f..d4ff50c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -97,7 +97,7 @@ class IOAPI extends Module { * Loads the diagram from a certain \c filename. * @param {string} filename */ - loadDiagram(filename) { + async loadDiagram(filename) { if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!") if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!") let basename = filename.split("/").pop() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs index f2e9b0b..0071779 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs @@ -65,19 +65,6 @@ class LatexAPI extends Module { this.enabled = Helper.getSettingBool("enable_latex") } - /** - * Prepares and renders a latex string into a png file. - * - * @param {string} markup - LaTeX markup to render. - * @param {number} fontSize - Font size (in pt) to render. - * @param {color} color - Color of the text to render. - * @returns {LatexRenderResult} - */ - renderSync(markup, fontSize, color) { - let args = Latex.render(markup, fontSize, color).split(",") - return new LatexRenderResult(...args) - } - /** * Checks if the given markup (with given font size and color) has already been * rendered, and if so, returns its data. Otherwise, returns null. @@ -103,10 +90,9 @@ class LatexAPI extends Module { * @param {color} color - Color of the text to render. * @returns {Promise} */ - requestAsyncRender(markup, fontSize, color) { - return new Promise(resolve => { - resolve(this.renderSync(markup, fontSize, color)) - }) + async requestAsyncRender(markup, fontSize, color) { + let args = Latex.render(markup, fontSize, color).split(",") + return new LatexRenderResult(...args) } /** From 8cefc56ac797512ef2c900d3710c53cbd018534a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 27 Sep 2024 02:34:42 +0200 Subject: [PATCH 144/249] Adding JS polyfills to avoid issues because core-js does not deal well with the environment it's given. --- .../ad5001/LogarithmPlotter/js/autoload.mjs | 2 + .../js/lib/expr-eval/expression.mjs | 5 +- .../LogarithmPlotter/js/lib/polyfills/js.mjs | 126 ++++++++++++++++++ .../{qmlpolyfills.mjs => polyfills/qt.mjs} | 3 +- 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/{qmlpolyfills.mjs => polyfills/qt.mjs} (93%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs index 2507d88..47a9424 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +import js from "./lib/polyfills/js.mjs" + // Loading modules in order import * as Objects from "./module/objects.mjs" import * as ExprParser from "./module/expreval.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs index 57b4e0e..89831c7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs @@ -482,7 +482,7 @@ export class ExprEvalExpression { /** * Calculates the value of the expression by giving all variables and their corresponding values. - * @param {Object} values + * @param {Object} values * @returns {number} */ evaluate(values) { @@ -512,8 +512,7 @@ export class ExprEvalExpression { * as constants or functions. * @returns {string[]} */ - variables(options) { - options = options || {} + variables(options = {}) { const vars = [] getSymbols(this.tokens, vars, options) const functions = this.functions diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs new file mode 100644 index 0000000..43ed375 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs @@ -0,0 +1,126 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// JS polyfills to add because they're not implemented in the QML Scripting engine. +// CoreJS does not work well with it (as well as doubles the compiled size), so this is preferable. +function notPolyfilled(name) { + return function() { throw new Error(`${name} not polyfilled`) } +} + +/** + * @param {number} depth + * @this {Array} + * @returns {Array} + */ +function arrayFlat(depth = 1) { + const newArray = [] + for(const element of this) { + if(element instanceof Array) + newArray.push(...(depth > 1 ? element.flat(depth - 1) : element)) + else + newArray.push(element) + } + return newArray +} + +/** + * @param {function(any, number, Array): any} callbackFn + * @param {object} thisArg + * @this {Array} + * @returns {Array} + */ +function arrayFlatMap(callbackFn, thisArg) { + const newArray = [] + for(let i = 0; i < this.length; i++) { + const value = callbackFn.call(thisArg ?? this, this[i], i, this) + if(value instanceof Array) + newArray.push(...value) + else + newArray.push(value) + } + return newArray +} + +/** + * Replaces all instances of from by to. + * @param {string} from + * @param {string} to + * @this {string} + * @return {String} + */ +function stringReplaceAll(from, to) { + let str = this + while(str.includes(from)) + str = str.replace(from, to) + return str +} + + +const polyfills = { + 2017: [ + [Object, "entries", notPolyfilled("Object.entries")], + [Object, "values", notPolyfilled("Object.values")], + [Object, "getOwnPropertyDescriptors", notPolyfilled("Object.getOwnPropertyDescriptors")], + [String.prototype, "padStart", notPolyfilled("String.prototype.padStart")], + [String.prototype, "padEnd", notPolyfilled("String.prototype.padEnd")] + ], + 2018: [ + [Promise.prototype, "finally", notPolyfilled("Object.entries")] + ], + 2019: [ + [String.prototype, "trimStart", notPolyfilled("String.prototype.trimStart")], + [String.prototype, "trimEnd", notPolyfilled("String.prototype.trimEnd")], + [Object, "fromEntries", notPolyfilled("Object.fromEntries")], + [Array.prototype, "flat", arrayFlat], + [Array.prototype, "flatMap", arrayFlatMap] + ], + 2020: [ + [String.prototype, "matchAll", notPolyfilled("String.prototype.matchAll")], + [Promise, "allSettled", notPolyfilled("Promise.allSettled")] + ], + 2021: [ + [Promise, "any", notPolyfilled("Promise.any")], + [String.prototype, "replaceAll", stringReplaceAll] + ], + 2022: [ + [Array.prototype, "at", notPolyfilled("Array.prototype.at")], + [String.prototype, "at", notPolyfilled("String.prototype.at")], + [Object, "hasOwn", notPolyfilled("Object.hasOwn")] + ], + 2023: [ + [Array.prototype, "findLast", notPolyfilled("Array.prototype.findLast")], + [Array.prototype, "toReversed", notPolyfilled("Array.prototype.toReversed")], + [Array.prototype, "toSorted", notPolyfilled("Array.prototype.toSorted")], + [Array.prototype, "toSpliced", notPolyfilled("Array.prototype.toSpliced")], + [Array.prototype, "with", notPolyfilled("Array.prototype.with")] + ], + 2024: [ + [Object, "groupBy", notPolyfilled("Object.groupBy")], + [Map, "groupBy", notPolyfilled("Map.groupBy")] + ] +} + +// Fulfill polyfill. +for(const [year, entries] of Object.entries(polyfills)) { + const defined = entries.filter(x => x[0][x[1]] !== undefined) + console.info(`ES${year} support: ${defined.length === entries.length} (${defined.length}/${entries.length})`) + // Apply polyfills + for(const [context, functionName, polyfill] of entries.filter(x => x[0][x[1]] === undefined)) { + context[functionName] = polyfill + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs index daefa6c..7cbb2f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs @@ -18,6 +18,7 @@ // Type polyfills for IDEs. // Never directly imported. +// Might need to be reimplemented in other implemententations. Modules = Modules || {} /** @type {function(string, string): string} */ @@ -25,7 +26,7 @@ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTra /** @type {function(string): string} */ qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } /** @type {function(string, string): string} */ -QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } +QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(category, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } /** @type {function(string): string} */ QT_TR_NOOP = QT_TR_NOOP || function(string) { throw new Error('QT_TR_NOOP not implemented.'); } /** @type {function(string|boolean|int): string} */ From c32d70e9ed3651cfa32be6754f6da2d47c1453d5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 27 Sep 2024 02:54:20 +0200 Subject: [PATCH 145/249] Reformatting JS files --- .../Setting/ExpressionEditor.qml | 2 +- .../LogarithmPlotter/js/history/color.mjs | 43 +-- .../LogarithmPlotter/js/history/common.mjs | 60 ++-- .../LogarithmPlotter/js/history/create.mjs | 42 +-- .../LogarithmPlotter/js/history/delete.mjs | 6 +- .../js/history/editproperty.mjs | 78 ++--- .../LogarithmPlotter/js/history/name.mjs | 5 +- .../LogarithmPlotter/js/history/position.mjs | 75 ++--- .../js/history/visibility.mjs | 44 +-- .../LogarithmPlotter/js/math/domain.mjs | 267 +++++++++--------- .../LogarithmPlotter/js/math/expression.mjs | 62 ++-- .../LogarithmPlotter/js/module/canvas.mjs | 4 +- .../LogarithmPlotter/js/module/common.mjs | 2 +- .../LogarithmPlotter/js/module/expreval.mjs | 2 +- .../LogarithmPlotter/js/module/history.mjs | 1 - .../LogarithmPlotter/js/module/interface.mjs | 4 + .../ad5001/LogarithmPlotter/js/module/io.mjs | 2 +- .../LogarithmPlotter/js/module/latex.mjs | 34 +-- .../LogarithmPlotter/js/module/objects.mjs | 35 +-- .../js/module/preferences.mjs | 10 +- .../LogarithmPlotter/js/objs/autoload.mjs | 6 +- .../js/objs/bodemagnitude.mjs | 105 ++++--- .../js/objs/bodemagnitudesum.mjs | 78 ++--- .../LogarithmPlotter/js/objs/bodephase.mjs | 93 +++--- .../LogarithmPlotter/js/objs/bodephasesum.mjs | 107 ++++--- .../LogarithmPlotter/js/objs/common.mjs | 260 +++++++++-------- .../LogarithmPlotter/js/objs/distribution.mjs | 132 +++++---- .../LogarithmPlotter/js/objs/function.mjs | 119 ++++---- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 80 +++--- .../LogarithmPlotter/js/objs/sequence.mjs | 103 ++++--- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 87 +++--- .../LogarithmPlotter/js/objs/xcursor.mjs | 33 +-- .../ad5001/LogarithmPlotter/js/parameters.mjs | 149 +++++----- .../LogarithmPlotter/js/parsing/common.mjs | 30 +- .../LogarithmPlotter/js/parsing/reference.mjs | 196 ++++++------- .../LogarithmPlotter/js/parsing/tokenizer.mjs | 124 ++++---- .../js/preferences/common.mjs | 22 +- .../js/preferences/default.mjs | 16 +- .../js/preferences/expression.mjs | 18 +- .../js/preferences/general.mjs | 12 +- .../eu/ad5001/LogarithmPlotter/js/utils.mjs | 23 +- LogarithmPlotter/util/debug.py | 2 +- package-lock.json | 138 --------- package.json | 1 - rollup.config.mjs | 4 - 45 files changed, 1390 insertions(+), 1326 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 14d78ab..afa3e09 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -538,7 +538,7 @@ Item { try { expr = new JS.MathLib.Expression(value.toString()) // Check if the expression is valid, throws error otherwise. - if(!expr.allRequirementsFullfilled()) { + if(!expr.allRequirementsFulfilled()) { let undefVars = expr.undefinedVariables() if(undefVars.length > 1) throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', '))) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index 51541b0..1d395ed 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -21,36 +21,41 @@ import Objects from "../module/objects.mjs" export default class ColorChanged extends EditedProperty { // Action used everytime when an object's color is changed - type(){return 'ColorChanged'} - - icon(){return 'appearance'} - - + type() { + return "ColorChanged" + } + + icon() { + return "appearance" + } + constructor(targetName = "", targetType = "Point", oldColor = "black", newColor = "white") { super(targetName, targetType, "color", oldColor, newColor) } - + export() { return [this.targetName, this.targetType, this.previousValue, this.newValue] } - - color(darkVer=false){return darkVer ? 'purple' : 'plum'} - + + color(darkVer = false) { + return darkVer ? "purple" : "plum" + } + getReadableString() { return qsTranslate("color", "%1 %2's color changed from %3 to %4.") - .arg(Objects.types[this.targetType].displayType()).arg(this.targetName) - .arg(this.previousValue).arg(this.newValue) + .arg(Objects.types[this.targetType].displayType()).arg(this.targetName) + .arg(this.previousValue).arg(this.newValue) } - + formatColor(color) { return `██` } - + getHTMLString() { return qsTranslate("color", "%1 %2's color changed from %3 to %4.") - .arg(Objects.types[this.targetType].displayType()) - .arg(' ' + this.targetName + " ") - .arg(this.formatColor(this.previousValue)).arg(this.formatColor(this.newValue)) + .arg(Objects.types[this.targetType].displayType()) + .arg(" " + this.targetName + " ") + .arg(this.formatColor(this.previousValue)).arg(this.formatColor(this.newValue)) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 9e59376..33f9118 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -22,66 +22,72 @@ import Latex from "../module/latex.mjs" export class Action { /** * Type of the action. - * + * * @returns {string} */ - type(){return 'Unknown'} - + type() { + return "Unknown" + } + /** * Icon associated with the action. - * + * * @returns {string} */ - icon(){return 'position'} - + icon() { + return "position" + } + // TargetName is the name of the object that's targeted by the event. constructor(targetName = "", targetType = "Point") { this.targetName = targetName this.targetType = targetType } - + /** * Undoes the action. */ - undo() {} - + undo() { + } + /** * Redoes the action. */ - redo() {} - + redo() { + } + /** * Export the action to a serializable format. * NOTE: These arguments will be reinputed in the constructor in this order. - * + * * @returns {string[]} */ export() { return [this.targetName, this.targetType] } - + /** - * Returns a string with the human readable description of the action. - * + * Returns a string with the human-readable description of the action. + * * @returns {string} */ getReadableString() { - return 'Unknown action' + return "Unknown action" } - + /** * Returns a string containing an HTML tag describing the icon of a type - * + * * @param {string} type - Name of the icon to put in rich text. * @returns {string} */ getIconRichText(type) { - return `` + return `` } - + /** * Renders a LaTeX-formatted string to an image and wraps it in an HTML tag in a string. - * + * * @param {string} latexString - Source string of the latex. * @returns {Promise} */ @@ -94,12 +100,12 @@ export class Action { imgDepth * (History.fontSize + 2), History.themeTextColor ) - return `` + return `` } - + /** * Returns a string with the HTML-formatted description of the action. - * + * * @returns {string|Promise} */ getHTMLString() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index 9f0fa52..1308d9e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -19,43 +19,51 @@ import Objects from "../module/objects.mjs" import { Action } from "./common.mjs" +/** + * Action used for the creation of an object. + */ export default class CreateNewObject extends Action { - // Action used for the creation of an object - type(){return 'CreateNewObject'} - - icon(){return 'create'} - - color(darkVer=false){return darkVer ? 'green' : 'lime'} - + type() { + return "CreateNewObject" + } + + icon() { + return "create" + } + + color(darkVer = false) { + return darkVer ? "green" : "lime" + } + constructor(targetName = "", targetType = "Point", properties = []) { super(targetName, targetType) this.targetProperties = properties } - + undo() { Objects.deleteObject(this.targetName) } - + redo() { Objects.createNewRegisteredObject(this.targetType, this.targetProperties) Objects.currentObjectsByName[this.targetName].update() } - + export() { return [this.targetName, this.targetType, this.targetProperties] } - + getReadableString() { return qsTranslate("create", "New %1 %2 created.") .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName) } - + getHTMLString() { return qsTranslate("create", "New %1 %2 created.") - .arg(Objects.types[this.targetType].displayType()) - .arg('' + this.targetName + "") + .arg(Objects.types[this.targetType].displayType()) + .arg("" + this.targetName + "") } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index 984b5c2..f9674c5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -20,10 +20,10 @@ import Objects from "../module/objects.mjs" import CreateNewObject from "./create.mjs" +/** + * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed. + */ export default class DeleteObject extends CreateNewObject { - /** - * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed. - */ type(){return 'DeleteObject'} icon(){return 'delete'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 93cc680..886f100 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -22,14 +22,20 @@ import * as MathLib from "../math/index.mjs" import { Action } from "./common.mjs" import { DrawableObject } from "../objs/common.mjs" +/** + * Action used everytime an object's property has been changed. + */ export default class EditedProperty extends Action { - // Action used everytime an object's property has been changed - type(){return 'EditedProperty'} - - icon(){return 'modify'} - - color(darkVer=false){ - return darkVer ? 'darkslateblue' : 'cyan'; + type() { + return "EditedProperty" + } + + icon() { + return "modify" + } + + color(darkVer = false) { + return darkVer ? "darkslateblue" : "cyan" } /** @@ -49,12 +55,12 @@ export default class EditedProperty extends Action { this.newValue = newValue this.propertyType = Objects.types[targetType].properties()[targetProperty] if(valueIsExpressionNeedingImport) { - if(typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { - this.previousValue = new MathLib.Expression(this.previousValue); - this.newValue = new MathLib.Expression(this.newValue); + if(typeof this.propertyType == "object" && this.propertyType.type === "Expression") { + this.previousValue = new MathLib.Expression(this.previousValue) + this.newValue = new MathLib.Expression(this.newValue) } else if(this.propertyType === "Domain") { - this.previousValue = MathLib.parseDomain(this.previousValue); - this.newValue = MathLib.parseDomain(this.newValue); + this.previousValue = MathLib.parseDomain(this.previousValue) + this.newValue = MathLib.parseDomain(this.newValue) } else { // Objects this.previousValue = Objects.currentObjectsByName[this.previousValue] // Objects.getObjectByName(this.previousValue); @@ -63,17 +69,17 @@ export default class EditedProperty extends Action { } this.setReadableValues() } - + undo() { Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.previousValue Objects.currentObjectsByName[this.targetName].update() } - + redo() { Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.newValue Objects.currentObjectsByName[this.targetName].update() } - + export() { if(this.previousValue instanceof MathLib.Expression) { return [this.targetName, this.targetType, this.targetProperty, this.previousValue.toEditableString(), this.newValue.toEditableString(), true] @@ -83,7 +89,7 @@ export default class EditedProperty extends Action { return [this.targetName, this.targetType, this.targetProperty, this.previousValue, this.newValue, false] } } - + setReadableValues() { this.prevString = "" this.nextString = "" @@ -93,45 +99,45 @@ export default class EditedProperty extends Action { case "Enum": this.prevString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.previousValue)] this.nextString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.newValue)] - break; + break case "ObjectType": this.prevString = this.previousValue == null ? "null" : this.previousValue.name this.nextString = this.newValue == null ? "null" : this.newValue.name - break; + break case "List": this.prevString = this.previousValue.join(",") this.nextString = this.newValue.name.join(",") - break; + break case "Dict": this.prevString = JSON.stringify(this.previousValue) this.nextString = JSON.stringify(this.newValue) - break; + break case "Expression": this.prevString = this.previousValue == null ? "null" : this.previousValue.toString() this.nextString = this.newValue == null ? "null" : this.newValue.toString() - break; + break } } else { this.prevString = this.previousValue == null ? "null" : this.previousValue.toString() this.nextString = this.newValue == null ? "null" : this.newValue.toString() } // HTML - this.prevHTML = ' '+this.prevString+' ' - this.nextHTML = ' '+this.nextString+' ' - if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { + this.prevHTML = " " + this.prevString + " " + this.nextHTML = " " + this.nextString + " " + if(Latex.enabled && typeof this.propertyType == "object" && this.propertyType.type === "Expression") { // Store promises so that querying can wait for them to finish. this._renderPromises = [ this.renderLatexAsHtml(this.previousValue.latexMarkup).then(prev => this.prevHTML = prev), - this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = prev) + this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = next) ] } } - + getReadableString() { - return qsTranslate("editproperty", '%1 of %2 %3 changed from "%4" to "%5".') - .arg(this.targetPropertyReadable) - .arg(Objects.types[this.targetType].displayType()) - .arg(this.targetName).arg(this.prevString).arg(this.nextString) + return qsTranslate("editproperty", "%1 of %2 %3 changed from \"%4\" to \"%5\".") + .arg(this.targetPropertyReadable) + .arg(Objects.types[this.targetType].displayType()) + .arg(this.targetName).arg(this.prevString).arg(this.nextString) } /** @@ -139,9 +145,9 @@ export default class EditedProperty extends Action { * @return {Promise|string} */ async getHTMLString() { - const translation = qsTranslate("editproperty", '%1 of %2 changed from %3 to %4.') - .arg(this.targetPropertyReadable) - .arg(' ' + this.targetName + ' ') + const translation = qsTranslate("editproperty", "%1 of %2 changed from %3 to %4.") + .arg(this.targetPropertyReadable) + .arg(" " + this.targetName + " ") // Check if we need to wait for LaTeX HTML to be rendered. if(this.prevHTML === undefined || this.nextHTML === undefined) { const [prevHTML, nextHTML] = await Promise.all(this._renderPromises) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index b2ce9f1..5c5b397 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -19,9 +19,10 @@ import EditedProperty from "./editproperty.mjs" import Objects from "../module/objects.mjs" - +/** + * Action used everytime an object's name has been changed. + */ export default class NameChanged extends EditedProperty { - // Action used everytime an object's property has been changed type(){return 'NameChanged'} icon(){return 'name'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index b84c18b..4c1af60 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -21,43 +21,48 @@ import Latex from "../module/latex.mjs" import * as MathLib from "../math/index.mjs" import { escapeHTML } from "../utils.mjs" import { Action } from "./common.mjs" -import { DrawableObject } from "../objs/common.mjs" +/** + * Action used for objects that have a X and Y expression properties (points, texts...) + */ export default class EditedPosition extends Action { - // Action used for objects that have a X and Y expression properties (points, texts...) - type(){return 'EditedPosition'} - - icon(){return 'position'} - - color(darkVer=false){ - return darkVer ? 'seagreen' : 'lightseagreen'; + type() { + return "EditedPosition" } - + + icon() { + return "position" + } + + color(darkVer = false) { + return darkVer ? "seagreen" : "lightseagreen" + } + constructor(targetName = "", targetType = "Point", previousXValue = "", newXValue = "", previousYValue = "", newYValue = "") { - super(targetName, targetType) + super(targetName, targetType) let imports = { - 'previousXValue': previousXValue, - 'previousYValue': previousYValue, - 'newXValue': newXValue, - 'newYValue': newYValue + "previousXValue": previousXValue, + "previousYValue": previousYValue, + "newXValue": newXValue, + "newYValue": newYValue } for(let name in imports) - this[name] = (typeof imports[name]) == 'string' ? new MathLib.Expression(imports[name]) : imports[name] + this[name] = (typeof imports[name]) == "string" ? new MathLib.Expression(imports[name]) : imports[name] this.setReadableValues() } - + undo() { Objects.currentObjectsByName[this.targetName].x = this.previousXValue Objects.currentObjectsByName[this.targetName].y = this.previousYValue Objects.currentObjectsByName[this.targetName].update() } - + redo() { Objects.currentObjectsByName[this.targetName].x = this.newXValue Objects.currentObjectsByName[this.targetName].y = this.newYValue Objects.currentObjectsByName[this.targetName].update() } - + setReadableValues() { this.prevString = `(${this.previousXValue.toString()},${this.previousYValue.toString()})` this.nextString = `(${this.newXValue.toString()},${this.newYValue.toString()})` @@ -71,27 +76,27 @@ export default class EditedPosition extends Action { this.renderLatexAsHtml(nextMarkup) ] } else { - this.prevHTML = ' '+escapeHTML(this.prevString)+' ' - this.nextHTML = ' '+escapeHTML(this.nextString)+' ' + this.prevHTML = " " + escapeHTML(this.prevString) + " " + this.nextHTML = " " + escapeHTML(this.nextString) + " " } - + } - + export() { return [this.targetName, this.targetType, - this.previousXValue.toEditableString(), this.newXValue.toEditableString(), - this.previousYValue.toEditableString(), this.newYValue.toEditableString()] + this.previousXValue.toEditableString(), this.newXValue.toEditableString(), + this.previousYValue.toEditableString(), this.newYValue.toEditableString()] } - + getReadableString() { - return qsTranslate("position", 'Position of %1 %2 set from "%3" to "%4".') - .arg(Objects.types[this.targetType].displayType()) - .arg(this.targetName).arg(this.prevString).arg(this.nextString) + return qsTranslate("position", "Position of %1 %2 set from \"%3\" to \"%4\".") + .arg(Objects.types[this.targetType].displayType()) + .arg(this.targetName).arg(this.prevString).arg(this.nextString) } - + async getHTMLString() { - const translation = qsTranslate("position", 'Position of %1 set from %2 to %3.') - .arg(' ' + this.targetName + ' ') + const translation = qsTranslate("position", "Position of %1 set from %2 to %3.") + .arg(" " + this.targetName + " ") // Check if we need to wait for LaTeX HTML to be rendered. if(this.prevHTML === undefined || this.nextHTML === undefined) { const [prevHTML, nextHTML] = await Promise.all(this._renderPromises) @@ -99,6 +104,6 @@ export default class EditedPosition extends Action { this.nextHTML = this.nextHTML ?? nextHTML } return translation.arg(this.prevHTML).arg(this.nextHTML) - + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index c66ade0..e911c1b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,36 +20,42 @@ import EditedProperty from "./editproperty.mjs" import Objects from "../module/objects.mjs" +/** + * Action used when an object's shown or hidden. + */ export default class EditedVisibility extends EditedProperty { - // Action used when an object's shown or hidden. - type(){return 'EditedVisibility'} - - icon(){return 'visibility'} - - color(darkVer=false){ - return this.newValue ? - (darkVer ? 'darkgray' : 'whitesmoke') : - (darkVer ? 'dimgray' : 'lightgray') + type() { + return "EditedVisibility" } - + + icon() { + return "visibility" + } + + color(darkVer = false) { + return this.newValue ? + (darkVer ? "darkgray" : "whitesmoke") : + (darkVer ? "dimgray" : "lightgray") + } + constructor(targetName = "", targetType = "Point", newValue = true) { super(targetName, targetType, "visible", !newValue, newValue) } - + export() { return [this.targetName, this.targetType, this.newValue] } - + getReadableString() { - return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.')) + return (this.newValue ? qsTranslate("visibility", "%1 %2 shown.") : qsTranslate("visibility", "%1 %2 hidden.")) .arg(Objects.types[this.targetType].displayType()) .arg(this.targetName) } - + getHTMLString() { - return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.')) + return (this.newValue ? qsTranslate("visibility", "%1 %2 shown.") : qsTranslate("visibility", "%1 %2 hidden.")) .arg(Objects.types[this.targetType].displayType()) - .arg('' + this.targetName + "") + .arg("" + this.targetName + "") } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index a9cefb5..846b66b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -23,35 +23,44 @@ import { Expression, executeExpression } from "./expression.mjs" * It doesn't represent any kind of domain and is meant to be extended. */ export class Domain { - constructor() {} - + constructor() { + } + /** * Checks whether x is included in the domain. * @param {number} x - The x value. * @return {boolean} true if included, false otherwise. */ - includes(x) { return false } - + includes(x) { + return false + } + /** * Returns a string representation of the domain. * @return {string} String representation of the domain. */ - toString() { return '???' } - + toString() { + return "???" + } + /** * Returns a new domain that is the union between this domain and another. * @param {Domain} domain - Domain to unionise with this. * @return {Domain} newly created domain. */ - union(domain) { return domain } - + union(domain) { + return domain + } + /** * Returns a new domain that is the intersection between this domain and another. * @param {Domain} domain - Domain to get the interscection with this. * @return {Domain} newly created domain. */ - intersection(domain) { return this } - + intersection(domain) { + return this + } + /** * Imports a domain from a string. * @return {Domain} Found domain, string otherwise. @@ -61,24 +70,20 @@ export class Domain { case "R": case "ℝ": return Domain.R - break; case "RE": case "R*": case "ℝ*": return Domain.RE - break; case "RP": case "R+": case "ℝ⁺": case "ℝ+": return Domain.RP - break; case "RM": case "R-": case "ℝ⁻": case "ℝ-": return Domain.RM - break; case "RPE": case "REP": case "R+*": @@ -88,7 +93,6 @@ export class Domain { case "ℝ*+": case "ℝ+*": return Domain.RPE - break; case "RME": case "REM": case "R-*": @@ -98,7 +102,6 @@ export class Domain { case "ℝ-*": case "ℝ*-": return Domain.RME - break; case "ℕ": case "N": case "ZP": @@ -106,12 +109,10 @@ export class Domain { case "ℤ⁺": case "ℤ+": return Domain.N - break; case "NLOG": case "ℕˡᵒᵍ": case "ℕLOG": return Domain.NLog - break; case "NE": case "NP": case "N*": @@ -128,17 +129,14 @@ export class Domain { case "ℤ+*": case "ℤ*+": return Domain.NE - break; case "Z": case "ℤ": return Domain.Z - break; case "ZM": case "Z-": case "ℤ⁻": case "ℤ-": return Domain.ZM - break; case "ZME": case "ZEM": case "Z-*": @@ -148,15 +146,12 @@ export class Domain { case "ℤ-*": case "ℤ*-": return Domain.ZME - break; case "ZE": case "Z*": case "ℤ*": return Domain.ZE - break; default: return Domain.EmptySet - break; } } } @@ -170,16 +165,26 @@ export class EmptySet extends Domain { this.displayName = "∅" this.latexMarkup = "\\emptyset" } - - includes(x) { return false } - - toString() { return this.displayName } - - union(domain) { return domain } - - intersection(domain) { return this } - - static import(frm) { return new EmptySet() } + + includes(x) { + return false + } + + toString() { + return this.displayName + } + + union(domain) { + return domain + } + + intersection(domain) { + return this + } + + static import(frm) { + return new EmptySet() + } } Domain.EmptySet = new EmptySet() // To prevent use prior to declaration. @@ -190,27 +195,27 @@ Domain.EmptySet = new EmptySet() // To prevent use prior to declaration. export class Range extends Domain { constructor(begin, end, openBegin, openEnd) { super() - if(typeof begin == 'number' || typeof begin == 'string') begin = new Expression(begin.toString()) + if(typeof begin == "number" || typeof begin == "string") begin = new Expression(begin.toString()) this.begin = begin - if(typeof end == 'number' || typeof end == 'string') end = new Expression(end.toString()) + if(typeof end == "number" || typeof end == "string") end = new Expression(end.toString()) this.end = end this.openBegin = openBegin this.openEnd = openEnd this.displayName = (openBegin ? "]" : "[") + begin.toString() + ";" + end.toString() + (openEnd ? "[" : "]") this.latexMarkup = `\\mathopen${openBegin ? "]" : "["}${this.begin.latexMarkup};${this.end.latexMarkup}\\mathclose${openEnd ? "[" : "]"}` } - + includes(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) } - + toString() { return this.displayName } - + union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) return domain.union(this) @@ -219,7 +224,7 @@ export class Range extends Domain { if(domain instanceof MinusDomain) return new UnionDomain(this, domain) if(domain instanceof Range) return new UnionDomain(this, domain) } - + intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) return domain.intersection(this) @@ -228,11 +233,11 @@ export class Range extends Domain { if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain) if(domain instanceof Range) return new IntersectionDomain(this, domain) } - + static import(frm) { let openBegin = frm.trim().charAt(0) === "]" - let openEnd = frm.trim().charAt(frm.length -1) === "[" - let [begin, end] = frm.substr(1, frm.length-2).split(";") + let openEnd = frm.trim().charAt(frm.length - 1) === "[" + let [begin, end] = frm.substring(1, frm.length - 1).split(";") return new Range(begin.trim(), end.trim(), openBegin, openEnd) } } @@ -250,7 +255,7 @@ export class SpecialDomain extends Domain { * @param {boolean} moveSupported - Only true if next and previous functions are valid. */ constructor(displayName, isValid, next = () => true, previous = () => true, - moveSupported = true) { + moveSupported = true) { super() this.displayName = displayName this.isValid = isValid @@ -258,29 +263,29 @@ export class SpecialDomain extends Domain { this.prevValue = previous this.moveSupported = moveSupported } - + includes(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) return this.isValid(x) } - + next(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) return this.nextValue(x) } - + previous(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) return this.prevValue(x) } - + toString() { return this.displayName } - + union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) return domain.union(this) @@ -289,7 +294,7 @@ export class SpecialDomain extends Domain { if(domain instanceof MinusDomain) return new UnionDomain(this, domain) if(domain instanceof Range) return new UnionDomain(this, domain) } - + intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) return domain.intersection(this) @@ -305,7 +310,7 @@ export class SpecialDomain extends Domain { */ export class DomainSet extends SpecialDomain { constructor(values) { - super('', x => true, x => x, true) + super("", () => true, x => x, true) let newVals = {} this.executedValues = [] for(let value of values) { @@ -314,54 +319,54 @@ export class DomainSet extends SpecialDomain { newVals[ex] = expr this.executedValues.push(ex) } - this.executedValues.sort((a,b) => a-b) + this.executedValues.sort((a, b) => a - b) this.values = this.executedValues.map(val => newVals[val]) this.displayName = "{" + this.values.join(";") + "}" this.latexMarkup = `\\{${this.values.join(";")}\\}` } - + includes(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) for(let value of this.values) if(x === value.execute()) return true return false } - + next(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) + if(typeof x == "string") x = executeExpression(x) if(x < this.executedValues[0]) return this.executedValues[0] for(let i = 1; i < this.values.length; i++) { - let prevValue = this.executedValues[i-1] + let prevValue = this.executedValues[i - 1] let value = this.executedValues[i] if(x >= prevValue && x < value) return value } return null } - + previous(x) { if(x instanceof Expression) x = x.execute() - if(typeof x == 'string') x = executeExpression(x) - if(x > this.executedValues[this.executedValues.length-1]) - return this.executedValues[this.executedValues.length-1] + if(typeof x == "string") x = executeExpression(x) + if(x > this.executedValues[this.executedValues.length - 1]) + return this.executedValues[this.executedValues.length - 1] for(let i = 1; i < this.values.length; i++) { - let prevValue = this.executedValues[i-1] + let prevValue = this.executedValues[i - 1] let value = this.executedValues[i] if(x > prevValue && x <= value) return prevValue } return null } - + toString() { return this.displayName } - + union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) { let newValues = [] - let values = this.values.concat(domain.values).filter(function(val){ + let values = this.values.concat(domain.values).filter(function(val) { newValues.push(val.execute()) return newValues.indexOf(val.execute()) === newValues.length - 1 }) @@ -378,18 +383,18 @@ export class DomainSet extends SpecialDomain { domain.openEnd = false } } - if(!domain.includes(value)) + if(!domain.includes(value)) notIncludedValues.push(this.values[i].toEditableString()) } if(notIncludedValues.length === 0) return domain return new UnionDomain(domain, new DomainSet(notIncludedValues)) } - + intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) { let domValues = domain.values.map(expr => expr.execute()) - this.values = this.values.filter(function(val){ + this.values = this.values.filter(function(val) { return domValues.indexOf(val.execute()) >= 0 }) return this @@ -405,16 +410,16 @@ export class DomainSet extends SpecialDomain { domain.openEnd = false } } - if(domain.includes(value)) + if(domain.includes(value)) includedValues.push(this.values[i].toEditableString()) } if(includedValues.length === 0) return new EmptySet() if(includedValues.length === this.values.length) return this return new IntersectionDomain(domain, new DomainSet(includedValues)) } - + static import(frm) { - return new DomainSet(frm.substr(1, frm.length-2).split(";")) + return new DomainSet(frm.substring(1, frm.length - 1).split(";")) } } @@ -429,15 +434,15 @@ export class UnionDomain extends Domain { this.displayName = this.dom1.toString() + " ∪ " + this.dom2.toString() this.latexMarkup = `${dom1.latexMarkup}\\cup${dom2.latexMarkup}` } - + includes(x) { return this.dom1.includes(x) || this.dom2.includes(x) } - + toString() { return this.displayName } - + union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) return domain.union(this) @@ -446,7 +451,7 @@ export class UnionDomain extends Domain { if(domain instanceof IntersectionDomain) return new UnionDomain(this, domain) if(domain instanceof MinusDomain) return new MinusDomain(this, domain) } - + intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) return domain.intersection(this) @@ -454,12 +459,12 @@ export class UnionDomain extends Domain { if(domain instanceof IntersectionDomain) return this.dom1.intersection(domain.dom1).intersection(this.dom2).intersection(domain.dom2) if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain) } - + static import(frm) { let domains = frm.trim().split("∪") if(domains.length === 1) domains = frm.trim().split("U") // Fallback let dom2 = parseDomain(domains.pop()) - let dom1 = parseDomain(domains.join('∪')) + let dom1 = parseDomain(domains.join("∪")) return dom1.union(dom2) } } @@ -475,24 +480,24 @@ export class IntersectionDomain extends Domain { this.displayName = dom1.toString() + " ∩ " + dom2.toString() this.latexMarkup = `${dom1.latexMarkup}\\cap${dom2.latexMarkup}` } - + includes(x) { return this.dom1.includes(x) && this.dom2.includes(x) } - + toString() { return this.displayName } - + union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) return domain.union(this) if(domain instanceof Range) return domain.union(this) - if(domain instanceof UnionDomain) return this.dom1.union(domain.dom1).union(this.dom2).union(domain.dom2) + if(domain instanceof UnionDomain) return this.dom1.union(domain.dom1).union(this.dom2).union(domain.dom2) if(domain instanceof IntersectionDomain) return new UnionDomain(this, domain) if(domain instanceof MinusDomain) return new MinusDomain(this, domain) } - + intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) return domain.intersection(this) @@ -500,11 +505,11 @@ export class IntersectionDomain extends Domain { if(domain instanceof IntersectionDomain) return new IntersectionDomain(this, domain) if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain) } - + static import(frm) { let domains = frm.trim().split("∩") let dom1 = parseDomain(domains.pop()) - let dom2 = parseDomain(domains.join('∩')) + let dom2 = parseDomain(domains.join("∩")) return dom1.intersection(dom2) } } @@ -520,20 +525,20 @@ export class MinusDomain extends Domain { this.displayName = dom1.toString() + "∖" + dom2.toString() this.latexMarkup = `${dom1.latexMarkup}\\setminus${dom2.latexMarkup}` } - + includes(x) { return this.dom1.includes(x) && !this.dom2.includes(x) } - + toString() { return this.displayName } - + static import(frm) { let domains = frm.trim().split("∖") if(domains.length === 1) domains = frm.trim().split("\\") // Fallback let dom1 = parseDomain(domains.shift()) - let dom2 = parseDomain(domains.join('∪')) + let dom2 = parseDomain(domains.join("∪")) return new MinusDomain(dom1, dom2) } } @@ -542,53 +547,53 @@ Domain.RE = new MinusDomain("R", "{0}") Domain.RE.displayName = "ℝ*" Domain.RE.latexMarkup = "\\mathbb{R}^{*}" -Domain.R = new Range(-Infinity,Infinity,true,true) +Domain.R = new Range(-Infinity, Infinity, true, true) Domain.R.displayName = "ℝ" Domain.R.latexMarkup = "\\mathbb{R}" -Domain.RP = new Range(0,Infinity,true,false) +Domain.RP = new Range(0, Infinity, true, false) Domain.RP.displayName = "ℝ⁺" Domain.RP.latexMarkup = "\\mathbb{R}^{+}" -Domain.RM = new Range(-Infinity,0,true,false) +Domain.RM = new Range(-Infinity, 0, true, false) Domain.RM.displayName = "ℝ⁻" Domain.RM.latexMarkup = "\\mathbb{R}^{-}" -Domain.RPE = new Range(0,Infinity,true,true) +Domain.RPE = new Range(0, Infinity, true, true) Domain.RPE.displayName = "ℝ⁺*" Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}" -Domain.RME = new Range(-Infinity,0,true,true) +Domain.RME = new Range(-Infinity, 0, true, true) Domain.RME.displayName = "ℝ⁻*" Domain.RME.latexMarkup = "\\mathbb{R}^{+*}" -Domain.N = new SpecialDomain('ℕ', x => x%1===0 && x >= 0, - x => Math.max(Math.floor(x)+1, 0), - x => Math.max(Math.ceil(x)-1, 0)) +Domain.N = new SpecialDomain("ℕ", x => x % 1 === 0 && x >= 0, + x => Math.max(Math.floor(x) + 1, 0), + x => Math.max(Math.ceil(x) - 1, 0)) Domain.N.latexMarkup = "\\mathbb{N}" -Domain.NE = new SpecialDomain('ℕ*', x => x%1===0 && x > 0, - x => Math.max(Math.floor(x)+1, 1), - x => Math.max(Math.ceil(x)-1, 1)) +Domain.NE = new SpecialDomain("ℕ*", x => x % 1 === 0 && x > 0, + x => Math.max(Math.floor(x) + 1, 1), + x => Math.max(Math.ceil(x) - 1, 1)) Domain.NE.latexMarkup = "\\mathbb{N}^{*}" -Domain.Z = new SpecialDomain('ℤ', x => x%1===0, x => Math.floor(x)+1, x => Math.ceil(x)-1) +Domain.Z = new SpecialDomain("ℤ", x => x % 1 === 0, x => Math.floor(x) + 1, x => Math.ceil(x) - 1) Domain.Z.latexMarkup = "\\mathbb{Z}" -Domain.ZE = new SpecialDomain('ℤ*', x => x%1===0 && x !== 0, - x => Math.floor(x)+1 === 0 ? Math.floor(x)+2 : Math.floor(x)+1, - x => Math.ceil(x)-1 === 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) +Domain.ZE = new SpecialDomain("ℤ*", x => x % 1 === 0 && x !== 0, + x => Math.floor(x) + 1 === 0 ? Math.floor(x) + 2 : Math.floor(x) + 1, + x => Math.ceil(x) - 1 === 0 ? Math.ceil(x) - 2 : Math.ceil(x) - 1) Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}" -Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1===0 && x <= 0, - x => Math.min(Math.floor(x)+1, 0), - x => Math.min(Math.ceil(x)-1, 0)) +Domain.ZM = new SpecialDomain("ℤ⁻", x => x % 1 === 0 && x <= 0, + x => Math.min(Math.floor(x) + 1, 0), + x => Math.min(Math.ceil(x) - 1, 0)) Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}" -Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1===0 && x < 0, - x => Math.min(Math.floor(x)+1, -1), - x => Math.min(Math.ceil(x)-1, -1)) +Domain.ZME = new SpecialDomain("ℤ⁻*", x => x % 1 === 0 && x < 0, + x => Math.min(Math.floor(x) + 1, -1), + x => Math.min(Math.ceil(x) - 1, -1)) Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" -Domain.NLog = new SpecialDomain('ℕˡᵒᵍ', - x => x/Math.pow(10, x.toString().length-1) % 1 === 0 && x > 0, - function(x) { - let x10pow = Math.pow(10, x.toString().length-1) - return Math.max(1, (Math.floor(x/x10pow)+1)*x10pow) - }, - function(x) { - let x10pow = Math.pow(10, x.toString().length-1) - return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow) - }) +Domain.NLog = new SpecialDomain("ℕˡᵒᵍ", + x => x / Math.pow(10, x.toString().length - 1) % 1 === 0 && x > 0, + function(x) { + let x10pow = Math.pow(10, x.toString().length - 1) + return Math.max(1, (Math.floor(x / x10pow) + 1) * x10pow) + }, + function(x) { + let x10pow = Math.pow(10, x.toString().length - 1) + return Math.max(1, (Math.ceil(x / x10pow) - 1) * x10pow) + }) Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" let refedDomains = [] @@ -600,11 +605,11 @@ let refedDomains = [] * @returns {Domain} Parsed domain. */ export function parseDomain(domain) { - if(!domain.includes(')') && !domain.includes('(')) return parseDomainSimple(domain) + if(!domain.includes(")") && !domain.includes("(")) return parseDomainSimple(domain) let domStr while((domStr = /\(([^)(]+)\)/.exec(domain)) !== null) { - let dom = parseDomainSimple(domStr[1].trim()); - domain = domain.replace(domStr[0], 'D' + refedDomains.length) + let dom = parseDomainSimple(domStr[1].trim()) + domain = domain.replace(domStr[0], "D" + refedDomains.length) refedDomains.push(dom) } return parseDomainSimple(domain) @@ -621,10 +626,10 @@ export function parseDomainSimple(domain) { if(domain.includes("U") || domain.includes("∪")) return UnionDomain.import(domain) if(domain.includes("∩")) return IntersectionDomain.import(domain) if(domain.includes("∖") || domain.includes("\\")) return MinusDomain.import(domain) - if(domain.charAt(0) === "{" && domain.charAt(domain.length -1) === "}") return DomainSet.import(domain) + if(domain.charAt(0) === "{" && domain.charAt(domain.length - 1) === "}") return DomainSet.import(domain) if(domain.includes("]") || domain.includes("[")) return Range.import(domain) if(["R", "ℝ", "N", "ℕ", "Z", "ℤ"].some(str => domain.toUpperCase().includes(str))) return Domain.import(domain) - if(domain[0] === 'D') return refedDomains[parseInt(domain.substr(1))] + if(domain[0] === "D") return refedDomains[parseInt(domain.substring(1))] return new EmptySet() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 6505018..2862183 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -37,70 +37,90 @@ export class Expression { } this.cached = this.isConstant() this.cachedValue = null - if(this.cached && this.allRequirementsFullfilled()) + if(this.cached && this.allRequirementsFulfilled()) this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } + /** + * Return all the variables used in calc + * @return {string[]} + */ variables() { return this.calc.variables() } + /** + * Checks if the current expression is constant (does not depend on a variable, be it x or n). + * @return {boolean} + */ isConstant() { let vars = this.calc.variables() return !vars.includes("x") && !vars.includes("n") } - + + /** + * Returns the list of object names this expression is dependant on. + * @return {string[]} + */ requiredObjects() { return this.calc.variables().filter(objName => objName !== "x" && objName !== "n") } - - allRequirementsFullfilled() { + + /** + * Checks if all the objects required for this expression are defined. + * @return {boolean} + */ + allRequirementsFulfilled() { return this.requiredObjects().every(objName => objName in Objects.currentObjectsByName) } - + + /** + * Returns a list of names whose corresponding objects this expression is dependant on and are missing. + * @return {boolean} + */ undefinedVariables() { return this.requiredObjects().filter(objName => !(objName in Objects.currentObjectsByName)) } - + recache() { if(this.cached) this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) } - + execute(x = 1) { if(this.cached) { if(this.cachedValue == null) this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) return this.cachedValue } - ExprParser.currentVars = Object.assign({'x': x}, Objects.currentObjectsByName) + ExprParser.currentVars = Object.assign({ "x": x }, Objects.currentObjectsByName) return this.calc.evaluate(ExprParser.currentVars) } - + simplify(x) { - let expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate() === 0) expr = '0' + let expr = this.calc.substitute("x", x).simplify() + if(expr.evaluate() === 0) expr = "0" return new Expression(expr) } - + toEditableString() { return this.calc.toString() } - - toString(forceSign=false) { + + toString(forceSign = false) { let str = Utils.makeExpressionReadable(this.calc.toString()) if(str !== undefined && str.match(/^\d*\.\d+$/)) { - if(str.split('.')[1].split('0').length > 7) { + if(str.split(".")[1].split("0").length > 7) { // Likely rounding error - str = parseFloat(str.substring(0, str.length-1)).toString(); + str = parseFloat(str.substring(0, str.length - 1)).toString() } } - if(str[0] !== '-' && forceSign) str = '+' + str + if(str[0] !== "-" && forceSign) str = "+" + str return str } } -export function executeExpression(expr){ +export function executeExpression(expr) { return (new Expression(expr.toString())).execute() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs index 04abf68..e623034 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs @@ -17,7 +17,7 @@ */ import { Module } from "./common.mjs" -import { FUNCTION, Interface, CanvasInterface, DialogInterface } from "./interface.mjs" +import { CanvasInterface, DialogInterface } from "./interface.mjs" import { textsup } from "../utils.mjs" import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" @@ -227,7 +227,7 @@ class CanvasAPI extends Module { // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) console.error(e) console.log(e.stack) - this._drawingErrorDialog.showDialog(objType, obj.name, e.message) + this._drawingErrorDialog.show(objType, obj.name, e.message) History.undo() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs index 6902745..0a5046b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs @@ -26,7 +26,7 @@ export class Module { /** * * @param {string} name - Name of the API - * @param {Object.} initializationParameters - List of parameters for the initialize function. + * @param {Object.} initializationParameters - List of parameters for the initialize function. */ constructor(name, initializationParameters = {}) { console.log(`Loading module ${name}...`) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs index f40489f..854f928 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs @@ -55,7 +55,7 @@ class ExprParserAPI extends Module { * @return {function} JS function to call. */ parseArgumentsForFunction(args, usage1, usage2) { - let f, target, variable + let f, variable if(args.length === 1) { // Parse object f = args[0] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs index 09b45d6..42146ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs @@ -17,7 +17,6 @@ */ import { Module } from "./common.mjs" -import Latex from "./latex.mjs" import { HistoryInterface, NUMBER, STRING } from "./interface.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs index 37f4f5b..77e2741 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -94,6 +94,10 @@ export class CanvasInterface extends SettingsInterface { markDirty = FUNCTION /** @type {function(string)} */ loadImage = FUNCTION + /** @type {function(string)} */ + isImageLoading = FUNCTION + /** @type {function(string)} */ + isImageLoaded = FUNCTION /** @type {function()} */ requestPaint = FUNCTION } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs index d4ff50c..b6d40f5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs @@ -20,7 +20,7 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" -import { DialogInterface, FUNCTION, Interface, RootInterface, SettingsInterface } from "./interface.mjs" +import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs" class IOAPI extends Module { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs index 0071779..fa194f5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs @@ -20,7 +20,8 @@ import { Module } from "./common.mjs" import * as Instruction from "../lib/expr-eval/instruction.mjs" import { escapeValue } from "../lib/expr-eval/expression.mjs" -const unicodechars = ["α", "β", "γ", "δ", "ε", "ζ", "η", +const unicodechars = [ + "α", "β", "γ", "δ", "ε", "ζ", "η", "π", "θ", "κ", "λ", "μ", "ξ", "ρ", "ς", "σ", "τ", "φ", "χ", "ψ", "ω", "Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Σ", @@ -30,7 +31,8 @@ const unicodechars = ["α", "β", "γ", "δ", "ε", "ζ", "η", "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", "₄", "₅", "₆", "₇", "₈", "₉", "₀", "pi", "∞"] -const equivalchars = ["\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", +const equivalchars = [ + "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", "\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho", "\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega", "\\Gamma", "\\Delta", "\\Theta", "\\Lambda", "\\Xi", "\\Pi", "\\Sigma", @@ -71,7 +73,7 @@ class LatexAPI extends Module { * * @param {string} markup - LaTeX markup to render. * @param {number} fontSize - Font size (in pt) to render. - * @param {color} color - Color of the text to render. + * @param {string} color - Color of the text to render. * @returns {LatexRenderResult|null} */ findPrerendered(markup, fontSize, color) { @@ -87,7 +89,7 @@ class LatexAPI extends Module { * * @param {string} markup - LaTeX markup to render. * @param {number} fontSize - Font size (in pt) to render. - * @param {color} color - Color of the text to render. + * @param {string} color - Color of the text to render. * @returns {Promise} */ async requestAsyncRender(markup, fontSize, color) { @@ -119,7 +121,7 @@ class LatexAPI extends Module { if(elem[0] !== "(" && elem[elem.length - 1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) return this.par(elem) if(elem[0] === "(" && elem[elem.length - 1] === ")") - return elem.substr(1, elem.length - 2) + return elem.removeEnclosure() return elem } @@ -134,24 +136,24 @@ class LatexAPI extends Module { switch(f) { case "derivative": if(args.length === 3) - return "\\frac{d" + args[0].substr(1, args[0].length - 2).replace(new RegExp(args[1].substr(1, args[1].length - 2), "g"), "x") + "}{dx}" + return `\\frac{d${args[0].removeEnclosure().replaceAll(args[1].removeEnclosure(), "x")}}{dx}` else - return "\\frac{d" + args[0] + "}{dx}(x)" + return `\\frac{d${args[0]}}{dx}(x)` case "integral": if(args.length === 4) - return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2].substr(1, args[2].length - 2) + " d" + args[3].substr(1, args[3].length - 2) + return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2].removeEnclosure()} d${args[3].removeEnclosure()}` else - return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2] + "(t) dt" + return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2]}(t) dt` case "sqrt": - return "\\sqrt\\left(" + args.join(", ") + "\\right)" + return `\\sqrt\\left(${args.join(", ")}\\right)` case "abs": - return "\\left|" + args.join(", ") + "\\right|" + return `\\left|${args.join(", ")}\\right|` case "floor": - return "\\left\\lfloor" + args.join(", ") + "\\right\\rfloor" + return `\\left\\lfloor${args.join(", ")}\\right\\rfloor` case "ceil": - return "\\left\\lceil" + args.join(", ") + "\\right\\rceil" + return `\\left\\lceil${args.join(", ")}\\right\\rceil` default: - return "\\mathrm{" + f + "}\\left(" + args.join(", ") + "\\right)" + return `\\mathrm{${f}}\\left(${args.join(", ")}\\right)` } } @@ -166,12 +168,12 @@ class LatexAPI extends Module { if(wrapIn$) for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], "g"), "$" + equivalchars[i] + "$") + vari = vari.replaceAll(unicodechars[i], "$" + equivalchars[i] + "$") } else for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], "g"), equivalchars[i]) + vari = vari.replaceAll(unicodechars[i], equivalchars[i]) } return vari } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs index 5a63386..a95dc89 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs @@ -1,28 +1,28 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import { Module } from './common.mjs' -import { textsub } from '../utils.mjs' +import { Module } from "./common.mjs" +import { textsub } from "../utils.mjs" class ObjectsAPI extends Module { constructor() { - super('Objects') + super("Objects") this.types = {} /** @@ -45,7 +45,7 @@ class ObjectsAPI extends Module { * @param {string} prefix - Prefix to the name. * @return {string} New unused name for a new object. */ - getNewName(allowedLetters, prefix='') { + getNewName(allowedLetters, prefix = "") { // Allows to get a new name, based on the allowed letters, // as well as adding a sub number when needs be. let newid = 0 @@ -53,7 +53,7 @@ class ObjectsAPI extends Module { do { let letter = allowedLetters[newid % allowedLetters.length] let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) - ret = prefix + letter + (num > 0 ? textsub(num-1) : '') + ret = prefix + letter + (num > 0 ? textsub(num - 1) : "") newid += 1 } while(ret in this.currentObjectsByName) return ret @@ -78,7 +78,7 @@ class ObjectsAPI extends Module { deleteObject(objName) { let obj = this.currentObjectsByName[objName] if(obj !== undefined) { - this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj),1) + this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj), 1) obj.delete() delete this.currentObjectsByName[objName] } @@ -90,15 +90,10 @@ class ObjectsAPI extends Module { * @returns {string[]} List of names of the objects. */ getObjectsName(objType) { - if(objType === "ExecutableObject") { - // NOTE: QMLJS does not support flatMap. - // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) - let types = this.getExecutableTypes() - let elementNames = [''] - for(let elemType of types) - elementNames = elementNames.concat(this.currentObjects[elemType].map(obj => obj.name)) - return elementNames - } + if(objType === "ExecutableObject") + return this.getExecutableTypes().flatMap( + elemType => this.currentObjects[elemType].map(obj => obj.name) + ) if(this.currentObjects[objType] === undefined) return [] return this.currentObjects[objType].map(obj => obj.name) } @@ -117,9 +112,9 @@ class ObjectsAPI extends Module { * @param {string[]} args - List of arguments for the objects (can be empty). * @return {DrawableObject} Newly created object. */ - createNewRegisteredObject(objType, args= []) { + createNewRegisteredObject(objType, args = []) { if(Object.keys(this.types).indexOf(objType) === -1) return null // Object type does not exist. - let newobj = new this.types[objType](...args) + const newobj = new this.types[objType](...args) if(Object.keys(this.currentObjects).indexOf(objType) === -1) { this.currentObjects[objType] = [] } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs index 389a5ba..453bc0e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs @@ -15,19 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import {Module} from "./common.mjs" +import { Module } from "./common.mjs" import General from "../preferences/general.mjs" import Editor from "../preferences/expression.mjs" import DefaultGraph from "../preferences/default.mjs" class PreferencesAPI extends Module { constructor() { - super('Preferences') + super("Preferences") this.categories = { - [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, - [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor, - [QT_TRANSLATE_NOOP('settingCategory', 'default')]: DefaultGraph, + [QT_TRANSLATE_NOOP("settingCategory", "general")]: General, + [QT_TRANSLATE_NOOP("settingCategory", "editor")]: Editor, + [QT_TRANSLATE_NOOP("settingCategory", "default")]: DefaultGraph } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index 729e167..26a6003 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs index 1534dd5..82d9728 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -27,89 +27,100 @@ import { ExecutableObject } from "./common.mjs" import Function from "./function.mjs" export default class BodeMagnitude extends ExecutableObject { - static type(){return 'Gain Bode'} - static displayType(){return qsTranslate("bodemagnitude", 'Bode Magnitude')} - static displayTypeMultiple(){return qsTranslate("bodemagnitude", 'Bode Magnitudes')} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), - [QT_TRANSLATE_NOOP('prop','pass')]: P.Enum.BodePass, - [QT_TRANSLATE_NOOP('prop','gain')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - [QT_TRANSLATE_NOOP('prop','omGraduation')]: 'boolean' - }} + static type() { + return "Gain Bode" + } - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { - if(name == null) name = Objects.getNewName('G') - if(name === 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). + static displayType() { + return qsTranslate("bodemagnitude", "Bode Magnitude") + } + + static displayTypeMultiple() { + return qsTranslate("bodemagnitude", "Bode Magnitudes") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "om_0")]: new P.ObjectType("Point"), + [QT_TRANSLATE_NOOP("prop", "pass")]: P.Enum.BodePass, + [QT_TRANSLATE_NOOP("prop", "gain")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number", + [QT_TRANSLATE_NOOP("prop", "omGraduation")]: "boolean" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + om_0 = "", pass = "high", gain = "20", labelPosition = "above", labelX = 1, omGraduation = false) { + if(name == null) name = Objects.getNewName("G") + if(name === "G") name = "G₀" // G is reserved for sum of BODE magnitudes (Somme gains Bode). super(name, visible, color, labelContent) if(typeof om_0 == "string") { // Point name or create one om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), true, this.color, 'name']) - History.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) + om_0 = Objects.createNewRegisteredObject("Point", [Objects.getNewName("ω"), true, this.color, "name"]) + History.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export())) om_0.update() - labelPosition = 'below' + labelPosition = "below" } om_0.requiredBy.push(this) } /** @type {Point} */ this.om_0 = om_0 this.pass = pass - if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString()) + if(typeof gain == "number" || typeof gain == "string") gain = new Expression(gain.toString()) this.gain = gain this.labelPosition = labelPosition this.labelX = labelX this.omGraduation = omGraduation } - + getReadableString() { - let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass"); - return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec` + let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass") + return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${" ".repeat(this.name.length)}${this.gain.toString(true)} dB/dec` } - + getLatexString() { - let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass"); + let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass") return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} \\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ ${this.gain.latexMarkup}\\textsf{ dB/dec} \\end{array}` } - - execute(x=1) { - if(typeof x == 'string') x = executeExpression(x) - if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) { + + execute(x = 1) { + if(typeof x == "string") x = executeExpression(x) + if((this.pass === "high" && x < this.om_0.x) || (this.pass === "low" && x > this.om_0.x)) { let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.execute(x) } else { return this.om_0.y.execute() } } - + simplify(x = 1) { let xval = x - if(typeof x == 'string') xval = executeExpression(x) - if((this.pass === 'high' && xval < this.om_0.x.execute()) || (this.pass === 'low' && xval > this.om_0.x.execute())) { + if(typeof x == "string") xval = executeExpression(x) + if((this.pass === "high" && xval < this.om_0.x.execute()) || (this.pass === "low" && xval > this.om_0.x.execute())) { let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.simplify(x) } else { return this.om_0.y.toString() } } - + canExecute(x = 1) { return true } - + draw(canvas) { let base = [canvas.x2px(this.om_0.x.execute()), canvas.y2px(this.om_0.y.execute())] let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) - let inDrawDom = new EmptySet() + let inDrawDom - if(this.pass === 'high') { + if(this.pass === "high") { // High pass, linear line from beginning, then constant to the end. canvas.drawLine(base[0], base[1], canvas.width, base[1]) inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`) @@ -122,26 +133,28 @@ export default class BodeMagnitude extends ExecutableObject { // Dashed line representing break in function let xpos = canvas.x2px(this.om_0.x.execute()) let dashPxSize = 10 - for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize*2) - canvas.drawLine(xpos, i, xpos, i+dashPxSize) - + for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize * 2) + canvas.drawLine(xpos, i, xpos, i + dashPxSize) + // Label this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } - + update() { super.update() - let sumObjs = Objects.currentObjects['Somme gains Bode'] + /** @type {BodeMagnitudeSum[]} */ + let sumObjs = Objects.currentObjects["Somme gains Bode"] if(sumObjs !== undefined && sumObjs.length > 0) { sumObjs[0].recalculateCache() } else { - Objects.createNewRegisteredObject('Somme gains Bode') + Objects.createNewRegisteredObject("Somme gains Bode") } } - + delete() { super.delete() - let sumObjs = Objects.currentObjects['Somme gains Bode'] + /** @type {BodeMagnitudeSum[]} */ + let sumObjs = Objects.currentObjects["Somme gains Bode"] if(sumObjs !== undefined && sumObjs.length > 0) { sumObjs[0].recalculateCache() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs index f268bbe..eb81663 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -26,32 +26,46 @@ import Function from "./function.mjs" export default class BodeMagnitudeSum extends ExecutableObject { - static type(){return 'Somme gains Bode'} - static displayType(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')} - static displayTypeMultiple(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')} - static createable() {return false} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - labelPosition = 'above', labelX = 1) { - if(name == null) name = 'G' + static type() { + return "Somme gains Bode" + } + + static displayType() { + return qsTranslate("bodemagnitudesum", "Bode Magnitudes Sum") + } + + static displayTypeMultiple() { + return qsTranslate("bodemagnitudesum", "Bode Magnitudes Sum") + } + + static createable() { + return false + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + labelPosition = "above", labelX = 1) { + if(name == null) name = "G" super(name, visible, color, labelContent) this.labelPosition = labelPosition this.labelX = labelX this.recalculateCache() } - + getReadableString() { - return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` + return `${this.name} = ${Objects.getObjectsName("Gain Bode").join(" + ")}` } - + getLatexString() { - return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(name => Latex.variable(name)).join(' + ')}` + return `${Latex.variable(this.name)} = ${Objects.getObjectsName("Gain Bode").map(name => Latex.variable(name)).join(" + ")}` } - + execute(x = 0) { for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { @@ -60,50 +74,50 @@ export default class BodeMagnitudeSum extends ExecutableObject { } return null } - + canExecute(x = 1) { return true // Should always be true } - + simplify(x = 1) { for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { return limitedDrawFunction.simplify(x) } } - return '' + return "" } - + recalculateCache() { this.cachedParts = [] // Calculating this is fairly resource expansive so it's cached. - let magnitudeObjects = Objects.currentObjects['Gain Bode'] + let magnitudeObjects = Objects.currentObjects["Gain Bode"] if(magnitudeObjects === undefined || magnitudeObjects.length < 1) { Objects.deleteObject(this.name) } else { - console.log('Recalculating cache gain') + console.log("Recalculating cache gain") // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. const MIN_DRAW = 1e-20 // Format: [[x value of where the filter transitions, magnitude, high-pass (bool)]] - const magnitudes = [] + const magnitudes = [] const XVALUE = 0 const MAGNITUDE = 1 const PASS = 2 magnitudes.push([Number.MAX_VALUE, 0, true]) // Draw the ending section // Collect data from current magnitude (or gain in French) objects. let baseY = 0 - for(/** @type {Bodemagnitude} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position. + for(/** @type {BodeMagnitude} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position. const om0x = magnitudeObj.om_0.x.execute() - magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === 'high']) + magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === "high"]) baseY += magnitudeObj.execute(MIN_DRAW) } // Sorting the data by their x transitions value - magnitudes.sort((a,b) => a[XVALUE] - b[XVALUE]) + magnitudes.sort((a, b) => a[XVALUE] - b[XVALUE]) // Adding the total gains. let magnitudesBeforeTransition = [] let magnitudesAfterTransition = [] let totalMagnitudeAtStart = 0 // Magnitude at the lowest x value (sum of all high-pass magnitudes) - for(let [om0x, magnitude, highpass] of magnitudes){ + for(let [om0x, magnitude, highpass] of magnitudes) { if(highpass) { magnitudesBeforeTransition.push(magnitude) magnitudesAfterTransition.push(0) @@ -129,7 +143,7 @@ export default class BodeMagnitudeSum extends ExecutableObject { } } } - + draw(canvas) { if(this.cachedParts.length > 0) { for(let [limitedDrawFunction, drawDomain] of this.cachedParts) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs index 310bb25..9c93bba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -27,33 +27,44 @@ import { ExecutableObject } from "./common.mjs" export default class BodePhase extends ExecutableObject { - static type(){return 'Phase Bode'} - static displayType(){return qsTranslate("bodephase", 'Bode Phase')} - static displayTypeMultiple(){return qsTranslate("bodephase", 'Bode Phases')} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), - [QT_TRANSLATE_NOOP('prop','phase')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','unit')]: new P.Enum('°', 'deg', 'rad'), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number' - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) { - if(name == null) name = Objects.getNewName('φ') - if(name === 'φ') name = 'φ₀' // φ is reserved for sum of Bode phases. + static type() { + return "Phase Bode" + } + + static displayType() { + return qsTranslate("bodephase", "Bode Phase") + } + + static displayTypeMultiple() { + return qsTranslate("bodephase", "Bode Phases") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "om_0")]: new P.ObjectType("Point"), + [QT_TRANSLATE_NOOP("prop", "phase")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "unit")]: new P.Enum("°", "deg", "rad"), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + om_0 = "", phase = 90, unit = "°", labelPosition = "above", labelX = 1) { + if(name == null) name = Objects.getNewName("φ") + if(name === "φ") name = "φ₀" // φ is reserved for sum of Bode phases. super(name, visible, color, labelContent) - if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString()) + if(typeof phase == "number" || typeof phase == "string") phase = new Expression(phase.toString()) this.phase = phase if(typeof om_0 == "string") { // Point name or create one om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), this.color, 'name']) - om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' - History.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) - labelPosition = 'below' + om_0 = Objects.createNewRegisteredObject("Point", [Objects.getNewName("ω"), this.color, "name"]) + om_0.labelPosition = this.phase.execute() >= 0 ? "above" : "below" + History.history.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export())) + labelPosition = "below" } om_0.requiredBy.push(this) } @@ -63,69 +74,71 @@ export default class BodePhase extends ExecutableObject { this.labelPosition = labelPosition this.labelX = labelX } - + getReadableString() { return `${this.name}: ${this.phase.toString(true)}${this.unit} at ${this.om_0.name} = ${this.om_0.x}` } - + getLatexString() { return `${Latex.variable(this.name)}: ${this.phase.latexMarkup}\\textsf{${this.unit} at }${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup}` } - - execute(x=1) { - if(typeof x == 'string') x = executeExpression(x) + + execute(x = 1) { + if(typeof x == "string") x = executeExpression(x) if(x < this.om_0.x) { return this.om_0.y.execute() } else { return this.om_0.y.execute() + this.phase.execute() } } - + simplify(x = 1) { let xval = x - if(typeof x == 'string') xval = executeExpression(x) + if(typeof x == "string") xval = executeExpression(x) if(xval < this.om_0.x) { return this.om_0.y.toString() } else { - let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() + let newExp = this.om_0.y.toEditableString() + " + " + this.phase.toEditableString() return new Expression(newExp) } } - + canExecute(x = 1) { return true } - + draw(canvas) { let baseX = canvas.x2px(this.om_0.x.execute()) let omy = this.om_0.y.execute() let augmt = this.phase.execute() let baseY = canvas.y2px(omy) - let augmtY = canvas.y2px(omy+augmt) + let augmtY = canvas.y2px(omy + augmt) // Before change line. canvas.drawLine(0, baseY, Math.min(baseX, canvas.height), baseY) // Transition line. canvas.drawLine(baseX, baseY, baseX, augmtY) // After change line canvas.drawLine(Math.max(0, baseX), augmtY, canvas.width, augmtY) - + // Label this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } - + update() { super.update() - let sumObjs = Objects.currentObjects['Somme phases Bode'] + /** @type {BodePhaseSum[]} */ + let sumObjs = Objects.currentObjects["Somme phases Bode"] if(sumObjs !== undefined && sumObjs.length > 0) { sumObjs[0].recalculateCache() } else { - Objects.createNewRegisteredObject('Somme phases Bode') + Objects.createNewRegisteredObject("Somme phases Bode") } } - + delete() { super.update() - let sumObjs = Objects.currentObjects['Somme phases Bode'] + /** @type {BodePhaseSum[]} */ + let sumObjs = Objects.currentObjects["Somme phases Bode"] if(sumObjs !== undefined && sumObjs.length > 0) { sumObjs[0].recalculateCache() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs index a3de8f6..90864d7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -24,101 +24,114 @@ import Latex from "../module/latex.mjs" import { ExecutableObject } from "./common.mjs" export default class BodePhaseSum extends ExecutableObject { - static type(){return 'Somme phases Bode'} - static displayType(){return qsTranslate("bodephasesum", 'Bode Phases Sum')} - static displayTypeMultiple(){return qsTranslate("bodephasesum", 'Bode Phases Sum')} - static createable() {return false} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - labelPosition = 'above', labelX = 1) { - if(name == null) name = 'φ' + static type() { + return "Somme phases Bode" + } + + static displayType() { + return qsTranslate("bodephasesum", "Bode Phases Sum") + } + + static displayTypeMultiple() { + return qsTranslate("bodephasesum", "Bode Phases Sum") + } + + static createable() { + return false + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + labelPosition = "above", labelX = 1) { + if(name == null) name = "φ" super(name, visible, color, labelContent) this.labelPosition = labelPosition this.labelX = labelX this.recalculateCache() } - + getReadableString() { - return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` + return `${this.name} = ${Objects.getObjectsName("Phase Bode").join(" + ")}` } - + getLatexString() { - return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(name => Latex.variable(name)).join(' + ')}` + return `${Latex.variable(this.name)} = ${Objects.getObjectsName("Phase Bode").map(name => Latex.variable(name)).join(" + ")}` } - - execute(x=1) { - if(typeof x == 'string') x = executeExpression(x) - for(let i = 0; i < this.om0xList.length-1; i++) { - if(x >= this.om0xList[i] && x < this.om0xList[i+1]) return this.phasesList[i] + + execute(x = 1) { + if(typeof x == "string") x = executeExpression(x) + for(let i = 0; i < this.om0xList.length - 1; i++) { + if(x >= this.om0xList[i] && x < this.om0xList[i + 1]) return this.phasesList[i] } } - + simplify(x = 1) { let xval = x - if(typeof x == 'string') xval = executeExpression(x) - for(let i = 0; i < this.om0xList.length-1; i++) { - if(xval >= this.om0xList[i] && xval < this.om0xList[i+1]) { + if(typeof x == "string") xval = executeExpression(x) + for(let i = 0; i < this.om0xList.length - 1; i++) { + if(xval >= this.om0xList[i] && xval < this.om0xList[i + 1]) { return (new Expression(this.phasesExprList[i])).simplify() } } - return '0' + return "0" } - + canExecute(x = 1) { return true } - + recalculateCache() { // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. let drawMin = 1e-20 let drawMax = 1e20 this.om0xList = [drawMin, drawMax] this.phasesList = [0] - this.phasesExprList = ['0'] + this.phasesExprList = ["0"] let phasesDict = new Map() let phasesExprDict = new Map() phasesDict.set(drawMax, 0) - - let phaseObjects = Objects.currentObjects['Phase Bode'] + + let phaseObjects = Objects.currentObjects["Phase Bode"] if(phaseObjects === undefined || phaseObjects.length < 1) { Objects.deleteObject(this.name) } else { - console.log('Recalculating cache phase') - for(/** @type {Bodephase} */ let obj of phaseObjects) { + console.log("Recalculating cache phase") + for(/** @type {BodePhase} */ let obj of phaseObjects) { this.om0xList.push(obj.om_0.x.execute()) if(!phasesDict.has(obj.om_0.x.execute())) { phasesDict.set(obj.om_0.x.execute(), obj.phase.execute()) phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString()) } else { phasesDict.set(obj.om_0.x.execute(), obj.phase.execute() + phasesDict.get(obj.om_0.x.execute())) - phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString() + '+' + phasesExprDict.get(obj.om_0.x.execute())) + phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString() + "+" + phasesExprDict.get(obj.om_0.x.execute())) } this.phasesList[0] += obj.om_0.y.execute() - this.phasesExprList[0] += '+' + obj.om_0.y.toEditableString() + this.phasesExprList[0] += "+" + obj.om_0.y.toEditableString() } - this.om0xList.sort((a,b) => a - b) - let totalAdded = this.phasesList[0] + this.om0xList.sort((a, b) => a - b) for(let i = 1; i < this.om0xList.length; i++) { - this.phasesList[i] = this.phasesList[i-1] + phasesDict.get(this.om0xList[i]) - this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict.get(this.om0xList[i]) + this.phasesList[i] = this.phasesList[i - 1] + phasesDict.get(this.om0xList[i]) + this.phasesExprList[i] = this.phasesExprList[i - 1] + "+" + phasesDict.get(this.om0xList[i]) } } } - + draw(canvas) { - for(let i = 0; i < this.om0xList.length-1; i++) { + for(let i = 0; i < this.om0xList.length - 1; i++) { let om0xBegin = canvas.x2px(this.om0xList[i]) - let om0xEnd = canvas.x2px(this.om0xList[i+1]) + let om0xEnd = canvas.x2px(this.om0xList[i + 1]) let baseY = canvas.y2px(this.phasesList[i]) - let nextY = canvas.y2px(this.phasesList[i+1]) + let nextY = canvas.y2px(this.phasesList[i + 1]) canvas.drawLine(om0xBegin, baseY, om0xEnd, baseY) canvas.drawLine(om0xEnd, baseY, om0xEnd, nextY) } - + // Label this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 9b13fbd..891fdd5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -1,25 +1,25 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import { getRandomColor, textsub } from "../utils.mjs" +import { getRandomColor } from "../utils.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" -import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" +import { ensureTypeSafety, serializesByPropertyType } from "../parameters.mjs" // This file contains the default data to be imported from all other objects @@ -32,52 +32,64 @@ export class DrawableObject { * Base name of the object. Needs to be constant over time. * @return {string} Type of the object. */ - static type(){return 'Unknown'} - + static type() { + return "Unknown" + } + /** * Translated name of the object to be shown to the user. * @return {string} */ - static displayType(){return 'Unknown'} - + static displayType() { + return "Unknown" + } + /** * Translated name of the object in plural form to be shown to the user. * @return {string} */ - static displayTypeMultiple(){return 'Unknowns'} - + static displayTypeMultiple() { + return "Unknowns" + } + /** * True if this object can be created by the user, false if it can only * be instantiated by other objects * @return {boolean} */ - static createable() {return true} - + static createable() { + return true + } + /** * List of properties used in the Object Editor. - * + * * Properties are set with key as property name and * value as it's type name (e.g 'numbers', 'string'...), * an Enum for enumerations, an ObjectType for DrawableObjects - * with a specific type, a List instance for lists, a + * with a specific type, a List instance for lists, a * Dictionary instance for dictionaries, an Expression for expressions... - * + * * If the property is to be translated, the key should be passed * through the QT_TRANSLATE_NOOP macro in that form: * [QT_TRANSLATE_NOOP('prop','key')] - * Enums that are translated should be indexed in parameters.mjs and + * Enums that are translated should be indexed in parameters.mjs and * then be linked directly here. - * + * * @return {Object.} */ - static properties() {return {}} - + static properties() { + return {} + } + /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. * @return {boolean} */ - static executable() {return false} + static executable() { + return false + } /** * Imports the object from its serialized form. @@ -85,23 +97,23 @@ export class DrawableObject { */ static import(name, visible, color, labelContent, ...args) { let importedArgs = [name.toString(), visible === true, color.toString(), labelContent] - console.log('Importing', this.type(), name, args) + console.log("Importing", this.type(), name, args) for(let [name, propType] of Object.entries(this.properties())) - if(!name.startsWith('comment')) { - importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4])) + if(!name.startsWith("comment")) { + importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length - 4])) } return new this(...importedArgs) } - + /** * Base constructor for the object. * @param {string} name - Name of the object * @param {boolean} visible - true if the object is visible, false otherwise. * @param {color|string} color - Color of the object (can be string or QColor) - * @param {'null'|'name'|'name + value'} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. + * @param {"null"|"name"|"name + value"} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. * @constructor */ - constructor(name, visible = true, color = null, labelContent = 'name + value') { + constructor(name, visible = true, color = null, labelContent = "name + value") { if(color == null) color = getRandomColor() this.type = this.constructor.type() this.name = name @@ -120,11 +132,11 @@ export class DrawableObject { export() { let exportList = [this.name, this.visible, this.color.toString(), this.labelContent] for(let [name, propType] of Object.entries(this.constructor.properties())) - if(!name.startsWith('comment')) + if(!name.startsWith("comment")) exportList.push(serializesByPropertyType(propType, this[name])) return exportList } - + /** * String representing the object that will be displayed to the user. * It allows for 2 lines and translated text, but it shouldn't be too long. @@ -133,10 +145,10 @@ export class DrawableObject { getReadableString() { return `${this.name} = Unknown` } - + /** * Latex markuped version of the readable string. - * Every non latin character should be passed as latex symbols and formulas + * Every non latin character should be passed as latex symbols and formulas * should be in latex form. * See ../latex.mjs for helper methods. * @return {string} @@ -144,42 +156,42 @@ export class DrawableObject { getLatexString() { return this.getReadableString() } - + /** * Readable string content of the label depending on the value of the latexContent. * @return {string} */ getLabel() { switch(this.labelContent) { - case 'name': + case "name": return this.name - case 'name + value': + case "name + value": return this.getReadableString() - case 'null': - return '' - + case "null": + return "" + } } - + /** * Latex markup string content of the label depending on the value of the latexContent. - * Every non latin character should be passed as latex symbols and formulas + * Every non latin character should be passed as latex symbols and formulas * should be in latex form. * See ../latex.mjs for helper methods. * @return {string} */ getLatexLabel() { switch(this.labelContent) { - case 'name': + case "name": return Latex.variable(this.name) - case 'name + value': + case "name + value": return this.getLatexString() - case 'null': - return '' - + case "null": + return "" + } } - + /** * Returns the recursive list of objects this one depends on. * @return {array} @@ -190,7 +202,7 @@ export class DrawableObject { dependencies = dependencies.concat(obj.getDependenciesList()) return dependencies } - + /** * Callback method when one of the properties of the object is updated. */ @@ -203,8 +215,8 @@ export class DrawableObject { let currentObjectsByName = Objects.currentObjectsByName let properties = this.constructor.properties() for(let property in properties) - if(typeof properties[property] == 'object' && 'type' in properties[property]) - if(properties[property].type === 'Expression' && this[property] != null) { + if(typeof properties[property] == "object" && "type" in properties[property]) + if(properties[property].type === "Expression" && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { if(objName in currentObjectsByName && !this.requires.includes(currentObjectsByName[objName])) { @@ -215,8 +227,8 @@ export class DrawableObject { if(this[property].cached && this[property].requiredObjects().length > 0) // Recalculate this[property].recache() - - } else if(properties[property].type === 'ObjectType' && this[property] != null) { + + } else if(properties[property].type === "ObjectType" && this[property] != null) { // Object dependency this.requires.push(this[property]) this[property].requiredBy.push(this) @@ -225,7 +237,7 @@ export class DrawableObject { for(let req of this.requiredBy) req.update() } - + /** * Callback method when the object is about to get deleted. */ @@ -237,64 +249,65 @@ export class DrawableObject { toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this) } } - + /** * Abstract method. Draw the object onto the canvas with the. * @param {CanvasAPI} canvas */ - draw(canvas) {} - + draw(canvas) { + } + /** - * Applicates a drawFunction with two position arguments depending on - * both the posX and posY of where the label should be displayed, + * Applicates a drawFunction with two position arguments depending on + * both the posX and posY of where the label should be displayed, * and the labelPosition which declares the label should be displayed * relatively to that position. - * + * * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} offset - Margin between the position and the object to be drawn - * @param {Object.} size - Size of the label item, containing two properties, "width" and "height" - * @param {number} posX - Component of the marked position on the x-axis - * @param {number} posY - Component of the marked position on the y-axis - * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label + * @param {{width: number, height: number}} size - Size of the label item, containing two properties, "width" and "height" + * @param {number} posX - Component of the marked position on the x-axis + * @param {number} posY - Component of the marked position on the y-axis + * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label */ drawPositionDivergence(labelPosition, offset, size, posX, posY, drawFunction) { switch(labelPosition) { - case 'center': - drawFunction(posX-size.width/2, posY-size.height/2) - break; - case 'top': - case 'above': - drawFunction(posX-size.width/2, posY-size.height-offset) - break; - case 'bottom': - case 'below': - drawFunction(posX-size.width/2, posY+offset) - break; - case 'left': - drawFunction(posX-size.width-offset, posY-size.height/2) - break; - case 'right': - drawFunction(posX+offset, posY-size.height/2) - break; - case 'top-left': - case 'above-left': - drawFunction(posX-size.width, posY-size.height-offset) - break; - case 'top-right': - case 'above-right': - drawFunction(posX+offset, posY-size.height-offset) - break; - case 'bottom-left': - case 'below-left': - drawFunction(posX-size.width-offset, posY+offset) - break; - case 'bottom-right': - case 'below-right': - drawFunction(posX+offset, posY+offset) - break; + case "center": + drawFunction(posX - size.width / 2, posY - size.height / 2) + break + case "top": + case "above": + drawFunction(posX - size.width / 2, posY - size.height - offset) + break + case "bottom": + case "below": + drawFunction(posX - size.width / 2, posY + offset) + break + case "left": + drawFunction(posX - size.width - offset, posY - size.height / 2) + break + case "right": + drawFunction(posX + offset, posY - size.height / 2) + break + case "top-left": + case "above-left": + drawFunction(posX - size.width, posY - size.height - offset) + break + case "top-right": + case "above-right": + drawFunction(posX + offset, posY - size.height - offset) + break + case "bottom-left": + case "below-left": + drawFunction(posX - size.width - offset, posY + offset) + break + case "bottom-right": + case "below-right": + drawFunction(posX + offset, posY + offset) + break } } - + /** * Automatically draw text (by default the label of the object on the canvas * depending on user settings. @@ -304,55 +317,54 @@ export class DrawableObject { * depending on whether to use latex. * Then, it's displayed using the drawFunctionLatex (x,y,imageData) and * drawFunctionText (x,y,text) depending on whether to use latex. - * + * * @param {CanvasAPI} canvas * @param {string|Enum} labelPosition - Position of the label relative to the marked position - * @param {number} posX - Component of the marked position on the x-axis - * @param {number} posY - Component of the marked position on the y-axis + * @param {number} posX - Component of the marked position on the x-axis + * @param {number} posY - Component of the marked position on the y-axis * @param {boolean} forceText - Force the rendering of the label as text * @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed * @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ - drawLabel(canvas, labelPosition, posX, posY,forceText = false, - getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { + drawLabel(canvas, labelPosition, posX, posY, forceText = false, + getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { // Default functions if(getLatexFunction == null) getLatexFunction = this.getLatexLabel.bind(this) if(getTextFunction == null) getTextFunction = this.getLabel.bind(this) if(drawFunctionLatex == null) - drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height) + drawFunctionLatex = (x, y, ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height) if(drawFunctionText == null) - drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height) // Positioned from left bottom + drawFunctionText = (x, y, text, textSize) => canvas.drawVisibleText(text, x, y + textSize.height) // Positioned from left bottom // Drawing the label - let offset if(!forceText && Latex.enabled) { // With latex let drawLblCb = ((ltxImg) => { - this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) - }).bind(this) - let ltxLabel = getLatexFunction(); + this.drawPositionDivergence(labelPosition, 8 + canvas.linewidth / 2, ltxImg, posX, posY, (x, y) => drawFunctionLatex(x, y, ltxImg)) + }) + let ltxLabel = getLatexFunction() if(ltxLabel !== "") - canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) + canvas.renderLatexImage(ltxLabel, this.color, drawLblCb) } else { // Without latex let text = getTextFunction() canvas.font = `${canvas.textsize}px sans-serif` let textSize = canvas.measureText(text) - this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) + this.drawPositionDivergence(labelPosition, 8 + canvas.linewidth / 2, textSize, posX, posY, (x, y) => drawFunctionText(x, y, text, textSize)) } } - + toString() { - return this.name; + return this.name } } /** - * Class to be extended for every object on which + * Class to be extended for every object on which * an y for a x can be computed with the execute function. * If a value cannot be found during execute, it will * return null. However, theses same x values will @@ -363,32 +375,42 @@ export class ExecutableObject extends DrawableObject { * Returns the corresponding y value for an x value. * If the object isn't defined on the given x, then * this function will return null. - * + * * @param {number} x * @returns {number|null} */ - execute(x = 1) {return 0} + execute(x = 1) { + return 0 + } + /** * Returns false if the object isn't defined on the given x, true otherwise. - * + * * @param {number} x * @returns {boolean} */ - canExecute(x = 1) {return true} + canExecute(x = 1) { + return true + } + /** * Returns the simplified expression string for a given x. - * + * * @param {number} x * @returns {string|Expression} */ - simplify(x = 1) {return '0'} - + simplify(x = 1) { + return "0" + } + /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. * @return {boolean} */ - static executable() {return true} + static executable() { + return true + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs index 411e191..16aa4d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -24,18 +24,30 @@ import { ExecutableObject } from "./common.mjs" export default class DistributionFunction extends ExecutableObject { - static type(){return 'Repartition'} - static displayType(){return qsTranslate("distribution", 'Repartition')} - static displayTypeMultiple(){return qsTranslate("distribution", 'Repartition functions')} - static properties() {return { - 'comment1': QT_TRANSLATE_NOOP( - 'comment', - 'Note: Specify the probability for each value.' - ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'double', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - }} + static type() { + return "Repartition" + } + + static displayType() { + return qsTranslate("distribution", "Repartition") + } + + static displayTypeMultiple() { + return qsTranslate("distribution", "Repartition functions") + } + + static properties() { + return { + "comment1": QT_TRANSLATE_NOOP( + "comment", + "Note: Specify the probability for each value." + ), + [QT_TRANSLATE_NOOP("prop", "probabilities")]: new P.Dictionary("string", "double", /^-?[\d.,]+$/, /^-?[\d.,]+$/, "P({name_} = ", ") = "), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number" + } + } + static import(name, visible, color, labelContent, ...args) { console.log(args, args.length) if(args.length === 5) { @@ -45,99 +57,101 @@ export default class DistributionFunction extends ExecutableObject { } return super.import(name, visible, color, labelContent, ...args) } - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { - if(name == null) name = Objects.getNewName('XYZUVW', "F_") + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + probabilities = { "0": "0" }, labelPosition = "above", labelX = 1) { + if(name == null) name = Objects.getNewName("XYZUVW", "F_") super(name, visible, color, labelContent) this.probabilities = probabilities this.labelPosition = labelPosition this.labelX = labelX this.update() } - + getReadableString() { - let keys = Object.keys(this.probabilities).sort((a,b) => a-b); - let varname = this.name.substring(this.name.indexOf("_")+1) + let keys = Object.keys(this.probabilities).sort((a, b) => a - b) + let varname = this.name.substring(this.name.indexOf("_") + 1) return `${this.name}(x) = P(${varname} ≤ x)\n` + keys.map(idx => `P(${varname}=${idx})=${this.probabilities[idx]}`).join("; ") } - + getLatexString() { - let keys = Object.keys(this.probabilities).sort((a,b) => a-b); + let keys = Object.keys(this.probabilities).sort((a, b) => a - b) let funcName = Latex.variable(this.name) - let varName = Latex.variable(this.name.substring(this.name.indexOf("_")+1)) - return `\\begin{array}{l}{${funcName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}' + let varName = Latex.variable(this.name.substring(this.name.indexOf("_") + 1)) + return `\\begin{array}{l}{${funcName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + "\\end{array}" } - + execute(x = 1) { - let ret = 0; - Object.keys(this.probabilities).sort((a,b) => a-b).forEach(idx => { - if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, '.')) + let ret = 0 + Object.keys(this.probabilities).sort((a, b) => a - b).forEach(idx => { + if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, ".")) }) return ret } - - canExecute(x = 1) {return true} + + canExecute(x = 1) { + return true + } // Simplify returns the simplified string of the expression. simplify(x = 1) { return this.execute(x).toString() } - + getLabel() { switch(this.labelContent) { - case 'name': + case "name": return `${this.name}(x)` - case 'name + value': + case "name + value": return this.getReadableString() - case 'null': - return '' + case "null": + return "" } } - + draw(canvas) { - let currentY = 0; - let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) - if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { + let currentY = 0 + let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a, b) => a - b) + if(canvas.isVisible(keys[0], this.probabilities[keys[0]].replace(/,/g, "."))) { canvas.drawLine(0, canvas.y2px(0), canvas.x2px(keys[0]), canvas.y2px(0)) - if(canvas.isVisible(keys[0],0)) { - canvas.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); + if(canvas.isVisible(keys[0], 0)) { + canvas.arc(canvas.x2px(keys[0]) + 4, canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2) } } - for(let i = 0; i < keys.length-1; i++) { - let idx = keys[i]; - currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); - if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { + for(let i = 0; i < keys.length - 1; i++) { + let idx = keys[i] + currentY += parseFloat(this.probabilities[idx].replace(/,/g, ".")) + if(canvas.isVisible(idx, currentY) || canvas.isVisible(keys[i + 1], currentY)) { canvas.drawLine( - Math.max(0,canvas.x2px(idx)), + Math.max(0, canvas.x2px(idx)), canvas.y2px(currentY), - Math.min(canvas.width,canvas.x2px(keys[i+1])), + Math.min(canvas.width, canvas.x2px(keys[i + 1])), canvas.y2px(currentY) ) - if(canvas.isVisible(idx,currentY)) { + if(canvas.isVisible(idx, currentY)) { canvas.disc(canvas.x2px(idx), canvas.y2px(currentY), 4) } - if(canvas.isVisible(keys[i+1],currentY)) { - canvas.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); + if(canvas.isVisible(keys[i + 1], currentY)) { + canvas.arc(canvas.x2px(keys[i + 1]) + 4, canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2) } } } - if(canvas.isVisible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) { + if(canvas.isVisible(keys[keys.length - 1], currentY + parseFloat(this.probabilities[keys[keys.length - 1]]))) { canvas.drawLine( - Math.max(0,canvas.x2px(keys[keys.length-1])), - canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), + Math.max(0, canvas.x2px(keys[keys.length - 1])), + canvas.y2px(currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, "."))), canvas.width, - canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))) + canvas.y2px(currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, "."))) ) canvas.disc( - canvas.x2px(keys[keys.length-1]), + canvas.x2px(keys[keys.length - 1]), canvas.y2px( - currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.')) + currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, ".")) ), 4 ) } - + // Label this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 84cf45c..1e345cb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -25,39 +25,50 @@ import Latex from "../module/latex.mjs" export default class Function extends ExecutableObject { - static type(){return 'Function'} - static displayType(){return qsTranslate("function", 'Function')} - static displayTypeMultiple(){return qsTranslate("function", 'Functions')} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','expression')]: new P.Expression('x'), - [QT_TRANSLATE_NOOP('prop','definitionDomain')]: 'Domain', - [QT_TRANSLATE_NOOP('prop','destinationDomain')]: 'Domain', - 'comment1': QT_TRANSLATE_NOOP( - 'comment', - 'Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}' - ), - [QT_TRANSLATE_NOOP('prop','displayMode')]: P.Enum.FunctionDisplayType, - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - 'comment2': QT_TRANSLATE_NOOP( - 'comment', - 'The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...)' - ), - [QT_TRANSLATE_NOOP('prop','drawPoints')]: 'boolean', - [QT_TRANSLATE_NOOP('prop','drawDashedLines')]: 'boolean' - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - expression = 'x', definitionDomain = 'RPE', destinationDomain = 'R', - displayMode = 'application', labelPosition = 'above', labelX = 1, - drawPoints = true, drawDashedLines = true) { - if(name == null) name = Objects.getNewName('fghjqlmnopqrstuvwabcde') + static type() { + return "Function" + } + + static displayType() { + return qsTranslate("function", "Function") + } + + static displayTypeMultiple() { + return qsTranslate("function", "Functions") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "expression")]: new P.Expression("x"), + [QT_TRANSLATE_NOOP("prop", "definitionDomain")]: "Domain", + [QT_TRANSLATE_NOOP("prop", "destinationDomain")]: "Domain", + "comment1": QT_TRANSLATE_NOOP( + "comment", + "Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}" + ), + [QT_TRANSLATE_NOOP("prop", "displayMode")]: P.Enum.FunctionDisplayType, + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number", + "comment2": QT_TRANSLATE_NOOP( + "comment", + "The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...)" + ), + [QT_TRANSLATE_NOOP("prop", "drawPoints")]: "boolean", + [QT_TRANSLATE_NOOP("prop", "drawDashedLines")]: "boolean" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + expression = "x", definitionDomain = "RPE", destinationDomain = "R", + displayMode = "application", labelPosition = "above", labelX = 1, + drawPoints = true, drawDashedLines = true) { + if(name == null) name = Objects.getNewName("fghjqlmnopqrstuvwabcde") super(name, visible, color, labelContent) - if(typeof expression == 'number' || typeof expression == 'string') expression = new Expression(expression.toString()) + if(typeof expression == "number" || typeof expression == "string") expression = new Expression(expression.toString()) this.expression = expression - if(typeof definitionDomain == 'string') definitionDomain = parseDomain(definitionDomain) + if(typeof definitionDomain == "string") definitionDomain = parseDomain(definitionDomain) this.definitionDomain = definitionDomain - if(typeof destinationDomain == 'string') destinationDomain = parseDomain(destinationDomain) + if(typeof destinationDomain == "string") destinationDomain = parseDomain(destinationDomain) this.destinationDomain = destinationDomain this.displayMode = displayMode this.labelPosition = labelPosition @@ -65,17 +76,17 @@ export default class Function extends ExecutableObject { this.drawPoints = drawPoints this.drawDashedLines = drawDashedLines } - + getReadableString() { - if(this.displayMode === 'application') { - return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⟼ ${this.expression.toString()}` + if(this.displayMode === "application") { + return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${" ".repeat(this.name.length)}x ⟼ ${this.expression.toString()}` } else { return `${this.name}(x) = ${this.expression.toString()}\nD${textsub(this.name)} = ${this.definitionDomain}` } } - + getLatexString() { - if(this.displayMode === 'application') { + if(this.displayMode === "application") { return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { @@ -88,17 +99,17 @@ export default class Function extends ExecutableObject { return this.expression.execute(x) return null } - + canExecute(x = 1) { return this.definitionDomain.includes(x) } - + simplify(x = 1) { if(this.definitionDomain.includes(x)) return this.expression.simplify(x) - return '' + return "" } - + draw(canvas) { Function.drawFunction(canvas, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) // Label @@ -112,7 +123,7 @@ export default class Function extends ExecutableObject { static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { let pxprecision = 10 let previousX = canvas.px2x(0) - let previousY = null; + let previousY = null if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) { // Point based functions. previousX = definitionDomain.next(previousX) @@ -121,16 +132,16 @@ export default class Function extends ExecutableObject { if(!drawPoints && !drawDash) return while(previousX !== null && canvas.x2px(previousX) < canvas.width) { // Reconverted for canvas to fix for logarithmic scales. - let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); + let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX) + pxprecision)) let currentY = expr.execute(currentX) - if(currentX === null) break; + if(currentX === null) break if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && (destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) { if(drawDash) canvas.drawDashedLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) if(drawPoints) { - canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX) - 5, canvas.y2px(previousY) - 1, 10, 2) + canvas.fillRect(canvas.x2px(previousX) - 1, canvas.y2px(previousY) - 5, 2, 10) } } previousX = currentX @@ -138,8 +149,8 @@ export default class Function extends ExecutableObject { } if(drawPoints) { // Drawing the last cross - canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX) - 5, canvas.y2px(previousY) - 1, 10, 2) + canvas.fillRect(canvas.x2px(previousX) - 1, canvas.y2px(previousY) - 5, 2, 10) } } else { // Use max precision if function is trigonometrical on log scale. @@ -154,9 +165,9 @@ export default class Function extends ExecutableObject { if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { // Should draw up to currentX, but NOT at previousX. // Need to find the starting point. - let tmpPx = px-pxprecision + let tmpPx = px - pxprecision do { - tmpPx++; + tmpPx++ previousX = canvas.px2x(tmpPx) } while(!definitionDomain.includes(previousX)) // Recaclulate previousY @@ -166,16 +177,16 @@ export default class Function extends ExecutableObject { // Augmenting the pixel precision until this condition is fulfilled. let tmpPx = px do { - tmpPx--; + tmpPx-- currentX = canvas.px2x(tmpPx) } while(!definitionDomain.includes(currentX) && currentX !== previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) - let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.height)) + let maxvariation = (canvas.px2y(0) - canvas.px2y(canvas.height)) if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { let currentY = expr.execute(currentX) if(destinationDomain.includes(currentY)) { - if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY-currentY) < maxvariation) { + if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY - currentY) < maxvariation) { canvas.drawLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 2c07836..d179481 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -24,53 +24,63 @@ import Latex from "../module/latex.mjs" import { DrawableObject } from "./common.mjs" -export default class Point extends DrawableObject { - static type(){return 'Point'} - static displayType(){return qsTranslate("point", 'Point')} - static displayTypeMultiple(){return qsTranslate("point", 'Points')} - - static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','pointStyle')]: new P.Enum('●', '✕', '+') - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - x = 1, y = 0, labelPosition = 'above', pointStyle = '●') { - if(name == null) name = Objects.getNewName('ABCDEFJKLMNOPQRSTUVW') +export default class Point extends DrawableObject { + static type() { + return "Point" + } + + static displayType() { + return qsTranslate("point", "Point") + } + + static displayTypeMultiple() { + return qsTranslate("point", "Points") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "x")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "y")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "pointStyle")]: new P.Enum("●", "✕", "+") + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + x = 1, y = 0, labelPosition = "above", pointStyle = "●") { + if(name == null) name = Objects.getNewName("ABCDEFJKLMNOPQRSTUVW") super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) + if(typeof x == "number" || typeof x == "string") x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) + if(typeof y == "number" || typeof y == "string") y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.pointStyle = pointStyle } - + getReadableString() { return `${this.name} = (${this.x}, ${this.y})` } - + getLatexString() { return `${Latex.variable(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` } - + draw(canvas) { let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] - let pointSize = 8+(canvas.linewidth*2) + let pointSize = 8 + (canvas.linewidth * 2) switch(this.pointStyle) { - case '●': - canvas.disc(canvasX, canvasY, pointSize/2) - break; - case '✕': - canvas.drawLine(canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2) - canvas.drawLine(canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2) - break; - case '+': - canvas.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2) - canvas.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) - break; + case "●": + canvas.disc(canvasX, canvasY, pointSize / 2) + break + case "✕": + canvas.drawLine(canvasX - pointSize / 2, canvasY - pointSize / 2, canvasX + pointSize / 2, canvasY + pointSize / 2) + canvas.drawLine(canvasX - pointSize / 2, canvasY + pointSize / 2, canvasX + pointSize / 2, canvasY - pointSize / 2) + break + case "+": + canvas.fillRect(canvasX - pointSize / 2, canvasY - 1, pointSize, 2) + canvas.fillRect(canvasX - 1, canvasY - pointSize / 2, 2, pointSize) + break } this.drawLabel(canvas, this.labelPosition, canvasX, canvasY) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 310444e..0328041 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -26,27 +26,37 @@ import Function from "./function.mjs" export default class Sequence extends ExecutableObject { - static type(){return 'Sequence'} - static displayType(){return qsTranslate("sequence", 'Sequence')} - static displayTypeMultiple(){return qsTranslate("sequence", 'Sequences')} - - static properties() {return { - [QT_TRANSLATE_NOOP('prop','drawPoints')]: 'boolean', - [QT_TRANSLATE_NOOP('prop','drawDashedLines')]: 'boolean', - [QT_TRANSLATE_NOOP('prop','defaultExpression')]: new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[n+', '] = ', true), - 'comment1': QT_TRANSLATE_NOOP( - 'comment', - 'Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁...' - ), - [QT_TRANSLATE_NOOP('prop','baseValues')]: new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[', '] = '), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', - }} - - constructor(name = null, visible = true, color = null, labelContent = 'name + value', - drawPoints = true, drawDashedLines = true, defaultExp = {1: "n"}, - baseValues = {0: 0}, labelPosition = 'above', labelX = 1) { - if(name == null) name = Objects.getNewName('uvwPSUVWabcde') + static type() { + return "Sequence" + } + + static displayType() { + return qsTranslate("sequence", "Sequence") + } + + static displayTypeMultiple() { + return qsTranslate("sequence", "Sequences") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "drawPoints")]: "boolean", + [QT_TRANSLATE_NOOP("prop", "drawDashedLines")]: "boolean", + [QT_TRANSLATE_NOOP("prop", "defaultExpression")]: new P.Dictionary("string", "int", /^.+$/, /^\d+$/, "{name}[n+", "] = ", true), + "comment1": QT_TRANSLATE_NOOP( + "comment", + "Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁..." + ), + [QT_TRANSLATE_NOOP("prop", "baseValues")]: new P.Dictionary("string", "int", /^.+$/, /^\d+$/, "{name}[", "] = "), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position, + [QT_TRANSLATE_NOOP("prop", "labelX")]: "number" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "name + value", + drawPoints = true, drawDashedLines = true, defaultExp = { 1: "n" }, + baseValues = { 0: 0 }, labelPosition = "above", labelX = 1) { + if(name == null) name = Objects.getNewName("uvwPSUVWabcde") super(name, visible, color, labelContent) this.drawPoints = drawPoints this.drawDashedLines = drawDashedLines @@ -58,68 +68,71 @@ export default class Sequence extends ExecutableObject { } update() { - console.log('Updating sequence', this.sequence) + console.log("Updating sequence", this.sequence) super.update() if( this.sequence == null || this.baseValues !== this.sequence.baseValues || this.sequence.name !== this.name || this.sequence.expr !== Object.values(this.defaultExpression)[0] || - this.sequence.valuePlus !== Object.keys(this.defaultExpression)[0] + this.sequence.valuePlus.toString() !== Object.keys(this.defaultExpression)[0] ) this.sequence = new MathSequence( - this.name, this.baseValues, - Object.keys(this.defaultExpression)[0], + this.name, this.baseValues, + parseFloat(Object.keys(this.defaultExpression)[0]), Object.values(this.defaultExpression)[0] ) } - + getReadableString() { return this.sequence.toString() } - + getLatexString() { return this.sequence.toLatexString() } - + execute(x = 1) { if(x % 1 === 0) return this.sequence.execute(x) return null } - canExecute(x = 1) {return x%1 === 0} - + + canExecute(x = 1) { + return x % 1 === 0 + } + // Simplify returns the simplified string of the expression. simplify(x = 1) { if(x % 1 === 0) return this.sequence.simplify(x) return null } - + getLabel() { switch(this.labelContent) { - case 'name': + case "name": return `(${this.name}ₙ)` - case 'name + value': + case "name + value": return this.getReadableString() - case 'null': - return '' + case "null": + return "" } } - + getLatexLabel() { switch(this.labelContent) { - case 'name': + case "name": return `(${Latex.variable(this.name)}_n)` - case 'name + value': + case "name + value": return this.getLatexString() - case 'null': - return '' + case "null": + return "" } } - + draw(canvas) { Function.drawFunction(canvas, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) - + // Label this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index e7f7a05..af79824 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -24,72 +24,85 @@ import Latex from "../module/latex.mjs" import { DrawableObject } from "./common.mjs" -export default class Text extends DrawableObject { - static type(){return 'Text'} - static displayType(){return qsTranslate("text", 'Text')} - static displayTypeMultiple(){return qsTranslate("text", 'Texts')} - static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, - [QT_TRANSLATE_NOOP('prop','text')]: 'string', - 'comment1': QT_TRANSLATE_NOOP( - 'comment', - 'If you have latex enabled, you can use use latex markup in between $$ to create equations.' - ), - [QT_TRANSLATE_NOOP('prop','disableLatex')]: 'boolean' - }} - - constructor(name = null, visible = true, color = null, labelContent = 'null', - x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { - if(name == null) name = Objects.getNewName('t') +export default class Text extends DrawableObject { + static type() { + return "Text" + } + + static displayType() { + return qsTranslate("text", "Text") + } + + static displayTypeMultiple() { + return qsTranslate("text", "Texts") + } + + static properties() { + return { + [QT_TRANSLATE_NOOP("prop", "x")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "y")]: new P.Expression(), + [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Positioning, + [QT_TRANSLATE_NOOP("prop", "text")]: "string", + "comment1": QT_TRANSLATE_NOOP( + "comment", + "If you have latex enabled, you can use use latex markup in between $$ to create equations." + ), + [QT_TRANSLATE_NOOP("prop", "disableLatex")]: "boolean" + } + } + + constructor(name = null, visible = true, color = null, labelContent = "null", + x = 1, y = 0, labelPosition = "center", text = "New text", disableLatex = false) { + if(name == null) name = Objects.getNewName("t") super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) + if(typeof x == "number" || typeof x == "string") x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) + if(typeof y == "number" || typeof y == "string") y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.text = text this.disableLatex = disableLatex } - + getReadableString() { return `${this.name} = "${this.text}"` } - + latexMarkupText() { // Check whether the text contains latex escaped elements. let txt = [] - this.text.split('$$').forEach(function(t) { txt = txt.concat(Latex.variable(t, true).replace(/\$\$/g, '').split('$')) }) + this.text.split("$$").forEach(function(t) { + txt = txt.concat(Latex.variable(t, true).replace(/\$\$/g, "").split("$")) + }) let newTxt = txt[0] let i // Split between normal text and latex escaped. - for(i = 0; i < txt.length-1; i++) + for(i = 0; i < txt.length - 1; i++) if(i & 0x01) // Every odd number - newTxt += '\\textsf{'+Latex.variable(txt[i+1]) + newTxt += "\\textsf{" + Latex.variable(txt[i + 1]) else - newTxt += '}'+txt[i+1] + newTxt += "}" + txt[i + 1] // Finished by a } - if(i & 0x01) + if(i & 0x01) newTxt += "{" return newTxt } - + getLatexString() { return `${Latex.variable(this.name)} = "\\textsf{${this.latexMarkupText()}}"` } - + getLabel() { return this.text } - + getLatexLabel() { return `\\textsf{${this.latexMarkupText()}}` } - + draw(canvas) { - let yOffset = this.disableLatex ? canvas.textsize-4 : 0 - this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) + let yOffset = this.disableLatex ? canvas.textsize - 4 : 0 + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute()) + yOffset, this.disableLatex) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 7c6d422..11f6a5a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -72,30 +72,29 @@ export default class XCursor extends DrawableObject { ${this.getTargetValueLatexLabel()} \\end{array}` } - - getTargetValueLabel() { - var t = this.targetElement - var approx = '' + + getApprox() { + let approx = '' if(this.approximate) { - approx = (t.execute(this.x.execute())) + approx = (this.targetElement.execute(this.x.execute())) let intLength = Math.round(approx).toString().length let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1) approx = approx.toPrecision(rounding + intLength) } + return approx + } + + getTargetValueLabel() { + const t = this.targetElement + const approx = this.getApprox() return `${t.name}(${this.name}) = ${t.simplify(this.x.toEditableString())}` + (this.approximate ? ' ≈ ' + approx : '') } getTargetValueLatexLabel() { - let t = this.targetElement - let approx = '' - if(this.approximate) { - approx = (t.execute(this.x.execute())) - let intLength = Math.round(approx).toString().length - let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1) - approx = approx.toPrecision(rounding + intLength) - } - let simpl = t.simplify(this.x.toEditableString()) + const t = this.targetElement + const approx = this.getApprox() + const simpl = t.simplify(this.x.toEditableString()) return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.latexMarkup ? simpl.latexMarkup : Latex.variable(simpl)}` + (this.approximate ? ' \\simeq ' + approx : '') } @@ -104,16 +103,13 @@ export default class XCursor extends DrawableObject { switch(this.labelContent) { case 'name': return this.name - break; case 'name + value': switch(this.targetValuePosition) { case 'Next to target': case 'Hidden': return `${this.name} = ${this.x.toString()}` - break; case 'With label': return this.getReadableString() - break; } case 'null': return '' @@ -124,16 +120,13 @@ export default class XCursor extends DrawableObject { switch(this.labelContent) { case 'name': return Latex.variable(this.name) - break; case 'name + value': switch(this.targetValuePosition) { case 'Next to target': case 'Hidden': return `${Latex.variable(this.name)} = ${this.x.latexMarkup}` - break; case 'With label': return this.getLatexString() - break; } case 'null': return '' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index b301997..1078518 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -15,15 +15,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import {parseDomain, Expression as Expr, Domain} from "./math/index.mjs" +import { parseDomain, Expression as Expr, Domain } from "./math/index.mjs" import Objects from "./module/objects.mjs" -const NONE = class Empty {} +const NONE = class Empty { +} let stringValuesValidators = { - 'int': [parseInt, (x) => !isNaN(x)], - 'double': [parseFloat, (x) => !isNaN(x)], - 'string': [(x) => x, () => true] + "int": [parseInt, (x) => !isNaN(x)], + "double": [parseFloat, (x) => !isNaN(x)], + "string": [(x) => x, () => true] } let stringValidatorTypes = Object.keys(stringValuesValidators) @@ -52,17 +53,17 @@ class PropertyType { export class Expression extends PropertyType { constructor(...variables) { super() - this.type = 'Expression' + this.type = "Expression" this.variables = variables } - + toString() { - return this.variables.length === 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + return this.variables.length === 0 ? "Number" : `Expression(${this.variables.join(", ")})` } parse(value) { let result = NONE - if(typeof value == 'string') + if(typeof value == "string") try { result = new Expr(value) } catch(e) { @@ -86,14 +87,14 @@ export class Expression extends PropertyType { export class Enum extends PropertyType { constructor(...values) { super() - this.type = 'Enum' + this.type = "Enum" this.values = values this.legacyValues = {} - this.translatedValues = values.map(x => qsTranslate('parameters', x)) + this.translatedValues = values.map(x => qsTranslate("parameters", x)) } - + toString() { - return `${this.type}(${this.values.join(', ')})` + return `${this.type}(${this.values.join(", ")})` } parse(value) { @@ -111,28 +112,28 @@ export class Enum extends PropertyType { else if(this.legacyValues[value]) return this.legacyValues[value] else - throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(', ')}.`) + throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(", ")}.`) } } export class ObjectType extends PropertyType { - constructor(objType, allowNull=false) { + constructor(objType, allowNull = false) { super() - this.type = 'ObjectType' + this.type = "ObjectType" this.objType = objType this.allowNull = allowNull } - + toString() { return this.objType } parse(name) { let result = NONE - if(typeof name == 'string' && name in Objects.currentObjectsByName) { + if(typeof name == "string" && name in Objects.currentObjectsByName) { let obj = Objects.currentObjectsByName[name] - if (obj.type === this.objType || (this.objType === 'ExecutableObject' && obj.execute)) { + if(obj.type === this.objType || (this.objType === "ExecutableObject" && obj.execute)) { result = obj } else { // Silently error and return null @@ -147,7 +148,7 @@ export class ObjectType extends PropertyType { export(value) { if(value == null && this.allowNull) return null - else if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) + else if(value.type === this.objType || (this.objType === "ExecutableObject" && value.execute)) return value.name else throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`) @@ -156,28 +157,28 @@ export class ObjectType extends PropertyType { export class List extends PropertyType { - constructor(type, format = /^.+$/, label = '', forbidAdding = false) { + constructor(type, format = /^.+$/, label = "", forbidAdding = false) { super() // type can be string, int and double. - this.type = 'List' + this.type = "List" this.valueType = type if(!stringValidatorTypes.includes(this.valueType)) - throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(', ')}.`) + throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(", ")}.`) this.format = format this.label = label this.forbidAdding = forbidAdding } - + toString() { return `${this.type}(${this.valueType}:${this.format})` } parse(value) { let result = NONE - if(typeof value == 'object' && value.__proto__ === Array) { + if(typeof value == "object" && value.__proto__ === Array) { let valid = 0 for(let v of value) { - if (this.format.test(v)) { + if(this.format.test(v)) { v = stringValuesValidators[this.valueType][0](v) if(stringValuesValidators[this.valueType][1](v)) valid++ @@ -190,7 +191,7 @@ export class List extends PropertyType { } export(value) { - if(typeof value == 'object' && value.__proto__ === Array) + if(typeof value == "object" && value.__proto__ === Array) return value else throw new TypeError(`Exportation error: ${value} not a list.`) @@ -200,10 +201,10 @@ export class List extends PropertyType { export class Dictionary extends PropertyType { - constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { + constructor(type, keyType = "string", format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = "", postKeyLabel = ": ", forbidAdding = false) { super() // type & keyType can be string, int and double. - this.type = 'Dict' + this.type = "Dict" this.valueType = type this.keyType = keyType this.format = format @@ -219,10 +220,10 @@ export class Dictionary extends PropertyType { parse(value) { let result = NONE - if(typeof value == 'object' && value.__proto__ !== Array) { + if(typeof value == "object" && value.__proto__ !== Array) { let dict = [] for(let [k, v] of Object.entries(value)) { - if (this.format.test(v) && this.keyFormat.test(k)) { + if(this.format.test(v) && this.keyFormat.test(k)) { k = stringValuesValidators[this.keyType][0](k) v = stringValuesValidators[this.valueType][0](v) if(stringValuesValidators[this.keyType][1](k)) @@ -237,7 +238,7 @@ export class Dictionary extends PropertyType { } export(value) { - if(typeof value == 'object' && value.__proto__ !== Array) + if(typeof value == "object" && value.__proto__ !== Array) return value else throw new TypeError(`Exportation error: ${value} not a dictionary.`) @@ -247,51 +248,51 @@ export class Dictionary extends PropertyType { // Common parameters for Enums Enum.Position = new Enum( - QT_TRANSLATE_NOOP('parameters', 'above'), - QT_TRANSLATE_NOOP('parameters', 'below'), - QT_TRANSLATE_NOOP('parameters', 'left'), - QT_TRANSLATE_NOOP('parameters', 'right'), - QT_TRANSLATE_NOOP('parameters', 'above-left'), - QT_TRANSLATE_NOOP('parameters', 'above-right'), - QT_TRANSLATE_NOOP('parameters', 'below-left'), - QT_TRANSLATE_NOOP('parameters', 'below-right') + QT_TRANSLATE_NOOP("parameters", "above"), + QT_TRANSLATE_NOOP("parameters", "below"), + QT_TRANSLATE_NOOP("parameters", "left"), + QT_TRANSLATE_NOOP("parameters", "right"), + QT_TRANSLATE_NOOP("parameters", "above-left"), + QT_TRANSLATE_NOOP("parameters", "above-right"), + QT_TRANSLATE_NOOP("parameters", "below-left"), + QT_TRANSLATE_NOOP("parameters", "below-right") ) Enum.Position.legacyValues = { - 'top': 'above', - 'bottom': 'below', - 'top-left': 'above-left', - 'top-right': 'above-right', - 'bottom-left': 'below-left', - 'bottom-right': 'below-right', + "top": "above", + "bottom": "below", + "top-left": "above-left", + "top-right": "above-right", + "bottom-left": "below-left", + "bottom-right": "below-right" } Enum.Positioning = new Enum( - QT_TRANSLATE_NOOP('parameters', 'center'), - QT_TRANSLATE_NOOP('parameters', 'top'), - QT_TRANSLATE_NOOP('parameters', 'bottom'), - QT_TRANSLATE_NOOP('parameters', 'left'), - QT_TRANSLATE_NOOP('parameters', 'right'), - QT_TRANSLATE_NOOP('parameters', 'top-left'), - QT_TRANSLATE_NOOP('parameters', 'top-right'), - QT_TRANSLATE_NOOP('parameters', 'bottom-left'), - QT_TRANSLATE_NOOP('parameters', 'bottom-right') + QT_TRANSLATE_NOOP("parameters", "center"), + QT_TRANSLATE_NOOP("parameters", "top"), + QT_TRANSLATE_NOOP("parameters", "bottom"), + QT_TRANSLATE_NOOP("parameters", "left"), + QT_TRANSLATE_NOOP("parameters", "right"), + QT_TRANSLATE_NOOP("parameters", "top-left"), + QT_TRANSLATE_NOOP("parameters", "top-right"), + QT_TRANSLATE_NOOP("parameters", "bottom-left"), + QT_TRANSLATE_NOOP("parameters", "bottom-right") ) Enum.FunctionDisplayType = new Enum( - QT_TRANSLATE_NOOP('parameters', 'application'), - QT_TRANSLATE_NOOP('parameters', 'function') + QT_TRANSLATE_NOOP("parameters", "application"), + QT_TRANSLATE_NOOP("parameters", "function") ) Enum.BodePass = new Enum( - QT_TRANSLATE_NOOP('parameters', 'high'), - QT_TRANSLATE_NOOP('parameters', 'low') + QT_TRANSLATE_NOOP("parameters", "high"), + QT_TRANSLATE_NOOP("parameters", "low") ) Enum.XCursorValuePosition = new Enum( - QT_TRANSLATE_NOOP('parameters', 'Next to target'), - QT_TRANSLATE_NOOP('parameters', 'With label'), - QT_TRANSLATE_NOOP('parameters', 'Hidden') + QT_TRANSLATE_NOOP("parameters", "Next to target"), + QT_TRANSLATE_NOOP("parameters", "With label"), + QT_TRANSLATE_NOOP("parameters", "Hidden") ) /** @@ -303,23 +304,23 @@ Enum.XCursorValuePosition = new Enum( export function ensureTypeSafety(propertyType, value) { let result let error = false - if(typeof propertyType == 'string') + if(typeof propertyType == "string") switch(propertyType) { - case 'string': + case "string": result = value - error = typeof value !== 'string' + error = typeof value !== "string" break - case 'number': + case "number": result = parseFloat(value) error = isNaN(result) break - case 'boolean': + case "boolean": result = value error = value !== true && value !== false break - case 'Domain': + case "Domain": try { - error = typeof value !== 'string' + error = typeof value !== "string" if(!error) result = parseDomain(value) } catch(e) { @@ -353,18 +354,18 @@ export function ensureTypeSafety(propertyType, value) { */ export function serializesByPropertyType(propertyType, value) { let result - if(typeof propertyType == 'string') + if(typeof propertyType == "string") switch(propertyType) { - case 'string': + case "string": result = value.toString() break - case 'number': + case "number": result = parseFloat(value) break - case 'boolean': + case "boolean": result = value === true break - case 'Domain': + case "Domain": if(value instanceof Domain) result = value.toString() else diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs index 3313a1b..72a9a4b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -19,30 +19,30 @@ export default class InputExpression { constructor(expression) { - this.position = 0; - this.input = expression; + this.position = 0 + this.input = expression } - + next() { - return this.input[this.position++]; + return this.input[this.position++] } - + peek() { - return this.input[this.position]; + return this.input[this.position] } - + skip(char) { if(!this.atEnd() && this.peek() === char) { - this.position++; + this.position++ } else { - this.raise("Unexpected character " + this.peek() + ". Expected character " + char); + this.raise("Unexpected character " + this.peek() + ". Expected character " + char) } } - + atEnd() { - return this.position >= this.input.length; + return this.position >= this.input.length } - + raise(message) { throw new SyntaxError(message + " at " + this.position + ".") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs index 9c30991..36d4c8c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -25,8 +25,8 @@ export const CONSTANTS = { "infinity": Infinity, "∞": Infinity, "e": Math.E -}; -export const CONSTANTS_LIST = Object.keys(CONSTANTS); +} +export const CONSTANTS_LIST = Object.keys(CONSTANTS) export const FUNCTIONS = { // The functions commented are the one either not implemented @@ -36,78 +36,78 @@ export const FUNCTIONS = { //'-': (x) => -x, //'!' // Other operations - 'length': (s) => Array.isArray(s) ? s.length : String(s).length, + "length": (s) => Array.isArray(s) ? s.length : String(s).length, // Boolean functions - 'not': (x) => !x, + "not": (x) => !x, // Math functions - 'abs': Math.abs, - 'acos': Math.acos, - 'acosh': Math.acosh, - 'asin': Math.asin, - 'asinh': Math.asinh, - 'atan': Math.atan, - 'atan2': Math.atan2, - 'atanh': Math.atanh, - 'cbrt': Math.cbrt, - 'ceil': Math.ceil, + "abs": Math.abs, + "acos": Math.acos, + "acosh": Math.acosh, + "asin": Math.asin, + "asinh": Math.asinh, + "atan": Math.atan, + "atan2": Math.atan2, + "atanh": Math.atanh, + "cbrt": Math.cbrt, + "ceil": Math.ceil, //'clz32': Math.clz32, - 'cos': Math.cos, - 'cosh': Math.cosh, - 'exp': Math.exp, - 'expm1': Math.expm1, - 'floor': Math.floor, + "cos": Math.cos, + "cosh": Math.cosh, + "exp": Math.exp, + "expm1": Math.expm1, + "floor": Math.floor, //'fround': Math.fround, - 'hypot': Math.hypot, + "hypot": Math.hypot, //'imul': Math.imul, - 'lg': Math.log10, - 'ln': Math.log, - 'log': Math.log, - 'log10': Math.log10, - 'log1p': Math.log1p, - 'log2': Math.log2, - 'max': Math.max, - 'min': Math.min, - 'pow': Math.log2, - 'random': Math.random, - 'round': Math.round, - 'sign': Math.sign, - 'sin': Math.sin, - 'sinh': Math.sinh, - 'sqrt': Math.sqrt, - 'tan': Math.tan, - 'tanh': Math.tanh, - 'trunc': Math.trunc, + "lg": Math.log10, + "ln": Math.log, + "log": Math.log, + "log10": Math.log10, + "log1p": Math.log1p, + "log2": Math.log2, + "max": Math.max, + "min": Math.min, + "pow": Math.log2, + "random": Math.random, + "round": Math.round, + "sign": Math.sign, + "sin": Math.sin, + "sinh": Math.sinh, + "sqrt": Math.sqrt, + "tan": Math.tan, + "tanh": Math.tanh, + "trunc": Math.trunc, // Functions in expr-eval, ported here. - 'fac': Polyfill.factorial, - 'gamma': Polyfill.gamma, - 'Γ': Polyfill.gamma, - 'roundTo': (x, exp) => Number(x).toFixed(exp), + "fac": Polyfill.factorial, + "gamma": Polyfill.gamma, + "Γ": Polyfill.gamma, + "roundTo": (x, exp) => Number(x).toFixed(exp), // 'map': Polyfill.arrayMap, // 'fold': Polyfill.arrayFold, // 'filter': Polyfill.arrayFilter, // 'indexOf': Polyfill.indexOf, // 'join': Polyfill.arrayJoin, // Integral & derivative (only here for autocomplete). - 'integral': () => 0, // TODO: Implement - 'derivative': () => 0, + "integral": () => 0, // TODO: Implement + "derivative": () => 0 } -export const FUNCTIONS_LIST = Object.keys(FUNCTIONS); +export const FUNCTIONS_LIST = Object.keys(FUNCTIONS) export class P { // Parameter class. - constructor(type, name = '', optional = false, multipleAllowed = false) { + constructor(type, name = "", optional = false, multipleAllowed = false) { this.name = name this.type = type this.optional = optional this.multipleAllowed = multipleAllowed } - + toString() { let base_string = this.type - if(this.name !== '') + if(this.name !== "") base_string = `${this.name}: ${base_string}` if(this.multipleAllowed) - base_string += '...' + base_string += "..." if(!this.optional) base_string = `<${base_string}>` else @@ -116,59 +116,59 @@ export class P { } } -export let string = new P('string') -export let bool = new P('bool') -export let number = new P('number') -export let array = new P('array') +export let string = new P("string") +export let bool = new P("bool") +export let number = new P("number") +export let array = new P("array") export const FUNCTIONS_USAGE = { - 'length': [string], - 'not': [bool], + "length": [string], + "not": [bool], // Math functions - 'abs': [number], - 'acos': [number], - 'acosh': [number], - 'asin': [number], - 'asinh': [number], - 'atan': [number], - 'atan2': [number], - 'atanh': [number], - 'cbrt': [number], - 'ceil': [number], + "abs": [number], + "acos": [number], + "acosh": [number], + "asin": [number], + "asinh": [number], + "atan": [number], + "atan2": [number], + "atanh": [number], + "cbrt": [number], + "ceil": [number], //'clz32': [number], - 'cos': [number], - 'cosh': [number], - 'exp': [number], - 'expm1': [number], - 'floor': [number], + "cos": [number], + "cosh": [number], + "exp": [number], + "expm1": [number], + "floor": [number], //'fround': [number], - 'hypot': [number], + "hypot": [number], //'imul': [number], - 'lg': [number], - 'ln': [number], - 'log': [number], - 'log10': [number], - 'log1p': [number], - 'log2': [number], - 'max': [number, number, new P('numbers', '', true, true)], - 'min': [number, number, new P('numbers', '', true, true)], - 'pow': [number, new P('number', 'exp')], - 'random': [number, number], - 'round': [number], - 'sign': [number], - 'sin': [number], - 'sinh': [number], - 'sqrt': [number], - 'tan': [number], - 'tanh': [number], - 'trunc': [number], + "lg": [number], + "ln": [number], + "log": [number], + "log10": [number], + "log1p": [number], + "log2": [number], + "max": [number, number, new P("numbers", "", true, true)], + "min": [number, number, new P("numbers", "", true, true)], + "pow": [number, new P("number", "exp")], + "random": [number, number], + "round": [number], + "sign": [number], + "sin": [number], + "sinh": [number], + "sqrt": [number], + "tan": [number], + "tanh": [number], + "trunc": [number], // Functions in expr-eval, ported here. - 'fac': [number], - 'gamma': [number], - 'Γ': [number], - 'roundTo': [number, new P('number')], + "fac": [number], + "gamma": [number], + "Γ": [number], + "roundTo": [number, new P("number")], // Function manipulation - 'derivative': [new P('f'), new P('string', 'var', true), number], - 'integral': [new P('from'), new P('to'), new P('f'), new P('string', 'var', true)], + "derivative": [new P("f"), new P("string", "var", true), number], + "integral": [new P("from"), new P("to"), new P("f"), new P("string", "var", true)] } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs index 2dd8620..a8552fc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs @@ -1,17 +1,17 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,9 +20,9 @@ import * as Reference from "./reference.mjs" const WHITESPACES = " \t\n\r" -const STRING_LIMITERS = '"\'`'; -const OPERATORS = "+-*/^%?:=!><"; -const PUNCTUATION = "()[]{},."; +const STRING_LIMITERS = "\"'`" +const OPERATORS = "+-*/^%?:=!><" +const PUNCTUATION = "()[]{},." const NUMBER_CHARS = "0123456789" const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ" @@ -41,8 +41,8 @@ export const TokenType = { export class Token { constructor(type, value, startPosition) { - this.type = type; - this.value = value; + this.type = type + this.value = value this.startPosition = startPosition } } @@ -55,120 +55,120 @@ export class ExpressionTokenizer { * @param {boolean} errorOnUnknown */ constructor(input, tokenizeWhitespaces = false, errorOnUnknown = true) { - this.input = input; - this.currentToken = null; + this.input = input + this.currentToken = null this.tokenizeWhitespaces = tokenizeWhitespaces this.errorOnUnknown = errorOnUnknown } - + skipWhitespaces() { while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek())) - this.input.next(); + this.input.next() } - + readWhitespaces() { - let included = ""; + let included = "" while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek())) { - included += this.input.next(); + included += this.input.next() } - return new Token(TokenType.WHITESPACE, included, this.input.position-included.length) + return new Token(TokenType.WHITESPACE, included, this.input.position - included.length) } - + readString() { - let delimitation = this.input.peek(); + let delimitation = this.input.peek() if(STRING_LIMITERS.includes(delimitation)) { this.input.skip(delimitation) - let included = ""; - let justEscaped = false; + let included = "" + let justEscaped = false while(!this.input.atEnd() && (!STRING_LIMITERS.includes(this.input.peek()) || justEscaped)) { justEscaped = this.input.peek() === "\\" if(!justEscaped) - included += this.input.next(); + included += this.input.next() } this.input.skip(delimitation) - let token = new Token(TokenType.STRING, included, this.input.position-included.length) + let token = new Token(TokenType.STRING, included, this.input.position - included.length) token.limitator = delimitation return token } else { this.input.raise("Unexpected " + delimitation + ". Expected string delimitator") } } - + readNumber() { - let included = ""; - let hasDot = false; - while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === '.')) { + let included = "" + let hasDot = false + while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === ".")) { if(this.input.peek() === ".") { if(hasDot) this.input.raise("Unexpected '.'. Expected digit") - hasDot = true; + hasDot = true } - included += this.input.next(); + included += this.input.next() } - return new Token(TokenType.NUMBER, included, this.input.position-included.length) + return new Token(TokenType.NUMBER, included, this.input.position - included.length) } - + readOperator() { - let included = ""; + let included = "" while(!this.input.atEnd() && OPERATORS.includes(this.input.peek())) { - included += this.input.next(); + included += this.input.next() } - return new Token(TokenType.OPERATOR, included, this.input.position-included.length) + return new Token(TokenType.OPERATOR, included, this.input.position - included.length) } - + readIdentifier() { - let identifier = ""; + let identifier = "" while(!this.input.atEnd() && IDENTIFIER_CHARS.includes(this.input.peek().toLowerCase())) { - identifier += this.input.next(); + identifier += this.input.next() } if(Reference.CONSTANTS_LIST.includes(identifier.toLowerCase())) { - return new Token(TokenType.CONSTANT, identifier.toLowerCase(), this.input.position-identifier.length) + return new Token(TokenType.CONSTANT, identifier.toLowerCase(), this.input.position - identifier.length) } else if(Reference.FUNCTIONS_LIST.includes(identifier.toLowerCase())) { - return new Token(TokenType.FUNCTION, identifier.toLowerCase(), this.input.position-identifier.length) + return new Token(TokenType.FUNCTION, identifier.toLowerCase(), this.input.position - identifier.length) } else { - return new Token(TokenType.VARIABLE, identifier, this.input.position-identifier.length) + return new Token(TokenType.VARIABLE, identifier, this.input.position - identifier.length) } } - + readNextToken() { if(!this.tokenizeWhitespaces) this.skipWhitespaces() - if(this.input.atEnd()) return null; - let c = this.input.peek(); - if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces(); - if(STRING_LIMITERS.includes(c)) return this.readString(); - if(NUMBER_CHARS.includes(c)) return this.readNumber(); - if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier(); - if(OPERATORS.includes(c)) return this.readOperator(); - if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position-1); - if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); + if(this.input.atEnd()) return null + let c = this.input.peek() + if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces() + if(STRING_LIMITERS.includes(c)) return this.readString() + if(NUMBER_CHARS.includes(c)) return this.readNumber() + if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier() + if(OPERATORS.includes(c)) return this.readOperator() + if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position - 1) + if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position - 1) if(this.errorOnUnknown) this.input.raise("Unknown token character " + c) else - return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position-1); + return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position - 1) } peek() { - if(this.currentToken == null) this.currentToken = this.readNextToken(); - return this.currentToken; + if(this.currentToken == null) this.currentToken = this.readNextToken() + return this.currentToken } next() { - let tmp; + let tmp if(this.currentToken == null) - tmp = this.readNextToken(); + tmp = this.readNextToken() else - tmp = this.currentToken; - this.currentToken = null; - return tmp; + tmp = this.currentToken + this.currentToken = null + return tmp } - + atEnd() { - return this.peek() == null; + return this.peek() == null } - + skip(type) { - let next = this.next(); + let next = this.next() if(next.type !== type) - this.input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); + this.input.raise("Unexpected token " + next.type.toLowerCase() + " \"" + next.value + "\". Expected " + type.toLowerCase()) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs index 1e708ca..e456dc2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {Expression} from "../math/index.mjs" +import { Expression } from "../math/index.mjs" class Setting { constructor(type, name, nameInConfig, icon) { @@ -49,7 +49,7 @@ class Setting { export class BoolSetting extends Setting { constructor(name, nameInConfig, icon) { - super('bool', name, nameInConfig, icon) + super("bool", name, nameInConfig, icon) } value() { @@ -63,9 +63,9 @@ export class BoolSetting extends Setting { export class NumberSetting extends Setting { constructor(name, nameInConfig, icon, min = -Infinity, max = +Infinity) { - super('number', name, nameInConfig, icon) - this.min = typeof min == 'number' ? () => min : min - this.max = typeof max == 'number' ? () => max : max + super("number", name, nameInConfig, icon) + this.min = typeof min == "number" ? () => min : min + this.max = typeof max == "number" ? () => max : max } value() { @@ -79,7 +79,7 @@ export class NumberSetting extends Setting { export class EnumIntSetting extends Setting { constructor(name, nameInConfig, icon, values = []) { - super('enum', name, nameInConfig, icon) + super("enum", name, nameInConfig, icon) this.values = values } @@ -94,7 +94,7 @@ export class EnumIntSetting extends Setting { export class ExpressionSetting extends Setting { constructor(name, nameInConfig, icon, variables = []) { - super('expression', name, nameInConfig, icon) + super("expression", name, nameInConfig, icon) this.variables = variables } @@ -112,17 +112,17 @@ export class ExpressionSetting extends Setting { Helper.setSetting(this.nameInConfig, value) else { let undefinedVars = vars.filter(x => !this.variables.includes(x)) - let allowed = '' + let allowed = "" if(this.variables.length > 0) - allowed = `Allowed variables: ${this.variables.join(', ')}.` - throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(', or ')} to define ${this.displayName}. ${allowed}`) + allowed = `Allowed variables: ${this.variables.join(", ")}.` + throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(", or ")} to define ${this.displayName}. ${allowed}`) } } } export class StringSetting extends Setting { constructor(name, nameInConfig, icon, defaultValues = []) { - super('string', name, nameInConfig, icon) + super("string", name, nameInConfig, icon) this.defaultValues = defaultValues } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs index c58f4de..0fa9531 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "./common.mjs" +import { BoolSetting, ExpressionSetting, NumberSetting, StringSetting } from "./common.mjs" const XZOOM = new NumberSetting( @@ -49,13 +49,13 @@ const YMAX = new NumberSetting( const XAXISSTEP = new ExpressionSetting( qsTranslate("Settings", "X Axis Step"), "default_graph.xaxisstep", - "xaxisstep", + "xaxisstep" ) const YAXISSTEP = new ExpressionSetting( qsTranslate("Settings", "Y Axis Step"), "default_graph.yaxisstep", - "yaxisstep", + "yaxisstep" ) const LINE_WIDTH = new NumberSetting( @@ -72,33 +72,33 @@ const TEXT_SIZE = new NumberSetting( ) const X_LABEL = new StringSetting( - qsTranslate("Settings", 'X Label'), + qsTranslate("Settings", "X Label"), "default_graph.xlabel", "xlabel", ["", "x", "ω (rad/s)"] ) const Y_LABEL = new StringSetting( - qsTranslate("Settings", 'Y Label'), + qsTranslate("Settings", "Y Label"), "default_graph.ylabel", "xlabel", ["", "y", "G (dB)", "φ (°)", "φ (deg)", "φ (rad)"] ) const LOG_SCALE_X = new BoolSetting( - qsTranslate("Settings", 'X Log scale'), + qsTranslate("Settings", "X Log scale"), "default_graph.logscalex", "logscalex" ) const SHOW_X_GRAD = new BoolSetting( - qsTranslate("Settings", 'Show X graduation'), + qsTranslate("Settings", "Show X graduation"), "default_graph.showxgrad", "showxgrad" ) const SHOW_Y_GRAD = new BoolSetting( - qsTranslate("Settings", 'Show Y graduation'), + qsTranslate("Settings", "Show Y graduation"), "default_graph.showygrad", "showygrad" ) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs index efd7b40..85e1fbe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs @@ -16,30 +16,30 @@ * along with this program. If not, see . */ -import {BoolSetting, EnumIntSetting} from "./common.mjs" +import { BoolSetting, EnumIntSetting } from "./common.mjs" const AUTOCLOSE_FORMULA = new BoolSetting( qsTranslate("expression", "Automatically close parenthesises and brackets"), - 'expression_editor.autoclose', - 'text' + "expression_editor.autoclose", + "text" ) const ENABLE_SYNTAX_HIGHLIGHTING = new BoolSetting( qsTranslate("expression", "Enable syntax highlighting"), - 'expression_editor.colorize', - 'appearance' + "expression_editor.colorize", + "appearance" ) const ENABLE_AUTOCOMPLETE = new BoolSetting( qsTranslate("expression", "Enable autocompletion"), - 'autocompletion.enabled', - 'label' + "autocompletion.enabled", + "label" ) const PICK_COLOR_SCHEME = new EnumIntSetting( qsTranslate("expression", "Color Scheme"), - 'expression_editor.color_scheme', - 'color', + "expression_editor.color_scheme", + "color", ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] ) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 8d1e751..81c5e3d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -16,25 +16,25 @@ * along with this program. If not, see . */ -import {BoolSetting} from "./common.mjs" +import { BoolSetting } from "./common.mjs" import Canvas from "../module/canvas.mjs" import LatexAPI from "../module/latex.mjs" const CHECK_FOR_UPDATES = new BoolSetting( qsTranslate("general", "Check for updates on startup"), - 'check_for_updates', - 'update' + "check_for_updates", + "update" ) const RESET_REDO_STACK = new BoolSetting( qsTranslate("general", "Reset redo stack automaticly"), - 'reset_redo_stack', - 'timeline' + "reset_redo_stack", + "timeline" ) class EnableLatex extends BoolSetting { constructor() { - super(qsTranslate("general","Enable LaTeX rendering"), 'enable_latex', 'Expression') + super(qsTranslate("general", "Enable LaTeX rendering"), "enable_latex", "Expression") } set(value) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs index 2e82be4..4f6b0c5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs @@ -16,6 +16,25 @@ * along with this program. If not, see . */ +// Add string methods +/** + * Replaces latin characters with their uppercase versions. + * @return {string} + */ +String.prototype.toLatinUppercase = String.prototype.toLatinUppercase || function() { + return this.replace(/[a-z]/g, function(match) { + return match.toUpperCase() + }) +} + +/** + * Removes the 'enclosers' of a string (e.g. quotes, parentheses, brackets...) + * @return {string} + */ +String.prototype.removeEnclosure = function() { + return this.substring(1, this.length - 1) +} + const powerpos = { "-": "⁻", "+": "⁺", @@ -350,10 +369,6 @@ export function parseName(str, removeUnallowed = true) { return str } -String.prototype.toLatinUppercase = function() { - return this.replace(/[a-z]/g, function(match){return match.toUpperCase()}) -} - /** * Transforms camel case strings to a space separated one. * diff --git a/LogarithmPlotter/util/debug.py b/LogarithmPlotter/util/debug.py index b093ee0..05271ac 100644 --- a/LogarithmPlotter/util/debug.py +++ b/LogarithmPlotter/util/debug.py @@ -29,7 +29,7 @@ class LOG_COLORS: GRAY = "\033[90m" BLUE = "\033[94m" ORANGE = "\033[38;5;166m" - RED = "\033[e[38;5;204m" + RED = "\033[38;5;204m" INVERT = "\033[7m" RESET_INVERT = "\033[27m" RESET = "\033[0m" diff --git a/package-lock.json b/package-lock.json index 1232c01..639f4a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", - "@rollup/plugin-terser": "^0.4.4", "install": "^0.13.0", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" @@ -1724,16 +1723,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1838,28 +1827,6 @@ } } }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "license": "MIT", - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@rollup/pluginutils": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", @@ -2114,18 +2081,6 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "license": "MIT" }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2209,12 +2164,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, "node_modules/caniuse-lite": { "version": "1.0.30001663", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", @@ -2264,12 +2213,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2602,15 +2545,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -2770,26 +2704,6 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "license": "MIT" }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -2799,15 +2713,6 @@ "semver": "bin/semver.js" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/skip-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", @@ -2817,31 +2722,6 @@ "node": ">=4.2" } }, - "node_modules/smob": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", - "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", - "license": "MIT" - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -2873,24 +2753,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/terser": { - "version": "5.33.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz", - "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", diff --git a/package.json b/package.json index 78fad44..00761cd 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", - "@rollup/plugin-terser": "^0.4.4", "install": "^0.13.0", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" diff --git a/rollup.config.mjs b/rollup.config.mjs index 4b4a305..892c9fb 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -20,7 +20,6 @@ import { nodeResolve } from "@rollup/plugin-node-resolve" import commonjs from "@rollup/plugin-commonjs" import { babel } from "@rollup/plugin-babel" import cleanup from "rollup-plugin-cleanup" -import terser from "@rollup/plugin-terser" const path = "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js" @@ -39,9 +38,6 @@ export default { babel({ babelHelpers: "bundled" }), - // terser({ - // ecma: 2015 - // }) ] } From c806f09b10c18fdb0359b7092c8c20acab7a5195 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 27 Sep 2024 03:02:55 +0200 Subject: [PATCH 146/249] Improving translations update script. --- LogarithmPlotter/i18n/update.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/update.sh b/LogarithmPlotter/i18n/update.sh index 3a01e14..8d589d5 100755 --- a/LogarithmPlotter/i18n/update.sh +++ b/LogarithmPlotter/i18n/update.sh @@ -4,7 +4,7 @@ # specificities so that lupdate doesn't cry out in pain. # See also: https://bugreports.qt.io/browse/QTBUG-123819 # - + escape() { str="$1" str="${str//\//\\/}" # Escape slashes @@ -19,15 +19,20 @@ replace() { sed -i "s/${from}/${to}/g" "$file" } +rm ../qml/eu/ad5001/LogarithmPlotter/js/index.mjs # Remove index which should not be scanned + files=$(find .. -name *.mjs) for file in $files; do echo "Moving '$file' to '${file%.*}.js'..." mv "$file" "${file%.*}.js" # Replacements to make it valid js replace "${file%.*}.js" "^import" "/*import" + replace "${file%.*}.js" "^export *" "/*export *" replace "${file%.*}.js" '.mjs"$' '.mjs"*/' replace "${file%.*}.js" "^export default" "/*export default*/" replace "${file%.*}.js" "^export" "/*export*/" + replace "${file%.*}.js" "async " "/*async */" + replace "${file%.*}.js" "await" "/*await */" done echo "----------------------------" @@ -38,7 +43,6 @@ lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts for lp in *.ts; do echo "Replacing locations in $lp..." for file in $files; do - echo " > Replacing for file $file..." replace "$lp" "${file%.*}.js" "$file" done done @@ -47,8 +51,11 @@ for file in $files; do echo "Moving '${file%.*}.js' to '$file'..." mv "${file%.*}.js" "$file" # Resetting changes - replace "$file" "^/*import" "import" - replace "$file" '.mjs"*/$' '.mjs"' - replace "$file" "^/*export default*/" "export default" + replace "$file" "/*await */" "await" + replace "$file" "/*async */" "async " replace "$file" "^/*export*/" "export" + replace "$file" "^/*export default*/" "export default" + replace "$file" "^/*import" "import" + replace "$file" "^/*export" "export" + replace "$file" '.mjs"*/$' '.mjs"' done From f8ce98d4adf1b61229176ab75a9e3c357f1f139b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 27 Sep 2024 04:15:34 +0200 Subject: [PATCH 147/249] Removing logplotter.svg file (duplicate) + adding PySide6-Addons as dependency --- README.md | 2 +- linux/debian/control | 2 +- linux/debian/depends | 2 +- linux/logarithmplotter.desktop | 2 +- linux/x-logarithm-plot.xml | 2 +- logplotter.svg | 64 ---------------------------------- scripts/build-wine.sh | 2 +- setup.py | 10 +++--- 8 files changed, 11 insertions(+), 75 deletions(-) delete mode 100644 logplotter.svg diff --git a/README.md b/README.md index e368435..8ae4d47 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![icon](https://git.ad5001.eu/Ad5001/LogarithmPlotter/raw/branch/master/logplotter.svg) LogarithmPlotter +# ![icon](https://git.ad5001.eu/Ad5001/LogarithmPlotter/raw/branch/master/LogarithmPlotter/logarithmplotter.svg) LogarithmPlotter [![Build Status](https://ci.ad5001.eu/api/badges/Ad5001/LogarithmPlotter/status.svg)](https://ci.ad5001.eu/Ad5001/LogarithmPlotter) [![Translation status](https://hosted.weblate.org/widgets/logarithmplotter/-/logarithmplotter/svg-badge.svg)](https://hosted.weblate.org/engage/logarithmplotter/) diff --git a/linux/debian/control b/linux/debian/control index 57281bc..e63e970 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -3,7 +3,7 @@ Source: logarithmplotter Version: 0.6.0 Architecture: all Maintainer: Ad5001 -Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng +Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7), texlive-latex-base, dvipng Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.9) Section: science diff --git a/linux/debian/depends b/linux/debian/depends index 5eea4fd..c17dcdd 100644 --- a/linux/debian/depends +++ b/linux/debian/depends @@ -1 +1 @@ -python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng +python3, python3-pip, python3-pyside6-essentials (>= 6.7), python3-pyside6-addons (>= 6.7), texlive-latex-base, dvipng diff --git a/linux/logarithmplotter.desktop b/linux/logarithmplotter.desktop index 00c871f..70637c5 100644 --- a/linux/logarithmplotter.desktop +++ b/linux/logarithmplotter.desktop @@ -14,7 +14,7 @@ Comment[hu]=Bode-ábrák, sorozatok és újraosztási függvények létrehozása TryExec=logarithmplotter Exec=logarithmplotter %f -Icon=logplotter +Icon=logarithmplotter MimeType=application/x-logarithm-plot; Terminal=false StartupNotify=false diff --git a/linux/x-logarithm-plot.xml b/linux/x-logarithm-plot.xml index 31b5c9d..888641e 100644 --- a/linux/x-logarithm-plot.xml +++ b/linux/x-logarithm-plot.xml @@ -1,7 +1,7 @@ - Logarithm Plot File + Logarithmic Plot File Fichier Graphe Logarithmique diff --git a/logplotter.svg b/logplotter.svg deleted file mode 100644 index 77a2817..0000000 --- a/logplotter.svg +++ /dev/null @@ -1,64 +0,0 @@ - -LogarithmPlotter Icon v1.0image/svg+xmlLogarithmPlotter Icon v1.02021Ad5001(c) Ad5001 2021 - All rights reserved diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 39b2312..95a5995 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -11,7 +11,7 @@ cd "LogarithmPlotter/i18n/" bash release.sh cd ../../ -wine pyinstaller --add-data "logplotter.svg;." \ +wine pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ --add-data "LogarithmPlotter/qml;qml" \ --add-data "LogarithmPlotter/i18n;i18n" \ --noconsole \ diff --git a/setup.py b/setup.py index 5d1aae7..4a4d2ea 100644 --- a/setup.py +++ b/setup.py @@ -99,11 +99,11 @@ if sys.platform == 'linux': data_files.append(('share/applications/', ['linux/logarithmplotter.desktop'])) data_files.append(('share/mime/packages/', ['linux/x-logarithm-plot.xml'])) data_files.append(('share/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) - data_files.append(('share/icons/hicolor/scalable/apps/', ['logplotter.svg'])) + data_files.append(('share/icons/hicolor/scalable/apps/', ['LogarithmPlotter/logarithmplotter.svg'])) data_files.append((os.environ["PREFIX"] + '/applications/', ['linux/logarithmplotter.desktop'])) data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml'])) data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) - data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) + data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['LogarithmPlotter/logarithmplotter.svg'])) if len(sys.argv) > 1: if sys.argv[1] == "install": os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True) @@ -114,15 +114,15 @@ if sys.platform == 'linux': copyfile(current_dir + '/linux/x-logarithm-plot.xml', os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') copyfile(current_dir + '/linux/application-x-logarithm-plot.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') - copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') + copyfile(current_dir + '/LogarithmPlotter/logarithmplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/LogarithmPlotter/logarithmplotter.svg') elif sys.argv[1] == "uninstall": os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') - os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') + os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/LogarithmPlotter/logarithmplotter.svg') setuptools.setup( - install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials"]), + install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials", "PySide6-Addons"]), python_requires='>=3.9', name='logarithmplotter', From 80cea6d280302b59c29b424946cca1c9704e470c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 26 Sep 2024 15:55:29 +0000 Subject: [PATCH 148/249] Translated using Weblate (Hungarian) Currently translated at 95.1% (256 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 8618a0b..313d8de 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1717,7 +1717,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents baseValues - Kezdeményezési értékek + Kezdeményezési értékek color From c2eae30bd68b5370492259059a5ccb0bc8745f6e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 27 Sep 2024 22:26:15 +0200 Subject: [PATCH 149/249] Updating qmldirs --- .../ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 4 ++-- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/qmldir | 8 ++++---- .../qml/eu/ad5001/LogarithmPlotter/Setting/qmldir | 4 ++-- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir | 5 ++++- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index d92c36b..f755a6f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -71,8 +71,8 @@ ScrollView { id: typeVisibilityCheckBox checked: Modules.Objects.currentObjects[objType] != undefined ? Modules.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(var obj of Modules.Objects.currentObjects[objType]) obj.visible = this.checked - for(var obj of objTypeList.editingRows) obj.objVisible = this.checked + for(const obj of Modules.Objects.currentObjects[objType]) obj.visible = this.checked + for(const obj of objTypeList.editingRows) obj.objVisible = this.checked objectListList.changed() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 2dcd5c0..a1b9d82 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -227,7 +227,7 @@ Item { function deleteRecursively(object) { for(let toRemove of object.requiredBy) deleteRecursively(toRemove) - if(Modules.Objects.currentObjectsByName[object.name] != undefined) { + if(Modules.Objects.currentObjectsByName[object.name] !== undefined) { // Object still exists // Temporary fix for objects require not being propertly updated. object.requiredBy = [] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index 8c0859f..3cf03fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -1,11 +1,11 @@ module eu.ad5001.LogarithmPlotter.Popup -BaseDialog 1.0 BaseDialog.qml -About 1.0 About.qml Alert 1.0 Alert.qml +About 1.0 About.qml +BaseDialog 1.0 BaseDialog.qml +Changelog 1.0 Changelog.qml FileDialog 1.0 FileDialog.qml GreetScreen 1.0 GreetScreen.qml -Changelog 1.0 Changelog.qml -ThanksTo 1.0 ThanksTo.qml InsertCharacter 1.0 InsertCharacter.qml Preferences 1.0 Preferences.qml +ThanksTo 1.0 ThanksTo.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir index 8106e26..bb78bbe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir @@ -1,8 +1,8 @@ module eu.ad5001.LogarithmPlotter.Setting +AutocompletionCategory 1.0 AutocompletionCategory.qml ComboBoxSetting 1.0 ComboBoxSetting.qml +ExpressionEditor 1.0 ExpressionEditor.qml Icon 1.0 Icon.qml ListSetting 1.0 ListSetting.qml TextSetting 1.0 TextSetting.qml -ExpressionEditor 1.0 ExpressionEditor.qml -AutocompletionCategory 1.0 AutocompletionCategory.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir index ac68e47..3aeaa15 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir @@ -1,4 +1,7 @@ module eu.ad5001.LogarithmPlotter +AppMenuBar 1.0 AppMenuBar.qml +LogGraphCanvas 1.0 LogGraphCanvas.qml +PickLocationOverlay 1.0 PickLocationOverlay.qml Settings 1.0 Settings.qml -Alert 1.0 Alert.qml +ViewPositionChangeOverlay 1.0 ViewPositionChangeOverlay.qml \ No newline at end of file From 56a0817960f12187de211a1e8f562a7dc8c67b69 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 28 Sep 2024 03:32:51 +0200 Subject: [PATCH 150/249] Testing! --- .mocharc.jsonc | 25 + LogarithmPlotter/logarithmplotter.py | 2 +- .../LogarithmPlotter/LogarithmPlotter.qml | 6 + .../eu/ad5001/LogarithmPlotter/Settings.qml | 4 - .../ad5001/LogarithmPlotter/js/autoload.mjs | 9 +- .../LogarithmPlotter/js/lib/polyfills/qt.mjs | 31 +- .../LogarithmPlotter/js/math/domain.mjs | 6 +- .../LogarithmPlotter/js/module/common.mjs | 7 +- .../LogarithmPlotter/js/module/history.mjs | 1 - .../LogarithmPlotter/js/module/index.mjs | 35 + .../LogarithmPlotter/js/module/interface.mjs | 85 +- .../LogarithmPlotter/js/module/latex.mjs | 27 +- .../js/module/preferences.mjs | 2 +- LogarithmPlotter/util/config.py | 12 +- package-lock.json | 1044 +++++++++++++++++ package.json | 11 +- tests/js/hooks.mjs | 30 + tests/js/math/domain.mjs | 63 + tests/js/mock/fs.mjs | 44 + tests/js/mock/helper.mjs | 158 +++ tests/js/mock/latex.mjs | 90 ++ tests/js/mock/qt.mjs | 60 + 22 files changed, 1680 insertions(+), 72 deletions(-) create mode 100644 .mocharc.jsonc create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs create mode 100644 tests/js/hooks.mjs create mode 100644 tests/js/math/domain.mjs create mode 100644 tests/js/mock/fs.mjs create mode 100644 tests/js/mock/helper.mjs create mode 100644 tests/js/mock/latex.mjs create mode 100644 tests/js/mock/qt.mjs diff --git a/.mocharc.jsonc b/.mocharc.jsonc new file mode 100644 index 0000000..5fa553a --- /dev/null +++ b/.mocharc.jsonc @@ -0,0 +1,25 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +{ + "recursive": true, + "require": [ + "esm", + "./tests/js/hooks.mjs" + ] +} \ No newline at end of file diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 9aede1b..3264097 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -130,7 +130,7 @@ def create_engine(helper: Helper, latex: Latex, dep_time: float) -> tuple[QQmlAp global tmpfile engine = QQmlApplicationEngine() js_globals = PyJSValue(engine.globalObject()) - js_globals.Modules = engine.newObject() + js_globals.globalThis = engine.globalObject() js_globals.Helper = engine.newQObject(helper) js_globals.Latex = engine.newQObject(latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index e41aa24..8545153 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -259,4 +259,10 @@ ApplicationWindow { function showUpdateMenu() { appMenu.addMenu(updateMenu) } + + // Initializing modules + Component.onCompleted: { + Modules.IO.initialize({ root, settings, alert }) + Modules.Latex.initialize({ latex: Latex, helper: Helper }) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 7ba80aa..534556f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -127,10 +127,6 @@ ScrollView { */ property string saveFilename: "" - Component.onCompleted: { - Modules.IO.initialize({ root, settings, alert }) - } - Column { spacing: 10 width: parent.width diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs index 47a9424..c19e2fe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs @@ -18,15 +18,8 @@ import js from "./lib/polyfills/js.mjs" -// Loading modules in order -import * as Objects from "./module/objects.mjs" -import * as ExprParser from "./module/expreval.mjs" +import * as Modules from "./module/index.mjs" import * as ObjsAutoload from "./objs/autoload.mjs" -import * as Latex from "./module/latex.mjs" -import * as History from "./module/history.mjs" -import * as CanvasAPI from "./module/canvas.mjs" -import * as IOAPI from "./module/io.mjs" -import * as PreferencesAPI from "./module/preferences.mjs" export * as MathLib from "./math/index.mjs" export * as HistoryLib from "./history/index.mjs" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs index 7cbb2f7..6559423 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs @@ -43,33 +43,4 @@ const Qt = { rect: function(x, y, width, height) { return {x: x, y: y, width: width, height: height}; } -} - -/** Typehints for Helper. */ -const Helper = { - /** @type {function(string): boolean} */ - getSettingBool: (setting) => true, - /** @type {function(string): int} */ - getSettingInt: (setting) => 0, - /** @type {function(string): string} */ - getSetting: (setting) => '', - /** @type {function(string, boolean)} */ - setSettingBool: (setting, value) => {}, - /** @type {function(string, int)} */ - setSettingInt: (setting, value) => 0, - /** @type {function(string, string)} */ - setSetting: (setting, value) => '', - /** @type {function(string, string)} */ - write: (filename, data) => {}, - /** @type {function(string): string} */ - load: (filename) => '', -} - -const Latex = { - /** @type {function(string, number, string): string} */ - render: (latex_markup, font_size, color) => '', - /** @type {function(string, number, string): string} */ - findPrerendered: (latex_markup, font_size, color) => '', - /** @type {function(): boolean} */ - checkLatexInstallation: () => true, -} +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index 846b66b..48bf8ad 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -585,13 +585,13 @@ Domain.ZME = new SpecialDomain("ℤ⁻*", x => x % 1 === 0 && x < 0, x => Math.min(Math.ceil(x) - 1, -1)) Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" Domain.NLog = new SpecialDomain("ℕˡᵒᵍ", - x => x / Math.pow(10, x.toString().length - 1) % 1 === 0 && x > 0, + x => x / Math.pow(10, Math.ceil(Math.log10(x))) % 1 === 0 && x > 0, function(x) { - let x10pow = Math.pow(10, x.toString().length - 1) + let x10pow = Math.pow(10, Math.ceil(Math.log10(x))) return Math.max(1, (Math.floor(x / x10pow) + 1) * x10pow) }, function(x) { - let x10pow = Math.pow(10, x.toString().length - 1) + let x10pow = Math.pow(10, Math.ceil(Math.log10(x))) return Math.max(1, (Math.ceil(x / x10pow) - 1) * x10pow) }) Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs index 0a5046b..b757f14 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs @@ -18,6 +18,9 @@ import { Interface } from "./interface.mjs" +// Define Modules interface before they are imported. +globalThis.Modules = globalThis.Modules || {} + /** * Base class for global APIs in runtime. */ @@ -33,6 +36,7 @@ export class Module { this.__name = name this.__initializationParameters = initializationParameters this.initialized = false + } /** @@ -42,6 +46,7 @@ export class Module { initialize(options) { if(this.initialized) throw new Error(`Cannot reinitialize module ${this.__name}.`) + console.log(`Initializing ${this.__name}...`) for(const [name, value] of Object.entries(this.__initializationParameters)) { if(!options.hasOwnProperty(name)) throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) @@ -52,4 +57,4 @@ export class Module { } this.initialized = true } -} \ No newline at end of file +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs index 42146ce..8cd3f60 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs @@ -37,7 +37,6 @@ class HistoryAPI extends Module { initialize({ historyObj, themeTextColor, imageDepth, fontSize }) { super.initialize({ historyObj, themeTextColor, imageDepth, fontSize }) - console.log("Initializing history...") this.history = historyObj this.themeTextColor = themeTextColor this.imageDepth = imageDepth diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs new file mode 100644 index 0000000..fe2e8d9 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs @@ -0,0 +1,35 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Objects from "./objects.mjs" +import ExprParser from "./expreval.mjs" +import Latex from "./latex.mjs" +import History from "./history.mjs" +import Canvas from "./canvas.mjs" +import IO from "./io.mjs" +import Preferences from "./preferences.mjs" + +export default { + Objects, + ExprParser, + Latex, + History, + Canvas, + IO, + Preferences +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs index 77e2741..9273c8f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs @@ -25,6 +25,7 @@ export const STRING = "string" export const BOOLEAN = true export const OBJECT = {} export const FUNCTION = () => { + throw new Error("Cannot call function of an interface.") } @@ -42,7 +43,7 @@ export class Interface { const toCheckName = classToCheck.constructor.name for(const [property, value] of Object.entries(properties)) if(property !== "implement") { - if(!classToCheck.hasOwnProperty(property)) + if(classToCheck[property] === undefined) // Check if the property exist throw new Error(`Property '${property}' (${typeof value}) is present in interface ${interfaceName}, but not in implementation ${toCheckName}.`) else if((typeof value) !== (typeof classToCheck[property])) @@ -56,15 +57,6 @@ export class Interface { throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is not '${value.constructor.name}'.`) } } - - /** - * Decorator to automatically check if a class conforms to the current interface. - * @param {object} class_ - */ - implement(class_) { - Interface.check_implementation(this, class_) - return class_ - } } @@ -120,3 +112,76 @@ export class HistoryInterface extends Interface { unserialize = FUNCTION serialize = FUNCTION } + +export class LatexInterface extends Interface { + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {string} - Comma separated data of the image (source, width, height) + */ + render = FUNCTION + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {string} - Comma separated data of the image (source, width, height) + */ + findPrerendered = FUNCTION + /** + * Checks if the Latex installation is valid + * @returns {boolean} + */ + checkLatexInstallation = FUNCTION +} + +export class HelperInterface extends Interface { + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {boolean} Value of the setting + */ + getSettingBool = FUNCTION + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {number} Value of the setting + */ + getSettingInt = FUNCTION + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {string} Value of the setting + */ + getSetting = FUNCTION + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {boolean} value + */ + setSettingBool = FUNCTION + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {number} value + */ + setSettingInt = FUNCTION + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {string} value + */ + setSetting = FUNCTION + /** + * Sends data to be written + * @param {string} file + * @param {string} dataToWrite - just JSON encoded, requires the "LPFv1" mime to be added before writing + */ + write = FUNCTION + /** + * Requests data to be read from a file + * @param {string} file + * @returns {string} the loaded data - just JSON encoded, requires the "LPFv1" mime to be stripped + */ + load = FUNCTION +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs index fa194f5..8740160 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs @@ -19,6 +19,7 @@ import { Module } from "./common.mjs" import * as Instruction from "../lib/expr-eval/instruction.mjs" import { escapeValue } from "../lib/expr-eval/expression.mjs" +import { HelperInterface, LatexInterface } from "./interface.mjs" const unicodechars = [ "α", "β", "γ", "δ", "ε", "ζ", "η", @@ -60,11 +61,25 @@ class LatexRenderResult { class LatexAPI extends Module { constructor() { - super("Latex") + super("Latex", { + latex: LatexInterface, + helper: HelperInterface + }) /** * true if latex has been enabled by the user, false otherwise. */ - this.enabled = Helper.getSettingBool("enable_latex") + this.enabled = false + } + + /** + * @param {LatexInterface} latex + * @param {HelperInterface} helper + */ + initialize({ latex, helper }) { + super.initialize({ latex, helper }) + this.latex = latex + this.helper = helper + this.enabled = helper.getSettingBool("enable_latex") } /** @@ -77,7 +92,8 @@ class LatexAPI extends Module { * @returns {LatexRenderResult|null} */ findPrerendered(markup, fontSize, color) { - const data = Latex.findPrerendered(markup, fontSize, color) + if(!this.initialized) throw new Error("Attempting findPrerendered before initialize!") + const data = this.latex.findPrerendered(markup, fontSize, color) let ret = null if(data !== "") ret = new LatexRenderResult(...data.split(",")) @@ -93,7 +109,8 @@ class LatexAPI extends Module { * @returns {Promise} */ async requestAsyncRender(markup, fontSize, color) { - let args = Latex.render(markup, fontSize, color).split(",") + if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") + let args = this.latex.render(markup, fontSize, color).split(",") return new LatexRenderResult(...args) } @@ -313,5 +330,5 @@ class LatexAPI extends Module { /** @type {LatexAPI} */ Modules.Latex = Modules.Latex || new LatexAPI() - +/** @type {LatexAPI} */ export default Modules.Latex diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs index 453bc0e..afb795e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs @@ -34,4 +34,4 @@ class PreferencesAPI extends Module { /** @type {CanvasAPI} */ Modules.Preferences = Modules.Preferences || new PreferencesAPI() -export const API = Modules.Preferences +export default Modules.Preferences diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index d295caa..a5ee23c 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -120,11 +120,9 @@ def setSetting(namespace, data): """ names = namespace.split(".") setting = current_config - for name in names: - if name != names[-1]: - if name in setting: - setting = setting[name] - else: - raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") + for name in names[:-1]: + if name in setting: + setting = setting[name] else: - setting[name] = data + raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") + setting[names[-1]] = data diff --git a/package-lock.json b/package-lock.json index 639f4a7..72ec068 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,14 @@ "install": "^0.13.0", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" + }, + "devDependencies": { + "@types/chai": "^5.0.0", + "@types/mocha": "^10.0.8", + "chai": "^5.1.1", + "chai-as-promised": "^8.0.0", + "esm": "^3.2.25", + "mocha": "^10.7.3" } }, "node_modules/@ampproject/remapping": { @@ -2069,18 +2077,52 @@ "win32" ] }, + "node_modules/@types/chai": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.0.tgz", + "integrity": "sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, + "node_modules/@types/mocha": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", + "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "license": "MIT" }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2093,6 +2135,50 @@ "node": ">=4" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", @@ -2132,6 +2218,56 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, "node_modules/browserslist": { "version": "4.23.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", @@ -2164,6 +2300,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001663", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", @@ -2184,6 +2333,36 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chai-as-promised": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.0.tgz", + "integrity": "sha512-sMsGXTrS3FunP/wbqh/KxM8Kj/aLPXQGkNtvE5wPfSToq8wkkvBpTZo1LIiEVmC4BwkKpag+l5h/20lBMk6nUg==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "check-error": "^2.0.0" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2198,6 +2377,53 @@ "node": ">=4" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -2256,6 +2482,29 @@ } } }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -2265,12 +2514,29 @@ "node": ">=0.10.0" } }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.27", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", "license": "ISC" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -2289,6 +2555,16 @@ "node": ">=0.8.0" } }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -2318,6 +2594,53 @@ } } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2351,6 +2674,60 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -2381,6 +2758,35 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, "node_modules/install": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", @@ -2390,6 +2796,19 @@ "node": ">= 0.10" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", @@ -2405,12 +2824,65 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "license": "MIT" }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -2420,6 +2892,19 @@ "@types/estree": "*" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/js-cleanup": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", @@ -2449,6 +2934,19 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -2474,12 +2972,131 @@ "node": ">=6" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2498,6 +3115,94 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2510,12 +3215,84 @@ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/perf-regexes": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", @@ -2545,6 +3322,42 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -2615,6 +3428,16 @@ "jsesc": "bin/jsesc" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -2704,6 +3527,27 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "license": "MIT" }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -2713,6 +3557,16 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/skip-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", @@ -2729,6 +3583,47 @@ "deprecated": "Please use @jridgewell/sourcemap-codec instead", "license": "MIT" }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2762,6 +3657,19 @@ "node": ">=4" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -2832,11 +3740,147 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 00761cd..a3451ab 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "2D plotter software to make Bode plots, sequences and distribution functions.", "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", "scripts": { - "build": "rollup --config rollup.config.mjs" + "build": "rollup --config rollup.config.mjs", + "test": "mocha tests/js/**/*.mjs" }, "repository": { "type": "git", @@ -20,5 +21,13 @@ "install": "^0.13.0", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" + }, + "devDependencies": { + "@types/chai": "^5.0.0", + "@types/mocha": "^10.0.8", + "chai": "^5.1.1", + "chai-as-promised": "^8.0.0", + "esm": "^3.2.25", + "mocha": "^10.7.3" } } diff --git a/tests/js/hooks.mjs b/tests/js/hooks.mjs new file mode 100644 index 0000000..8c3e929 --- /dev/null +++ b/tests/js/hooks.mjs @@ -0,0 +1,30 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import * as fs from "./mock/fs.mjs"; +import Qt from "./mock/qt.mjs"; +import { MockHelper } from "./mock/helper.mjs"; +import { MockLatex } from "./mock/latex.mjs"; +import Modules from "../../LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs"; + +function setup() { + globalThis.Helper = new MockHelper() + globalThis.Latex = new MockLatex() + Modules.Latex.initialize({ latex: Latex, helper: Helper }) +} + +setup() \ No newline at end of file diff --git a/tests/js/math/domain.mjs b/tests/js/math/domain.mjs new file mode 100644 index 0000000..a67364f --- /dev/null +++ b/tests/js/math/domain.mjs @@ -0,0 +1,63 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { describe, it } from "mocha" +import { expect } from "chai" + +import { Domain, parseDomainSimple } from "../../../LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs" + +describe("math.domain", function() { + describe("#parseDomainSimple", function() { + it("returns predefined domains", function() { + const predefinedToCheck = [ + // Real domains + { domain: Domain.R, shortcuts: ["R", "ℝ"] }, + // Zero exclusive real domains + { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] }, + // Real positive domains + { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] }, + // Zero-exclusive real positive domains + { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] }, + // Real negative domain + { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] }, + // Zero-exclusive real negative domains + { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] }, + // Natural integers domain + { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] }, + // Zero-exclusive natural integers domain + { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] }, + // Logarithmic natural domains + { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] }, + // All integers domains + { domain: Domain.Z, shortcuts: ["Z", "ℤ"] }, + // Zero-exclusive all integers domain + { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] }, + // Negative integers domain + { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] }, + // Zero-exclusive negative integers domain + { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] }, + ] + + // Real domains + for(const { domain, shortcuts } of predefinedToCheck) + for(const shortcut of shortcuts) + expect(parseDomainSimple(shortcut)).to.be.equal(domain) + }) + + }) +}) diff --git a/tests/js/mock/fs.mjs b/tests/js/mock/fs.mjs new file mode 100644 index 0000000..bccb71f --- /dev/null +++ b/tests/js/mock/fs.mjs @@ -0,0 +1,44 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { readFileSync as readNode } from "node:fs" +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)) + +export const HOME = "/home/user" +export const TMP = "/tmp" + + +const filesystem = { + [`${HOME}/test1.lpf`]: readNode(__dirname + "/../../../ci/test1.lpf") +} + + +export function existsSync(file) { + return filesystem[file] !== undefined +} + +export function writeFileSync(file, data, encoding) { + filesystem[file] = Buffer.from(data, encoding) +} + +export function readFileSync(file, encoding) { + return filesystem[file].toString(encoding) +} \ No newline at end of file diff --git a/tests/js/mock/helper.mjs b/tests/js/mock/helper.mjs new file mode 100644 index 0000000..9f74b64 --- /dev/null +++ b/tests/js/mock/helper.mjs @@ -0,0 +1,158 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { readFileSync, writeFileSync, existsSync } from "./fs.mjs" + +const DEFAULT_SETTINGS = { + "check_for_updates": true, + "reset_redo_stack": true, + "last_install_greet": "0", + "enable_latex": false, + "expression_editor": { + "autoclose": true, + "colorize": true, + "color_scheme": 0 + }, + "autocompletion": { + "enabled": true + }, + "default_graph": { + "xzoom": 100, + "yzoom": 10, + "xmin": 5 / 10, + "ymax": 25, + "xaxisstep": "4", + "yaxisstep": "4", + "xlabel": "", + "ylabel": "", + "linewidth": 1, + "textsize": 18, + "logscalex": true, + "showxgrad": true, + "showygrad": true + } +} + +export class MockHelper { + constructor() { + this.__settings = { ...DEFAULT_SETTINGS } + } + + __getSetting(settingName) { + const namespace = settingName.split(".") + let data = this.__settings + for(const name of namespace) + if(data.hasOwnProperty(name)) + data = data[name] + else + throw new Error(`Setting ${namespace} does not exist.`) + return data + } + + __setSetting(settingName, value) { + const namespace = settingName.split(".") + const finalName = namespace.pop() + let data = this.__settings + for(const name of namespace) + if(data.hasOwnProperty(name)) + data = data[name] + else + throw new Error(`Setting ${namespace} does not exist.`) + data[finalName] = value + } + + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {boolean} Value of the setting + */ + getSettingBool(settingName) { + return this.__getSetting(settingName) === true + } + + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {number} Value of the setting + */ + getSettingInt(settingName) { + return +(this.__getSetting(settingName)) + } + + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {string} Value of the setting + */ + getSetting(settingName) { + return this.__getSetting(settingName).toString() + } + + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {boolean} value + */ + setSettingBool(settingName, value) { + return this.__setSetting(settingName, value === true) + } + + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {number} value + */ + setSettingInt(settingName, value) { + return this.__setSetting(settingName, +(value)) + } + + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {string} value + */ + setSetting(settingName, value) { + return this.__setSetting(settingName, value.toString()) + } + + /** + * Sends data to be written + * @param {string} file + * @param {string} dataToWrite - just JSON encoded, requires the "LPFv1" mime to be added before writing + */ + write(file, dataToWrite) { + writeFileSync(file, "LPFv1" + dataToWrite) + } + + /** + * Requests data to be read from a file + * @param {string} file + * @returns {string} the loaded data - just JSON encoded, requires the "LPFv1" mime to be stripped + */ + load(file) { + if(existsSync(file)) { + const data = readFileSync(file, "utf8") + if(data.startsWith("LPFv1")) + return data.substring(5) + else + throw new Error(`Invalid LogarithmPlotter file.`) + } else + throw new Error(`File not found.`) + } + +} \ No newline at end of file diff --git a/tests/js/mock/latex.mjs b/tests/js/mock/latex.mjs new file mode 100644 index 0000000..ab56999 --- /dev/null +++ b/tests/js/mock/latex.mjs @@ -0,0 +1,90 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { TMP, existsSync, writeFileSync } from "./fs.mjs" + +const PIXEL = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAAgABc3UBGAAAAABJRU5ErkJggg==" + +export class MockLatex { + constructor() { + } + + /** + * Creates a simple string hash. + * @param {string} string + * @return {number} + * @private + */ + __hash(string) { + let hash = 0 + let i, chr + if(string.length === 0) return hash + for(i = 0; i < string.length; i++) { + chr = string.charCodeAt(i) + hash = ((hash << 5) - hash) + chr + hash |= 0 // Convert to 32bit integer + } + return hash + } + + /** + * + * @param {string} markup + * @param {number} fontSize + * @param {string} color + * @return {string} + * @private + */ + __getFileName(markup, fontSize, color) { + const name = this.__hash(`${markup}_${fontSize}_${color}`) + return `${TMP}/${name}.png` + } + + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {string} - Comma separated data of the image (source, width, height) + */ + render(markup, fontSize, color) { + const file = this.__getFileName(markup, fontSize, color) + writeFileSync(file, PIXEL, "base64") + return `${file},1,1` + } + + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {string} - Comma separated data of the image (source, width, height) + */ + findPrerendered(markup, fontSize, color) { + const file = this.__getFileName(markup, fontSize, color) + if(existsSync(file)) + return `${file},1,1` + return "" + } + + /** + * Checks if the Latex installation is valid + * @returns {boolean} + */ + checkLatexInstallation() { + return true // We're not *actually* doing any latex. + } +} \ No newline at end of file diff --git a/tests/js/mock/qt.mjs b/tests/js/mock/qt.mjs new file mode 100644 index 0000000..50ec349 --- /dev/null +++ b/tests/js/mock/qt.mjs @@ -0,0 +1,60 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Mock qt methods. + +/** + * Polyfill for Qt.rect. + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @returns {{x, width, y, height}} + */ +function rect(x, y, width, height) { + return { x, y, width, height } +} + +/** + * Mock for QT_TRANSLATE_NOOP and qsTranslate + * @param {string} category + * @param {string} string + * @return {string} + */ +function QT_TRANSLATE_NOOP(category, string) { + return string +} + +function setup() { + globalThis.Qt = { + rect + } + + globalThis.QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP + globalThis.qsTranslate = QT_TRANSLATE_NOOP + + String.prototype.arg = function() { return this; } // No need to reimplement it for now. +} + +setup() + +export default { + rect, + QT_TRANSLATE_NOOP, + qtTranslate: QT_TRANSLATE_NOOP, +} \ No newline at end of file From a2443d79154ad4b015c8fdfd09a4b7296cb1463c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 28 Sep 2024 03:46:16 +0200 Subject: [PATCH 151/249] Adding coverage --- .gitignore | 3 +- package-lock.json | 618 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 4 +- 3 files changed, 590 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 121e497..0bfb625 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,6 @@ linux/flatpak/.flatpak-builder .vscode *.kdev4 .kdev4 -.coverage docs/html .directory *.lpf @@ -40,4 +39,6 @@ docs/html # npm node_modules +coverage/ +.coverage LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs* diff --git a/package-lock.json b/package-lock.json index 72ec068..0b60cac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", - "install": "^0.13.0", + "c8": "^10.1.2", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" }, @@ -1699,6 +1699,117 @@ "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -1747,6 +1858,16 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-babel": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", @@ -2090,6 +2211,12 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, "node_modules/@types/mocha": { "version": "10.0.8", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", @@ -2117,7 +2244,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2222,7 +2348,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { @@ -2242,7 +2367,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -2300,6 +2424,129 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/c8": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.2.tgz", + "integrity": "sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==", + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^7.0.1", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true + } + } + }, + "node_modules/c8/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/c8/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -2449,8 +2696,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/core-js-compat": { "version": "3.38.1", @@ -2465,6 +2711,20 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -2524,6 +2784,12 @@ "node": ">=0.3.1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.27", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", @@ -2534,7 +2800,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/escalade": { @@ -2611,7 +2876,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -2634,6 +2898,34 @@ "flat": "cli.js" } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2678,7 +2970,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -2768,6 +3059,12 @@ "he": "bin/he" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2787,15 +3084,6 @@ "dev": true, "license": "ISC" }, - "node_modules/install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2838,7 +3126,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2905,6 +3192,111 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-cleanup": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", @@ -2976,7 +3368,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -3128,6 +3519,15 @@ "node": ">=10" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mocha": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", @@ -3239,7 +3639,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -3255,7 +3654,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -3267,11 +3665,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -3283,6 +3695,28 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/pathval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", @@ -3432,7 +3866,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3567,6 +4000,27 @@ "randombytes": "^2.1.0" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/skip-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", @@ -3587,7 +4041,21 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -3602,7 +4070,19 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3740,6 +4220,35 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", @@ -3751,7 +4260,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -3765,11 +4273,61 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3785,7 +4343,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3798,7 +4355,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/wrappy": { @@ -3812,7 +4368,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -3873,7 +4428,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" diff --git a/package.json b/package.json index a3451ab..aaa4841 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", "scripts": { "build": "rollup --config rollup.config.mjs", - "test": "mocha tests/js/**/*.mjs" + "test": "c8 mocha tests/js/**/*.mjs" }, "repository": { "type": "git", @@ -18,7 +18,7 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", - "install": "^0.13.0", + "c8": "^10.1.2", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" }, From e9d204daabfb770636ae1c1782620b9e8634785d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 28 Sep 2024 03:49:14 +0200 Subject: [PATCH 152/249] Code coverage for JS --- ci/drone.yml | 3 +++ scripts/run-tests.sh | 2 +- tests/js/math/domain.mjs | 1 + tests/python/test_debug.py | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index b79c656..4ff14ff 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -26,6 +26,9 @@ steps: - name: Unit Tests image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex commands: + - apt update + - apt install -y npm + - npm install -D - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 52d4413..257d748 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -3,5 +3,5 @@ cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." # Run python tests PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . - +npm test diff --git a/tests/js/math/domain.mjs b/tests/js/math/domain.mjs index a67364f..6c185d4 100644 --- a/tests/js/math/domain.mjs +++ b/tests/js/math/domain.mjs @@ -59,5 +59,6 @@ describe("math.domain", function() { expect(parseDomainSimple(shortcut)).to.be.equal(domain) }) + it("") }) }) diff --git a/tests/python/test_debug.py b/tests/python/test_debug.py index e8fd98c..4799024 100644 --- a/tests/python/test_debug.py +++ b/tests/python/test_debug.py @@ -43,7 +43,7 @@ def test_setup(): def test_map_source(): sourcemap_available = debug.SOURCEMAP_INDEX is not None if sourcemap_available: - assert debug.map_javascript_source("js/index.mjs", 22) == ("js/module/interface.mjs", 23) + assert debug.map_javascript_source("js/index.mjs", 22) != ("js/module/index.mjs", 22) assert debug.map_javascript_source("js/index.mjs", 100000) == ("js/index.mjs", 100000) # Too long, not found debug.SOURCEMAP_INDEX = None assert debug.map_javascript_source("js/index.mjs", 21) == ("js/index.mjs", 21) From 34cb856dd46d1de35b87551cc80c704489623376 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 00:23:39 +0200 Subject: [PATCH 153/249] Reorganizing paths --- .gitignore | 16 +- .gitmodules | 4 +- {LogarithmPlotter => assets}/i18n/lp_de.ts | 0 {LogarithmPlotter => assets}/i18n/lp_en.ts | 0 {LogarithmPlotter => assets}/i18n/lp_es.ts | 0 {LogarithmPlotter => assets}/i18n/lp_fr.ts | 0 {LogarithmPlotter => assets}/i18n/lp_hu.ts | 0 {LogarithmPlotter => assets}/i18n/lp_nb_NO.ts | 0 .../i18n/lp_template.ts | 0 {LogarithmPlotter => assets}/i18n/release.sh | 0 {LogarithmPlotter => assets}/i18n/update.sh | 0 .../icons/common/angle.svg | 0 .../icons/common/appearance.svg | 0 .../icons/common/arrow.svg | 0 .../icons/common/close.svg | 0 .../icons/common/delete.svg | 0 .../icons/common/label.svg | 0 .../icons/common/manual.svg | 0 .../icons/common/new.svg | 0 .../icons/common/position.svg | 0 .../icons/common/settings.svg | 0 .../icons/common/target.svg | 0 .../icons/common/text.svg | 0 .../icons/history/appearance.svg | 0 .../icons/history/create.svg | 0 .../icons/history/delete.svg | 0 .../icons/history/modify.svg | 0 .../icons/history/name.svg | 0 .../icons/history/position.svg | 0 .../icons/history/visibility.svg | 0 .../icons/logarithmplotter.svg | 0 .../icons/objects/Function.svg | 0 .../icons/objects/Gain Bode.svg | 0 .../icons/objects/Phase Bode.svg | 0 .../icons/objects/Point.svg | 0 .../icons/objects/Repartition.svg | 0 .../icons/objects/Sequence.svg | 0 .../icons/objects/Text.svg | 0 .../icons/objects/X Cursor.svg | 0 .../icons/settings/color.svg | 0 .../settings/custom/Definition Domain.svg | 0 .../settings/custom/Destination Domain.svg | 0 .../icons/settings/custom/Display Mode.svg | 0 .../icons/settings/custom/Display Style.svg | 0 .../icons/settings/custom/Expression.svg | 0 .../icons/settings/custom/Gain.svg | 0 .../icons/settings/custom/Label Position.svg | 0 .../icons/settings/custom/Label X.svg | 0 .../icons/settings/custom/Pass.svg | 0 .../icons/settings/custom/Phase.svg | 0 .../icons/settings/custom/Point Style.svg | 0 .../icons/settings/custom/Rounding.svg | 0 .../icons/settings/custom/Target Element.svg | 0 .../settings/custom/Target Value Position.svg | 0 .../icons/settings/custom/Text.svg | 0 .../icons/settings/custom/Unit.svg | 0 .../icons/settings/custom/X.svg | 0 .../icons/settings/custom/Y.svg | 0 .../icons/settings/custom/ω_0.svg | 0 .../icons/settings/label.svg | 0 .../icons/settings/linewidth.svg | 0 .../icons/settings/text.svg | 0 .../icons/settings/textsize.svg | 0 .../icons/settings/timeline.svg | 0 .../icons/settings/update.svg | 0 .../icons/settings/xaxisstep.svg | 0 .../icons/settings/xlabel.svg | 0 .../icons/settings/xmax.svg | 0 .../icons/settings/xmin.svg | 0 .../icons/settings/xzoom.svg | 0 .../icons/settings/yaxisstep.svg | 0 .../icons/settings/ylabel.svg | 0 .../icons/settings/ymax.svg | 0 .../icons/settings/ymin.svg | 0 .../icons/settings/yzoom.svg | 0 .../logarithmplotter.svg | 0 .../logplotterfile.svg | 0 .../native/linux}/debian/changelog | 0 {linux => assets/native/linux}/debian/control | 0 .../native/linux}/debian/copyright | 0 {linux => assets/native/linux}/debian/depends | 0 .../native/linux}/debian/recommends | 0 {linux => assets/native/linux}/debian/rules | 0 .../eu.ad5001.LogarithmPlotter.metainfo.xml | 0 .../native/linux}/logarithmplotter.desktop | 0 .../launcher/launch-logarithmplotter | 0 .../native/linux}/x-logarithm-plot.xml | 0 {mac => assets/native/mac}/Info.plist | 0 {mac => assets/native/mac}/install-bg.png | Bin {mac => assets/native/mac}/install-bg.xcf | Bin .../native/mac}/logarithmplotter.icns | Bin .../logarithmplotter.iconset/icon_128x128.png | Bin .../logarithmplotter.iconset/icon_16x16.png | Bin .../logarithmplotter.iconset/icon_256x256.png | Bin .../logarithmplotter.iconset/icon_32x32.png | Bin .../logarithmplotter.iconset/icon_512x512.png | Bin .../native/mac}/logarithmplotterfile.icns | Bin .../icon_128x128.png | Bin .../icon_128x128@2x.png | Bin .../icon_16x16.png | Bin .../icon_16x16@2x.png | Bin .../icon_256x256.png | Bin .../icon_256x256@2x.png | Bin .../icon_32x32.png | Bin .../icon_32x32@2x.png | Bin .../icon_512x512.png | Bin .../icon_512x512@2x.png | Bin {win => assets/native/win}/inst_banner.bmp | Bin {win => assets/native/win}/installer.nsi | 2 +- .../native/win}/logarithmplotter.ico | Bin ci/drone.yml | 3 +- .mocharc.jsonc => common/.mocharc.jsonc | 0 babel.config.json => common/babel.config.json | 0 package-lock.json => common/package-lock.json | 0 package.json => common/package.json | 2 +- rollup.config.mjs => common/rollup.config.mjs | 7 +- .../js => common/src}/history/color.mjs | 0 .../js => common/src}/history/common.mjs | 0 .../js => common/src}/history/create.mjs | 0 .../js => common/src}/history/delete.mjs | 0 .../src}/history/editproperty.mjs | 0 .../js => common/src}/history/index.mjs | 0 .../js => common/src}/history/name.mjs | 0 .../js => common/src}/history/position.mjs | 0 .../js => common/src}/history/visibility.mjs | 0 .../js/autoload.mjs => common/src/index.mjs | 0 .../src}/lib/expr-eval/expression.mjs | 0 .../src}/lib/expr-eval/instruction.mjs | 0 .../src}/lib/expr-eval/parser.mjs | 0 .../src}/lib/expr-eval/parserstate.mjs | 0 .../src}/lib/expr-eval/polyfill.mjs | 0 .../src}/lib/expr-eval/tokens.mjs | 0 .../js => common/src}/lib/polyfills/js.mjs | 0 .../js => common/src}/lib/polyfills/qt.mjs | 0 .../js => common/src}/math/domain.mjs | 0 .../js => common/src}/math/expression.mjs | 0 .../js => common/src}/math/index.mjs | 0 .../js => common/src}/math/sequence.mjs | 0 .../js => common/src}/module/canvas.mjs | 0 .../js => common/src}/module/common.mjs | 0 .../js => common/src}/module/expreval.mjs | 0 .../js => common/src}/module/history.mjs | 0 .../js => common/src}/module/index.mjs | 0 .../js => common/src}/module/interface.mjs | 0 .../js => common/src}/module/io.mjs | 0 .../js => common/src}/module/latex.mjs | 0 .../js => common/src}/module/objects.mjs | 0 .../js => common/src}/module/preferences.mjs | 0 .../js => common/src}/objs/autoload.mjs | 0 .../js => common/src}/objs/bodemagnitude.mjs | 0 .../src}/objs/bodemagnitudesum.mjs | 0 .../js => common/src}/objs/bodephase.mjs | 0 .../js => common/src}/objs/bodephasesum.mjs | 0 .../js => common/src}/objs/common.mjs | 0 .../js => common/src}/objs/distribution.mjs | 0 .../js => common/src}/objs/function.mjs | 0 .../js => common/src}/objs/point.mjs | 0 .../js => common/src}/objs/sequence.mjs | 0 .../js => common/src}/objs/text.mjs | 0 .../js => common/src}/objs/xcursor.mjs | 0 .../js => common/src}/parameters.mjs | 0 .../js => common/src}/parsing/README.md | 0 .../js => common/src}/parsing/common.mjs | 0 .../js => common/src}/parsing/index.mjs | 0 .../js => common/src}/parsing/reference.mjs | 0 .../js => common/src}/parsing/tokenizer.mjs | 0 .../js => common/src}/preferences/common.mjs | 0 .../js => common/src}/preferences/default.mjs | 0 .../src}/preferences/expression.mjs | 0 .../js => common/src}/preferences/general.mjs | 0 .../js => common/src}/utils.mjs | 0 {tests/js => common/test}/hooks.mjs | 0 {tests/js => common/test}/math/domain.mjs | 0 {tests/js => common/test}/mock/fs.mjs | 0 {tests/js => common/test}/mock/helper.mjs | 0 {tests/js => common/test}/mock/latex.mjs | 0 {tests/js => common/test}/mock/qt.mjs | 0 linux/application-x-logarithm-plot.svg | 177 ------------------ run.py | 17 +- .../LogarithmPlotter}/__init__.py | 0 .../LogarithmPlotter}/logarithmplotter.py | 0 .../LogarithmPlotter/logarithmplotter.svg | 0 .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 0 .../LogarithmPlotter/History/History.qml | 0 .../History/HistoryBrowser.qml | 0 .../LogarithmPlotter/History/HistoryItem.qml | 0 .../eu/ad5001/LogarithmPlotter/History/qmldir | 0 .../LogarithmPlotter/LogGraphCanvas.qml | 0 .../LogarithmPlotter/LogarithmPlotter.qml | 0 .../ObjectLists/Editor/CustomPropertyList.qml | 0 .../ObjectLists/Editor/Dialog.qml | 0 .../ObjectLists/Editor/qmldir | 0 .../ObjectLists/ObjectCreationGrid.qml | 0 .../ObjectLists/ObjectLists.qml | 0 .../ObjectLists/ObjectRow.qml | 0 .../LogarithmPlotter/ObjectLists/qmldir | 0 .../LogarithmPlotter/PickLocationOverlay.qml | 0 .../ad5001/LogarithmPlotter/Popup/About.qml | 0 .../ad5001/LogarithmPlotter/Popup/Alert.qml | 0 .../LogarithmPlotter/Popup/BaseDialog.qml | 0 .../LogarithmPlotter/Popup/Changelog.qml | 0 .../LogarithmPlotter/Popup/FileDialog.qml | 0 .../LogarithmPlotter/Popup/GreetScreen.qml | 0 .../Popup/InsertCharacter.qml | 0 .../LogarithmPlotter/Popup/Preferences.qml | 0 .../LogarithmPlotter/Popup/ThanksTo.qml | 0 .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 0 .../Setting/AutocompletionCategory.qml | 0 .../Setting/ComboBoxSetting.qml | 0 .../Setting/ExpressionEditor.qml | 0 .../ad5001/LogarithmPlotter/Setting/Icon.qml | 0 .../LogarithmPlotter/Setting/ListSetting.qml | 0 .../LogarithmPlotter/Setting/TextSetting.qml | 0 .../eu/ad5001/LogarithmPlotter/Setting/qmldir | 0 .../eu/ad5001/LogarithmPlotter/Settings.qml | 0 .../ViewPositionChangeOverlay.qml | 0 .../qml/eu/ad5001/LogarithmPlotter/qmldir | 0 .../LogarithmPlotter}/qml/eu/ad5001/MixedMenu | 0 .../LogarithmPlotter}/util/__init__.py | 0 .../LogarithmPlotter}/util/config.py | 0 .../LogarithmPlotter}/util/debug.py | 2 +- .../LogarithmPlotter}/util/helper.py | 0 .../LogarithmPlotter}/util/js.py | 0 .../LogarithmPlotter}/util/latex.py | 0 .../LogarithmPlotter}/util/native.py | 0 .../LogarithmPlotter}/util/update.py | 0 MANIFEST.in => runtime-pyside6/MANIFEST.in | 0 poetry.lock => runtime-pyside6/poetry.lock | 0 .../pyproject.toml | 0 setup.py => runtime-pyside6/setup.py | 0 .../tests}/globals.py | 0 .../tests}/test_config.py | 0 .../tests}/test_debug.py | 0 .../tests}/test_helper.py | 0 .../tests}/test_latex.py | 0 .../tests}/test_main.py | 0 .../tests}/test_native.py | 0 .../tests}/test_pyjs.py | 0 .../tests}/test_update.py | 0 scripts/build-macosx.sh | 21 +-- scripts/build-windows.bat | 17 -- scripts/build-wine.sh | 16 +- scripts/build.sh | 49 +++++ scripts/package-deb.sh | 11 ++ scripts/package-linux.sh | 32 ---- scripts/package-macosx.sh | 8 +- scripts/package-windows.bat | 7 - scripts/package-wine.sh | 6 +- snapcraft.yaml | 15 +- 249 files changed, 118 insertions(+), 294 deletions(-) rename {LogarithmPlotter => assets}/i18n/lp_de.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_en.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_es.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_fr.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_hu.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_nb_NO.ts (100%) rename {LogarithmPlotter => assets}/i18n/lp_template.ts (100%) rename {LogarithmPlotter => assets}/i18n/release.sh (100%) rename {LogarithmPlotter => assets}/i18n/update.sh (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/angle.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/appearance.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/arrow.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/close.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/delete.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/label.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/manual.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/new.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/position.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/settings.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/target.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/common/text.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/appearance.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/create.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/delete.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/modify.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/name.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/position.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/history/visibility.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/logarithmplotter.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Function.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Gain Bode.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Phase Bode.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Point.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Repartition.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Sequence.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/Text.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/objects/X Cursor.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/color.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Definition Domain.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Destination Domain.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Display Mode.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Display Style.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Expression.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Gain.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Label Position.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Label X.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Pass.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Phase.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Point Style.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Rounding.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Target Element.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Target Value Position.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Text.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Unit.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/X.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/Y.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/custom/ω_0.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/label.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/linewidth.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/text.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/textsize.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/timeline.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/update.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/xaxisstep.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/xlabel.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/xmax.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/xmin.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/xzoom.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/yaxisstep.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/ylabel.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/ymax.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/ymin.svg (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter => assets}/icons/settings/yzoom.svg (100%) rename {LogarithmPlotter => assets}/logarithmplotter.svg (100%) rename logplotterfile.svg => assets/logplotterfile.svg (100%) rename {linux => assets/native/linux}/debian/changelog (100%) rename {linux => assets/native/linux}/debian/control (100%) rename {linux => assets/native/linux}/debian/copyright (100%) rename {linux => assets/native/linux}/debian/depends (100%) rename {linux => assets/native/linux}/debian/recommends (100%) rename {linux => assets/native/linux}/debian/rules (100%) rename {linux => assets/native/linux}/eu.ad5001.LogarithmPlotter.metainfo.xml (100%) rename {linux => assets/native/linux}/logarithmplotter.desktop (100%) rename {linux => assets/native/linux}/snapcraft/launcher/launch-logarithmplotter (100%) rename {linux => assets/native/linux}/x-logarithm-plot.xml (100%) rename {mac => assets/native/mac}/Info.plist (100%) rename {mac => assets/native/mac}/install-bg.png (100%) rename {mac => assets/native/mac}/install-bg.xcf (100%) rename {mac => assets/native/mac}/logarithmplotter.icns (100%) rename {mac => assets/native/mac}/logarithmplotter.iconset/icon_128x128.png (100%) rename {mac => assets/native/mac}/logarithmplotter.iconset/icon_16x16.png (100%) rename {mac => assets/native/mac}/logarithmplotter.iconset/icon_256x256.png (100%) rename {mac => assets/native/mac}/logarithmplotter.iconset/icon_32x32.png (100%) rename {mac => assets/native/mac}/logarithmplotter.iconset/icon_512x512.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.icns (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_128x128.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_128x128@2x.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_16x16.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_16x16@2x.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_256x256.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_256x256@2x.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_32x32.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_32x32@2x.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_512x512.png (100%) rename {mac => assets/native/mac}/logarithmplotterfile.iconset/icon_512x512@2x.png (100%) rename {win => assets/native/win}/inst_banner.bmp (100%) rename {win => assets/native/win}/installer.nsi (99%) rename {win => assets/native/win}/logarithmplotter.ico (100%) rename .mocharc.jsonc => common/.mocharc.jsonc (100%) rename babel.config.json => common/babel.config.json (100%) rename package-lock.json => common/package-lock.json (100%) rename package.json => common/package.json (95%) rename rollup.config.mjs => common/rollup.config.mjs (88%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/color.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/common.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/create.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/delete.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/editproperty.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/index.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/name.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/position.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/history/visibility.mjs (100%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs => common/src/index.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/expression.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/instruction.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/parser.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/parserstate.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/polyfill.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/expr-eval/tokens.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/polyfills/js.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/lib/polyfills/qt.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/math/domain.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/math/expression.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/math/index.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/math/sequence.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/canvas.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/common.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/expreval.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/history.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/index.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/interface.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/io.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/latex.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/objects.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/module/preferences.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/autoload.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/bodemagnitude.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/bodemagnitudesum.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/bodephase.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/bodephasesum.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/common.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/distribution.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/function.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/point.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/sequence.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/text.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/objs/xcursor.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parameters.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parsing/README.md (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parsing/common.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parsing/index.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parsing/reference.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/parsing/tokenizer.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/preferences/common.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/preferences/default.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/preferences/expression.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/preferences/general.mjs (100%) rename {LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js => common/src}/utils.mjs (100%) rename {tests/js => common/test}/hooks.mjs (100%) rename {tests/js => common/test}/math/domain.mjs (100%) rename {tests/js => common/test}/mock/fs.mjs (100%) rename {tests/js => common/test}/mock/helper.mjs (100%) rename {tests/js => common/test}/mock/latex.mjs (100%) rename {tests/js => common/test}/mock/qt.mjs (100%) delete mode 100644 linux/application-x-logarithm-plot.svg rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/__init__.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/logarithmplotter.py (100%) rename logplotter.svg => runtime-pyside6/LogarithmPlotter/logarithmplotter.svg (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/History/History.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/History/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/Settings.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/LogarithmPlotter/qmldir (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/qml/eu/ad5001/MixedMenu (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/__init__.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/config.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/debug.py (98%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/helper.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/js.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/latex.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/native.py (100%) rename {LogarithmPlotter => runtime-pyside6/LogarithmPlotter}/util/update.py (100%) rename MANIFEST.in => runtime-pyside6/MANIFEST.in (100%) rename poetry.lock => runtime-pyside6/poetry.lock (100%) rename pyproject.toml => runtime-pyside6/pyproject.toml (100%) rename setup.py => runtime-pyside6/setup.py (100%) rename {tests/python => runtime-pyside6/tests}/globals.py (100%) rename {tests/python => runtime-pyside6/tests}/test_config.py (100%) rename {tests/python => runtime-pyside6/tests}/test_debug.py (100%) rename {tests/python => runtime-pyside6/tests}/test_helper.py (100%) rename {tests/python => runtime-pyside6/tests}/test_latex.py (100%) rename {tests/python => runtime-pyside6/tests}/test_main.py (100%) rename {tests/python => runtime-pyside6/tests}/test_native.py (100%) rename {tests/python => runtime-pyside6/tests}/test_pyjs.py (100%) rename {tests/python => runtime-pyside6/tests}/test_update.py (100%) delete mode 100644 scripts/build-windows.bat create mode 100755 scripts/build.sh create mode 100755 scripts/package-deb.sh delete mode 100755 scripts/package-linux.sh delete mode 100644 scripts/package-windows.bat diff --git a/.gitignore b/.gitignore index 0bfb625..3961125 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,10 @@ build/ dist/ deb_dist/ -linux/flatpak/AppDir -linux/flatpak/repo -linux/flatpak/build-dir -linux/flatpak/.flatpak-builder +assets/linux/flatpak/AppDir +assets/linux/flatpak/repo +assets/linux/flatpak/build-dir +assets/linux/flatpak/.flatpak-builder *.snap *.spec *.zip @@ -38,7 +38,7 @@ docs/html *.lgg # npm -node_modules -coverage/ -.coverage -LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs* +common/node_modules +common/coverage/ +common/.coverage +runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs* diff --git a/.gitmodules b/.gitmodules index df81e42..042c634 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "LogarithmPlotter/qml/eu/ad5001/MixedMenu"] - path = LogarithmPlotter/qml/eu/ad5001/MixedMenu +[submodule "runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu"] + path = runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu url = https://git.ad5001.eu/Ad5001/MixedMenu diff --git a/LogarithmPlotter/i18n/lp_de.ts b/assets/i18n/lp_de.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_de.ts rename to assets/i18n/lp_de.ts diff --git a/LogarithmPlotter/i18n/lp_en.ts b/assets/i18n/lp_en.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_en.ts rename to assets/i18n/lp_en.ts diff --git a/LogarithmPlotter/i18n/lp_es.ts b/assets/i18n/lp_es.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_es.ts rename to assets/i18n/lp_es.ts diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_fr.ts rename to assets/i18n/lp_fr.ts diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_hu.ts rename to assets/i18n/lp_hu.ts diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_nb_NO.ts rename to assets/i18n/lp_nb_NO.ts diff --git a/LogarithmPlotter/i18n/lp_template.ts b/assets/i18n/lp_template.ts similarity index 100% rename from LogarithmPlotter/i18n/lp_template.ts rename to assets/i18n/lp_template.ts diff --git a/LogarithmPlotter/i18n/release.sh b/assets/i18n/release.sh similarity index 100% rename from LogarithmPlotter/i18n/release.sh rename to assets/i18n/release.sh diff --git a/LogarithmPlotter/i18n/update.sh b/assets/i18n/update.sh similarity index 100% rename from LogarithmPlotter/i18n/update.sh rename to assets/i18n/update.sh diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/angle.svg b/assets/icons/common/angle.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/angle.svg rename to assets/icons/common/angle.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/appearance.svg b/assets/icons/common/appearance.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/appearance.svg rename to assets/icons/common/appearance.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/arrow.svg b/assets/icons/common/arrow.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/arrow.svg rename to assets/icons/common/arrow.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg b/assets/icons/common/close.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg rename to assets/icons/common/close.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/delete.svg b/assets/icons/common/delete.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/delete.svg rename to assets/icons/common/delete.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/label.svg b/assets/icons/common/label.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/label.svg rename to assets/icons/common/label.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg b/assets/icons/common/manual.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg rename to assets/icons/common/manual.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg b/assets/icons/common/new.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg rename to assets/icons/common/new.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/position.svg b/assets/icons/common/position.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/position.svg rename to assets/icons/common/position.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg b/assets/icons/common/settings.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg rename to assets/icons/common/settings.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/target.svg b/assets/icons/common/target.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/target.svg rename to assets/icons/common/target.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg b/assets/icons/common/text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg rename to assets/icons/common/text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/appearance.svg b/assets/icons/history/appearance.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/appearance.svg rename to assets/icons/history/appearance.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/create.svg b/assets/icons/history/create.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/create.svg rename to assets/icons/history/create.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/assets/icons/history/delete.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg rename to assets/icons/history/delete.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/modify.svg b/assets/icons/history/modify.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/modify.svg rename to assets/icons/history/modify.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/name.svg b/assets/icons/history/name.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/name.svg rename to assets/icons/history/name.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/position.svg b/assets/icons/history/position.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/position.svg rename to assets/icons/history/position.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/visibility.svg b/assets/icons/history/visibility.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/visibility.svg rename to assets/icons/history/visibility.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/logarithmplotter.svg b/assets/icons/logarithmplotter.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/logarithmplotter.svg rename to assets/icons/logarithmplotter.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg b/assets/icons/objects/Function.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg rename to assets/icons/objects/Function.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg b/assets/icons/objects/Gain Bode.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg rename to assets/icons/objects/Gain Bode.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg b/assets/icons/objects/Phase Bode.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg rename to assets/icons/objects/Phase Bode.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg b/assets/icons/objects/Point.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg rename to assets/icons/objects/Point.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Repartition.svg b/assets/icons/objects/Repartition.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Repartition.svg rename to assets/icons/objects/Repartition.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg b/assets/icons/objects/Sequence.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg rename to assets/icons/objects/Sequence.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg b/assets/icons/objects/Text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg rename to assets/icons/objects/Text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg b/assets/icons/objects/X Cursor.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg rename to assets/icons/objects/X Cursor.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg b/assets/icons/settings/color.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg rename to assets/icons/settings/color.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Definition Domain.svg b/assets/icons/settings/custom/Definition Domain.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Definition Domain.svg rename to assets/icons/settings/custom/Definition Domain.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Destination Domain.svg b/assets/icons/settings/custom/Destination Domain.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Destination Domain.svg rename to assets/icons/settings/custom/Destination Domain.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Mode.svg b/assets/icons/settings/custom/Display Mode.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Mode.svg rename to assets/icons/settings/custom/Display Mode.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Style.svg b/assets/icons/settings/custom/Display Style.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Style.svg rename to assets/icons/settings/custom/Display Style.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Expression.svg b/assets/icons/settings/custom/Expression.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Expression.svg rename to assets/icons/settings/custom/Expression.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Gain.svg b/assets/icons/settings/custom/Gain.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Gain.svg rename to assets/icons/settings/custom/Gain.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label Position.svg b/assets/icons/settings/custom/Label Position.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label Position.svg rename to assets/icons/settings/custom/Label Position.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label X.svg b/assets/icons/settings/custom/Label X.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label X.svg rename to assets/icons/settings/custom/Label X.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Pass.svg b/assets/icons/settings/custom/Pass.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Pass.svg rename to assets/icons/settings/custom/Pass.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Phase.svg b/assets/icons/settings/custom/Phase.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Phase.svg rename to assets/icons/settings/custom/Phase.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Point Style.svg b/assets/icons/settings/custom/Point Style.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Point Style.svg rename to assets/icons/settings/custom/Point Style.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Rounding.svg b/assets/icons/settings/custom/Rounding.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Rounding.svg rename to assets/icons/settings/custom/Rounding.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Element.svg b/assets/icons/settings/custom/Target Element.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Element.svg rename to assets/icons/settings/custom/Target Element.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Value Position.svg b/assets/icons/settings/custom/Target Value Position.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Value Position.svg rename to assets/icons/settings/custom/Target Value Position.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Text.svg b/assets/icons/settings/custom/Text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Text.svg rename to assets/icons/settings/custom/Text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Unit.svg b/assets/icons/settings/custom/Unit.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Unit.svg rename to assets/icons/settings/custom/Unit.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/X.svg b/assets/icons/settings/custom/X.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/X.svg rename to assets/icons/settings/custom/X.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Y.svg b/assets/icons/settings/custom/Y.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Y.svg rename to assets/icons/settings/custom/Y.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg b/assets/icons/settings/custom/ω_0.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg rename to assets/icons/settings/custom/ω_0.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg b/assets/icons/settings/label.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg rename to assets/icons/settings/label.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/linewidth.svg b/assets/icons/settings/linewidth.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/linewidth.svg rename to assets/icons/settings/linewidth.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg b/assets/icons/settings/text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg rename to assets/icons/settings/text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/textsize.svg b/assets/icons/settings/textsize.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/textsize.svg rename to assets/icons/settings/textsize.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/timeline.svg b/assets/icons/settings/timeline.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/timeline.svg rename to assets/icons/settings/timeline.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/update.svg b/assets/icons/settings/update.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/update.svg rename to assets/icons/settings/update.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xaxisstep.svg b/assets/icons/settings/xaxisstep.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xaxisstep.svg rename to assets/icons/settings/xaxisstep.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xlabel.svg b/assets/icons/settings/xlabel.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xlabel.svg rename to assets/icons/settings/xlabel.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmax.svg b/assets/icons/settings/xmax.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmax.svg rename to assets/icons/settings/xmax.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmin.svg b/assets/icons/settings/xmin.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmin.svg rename to assets/icons/settings/xmin.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xzoom.svg b/assets/icons/settings/xzoom.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xzoom.svg rename to assets/icons/settings/xzoom.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yaxisstep.svg b/assets/icons/settings/yaxisstep.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yaxisstep.svg rename to assets/icons/settings/yaxisstep.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ylabel.svg b/assets/icons/settings/ylabel.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ylabel.svg rename to assets/icons/settings/ylabel.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymax.svg b/assets/icons/settings/ymax.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymax.svg rename to assets/icons/settings/ymax.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymin.svg b/assets/icons/settings/ymin.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymin.svg rename to assets/icons/settings/ymin.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yzoom.svg b/assets/icons/settings/yzoom.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yzoom.svg rename to assets/icons/settings/yzoom.svg diff --git a/LogarithmPlotter/logarithmplotter.svg b/assets/logarithmplotter.svg similarity index 100% rename from LogarithmPlotter/logarithmplotter.svg rename to assets/logarithmplotter.svg diff --git a/logplotterfile.svg b/assets/logplotterfile.svg similarity index 100% rename from logplotterfile.svg rename to assets/logplotterfile.svg diff --git a/linux/debian/changelog b/assets/native/linux/debian/changelog similarity index 100% rename from linux/debian/changelog rename to assets/native/linux/debian/changelog diff --git a/linux/debian/control b/assets/native/linux/debian/control similarity index 100% rename from linux/debian/control rename to assets/native/linux/debian/control diff --git a/linux/debian/copyright b/assets/native/linux/debian/copyright similarity index 100% rename from linux/debian/copyright rename to assets/native/linux/debian/copyright diff --git a/linux/debian/depends b/assets/native/linux/debian/depends similarity index 100% rename from linux/debian/depends rename to assets/native/linux/debian/depends diff --git a/linux/debian/recommends b/assets/native/linux/debian/recommends similarity index 100% rename from linux/debian/recommends rename to assets/native/linux/debian/recommends diff --git a/linux/debian/rules b/assets/native/linux/debian/rules similarity index 100% rename from linux/debian/rules rename to assets/native/linux/debian/rules diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml similarity index 100% rename from linux/eu.ad5001.LogarithmPlotter.metainfo.xml rename to assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml diff --git a/linux/logarithmplotter.desktop b/assets/native/linux/logarithmplotter.desktop similarity index 100% rename from linux/logarithmplotter.desktop rename to assets/native/linux/logarithmplotter.desktop diff --git a/linux/snapcraft/launcher/launch-logarithmplotter b/assets/native/linux/snapcraft/launcher/launch-logarithmplotter similarity index 100% rename from linux/snapcraft/launcher/launch-logarithmplotter rename to assets/native/linux/snapcraft/launcher/launch-logarithmplotter diff --git a/linux/x-logarithm-plot.xml b/assets/native/linux/x-logarithm-plot.xml similarity index 100% rename from linux/x-logarithm-plot.xml rename to assets/native/linux/x-logarithm-plot.xml diff --git a/mac/Info.plist b/assets/native/mac/Info.plist similarity index 100% rename from mac/Info.plist rename to assets/native/mac/Info.plist diff --git a/mac/install-bg.png b/assets/native/mac/install-bg.png similarity index 100% rename from mac/install-bg.png rename to assets/native/mac/install-bg.png diff --git a/mac/install-bg.xcf b/assets/native/mac/install-bg.xcf similarity index 100% rename from mac/install-bg.xcf rename to assets/native/mac/install-bg.xcf diff --git a/mac/logarithmplotter.icns b/assets/native/mac/logarithmplotter.icns similarity index 100% rename from mac/logarithmplotter.icns rename to assets/native/mac/logarithmplotter.icns diff --git a/mac/logarithmplotter.iconset/icon_128x128.png b/assets/native/mac/logarithmplotter.iconset/icon_128x128.png similarity index 100% rename from mac/logarithmplotter.iconset/icon_128x128.png rename to assets/native/mac/logarithmplotter.iconset/icon_128x128.png diff --git a/mac/logarithmplotter.iconset/icon_16x16.png b/assets/native/mac/logarithmplotter.iconset/icon_16x16.png similarity index 100% rename from mac/logarithmplotter.iconset/icon_16x16.png rename to assets/native/mac/logarithmplotter.iconset/icon_16x16.png diff --git a/mac/logarithmplotter.iconset/icon_256x256.png b/assets/native/mac/logarithmplotter.iconset/icon_256x256.png similarity index 100% rename from mac/logarithmplotter.iconset/icon_256x256.png rename to assets/native/mac/logarithmplotter.iconset/icon_256x256.png diff --git a/mac/logarithmplotter.iconset/icon_32x32.png b/assets/native/mac/logarithmplotter.iconset/icon_32x32.png similarity index 100% rename from mac/logarithmplotter.iconset/icon_32x32.png rename to assets/native/mac/logarithmplotter.iconset/icon_32x32.png diff --git a/mac/logarithmplotter.iconset/icon_512x512.png b/assets/native/mac/logarithmplotter.iconset/icon_512x512.png similarity index 100% rename from mac/logarithmplotter.iconset/icon_512x512.png rename to assets/native/mac/logarithmplotter.iconset/icon_512x512.png diff --git a/mac/logarithmplotterfile.icns b/assets/native/mac/logarithmplotterfile.icns similarity index 100% rename from mac/logarithmplotterfile.icns rename to assets/native/mac/logarithmplotterfile.icns diff --git a/mac/logarithmplotterfile.iconset/icon_128x128.png b/assets/native/mac/logarithmplotterfile.iconset/icon_128x128.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_128x128.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_128x128.png diff --git a/mac/logarithmplotterfile.iconset/icon_128x128@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_128x128@2x.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_128x128@2x.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_128x128@2x.png diff --git a/mac/logarithmplotterfile.iconset/icon_16x16.png b/assets/native/mac/logarithmplotterfile.iconset/icon_16x16.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_16x16.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_16x16.png diff --git a/mac/logarithmplotterfile.iconset/icon_16x16@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_16x16@2x.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_16x16@2x.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_16x16@2x.png diff --git a/mac/logarithmplotterfile.iconset/icon_256x256.png b/assets/native/mac/logarithmplotterfile.iconset/icon_256x256.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_256x256.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_256x256.png diff --git a/mac/logarithmplotterfile.iconset/icon_256x256@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_256x256@2x.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_256x256@2x.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_256x256@2x.png diff --git a/mac/logarithmplotterfile.iconset/icon_32x32.png b/assets/native/mac/logarithmplotterfile.iconset/icon_32x32.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_32x32.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_32x32.png diff --git a/mac/logarithmplotterfile.iconset/icon_32x32@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_32x32@2x.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_32x32@2x.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_32x32@2x.png diff --git a/mac/logarithmplotterfile.iconset/icon_512x512.png b/assets/native/mac/logarithmplotterfile.iconset/icon_512x512.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_512x512.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_512x512.png diff --git a/mac/logarithmplotterfile.iconset/icon_512x512@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_512x512@2x.png similarity index 100% rename from mac/logarithmplotterfile.iconset/icon_512x512@2x.png rename to assets/native/mac/logarithmplotterfile.iconset/icon_512x512@2x.png diff --git a/win/inst_banner.bmp b/assets/native/win/inst_banner.bmp similarity index 100% rename from win/inst_banner.bmp rename to assets/native/win/inst_banner.bmp diff --git a/win/installer.nsi b/assets/native/win/installer.nsi similarity index 99% rename from win/installer.nsi rename to assets/native/win/installer.nsi index 58261ff..ebb84c9 100644 --- a/win/installer.nsi +++ b/assets/native/win/installer.nsi @@ -14,7 +14,7 @@ Unicode True !define VERSION_SHORT "0.6.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2021-2024" -!define DESCRIPTION "Create graphs with logarithm scales." +!define DESCRIPTION "Create graphs with logarithmic scales." !define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter" !define REG_APPPATHS "Software\Microsoft\Windows\CurrentVersion\App Paths\logarithmplotter.exe" diff --git a/win/logarithmplotter.ico b/assets/native/win/logarithmplotter.ico similarity index 100% rename from win/logarithmplotter.ico rename to assets/native/win/logarithmplotter.ico diff --git a/ci/drone.yml b/ci/drone.yml index 4ff14ff..2800cb6 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -18,8 +18,7 @@ steps: - apt update - apt install -y qtchooser qttools5-dev-tools # Start building - - cd LogarithmPlotter/i18n && bash release.sh && cd ../.. - - npm run build + - bash scripts/build.sh when: event: [ push, tag ] diff --git a/.mocharc.jsonc b/common/.mocharc.jsonc similarity index 100% rename from .mocharc.jsonc rename to common/.mocharc.jsonc diff --git a/babel.config.json b/common/babel.config.json similarity index 100% rename from babel.config.json rename to common/babel.config.json diff --git a/package-lock.json b/common/package-lock.json similarity index 100% rename from package-lock.json rename to common/package-lock.json diff --git a/package.json b/common/package.json similarity index 95% rename from package.json rename to common/package.json index aaa4841..9ef203c 100644 --- a/package.json +++ b/common/package.json @@ -5,7 +5,7 @@ "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", "scripts": { "build": "rollup --config rollup.config.mjs", - "test": "c8 mocha tests/js/**/*.mjs" + "test": "c8 mocha test/**/*.mjs" }, "repository": { "type": "git", diff --git a/rollup.config.mjs b/common/rollup.config.mjs similarity index 88% rename from rollup.config.mjs rename to common/rollup.config.mjs index 892c9fb..6a18a41 100644 --- a/rollup.config.mjs +++ b/common/rollup.config.mjs @@ -21,12 +21,13 @@ import commonjs from "@rollup/plugin-commonjs" import { babel } from "@rollup/plugin-babel" import cleanup from "rollup-plugin-cleanup" -const path = "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js" +const src = "./src/index.mjs" +const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs" export default { - input: `${path}/autoload.mjs`, + input: src, output: { - file: `${path}/index.mjs`, + file: dest, compact: false, sourcemap: true, format: "es" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/common/src/history/color.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs rename to common/src/history/color.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/common/src/history/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs rename to common/src/history/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/common/src/history/create.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs rename to common/src/history/create.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/common/src/history/delete.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs rename to common/src/history/delete.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/common/src/history/editproperty.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs rename to common/src/history/editproperty.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs b/common/src/history/index.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs rename to common/src/history/index.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/common/src/history/name.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs rename to common/src/history/name.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/common/src/history/position.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs rename to common/src/history/position.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/common/src/history/visibility.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs rename to common/src/history/visibility.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/common/src/index.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs rename to common/src/index.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs rename to common/src/lib/expr-eval/expression.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs b/common/src/lib/expr-eval/instruction.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs rename to common/src/lib/expr-eval/instruction.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs rename to common/src/lib/expr-eval/parser.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs b/common/src/lib/expr-eval/parserstate.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs rename to common/src/lib/expr-eval/parserstate.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs rename to common/src/lib/expr-eval/polyfill.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs b/common/src/lib/expr-eval/tokens.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs rename to common/src/lib/expr-eval/tokens.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/js.mjs rename to common/src/lib/polyfills/js.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs b/common/src/lib/polyfills/qt.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/polyfills/qt.mjs rename to common/src/lib/polyfills/qt.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/common/src/math/domain.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs rename to common/src/math/domain.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/common/src/math/expression.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs rename to common/src/math/expression.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs b/common/src/math/index.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs rename to common/src/math/index.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/common/src/math/sequence.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs rename to common/src/math/sequence.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/common/src/module/canvas.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs rename to common/src/module/canvas.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/common/src/module/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs rename to common/src/module/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/common/src/module/expreval.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs rename to common/src/module/expreval.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/common/src/module/history.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs rename to common/src/module/history.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs b/common/src/module/index.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs rename to common/src/module/index.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/common/src/module/interface.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs rename to common/src/module/interface.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/common/src/module/io.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs rename to common/src/module/io.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/common/src/module/latex.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs rename to common/src/module/latex.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs b/common/src/module/objects.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs rename to common/src/module/objects.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs b/common/src/module/preferences.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs rename to common/src/module/preferences.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/common/src/objs/autoload.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs rename to common/src/objs/autoload.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/common/src/objs/bodemagnitude.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs rename to common/src/objs/bodemagnitude.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/common/src/objs/bodemagnitudesum.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs rename to common/src/objs/bodemagnitudesum.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/common/src/objs/bodephase.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs rename to common/src/objs/bodephase.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/common/src/objs/bodephasesum.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs rename to common/src/objs/bodephasesum.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/common/src/objs/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs rename to common/src/objs/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/common/src/objs/distribution.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs rename to common/src/objs/distribution.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/common/src/objs/function.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs rename to common/src/objs/function.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/common/src/objs/point.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs rename to common/src/objs/point.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/common/src/objs/sequence.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs rename to common/src/objs/sequence.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/common/src/objs/text.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs rename to common/src/objs/text.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/common/src/objs/xcursor.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs rename to common/src/objs/xcursor.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/common/src/parameters.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs rename to common/src/parameters.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md b/common/src/parsing/README.md similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md rename to common/src/parsing/README.md diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs b/common/src/parsing/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs rename to common/src/parsing/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/index.mjs b/common/src/parsing/index.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/index.mjs rename to common/src/parsing/index.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs b/common/src/parsing/reference.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs rename to common/src/parsing/reference.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs b/common/src/parsing/tokenizer.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs rename to common/src/parsing/tokenizer.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/common/src/preferences/common.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs rename to common/src/preferences/common.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/common/src/preferences/default.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs rename to common/src/preferences/default.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/common/src/preferences/expression.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs rename to common/src/preferences/expression.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/common/src/preferences/general.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs rename to common/src/preferences/general.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs b/common/src/utils.mjs similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs rename to common/src/utils.mjs diff --git a/tests/js/hooks.mjs b/common/test/hooks.mjs similarity index 100% rename from tests/js/hooks.mjs rename to common/test/hooks.mjs diff --git a/tests/js/math/domain.mjs b/common/test/math/domain.mjs similarity index 100% rename from tests/js/math/domain.mjs rename to common/test/math/domain.mjs diff --git a/tests/js/mock/fs.mjs b/common/test/mock/fs.mjs similarity index 100% rename from tests/js/mock/fs.mjs rename to common/test/mock/fs.mjs diff --git a/tests/js/mock/helper.mjs b/common/test/mock/helper.mjs similarity index 100% rename from tests/js/mock/helper.mjs rename to common/test/mock/helper.mjs diff --git a/tests/js/mock/latex.mjs b/common/test/mock/latex.mjs similarity index 100% rename from tests/js/mock/latex.mjs rename to common/test/mock/latex.mjs diff --git a/tests/js/mock/qt.mjs b/common/test/mock/qt.mjs similarity index 100% rename from tests/js/mock/qt.mjs rename to common/test/mock/qt.mjs diff --git a/linux/application-x-logarithm-plot.svg b/linux/application-x-logarithm-plot.svg deleted file mode 100644 index 580277f..0000000 --- a/linux/application-x-logarithm-plot.svg +++ /dev/null @@ -1,177 +0,0 @@ - - - LogarithmPlotter Icon - - - - - - - - - - - - - - - - - - - image/svg+xml - - LogarithmPlotter File Icon - 2021 - - - Ad5001 - - - - - (c) Copyright Ad5001 2021 - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/run.py b/run.py index 7978a15..2fae168 100644 --- a/run.py +++ b/run.py @@ -15,22 +15,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -def update_translations(): +from os import system, getcwd, path +from sys import path as sys_path + +def build(): """ Updates all binary translations """ - from os import system, getcwd, chdir, path - pwd = getcwd() - system("npm run build") - chdir(path.join("LogarithmPlotter", "i18n")) - system("./release.sh") - chdir(pwd) + system("./scripts/build.sh") def run(): - update_translations() from LogarithmPlotter import logarithmplotter logarithmplotter.run() if __name__ == "__main__": + build() + logplotter_path = path.realpath(path.join(getcwd(), "build", "runtime-pyside6")) + print("Appending " + logplotter_path + " to path...") + sys_path.append(logplotter_path) run() diff --git a/LogarithmPlotter/__init__.py b/runtime-pyside6/LogarithmPlotter/__init__.py similarity index 100% rename from LogarithmPlotter/__init__.py rename to runtime-pyside6/LogarithmPlotter/__init__.py diff --git a/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py similarity index 100% rename from LogarithmPlotter/logarithmplotter.py rename to runtime-pyside6/LogarithmPlotter/logarithmplotter.py diff --git a/logplotter.svg b/runtime-pyside6/LogarithmPlotter/logarithmplotter.svg similarity index 100% rename from logplotter.svg rename to runtime-pyside6/LogarithmPlotter/logarithmplotter.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir diff --git a/LogarithmPlotter/qml/eu/ad5001/MixedMenu b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/MixedMenu rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu diff --git a/LogarithmPlotter/util/__init__.py b/runtime-pyside6/LogarithmPlotter/util/__init__.py similarity index 100% rename from LogarithmPlotter/util/__init__.py rename to runtime-pyside6/LogarithmPlotter/util/__init__.py diff --git a/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py similarity index 100% rename from LogarithmPlotter/util/config.py rename to runtime-pyside6/LogarithmPlotter/util/config.py diff --git a/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py similarity index 98% rename from LogarithmPlotter/util/debug.py rename to runtime-pyside6/LogarithmPlotter/util/debug.py index 05271ac..8b57687 100644 --- a/LogarithmPlotter/util/debug.py +++ b/runtime-pyside6/LogarithmPlotter/util/debug.py @@ -52,7 +52,7 @@ def map_javascript_source(source_file: str, line: str) -> tuple[str, str]: try: if SOURCEMAP_INDEX is not None: token = SOURCEMAP_INDEX.lookup(line, 20) - source_file = source_file[:-len("index.mjs")] + token.src + source_file = token.src.split("../")[-1] line = token.src_line except IndexError: pass # Unable to find source, leave as is. diff --git a/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py similarity index 100% rename from LogarithmPlotter/util/helper.py rename to runtime-pyside6/LogarithmPlotter/util/helper.py diff --git a/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py similarity index 100% rename from LogarithmPlotter/util/js.py rename to runtime-pyside6/LogarithmPlotter/util/js.py diff --git a/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py similarity index 100% rename from LogarithmPlotter/util/latex.py rename to runtime-pyside6/LogarithmPlotter/util/latex.py diff --git a/LogarithmPlotter/util/native.py b/runtime-pyside6/LogarithmPlotter/util/native.py similarity index 100% rename from LogarithmPlotter/util/native.py rename to runtime-pyside6/LogarithmPlotter/util/native.py diff --git a/LogarithmPlotter/util/update.py b/runtime-pyside6/LogarithmPlotter/util/update.py similarity index 100% rename from LogarithmPlotter/util/update.py rename to runtime-pyside6/LogarithmPlotter/util/update.py diff --git a/MANIFEST.in b/runtime-pyside6/MANIFEST.in similarity index 100% rename from MANIFEST.in rename to runtime-pyside6/MANIFEST.in diff --git a/poetry.lock b/runtime-pyside6/poetry.lock similarity index 100% rename from poetry.lock rename to runtime-pyside6/poetry.lock diff --git a/pyproject.toml b/runtime-pyside6/pyproject.toml similarity index 100% rename from pyproject.toml rename to runtime-pyside6/pyproject.toml diff --git a/setup.py b/runtime-pyside6/setup.py similarity index 100% rename from setup.py rename to runtime-pyside6/setup.py diff --git a/tests/python/globals.py b/runtime-pyside6/tests/globals.py similarity index 100% rename from tests/python/globals.py rename to runtime-pyside6/tests/globals.py diff --git a/tests/python/test_config.py b/runtime-pyside6/tests/test_config.py similarity index 100% rename from tests/python/test_config.py rename to runtime-pyside6/tests/test_config.py diff --git a/tests/python/test_debug.py b/runtime-pyside6/tests/test_debug.py similarity index 100% rename from tests/python/test_debug.py rename to runtime-pyside6/tests/test_debug.py diff --git a/tests/python/test_helper.py b/runtime-pyside6/tests/test_helper.py similarity index 100% rename from tests/python/test_helper.py rename to runtime-pyside6/tests/test_helper.py diff --git a/tests/python/test_latex.py b/runtime-pyside6/tests/test_latex.py similarity index 100% rename from tests/python/test_latex.py rename to runtime-pyside6/tests/test_latex.py diff --git a/tests/python/test_main.py b/runtime-pyside6/tests/test_main.py similarity index 100% rename from tests/python/test_main.py rename to runtime-pyside6/tests/test_main.py diff --git a/tests/python/test_native.py b/runtime-pyside6/tests/test_native.py similarity index 100% rename from tests/python/test_native.py rename to runtime-pyside6/tests/test_native.py diff --git a/tests/python/test_pyjs.py b/runtime-pyside6/tests/test_pyjs.py similarity index 100% rename from tests/python/test_pyjs.py rename to runtime-pyside6/tests/test_pyjs.py diff --git a/tests/python/test_update.py b/runtime-pyside6/tests/test_update.py similarity index 100% rename from tests/python/test_update.py rename to runtime-pyside6/tests/test_update.py diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index a8f0783..c398735 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -1,20 +1,17 @@ #!/usr/bin/env bash DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$DIR/.." +cd "$DIR/.." || exit 1 +rm -rf build +bash scripts/build.sh +cd build || exit 1 -rm $(find . -name "*.qmlc") rm $(find . -name "*.pyc") -# Building translations -cd "LogarithmPlotter/i18n/" -bash release.sh -cd ../../ - pyinstaller --add-data "LogarithmPlotter/qml:qml" \ --add-data "LogarithmPlotter/i18n:i18n" \ --add-data "LICENSE.md:." \ - --add-data "mac/logarithmplotterfile.icns:." \ + --add-data "../assets/native/mac/logarithmplotterfile.icns:." \ --add-data "README.md:." \ --exclude-module "FixTk" \ --exclude-module "tcl" \ @@ -24,21 +21,19 @@ pyinstaller --add-data "LogarithmPlotter/qml:qml" \ --exclude-module "Tkinter" \ --noconsole \ --noconfirm \ - --icon=mac/logarithmplotter.icns \ + --icon=../assets/native/mac/logarithmplotter.icns \ --osx-bundle-identifier eu.ad5001.LogarithmPlotter \ -n LogarithmPlotter \ LogarithmPlotter/logarithmplotter.py -cp mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist +cp ../assets/native/mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist # Remove QtWebEngine, 3D and all other unused libs libs rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/{QtNetwork.abi3.so} # Removing QtQuick3D -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick3D -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/Qt3D -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtWebEngine +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/{QtQuick3D,Qt3D,QtWebEngine} # Remove the QtQuick styles that are unused rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick/Controls/{Imagine,Material,iOS,Universal,designer} diff --git a/scripts/build-windows.bat b/scripts/build-windows.bat deleted file mode 100644 index ef92aee..0000000 --- a/scripts/build-windows.bat +++ /dev/null @@ -1,17 +0,0 @@ -rem Make sure pyinstaller is installed -python -m pip install -U pyinstaller - -rem Building translations -cd "LogarithmPlotter\i18n" -cmd release.sh -cd ..\.. - -pyinstaller --add-data "logplotter.svg;." --add-data "LogarithmPlotter/qml;qml" --add-data "LogarithmPlotter/i18n;i18n" --noconsole LogarithmPlotter/logarithmplotter.py --icon=win/logarithmplotter.ico -n logarithmplotter - -rem Remove QtWebEngine -del dist\logarithmplotter\PySide6\Qt6WebEngineCore.dll -rem Remove the QtQuick styles that are unused -rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Imagine /s /q -rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Material /s /q -rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\designer /s /q -rem Remove unused translations diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 39b2312..c99d1e1 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -1,22 +1,18 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit -rm -rf dist +rm -rf build +bash scripts/build.sh +cd build || exit 1 -rm $(find . -name "*.qmlc") rm -rf $(find . -name "*.pyc") -# Building translations -cd "LogarithmPlotter/i18n/" -bash release.sh -cd ../../ - -wine pyinstaller --add-data "logplotter.svg;." \ +wine pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ --add-data "LogarithmPlotter/qml;qml" \ --add-data "LogarithmPlotter/i18n;i18n" \ --noconsole \ LogarithmPlotter/logarithmplotter.py \ - --icon=win/logarithmplotter.ico \ + --icon=../assets/native/win/logarithmplotter.ico \ -n logarithmplotter # Copy Qt6ShaderTools, a required library for for Qt5Compat diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..be25274 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. +# Copyright (C) 2021-2024 Ad5001 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# This script builds a dist version of LogarithmPlotter + +DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$DIR/.." || exit 1 + +box() { + len=${#1} + echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐" + echo "│ $1 │" + echo "└─$(printf '─%.0s' $(seq 1 "$len"))─┘" +} + +rm -rf build +mkdir -p build/runtime-pyside6 + +# Copy python +box "Copying pyside6 python runtime..." +cp -r runtime-pyside6/{setup.py,LogarithmPlotter} build/runtime-pyside6 + +box "Building ecmascript modules..." +mkdir -p build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js +cd common && (npm run build || exit) && cd .. + +box "Building translations..." +cd assets/i18n/ && (bash release.sh || exit) && cd ../../ +mkdir -p build/runtime-pyside6/LogarithmPlotter/i18n && cp assets/i18n/*.qm build/runtime-pyside6/LogarithmPlotter/i18n/ + +box "Building icons..." +cp -r assets/icons build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ +cp assets/logarithmplotter.svg build/runtime-pyside6/LogarithmPlotter/ diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh new file mode 100755 index 0000000..477ecda --- /dev/null +++ b/scripts/package-deb.sh @@ -0,0 +1,11 @@ +#!/bin/bash +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." + +rm -rf build +bash scripts/build.sh +cd build || exit 1 + +# Deb +sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ + --package logarithmplotter --copyright-file linux/debian/copyright --suite noble --depends3 "$(cat linux/debian/depends)" --section science \ + bdist_deb diff --git a/scripts/package-linux.sh b/scripts/package-linux.sh deleted file mode 100755 index ca2bcf7..0000000 --- a/scripts/package-linux.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." - -# Building translations -cd "LogarithmPlotter/i18n/" -bash release.sh -cd ../../ - -# Deb -sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ - --package logarithmplotter --copyright-file linux/debian/copyright --suite noble --depends3 "$(cat linux/debian/depends)" --section science \ - bdist_deb - -# Flatpak building -FLATPAK_BUILDER=$(which flatpak-builder) -if [ -z $FLATPAK_BUILDER ]; then - echo "flatpak-builder not installed. Will not proceed to build flatpak." -else - cd linux - git clone https://github.com/Ad5001/eu.ad5001.LogarithmPlotter - cd eu.ad5001.LogarithmPlotter - flatpak-builder AppDir eu.ad5001.LogarithmPlotter.json --user --force-clean --install - cd ../../ -fi - -# Snapcraft building -SNAPCRAFT=$(which snapcraft) -if [ -z $SNAPCRAFT ]; then - echo "snapcraft not installed. Will not proceed to build snap" -else - snapcraft -fi diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index 745f05b..cf312a4 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -8,14 +8,14 @@ applicationName=LogarithmPlotter backgroundPictureName=logarithmplotter-installer-background.png source=Installer -cd dist +cd build/dist rm -rf Installer mkdir -p Installer mkdir -p Installer/.background -cp ../mac/install-bg.png "./Installer/.background/${backgroundPictureName}" +cp ../../assets/native/mac/install-bg.png "./Installer/.background/${backgroundPictureName}" cp -r LogarithmPlotter.app Installer/LogarithmPlotter.app -cp ../LICENSE.md Installer/LICENSE.md -cp ../README.md Installer/README.md +cp ../../LICENSE.md Installer/LICENSE.md +cp ../../README.md Installer/README.md # Calculating folder size duoutput=$(du -h Installer | tail -n1) diff --git a/scripts/package-windows.bat b/scripts/package-windows.bat deleted file mode 100644 index 777f2f9..0000000 --- a/scripts/package-windows.bat +++ /dev/null @@ -1,7 +0,0 @@ -XCOPY win\*.* dist\logarithmplotter /C /S /D /Y /I -XCOPY README.md dist\logarithmplotter /C /D /Y -XCOPY LICENSE.md dist\logarithmplotter /C /D /Y -rem Creating installer -cd dist\logarithmplotter -"C:\Program Files (x86)\NSIS\makensis" installer.nsi -cd ..\.. diff --git a/scripts/package-wine.sh b/scripts/package-wine.sh index 98209e0..2b6391c 100644 --- a/scripts/package-wine.sh +++ b/scripts/package-wine.sh @@ -1,8 +1,8 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 # Moving files -cp win/* README.md LICENSE.md dist/logarithmplotter/ +cp assets/native/win/* README.md LICENSE.md build/dist/logarithmplotter/ # Creating installer -cd dist/logarithmplotter/ +cd build/dist/logarithmplotter/ makensis installer.nsi diff --git a/snapcraft.yaml b/snapcraft.yaml index e8c8628..2811b21 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -5,7 +5,7 @@ summary: Create and edit Bode plots confinement: strict base: core22 grade: stable -icon: LogarithmPlotter/logarithmplotter.svg +icon: assets/logarithmplotter.svg adopt-info: linuxfiles license: GPL-3.0+ @@ -57,21 +57,26 @@ parts: # - fcitx-frontend-gtk3 # - libgtk2.0-0 launchers: - source: linux/snapcraft/launcher/ + source: assets/native/linux/snapcraft/launcher/ plugin: dump organize: '*': bin/ linuxfiles: - source: linux/ + source: assets/native/linux/ plugin: dump parse-info: [eu.ad5001.LogarithmPlotter.metainfo.xml] organize: logarithmplotter.desktop: usr/share/applications/logarithmplotter.desktop x-logarithm-plot.xml: usr/share/mime/packages/x-logarithm-plot.xml application-x-logarithm-plot.svg: usr/share/mime/packages/application-x-logarithm-plot.svg + linuxfiles: + source: assets/ + plugin: dump + organize: + logplotterfile.svg: usr/share/mime/packages/application-x-logarithm-plot.svg logarithmplotter: plugin: python - source: . + source: build stage-packages: - breeze-icon-theme # Latex dependencies @@ -145,7 +150,7 @@ parts: source: . plugin: dump organize: - CHANGELOG.md: lib/python3.8/site-packages/LogarithmPlotter/util/ + CHANGELOG.md: lib/python3.12/site-packages/LogarithmPlotter/util/ apps: logarithmplotter: From ca5c7492dcf8507e7aa4e7d1db14149debbc6afd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 00:54:30 +0200 Subject: [PATCH 154/249] Fixing deb building --- .../linux/application-x-logarithm-plot.svg | 1 + assets/native/linux/debian/control | 4 +- assets/native/linux/debian/depends | 2 +- assets/native/linux/logarithmplotter.desktop | 2 +- runtime-pyside6/poetry.lock | 38 +++++++-------- runtime-pyside6/pyproject.toml | 1 + runtime-pyside6/setup.py | 48 +++++++++---------- scripts/package-deb.sh | 14 ++++-- scripts/sign-deb.sh | 3 +- 9 files changed, 59 insertions(+), 54 deletions(-) create mode 120000 assets/native/linux/application-x-logarithm-plot.svg diff --git a/assets/native/linux/application-x-logarithm-plot.svg b/assets/native/linux/application-x-logarithm-plot.svg new file mode 120000 index 0000000..4e7d218 --- /dev/null +++ b/assets/native/linux/application-x-logarithm-plot.svg @@ -0,0 +1 @@ +../../logplotterfile.svg \ No newline at end of file diff --git a/assets/native/linux/debian/control b/assets/native/linux/debian/control index 57281bc..a1089e7 100644 --- a/assets/native/linux/debian/control +++ b/assets/native/linux/debian/control @@ -3,9 +3,9 @@ Source: logarithmplotter Version: 0.6.0 Architecture: all Maintainer: Ad5001 -Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng +Depends: python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng -Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.9) +Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools Section: science Priority: optional Homepage: https://apps.ad5001.eu/logarithmplotter/ diff --git a/assets/native/linux/debian/depends b/assets/native/linux/debian/depends index 5eea4fd..5b7d902 100644 --- a/assets/native/linux/debian/depends +++ b/assets/native/linux/debian/depends @@ -1 +1 @@ -python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng +python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng diff --git a/assets/native/linux/logarithmplotter.desktop b/assets/native/linux/logarithmplotter.desktop index 00c871f..70637c5 100644 --- a/assets/native/linux/logarithmplotter.desktop +++ b/assets/native/linux/logarithmplotter.desktop @@ -14,7 +14,7 @@ Comment[hu]=Bode-ábrák, sorozatok és újraosztási függvények létrehozása TryExec=logarithmplotter Exec=logarithmplotter %f -Icon=logplotter +Icon=logarithmplotter MimeType=application/x-logarithm-plot; Terminal=false StartupNotify=false diff --git a/runtime-pyside6/poetry.lock b/runtime-pyside6/poetry.lock index c94f9e7..2979b69 100644 --- a/runtime-pyside6/poetry.lock +++ b/runtime-pyside6/poetry.lock @@ -261,36 +261,36 @@ setuptools = ">=42.0.0" [[package]] name = "pyside6-addons" -version = "6.7.2" +version = "6.7.3" description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Addons-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:90b995efce61058d995c603ea480a9a3054fe8206739dcbc273fc3b53d40650f"}, - {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:94b9bf6a2a4a7ac671e1776633e50d51326c86f4184f1c6e556f4dd5498fd52a"}, - {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:22979b1aa09d9cf1d7a86c8a9aa0cb4791d6bd1cc94f96c5b6780c5ef8a9e34e"}, - {file = "PySide6_Addons-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:ebf549eb25998665d8e4ec24014fbbd37bebc5ecdcb050b34db1e1c03e1bf81d"}, + {file = "PySide6_Addons-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:3174cb3a373c09c98740b452e8e8f4945d64cfa18ed8d43964111d570f0dc647"}, + {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:bde1eb03dbffd089b50cd445847aaecaf4056cea84c49ea592d00f84f247251e"}, + {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:5a9e0df31345fe6caea677d916ea48b53ba86f95cc6499c57f89e392447ad6db"}, + {file = "PySide6_Addons-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:d8a19c2b2446407724c81c33ebf3217eaabd092f0f72da8130c17079e04a7813"}, ] [package.dependencies] -PySide6-Essentials = "6.7.2" -shiboken6 = "6.7.2" +PySide6-Essentials = "6.7.3" +shiboken6 = "6.7.3" [[package]] name = "pyside6-essentials" -version = "6.7.2" +version = "6.7.3" description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Essentials-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d13666e796ec140ecfb432c4f3d7baef6dfafc11929985a83b22c0025532fb7"}, - {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a1a4c09f1e916b9cfe53151fe4a503a6acb1f6621ba28204d1bfe636f80d6780"}, - {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:9135513e1c4c6e2fbb1e4f9afcb3d42e54708b0d9ed870cb3213ea4874cafa1e"}, - {file = "PySide6_Essentials-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:0111d5fa8cf826de3ca9d82fed54726cce116d57f454f88a6467578652032d69"}, + {file = "PySide6_Essentials-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:f9e08a4e9e7dc7b5ab72fde20abce8c97df7af1b802d9743f098f577dfe1f649"}, + {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cda6fd26aead48f32e57f044d18aa75dc39265b49d7957f515ce7ac3989e7029"}, + {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:acdde06b74f26e7d26b4ae1461081b32a6cb17fcaa2a580050b5e0f0f12236c9"}, + {file = "PySide6_Essentials-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:f0950fcdcbcd4f2443336dc6a5fe692172adc225f876839583503ded0ab2f2a7"}, ] [package.dependencies] -shiboken6 = "6.7.2" +shiboken6 = "6.7.3" [[package]] name = "pytest" @@ -384,15 +384,15 @@ type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11 [[package]] name = "shiboken6" -version = "6.7.2" +version = "6.7.3" description = "Python/C++ bindings helper module" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "shiboken6-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:50c33ac6317b673a1eb97a9abaafccb162c4ba0c9ca658a8e449c49a8aadc379"}, - {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:70e80737b27cd5d83504b373013b55e70462bd4a27217d919ff9a83958731990"}, - {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:98bedf9a15f1d8ba1af3e4d1e7527f7946ce36da541e08074fd9dc9ab5ff1adf"}, - {file = "shiboken6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:9024e6afb2af1568ebfc8a5d07e4ff6c8829f40923eeb28901f535463e2b6b65"}, + {file = "shiboken6-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:285fe3cf79be3135fe1ad1e2b9ff6db3a48698887425af6aa6ed7a05a9abc3d6"}, + {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f0852e5781de78be5b13c140ec4c7fb9734e2aaf2986eb2d6a224363e03efccc"}, + {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:f0dd635178e64a45be2f84c9f33dd79ac30328da87f834f21a0baf69ae210e6e"}, + {file = "shiboken6-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:5f29325dfa86fde0274240f1f38e421303749d3174ce3ada178715b5f4719db9"}, ] [[package]] @@ -449,4 +449,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "30da53f0a05c06c5f93aa1260217d807ce2ab64debd26f313b47c664931e67c7" +content-hash = "867f6da20f7e5b66e5d6cf927b56b335e81ff15f53d4ee0fc3c68ab1603de7af" diff --git a/runtime-pyside6/pyproject.toml b/runtime-pyside6/pyproject.toml index 7b5b6f6..94af012 100644 --- a/runtime-pyside6/pyproject.toml +++ b/runtime-pyside6/pyproject.toml @@ -15,6 +15,7 @@ pyside6-addons = "^6.7.2" [tool.poetry.group.packaging.dependencies] pyinstaller = "^6.10.0" stdeb = "^0.10.0" +setuptools = "^75.1.0" [tool.poetry.group.test.dependencies] pytest = "^8.3.3" diff --git a/runtime-pyside6/setup.py b/runtime-pyside6/setup.py index 5d1aae7..e2bbd57 100644 --- a/runtime-pyside6/setup.py +++ b/runtime-pyside6/setup.py @@ -96,30 +96,30 @@ def package_data(): data_files = [] if sys.platform == 'linux': - data_files.append(('share/applications/', ['linux/logarithmplotter.desktop'])) - data_files.append(('share/mime/packages/', ['linux/x-logarithm-plot.xml'])) - data_files.append(('share/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) - data_files.append(('share/icons/hicolor/scalable/apps/', ['logplotter.svg'])) - data_files.append((os.environ["PREFIX"] + '/applications/', ['linux/logarithmplotter.desktop'])) - data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml'])) - data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) - data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) - if len(sys.argv) > 1: - if sys.argv[1] == "install": - os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True) - os.makedirs(os.environ["PREFIX"] + '/mime/packages/', exist_ok=True) - os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', exist_ok=True) - os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', exist_ok=True) - os.makedirs(os.environ["PREFIX"] + '/metainfo/', exist_ok=True) - copyfile(current_dir + '/linux/x-logarithm-plot.xml', os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') - copyfile(current_dir + '/linux/application-x-logarithm-plot.svg', - os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') - copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') - elif sys.argv[1] == "uninstall": - os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') - os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') - os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') - os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') + data_files.append(('share/applications/', ['assets/native/linux/logarithmplotter.desktop'])) + data_files.append(('share/mime/packages/', ['assets/native/linux/x-logarithm-plot.xml'])) + data_files.append(('share/icons/hicolor/scalable/mimetypes/', ['assets/native/linux/application-x-logarithm-plot.svg'])) + data_files.append(('share/icons/hicolor/scalable/apps/', ['assets/logarithmplotter.svg'])) + # data_files.append((os.environ["PREFIX"] + '/applications/', ['linux/logarithmplotter.desktop'])) + # data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml'])) + # data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) + # data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) + # if len(sys.argv) > 1: + # if sys.argv[1] == "install": + # os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True) + # os.makedirs(os.environ["PREFIX"] + '/mime/packages/', exist_ok=True) + # os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', exist_ok=True) + # os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', exist_ok=True) + # os.makedirs(os.environ["PREFIX"] + '/metainfo/', exist_ok=True) + # copyfile(current_dir + '/linux/x-logarithm-plot.xml', os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') + # copyfile(current_dir + '/linux/application-x-logarithm-plot.svg', + # os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') + # copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') + # elif sys.argv[1] == "uninstall": + # os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') + # os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') + # os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') + # os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') setuptools.setup( install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials"]), diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh index 477ecda..b280675 100755 --- a/scripts/package-deb.sh +++ b/scripts/package-deb.sh @@ -1,11 +1,15 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 rm -rf build bash scripts/build.sh -cd build || exit 1 +cd build/runtime-pyside6 || exit 1 -# Deb -sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ - --package logarithmplotter --copyright-file linux/debian/copyright --suite noble --depends3 "$(cat linux/debian/depends)" --section science \ +mkdir assets +cp -r ../../assets/{native,*.svg} assets/ +cp ../../README.md . + +python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ + --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \ + --suite noble --depends3 "$(cat assets/native/linux/debian/depends)" --section science \ bdist_deb diff --git a/scripts/sign-deb.sh b/scripts/sign-deb.sh index 6939243..f8e0a9a 100755 --- a/scripts/sign-deb.sh +++ b/scripts/sign-deb.sh @@ -1,11 +1,10 @@ #!/bin/bash # This script is used to sign the LogarithmPlotter deb directly from it's DSC file. # Adapted from https://github.com/astraw/stdeb/issues/181 +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/deb_dist" || exit 1 PPA_ARCHIVE="ppa:ad5001/logarithmplotter" -cd ../deb_dist - # create a temporary folder mkdir tmp -p cd tmp From e2841c012984dec48c1552f44ef612883c17dfc8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 01:27:30 +0200 Subject: [PATCH 155/249] Updating remaining paths in scripts --- README.md | 30 +++++++++++++----------------- runtime-pyside6/poetry.lock | 2 +- runtime-pyside6/pyproject.toml | 4 ++-- scripts/build-macosx.sh | 6 +++--- scripts/build-wine.sh | 6 +++--- scripts/package-macosx.sh | 9 ++++----- scripts/package-wine.sh | 4 ++-- scripts/run-tests.sh | 4 ++++ snapcraft.yaml | 2 +- 9 files changed, 33 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 8402402..4a44ced 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,15 @@ You can find more screenshots on the [app's website](https://apps.ad5001.eu/loga First, you'll need to install all the required dependencies: -- [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and setup a virtual environment and call +- [Python 3](https://python.org) with [poetry](https://python-poetry.org/), setup a virtual environment, go to the `runtime-pyside6` directory, and call `poetry install`. -- [npm](https://npmjs.com) (or [yarn](https://yarnpkg.com/)), and run `npm install` (or `yarn install`). +- [npm](https://npmjs.com) (or [yarn](https://yarnpkg.com/)), go to the `common` directory, and run `npm install` (or `yarn install`). You can simply run LogarithmPlotter using `python3 run.py`. It automatically compiles the language files (requires `lrelease` to be installed and in path), and the JavaScript modules. -If you do not wish do recompile the files again on every run, you can use -`python3 LogarithmPlotter/logarithmplotter.py`. +If you do not wish do recompile the files again on every run, you can use the build script (`scripts/build.sh`) and run +`python3 build/runtime-pyside6/LogarithmPlotter/logarithmplotter.py`. In order to test translations, you can use the `--lang=` commandline option to force the locale. @@ -39,22 +39,18 @@ All scripts noted here can be found in the `scripts` directory. You can generate installers for LogarithmPlotter after installing all the dependencies. -- Windows installer: - - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an - exe for LogarithmPlotter. - - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (Linux users can install - the [nsis](https://pkgs.org/download/nsis) package). - - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a - logarithmplotter-setup.exe installer in the dist/logarithmplotter/ folder. +- Windows installer (crosscompiling from Linux): + - Run `build-wine.sh` (requires wine) to build an exe for LogarithmPlotter in build/runtime-pyside6/dist. + - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (the [nsis](https://pkgs.org/download/nsis) package is available on linux). + - Run the `package-wine.sh` script. You will find a logarithmplotter-setup.exe installer in the build/runtime-pyside6/dist/logarithmplotter/ folder. - MacOS Archive creator installer: - - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the dist directory. + - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the build/runtime-pyside6/dist directory. - Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v<version>-setup.dmg installer in the - dist/ folder. + build/runtime-pyside6/build/pysdist/ folder. - Linux packages: - - To build and install the flatpak, you - need [flatpak-builder](https://docs.flatpak.org/en/latest/flatpak-builder.html) installed. - - To build the snap, you need [snapcraft](https://snapcraft.io) installed. - - Run `package-linux.sh`. + - Run `package-deb.sh`. It will create an DSC and a DEB in build/runtime-pyside6/deb_dist/ + - Run `scripts/build.sh` followed by `snapcraft`. It .snap file in the root directory. + - See [the flatpak repo](https://github.com/Ad5001/eu.ad5001.LogarithmPlotter) for instrutions on how to build the flatpak. ## Contribute diff --git a/runtime-pyside6/poetry.lock b/runtime-pyside6/poetry.lock index 2979b69..a4727e1 100644 --- a/runtime-pyside6/poetry.lock +++ b/runtime-pyside6/poetry.lock @@ -449,4 +449,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "867f6da20f7e5b66e5d6cf927b56b335e81ff15f53d4ee0fc3c68ab1603de7af" +content-hash = "5636605737f21954e102a0110972e6bd3df07f2d5929f41fe541c7347c3ecf08" diff --git a/runtime-pyside6/pyproject.toml b/runtime-pyside6/pyproject.toml index 94af012..5293365 100644 --- a/runtime-pyside6/pyproject.toml +++ b/runtime-pyside6/pyproject.toml @@ -9,8 +9,8 @@ package-mode = false [tool.poetry.dependencies] python = ">=3.9,<3.13" -PySide6-Essentials = "^6.7.2" -pyside6-addons = "^6.7.2" +PySide6-Essentials = "^6.7" +PySide6-Addons = "^6.7" [tool.poetry.group.packaging.dependencies] pyinstaller = "^6.10.0" diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index c398735..c76b5ec 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -4,7 +4,7 @@ cd "$DIR/.." || exit 1 rm -rf build bash scripts/build.sh -cd build || exit 1 +cd build/runtime-pyside6 || exit 1 rm $(find . -name "*.pyc") @@ -21,12 +21,12 @@ pyinstaller --add-data "LogarithmPlotter/qml:qml" \ --exclude-module "Tkinter" \ --noconsole \ --noconfirm \ - --icon=../assets/native/mac/logarithmplotter.icns \ + --icon=../../assets/native/mac/logarithmplotter.icns \ --osx-bundle-identifier eu.ad5001.LogarithmPlotter \ -n LogarithmPlotter \ LogarithmPlotter/logarithmplotter.py -cp ../assets/native/mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist +cp ../../assets/native/mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist # Remove QtWebEngine, 3D and all other unused libs libs rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index c99d1e1..bf8a7ff 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -3,16 +3,16 @@ cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit rm -rf build bash scripts/build.sh -cd build || exit 1 +cd build/runtime-pyside6 || exit 1 rm -rf $(find . -name "*.pyc") -wine pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ +wine_py pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ --add-data "LogarithmPlotter/qml;qml" \ --add-data "LogarithmPlotter/i18n;i18n" \ --noconsole \ LogarithmPlotter/logarithmplotter.py \ - --icon=../assets/native/win/logarithmplotter.ico \ + --icon=../../assets/native/win/logarithmplotter.ico \ -n logarithmplotter # Copy Qt6ShaderTools, a required library for for Qt5Compat diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index cf312a4..d38ecdc 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/dist" || exit 1 VERSION=0.6.0 title="LogarithmPlotter v${VERSION} Setup" @@ -8,14 +8,13 @@ applicationName=LogarithmPlotter backgroundPictureName=logarithmplotter-installer-background.png source=Installer -cd build/dist rm -rf Installer mkdir -p Installer mkdir -p Installer/.background -cp ../../assets/native/mac/install-bg.png "./Installer/.background/${backgroundPictureName}" +cp ../../../assets/native/mac/install-bg.png "./Installer/.background/${backgroundPictureName}" cp -r LogarithmPlotter.app Installer/LogarithmPlotter.app -cp ../../LICENSE.md Installer/LICENSE.md -cp ../../README.md Installer/README.md +cp ../../../LICENSE.md Installer/LICENSE.md +cp ../../../README.md Installer/README.md # Calculating folder size duoutput=$(du -h Installer | tail -n1) diff --git a/scripts/package-wine.sh b/scripts/package-wine.sh index 2b6391c..89295e7 100644 --- a/scripts/package-wine.sh +++ b/scripts/package-wine.sh @@ -2,7 +2,7 @@ cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 # Moving files -cp assets/native/win/* README.md LICENSE.md build/dist/logarithmplotter/ +cp assets/native/win/* README.md LICENSE.md build/runtime-pyside6/dist/logarithmplotter/ # Creating installer -cd build/dist/logarithmplotter/ +cd build/runtime-pyside6/dist/logarithmplotter/ || exit 1 makensis installer.nsi diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 257d748..ac612f4 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,7 +1,11 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +rm -rf build +bash scripts/build.sh + # Run python tests +cp -r runtime-pyside6/tests build/runtime-pyside6 PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . npm test diff --git a/snapcraft.yaml b/snapcraft.yaml index 2811b21..12b41d2 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -69,7 +69,7 @@ parts: logarithmplotter.desktop: usr/share/applications/logarithmplotter.desktop x-logarithm-plot.xml: usr/share/mime/packages/x-logarithm-plot.xml application-x-logarithm-plot.svg: usr/share/mime/packages/application-x-logarithm-plot.svg - linuxfiles: + filetypeicon: source: assets/ plugin: dump organize: From 1c7e9d627decbc784502ddd8229c031e02359992 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 01:35:24 +0200 Subject: [PATCH 156/249] Updating tests --- common/.mocharc.jsonc | 4 ++-- common/test/hooks.mjs | 4 ++-- common/test/math/domain.mjs | 2 +- scripts/run-tests.sh | 6 ++++++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common/.mocharc.jsonc b/common/.mocharc.jsonc index 5fa553a..56a6b31 100644 --- a/common/.mocharc.jsonc +++ b/common/.mocharc.jsonc @@ -20,6 +20,6 @@ "recursive": true, "require": [ "esm", - "./tests/js/hooks.mjs" + "./test/hooks.mjs" ] -} \ No newline at end of file +} diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index 8c3e929..e48525e 100644 --- a/common/test/hooks.mjs +++ b/common/test/hooks.mjs @@ -19,7 +19,7 @@ import * as fs from "./mock/fs.mjs"; import Qt from "./mock/qt.mjs"; import { MockHelper } from "./mock/helper.mjs"; import { MockLatex } from "./mock/latex.mjs"; -import Modules from "../../LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/index.mjs"; +import Modules from "../src/module/index.mjs"; function setup() { globalThis.Helper = new MockHelper() @@ -27,4 +27,4 @@ function setup() { Modules.Latex.initialize({ latex: Latex, helper: Helper }) } -setup() \ No newline at end of file +setup() diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs index 6c185d4..c00384f 100644 --- a/common/test/math/domain.mjs +++ b/common/test/math/domain.mjs @@ -19,7 +19,7 @@ import { describe, it } from "mocha" import { expect } from "chai" -import { Domain, parseDomainSimple } from "../../../LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs" +import { Domain, parseDomainSimple } from "../../src/math/domain.mjs" describe("math.domain", function() { describe("#parseDomainSimple", function() { diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index ac612f4..21b1f41 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -6,6 +6,12 @@ bash scripts/build.sh # Run python tests cp -r runtime-pyside6/tests build/runtime-pyside6 +cp -r ci CHANGELOG.md build/runtime-pyside6 +cd build/runtime-pyside6 || exit 1 PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . +cd ../../ + +# Run js tests +cd common npm test From cd6f25872028be5f22380c467e6ba3a1793d16b3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 01:39:59 +0200 Subject: [PATCH 157/249] Fixing CI --- ci/drone.yml | 4 ++-- scripts/build-wine.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 2800cb6..b04d9df 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,7 +14,7 @@ steps: - name: Build image: node:18-bookworm commands: - - npm install + - cd common && npm install && cd .. - apt update - apt install -y qtchooser qttools5-dev-tools # Start building @@ -27,7 +27,7 @@ steps: commands: - apt update - apt install -y npm - - npm install -D + - cd common && npm install -D && cd .. - xvfb-run bash scripts/run-tests.sh when: event: [ push, tag ] diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index bf8a7ff..1b4e9cb 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -7,7 +7,7 @@ cd build/runtime-pyside6 || exit 1 rm -rf $(find . -name "*.pyc") -wine_py pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ +wine pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \ --add-data "LogarithmPlotter/qml;qml" \ --add-data "LogarithmPlotter/i18n;i18n" \ --noconsole \ From 07e556da56860dd69cb70070b4afe47a6b9e4c14 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 30 Sep 2024 01:45:02 +0200 Subject: [PATCH 158/249] Removing building when testing current build. --- run.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run.py b/run.py index 2fae168..0c2bda7 100644 --- a/run.py +++ b/run.py @@ -16,7 +16,7 @@ * along with this program. If not, see . """ from os import system, getcwd, path -from sys import path as sys_path +from sys import path as sys_path, argv def build(): """ @@ -29,7 +29,8 @@ def run(): logarithmplotter.run() if __name__ == "__main__": - build() + if '--test-build' not in argv: + build() logplotter_path = path.realpath(path.join(getcwd(), "build", "runtime-pyside6")) print("Appending " + logplotter_path + " to path...") sys_path.append(logplotter_path) From 7ef55e48e827808b210c53917c0f73469898c6b3 Mon Sep 17 00:00:00 2001 From: ovari Date: Tue, 1 Oct 2024 00:54:21 +0000 Subject: [PATCH 159/249] Translated using Weblate (Hungarian) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 313d8de..e03702f 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -39,7 +39,7 @@ &Load... - &Betöltés… + &Megnyitás… @@ -79,7 +79,7 @@ &Preferences - + &Beállítások @@ -394,7 +394,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Preferences - + Beállítások @@ -606,7 +606,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Close - + Bezárás @@ -707,17 +707,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Save plot - Ábra mentése + Ábra mentése… Save plot as - Ábra mentése másként + Ábra mentése másként… Load plot - Ábra betöltése + Ábra megnyitása… Close @@ -808,7 +808,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Spanish - + spanyol @@ -1055,7 +1055,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Parse error [position %1]: %2 - + Elemzési hiba [hely %1]: %2 @@ -1386,7 +1386,11 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents - {} (https://ctan.org/pkg/{}) Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + A LaTeX telepítése nem tartalmaz néhány szükséges csomagot: + +- {} (https://ctan.org/pkg/{}) + +Győződjön meg arról, hogy az említett csomag telepítve van, vagy tiltsa le a LaTeX megjelenítést a LogarithmPlotterben. @@ -1692,7 +1696,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents approximate - Hozzávetőleges érték megjelenítése + Kerekített számított érték megjelenítése @@ -1753,7 +1757,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents general - + Általános @@ -1821,7 +1825,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents integral(<from: number>, <to: number>, <f: ExecutableObject>) - integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) + integral(<alsó korlát: szám>, <felső korlát: szám>, <f: függvényszerű objektum>) @@ -1850,7 +1854,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents derivative(<f: ExecutableObject>, <x: number>) - derivative(<függvény: VégrehajthatóObjektum>, <x: szám>) + derivative(<f: függvényszerű objektum>, <x: szám>) From 1fc19f6ba3599708649d9dc4b0b5ca5064d4ae6d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 1 Oct 2024 21:50:10 +0200 Subject: [PATCH 160/249] Adding rebuild to scripts --- ci/drone.yml | 4 ++-- run.py | 2 +- scripts/build-macosx.sh | 23 ++++++++++++++++++++--- scripts/build-wine.sh | 21 +++++++++++++++++++-- scripts/package-deb.sh | 21 +++++++++++++++++++-- scripts/package-macosx.sh | 8 ++++---- scripts/run-tests.sh | 26 ++++++++++++++++++++++---- 7 files changed, 87 insertions(+), 18 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index b04d9df..da7d1c7 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -28,7 +28,7 @@ steps: - apt update - apt install -y npm - cd common && npm install -D && cd .. - - xvfb-run bash scripts/run-tests.sh + - xvfb-run bash scripts/run-tests.sh --no-rebuild when: event: [ push, tag ] @@ -44,7 +44,7 @@ steps: - name: Windows build image: ad5001/ubuntu-pyside-xvfb:wine-6-latest commands: - - bash scripts/build-wine.sh + - bash scripts/build-wine.sh --no-rebuild - bash scripts/package-wine.sh when: event: [ push, tag ] diff --git a/run.py b/run.py index 0c2bda7..783e23b 100644 --- a/run.py +++ b/run.py @@ -32,7 +32,7 @@ if __name__ == "__main__": if '--test-build' not in argv: build() logplotter_path = path.realpath(path.join(getcwd(), "build", "runtime-pyside6")) - print("Appending " + logplotter_path + " to path...") + print(f"Appending {logplotter_path} to path...") sys_path.append(logplotter_path) run() diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index c76b5ec..2ccd626 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -2,8 +2,25 @@ DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$DIR/.." || exit 1 -rm -rf build -bash scripts/build.sh +rebuild=true + +while [ $# -gt 0 ]; do + case "$1" in + --no-rebuild) + rebuild=false + ;; + *) + box "Error: Invalid argument." + exit 1 + esac + shift +done + +if [ "$rebuild" == "true" ]; then + rm -rf build + bash scripts/build.sh +fi + cd build/runtime-pyside6 || exit 1 rm $(find . -name "*.pyc") @@ -30,7 +47,7 @@ cp ../../assets/native/mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.pl # Remove QtWebEngine, 3D and all other unused libs libs rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/{QtNetwork.abi3.so} +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/QtNetwork.abi3.so # Removing QtQuick3D rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/{QtQuick3D,Qt3D,QtWebEngine} diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 1b4e9cb..fa78bb1 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -1,8 +1,25 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit -rm -rf build -bash scripts/build.sh +rebuild=true + +while [ $# -gt 0 ]; do + case "$1" in + --no-rebuild) + rebuild=false + ;; + *) + box "Error: Invalid argument." + exit 1 + esac + shift +done + +if [ "$rebuild" == "true" ]; then + rm -rf build + bash scripts/build.sh +fi + cd build/runtime-pyside6 || exit 1 rm -rf $(find . -name "*.pyc") diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh index b280675..8ed03ee 100755 --- a/scripts/package-deb.sh +++ b/scripts/package-deb.sh @@ -1,8 +1,25 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 -rm -rf build -bash scripts/build.sh +rebuild=true + +while [ $# -gt 0 ]; do + case "$1" in + --no-rebuild) + rebuild=false + ;; + *) + box "Error: Invalid argument." + exit 1 + esac + shift +done + +if [ "$rebuild" == "true" ]; then + rm -rf build + bash scripts/build.sh +fi + cd build/runtime-pyside6 || exit 1 mkdir assets diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index d38ecdc..c050a32 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -18,7 +18,7 @@ cp ../../../README.md Installer/README.md # Calculating folder size duoutput=$(du -h Installer | tail -n1) -size=$(expr ${duoutput%M*} + 2) # +2 for allowing small space to edit. +size=$(( ${duoutput%M*} + 2)) # +2 for allowing small space to edit. echo "Creating DMG file with size ${size}M." # Adapted from https://stackoverflow.com/a/1513578 @@ -26,7 +26,7 @@ hdiutil create -srcfolder "${source}" -volname "${title}" -fs HFS+ \ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}M pack.temp.dmg device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \ - egrep '^/dev/' | sed 1q | awk '{print $1}') + grep -E '^/dev/' | sed 1q | awk '{print $1}') sleep 3 @@ -53,10 +53,10 @@ echo ' end tell end tell ' | osascript -chmod -Rf go-w /Volumes/"${title}" +chmod -Rf go-w "/Volumes/${title}" sync sync -hdiutil detach ${device} +hdiutil detach "${device}" hdiutil convert "pack.temp.dmg" -format UDZO -imagekey zlib-level=9 -o "${finalDMGName}" rm -f pack.temp.dmg rm -rf Installer diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 21b1f41..1410244 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,8 +1,26 @@ #!/bin/bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 + +rebuild=true + +while [ $# -gt 0 ]; do + case "$1" in + --no-rebuild) + rebuild=false + ;; + *) + box "Error: Invalid argument." + exit 1 + esac + shift +done + +if [ "$rebuild" == "true" ]; then + rm -rf build + bash scripts/build.sh +fi + -rm -rf build -bash scripts/build.sh # Run python tests cp -r runtime-pyside6/tests build/runtime-pyside6 @@ -12,6 +30,6 @@ PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missi cd ../../ # Run js tests -cd common +cd common || exit 1 npm test From a60ac79d83d9a91bee9f76c4df7105020de8ff42 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 9 Oct 2024 20:15:27 +0200 Subject: [PATCH 161/249] Updating translations to new folder structure. --- assets/i18n/lp_de.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_en.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_es.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_fr.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_hu.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_nb_NO.ts | 676 +++++++++++++++++++------------------ assets/i18n/lp_template.ts | 670 ++++++++++++++++++------------------ assets/i18n/update.sh | 4 +- 8 files changed, 2377 insertions(+), 2353 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 761283f..4f29919 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter Über LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D-Grafiksoftware zur Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen. - + Report a bug Bug melden - + Official website Offizielle Website @@ -32,57 +32,57 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Preferences &Einstellung - + &Create &Erstellen @@ -123,52 +123,52 @@ Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -176,7 +176,7 @@ BaseDialog - + Close Schließen @@ -191,12 +191,12 @@ Changelog - + Fetching changelog... Changelog abrufen… - + Close Schließen @@ -204,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -218,42 +218,42 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -292,32 +292,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktionen - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -325,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Logarithmusgrafik exportieren - + Import Logarithm Plot file Logarithmusgrafik importieren @@ -338,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 @@ -382,22 +382,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + Preferences Einstellung - + Close Schließen @@ -405,22 +405,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" HistoryBrowser - + Filter... Filtern… - + Redo > Wiederherstellen > - + > Now > Aktueller Stand - + < Undo < Rückgängig @@ -428,7 +428,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ListSetting - + + Add Entry + Neuer Eintrag @@ -436,17 +436,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - + Objects Objekte - + Settings Einstellungen - + History Verlauf @@ -475,17 +475,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -493,7 +493,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectCreationGrid - + + Create new: + Neu erstellen: @@ -501,12 +501,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectLists - + Hide all %1 Alle %1 ausblenden - + Show all %1 Alle %1 anzeigen @@ -534,27 +534,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectRow - + Hide %1 %2 Ausblenden %1 %2 - + Show %1 %2 Anzeigen %1 %2 - + Set %1 %2 position Position von %1 %2 einstellen - + Delete %1 %2 %1 %2 löschen - + Pick new color for %1 %2 Neue Farbe für %1 %2 auswählen @@ -562,7 +562,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: @@ -571,32 +571,32 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Am Gitter einrasten - + Snap to grid: Am Raster einrasten: - + Pick X X nehmen - + Pick Y Y nehmen - + Open picker settings Zeigereinstellungen öffnen - + Hide picker settings Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -604,7 +604,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Preferences - + Close Schließen @@ -612,110 +612,110 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Settings - - + + X Zoom Zoom auf X - - + + Y Zoom Zoom auf Y - - + + Min X Minimum X - - + + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - - + + X Axis Step X-Achsen-Schritt - - + + Y Axis Step Y-Achsen-Schritt - - + + Line width Linienbreite - - + + Text size (px) Textgröße (px) - - + + X Label Etikett der X-Achse - - + + Y Label Etikett der Y-Achse - - + + X Log scale Logarithmische Skala in X - - + + Show X graduation X-Teilung anzeigen - - + + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern… - + Save plot as Grafik speichern unter… - + Load plot Grafik laden… @@ -727,96 +727,96 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ThanksTo - + Thanks and Contributions - LogarithmPlotter Danksagungen und Beiträge - LogarithmPlotter - + Source code Quellcode - + Original library by Raphael Graf Originalbibliothek von Raphael Graf - + Source Quelle - + Ported to Javascript by Matthew Crumley Portiert auf JavaScript von Matthew Crumley - - - + + + Website Website - + Ported to QMLJS by Ad5001 Portiert auf QMLJS von Ad5001 - + Libraries included Einschließlich Bibliotheken - + Email E-Mail - + English Englisch - + French Französisch - + German Deutsch - + Hungarian Ungarisch - - - + + + Github GitHub - + Norwegian Norwegisch - + Spanish Spanisch - + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -824,24 +824,24 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodemagnitude - + Bode Magnitude Bode-Magnitude - + Bode Magnitudes Bode-Magnituden - - + + low-pass Tiefpass - - + + high-pass Hochpass @@ -849,8 +849,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodemagnitudesum - - + + Bode Magnitudes Sum Bode-Magnituden Summe @@ -858,12 +858,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodephase - + Bode Phase Bode-Phase - + Bode Phases Bode-Phasen @@ -871,8 +871,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodephasesum - - + + Bode Phases Sum Bode-Phasen Summe @@ -880,12 +880,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -893,8 +893,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color - - + + %1 %2's color changed from %3 to %4. %1 %2 wurde von %3 bis %4 umgefärbt. @@ -902,27 +902,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - + Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -930,11 +930,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - - - - - + + + + + %1: %1: @@ -942,8 +942,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - - + + New %1 %2 created. Neu %1 %2 erstellt. @@ -951,8 +951,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete - - + + %1 %2 deleted. %1 %2 gelöscht. @@ -960,12 +960,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" distribution - + Repartition Verteilungsfunktion - + Repartition functions Verteilungsfunktionen @@ -973,12 +973,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -986,46 +986,46 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - - + + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. @@ -1034,12 +1034,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 @@ -1052,104 +1052,104 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Erwartete Variable für Zuweisung. - - + + Parse error [position %1]: %2 Analysefehler [Posten %1]: %2 - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1160,7 +1160,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1174,13 +1174,13 @@ Die letzte Änderung wurde rückgängig gemacht. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1191,27 +1191,27 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler - + Automatically close parenthesises and brackets Klammern automatisch schließen - + Enable syntax highlighting Syntaxhervorhebung einschalten - + Enable autocompletion Automatische Vervollständigung einschalten - + Color Scheme Syntaktische Färbung @@ -1219,12 +1219,12 @@ Ausdruck analysiert: %3 function - + Function Funktion - + Functions Funktionen @@ -1251,17 +1251,17 @@ Ausdruck analysiert: %3 general - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + Enable LaTeX rendering LaTeX-Rendering aktivieren @@ -1308,32 +1308,36 @@ Ausdruck analysiert: %3 Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - - Could not save file: - Die Datei konnte nicht gespeichert werden: + + Could not load file: + - + Could not save file: + Die Datei konnte nicht gespeichert werden: + + + Loaded file '%1'. Geladene Datei '%1'. @@ -1353,7 +1357,7 @@ Ausdruck analysiert: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1362,12 +1366,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1380,7 +1384,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1393,7 +1397,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Stellen Sie sicher, dass diese Pakete installiert sind, oder deaktivieren Sie das LaTeX-Rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1407,8 +1411,8 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde name - - + + %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -1416,114 +1420,114 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - + above ↑ Über - + below ↓ Unter - - + + left ← Links - - + + right → Rechts - + above-left ↖ Oben links - + above-right ↗ Oben rechts - + below-left ↙ Unten links - + below-right ↘ Unten rechts - + center >|< Zentrum - + top ↑ Über - + bottom ↓ Unter - + top-left ↖ Oben links - + top-right ↗ Oben rechts - + bottom-left ↙ Unten links - + bottom-right ↘ Unten rechts - + application Anwendung - + function Funktion - + high Hoch - + low Tief - + Next to target Neben dem Ziel - + With label Mit Etikett - + Hidden Versteckt @@ -1542,12 +1546,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde point - + Point Punkt - + Points Punkte @@ -1555,12 +1559,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde position - + Position of %1 %2 set from "%3" to "%4". %1 %2 wurde von "%3" nach "%4" verschoben. - + Position of %1 set from %2 to %3. %1 wurde von %2 nach %3 verschoben. @@ -1568,158 +1572,158 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde prop - + expression Ausdruck - + definitionDomain Definitionsbereich - + destinationDomain Reichweite - - - - - - - - - - + + + + + + + + + + labelPosition Position des Etiketts - + displayMode Anzeigemodus - - - - - - - + + + + + + + labelX X-Position des Etiketts - - + + drawPoints Unentschiedene Punkte - - + + drawDashedLines Gestrichelte Linien anzeigen - - + + om_0 ω₀ - + pass Pass - + gain Größenordnung - + omGraduation Teilung auf ω zeigen - + phase Phase - + unit Einheit - - - + + + x X - - + + y Y - + pointStyle Punkt-Stil - + probabilities Wahrscheinlichkeiten - + text Inhalt - + disableLatex LaTeX-Rendering für diesen Text deaktivieren - + targetElement Zielobjekt - + approximate Berechneten Wert gerundet anzeigen - + rounding Rundung - + displayStyle Stil - + targetValuePosition Wertposition des Ziels - + defaultExpression Standardausdruck - + baseValues Initialisierungswerte @@ -1742,12 +1746,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sequence - + Sequence Folge - + Sequences Folgen @@ -1755,17 +1759,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory - + default Standardeinstellungen - + general Allgemeine - + editor Ausdruckseditor @@ -1787,12 +1791,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde text - + Text Text - + Texts Texte @@ -1800,22 +1804,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde update - + An update for LogarithmPlotter (v{}) is available. Ein Update für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. @@ -1823,22 +1827,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: Funktionsähnliches Objekt>) - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 %2 @@ -1847,17 +1851,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: Funktionsähnliches Objekt>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) @@ -1865,14 +1869,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility - - + + %1 %2 shown. %1 %2 angezeigt. - - + + %1 %2 hidden. %1 %2 ausgeblendet. @@ -1880,12 +1884,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde xcursor - + X Cursor X Zeiger - + X Cursors X Zeiger diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index 92baeb1..4429a36 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter About LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D plotter software to make Bode plots, sequences and distribution functions. - + Report a bug Report a bug - + Official website Official website @@ -32,57 +32,57 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Preferences &Preferences - + &Create &Create @@ -123,52 +123,52 @@ Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -176,7 +176,7 @@ BaseDialog - + Close Close @@ -191,12 +191,12 @@ Changelog - + Fetching changelog... Fetching changelog… - + Close Close @@ -204,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -218,42 +218,42 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -292,32 +292,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -325,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Export Logarithm Plot file - + Import Logarithm Plot file Import Logarithm Plot file @@ -338,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 @@ -382,22 +382,22 @@ These settings can be changed at any time from the "Settings" menu.Color scheme: - + User manual User manual - + Changelog Changelog - + Preferences Preferences - + Close Close @@ -405,22 +405,22 @@ These settings can be changed at any time from the "Settings" menu. HistoryBrowser - + Filter... Filter… - + Redo > Redo > - + > Now > Now - + < Undo < Undo @@ -428,7 +428,7 @@ These settings can be changed at any time from the "Settings" menu. ListSetting - + + Add Entry + Add Entry @@ -436,17 +436,17 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects Objects - + Settings Settings - + History History @@ -475,17 +475,17 @@ These settings can be changed at any time from the "Settings" menu.Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -493,7 +493,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: + Create new: @@ -501,12 +501,12 @@ These settings can be changed at any time from the "Settings" menu. ObjectLists - + Hide all %1 Hide all %1 - + Show all %1 Show all %1 @@ -534,27 +534,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 Hide %1 %2 - + Show %1 %2 Show %1 %2 - + Set %1 %2 position Set %1 %2 position - + Delete %1 %2 Delete %1 %2 - + Pick new color for %1 %2 Pick new color for %1 %2 @@ -562,7 +562,7 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: @@ -571,32 +571,32 @@ These settings can be changed at any time from the "Settings" menu.Snap to grid - + Snap to grid: Snap to grid: - + Pick X Pick X - + Pick Y Pick Y - + Open picker settings Open picker settings - + Hide picker settings Hide picker settings - + (no pick selected) (no pick selected) @@ -604,7 +604,7 @@ These settings can be changed at any time from the "Settings" menu. Preferences - + Close Close @@ -612,110 +612,110 @@ These settings can be changed at any time from the "Settings" menu. Settings - - + + X Zoom X Zoom - - + + Y Zoom Y Zoom - - + + Min X Min X - - + + Max Y Max Y - + Max X Max X - + Min Y Min Y - - + + X Axis Step X Axis Step - - + + Y Axis Step Y Axis Step - - + + Line width Line width - - + + Text size (px) Text size (px) - - + + X Label X Label - - + + Y Label Y Label - - + + X Log scale X Log scale - - + + Show X graduation Show X graduation - - + + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot… - + Save plot as Save plot as… - + Load plot Open plot… @@ -727,96 +727,96 @@ These settings can be changed at any time from the "Settings" menu. ThanksTo - + Thanks and Contributions - LogarithmPlotter Thanks and Contributions - LogarithmPlotter - + Source code Source code - + Original library by Raphael Graf Original library by Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Ported to JavaScript by Matthew Crumley - - - + + + Website Website - + Ported to QMLJS by Ad5001 Ported to QMLJS by Ad5001 - + Libraries included Libraries included - + Email Email - + English English - + French French - + German German - + Hungarian Hungarian - - - + + + Github GitHub - + Norwegian Norwegian - + Spanish Spanish - + Translations included Translations included - + Improve Improve @@ -824,24 +824,24 @@ These settings can be changed at any time from the "Settings" menu. bodemagnitude - + Bode Magnitude Bode Magnitude - + Bode Magnitudes Bode Magnitudes - - + + low-pass low-pass - - + + high-pass high-pass @@ -849,8 +849,8 @@ These settings can be changed at any time from the "Settings" menu. bodemagnitudesum - - + + Bode Magnitudes Sum Bode Magnitudes Sum @@ -858,12 +858,12 @@ These settings can be changed at any time from the "Settings" menu. bodephase - + Bode Phase Bode Phase - + Bode Phases Bode Phases @@ -871,8 +871,8 @@ These settings can be changed at any time from the "Settings" menu. bodephasesum - - + + Bode Phases Sum Bode Phases Sum @@ -880,12 +880,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -893,8 +893,8 @@ These settings can be changed at any time from the "Settings" menu. color - - + + %1 %2's color changed from %3 to %4. %1 %2's color changed from %3 to %4. @@ -902,27 +902,27 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - + Note: Specify the probability for each value. Note: Specify the probability for each value. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -930,11 +930,11 @@ These settings can be changed at any time from the "Settings" menu. control - - - - - + + + + + %1: %1: @@ -942,8 +942,8 @@ These settings can be changed at any time from the "Settings" menu. create - - + + New %1 %2 created. New %1 %2 created. @@ -951,8 +951,8 @@ These settings can be changed at any time from the "Settings" menu. delete - - + + %1 %2 deleted. %1 %2 deleted. @@ -960,12 +960,12 @@ These settings can be changed at any time from the "Settings" menu. distribution - + Repartition Distribution - + Repartition functions Distribution functions @@ -973,12 +973,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -986,46 +986,46 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. @@ -1034,12 +1034,12 @@ These settings can be changed at any time from the "Settings" menu.Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 @@ -1052,104 +1052,104 @@ These settings can be changed at any time from the "Settings" menu.Expected variable for assignment. - - + + Parse error [position %1]: %2 Parse error [position %1]: %2 - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - + First argument to map is not a function. First argument to map is not a function. - + Second argument to map is not an array. Second argument to map is not an array. - + First argument to fold is not a function. First argument to fold is not a function. - + Second argument to fold is not an array. Second argument to fold is not an array. - + First argument to filter is not a function. First argument to filter is not a function. - + Second argument to filter is not an array. Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1160,7 +1160,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1174,13 +1174,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1191,27 +1191,27 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets Automatically close parentheses and brackets - + Enable syntax highlighting Enable syntax highlighting - + Enable autocompletion Enable autocompletion - + Color Scheme Color Scheme @@ -1219,12 +1219,12 @@ Evaluated expression: %3 function - + Function Function - + Functions Functions @@ -1251,17 +1251,17 @@ Evaluated expression: %3 general - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + Enable LaTeX rendering Enable LaTeX rendering @@ -1308,32 +1308,36 @@ Evaluated expression: %3 History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - - Could not save file: - Could not save file: + + Could not load file: + - + Could not save file: + Could not save file: + + + Loaded file '%1'. Loaded file '%1'. @@ -1353,7 +1357,7 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1362,12 +1366,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1380,7 +1384,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1393,7 +1397,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1407,8 +1411,8 @@ Please make sure your LaTeX installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -1416,114 +1420,114 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - + above ↑ Above - + below ↓ Below - - + + left ← Left - - + + right → Right - + above-left ↖ Above left - + above-right ↗ Above right - + below-left ↙ Below left - + below-right ↘ Below right - + center >|< Center - + top ↑ Top - + bottom ↓ Bottom - + top-left ↖ Top left - + top-right ↗ Top right - + bottom-left ↙ Bottom left - + bottom-right ↘ Bottom right - + application Application - + function Function - + high High - + low Low - + Next to target Next to target - + With label With label - + Hidden Hidden @@ -1542,12 +1546,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. point - + Point Point - + Points Points @@ -1555,12 +1559,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. position - + Position of %1 %2 set from "%3" to "%4". %1 %2 moved from "%3" to "%4". - + Position of %1 set from %2 to %3. %1 moved from %2 to %3. @@ -1568,158 +1572,158 @@ Please make sure your LaTeX installation is correct and report a bug if so. prop - + expression Expression - + definitionDomain Domain - + destinationDomain Range - - - - - - - - - - + + + + + + + + + + labelPosition Label position - + displayMode Display mode - - - - - - - + + + + + + + labelX Label's X position - - + + drawPoints Show points - - + + drawDashedLines Show dashed lines - - + + om_0 ω₀ - + pass Pass - + gain Magnitude gain - + omGraduation Show graduation on ω₀ - + phase Phase - + unit Unit to use - - - + + + x X - - + + y Y - + pointStyle Point style - + probabilities Probabilities list - + text Content - + disableLatex Disable LaTeX rendering for this text - + targetElement Object to target - + approximate Show rounded calculated value - + rounding Rounding - + displayStyle Display style - + targetValuePosition Target's value position - + defaultExpression Default expression - + baseValues Initialization values @@ -1742,12 +1746,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. sequence - + Sequence Sequence - + Sequences Sequences @@ -1755,17 +1759,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory - + general General - + editor Expression Editor - + default Default settings @@ -1787,12 +1791,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. text - + Text Text - + Texts Texts @@ -1800,22 +1804,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. @@ -1823,22 +1827,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: Function-like object>) - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 %2 @@ -1847,17 +1851,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: Function-like object>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1865,14 +1869,14 @@ Please make sure your LaTeX installation is correct and report a bug if so. visibility - - + + %1 %2 shown. %1 %2 shown. - - + + %1 %2 hidden. %1 %2 hidden. @@ -1880,12 +1884,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. xcursor - + X Cursor X Cursor - + X Cursors X Cursors diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index 02b39ef..f5e3d12 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. Software de trazado 2D para realizar gráficos de Bode, secuencias y funciones de distribución. - + Report a bug Informar de un error - + Official website Sitio web oficial @@ -32,57 +32,57 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Preferences &Preferencias - + &Create &Crear @@ -119,52 +119,52 @@ Esquema de colores - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -176,7 +176,7 @@ BaseDialog - + Close Cerrar @@ -191,12 +191,12 @@ Changelog - + Fetching changelog... Obteniendo el registro de cambios… - + Close Cerrar @@ -204,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Crear nuevo %1 - + Pick on graph Elegir en el gráfico @@ -218,42 +218,42 @@ Dialog - + Edit properties of %1 %2 Editar las propiedades de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nombre de objeto no válido - + An object with the name '%1' already exists. Ya existe un objeto con el nombre '%1'. - + Name - + Label content - + null - + name - + name + value nombre + valor @@ -292,32 +292,32 @@ ExpressionEditor - + Object Properties Propiedades de los objetos - + Variables - + Constants Constantes - + Functions Funciones - + Executable Objects Objetos de función - + Objects Objetos @@ -325,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Exportar archivo de gráfico de logaritmos - + Import Logarithm Plot file Importar archivo de gráfico de logaritmos @@ -338,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenid@ a LogarithmPlotter - + Version %1 @@ -352,22 +352,22 @@ Activar el renderizado de LaTeX - + User manual - + Changelog Registro de cambios - + Preferences Preferencias - + Close Cerrar @@ -405,22 +405,22 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes HistoryBrowser - + Filter... - + Redo > Rehacer > - + > Now > Ahora - + < Undo < Deshacer @@ -428,7 +428,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ListSetting - + + Add Entry + Añadir entrada @@ -436,32 +436,32 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes LogarithmPlotter - + Objects Objetos - + Settings Ajustes - + History Historial - + Copied plot screenshot to clipboard! ¡Captura de pantalla del gráfico copiada al portapapeles! - + &Update &Actualizar - + &Update LogarithmPlotter &Actualizar LogarithmPlotter @@ -493,7 +493,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ObjectCreationGrid - + + Create new: + Crear nuevo: @@ -501,12 +501,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ObjectLists - + Hide all %1 Ocultar todo %1 - + Show all %1 Mostrar todo %1 @@ -534,27 +534,27 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ObjectRow - + Hide %1 %2 Ocultar %1 %2 - + Show %1 %2 Mostrar %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 Elegir nuevo color para %1 %2 @@ -562,37 +562,37 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes PickLocationOverlay - + Pointer precision: Precisión del puntero: - + Snap to grid: Ajustar a la cuadrícula: - + Pick X Elige X - + Pick Y Elige Y - + Open picker settings Abrir los ajustes del selector - + Hide picker settings Ocultar ajustes del selector - + (no pick selected) (sin selección) @@ -604,7 +604,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Preferences - + Close Cerrar @@ -612,110 +612,110 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Settings - - + + X Zoom - - + + Y Zoom - - + + Min X - - + + Max Y - + Max X - + Min Y - - + + X Axis Step Paso por eje X - - + + Y Axis Step Paso por eje Y - - + + Line width Anchura de la línea - - + + Text size (px) Tamaño del texto (px) - - + + X Label - - + + Y Label - - + + X Log scale Escala logarítmica en X - - + + Show X graduation Mostrar graduación del eje X - - + + Show Y graduation Mostrar graduación del eje Y - + Copy to clipboard Copiar al portapapeles - + Save plot Guardar gráfico… - + Save plot as Guardar gráfico como… - + Load plot Abrir gráfico… @@ -727,96 +727,96 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ThanksTo - + Thanks and Contributions - LogarithmPlotter Agradecimientos y colaboraciones - LogarithmPlotter - + Source code - + Original library by Raphael Graf Biblioteca original de Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley Portado a JavaScript por Matthew Crumley - - - + + + Website - + Ported to QMLJS by Ad5001 Portado a QMLJS por Ad5001 - + Libraries included Bibliotecas incluidas - + Email - + English - + French - + German - + Hungarian - - - + + + Github GitHub - + Norwegian - + Spanish Español - + Translations included Traducciones incluidas - + Improve Mejorar @@ -824,24 +824,24 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes bodemagnitude - + Bode Magnitude Magnitud de Bode - + Bode Magnitudes Magnitudes de Bode - - + + low-pass Filtro paso bajo - - + + high-pass Filtro paso alto @@ -849,8 +849,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes bodemagnitudesum - - + + Bode Magnitudes Sum Suma de las Magnitudes de Bode @@ -858,12 +858,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes bodephase - + Bode Phase Fase de Bode - + Bode Phases Fases de Bode @@ -871,8 +871,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes bodephasesum - - + + Bode Phases Sum Suma de las fases de Bode @@ -880,12 +880,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes changelog - + Could not fetch changelog: Server error {}. No se ha podido recuperar el registro de cambios: Error del servidor {}. - + Could not fetch update: {}. No se pudo obtener el registro de cambios: {}. @@ -893,8 +893,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes color - - + + %1 %2's color changed from %3 to %4. El color de %1 %2 cambió de %3 a %4. @@ -902,27 +902,27 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) - + Note: Specify the probability for each value. Nota: Especifique la probabilidad para cada valor. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. @@ -930,11 +930,11 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes control - - - - - + + + + + %1: @@ -942,8 +942,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes create - - + + New %1 %2 created. Se ha creado un nuevo %1 %2. @@ -951,8 +951,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes delete - - + + %1 %2 deleted. %1 %2 borrados. @@ -960,12 +960,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes distribution - + Repartition Distribución - + Repartition functions Funciones de distribución @@ -973,12 +973,12 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 cambió de "%4" a "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 ha cambiado de %3 a %4. @@ -986,46 +986,46 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes error - - + + Cannot find property %1 of object %2. No se puede encontrar la propiedad %1 del objeto %2. - + Undefined variable %1. Variable %1 no definida. - + In order to be executed, object %1 must have at least one argument. Para ser ejecutado, el objeto %1 debe tener al menos un argumento. - + %1 cannot be executed. %1 no es una función. - - - + + + Invalid expression. Expresión incorrecta. - + Invalid expression (parity). Expresión no válida (paridad). - + Unknown character "%1". Carácter "%1" desconocido. - - + + Illegal escape sequence: %1. Secuencia de salida no válida: %1 . @@ -1034,109 +1034,109 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Error de análisis [%1:%2]: %3 - - + + Parse error [position %1]: %2 Error en el análisis [posición%1 ]:%2 - + Expected %1 Previsto %1 - + Unexpected %1 Inesperado %1 - + Unexpected ".": member access is not permitted "." Inesperado: el acceso de miembros no está permitido - + Unexpected "[]": arrays are disabled. "[]" inesperado: las matrices están desactivadas. - + Unexpected symbol: %1. Símbolo inesperado: %1. - - + + Function %1 must have at least one argument. La función %1 debe tener al menos un argumento. - + First argument to map is not a function. El primer argumento de map no es una función. - + Second argument to map is not an array. El segundo argumento de map no es una matriz. - + First argument to fold is not a function. El primer argumento de fold no es una función. - + Second argument to fold is not an array. El segundo argumento de fold no es una matriz. - + First argument to filter is not a function. El primer argumento del filtro no es una función. - + Second argument to filter is not an array. El segundo argumento del filtro no es una matriz. - + Second argument to indexOf is not a string or array. El segundo argumento de indexOf no es una cadena ni una matriz. - + Second argument to join is not an array. El segundo argumento para unirse no es una matriz. - + No object found with names %1. No se ha encontrado ningún objeto con el nombre %1. - + No object found with name %1. Ningún objeto con el nombre %1 encontrado. - + Object cannot be dependent on itself. El objeto no puede depender de sí mismo. - + Circular dependency detected. Object %1 depends on %2. Dependencia circular detectada. El objeto %1 depende de %2. - + Circular dependency detected. Objects %1 depend on %2. Dependencia circular detectada. Los objetos %1 dependen de %2. - + Error while parsing expression for property %1: %2 @@ -1147,7 +1147,7 @@ Evaluated expression: %3 Expresión evaluada: %3 - + Error while attempting to draw %1 %2: %3 @@ -1166,7 +1166,7 @@ Deshaciendo el último cambio. Variable de asignación esperada. - + EOF Fin de la expresión @@ -1174,13 +1174,13 @@ Deshaciendo el último cambio. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Error de procesamiento - + Error while parsing expression for property %1: %2 @@ -1191,27 +1191,27 @@ Evaluated expression: %3 Expresión evaluada: %3 - + LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets Cerrar automáticamente paréntesis y corchetes - + Enable syntax highlighting Activar el resaltado sintáctico - + Enable autocompletion Activar autocompletar - + Color Scheme Esquema de colores @@ -1219,12 +1219,12 @@ Expresión evaluada: %3 function - + Function Función - + Functions Funciones @@ -1251,17 +1251,17 @@ Expresión evaluada: %3 general - + Check for updates on startup Comprobación de las actualizaciones al arrancar - + Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - + Enable LaTeX rendering Activar el renderizado de LaTeX @@ -1320,32 +1320,36 @@ Expresión evaluada: %3 Objetos - + Saved plot to '%1'. Gráfico guardado en '%1'. - + Loading file '%1'. Cargando el archivo '%1'. - + Unknown object type: %1. Tipo de objeto desconocido: %1 . - + Invalid file provided. Se ha proporcionado un archivo no válido. - - Could not save file: - No se ha podido guardar el archivo: + + Could not load file: + - + Could not save file: + No se ha podido guardar el archivo: + + + Loaded file '%1'. Archivo cargado '%1'. @@ -1353,7 +1357,7 @@ Expresión evaluada: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1362,12 +1366,12 @@ Si ya tiene instalada una distribución de LaTeX, asegúrese de que está instal De lo contrario, puede descargar una distribución de LaTeX como TeX Live en https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. No se ha encontrado DVIPNG. Asegúrese de incluirlo en tu distribución LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1380,7 +1384,7 @@ El proceso '{}' terminó con un código de retorno distinto de cero {} Por favor, asegúrate de que tu instalación de LaTeX es correcta e informe de un error si es así. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1393,7 +1397,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Asegúrate de que dicho paquete está instalado, o desactive el renderizado LaTeX en LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1407,8 +1411,8 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u name - - + + %1 %2 renamed to %3. %1 %2 ha sido renombrado a %3. @@ -1416,114 +1420,114 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u parameters - + below ↓ Abajo - - + + left ← Izquierda - + above-left ↖ Arriba a la izquierda - + below-left ↙ Abajo a la izquierda - + below-right ↘ Arriba a la derecha - + center >|< Centro - + top ↑ Arriba - + above ↑ Arriba - - + + right → Derecha - + above-right ↗ Arriba a la derecha - + bottom ↓ Bajar - + top-right ↗ Arriba a la derecha - + application Aplicación - + Next to target Próximo al objetivo - + top-left ↖ Arriba a la izquierda - + bottom-left ↙ Abajo a la izquierda - + bottom-right ↘ Abajo a la derecha - + function Función - + high Alto - + low Bajo - + With label Con etiqueta - + Hidden Oculto @@ -1542,12 +1546,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u point - + Point Punto - + Points Puntos @@ -1555,12 +1559,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u position - + Position of %1 %2 set from "%3" to "%4". %1 %2 movido de "%3" a "%4". - + Position of %1 set from %2 to %3. %1 movido de %2 a %3. @@ -1568,153 +1572,153 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u prop - + expression Expresión - + definitionDomain Dominio - - + + om_0 ω₀ - + disableLatex Desactivar el renderizado LaTeX para este texto - + rounding Redondeo - - - - - - - + + + + + + + labelX Posición de la etiqueta en X - - + + drawPoints Mostrar puntos - - + + drawDashedLines Mostrar líneas discontinuas - + destinationDomain Rango - - - - - - - - - - + + + + + + + + + + labelPosition Posición de la etiqueta - + displayMode Modo de visualización - + pass Pasar - + gain Incremento de magnitud - + unit Unidad a usar - - + + y Y - + omGraduation Mostrar la graduación en ω₀ - + phase Fase - - - + + + x X - + pointStyle Estilo de puntos - + text Contenido - + probabilities Lista de probabilidades - + targetElement Objeto de destino - + approximate Mostrar el resultado redondeado - + displayStyle Estilo de visualización - + targetValuePosition Posición del valor del objetivo - + defaultExpression Expresión predeterminada @@ -1723,7 +1727,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Color - + baseValues Valores de inicialización @@ -1742,12 +1746,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u sequence - + Sequences Secuencias - + Sequence Secuencia @@ -1755,17 +1759,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u settingCategory - + general General - + editor Editor de expresiones - + default Ajustes por defecto @@ -1787,12 +1791,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u text - + Texts Textos - + Text Texto @@ -1800,22 +1804,22 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u update - + An update for LogarithmPlotter (v{}) is available. Una actualización para LogarithmPlotter (v{}) está disponible. - + No update available. No hay ninguna actualización disponible. - + Could not fetch update information: Server error {}. No se ha podido obtener la información de la actualización: Error del servidor {}. - + Could not fetch update information: {}. No se pudo obtener información de la actualización: {}. @@ -1823,22 +1827,22 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<desde: número>, <hasta: número>, <f: Objeto similar a una función>) - - + + Usage: %1 Uso: %1 - - - + + + Usage: %1 %2 @@ -1847,17 +1851,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<desde: número>, <hasta: número>, <f: cadena>, <variable: cadena>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: objeto similar a una función>, <x: número>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: cadena>, <variable: cadena>, <x: número>) @@ -1865,14 +1869,14 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u visibility - - + + %1 %2 shown. Se muestra %1 %2. - - + + %1 %2 hidden. Se oculta %1 %2. @@ -1880,12 +1884,12 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u xcursor - + X Cursor Cursor X - + X Cursors Cursores X diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index eeaa500..7df2b4f 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. Logiciel de traçage 2D pour les diagrammes de Bode, les suites et les fonctions de répartition. - + Report a bug Rapport de bug - + Official website Site officiel @@ -32,57 +32,57 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Preferences &Préférences - + &Create &Créer @@ -124,52 +124,52 @@ Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -177,7 +177,7 @@ BaseDialog - + Close Fermer @@ -192,12 +192,12 @@ Changelog - + Fetching changelog... Récupération de l'historique des modifications… - + Close Fermer @@ -205,13 +205,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -219,42 +219,42 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -294,32 +294,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -327,12 +327,12 @@ FileDialog - + Export Logarithm Plot file Exporter le graphe Logarithmique - + Import Logarithm Plot file Importer un graphe Logarithmique @@ -340,12 +340,12 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 @@ -376,22 +376,22 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Preferences Préférences - + Close Fermer @@ -407,22 +407,22 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P HistoryBrowser - + Filter... Filtrer… - + Redo > Rétablir > - + > Now > État actuel - + < Undo < Annuler @@ -430,7 +430,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ListSetting - + + Add Entry + Nouvelle entrée @@ -438,17 +438,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P LogarithmPlotter - + Objects Objets - + Settings Paramètres - + History Historique @@ -477,17 +477,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -495,7 +495,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ObjectCreationGrid - + + Create new: + Créer : @@ -503,12 +503,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ObjectLists - + Hide all %1 Cacher tous les %1 - + Show all %1 Montrer tous les %1 @@ -536,27 +536,27 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ObjectRow - + Hide %1 %2 Cacher l'objet %1 %2 - + Show %1 %2 Montrer l'objet %1 %2 - + Set %1 %2 position Définir la position de l'objet %1 %2 - + Delete %1 %2 Supprimer l'objet %1 %2 - + Pick new color for %1 %2 Choisissez une nouvelle couleur pour %1 %2 @@ -564,7 +564,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P PickLocationOverlay - + Pointer precision: Précision du pointeur : @@ -573,32 +573,32 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Placement sur la grille - + Snap to grid: Placer sur la grille : - + Pick X Prendre la position X - + Pick Y Prendre la position Y - + Open picker settings Ouvrir les paramètres du pointeur - + Hide picker settings Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -606,7 +606,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Preferences - + Close Fermer @@ -614,110 +614,110 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Settings - - + + X Zoom Zoom en X - - + + Y Zoom Zoom en Y - - + + Min X Min X - - + + Max Y Max Y - + Max X Max X - + Min Y Min Y - - + + X Axis Step Pas de l'axe X - - + + Y Axis Step Pas de l'axe Y - - + + Line width Taille des lignes - - + + Text size (px) Taille du texte (px) - - + + X Label Label de l'axe X - - + + Y Label Label de l'axe Y - - + + X Log scale Échelle logarithmique en X - - + + Show X graduation Montrer la graduation de l'axe X - - + + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe… - + Save plot as Sauvegarder le graphe sous… - + Load plot Ouvrir un graphe… @@ -729,96 +729,96 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ThanksTo - + Thanks and Contributions - LogarithmPlotter Remerciements et contributions - LogarithmPlotter - + Source code Code source - + Original library by Raphael Graf Bibliothèque originale de Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Porté en JavaScript par Matthew Crumley - - - + + + Website Site web - + Ported to QMLJS by Ad5001 Porté à QMLJS par Ad5001 - + Libraries included Bibliothèques incluses - + Email Email - + English Anglais - + French Français - + German Allemand - + Hungarian Hongrois - - - + + + Github GitHub - + Norwegian Norvégien - + Spanish Espagnol - + Translations included Traductions incluses - + Improve Améliorer @@ -826,24 +826,24 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P bodemagnitude - + Bode Magnitude Gain de Bode - + Bode Magnitudes Gains de Bode - - + + low-pass passe-bas - - + + high-pass passe-haut @@ -851,8 +851,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P bodemagnitudesum - - + + Bode Magnitudes Sum Sommes des gains de Bode @@ -860,12 +860,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P bodephase - + Bode Phase Phase de Bode - + Bode Phases Phases de Bode @@ -873,8 +873,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P bodephasesum - - + + Bode Phases Sum Somme des phases de Bode @@ -882,12 +882,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -895,8 +895,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P color - - + + %1 %2's color changed from %3 to %4. La couleur du %1 %2 a été changée du %3 au %4. @@ -904,28 +904,28 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - + Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -933,11 +933,11 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P control - - - - - + + + + + %1: %1 : @@ -945,8 +945,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P create - - + + New %1 %2 created. Nouvel objet %1 %2 créé. @@ -954,8 +954,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P delete - - + + %1 %2 deleted. %1 %2 supprimé(e). @@ -963,12 +963,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P distribution - + Repartition Répartition - + Repartition functions Fonctions de répartition @@ -976,12 +976,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -989,46 +989,46 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P error - - + + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. @@ -1037,12 +1037,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu @@ -1055,104 +1055,104 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Une variable est attendue pour l'affectation. - - + + Parse error [position %1]: %2 Erreur de syntaxe [position %1] : %2 - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1163,7 +1163,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1177,13 +1177,13 @@ La dernière modification a été annulée. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1194,27 +1194,27 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur - + Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - + Enable syntax highlighting Activer la coloration syntaxique - + Enable autocompletion Activer l'autocomplétion - + Color Scheme Coloration Syntaxique @@ -1222,12 +1222,12 @@ Formule analysée : %3 function - + Function Fonction - + Functions Fonctions @@ -1254,17 +1254,17 @@ Formule analysée : %3 general - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Réinitialiser la pile d'action "Rétablir" automatiquement - + Enable LaTeX rendering Activer le rendu LaTeX @@ -1323,32 +1323,36 @@ Formule analysée : %3 &Mettre à jour LogarithmPlotter - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - - Could not save file: - Impossible de sauvegarder le fichier : + + Could not load file: + - + Could not save file: + Impossible de sauvegarder le fichier : + + + Loaded file '%1'. Fichier '%1' chargé. @@ -1356,7 +1360,7 @@ Formule analysée : %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1365,12 +1369,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1383,7 +1387,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1396,7 +1400,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Assurez-vous que ce paquetage est installé, ou désactivez le rendu LaTeX dans LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1410,8 +1414,8 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c name - - + + %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -1419,114 +1423,114 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - + above ↑ Au dessus - + below ↓ En dessous - - + + left ← À gauche - - + + right → À droite - + above-left ↖ Au dessus à gauche - + above-right ↗ Au dessus à droite - + below-left ↙ En dessous à gauche - + below-right ↘ En dessous à droite - + center >|< Centré - + top ↑ Au dessus - + bottom ↓ En dessous - + top-left ↖ Au dessus à gauche - + top-right ↗ Au dessus à droite - + bottom-left ↙ En dessous à gauche - + bottom-right ↘ En dessous à droite - + application Application - + function Fonction - + high Haut - + low Bas - + Next to target A côté de la cible - + With label Avec l'étiquette - + Hidden Caché @@ -1545,12 +1549,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c point - + Point Point - + Points Points @@ -1558,12 +1562,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c position - + Position of %1 %2 set from "%3" to "%4". %1 %2 a été déplacé depuis "%3" vers "%4". - + Position of %1 set from %2 to %3. %1 a été déplacé depuis %2 vers %3. @@ -1571,158 +1575,158 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c prop - + expression Formule - + definitionDomain Domaine de définition - + destinationDomain Portée - - - - - - - - - - + + + + + + + + + + labelPosition Position de l'étiquette - + displayMode Mode d'affichage - - - - - - - + + + + + + + labelX Position en X de l'étiquette - - + + drawPoints Afficher les points - - + + drawDashedLines Afficher les pointillés - - + + om_0 ω₀ - + pass Passe - + gain Gain - + omGraduation Afficher la graduation sur ω₀ - + phase Phase - + unit Unité de la phase - - - + + + x X - - + + y Y - + pointStyle Style du point - + probabilities Liste de probabilités - + text Contenu - + disableLatex Désactiver le rendu LaTeX pour ce texte - + targetElement Objet à cibler - + approximate Afficher la valeur arrondie calculée - + rounding Arrondi - + displayStyle Style d'affichage - + targetValuePosition Position de la valeur de la cible - + defaultExpression Formule par défaut - + baseValues Valeurs d'initialisation @@ -1745,12 +1749,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sequence - + Sequence Suite - + Sequences Suites @@ -1758,17 +1762,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c settingCategory - + general Général - + editor Éditeur de formule - + default Paramètres par défaut @@ -1790,12 +1794,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c text - + Text Texte - + Texts Textes @@ -1803,22 +1807,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c update - + An update for LogarithmPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. @@ -1826,22 +1830,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet fonction>) - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 %2 @@ -1850,17 +1854,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet fonction>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) @@ -1868,14 +1872,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility - - + + %1 %2 shown. %1 %2 affiché(e). - - + + %1 %2 hidden. %1 %2 cachée(e). @@ -1883,12 +1887,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c xcursor - + X Cursor Curseur X - + X Cursors Curseurs X diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index e03702f..f817dd2 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye - + LogarithmPlotter v%1 LogarithmPlotter %1 verzió - + 2D plotter software to make BODE plots, sequences and repartition functions. Síkbeli ábrázolásszoftver Bode-ábrák, sorozatok és eloszlási funkciók készítéséhez. - + Report a bug Hiba bejelentése - + Official website Hivatalos honlap @@ -32,57 +32,57 @@ AppMenuBar - + &File &Fájl - + &Load... &Megnyitás… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Preferences &Beállítások - + &Create &Létrehozás @@ -123,52 +123,52 @@ Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -176,7 +176,7 @@ BaseDialog - + Close Bezárás @@ -191,12 +191,12 @@ Changelog - + Fetching changelog... Változásnapló lekérése… - + Close Kész @@ -204,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -218,42 +218,42 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -292,32 +292,32 @@ ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -325,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Logaritmus-ábra-fájl exportálása - + Import Logarithm Plot file Logaritmus-ábra-fájl importálása @@ -338,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió @@ -382,22 +382,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Színséma: - + User manual Használati utasítás - + Changelog Változásnapló - + Preferences Beállítások - + Close Kész @@ -405,22 +405,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. HistoryBrowser - + Filter... Szűrő… - + Redo > Ismétlés > - + > Now > Most - + < Undo < Visszavonás @@ -428,7 +428,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ListSetting - + + Add Entry + Bejegyzés hozzáadása @@ -436,17 +436,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - + Objects Tárgyak - + Settings Beállítások - + History Előzmények @@ -475,17 +475,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -493,7 +493,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectCreationGrid - + + Create new: + Új létrehozása: @@ -501,12 +501,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectLists - + Hide all %1 Összes %1 elrejtése - + Show all %1 Összes %1 megjelenítése @@ -534,27 +534,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectRow - + Hide %1 %2 %1 %2 elrejtése - + Show %1 %2 %1 %2 megjelenítése - + Set %1 %2 position %1 %2 helye beállítása - + Delete %1 %2 %1 %2 törlése - + Pick new color for %1 %2 Válasszon új színt a következőhöz: %1 %2 @@ -562,7 +562,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: @@ -571,32 +571,32 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Rácshoz illesztés - + Snap to grid: Rácshoz igazítás: - + Pick X X kijelölése - + Pick Y Y kijelölése - + Open picker settings Kijelölési beállítások megnyitása - + Hide picker settings Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -604,7 +604,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Preferences - + Close Bezárás @@ -612,110 +612,110 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Settings - - + + X Zoom X-nagyítás - - + + Y Zoom Y-nagyítás - - + + Min X Legkisebb X - - + + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - - + + X Axis Step X tengely lépésköze - - + + Y Axis Step Y tengely lépésköze - - + + Line width Vonalvastagság - - + + Text size (px) Szövegméret (képpont) - - + + X Label X címke - - + + Y Label Y címke - - + + X Log scale X tengely logaritmikus skálával - - + + Show X graduation X érettségi megjelenítése - - + + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése… - + Save plot as Ábra mentése másként… - + Load plot Ábra megnyitása… @@ -727,96 +727,96 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ThanksTo - + Thanks and Contributions - LogarithmPlotter Köszönet és hozzájárulás - LogarithmPlotter - + Source code Forráskód - + Original library by Raphael Graf Eredeti könyvtár: Graf Raphael - + Source Forrás - + Ported to Javascript by Matthew Crumley JavaScript-átalakítás: Crumley Máté - - - + + + Website Honlap - + Ported to QMLJS by Ad5001 QMLJS-átalakítás: Ad5001 - + Libraries included Tartalmazott könyvtárak - + Email E-mail - + English angol - + French francia - + German német - + Hungarian magyar - - - + + + Github GitHub - + Norwegian norvég - + Spanish spanyol - + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -824,24 +824,24 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. bodemagnitude - + Bode Magnitude Bode-nagyságrend - + Bode Magnitudes Bode-nagyságrendek - - + + low-pass aluláteresztő - - + + high-pass felüláteresztő @@ -849,8 +849,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. bodemagnitudesum - - + + Bode Magnitudes Sum Bode-nagyságrendek összege @@ -858,12 +858,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. bodephase - + Bode Phase Bode-fázis - + Bode Phases Bode-fázisok @@ -871,8 +871,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. bodephasesum - - + + Bode Phases Sum Bode-fázisok összege @@ -880,12 +880,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -893,8 +893,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color - - + + %1 %2's color changed from %3 to %4. %1 %2 színe %3-ról %4-re változott. @@ -902,27 +902,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - + Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -930,11 +930,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. control - - - - - + + + + + %1: %1: @@ -942,8 +942,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create - - + + New %1 %2 created. Új %1 %2 létrehozva. @@ -951,8 +951,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. delete - - + + %1 %2 deleted. %1 %2 törölve. @@ -960,12 +960,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. distribution - + Repartition Elosztás - + Repartition functions Elosztási függvények @@ -973,12 +973,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -986,46 +986,46 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - - + + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. @@ -1034,12 +1034,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 @@ -1052,104 +1052,104 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A hozzárendeléshez várt változó. - - + + Parse error [position %1]: %2 Elemzési hiba [hely %1]: %2 - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - + First argument to map is not a function. Az első leképezési argumentum nem függvény. - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1160,7 +1160,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1174,13 +1174,13 @@ Az utolsó módosítás visszavonása. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1191,27 +1191,27 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba - + Automatically close parenthesises and brackets Zárójelek automatikus bezárása - + Enable syntax highlighting Mondattani kiemelés engedélyezése - + Enable autocompletion Automatikus befejezés engedélyezése - + Color Scheme Színséma @@ -1219,12 +1219,12 @@ Kiértékelt kifejezés: %3 function - + Function Függvény - + Functions Függvények @@ -1251,17 +1251,17 @@ Kiértékelt kifejezés: %3 general - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése @@ -1304,32 +1304,36 @@ Kiértékelt kifejezés: %3 Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - - Could not save file: - A fájl mentése nem sikerült: + + Could not load file: + - + Could not save file: + A fájl mentése nem sikerült: + + + Loaded file '%1'. A(z) „%1” fájl betöltve. @@ -1353,7 +1357,7 @@ Kiértékelt kifejezés: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1362,12 +1366,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1380,7 +1384,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1393,7 +1397,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Győződjön meg arról, hogy az említett csomag telepítve van, vagy tiltsa le a LaTeX megjelenítést a LogarithmPlotterben. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1407,8 +1411,8 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents name - - + + %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -1416,114 +1420,114 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - + above ↑ Felett - + below ↓ Alatt - - + + left ← Balra - - + + right → Jobbra - + above-left ↖ Felett, balra - + above-right ↗ Felett, jobbra - + below-left ↙ Alatt, balra - + below-right ↘ Alatt, jobbra - + center >|< Középre - + top ↑ Felső - + bottom ↓ Alsó - + top-left ↖ Bal felső - + top-right ↗ Jobb felső - + bottom-left ↙ Bal alsó - + bottom-right ↘ Jobb alsó - + application Alkalmazás - + function Függvény - + high Magas - + low Alul - + Next to target Cél mellé - + With label Címkével - + Hidden Rejtett @@ -1542,12 +1546,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents point - + Point Pont - + Points Pontok @@ -1555,12 +1559,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents position - + Position of %1 %2 set from "%3" to "%4". %1 %2 áthelyezve innen: „%3” ide: „%4”. - + Position of %1 set from %2 to %3. %1 áthelyezve innen: %2 ide: %3. @@ -1568,158 +1572,158 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents prop - + expression Kifejezés - + definitionDomain Abszcissza tartomány - + destinationDomain Ordináta tartomány - - - - - - - - - - + + + + + + + + + + labelPosition Címke helyzete - + displayMode Megjelenítési mód - - - - - - - + + + + + + + labelX Címke X helyzete - - + + drawPoints Pontok megjelenítése - - + + drawDashedLines Szaggatott vonalak megjelenítése - - + + om_0 ω₀ - + pass Áteresztő - + gain Nagyságrend nyeresége - + omGraduation ω₀ érettségi megjelenítése - + phase Fázis - + unit Egység használata - - - + + + x X - - + + y Y - + pointStyle Pontstílus - + probabilities Valószínűségek listája - + text Tartalom - + disableLatex LaTeX-megjelenítés letiltása ennél a szövegnél - + targetElement Tárgycél - + approximate Kerekített számított érték megjelenítése - + rounding Kerekítés - + displayStyle Megjelenítési stílus - + targetValuePosition Cél értékpozíciója - + defaultExpression Alapértelmezett kifejezés - + baseValues Kezdeményezési értékek @@ -1742,12 +1746,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sequence - + Sequence Sorozat - + Sequences Sorozatok @@ -1755,17 +1759,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory - + general Általános - + editor Kifejezésszerkesztő - + default Alapértelmezett ábra @@ -1787,12 +1791,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents text - + Text Szöveg - + Texts Szövegek @@ -1800,22 +1804,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents update - + An update for LogarithmPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. @@ -1823,22 +1827,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<alsó korlát: szám>, <felső korlát: szám>, <f: függvényszerű objektum>) - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 %2 @@ -1847,17 +1851,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: függvényszerű objektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) @@ -1865,14 +1869,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility - - + + %1 %2 shown. %1 %2 megjelenítve. - - + + %1 %2 hidden. %1 %2 rejtve. @@ -1880,12 +1884,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents xcursor - + X Cursor X kurzor - + X Cursors X kurzorok diff --git a/assets/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts index 5e94d77..b46ffe7 100644 --- a/assets/i18n/lp_nb_NO.ts +++ b/assets/i18n/lp_nb_NO.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter Om - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. - + Report a bug Rapporter en feil - + Official website @@ -32,57 +32,57 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Preferences - + &Create &Opprett @@ -99,52 +99,52 @@ Tilbakestill angrehistorikk automatisk - + &Help &Hjelp - + &Source code - + &Report a bug &Rapporter en feil - + &User manual - + &Changelog &Endringslogg - + &Help translating! &Hjelp til å oversette! - + &Thanks &Erkjennelser - + &About &Om - + Save unsaved changes? Lagre ikke-lagrede endringer? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? @@ -152,7 +152,7 @@ BaseDialog - + Close Lukk @@ -167,12 +167,12 @@ Changelog - + Fetching changelog... Henter endringslogg… - + Close Lukk @@ -180,13 +180,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -194,42 +194,42 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ugyldig objektnavn - + An object with the name '%1' already exists. Et objekt med navnet '%1' finnes allerede. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -268,32 +268,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -301,12 +301,12 @@ FileDialog - + Export Logarithm Plot file Eksporter logaritmeplott-fil - + Import Logarithm Plot file Importer logaritmeplott-fil @@ -314,12 +314,12 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 @@ -338,22 +338,22 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Tilbakesitll angrehistorikk når en ny handling legges til - + User manual - + Changelog - + Preferences - + Close Lukk @@ -361,22 +361,22 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. HistoryBrowser - + Filter... - + Redo > Angre > - + > Now > Nå - + < Undo < Angre @@ -384,7 +384,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ListSetting - + + Add Entry @@ -392,17 +392,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - + Objects Objekter - + Settings Innstillinger - + History Historikk @@ -431,17 +431,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -449,7 +449,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectCreationGrid - + + Create new: + Opprett ny: @@ -457,12 +457,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectLists - + Hide all %1 Skjul alle %1 - + Show all %1 Vis alle %1 @@ -490,27 +490,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectRow - + Hide %1 %2 Skjul %1 %2 - + Show %1 %2 Vis %1 %2 - + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 Slett %1 %2 - + Pick new color for %1 %2 Velg ny farge for %1 %2 @@ -518,7 +518,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: @@ -527,32 +527,32 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Fest til rutenett - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -560,7 +560,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Preferences - + Close Lukk @@ -568,110 +568,110 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Settings - - + + X Zoom X-forstørrelse - - + + Y Zoom Y-forstørrelse - - + + Min X Min. X - - + + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - - + + X Axis Step X-aksesteg - - + + Y Axis Step Y-aksesteg - - + + Line width Linjebredde - - + + Text size (px) Tekststørrelse (piksler) - - + + X Label Navn på X-akse - - + + Y Label Navn på Y-akse - - + + X Log scale Logaritmisk skala i x - - + + Show X graduation Vis X-inndeling - - + + Show Y graduation Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott @@ -679,96 +679,96 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ThanksTo - + Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley Overført til JavaScript av Matthew Crumley - - - + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - - + + + Github GitHub - + Norwegian - + Spanish - + Translations included - + Improve @@ -776,24 +776,24 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodemagnitude - + Bode Magnitude Bode-magnitude - + Bode Magnitudes Bode-magnituder - - + + low-pass lavpass - - + + high-pass høypass @@ -801,8 +801,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodemagnitudesum - - + + Bode Magnitudes Sum Bode-magnitudesum @@ -810,12 +810,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodephase - + Bode Phase Bode-fase - + Bode Phases Bode-faser @@ -823,8 +823,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodephasesum - - + + Bode Phases Sum Bode-fasesum @@ -832,12 +832,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -845,8 +845,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. color - - + + %1 %2's color changed from %3 to %4. @@ -854,27 +854,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + Note: Specify the probability for each value. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -882,11 +882,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. control - - - - - + + + + + %1: @@ -894,8 +894,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create - - + + New %1 %2 created. Ny %1 %2 opprettet. @@ -903,8 +903,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. delete - - + + %1 %2 deleted. %1 %2 slettet. @@ -912,12 +912,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. distribution - + Repartition Distribusjon - + Repartition functions Distribusjonsfunksjoner @@ -925,12 +925,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 av %2 %3 endret fra «%4» til «%5». - + %1 of %2 changed from %3 to %4. @@ -938,32 +938,32 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. error - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -971,7 +971,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -979,128 +979,128 @@ Undoing last change. - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + EOF - - + + Parse error [position %1]: %2 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + Unknown character "%1". - - + + Illegal escape sequence: %1. @@ -1108,13 +1108,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1122,27 +1122,27 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme @@ -1150,12 +1150,12 @@ Evaluated expression: %3 function - + Function Funksjon - + Functions Funksjoner @@ -1182,17 +1182,17 @@ Evaluated expression: %3 general - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - + Enable LaTeX rendering @@ -1235,32 +1235,36 @@ Evaluated expression: %3 Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - - Could not save file: - Kunne ikke lagre fil: + + Could not load file: + - + Could not save file: + Kunne ikke lagre fil: + + + Loaded file '%1'. Lastet inn filen «%1». @@ -1280,19 +1284,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1301,7 +1305,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1310,7 +1314,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1321,8 +1325,8 @@ Please make sure your latex installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. @@ -1330,114 +1334,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden @@ -1456,12 +1460,12 @@ Please make sure your latex installation is correct and report a bug if so. point - + Point Punkt - + Points Punkter @@ -1469,12 +1473,12 @@ Please make sure your latex installation is correct and report a bug if so. position - + Position of %1 %2 set from "%3" to "%4". - + Position of %1 set from %2 to %3. @@ -1482,158 +1486,158 @@ Please make sure your latex installation is correct and report a bug if so. prop - + expression - + definitionDomain - + destinationDomain - + displayMode - - - - - - - - - - + + + + + + + + + + labelPosition - - - - - - - + + + + + + + labelX - - + + drawPoints - - + + drawDashedLines - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit - - - + + + x - - + + y - + pointStyle - + probabilities - + defaultExpression - + baseValues - + text - + disableLatex - + targetElement - + approximate - + rounding - + displayStyle - + targetValuePosition @@ -1652,12 +1656,12 @@ Please make sure your latex installation is correct and report a bug if so. sequence - + Sequence Følge - + Sequences Følger @@ -1665,17 +1669,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1697,12 +1701,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text Tekst - + Texts Tekster @@ -1710,22 +1714,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig. - + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. @@ -1733,38 +1737,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - - + + Usage: %1 - - - + + + Usage: %1 %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) @@ -1772,14 +1776,14 @@ Please make sure your latex installation is correct and report a bug if so. visibility - - + + %1 %2 shown. %1 %2 vist. - - + + %1 %2 hidden. %1 %2 skjult. @@ -1787,12 +1791,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor X-peker - + X Cursors X-pekere diff --git a/assets/i18n/lp_template.ts b/assets/i18n/lp_template.ts index 7626f7b..9440730 100644 --- a/assets/i18n/lp_template.ts +++ b/assets/i18n/lp_template.ts @@ -4,27 +4,27 @@ About - + About LogarithmPlotter - + LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. - + Report a bug - + Official website @@ -32,107 +32,107 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Preferences - + &Create - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -140,7 +140,7 @@ BaseDialog - + Close @@ -148,12 +148,12 @@ Changelog - + Fetching changelog... - + Close @@ -161,13 +161,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -175,42 +175,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -218,32 +218,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -251,12 +251,12 @@ FileDialog - + Export Logarithm Plot file - + Import Logarithm Plot file @@ -264,32 +264,32 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + User manual - + Changelog - + Preferences - + Close @@ -297,22 +297,22 @@ HistoryBrowser - + Filter... - + Redo > - + > Now - + < Undo @@ -320,7 +320,7 @@ ListSetting - + + Add Entry @@ -328,32 +328,32 @@ LogarithmPlotter - + Objects - + Settings - + History - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -361,7 +361,7 @@ ObjectCreationGrid - + + Create new: @@ -369,12 +369,12 @@ ObjectLists - + Hide all %1 - + Show all %1 @@ -382,27 +382,27 @@ ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -410,37 +410,37 @@ PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -448,7 +448,7 @@ Preferences - + Close @@ -456,110 +456,110 @@ Settings - - + + X Zoom - - + + Y Zoom - - + + Min X - - + + Max Y - + Max X - + Min Y - - + + X Axis Step - - + + Y Axis Step - - + + Line width - - + + Text size (px) - - + + X Label - - + + Y Label - - + + X Log scale - - + + Show X graduation - - + + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot @@ -567,96 +567,96 @@ ThanksTo - + Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - - + + + Github - + Norwegian - + Spanish - + Translations included - + Improve @@ -664,24 +664,24 @@ bodemagnitude - + Bode Magnitude - + Bode Magnitudes - - + + low-pass - - + + high-pass @@ -689,8 +689,8 @@ bodemagnitudesum - - + + Bode Magnitudes Sum @@ -698,12 +698,12 @@ bodephase - + Bode Phase - + Bode Phases @@ -711,8 +711,8 @@ bodephasesum - - + + Bode Phases Sum @@ -720,12 +720,12 @@ changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -733,8 +733,8 @@ color - - + + %1 %2's color changed from %3 to %4. @@ -742,27 +742,27 @@ comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + Note: Specify the probability for each value. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -770,11 +770,11 @@ control - - - - - + + + + + %1: @@ -782,8 +782,8 @@ create - - + + New %1 %2 created. @@ -791,8 +791,8 @@ delete - - + + %1 %2 deleted. @@ -800,12 +800,12 @@ distribution - + Repartition - + Repartition functions @@ -813,12 +813,12 @@ editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -826,32 +826,32 @@ error - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -859,7 +859,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -867,128 +867,128 @@ Undoing last change. - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + EOF - - + + Parse error [position %1]: %2 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + Unknown character "%1". - - + + Illegal escape sequence: %1. @@ -996,13 +996,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1010,27 +1010,27 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme @@ -1038,12 +1038,12 @@ Evaluated expression: %3 function - + Function - + Functions @@ -1051,17 +1051,17 @@ Evaluated expression: %3 general - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering @@ -1069,32 +1069,32 @@ Evaluated expression: %3 io - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - - Could not save file: + + Could not load file: - + Loaded file '%1'. @@ -1102,19 +1102,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1123,7 +1123,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1132,7 +1132,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1143,8 +1143,8 @@ Please make sure your latex installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. @@ -1152,114 +1152,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden @@ -1267,12 +1267,12 @@ Please make sure your latex installation is correct and report a bug if so. point - + Point - + Points @@ -1280,12 +1280,12 @@ Please make sure your latex installation is correct and report a bug if so. position - + Position of %1 %2 set from "%3" to "%4". - + Position of %1 set from %2 to %3. @@ -1293,158 +1293,158 @@ Please make sure your latex installation is correct and report a bug if so. prop - + expression - + definitionDomain - + destinationDomain - + displayMode - - - - - - - - - - + + + + + + + + + + labelPosition - - - - - - - + + + + + + + labelX - - + + drawPoints - - + + drawDashedLines - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit - - - + + + x - - + + y - + pointStyle - + probabilities - + defaultExpression - + baseValues - + text - + disableLatex - + targetElement - + approximate - + rounding - + displayStyle - + targetValuePosition @@ -1452,12 +1452,12 @@ Please make sure your latex installation is correct and report a bug if so. sequence - + Sequence - + Sequences @@ -1465,17 +1465,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1483,12 +1483,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text - + Texts @@ -1496,22 +1496,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. @@ -1519,38 +1519,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - - + + Usage: %1 - - - + + + Usage: %1 %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) @@ -1558,14 +1558,14 @@ Please make sure your latex installation is correct and report a bug if so. visibility - - + + %1 %2 shown. - - + + %1 %2 hidden. @@ -1573,12 +1573,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor - + X Cursors diff --git a/assets/i18n/update.sh b/assets/i18n/update.sh index 8d589d5..4ff172c 100755 --- a/assets/i18n/update.sh +++ b/assets/i18n/update.sh @@ -21,7 +21,7 @@ replace() { rm ../qml/eu/ad5001/LogarithmPlotter/js/index.mjs # Remove index which should not be scanned -files=$(find .. -name *.mjs) +files=$(find ../../common/src -name '*.mjs') for file in $files; do echo "Moving '$file' to '${file%.*}.js'..." mv "$file" "${file%.*}.js" @@ -38,7 +38,7 @@ done echo "----------------------------" echo "| Updating translations... |" echo "----------------------------" -lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts +lupdate -extensions js,qs,qml,py -recursive ../../common/src -recursive ../../runtime-pyside6/LogarithmPlotter -ts lp_*.ts # Updating locations in files for lp in *.ts; do echo "Replacing locations in $lp..." From 8c273f42204d828999ea3abdbe653fa8b940617f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 9 Oct 2024 18:18:24 +0000 Subject: [PATCH 162/249] Translated using Weblate (English) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- assets/i18n/lp_en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index 4429a36..ab62387 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -1330,7 +1330,7 @@ Evaluated expression: %3 Could not load file: - + Could not load file: Could not save file: From 6b3cce42522a7efdf2d67d1c38f3a9edcb7b173a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 9 Oct 2024 18:21:36 +0000 Subject: [PATCH 163/249] Translated using Weblate (German) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- assets/i18n/lp_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 4f29919..59980da 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -1330,7 +1330,7 @@ Ausdruck analysiert: %3 Could not load file: - + Datei konnte nicht geladen werden: Could not save file: From 40d86c8f823a7cdc69a52941d4bdb55f453cc913 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 9 Oct 2024 18:18:51 +0000 Subject: [PATCH 164/249] Translated using Weblate (French) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- assets/i18n/lp_fr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index 7df2b4f..a638be9 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -1345,7 +1345,7 @@ Formule analysée : %3 Could not load file: - + Impossible de charger le fichier : Could not save file: From b02ed87a29d0aac5a6c6c9656241fbc47ea64658 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 04:56:09 +0200 Subject: [PATCH 165/249] Updating package-lock --- common/package-lock.json | 1503 +++++++++++++++++++------------------- 1 file changed, 738 insertions(+), 765 deletions(-) diff --git a/common/package-lock.json b/common/package-lock.json index 0b60cac..b90e4f5 100644 --- a/common/package-lock.json +++ b/common/package-lock.json @@ -41,12 +41,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" }, "engines": { @@ -54,31 +54,31 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", + "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", + "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", "license": "MIT", "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -94,54 +94,54 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6", + "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz", + "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz", + "integrity": "sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -150,17 +150,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", - "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz", + "integrity": "sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.7", + "@babel/helper-member-expression-to-functions": "^7.25.7", + "@babel/helper-optimise-call-expression": "^7.25.7", + "@babel/helper-replace-supers": "^7.25.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7", + "@babel/traverse": "^7.25.7", "semver": "^6.3.1" }, "engines": { @@ -171,13 +171,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", - "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz", + "integrity": "sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.7", + "regexpu-core": "^6.1.1", "semver": "^6.3.1" }, "engines": { @@ -204,41 +204,41 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz", + "integrity": "sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -248,35 +248,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz", + "integrity": "sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", - "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz", + "integrity": "sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-wrap-function": "^7.25.0", - "@babel/traverse": "^7.25.0" + "@babel/helper-annotate-as-pure": "^7.25.7", + "@babel/helper-wrap-function": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -286,14 +286,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz", + "integrity": "sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==", "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-member-expression-to-functions": "^7.25.7", + "@babel/helper-optimise-call-expression": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -303,93 +303,93 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz", + "integrity": "sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", - "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz", + "integrity": "sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "license": "MIT", "peer": true, "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -399,12 +399,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", + "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.25.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -414,13 +414,13 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", - "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz", + "integrity": "sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.3" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -430,12 +430,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", - "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz", + "integrity": "sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -445,12 +445,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", - "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz", + "integrity": "sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -460,14 +460,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz", + "integrity": "sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7", + "@babel/plugin-transform-optional-chaining": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -477,13 +477,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", - "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz", + "integrity": "sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.0" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -568,12 +568,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", - "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz", + "integrity": "sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -583,12 +583,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", - "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz", + "integrity": "sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -740,12 +740,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz", + "integrity": "sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -755,15 +755,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", - "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.7.tgz", + "integrity": "sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-remap-async-to-generator": "^7.25.7", "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/traverse": "^7.25.4" + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -773,14 +773,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz", + "integrity": "sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-remap-async-to-generator": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -790,12 +790,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz", + "integrity": "sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -805,12 +805,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", - "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz", + "integrity": "sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -820,13 +820,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", - "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz", + "integrity": "sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -836,13 +836,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz", + "integrity": "sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -853,16 +853,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", - "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz", + "integrity": "sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-replace-supers": "^7.25.7", + "@babel/traverse": "^7.25.7", "globals": "^11.1.0" }, "engines": { @@ -873,13 +873,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz", + "integrity": "sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/template": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -889,12 +889,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", - "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz", + "integrity": "sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -904,13 +904,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz", + "integrity": "sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -920,12 +920,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz", + "integrity": "sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -935,13 +935,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", - "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz", + "integrity": "sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -951,12 +951,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz", + "integrity": "sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -967,13 +967,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz", + "integrity": "sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==", "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -983,12 +983,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz", + "integrity": "sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -999,13 +999,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz", + "integrity": "sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1015,14 +1015,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", - "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz", + "integrity": "sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.1" + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1032,12 +1032,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz", + "integrity": "sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1048,12 +1048,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", - "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz", + "integrity": "sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1063,12 +1063,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz", + "integrity": "sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1079,12 +1079,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz", + "integrity": "sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1094,13 +1094,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz", + "integrity": "sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1110,14 +1110,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz", + "integrity": "sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1127,15 +1127,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", - "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz", + "integrity": "sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1145,13 +1145,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz", + "integrity": "sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1161,13 +1161,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz", + "integrity": "sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1177,12 +1177,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz", + "integrity": "sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1192,12 +1192,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz", + "integrity": "sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1208,12 +1208,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz", + "integrity": "sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1224,15 +1224,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz", + "integrity": "sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/plugin-transform-parameters": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1242,13 +1242,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz", + "integrity": "sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-replace-supers": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1258,12 +1258,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz", + "integrity": "sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1274,13 +1274,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", - "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz", + "integrity": "sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1291,12 +1291,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz", + "integrity": "sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1306,13 +1306,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", - "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz", + "integrity": "sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1322,14 +1322,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz", + "integrity": "sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-annotate-as-pure": "^7.25.7", + "@babel/helper-create-class-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1340,12 +1340,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz", + "integrity": "sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1355,12 +1355,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz", + "integrity": "sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.7", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1371,12 +1371,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz", + "integrity": "sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1386,12 +1386,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz", + "integrity": "sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1401,13 +1401,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz", + "integrity": "sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1417,12 +1417,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz", + "integrity": "sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1432,12 +1432,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz", + "integrity": "sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1447,12 +1447,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", - "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz", + "integrity": "sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1462,12 +1462,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz", + "integrity": "sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1477,13 +1477,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz", + "integrity": "sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1493,13 +1493,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz", + "integrity": "sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1509,13 +1509,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", - "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz", + "integrity": "sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1525,28 +1525,28 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", - "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.7.tgz", + "integrity": "sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.4", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/compat-data": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-plugin-utils": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.7", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-assertions": "^7.25.7", + "@babel/plugin-syntax-import-attributes": "^7.25.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1558,60 +1558,60 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.4", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.25.4", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.25.4", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.8", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.25.1", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.25.2", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-modules-systemjs": "^7.25.0", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.8", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.25.4", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.8", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/plugin-transform-arrow-functions": "^7.25.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.7", + "@babel/plugin-transform-async-to-generator": "^7.25.7", + "@babel/plugin-transform-block-scoped-functions": "^7.25.7", + "@babel/plugin-transform-block-scoping": "^7.25.7", + "@babel/plugin-transform-class-properties": "^7.25.7", + "@babel/plugin-transform-class-static-block": "^7.25.7", + "@babel/plugin-transform-classes": "^7.25.7", + "@babel/plugin-transform-computed-properties": "^7.25.7", + "@babel/plugin-transform-destructuring": "^7.25.7", + "@babel/plugin-transform-dotall-regex": "^7.25.7", + "@babel/plugin-transform-duplicate-keys": "^7.25.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.7", + "@babel/plugin-transform-dynamic-import": "^7.25.7", + "@babel/plugin-transform-exponentiation-operator": "^7.25.7", + "@babel/plugin-transform-export-namespace-from": "^7.25.7", + "@babel/plugin-transform-for-of": "^7.25.7", + "@babel/plugin-transform-function-name": "^7.25.7", + "@babel/plugin-transform-json-strings": "^7.25.7", + "@babel/plugin-transform-literals": "^7.25.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.7", + "@babel/plugin-transform-member-expression-literals": "^7.25.7", + "@babel/plugin-transform-modules-amd": "^7.25.7", + "@babel/plugin-transform-modules-commonjs": "^7.25.7", + "@babel/plugin-transform-modules-systemjs": "^7.25.7", + "@babel/plugin-transform-modules-umd": "^7.25.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.7", + "@babel/plugin-transform-new-target": "^7.25.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.7", + "@babel/plugin-transform-numeric-separator": "^7.25.7", + "@babel/plugin-transform-object-rest-spread": "^7.25.7", + "@babel/plugin-transform-object-super": "^7.25.7", + "@babel/plugin-transform-optional-catch-binding": "^7.25.7", + "@babel/plugin-transform-optional-chaining": "^7.25.7", + "@babel/plugin-transform-parameters": "^7.25.7", + "@babel/plugin-transform-private-methods": "^7.25.7", + "@babel/plugin-transform-private-property-in-object": "^7.25.7", + "@babel/plugin-transform-property-literals": "^7.25.7", + "@babel/plugin-transform-regenerator": "^7.25.7", + "@babel/plugin-transform-reserved-words": "^7.25.7", + "@babel/plugin-transform-shorthand-properties": "^7.25.7", + "@babel/plugin-transform-spread": "^7.25.7", + "@babel/plugin-transform-sticky-regex": "^7.25.7", + "@babel/plugin-transform-template-literals": "^7.25.7", + "@babel/plugin-transform-typeof-symbol": "^7.25.7", + "@babel/plugin-transform-unicode-escapes": "^7.25.7", + "@babel/plugin-transform-unicode-property-regex": "^7.25.7", + "@babel/plugin-transform-unicode-regex": "^7.25.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.7", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.37.1", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -1635,16 +1635,10 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "license": "MIT" - }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1654,30 +1648,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1686,13 +1680,13 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", + "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1991,9 +1985,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], @@ -2004,9 +1998,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], @@ -2017,9 +2011,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], @@ -2030,9 +2024,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], @@ -2043,9 +2037,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], @@ -2056,9 +2050,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], @@ -2069,9 +2063,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], @@ -2082,9 +2076,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], @@ -2095,9 +2089,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], @@ -2108,9 +2102,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], @@ -2121,9 +2115,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], @@ -2134,9 +2128,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], @@ -2147,9 +2141,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], @@ -2160,9 +2154,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], @@ -2173,9 +2167,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], @@ -2186,9 +2180,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], @@ -2218,9 +2212,9 @@ "license": "MIT" }, "node_modules/@types/mocha": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", - "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", "dev": true, "license": "MIT" }, @@ -2393,9 +2387,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "funding": [ { "type": "opencollective", @@ -2412,8 +2406,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, @@ -2457,96 +2451,6 @@ } } }, - "node_modules/c8/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/c8/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/c8/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/c8/node_modules/test-exclude": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", - "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^9.0.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/c8/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/c8/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -2561,9 +2465,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001663", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", - "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", "funding": [ { "type": "opencollective", @@ -2660,15 +2564,17 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/color-convert": { @@ -2791,9 +2697,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.27", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", - "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "version": "1.5.34", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.34.tgz", + "integrity": "sha512-/TZAiChbAflBNjCg+VvstbcwAtIL/VdMFO3NgRFIzBjpvPzWOTIbbO8kNb6RwU4bt9TP7K+3KqBKw/lOU+Y+GA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -2846,9 +2752,9 @@ } }, "node_modules/fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.0.tgz", + "integrity": "sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==", "license": "MIT", "peerDependencies": { "picomatch": "^3 || ^4" @@ -2914,18 +2820,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2975,16 +2869,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -3230,33 +3114,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3340,15 +3197,15 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json5": { @@ -3479,14 +3336,11 @@ } }, "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -3506,6 +3360,33 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -3564,6 +3445,18 @@ "node": ">= 14.0.0" } }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3603,6 +3496,35 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3826,15 +3748,15 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", + "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.11.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -3842,26 +3764,24 @@ "node": ">=4" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.1.tgz", + "integrity": "sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==", "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3889,12 +3809,12 @@ } }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -3904,22 +3824,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -3954,12 +3874,6 @@ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "license": "MIT" }, - "node_modules/rollup/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "license": "MIT" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4021,6 +3935,18 @@ "node": ">=8" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/skip-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", @@ -4128,6 +4054,55 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -4191,9 +4166,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -4210,8 +4185,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -4380,32 +4355,30 @@ "license": "ISC" }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { From 934dd3ea1be6ab44d61e6df89399c37df35d5633 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 05:25:34 +0200 Subject: [PATCH 166/249] Adding private fields for Modules --- common/src/module/canvas.mjs | 145 +++++++++++++++--------------- common/src/module/common.mjs | 18 ++-- common/src/module/expreval.mjs | 14 +-- common/src/module/io.mjs | 84 +++++++++-------- common/src/module/latex.mjs | 10 ++- common/src/module/preferences.mjs | 3 + 6 files changed, 144 insertions(+), 130 deletions(-) diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index e623034..2aa14ad 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -25,23 +25,20 @@ import Objects from "./objects.mjs" import History from "./history.mjs" class CanvasAPI extends Module { + /** @type {CanvasInterface} */ + #canvas = null + /** @type {CanvasRenderingContext2D} */ + #ctx = null + /** @type {{show(string, string, string)}} */ + #drawingErrorDialog = null + + constructor() { super("Canvas", { canvas: CanvasInterface, drawingErrorDialog: DialogInterface }) - - /** @type {CanvasInterface} */ - this._canvas = null - - /** @type {CanvasRenderingContext2D} */ - this._ctx = null - - /** - * @type {{show(string, string, string)}} - * @private - */ - this._drawingErrorDialog = null + /** * * @type {Object.} @@ -67,18 +64,18 @@ class CanvasAPI extends Module { */ initialize({ canvas, drawingErrorDialog }) { super.initialize({ canvas, drawingErrorDialog }) - this._canvas = canvas - this._drawingErrorDialog = drawingErrorDialog + this.#canvas = canvas + this.#drawingErrorDialog = drawingErrorDialog } get width() { if(!this.initialized) throw new Error("Attempting width before initialize!") - return this._canvas.width + return this.#canvas.width } get height() { if(!this.initialized) throw new Error("Attempting height before initialize!") - return this._canvas.height + return this.#canvas.height } /** @@ -87,7 +84,7 @@ class CanvasAPI extends Module { */ get xmin() { if(!this.initialized) throw new Error("Attempting xmin before initialize!") - return this._canvas.xmin + return this.#canvas.xmin } /** @@ -96,7 +93,7 @@ class CanvasAPI extends Module { */ get xzoom() { if(!this.initialized) throw new Error("Attempting xzoom before initialize!") - return this._canvas.xzoom + return this.#canvas.xzoom } /** @@ -105,7 +102,7 @@ class CanvasAPI extends Module { */ get ymax() { if(!this.initialized) throw new Error("Attempting ymax before initialize!") - return this._canvas.ymax + return this.#canvas.ymax } /** @@ -114,7 +111,7 @@ class CanvasAPI extends Module { */ get yzoom() { if(!this.initialized) throw new Error("Attempting yzoom before initialize!") - return this._canvas.yzoom + return this.#canvas.yzoom } /** @@ -123,7 +120,7 @@ class CanvasAPI extends Module { */ get xlabel() { if(!this.initialized) throw new Error("Attempting xlabel before initialize!") - return this._canvas.xlabel + return this.#canvas.xlabel } /** @@ -132,7 +129,7 @@ class CanvasAPI extends Module { */ get ylabel() { if(!this.initialized) throw new Error("Attempting ylabel before initialize!") - return this._canvas.ylabel + return this.#canvas.ylabel } /** @@ -141,7 +138,7 @@ class CanvasAPI extends Module { */ get linewidth() { if(!this.initialized) throw new Error("Attempting linewidth before initialize!") - return this._canvas.linewidth + return this.#canvas.linewidth } /** @@ -150,7 +147,7 @@ class CanvasAPI extends Module { */ get textsize() { if(!this.initialized) throw new Error("Attempting textsize before initialize!") - return this._canvas.textsize + return this.#canvas.textsize } /** @@ -159,7 +156,7 @@ class CanvasAPI extends Module { */ get logscalex() { if(!this.initialized) throw new Error("Attempting logscalex before initialize!") - return this._canvas.logscalex + return this.#canvas.logscalex } /** @@ -168,7 +165,7 @@ class CanvasAPI extends Module { */ get showxgrad() { if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") - return this._canvas.showxgrad + return this.#canvas.showxgrad } /** @@ -177,7 +174,7 @@ class CanvasAPI extends Module { */ get showygrad() { if(!this.initialized) throw new Error("Attempting showygrad before initialize!") - return this._canvas.showygrad + return this.#canvas.showygrad } /** @@ -201,7 +198,7 @@ class CanvasAPI extends Module { requestPaint() { if(!this.initialized) throw new Error("Attempting requestPaint before initialize!") - this._canvas.requestPaint() + this.#canvas.requestPaint() } /** @@ -209,17 +206,17 @@ class CanvasAPI extends Module { */ redraw() { if(!this.initialized) throw new Error("Attempting redraw before initialize!") - this._ctx = this._canvas.getContext("2d") + this.#ctx = this.#canvas.getContext("2d") this._computeAxes() this._reset() this._drawGrid() this._drawAxes() this._drawLabels() - this._ctx.lineWidth = this.linewidth + this.#ctx.lineWidth = this.linewidth for(let objType in Objects.currentObjects) { for(let obj of Objects.currentObjects[objType]) { - this._ctx.strokeStyle = obj.color - this._ctx.fillStyle = obj.color + this.#ctx.strokeStyle = obj.color + this.#ctx.fillStyle = obj.color if(obj.visible) try { obj.draw(this) @@ -227,12 +224,12 @@ class CanvasAPI extends Module { // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) console.error(e) console.log(e.stack) - this._drawingErrorDialog.show(objType, obj.name, e.message) + this.#drawingErrorDialog.show(objType, obj.name, e.message) History.undo() } } } - this._ctx.lineWidth = 1 + this.#ctx.lineWidth = 1 } /** @@ -240,9 +237,9 @@ class CanvasAPI extends Module { * @private */ _computeAxes() { - let exprY = new Expression(`x*(${this._canvas.yaxisstep})`) + let exprY = new Expression(`x*(${this.#canvas.yaxisstep})`) let y1 = exprY.execute(1) - let exprX = new Expression(`x*(${this._canvas.xaxisstep})`) + let exprX = new Expression(`x*(${this.#canvas.xaxisstep})`) let x1 = exprX.execute(1) this.axesSteps = { x: { @@ -264,10 +261,10 @@ class CanvasAPI extends Module { */ _reset() { // Reset - this._ctx.fillStyle = "#FFFFFF" - this._ctx.strokeStyle = "#000000" - this._ctx.font = `${this.textsize}px sans-serif` - this._ctx.fillRect(0, 0, this.width, this.height) + this.#ctx.fillStyle = "#FFFFFF" + this.#ctx.strokeStyle = "#000000" + this.#ctx.font = `${this.textsize}px sans-serif` + this.#ctx.fillRect(0, 0, this.width, this.height) } /** @@ -275,7 +272,7 @@ class CanvasAPI extends Module { * @private */ _drawGrid() { - this._ctx.strokeStyle = "#C0C0C0" + this.#ctx.strokeStyle = "#C0C0C0" if(this.logscalex) { for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) { for(let xmulti = 1; xmulti < 10; xmulti++) { @@ -299,7 +296,7 @@ class CanvasAPI extends Module { * @private */ _drawAxes() { - this._ctx.strokeStyle = "#000000" + this.#ctx.strokeStyle = "#000000" let axisypos = this.logscalex ? 1 : 0 this.drawXLine(axisypos) this.drawYLine(0) @@ -320,19 +317,19 @@ class CanvasAPI extends Module { let axisypx = this.x2px(this.logscalex ? 1 : 0) // X coordinate of Y axis let axisxpx = this.y2px(0) // Y coordinate of X axis // Labels - this._ctx.fillStyle = "#000000" - this._ctx.font = `${this.textsize}px sans-serif` - this._ctx.fillText(this.ylabel, axisypx + 10, 24) - let textWidth = this._ctx.measureText(this.xlabel).width - this._ctx.fillText(this.xlabel, this.width - 14 - textWidth, axisxpx - 5) + this.#ctx.fillStyle = "#000000" + this.#ctx.font = `${this.textsize}px sans-serif` + this.#ctx.fillText(this.ylabel, axisypx + 10, 24) + let textWidth = this.#ctx.measureText(this.xlabel).width + this.#ctx.fillText(this.xlabel, this.width - 14 - textWidth, axisxpx - 5) // Axis graduation labels - this._ctx.font = `${this.textsize - 4}px sans-serif` + this.#ctx.font = `${this.textsize - 4}px sans-serif` - let txtMinus = this._ctx.measureText("-").width + let txtMinus = this.#ctx.measureText("-").width if(this.showxgrad) { if(this.logscalex) { for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow += 1) { - textWidth = this._ctx.measureText("10" + textsup(xpow)).width + textWidth = this.#ctx.measureText("10" + textsup(xpow)).width if(xpow !== 0) this.drawVisibleText("10" + textsup(xpow), this.x2px(Math.pow(10, xpow)) - textWidth / 2, axisxpx + 16 + (6 * (xpow === 1))) } @@ -350,13 +347,13 @@ class CanvasAPI extends Module { for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { let drawY = y * this.axesSteps.y.value let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, "$1") - textWidth = this._ctx.measureText(txtY).width + textWidth = this.#ctx.measureText(txtY).width this.drawVisibleText(txtY, axisypx - 6 - textWidth, this.y2px(drawY) + 4 + (10 * (y === 0))) if(y !== 0) this.drawVisibleText("-" + txtY, axisypx - 6 - textWidth - txtMinus, this.y2px(-drawY) + 4) } } - this._ctx.fillStyle = "#FFFFFF" + this.#ctx.fillStyle = "#FFFFFF" } // @@ -394,7 +391,7 @@ class CanvasAPI extends Module { drawVisibleText(text, x, y) { if(x > 0 && x < this.width && y > 0 && y < this.height) { text.toString().split("\n").forEach((txt, i) => { - this._ctx.fillText(txt, x, y + (this.textsize * i)) + this.#ctx.fillText(txt, x, y + (this.textsize * i)) }) } } @@ -409,8 +406,8 @@ class CanvasAPI extends Module { * @param {number} height */ drawVisibleImage(image, x, y, width, height) { - this._canvas.markDirty(Qt.rect(x, y, width, height)) - this._ctx.drawImage(image, x, y, width, height) + this.#canvas.markDirty(Qt.rect(x, y, width, height)) + this.#ctx.drawImage(image, x, y, width, height) } /** @@ -424,7 +421,7 @@ class CanvasAPI extends Module { let defaultHeight = this.textsize * 1.2 // Approximate but good enough! for(let txt of text.split("\n")) { theight += defaultHeight - if(this._ctx.measureText(txt).width > twidth) twidth = this._ctx.measureText(txt).width + if(this.#ctx.measureText(txt).width > twidth) twidth = this.#ctx.measureText(txt).width } return { "width": twidth, "height": theight } } @@ -494,10 +491,10 @@ class CanvasAPI extends Module { * @param {number} y2 */ drawLine(x1, y1, x2, y2) { - this._ctx.beginPath() - this._ctx.moveTo(x1, y1) - this._ctx.lineTo(x2, y2) - this._ctx.stroke() + this.#ctx.beginPath() + this.#ctx.moveTo(x1, y1) + this.#ctx.lineTo(x2, y2) + this.#ctx.stroke() } /** @@ -509,9 +506,9 @@ class CanvasAPI extends Module { * @param {number} dashPxSize */ drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) { - this._ctx.setLineDash([dashPxSize / 2, dashPxSize]) + this.#ctx.setLineDash([dashPxSize / 2, dashPxSize]) this.drawLine(x1, y1, x2, y2) - this._ctx.setLineDash([]) + this.#ctx.setLineDash([]) } /** @@ -522,10 +519,10 @@ class CanvasAPI extends Module { */ renderLatexImage(ltxText, color, callback) { const onRendered = (imgData) => { - if(!this._canvas.isImageLoaded(imgData.source) && !this._canvas.isImageLoading(imgData.source)) { + if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) { // Wait until the image is loaded to callback. - this._canvas.loadImage(imgData.source) - this._canvas.imageLoaders[imgData.source] = [callback, imgData] + this.#canvas.loadImage(imgData.source) + this.#canvas.imageLoaders[imgData.source] = [callback, imgData] } else { // Callback directly callback(imgData) @@ -543,11 +540,11 @@ class CanvasAPI extends Module { // get font() { - return this._ctx.font + return this.#ctx.font } set font(value) { - return this._ctx.font = value + return this.#ctx.font = value } /** @@ -560,9 +557,9 @@ class CanvasAPI extends Module { * @param {boolean} counterclockwise */ arc(x, y, radius, startAngle, endAngle, counterclockwise = false) { - this._ctx.beginPath() - this._ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) - this._ctx.stroke() + this.#ctx.beginPath() + this.#ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) + this.#ctx.stroke() } /** @@ -572,9 +569,9 @@ class CanvasAPI extends Module { * @param {number} radius */ disc(x, y, radius) { - this._ctx.beginPath() - this._ctx.arc(x, y, radius, 0, 2 * Math.PI) - this._ctx.fill() + this.#ctx.beginPath() + this.#ctx.arc(x, y, radius, 0, 2 * Math.PI) + this.#ctx.fill() } /** @@ -585,7 +582,7 @@ class CanvasAPI extends Module { * @param {number} h */ fillRect(x, y, w, h) { - this._ctx.fillRect(x, y, w, h) + this.#ctx.fillRect(x, y, w, h) } } diff --git a/common/src/module/common.mjs b/common/src/module/common.mjs index b757f14..5fc9387 100644 --- a/common/src/module/common.mjs +++ b/common/src/module/common.mjs @@ -25,6 +25,10 @@ globalThis.Modules = globalThis.Modules || {} * Base class for global APIs in runtime. */ export class Module { + /** @type {string} */ + #name + /** @type {Object.} */ + #initializationParameters /** * @@ -33,8 +37,8 @@ export class Module { */ constructor(name, initializationParameters = {}) { console.log(`Loading module ${name}...`) - this.__name = name - this.__initializationParameters = initializationParameters + this.#name = name + this.#initializationParameters = initializationParameters this.initialized = false } @@ -45,15 +49,15 @@ export class Module { */ initialize(options) { if(this.initialized) - throw new Error(`Cannot reinitialize module ${this.__name}.`) - console.log(`Initializing ${this.__name}...`) - for(const [name, value] of Object.entries(this.__initializationParameters)) { + throw new Error(`Cannot reinitialize module ${this.#name}.`) + console.log(`Initializing ${this.#name}...`) + for(const [name, value] of Object.entries(this.#initializationParameters)) { if(!options.hasOwnProperty(name)) - throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) + throw new Error(`Option '${name}' of initialize of module ${this.#name} does not exist.`) if(typeof value === "function" && value.prototype instanceof Interface) Interface.check_implementation(value, options[name]) else if(typeof value !== typeof options[name]) - throw new Error(`Option '${name}' of initialize of module ${this.__name} is not a '${value}' (${typeof options[name]}).`) + throw new Error(`Option '${name}' of initialize of module ${this.#name} is not a '${value}' (${typeof options[name]}).`) } this.initialized = true } diff --git a/common/src/module/expreval.mjs b/common/src/module/expreval.mjs index 854f928..964177c 100644 --- a/common/src/module/expreval.mjs +++ b/common/src/module/expreval.mjs @@ -35,15 +35,17 @@ const evalVariables = { } class ExprParserAPI extends Module { + #parser = new Parser() + constructor() { super("ExprParser") this.currentVars = {} - this._parser = new Parser() + this.#parser = new Parser() - this._parser.consts = Object.assign({}, this._parser.consts, evalVariables) + this.#parser.consts = Object.assign({}, this.#parser.consts, evalVariables) - this._parser.functions.integral = this.integral.bind(this) - this._parser.functions.derivative = this.derivative.bind(this) + this.#parser.functions.integral = this.integral.bind(this) + this.#parser.functions.derivative = this.derivative.bind(this) } /** @@ -68,7 +70,7 @@ class ExprParserAPI extends Module { [f, variable] = args if(typeof f !== "string" || typeof variable !== "string") throw EvalError(qsTranslate("usage", "Usage:\n%1").arg(usage2)) - f = this._parser.parse(f).toJSFunction(variable, this.currentVars) + f = this.#parser.parse(f).toJSFunction(variable, this.currentVars) } else throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) return f @@ -79,7 +81,7 @@ class ExprParserAPI extends Module { * @returns {ExprEvalExpression} */ parse(expression) { - return this._parser.parse(expression) + return this.#parser.parse(expression) } integral(a, b, ...args) { diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index b6d40f5..e32f2cf 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -24,6 +24,12 @@ import { DialogInterface, RootInterface, SettingsInterface } from "./interface.m class IOAPI extends Module { + /** @type {RootInterface} */ + #rootElement + /** @type {SettingsInterface} */ + #settings + /** @type {{show: function(string)}} */ + #alert constructor() { super("IO", { @@ -46,9 +52,9 @@ class IOAPI extends Module { */ initialize({ root, settings, alert }) { super.initialize({ root, settings, alert }) - this.rootElement = root - this.settings = settings - this.alert = alert + this.#rootElement = root + this.#settings = settings + this.#alert = alert } /** @@ -69,27 +75,27 @@ class IOAPI extends Module { } } let settings = { - "xzoom": this.settings.xzoom, - "yzoom": this.settings.yzoom, - "xmin": this.settings.xmin, - "ymax": this.settings.ymax, - "xaxisstep": this.settings.xaxisstep, - "yaxisstep": this.settings.yaxisstep, - "xaxislabel": this.settings.xlabel, - "yaxislabel": this.settings.ylabel, - "logscalex": this.settings.logscalex, - "linewidth": this.settings.linewidth, - "showxgrad": this.settings.showxgrad, - "showygrad": this.settings.showygrad, - "textsize": this.settings.textsize, + "xzoom": this.#settings.xzoom, + "yzoom": this.#settings.yzoom, + "xmin": this.#settings.xmin, + "ymax": this.#settings.ymax, + "xaxisstep": this.#settings.xaxisstep, + "yaxisstep": this.#settings.yaxisstep, + "xaxislabel": this.#settings.xlabel, + "yaxislabel": this.#settings.ylabel, + "logscalex": this.#settings.logscalex, + "linewidth": this.#settings.linewidth, + "showxgrad": this.#settings.showxgrad, + "showygrad": this.#settings.showygrad, + "textsize": this.#settings.textsize, "history": History.serialize(), - "width": this.rootElement.width, - "height": this.rootElement.height, + "width": this.#rootElement.width, + "height": this.#rootElement.height, "objects": objs, "type": "logplotv1" } Helper.write(filename, JSON.stringify(settings)) - this.alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) + this.#alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) History.history.saved = true } @@ -101,32 +107,32 @@ class IOAPI extends Module { if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!") if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!") let basename = filename.split("/").pop() - this.alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename)) + this.#alert.show(qsTranslate("io", "Loading file '%1'.").arg(basename)) let data = JSON.parse(Helper.load(filename)) let error = "" if(data.hasOwnProperty("type") && data["type"] === "logplotv1") { History.clear() // Importing settings - this.settings.saveFilename = filename - this.settings.xzoom = parseFloat(data["xzoom"]) || 100 - this.settings.yzoom = parseFloat(data["yzoom"]) || 10 - this.settings.xmin = parseFloat(data["xmin"]) || 5 / 10 - this.settings.ymax = parseFloat(data["ymax"]) || 24 - this.settings.xaxisstep = data["xaxisstep"] || "4" - this.settings.yaxisstep = data["yaxisstep"] || "4" - this.settings.xlabel = data["xaxislabel"] || "" - this.settings.ylabel = data["yaxislabel"] || "" - this.settings.logscalex = data["logscalex"] === true + this.#settings.saveFilename = filename + this.#settings.xzoom = parseFloat(data["xzoom"]) || 100 + this.#settings.yzoom = parseFloat(data["yzoom"]) || 10 + this.#settings.xmin = parseFloat(data["xmin"]) || 5 / 10 + this.#settings.ymax = parseFloat(data["ymax"]) || 24 + this.#settings.xaxisstep = data["xaxisstep"] || "4" + this.#settings.yaxisstep = data["yaxisstep"] || "4" + this.#settings.xlabel = data["xaxislabel"] || "" + this.#settings.ylabel = data["yaxislabel"] || "" + this.#settings.logscalex = data["logscalex"] === true if("showxgrad" in data) - this.settings.showxgrad = data["showxgrad"] + this.#settings.showxgrad = data["showxgrad"] if("showygrad" in data) - this.settings.textsize = data["showygrad"] + this.#settings.textsize = data["showygrad"] if("linewidth" in data) - this.settings.linewidth = data["linewidth"] + this.#settings.linewidth = data["linewidth"] if("textsize" in data) - this.settings.textsize = data["textsize"] - this.rootElement.height = parseFloat(data["height"]) || 500 - this.rootElement.width = parseFloat(data["width"]) || 1000 + this.#settings.textsize = data["textsize"] + this.#rootElement.height = parseFloat(data["height"]) || 500 + this.#rootElement.width = parseFloat(data["width"]) || 1000 // Importing objects Objects.currentObjects = {} @@ -158,18 +164,18 @@ class IOAPI extends Module { History.unserialize(...data["history"]) // Refreshing sidebar - this.rootElement.updateObjectsLists() + this.#rootElement.updateObjectsLists() } else { error = qsTranslate("io", "Invalid file provided.") } if(error !== "") { console.log(error) - this.alert.show(qsTranslate("io", "Could not load file: ") + error) + this.#alert.show(qsTranslate("io", "Could not load file: ") + error) // TODO: Error handling return } Canvas.redraw() - this.alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) + this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) History.history.saved = true } diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 8740160..8fabee4 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -60,6 +60,9 @@ class LatexRenderResult { } class LatexAPI extends Module { + /** @type {LatexInterface} */ + #latex = null + constructor() { super("Latex", { latex: LatexInterface, @@ -77,8 +80,7 @@ class LatexAPI extends Module { */ initialize({ latex, helper }) { super.initialize({ latex, helper }) - this.latex = latex - this.helper = helper + this.#latex = latex this.enabled = helper.getSettingBool("enable_latex") } @@ -93,7 +95,7 @@ class LatexAPI extends Module { */ findPrerendered(markup, fontSize, color) { if(!this.initialized) throw new Error("Attempting findPrerendered before initialize!") - const data = this.latex.findPrerendered(markup, fontSize, color) + const data = this.#latex.findPrerendered(markup, fontSize, color) let ret = null if(data !== "") ret = new LatexRenderResult(...data.split(",")) @@ -110,7 +112,7 @@ class LatexAPI extends Module { */ async requestAsyncRender(markup, fontSize, color) { if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") - let args = this.latex.render(markup, fontSize, color).split(",") + let args = this.#latex.render(markup, fontSize, color).split(",") return new LatexRenderResult(...args) } diff --git a/common/src/module/preferences.mjs b/common/src/module/preferences.mjs index afb795e..dea8677 100644 --- a/common/src/module/preferences.mjs +++ b/common/src/module/preferences.mjs @@ -20,6 +20,9 @@ import General from "../preferences/general.mjs" import Editor from "../preferences/expression.mjs" import DefaultGraph from "../preferences/default.mjs" +/** + * Module for application wide settings. + */ class PreferencesAPI extends Module { constructor() { super("Preferences") From 9663c335631ef0fa6eb4599aa3a48c94dc02c0b6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 05:33:01 +0200 Subject: [PATCH 167/249] Improving MJS lupdate hacky script to take private fields into account. --- assets/i18n/lp_de.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_en.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_es.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_fr.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_hu.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_nb_NO.ts | 36 ++++++++++++++++++------------------ assets/i18n/lp_template.ts | 36 ++++++++++++++++++------------------ assets/i18n/update.sh | 6 +++++- 8 files changed, 131 insertions(+), 127 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 59980da..4876e02 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -1308,27 +1308,27 @@ Ausdruck analysiert: %3 Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not load file: Datei konnte nicht geladen werden: @@ -1337,7 +1337,7 @@ Ausdruck analysiert: %3 Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. @@ -1759,17 +1759,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde settingCategory - + default Standardeinstellungen - + general Allgemeine - + editor Ausdruckseditor @@ -1827,22 +1827,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: Funktionsähnliches Objekt>) - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 %2 @@ -1851,17 +1851,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: Funktionsähnliches Objekt>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index ab62387..b2dfaff 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -1308,27 +1308,27 @@ Evaluated expression: %3 History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not load file: Could not load file: @@ -1337,7 +1337,7 @@ Evaluated expression: %3 Could not save file: - + Loaded file '%1'. Loaded file '%1'. @@ -1759,17 +1759,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory - + general General - + editor Expression Editor - + default Default settings @@ -1827,22 +1827,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: Function-like object>) - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 %2 @@ -1851,17 +1851,17 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: Function-like object>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index f5e3d12..14dd724 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -1320,27 +1320,27 @@ Expresión evaluada: %3 Objetos - + Saved plot to '%1'. Gráfico guardado en '%1'. - + Loading file '%1'. Cargando el archivo '%1'. - + Unknown object type: %1. Tipo de objeto desconocido: %1 . - + Invalid file provided. Se ha proporcionado un archivo no válido. - + Could not load file: @@ -1349,7 +1349,7 @@ Expresión evaluada: %3 No se ha podido guardar el archivo: - + Loaded file '%1'. Archivo cargado '%1'. @@ -1759,17 +1759,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u settingCategory - + general General - + editor Editor de expresiones - + default Ajustes por defecto @@ -1827,22 +1827,22 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<desde: número>, <hasta: número>, <f: Objeto similar a una función>) - - + + Usage: %1 Uso: %1 - - - + + + Usage: %1 %2 @@ -1851,17 +1851,17 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<desde: número>, <hasta: número>, <f: cadena>, <variable: cadena>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: objeto similar a una función>, <x: número>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: cadena>, <variable: cadena>, <x: número>) diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index a638be9..2b1a26d 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -1323,27 +1323,27 @@ Formule analysée : %3 &Mettre à jour LogarithmPlotter - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not load file: Impossible de charger le fichier : @@ -1352,7 +1352,7 @@ Formule analysée : %3 Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. @@ -1762,17 +1762,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c settingCategory - + general Général - + editor Éditeur de formule - + default Paramètres par défaut @@ -1830,22 +1830,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet fonction>) - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 %2 @@ -1854,17 +1854,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet fonction>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index f817dd2..975c600 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -1304,27 +1304,27 @@ Kiértékelt kifejezés: %3 Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not load file: @@ -1333,7 +1333,7 @@ Kiértékelt kifejezés: %3 A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. @@ -1759,17 +1759,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory - + general Általános - + editor Kifejezésszerkesztő - + default Alapértelmezett ábra @@ -1827,22 +1827,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<alsó korlát: szám>, <felső korlát: szám>, <f: függvényszerű objektum>) - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 %2 @@ -1851,17 +1851,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: függvényszerű objektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) diff --git a/assets/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts index b46ffe7..d278f03 100644 --- a/assets/i18n/lp_nb_NO.ts +++ b/assets/i18n/lp_nb_NO.ts @@ -1235,27 +1235,27 @@ Evaluated expression: %3 Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not load file: @@ -1264,7 +1264,7 @@ Evaluated expression: %3 Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». @@ -1669,17 +1669,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1737,38 +1737,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - - + + Usage: %1 - - - + + + Usage: %1 %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/assets/i18n/lp_template.ts b/assets/i18n/lp_template.ts index 9440730..0981f1b 100644 --- a/assets/i18n/lp_template.ts +++ b/assets/i18n/lp_template.ts @@ -1069,32 +1069,32 @@ Evaluated expression: %3 io - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not load file: - + Loaded file '%1'. @@ -1465,17 +1465,17 @@ Please make sure your latex installation is correct and report a bug if so. settingCategory - + general - + editor - + default @@ -1519,38 +1519,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - - + + Usage: %1 - - - + + + Usage: %1 %2 - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/assets/i18n/update.sh b/assets/i18n/update.sh index 4ff172c..ff96ef8 100755 --- a/assets/i18n/update.sh +++ b/assets/i18n/update.sh @@ -33,6 +33,8 @@ for file in $files; do replace "${file%.*}.js" "^export" "/*export*/" replace "${file%.*}.js" "async " "/*async */" replace "${file%.*}.js" "await" "/*await */" + replace "${file%.*}.js" " #" "// #" + replace "${file%.*}.js" "this.#" "/*this.#*/" done echo "----------------------------" @@ -55,7 +57,9 @@ for file in $files; do replace "$file" "/*async */" "async " replace "$file" "^/*export*/" "export" replace "$file" "^/*export default*/" "export default" + replace "$file" '.mjs"*/' '.mjs"' replace "$file" "^/*import" "import" replace "$file" "^/*export" "export" - replace "$file" '.mjs"*/$' '.mjs"' + replace "$file" "// #" " #" + replace "$file" "/*this.#*/" "this.#" done From bd346240bdbd9feaf0cabda43b39b23f1a8ebc9d Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Wed, 9 Oct 2024 18:30:49 +0000 Subject: [PATCH 168/249] Translated using Weblate (Spanish) Currently translated at 100.0% (269 of 269 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- assets/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index 14dd724..ef79648 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -1342,7 +1342,7 @@ Expresión evaluada: %3 Could not load file: - + No se pudo cargar el archivo: Could not save file: From af2950c3d21b6f12ddab60d4bde74875a0e9519a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 06:49:14 +0200 Subject: [PATCH 169/249] Starting Settings modules + implemented basic events for ECMAScript <=> Qt compat. --- common/src/events.mjs | 96 ++++++++++++++++++ common/src/lib/polyfills/js.mjs | 4 +- common/src/module/common.mjs | 4 +- common/src/module/interface.mjs | 4 +- common/src/module/settings.mjs | 173 ++++++++++++++++++++++++++++++++ 5 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 common/src/events.mjs create mode 100644 common/src/module/settings.mjs diff --git a/common/src/events.mjs b/common/src/events.mjs new file mode 100644 index 0000000..f1ec970 --- /dev/null +++ b/common/src/events.mjs @@ -0,0 +1,96 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * We do not inherit the DOM's Event, because not only the DOM part is unnecessary, + * but also because it does not exist within Qt environments. + */ + + +export class BaseEvent { + /** + * @property {string} name - Name of the event. + */ + constructor(name) { + this.name = name + } +} + + +/** + * Base class for all classes which can emit events. + */ +export class BaseEventEmitter { + static emits = [] + + /** @type {Record} */ + #listeners = {} + + constructor() { + for(const eventType of this.constructor.emits) { + this.#listeners[eventType] = new Set() + } + } + + /** + * Adds a listener to an event that can be emitted by this object. + * + * @param {string} eventType - Name of the event to listen to. Throws an error if this object does not emit this kind of event. + * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. + */ + addEventListener(eventType, eventListener) { + if(!this.emits.includes(eventType)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + } + if(!this.#listeners[eventType].has(eventListener)) + this.#listeners[eventType].add(eventListener) + } + + /** + * Remvoes a listener from an event that can be emitted by this object. + * + * @param {string} eventType - Name of the event that was listened to. Throws an error if this object does not emit this kind of event. + * @param {function(BaseEvent)} eventListener - The function previously registered as a listener. + * @returns {boolean} True if the listener was removed, false if it was not found. + */ + removeEventListener(eventType, eventListener) { + if(!this.emits.includes(eventType)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + } + return this.#listeners[eventType].delete(eventListener) + + } + + /** + * Emits an event to all of its listeners. + * + * @param {BaseEvent} e + */ + emit(e) { + if(!(e instanceof BaseEvent)) + throw new Error("Cannot emit non event object.") + if(!this.emits.includes(e.name)) + throw new Error(`Cannot emit event '${e.name}' from class ${this.constructor.name}. ${this.constructor.name} can only emits: ${this.constructor.emits.join(", ")}.`) + for(const listener of this.#listeners[e.name]) + listener(e) + } +} diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs index 43ed375..9bcf80c 100644 --- a/common/src/lib/polyfills/js.mjs +++ b/common/src/lib/polyfills/js.mjs @@ -1,4 +1,4 @@ -/** +/*! * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 * @@ -123,4 +123,4 @@ for(const [year, entries] of Object.entries(polyfills)) { for(const [context, functionName, polyfill] of entries.filter(x => x[0][x[1]] === undefined)) { context[functionName] = polyfill } -} \ No newline at end of file +} diff --git a/common/src/module/common.mjs b/common/src/module/common.mjs index 5fc9387..bdca62f 100644 --- a/common/src/module/common.mjs +++ b/common/src/module/common.mjs @@ -17,6 +17,7 @@ */ import { Interface } from "./interface.mjs" +import { BaseEventEmitter } from "../events.mjs" // Define Modules interface before they are imported. globalThis.Modules = globalThis.Modules || {} @@ -24,7 +25,7 @@ globalThis.Modules = globalThis.Modules || {} /** * Base class for global APIs in runtime. */ -export class Module { +export class Module extends BaseEventEmitter { /** @type {string} */ #name /** @type {Object.} */ @@ -36,6 +37,7 @@ export class Module { * @param {Object.} initializationParameters - List of parameters for the initialize function. */ constructor(name, initializationParameters = {}) { + super() console.log(`Loading module ${name}...`) this.#name = name this.#initializationParameters = initializationParameters diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index 9273c8f..f6e5a13 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -1,4 +1,4 @@ -/*! +/** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * * @author Ad5001 @@ -184,4 +184,4 @@ export class HelperInterface extends Interface { * @returns {string} the loaded data - just JSON encoded, requires the "LPFv1" mime to be stripped */ load = FUNCTION -} \ No newline at end of file +} diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs new file mode 100644 index 0000000..4487dde --- /dev/null +++ b/common/src/module/settings.mjs @@ -0,0 +1,173 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { Module } from "./common.mjs" +import { BaseEvent } from "../events.mjs" + + +/** + * Base event for when a setting was changed. + */ +class ChangedEvent extends BaseEvent { + /** + * + * @param {string} property - Name of the property that was chagned + * @param {string|number|boolean} oldValue - Old value of the property + * @param {string|number|boolean} newValue - Current (new) value of the property + * @param {boolean} byUser - True if the user is at the source of the change in the setting. + */ + constructor(property, oldValue, newValue, byUser) { + super("changed") + + this.property = property + this.oldValue = oldValue + this.newValue = newValue + this.byUser = byUser + } +} + +/** + * Module for graph settings. + */ +class SettingsAPI extends Module { + static emits = ["changed"] + + #properties = new Map([ + ['xzoom', 100], + ['yzoom', 10], + ['xmin', .5], + ['ymax', 25], + ['xaxisstep', "4"], + ['yaxisstep', "4"], + ['xlabel', ""], + ['ylabel', ""], + ['linewidth', 1], + ['textsize', 18], + ['logscalex', true], + ['showxgrad', true], + ['showygrad', true], + ]) + + constructor() { + super("Settings", { + helper: HelperInterface + }) + } + + initialize({ helper }) { + super.initialize({ helper }) + // Initialize default values. + for(const key of this.#properties.keys()) { + switch(typeof this.#properties.get(key)) { + case 'boolean': + this.set(key, helper.getSettingBool(key), false) + break + case 'number': + this.set(key, helper.getSettingInt(key), false) + break + case 'string': + this.set(key, helper.getSetting(key), false) + break + } + } + } + + /** + * Sets a setting to a given value + * + * @param {boolean} byUser - Set to true if the user is at the origin of this change. + */ + set(property, value, byUser) { + if(!this.#properties.has(property)) + throw new Error(`Property ${property} is not a setting.`) + const oldValue = this.#properties.get(property) + const propType = typeof oldValue + if(propType !== typeof value) + throw new Error(`Value of ${property} must be a ${propType}.`) + this.#properties.set(property, value) + this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) + } + + /** + * Zoom on the x axis of the diagram. + * @returns {number} + */ + get xzoom() { return this.#properties.get("xzoom"); } + /** + * Zoom on the y axis of the diagram. + * @returns {number} + */ + get yzoom() { return this.#properties.get("yzoom"); } + /** + * Minimum x of the diagram. + * @returns {number} + */ + get xmin() { return this.#properties.get("xmin"); } + /** + * Maximum y of the diagram. + * @returns {number} + */ + get ymax() { return this.#properties.get("ymax"); } + /** + * Step of the x axis graduation (expression). + * @note Only available in non-logarithmic mode. + * @returns {string} + */ + get xaxisstep() { return this.#properties.get("xaxisstep"); } + /** + * Step of the y axis graduation (expression). + * @returns {string} + */ + get yaxisstep() { return this.#properties.get("yaxisstep"); } + /** + * Label used on the x axis. + * @returns {string} + */ + get xlabel() { return this.#properties.get("xlabel"); } + /** + * Label used on the y axis. + * @returns {string} + */ + get ylabel() { return this.#properties.get("ylabel"); } + /** + * Width of lines that will be drawn into the canvas. + * @returns {number} + */ + get linewidth() { return this.#properties.get("linewidth"); } + /** + * Font size of the text that will be drawn into the canvas. + * @returns {number} + */ + get textsize() { return this.#properties.get("textsize"); } + /** + * true if the canvas should be in logarithmic mode, false otherwise. + * @returns {boolean} + */ + get logscalex() { return this.#properties.get("logscalex"); } + /** + * true if the x graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showxgrad() { return this.#properties.get("showxgrad"); } + /** + * true if the y graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showygrad() { return this.#properties.get("showygrad"); } + +} From d1ac70a946700b2193e67f2617f151722dcbfb0c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 19:15:46 +0200 Subject: [PATCH 170/249] Switching a lot of stuff to new Settings module + Fixing a bug that did not load the showygrad setting properly. --- common/src/events.mjs | 13 ++- common/src/module/canvas.mjs | 27 +++--- common/src/module/index.mjs | 2 + common/src/module/interface.mjs | 2 +- common/src/module/io.mjs | 66 +++++++------ common/src/module/settings.mjs | 83 +++++++++-------- common/src/utils.mjs | 13 +++ .../LogarithmPlotter/LogGraphCanvas.qml | 93 +------------------ .../LogarithmPlotter/LogarithmPlotter.qml | 14 --- .../Setting/ExpressionEditor.qml | 16 ++-- .../ViewPositionChangeOverlay.qml | 48 +++++----- 11 files changed, 148 insertions(+), 229 deletions(-) diff --git a/common/src/events.mjs b/common/src/events.mjs index f1ec970..bed4dea 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -38,7 +38,7 @@ export class BaseEvent { export class BaseEventEmitter { static emits = [] - /** @type {Record} */ + /** @type {Record>} */ #listeners = {} constructor() { @@ -54,7 +54,7 @@ export class BaseEventEmitter { * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. */ addEventListener(eventType, eventListener) { - if(!this.emits.includes(eventType)) { + if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) @@ -71,7 +71,7 @@ export class BaseEventEmitter { * @returns {boolean} True if the listener was removed, false if it was not found. */ removeEventListener(eventType, eventListener) { - if(!this.emits.includes(eventType)) { + if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) @@ -88,8 +88,11 @@ export class BaseEventEmitter { emit(e) { if(!(e instanceof BaseEvent)) throw new Error("Cannot emit non event object.") - if(!this.emits.includes(e.name)) - throw new Error(`Cannot emit event '${e.name}' from class ${this.constructor.name}. ${this.constructor.name} can only emits: ${this.constructor.emits.join(", ")}.`) + if(!this.constructor.emits.includes(e.name)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot emit event '${e.name}' from class ${className}. ${className} can only emit: ${eventTypes}`) + } for(const listener of this.#listeners[e.name]) listener(e) } diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 2aa14ad..5d42f5e 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -23,6 +23,7 @@ import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" +import Settings from "./settings.mjs" class CanvasAPI extends Module { /** @type {CanvasInterface} */ @@ -84,7 +85,7 @@ class CanvasAPI extends Module { */ get xmin() { if(!this.initialized) throw new Error("Attempting xmin before initialize!") - return this.#canvas.xmin + return Settings.xmin } /** @@ -93,7 +94,7 @@ class CanvasAPI extends Module { */ get xzoom() { if(!this.initialized) throw new Error("Attempting xzoom before initialize!") - return this.#canvas.xzoom + return Settings.xzoom } /** @@ -102,7 +103,7 @@ class CanvasAPI extends Module { */ get ymax() { if(!this.initialized) throw new Error("Attempting ymax before initialize!") - return this.#canvas.ymax + return Settings.ymax } /** @@ -111,7 +112,7 @@ class CanvasAPI extends Module { */ get yzoom() { if(!this.initialized) throw new Error("Attempting yzoom before initialize!") - return this.#canvas.yzoom + return Settings.yzoom } /** @@ -120,7 +121,7 @@ class CanvasAPI extends Module { */ get xlabel() { if(!this.initialized) throw new Error("Attempting xlabel before initialize!") - return this.#canvas.xlabel + return Settings.xlabel } /** @@ -129,7 +130,7 @@ class CanvasAPI extends Module { */ get ylabel() { if(!this.initialized) throw new Error("Attempting ylabel before initialize!") - return this.#canvas.ylabel + return Settings.ylabel } /** @@ -138,7 +139,7 @@ class CanvasAPI extends Module { */ get linewidth() { if(!this.initialized) throw new Error("Attempting linewidth before initialize!") - return this.#canvas.linewidth + return Settings.linewidth } /** @@ -147,7 +148,7 @@ class CanvasAPI extends Module { */ get textsize() { if(!this.initialized) throw new Error("Attempting textsize before initialize!") - return this.#canvas.textsize + return Settings.textsize } /** @@ -156,7 +157,7 @@ class CanvasAPI extends Module { */ get logscalex() { if(!this.initialized) throw new Error("Attempting logscalex before initialize!") - return this.#canvas.logscalex + return Settings.logscalex } /** @@ -165,7 +166,7 @@ class CanvasAPI extends Module { */ get showxgrad() { if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") - return this.#canvas.showxgrad + return Settings.showxgrad } /** @@ -174,7 +175,7 @@ class CanvasAPI extends Module { */ get showygrad() { if(!this.initialized) throw new Error("Attempting showygrad before initialize!") - return this.#canvas.showygrad + return Settings.showygrad } /** @@ -237,9 +238,9 @@ class CanvasAPI extends Module { * @private */ _computeAxes() { - let exprY = new Expression(`x*(${this.#canvas.yaxisstep})`) + let exprY = new Expression(`x*(${Settings.yaxisstep})`) let y1 = exprY.execute(1) - let exprX = new Expression(`x*(${this.#canvas.xaxisstep})`) + let exprX = new Expression(`x*(${Settings.xaxisstep})`) let x1 = exprX.execute(1) this.axesSteps = { x: { diff --git a/common/src/module/index.mjs b/common/src/module/index.mjs index fe2e8d9..2530a00 100644 --- a/common/src/module/index.mjs +++ b/common/src/module/index.mjs @@ -17,6 +17,7 @@ */ import Objects from "./objects.mjs" +import Settings from "./settings.mjs" import ExprParser from "./expreval.mjs" import Latex from "./latex.mjs" import History from "./history.mjs" @@ -26,6 +27,7 @@ import Preferences from "./preferences.mjs" export default { Objects, + Settings, ExprParser, Latex, History, diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index f6e5a13..606ec4d 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -78,7 +78,7 @@ export class SettingsInterface extends Interface { showygrad = BOOLEAN } -export class CanvasInterface extends SettingsInterface { +export class CanvasInterface extends Interface { imageLoaders = OBJECT /** @type {function(string): CanvasRenderingContext2D} */ getContext = FUNCTION diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index e32f2cf..183ae01 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -20,22 +20,20 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" +import Settings from "./settings.mjs" import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs" class IOAPI extends Module { /** @type {RootInterface} */ #rootElement - /** @type {SettingsInterface} */ - #settings /** @type {{show: function(string)}} */ #alert constructor() { super("IO", { alert: DialogInterface, - root: RootInterface, - settings: SettingsInterface + root: RootInterface }) /** * Path of the currently opened file. Empty if no file is opened. @@ -47,13 +45,11 @@ class IOAPI extends Module { /** * Initializes module with QML elements. * @param {RootInterface} root - * @param {SettingsInterface} settings * @param {{show: function(string)}} alert */ - initialize({ root, settings, alert }) { - super.initialize({ root, settings, alert }) + initialize({ root, alert }) { + super.initialize({ root, alert }) this.#rootElement = root - this.#settings = settings this.#alert = alert } @@ -75,19 +71,19 @@ class IOAPI extends Module { } } let settings = { - "xzoom": this.#settings.xzoom, - "yzoom": this.#settings.yzoom, - "xmin": this.#settings.xmin, - "ymax": this.#settings.ymax, - "xaxisstep": this.#settings.xaxisstep, - "yaxisstep": this.#settings.yaxisstep, - "xaxislabel": this.#settings.xlabel, - "yaxislabel": this.#settings.ylabel, - "logscalex": this.#settings.logscalex, - "linewidth": this.#settings.linewidth, - "showxgrad": this.#settings.showxgrad, - "showygrad": this.#settings.showygrad, - "textsize": this.#settings.textsize, + "xzoom": Settings.xzoom, + "yzoom": Settings.yzoom, + "xmin": Settings.xmin, + "ymax": Settings.ymax, + "xaxisstep": Settings.xaxisstep, + "yaxisstep": Settings.yaxisstep, + "xaxislabel": Settings.xlabel, + "yaxislabel": Settings.ylabel, + "logscalex": Settings.logscalex, + "linewidth": Settings.linewidth, + "showxgrad": Settings.showxgrad, + "showygrad": Settings.showygrad, + "textsize": Settings.textsize, "history": History.serialize(), "width": this.#rootElement.width, "height": this.#rootElement.height, @@ -113,24 +109,24 @@ class IOAPI extends Module { if(data.hasOwnProperty("type") && data["type"] === "logplotv1") { History.clear() // Importing settings - this.#settings.saveFilename = filename - this.#settings.xzoom = parseFloat(data["xzoom"]) || 100 - this.#settings.yzoom = parseFloat(data["yzoom"]) || 10 - this.#settings.xmin = parseFloat(data["xmin"]) || 5 / 10 - this.#settings.ymax = parseFloat(data["ymax"]) || 24 - this.#settings.xaxisstep = data["xaxisstep"] || "4" - this.#settings.yaxisstep = data["yaxisstep"] || "4" - this.#settings.xlabel = data["xaxislabel"] || "" - this.#settings.ylabel = data["yaxislabel"] || "" - this.#settings.logscalex = data["logscalex"] === true + Settings.set("saveFilename", filename, false) + Settings.set("xzoom", parseFloat(data["xzoom"]) || 100, false) + Settings.set("yzoom", parseFloat(data["yzoom"]) || 10, false) + Settings.set("xmin", parseFloat(data["xmin"]) || 5 / 10, false) + Settings.set("ymax", parseFloat(data["ymax"]) || 24, false) + Settings.set("xaxisstep", data["xaxisstep"] || "4", false) + Settings.set("yaxisstep", data["yaxisstep"] || "4", false) + Settings.set("xlabel", data["xaxislabel"] || "", false) + Settings.set("ylabel", data["yaxislabel"] || "", false) + Settings.set("logscalex", data["logscalex"] === true, false) if("showxgrad" in data) - this.#settings.showxgrad = data["showxgrad"] + Settings.set("showxgrad", data["showxgrad"], false) if("showygrad" in data) - this.#settings.textsize = data["showygrad"] + Settings.set("showygrad", data["showygrad"], false) if("linewidth" in data) - this.#settings.linewidth = data["linewidth"] + Settings.set("linewidth", data["linewidth"], false) if("textsize" in data) - this.#settings.textsize = data["textsize"] + Settings.set("textsize", data["textsize"], false) this.#rootElement.height = parseFloat(data["height"]) || 500 this.#rootElement.width = parseFloat(data["width"]) || 1000 diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 4487dde..4d79ce2 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -18,6 +18,7 @@ import { Module } from "./common.mjs" import { BaseEvent } from "../events.mjs" +import { HelperInterface } from "./interface.mjs" /** @@ -48,19 +49,20 @@ class SettingsAPI extends Module { static emits = ["changed"] #properties = new Map([ - ['xzoom', 100], - ['yzoom', 10], - ['xmin', .5], - ['ymax', 25], - ['xaxisstep', "4"], - ['yaxisstep', "4"], - ['xlabel', ""], - ['ylabel', ""], - ['linewidth', 1], - ['textsize', 18], - ['logscalex', true], - ['showxgrad', true], - ['showygrad', true], + ["saveFilename", ""], + ["xzoom", 100], + ["yzoom", 10], + ["xmin", .5], + ["ymax", 25], + ["xaxisstep", "4"], + ["yaxisstep", "4"], + ["xlabel", ""], + ["ylabel", ""], + ["linewidth", 1], + ["textsize", 18], + ["logscalex", true], + ["showxgrad", true], + ["showygrad", true] ]) constructor() { @@ -74,14 +76,14 @@ class SettingsAPI extends Module { // Initialize default values. for(const key of this.#properties.keys()) { switch(typeof this.#properties.get(key)) { - case 'boolean': - this.set(key, helper.getSettingBool(key), false) + case "boolean": + this.set(key, helper.getSettingBool("default_graph."+key), false) break - case 'number': - this.set(key, helper.getSettingInt(key), false) + case "number": + this.set(key, helper.getSettingInt("default_graph."+key), false) break - case 'string': - this.set(key, helper.getSetting(key), false) + case "string": + this.set(key, helper.getSetting("default_graph."+key), false) break } } @@ -89,16 +91,20 @@ class SettingsAPI extends Module { /** * Sets a setting to a given value - * - * @param {boolean} byUser - Set to true if the user is at the origin of this change. + * + * @param {string} property + * @param {string|number|boolean} value + * @param {boolean} byUser - Set to true if the user is at the origin of this change. */ set(property, value, byUser) { - if(!this.#properties.has(property)) + if(!this.#properties.has(property)) { throw new Error(`Property ${property} is not a setting.`) + } const oldValue = this.#properties.get(property) + console.debug("Setting", property, "from", oldValue, "to", value, `(${typeof value}, ${byUser})`) const propType = typeof oldValue if(propType !== typeof value) - throw new Error(`Value of ${property} must be a ${propType}.`) + throw new Error(`Value of ${property} must be a ${propType} (${typeof value} provided).`) this.#properties.set(property, value) this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) } @@ -107,67 +113,70 @@ class SettingsAPI extends Module { * Zoom on the x axis of the diagram. * @returns {number} */ - get xzoom() { return this.#properties.get("xzoom"); } + get xzoom() { return this.#properties.get("xzoom") } /** * Zoom on the y axis of the diagram. * @returns {number} */ - get yzoom() { return this.#properties.get("yzoom"); } + get yzoom() { return this.#properties.get("yzoom") } /** * Minimum x of the diagram. * @returns {number} */ - get xmin() { return this.#properties.get("xmin"); } + get xmin() { return this.#properties.get("xmin") } /** * Maximum y of the diagram. * @returns {number} */ - get ymax() { return this.#properties.get("ymax"); } + get ymax() { return this.#properties.get("ymax") } /** * Step of the x axis graduation (expression). * @note Only available in non-logarithmic mode. * @returns {string} */ - get xaxisstep() { return this.#properties.get("xaxisstep"); } + get xaxisstep() { return this.#properties.get("xaxisstep") } /** * Step of the y axis graduation (expression). * @returns {string} */ - get yaxisstep() { return this.#properties.get("yaxisstep"); } + get yaxisstep() { return this.#properties.get("yaxisstep") } /** * Label used on the x axis. * @returns {string} */ - get xlabel() { return this.#properties.get("xlabel"); } + get xlabel() { return this.#properties.get("xlabel") } /** * Label used on the y axis. * @returns {string} */ - get ylabel() { return this.#properties.get("ylabel"); } + get ylabel() { return this.#properties.get("ylabel") } /** * Width of lines that will be drawn into the canvas. * @returns {number} */ - get linewidth() { return this.#properties.get("linewidth"); } + get linewidth() { return this.#properties.get("linewidth") } /** * Font size of the text that will be drawn into the canvas. * @returns {number} */ - get textsize() { return this.#properties.get("textsize"); } + get textsize() { return this.#properties.get("textsize") } /** * true if the canvas should be in logarithmic mode, false otherwise. * @returns {boolean} */ - get logscalex() { return this.#properties.get("logscalex"); } + get logscalex() { return this.#properties.get("logscalex") } /** * true if the x graduation should be shown, false otherwise. * @returns {boolean} */ - get showxgrad() { return this.#properties.get("showxgrad"); } + get showxgrad() { return this.#properties.get("showxgrad") } /** * true if the y graduation should be shown, false otherwise. * @returns {boolean} */ - get showygrad() { return this.#properties.get("showygrad"); } - + get showygrad() { return this.#properties.get("showygrad") } } + +Modules.Settings = Modules.Settings || new SettingsAPI() +export default Modules.Settings + diff --git a/common/src/utils.mjs b/common/src/utils.mjs index 4f6b0c5..094147d 100644 --- a/common/src/utils.mjs +++ b/common/src/utils.mjs @@ -35,6 +35,19 @@ String.prototype.removeEnclosure = function() { return this.substring(1, this.length - 1) } +/** + * Rounds to a certain number of decimal places. + * From https://stackoverflow.com/a/48764436 + * + * @param {number} decimalPlaces + * @return {number} + */ +Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) { + const p = Math.pow(10, decimalPlaces); + const n = (this * p) * (1 + Number.EPSILON); + return Math.round(n) / p; +} + const powerpos = { "-": "⁻", "+": "⁺", diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 38d05be..07b6002 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -30,104 +30,15 @@ import Qt.labs.platform as Native */ Canvas { id: canvas - anchors.top: separator.bottom + anchors.top: parent.top anchors.left: parent.left height: parent.height - 90 width: parent.width - - /*! - \qmlproperty double LogGraphCanvas::xmin - Minimum x of the diagram, provided from settings. - \sa Settings - */ - property double xmin: 0 - /*! - \qmlproperty double LogGraphCanvas::ymax - Maximum y of the diagram, provided from settings. - \sa Settings - */ - property double ymax: 0 - /*! - \qmlproperty double LogGraphCanvas::xzoom - Zoom on the x axis of the diagram, provided from settings. - \sa Settings - */ - property double xzoom: 10 - /*! - \qmlproperty double LogGraphCanvas::yzoom - Zoom on the y axis of the diagram, provided from settings. - \sa Settings - */ - property double yzoom: 10 - /*! - \qmlproperty string LogGraphCanvas::xaxisstep - Step of the x axis graduation, provided from settings. - \note: Only available in non-logarithmic mode. - \sa Settings - */ - property string xaxisstep: "4" - /*! - \qmlproperty string LogGraphCanvas::yaxisstep - Step of the y axis graduation, provided from settings. - \sa Settings - */ - property string yaxisstep: "4" - /*! - \qmlproperty string LogGraphCanvas::xlabel - Label used on the x axis, provided from settings. - \sa Settings - */ - property string xlabel: "" - /*! - \qmlproperty string LogGraphCanvas::ylabel - Label used on the y axis, provided from settings. - \sa Settings - */ - property string ylabel: "" - /*! - \qmlproperty double LogGraphCanvas::linewidth - Width of lines that will be drawn into the canvas, provided from settings. - \sa Settings - */ - property double linewidth: 1 - /*! - \qmlproperty double LogGraphCanvas::textsize - Font size of the text that will be drawn into the canvas, provided from settings. - \sa Settings - */ - property double textsize: 14 - /*! - \qmlproperty bool LogGraphCanvas::logscalex - true if the canvas should be in logarithmic mode, false otherwise. - Provided from settings. - \sa Settings - */ - property bool logscalex: false - /*! - \qmlproperty bool LogGraphCanvas::showxgrad - true if the x graduation should be shown, false otherwise. - Provided from settings. - \sa Settings - */ - property bool showxgrad: false - /*! - \qmlproperty bool LogGraphCanvas::showygrad - true if the y graduation should be shown, false otherwise. - Provided from settings. - \sa Settings - */ - property bool showygrad: false - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. */ property var imageLoaders: {} - /*! - \qmlproperty var LogGraphCanvas::ctx - Cache for the 2D context so that it may be used asynchronously. - */ - property var ctx Component.onCompleted: { imageLoaders = {} @@ -155,7 +66,7 @@ Canvas { Object.keys(imageLoaders).forEach((key) => { if(isImageLoaded(key)) { // Calling callback - imageLoaders[key][0](canvas, ctx, imageLoaders[key][1]) + imageLoaders[key][0](imageLoaders[key][1]) delete imageLoaders[key] } }) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 8545153..d6b2c3f 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -145,20 +145,6 @@ ApplicationWindow { width: sidebar.inPortrait ? parent.width : parent.width - sidebar.width//*sidebar.position x: sidebar.width//*sidebar.position - xmin: settings.xmin - ymax: settings.ymax - xzoom: settings.xzoom - yzoom: settings.yzoom - xlabel: settings.xlabel - ylabel: settings.ylabel - yaxisstep: settings.yaxisstep - xaxisstep: settings.xaxisstep - logscalex: settings.logscalex - linewidth: settings.linewidth - textsize: settings.textsize - showxgrad: settings.showxgrad - showygrad: settings.showygrad - property bool firstDrawDone: false onPainted: if(!firstDrawDone) { diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index afa3e09..a0c030a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -175,17 +175,17 @@ Item { Icon { id: iconLabel anchors.top: parent.top - anchors.topMargin: icon == "" ? 0 : 3 - source: control.visible && icon != "" ? "../icons/" + control.icon : "" + anchors.topMargin: parent.icon == "" ? 0 : 3 + source: control.visible && parent.icon != "" ? "../icons/" + control.icon : "" width: height - height: icon == "" || !visible ? 0 : 24 + height: parent.icon == "" || !visible ? 0 : 24 color: sysPalette.windowText } Label { id: labelItem anchors.left: iconLabel.right - anchors.leftMargin: icon == "" ? 0 : 5 + anchors.leftMargin: parent.icon == "" ? 0 : 5 anchors.top: parent.top height: parent.height width: Math.max(85, implicitWidth) @@ -231,8 +231,8 @@ Item { onEditingFinished: { if(insertButton.focus || insertPopup.focus) return let value = text - if(value != "" && value.toString() != defValue) { - let expr = parse(value) + if(value != "" && value.toString() != parent.defValue) { + let expr = parent.parse(value) if(expr != null) { control.changed(expr) defValue = expr.toEditableString() @@ -280,10 +280,10 @@ Item { acPopupContent.itemSelected = 0 - if(event.text in openAndCloseMatches && autoClosing) { + if(event.text in parent.openAndCloseMatches && autoClosing) { let start = selectionStart insert(selectionStart, event.text) - insert(selectionEnd, openAndCloseMatches[event.text]) + insert(selectionEnd, parent.openAndCloseMatches[event.text]) cursorPosition = start+1 event.accepted = true } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index e8514d4..7a7072b 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -17,8 +17,6 @@ */ import QtQuick -import QtQuick.Controls -import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! \qmltype ViewPositionChangeOverlay @@ -81,7 +79,7 @@ Item { property int prevY /*! \qmlproperty double ViewPositionChangeOverlay::baseZoomMultiplier - How much should the zoom be mutliplied/scrolled by for one scroll step (120° on the mouse wheel). + How much should the zoom be multiplied/scrolled by for one scroll step (120° on the mouse wheel). */ property double baseZoomMultiplier: 0.1 @@ -91,15 +89,15 @@ Item { cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor property int positionChangeTimer: 0 - function updatePosition(deltaX, deltaY) { + function updatePosition(deltaX, deltaY, isEnd) { const unauthorized = [NaN, Infinity, -Infinity] - const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) - const ymax = settingsInstance.ymax + deltaY/canvas.yzoom + const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(Modules.Settings.xmin)-deltaX)) + const ymax = Modules.Settings.ymax + deltaY/Modules.Settings.yzoom if(!unauthorized.includes(xmin)) - settingsInstance.xmin = xmin + Modules.Settings.set("xmin", xmin, isEnd) if(!unauthorized.includes(ymax)) - settingsInstance.ymax = ymax.toFixed(4) - settingsInstance.changed() + Modules.Settings.set("ymax", ymax.toDecimalPrecision(6), isEnd) + Modules.Canvas.requestPaint() parent.positionChanged(deltaX, deltaY) } @@ -113,9 +111,9 @@ Item { onPositionChanged: function(mouse) { positionChangeTimer++ if(positionChangeTimer == 3) { - let deltaX = mouse.x - prevX - let deltaY = mouse.y - prevY - updatePosition(deltaX, deltaY) + let deltaX = mouse.x - parent.prevX + let deltaY = mouse.y - parent.prevY + updatePosition(deltaX, deltaY, false) prevX = mouse.x prevY = mouse.y positionChangeTimer = 0 @@ -123,35 +121,35 @@ Item { } onReleased: function(mouse) { - let deltaX = mouse.x - prevX - let deltaY = mouse.y - prevY - updatePosition(deltaX, deltaY) + let deltaX = mouse.x - parent.prevX + let deltaY = mouse.y - parent.prevY + updatePosition(deltaX, deltaY, true) parent.endPositionChange(deltaX, deltaY) } onWheel: function(wheel) { // Scrolling let scrollSteps = Math.round(wheel.angleDelta.y / 120) - let zoomMultiplier = Math.pow(1+baseZoomMultiplier, Math.abs(scrollSteps)) + let zoomMultiplier = Math.pow(1+parent.baseZoomMultiplier, Math.abs(scrollSteps)) // Avoid floating-point rounding errors by removing the zoom *after* - let xZoomDelta = (settingsInstance.xzoom*zoomMultiplier - settingsInstance.xzoom) - let yZoomDelta = (settingsInstance.yzoom*zoomMultiplier - settingsInstance.yzoom) + let xZoomDelta = (Modules.Settings.xzoom*zoomMultiplier - Modules.Settings.xzoom) + let yZoomDelta = (Modules.Settings.yzoom*zoomMultiplier - Modules.Settings.yzoom) if(scrollSteps < 0) { // Negative scroll xZoomDelta *= -1 yZoomDelta *= -1 } - let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) - let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) + let newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(0) + let newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(0) // Check if we need to have more precision if(newXZoom < 10) - newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) + newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(4) if(newYZoom < 10) - newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) + newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(4) if(newXZoom > 0.5) - settingsInstance.xzoom = newXZoom + Modules.Settings.set("xzoom", newXZoom) if(newYZoom > 0.5) - settingsInstance.yzoom = newYZoom - settingsInstance.changed() + Modules.Settings.set("yzoom", newYZoom) + Modules.Canvas.requestPaint() } } } From 52f859349ac9b1ac6d3e26e8b2a1c795b069958f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 23:28:25 +0200 Subject: [PATCH 171/249] Converting actual settings to new Settings module. --- common/src/events.mjs | 5 +- common/src/module/io.mjs | 2 +- common/src/module/settings.mjs | 27 ++- common/src/preferences/default.mjs | 2 +- .../LogarithmPlotter/LogarithmPlotter.qml | 9 +- .../LogarithmPlotter/PickLocationOverlay.qml | 2 +- .../LogarithmPlotter/Setting/TextSetting.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 202 +++++++++++++----- 8 files changed, 176 insertions(+), 75 deletions(-) diff --git a/common/src/events.mjs b/common/src/events.mjs index bed4dea..4e95db6 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -53,7 +53,7 @@ export class BaseEventEmitter { * @param {string} eventType - Name of the event to listen to. Throws an error if this object does not emit this kind of event. * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. */ - addEventListener(eventType, eventListener) { + on(eventType, eventListener) { if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") @@ -70,14 +70,13 @@ export class BaseEventEmitter { * @param {function(BaseEvent)} eventListener - The function previously registered as a listener. * @returns {boolean} True if the listener was removed, false if it was not found. */ - removeEventListener(eventType, eventListener) { + off(eventType, eventListener) { if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) } return this.#listeners[eventType].delete(eventListener) - } /** diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 183ae01..0b4c6fa 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -62,7 +62,7 @@ class IOAPI extends Module { // Add extension if necessary if(["lpf"].indexOf(filename.split(".")[filename.split(".").length - 1]) === -1) filename += ".lpf" - this.saveFilename = filename + Settings.set("saveFilename", filename, false) let objs = {} for(let objType in Objects.currentObjects) { objs[objType] = [] diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 4d79ce2..44a6593 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -48,6 +48,8 @@ class ChangedEvent extends BaseEvent { class SettingsAPI extends Module { static emits = ["changed"] + #nonConfigurable = ["saveFilename"] + #properties = new Map([ ["saveFilename", ""], ["xzoom", 100], @@ -75,16 +77,18 @@ class SettingsAPI extends Module { super.initialize({ helper }) // Initialize default values. for(const key of this.#properties.keys()) { - switch(typeof this.#properties.get(key)) { - case "boolean": - this.set(key, helper.getSettingBool("default_graph."+key), false) - break - case "number": - this.set(key, helper.getSettingInt("default_graph."+key), false) - break - case "string": - this.set(key, helper.getSetting("default_graph."+key), false) - break + if(!this.#nonConfigurable.includes(key)) { + switch(typeof this.#properties.get(key)) { + case "boolean": + this.set(key, helper.getSettingBool("default_graph."+key), false) + break + case "number": + this.set(key, helper.getSettingInt("default_graph."+key), false) + break + case "string": + this.set(key, helper.getSetting("default_graph."+key), false) + break + } } } } @@ -101,8 +105,9 @@ class SettingsAPI extends Module { throw new Error(`Property ${property} is not a setting.`) } const oldValue = this.#properties.get(property) - console.debug("Setting", property, "from", oldValue, "to", value, `(${typeof value}, ${byUser})`) const propType = typeof oldValue + if(byUser) + console.debug("Setting", property, "from", oldValue, "to", value, `(${typeof value}, ${byUser})`) if(propType !== typeof value) throw new Error(`Value of ${property} must be a ${propType} (${typeof value} provided).`) this.#properties.set(property, value) diff --git a/common/src/preferences/default.mjs b/common/src/preferences/default.mjs index 0fa9531..20d62e3 100644 --- a/common/src/preferences/default.mjs +++ b/common/src/preferences/default.mjs @@ -28,7 +28,7 @@ const XZOOM = new NumberSetting( const YZOOM = new NumberSetting( qsTranslate("Settings", "Y Zoom"), - "default_graph.xzoom", + "default_graph.yzoom", "yzoom", 0.1 ) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index d6b2c3f..51abb46 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -42,7 +42,7 @@ ApplicationWindow { width: 1000 height: 500 color: sysPalette.window - title: "LogarithmPlotter " + (settings.saveFilename != "" ? " - " + settings.saveFilename.split('/').pop() : "") + (history.saved ? "" : "*") + title: "LogarithmPlotter" SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } @@ -250,5 +250,12 @@ ApplicationWindow { Component.onCompleted: { Modules.IO.initialize({ root, settings, alert }) Modules.Latex.initialize({ latex: Latex, helper: Helper }) + Modules.Settings.on("changed", (evt) => { + if(evt.property === "saveFilename") { + const fileName = evt.newValue.split('/').pop().split('\\').pop() + if(fileName !== "") + title = `${fileName}` + } + }) } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 2fb45d4..680c310 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -285,7 +285,7 @@ Item { const axisX = Modules.Canvas.axesSteps.x.value const xpos = Modules.Canvas.px2x(picker.mouseX) if(snapToGridCheckbox.checked) { - if(canvas.logscalex) { + if(Modules.Settings.logscalex) { // Calculate the logged power let pow = Math.pow(10, Math.floor(Math.log10(xpos))) return pow*Math.round(xpos/pow) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index b0a054a..3689dc1 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -37,7 +37,7 @@ Item { Emitted when the value of the text has been changed. The corresponding handler is \c onChanged. */ - signal changed(string newValue) + signal changed(var newValue) /*! \qmlproperty bool TextSetting::isInt diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 534556f..b440d07 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -121,11 +121,6 @@ ScrollView { \sa Settings */ property bool showygrad: Helper.getSettingBool('default_graph.showygrad') - /*! - \qmlproperty bool Settings::saveFilename - Path of the currently opened file. Empty if no file is opened. - */ - property string saveFilename: "" Column { spacing: 10 @@ -136,15 +131,18 @@ ScrollView { id: fdiag onAccepted: { var filePath = fdiag.currentFile.toString().substr(7) - settings.saveFilename = filePath + Modules.Settings.set("saveFilename", filePath) if(exportMode) { Modules.IO.saveDiagram(filePath) } else { Modules.IO.loadDiagram(filePath) - if(xAxisLabel.find(settings.xlabel) == -1) xAxisLabel.model.append({text: settings.xlabel}) - xAxisLabel.editText = settings.xlabel - if(yAxisLabel.find(settings.ylabel) == -1) yAxisLabel.model.append({text: settings.ylabel}) - yAxisLabel.editText = settings.ylabel + // Adding labels. + if(xAxisLabel.find(Modules.Settings.xlabel) === -1) + xAxisLabel.model.append({text: Modules.Settings.xlabel}) + xAxisLabel.editText = Modules.Settings.xlabel + if(yAxisLabel.find(Modules.Settings.ylabel) === -1) + yAxisLabel.model.append({text: Modules.Settings.ylabel}) + yAxisLabel.editText = Modules.Settings.ylabel } } } @@ -158,11 +156,16 @@ ScrollView { min: 0.1 icon: "settings/xzoom.svg" width: settings.settingWidth - value: settings.xzoom.toFixed(2) + onChanged: function(newValue) { - settings.xzoom = newValue + Modules.Settings.set("xzoom", newValue, true) settings.changed() } + + function update(newValue) { + value = Modules.Settings.xzoom.toFixed(2) + maxX.update() + } } Setting.TextSetting { @@ -173,11 +176,16 @@ ScrollView { label: qsTr("Y Zoom") icon: "settings/yzoom.svg" width: settings.settingWidth - value: settings.yzoom.toFixed(2) + onChanged: function(newValue) { - settings.yzoom = newValue + Modules.Settings.set("yzoom", newValue, true) settings.changed() } + + function update(newValue) { + value = Modules.Settings.yzoom.toFixed(2) + minY.update() + } } // Positioning the graph @@ -189,14 +197,18 @@ ScrollView { label: qsTr("Min X") icon: "settings/xmin.svg" width: settings.settingWidth - defValue: settings.xmin + onChanged: function(newValue) { - if(parseFloat(maxX.value) > newValue) { - settings.xmin = newValue - settings.changed() - } else { - alert.show("Minimum x value must be inferior to maximum.") - } + Modules.Settings.set("xmin", newValue, true) + settings.changed() + } + + function update(newValue) { + let newVal = Modules.Settings.xmin + if(newVal > 1e-5) + newVal = newVal.toDecimalPrecision(8) + value = newVal + maxX.update() } } @@ -208,11 +220,16 @@ ScrollView { label: qsTr("Max Y") icon: "settings/ymax.svg" width: settings.settingWidth - defValue: settings.ymax + onChanged: function(newValue) { - settings.ymax = newValue + Modules.Settings.set("ymax", newValue, true) settings.changed() } + + function update() { + value = Modules.Settings.ymax + minY.update() + } } Setting.TextSetting { @@ -223,15 +240,24 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - defValue: Modules.Canvas.px2x(canvas.width).toFixed(2) + onChanged: function(xvaluemax) { - if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + if(xvaluemax > Modules.Settings.xmin) { + const newXZoom = Modules.Settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + Modules.Settings.set("xzoom", newXZoom, true) + zoomX.update() settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") } } + + function update() { + let newVal = Modules.Canvas.px2x(canvas.width) + if(newVal > 1e-5) + newVal = newVal.toDecimalPrecision(8) + value = newVal + } } Setting.TextSetting { @@ -242,15 +268,21 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) + onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + const newYZoom = Modules.Settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + Modules.Settings.set("yzoom", newYZoom, true) + zoomY.update() settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") } } + + function update() { + value = Modules.Canvas.px2y(canvas.height).toDecimalPrecision(8) + } } Setting.TextSetting { @@ -260,12 +292,16 @@ ScrollView { label: qsTr("X Axis Step") icon: "settings/xaxisstep.svg" width: settings.settingWidth - defValue: settings.xaxisstep - visible: !settings.logscalex + onChanged: function(newValue) { - settings.xaxisstep = newValue + Modules.Settings.set("xaxisstep", newValue, true) settings.changed() } + + function update() { + value = Modules.Settings.xaxisstep + visible = !Modules.Settings.logscalex + } } Setting.TextSetting { @@ -275,11 +311,13 @@ ScrollView { label: qsTr("Y Axis Step") icon: "settings/yaxisstep.svg" width: settings.settingWidth - defValue: settings.yaxisstep + onChanged: function(newValue) { - settings.yaxisstep = newValue + Modules.Settings.set("yaxisstep", newValue, true) settings.changed() } + + function update() { value = Modules.Settings.yaxisstep } } Setting.TextSetting { @@ -290,11 +328,13 @@ ScrollView { min: 1 icon: "settings/linewidth.svg" width: settings.settingWidth - defValue: settings.linewidth + onChanged: function(newValue) { - settings.linewidth = newValue + Modules.Settings.set("linewidth", newValue, true) settings.changed() } + + function update() { value = Modules.Settings.linewidth } } Setting.TextSetting { @@ -305,11 +345,13 @@ ScrollView { min: 1 icon: "settings/textsize.svg" width: settings.settingWidth - defValue: settings.textsize + onChanged: function(newValue) { - settings.textsize = newValue + Modules.Settings.set("textsize", newValue, true) settings.changed() } + + function update() { value = Modules.Settings.textsize } } Setting.ComboBoxSetting { @@ -318,24 +360,31 @@ ScrollView { width: settings.settingWidth label: qsTr('X Label') icon: "settings/xlabel.svg" + editable: true model: ListModel { ListElement { text: "" } ListElement { text: "x" } ListElement { text: "ω (rad/s)" } } - currentIndex: find(settings.xlabel) - editable: true + onAccepted: function(){ editText = JS.Utils.parseName(editText, false) - if (find(editText) === -1) model.append({text: editText}) - settings.xlabel = editText + if(find(editText) === -1) model.append({text: editText}) + currentIndex = find(editText) + Modules.Settings.set("xlabel", editText, true) settings.changed() } + onActivated: function(selectedId) { - settings.xlabel = model.get(selectedId).text + Modules.Settings.set("xlabel", model.get(selectedId).text, true) settings.changed() } - Component.onCompleted: editText = settings.xlabel + + function update() { + editText = Modules.Settings.xlabel + if(find(editText) === -1) model.append({text: editText}) + currentIndex = find(editText) + } } Setting.ComboBoxSetting { @@ -344,6 +393,7 @@ ScrollView { width: settings.settingWidth label: qsTr('Y Label') icon: "settings/ylabel.svg" + editable: true model: ListModel { ListElement { text: "" } ListElement { text: "y" } @@ -352,39 +402,52 @@ ScrollView { ListElement { text: "φ (deg)" } ListElement { text: "φ (rad)" } } - currentIndex: find(settings.ylabel) - editable: true + onAccepted: function(){ editText = JS.Utils.parseName(editText, false) - if (find(editText) === -1) model.append({text: editText, yaxisstep: root.yaxisstep}) - settings.ylabel = editText + if(find(editText) === -1) model.append({text: editText}) + currentIndex = find(editText) + Modules.Settings.set("ylabel", editText, true) settings.changed() } + onActivated: function(selectedId) { - settings.ylabel = model.get(selectedId).text + Modules.Settings.set("ylabel", model.get(selectedId).text, true) settings.changed() } - Component.onCompleted: editText = settings.ylabel + + function update() { + editText = Modules.Settings.ylabel + if(find(editText) === -1) model.append({text: editText}) + currentIndex = find(editText) + } } CheckBox { id: logScaleX - checked: settings.logscalex text: qsTr('X Log scale') onClicked: { - settings.logscalex = checked + Modules.Settings.set("logscalex", checked, true) + if(Modules.Settings.xmin <= 0) // Reset xmin to prevent crash. + Modules.Settings.set("xmin", .5) settings.changed() } + + function update() { + checked = Modules.Settings.logscalex + xAxisStep.update() + } } CheckBox { id: showXGrad - checked: settings.showxgrad text: qsTr('Show X graduation') onClicked: { - settings.showxgrad = checked + Modules.Settings.set("showxgrad", checked, true) settings.changed() } + + function update() { checked = Modules.Settings.showxgrad } } CheckBox { @@ -392,9 +455,10 @@ ScrollView { checked: settings.showygrad text: qsTr('Show Y graduation') onClicked: { - settings.showygrad = checked + Modules.Settings.set("showygrad", checked, true) settings.changed() } + function update() { checked = Modules.Settings.showygrad } } Button { @@ -440,10 +504,10 @@ ScrollView { Saves the current canvas in the opened file. If no file is currently opened, prompts to pick a save location. */ function save() { - if(settings.saveFilename == "") { + if(Modules.Settings.saveFilename == "") { saveAs() } else { - Modules.IO.saveDiagram(settings.saveFilename) + Modules.IO.saveDiagram(Modules.Settings.saveFilename) } } @@ -464,4 +528,30 @@ ScrollView { fdiag.exportMode = false fdiag.open() } + + /** + * Initializing the settings + */ + Component.onCompleted: function() { + const matchedElements = new Map([ + ["xzoom", zoomX], + ["yzoom", zoomY], + ["xmin", minX], + ["ymax", maxY], + ["xaxisstep", xAxisStep], + ["yaxisstep", yAxisStep], + ["xlabel", xAxisLabel], + ["ylabel", yAxisLabel], + ["linewidth", lineWidth], + ["textsize", textSize], + ["logscalex", logScaleX], + ["showxgrad", showXGrad], + ["showygrad", showYGrad] + ]) + Modules.Settings.on("changed", (evt) => { + if(matchedElements.has(evt.property)) + matchedElements.get(evt.property).update() + }) + Modules.Settings.initialize({ helper: Helper }) + } } From 54363b25bccb1696182dabe00ec3c03b10363a09 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 10 Oct 2024 23:56:42 +0200 Subject: [PATCH 172/249] Fixing issue with Replace All when replacement string includes source string. --- common/src/lib/polyfills/js.mjs | 5 +---- common/src/module/latex.mjs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs index 9bcf80c..b412716 100644 --- a/common/src/lib/polyfills/js.mjs +++ b/common/src/lib/polyfills/js.mjs @@ -64,10 +64,7 @@ function arrayFlatMap(callbackFn, thisArg) { * @return {String} */ function stringReplaceAll(from, to) { - let str = this - while(str.includes(from)) - str = str.replace(from, to) - return str + return this.split(from).join(to) } diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 8fabee4..a0e8401 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -261,7 +261,7 @@ class LatexAPI extends Module { throw new EvalError("Unknown operator " + item.value + ".") } break - case Instruction.IOP3: // Thirdiary operator + case Instruction.IOP3: // Ternary operator n3 = nstack.pop() n2 = nstack.pop() n1 = nstack.pop() From 2dc9234b228bf23c2ccfbad987d51d91ca99aad3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 01:14:52 +0200 Subject: [PATCH 173/249] Decoupled History from QML --- common/src/events.mjs | 36 ++++-- common/src/lib/polyfills/js.mjs | 17 ++- common/src/module/history.mjs | 117 +++++++++++++++-- common/src/module/interface.mjs | 18 --- common/src/module/io.mjs | 2 +- common/src/module/settings.mjs | 6 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 6 +- .../LogarithmPlotter/History/History.qml | 122 +----------------- .../History/HistoryBrowser.qml | 89 +++++++++++-- .../LogarithmPlotter/History/HistoryItem.qml | 17 +-- 10 files changed, 239 insertions(+), 191 deletions(-) diff --git a/common/src/events.mjs b/common/src/events.mjs index 4e95db6..fbc8228 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -54,29 +54,41 @@ export class BaseEventEmitter { * @param {function(BaseEvent)} eventListener - The function to be called back when the event is emitted. */ on(eventType, eventListener) { - if(!this.constructor.emits.includes(eventType)) { - const className = this.constructor.name - const eventTypes = this.constructor.emits.join(", ") - throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + if(eventType.includes(" ")) // Listen to several different events with the same listener. + for(const type of eventType.split(" ")) + this.on(type, eventListener) + else { + console.log("Listening to", eventType) + if(!this.constructor.emits.includes(eventType)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + } + if(!this.#listeners[eventType].has(eventListener)) + this.#listeners[eventType].add(eventListener) } - if(!this.#listeners[eventType].has(eventListener)) - this.#listeners[eventType].add(eventListener) } /** - * Remvoes a listener from an event that can be emitted by this object. + * Removes a listener from an event that can be emitted by this object. * * @param {string} eventType - Name of the event that was listened to. Throws an error if this object does not emit this kind of event. * @param {function(BaseEvent)} eventListener - The function previously registered as a listener. * @returns {boolean} True if the listener was removed, false if it was not found. */ off(eventType, eventListener) { - if(!this.constructor.emits.includes(eventType)) { - const className = this.constructor.name - const eventTypes = this.constructor.emits.join(", ") - throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + if(eventType.includes(" ")) { // Unlisten to several different events with the same listener. + let found = false + for(const type of eventType.split(" ")) + found ||= this.off(eventType, eventListener) + } else { + if(!this.constructor.emits.includes(eventType)) { + const className = this.constructor.name + const eventTypes = this.constructor.emits.join(", ") + throw new Error(`Cannot listen to unknown event ${eventType} in class ${className}. ${className} only emits: ${eventTypes}`) + } + return this.#listeners[eventType].delete(eventListener) } - return this.#listeners[eventType].delete(eventListener) } /** diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs index b412716..f8b910b 100644 --- a/common/src/lib/polyfills/js.mjs +++ b/common/src/lib/polyfills/js.mjs @@ -67,6 +67,19 @@ function stringReplaceAll(from, to) { return this.split(from).join(to) } +/** + * Returns the value of an element of the array at a given index. + * Accepts negative indexes. + * @this {Array|string} + * @param {number} index + * @return {*} + */ +function arrayAt(index) { + if(typeof index !== "number") + throw new Error(`${index} is not a number`) + return index >= 0 ? this[index] : this[this.length + index] +} + const polyfills = { 2017: [ @@ -95,8 +108,8 @@ const polyfills = { [String.prototype, "replaceAll", stringReplaceAll] ], 2022: [ - [Array.prototype, "at", notPolyfilled("Array.prototype.at")], - [String.prototype, "at", notPolyfilled("String.prototype.at")], + [Array.prototype, "at", arrayAt], + [String.prototype, "at", arrayAt], [Object, "hasOwn", notPolyfilled("Object.hasOwn")] ], 2023: [ diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 8cd3f60..7406925 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -17,60 +17,151 @@ */ import { Module } from "./common.mjs" -import { HistoryInterface, NUMBER, STRING } from "./interface.mjs" +import { HelperInterface, HistoryInterface, NUMBER, STRING } from "./interface.mjs" +import { BaseEvent } from "../events.mjs" +import { Action, Actions } from "../history/index.mjs" + +class UpdatedEvent extends BaseEvent { + constructor() { + super("updated") + } +} + +class UndoneEvent extends BaseEvent { + constructor(action) { + super("undone") + this.undid = action + } +} + +class RedoneEvent extends BaseEvent { + constructor(action) { + super("redone") + this.redid = action + } +} + class HistoryAPI extends Module { + static emits = ["updated", "undone", "redone"] + + #helper + constructor() { super("History", { - historyObj: HistoryInterface, + helper: HelperInterface, themeTextColor: STRING, imageDepth: NUMBER, fontSize: NUMBER }) // History QML object - this.history = null + /** @type {Action[]} */ + this.undoStack = [] + /** @type {Action[]} */ + this.redoStack = [] + this.themeTextColor = "#FF0000" this.imageDepth = 2 this.fontSize = 28 } - initialize({ historyObj, themeTextColor, imageDepth, fontSize }) { - super.initialize({ historyObj, themeTextColor, imageDepth, fontSize }) - this.history = historyObj + /** + * @param {HelperInterface} historyObj + * @param {string} themeTextColor + * @param {number} imageDepth + * @param {number} fontSize + */ + initialize({ helper, themeTextColor, imageDepth, fontSize }) { + super.initialize({ helper, themeTextColor, imageDepth, fontSize }) + this.#helper = helper this.themeTextColor = themeTextColor this.imageDepth = imageDepth this.fontSize = fontSize } + /** + * Undoes the Action at the top of the undo stack and pushes it to the top of the redo stack. + */ undo() { if(!this.initialized) throw new Error("Attempting undo before initialize!") - this.history.undo() + if(this.undoStack.length > 0) { + const action = this.undoStack.pop() + action.undo() + this.redoStack.push(action) + this.emit(new UndoneEvent(action)) + } } + /** + * Redoes the Action at the top of the redo stack and pushes it to the top of the undo stack. + */ redo() { if(!this.initialized) throw new Error("Attempting redo before initialize!") - this.history.redo() + if(this.redoStack.length > 0) { + const action = this.redoStack.pop() + action.redo() + this.undoStack.push(action) + this.emit(new RedoneEvent(action)) + } } + /** + * Clears both undo and redo stacks completely. + */ clear() { if(!this.initialized) throw new Error("Attempting clear before initialize!") - this.history.clear() + this.undoStack = [] + this.redoStack = [] + this.emit(new UpdatedEvent()) } + /** + * Adds an instance of HistoryLib.Action to history. + * @param action + */ addToHistory(action) { if(!this.initialized) throw new Error("Attempting addToHistory before initialize!") - this.history.addToHistory(action) + if(action instanceof Action) { + console.log("Added new entry to history: " + action.getReadableString()) + this.undoStack.push(action) + if(this.#helper.getSettingBool("reset_redo_stack")) + this.redoStack = [] + this.emit(new UpdatedEvent()) + } } - unserialize(...data) { + /** + * Unserializes both the undo stack and redo stack from serialized content. + * @param {[string, any[]][]} undoSt + * @param {[string, any[]][]} redoSt + */ + unserialize(undoSt, redoSt) { if(!this.initialized) throw new Error("Attempting unserialize before initialize!") - this.history.unserialize(...data) + this.clear() + for(const [name, args] of undoSt) + this.undoStack.push( + new Actions[name](...args) + ) + for(const [name, args] of redoSt) + this.redoStack.push( + new Actions[name](...args) + ) + this.emit(new UpdatedEvent()) } + /** + * Serializes history into JSON-able content. + * @return {[[string, any[]], [string, any[]]]} + */ serialize() { if(!this.initialized) throw new Error("Attempting serialize before initialize!") - return this.history.serialize() + let undoSt = [], redoSt = []; + for(const action of this.undoStack) + undoSt.push([ action.type(), action.export() ]) + for(const action of this.redoStack) + redoSt.push([ action.type(), action.export() ]) + return [undoSt, redoSt] } } diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index 606ec4d..1ee65a3 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -60,24 +60,6 @@ export class Interface { } -export class SettingsInterface extends Interface { - width = NUMBER - height = NUMBER - xmin = NUMBER - ymax = NUMBER - xzoom = NUMBER - yzoom = NUMBER - xaxisstep = STRING - yaxisstep = STRING - xlabel = STRING - ylabel = STRING - linewidth = NUMBER - textsize = NUMBER - logscalex = BOOLEAN - showxgrad = BOOLEAN - showygrad = BOOLEAN -} - export class CanvasInterface extends Interface { imageLoaders = OBJECT /** @type {function(string): CanvasRenderingContext2D} */ diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 0b4c6fa..8ca4b2b 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -21,7 +21,7 @@ import Objects from "./objects.mjs" import History from "./history.mjs" import Canvas from "./canvas.mjs" import Settings from "./settings.mjs" -import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs" +import { DialogInterface, RootInterface } from "./interface.mjs" class IOAPI extends Module { diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 44a6593..1530839 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -72,7 +72,11 @@ class SettingsAPI extends Module { helper: HelperInterface }) } - + + /** + * + * @param {HelperInterface} helper + */ initialize({ helper }) { super.initialize({ helper }) // Initialize default values. diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index f26fd5b..8c3f2d1 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -76,18 +76,16 @@ MenuBar { Action { text: qsTr("&Undo") shortcut: StandardKey.Undo - onTriggered: history.undo() + onTriggered: Modules.History.undo() icon.name: 'edit-undo' icon.color: enabled ? sysPalette.windowText : sysPaletteIn.windowText - enabled: history.undoCount > 0 } Action { text: qsTr("&Redo") shortcut: StandardKey.Redo - onTriggered: history.redo() + onTriggered: Modules.History.redo() icon.name: 'edit-redo' icon.color: enabled ? sysPalette.windowText : sysPaletteIn.windowText - enabled: history.redoCount > 0 } Action { text: qsTr("&Copy plot") diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 47db5f3..88579e7 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -64,10 +64,7 @@ Item { Clears both undo and redo stacks completly. */ function clear() { - undoCount = 0 - redoCount = 0 - undoStack = [] - redoStack = [] + Modules.History.clear() } @@ -76,18 +73,7 @@ Item { Serializes history into JSON-able content. */ function serialize() { - let undoSt = [], redoSt = []; - for(let i = 0; i < undoCount; i++) - undoSt.push([ - undoStack[i].type(), - undoStack[i].export() - ]); - for(let i = 0; i < redoCount; i++) - redoSt.push([ - redoStack[i].type(), - redoStack[i].export() - ]); - return [undoSt, redoSt] + return Modules.History.serialize() } /*! @@ -95,14 +81,7 @@ Item { Unserializes both \c undoSt stack and \c redoSt stack from serialized content. */ function unserialize(undoSt, redoSt) { - clear(); - for(let i = 0; i < undoSt.length; i++) - undoStack.push(new JS.HistoryLib.Actions[undoSt[i][0]](...undoSt[i][1])) - for(let i = 0; i < redoSt.length; i++) - redoStack.push(new JS.HistoryLib.Actions[redoSt[i][0]](...redoSt[i][1])) - undoCount = undoSt.length; - redoCount = redoSt.length; - objectLists.update() + Modules.History.unserialize(undoSt, redoSt) } /*! @@ -110,16 +89,7 @@ Item { Adds an instance of HistoryLib.Action to history. */ function addToHistory(action) { - if(action instanceof JS.HistoryLib.Action) { - console.log("Added new entry to history: " + action.getReadableString()) - undoStack.push(action) - undoCount++; - if(Helper.getSettingBool("reset_redo_stack")) { - redoStack = [] - redoCount = 0 - } - saved = false - } + Modules.History.addToHistory(action) } /*! @@ -128,16 +98,7 @@ Item { By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ function undo(updateObjectList = true) { - if(undoStack.length > 0) { - var action = undoStack.pop() - action.undo() - if(updateObjectList) - objectLists.update() - redoStack.push(action) - undoCount--; - redoCount++; - saved = false - } + Modules.History.undo() } /*! @@ -146,77 +107,6 @@ Item { By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ function redo(updateObjectList = true) { - if(redoStack.length > 0) { - var action = redoStack.pop() - action.redo() - if(updateObjectList) - objectLists.update() - undoStack.push(action) - undoCount++; - redoCount--; - saved = false - } - } - - /*! - \qmlmethod void History::undoMultipleDefered(int toUndoCount) - Undoes several HistoryLib.Action at the top of the undo stack and pushes them to the top of the redo stack. - It undoes them deferedly to avoid overwhelming the computer while creating a cool short accelerated summary of all changes. - */ - function undoMultipleDefered(toUndoCount) { - undoTimer.toUndoCount = toUndoCount; - undoTimer.start() - if(toUndoCount > 0) - saved = false - } - - - /*! - \qmlmethod void History::redoMultipleDefered(int toRedoCount) - Redoes several HistoryLib.Action at the top of the redo stack and pushes them to the top of the undo stack. - It redoes them deferedly to avoid overwhelming the computer while creating a cool short accelerated summary of all changes. - */ - function redoMultipleDefered(toRedoCount) { - redoTimer.toRedoCount = toRedoCount; - redoTimer.start() - if(toRedoCount > 0) - saved = false - } - - Timer { - id: undoTimer - interval: 5; running: false; repeat: true - property int toUndoCount: 0 - onTriggered: { - if(toUndoCount > 0) { - historyObj.undo(toUndoCount % 4 == 1) // Only redraw once every 4 changes. - toUndoCount--; - } else { - running = false; - } - } - } - - Timer { - id: redoTimer - interval: 5; running: false; repeat: true - property int toRedoCount: 0 - onTriggered: { - if(toRedoCount > 0) { - historyObj.redo(toRedoCount % 4 == 1) // Only redraw once every 4 changes. - toRedoCount--; - } else { - running = false; - } - } - } - - Component.onCompleted: { - Modules.History.initialize({ - historyObj, - themeTextColor: sysPalette.windowText.toString(), - imageDepth: Screen.devicePixelRatio, - fontSize: 14 - }) + Modules.History.redo() } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 926b42a..d79cc84 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +pragma ComponentBehavior: Bound + import QtQuick.Controls import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting @@ -46,6 +48,18 @@ Item { true when the system is running with a dark theme, false otherwise. */ property bool darkTheme: isDarkTheme() + + /*! + \qmlproperty int HistoryBrowser::undoCount + Number of actions in the undo stack. + */ + property int undoCount: 0 + + /*! + \qmlproperty int HistoryBrowser::redoCount + Number of actions in the redo stack. + */ + property int redoCount: 0 Setting.TextSetting { id: filterInput @@ -76,19 +90,22 @@ Item { id: redoColumn anchors.right: parent.right anchors.top: parent.top - width: actionWidth + width: historyBrowser.actionWidth Repeater { - model: history.redoCount + model: historyBrowser.redoCount HistoryItem { id: redoButton - width: actionWidth + width: historyBrowser.actionWidth //height: actionHeight isRedo: true - idx: index darkTheme: historyBrowser.darkTheme hidden: !(filterInput.value == "" || content.includes(filterInput.value)) + onClicked: { + redoTimer.toRedoCount = Modules.History.redoStack.length-index + redoTimer.start() + } } } } @@ -101,14 +118,14 @@ Item { transform: Rotation { origin.x: 30; origin.y: 30; angle: 270} height: 70 width: 20 - visible: history.redoCount > 0 + visible: historyBrowser.redoCount > 0 } Rectangle { id: nowRect anchors.right: parent.right anchors.top: redoColumn.bottom - width: actionWidth + width: historyBrowser.actionWidth height: 40 color: sysPalette.highlight Text { @@ -124,20 +141,24 @@ Item { id: undoColumn anchors.right: parent.right anchors.top: nowRect.bottom - width: actionWidth + width: historyBrowser.actionWidth Repeater { - model: history.undoCount + model: historyBrowser.undoCount HistoryItem { id: undoButton - width: actionWidth + width: historyBrowser.actionWidth //height: actionHeight isRedo: false - idx: index darkTheme: historyBrowser.darkTheme hidden: !(filterInput.value == "" || content.includes(filterInput.value)) + + onClicked: { + undoTimer.toUndoCount = +index+1 + undoTimer.start() + } } } } @@ -150,7 +171,39 @@ Item { transform: Rotation { origin.x: 30; origin.y: 30; angle: 270} height: 60 width: 20 - visible: history.undoCount > 0 + visible: historyBrowser.undoCount > 0 + } + } + } + + Timer { + id: undoTimer + interval: 5; running: false; repeat: true + property int toUndoCount: 0 + onTriggered: { + if(toUndoCount > 0) { + Modules.History.undo() + if(toUndoCount % 3 === 1) + Modules.Canvas.requestPaint() + toUndoCount--; + } else { + running = false; + } + } + } + + Timer { + id: redoTimer + interval: 5; running: false; repeat: true + property int toRedoCount: 0 + onTriggered: { + if(toRedoCount > 0) { + Modules.History.redo() + if(toRedoCount % 3 === 1) + Modules.Canvas.requestPaint() + toRedoCount--; + } else { + running = false; } } } @@ -163,6 +216,18 @@ Item { let hex = sysPalette.windowText.toString() // We only check the first parameter, as on all normal OSes, text color is grayscale. return parseInt(hex.substr(1,2), 16) > 128 - + } + + Component.onCompleted: { + Modules.History.initialize({ + helper: Helper, + themeTextColor: sysPalette.windowText.toString(), + imageDepth: Screen.devicePixelRatio, + fontSize: 14 + }) + Modules.History.on("updated undone redone", () => { + undoCount = Modules.History.undoStack.length + redoCount = Modules.History.redoStack.length + }) } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index f1e20a0..f37eb3b 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -41,17 +41,17 @@ Button { \qmlproperty bool HistoryItem::isRedo true if the action is in the redo stack, false othewise. */ - property bool isRedo + required property bool isRedo /*! - \qmlproperty int HistoryItem::idx + \qmlproperty int HistoryItem::index Index of the item within the HistoryBrowser list. */ - property int idx + required property int index /*! \qmlproperty bool HistoryItem::darkTheme true when the system is running with a dark theme, false otherwise. */ - property bool darkTheme + required property bool darkTheme /*! \qmlproperty bool HistoryItem::hidden true when the item is filtered out, false otherwise. @@ -61,7 +61,7 @@ Button { \qmlproperty int HistoryItem::historyAction Associated history action. */ - readonly property var historyAction: isRedo ? history.redoStack[idx] : history.undoStack[history.undoCount-idx-1] + readonly property var historyAction: isRedo ? Modules.History.redoStack.at(index) : Modules.History.undoStack.at(-index-1) /*! \qmlproperty int HistoryItem::actionHeight @@ -147,13 +147,6 @@ Button { ToolTip.visible: hovered ToolTip.delay: 200 ToolTip.text: content - - onClicked: { - if(isRedo) - history.redoMultipleDefered(history.redoCount-idx) - else - history.undoMultipleDefered(+idx+1) - } } From 448d94fee35d574832d73ed2195ce1fa35ae4d45 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 02:03:27 +0200 Subject: [PATCH 174/249] Fixed many issues with new History module, including saved status. + Fixed (old) bug that label content wasn't being saved. --- assets/i18n/lp_de.ts | 112 ++++++++-------- assets/i18n/lp_en.ts | 112 ++++++++-------- assets/i18n/lp_es.ts | 116 ++++++++-------- assets/i18n/lp_fr.ts | 112 ++++++++-------- assets/i18n/lp_hu.ts | 112 ++++++++-------- assets/i18n/lp_nb_NO.ts | 114 ++++++++-------- assets/i18n/lp_template.ts | 125 +++++++----------- common/src/module/history.mjs | 17 ++- common/src/module/interface.mjs | 1 - common/src/module/io.mjs | 49 +++++-- common/src/objs/bodephase.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../History/HistoryBrowser.qml | 2 +- .../LogarithmPlotter/LogarithmPlotter.qml | 22 ++- .../ObjectLists/Editor/CustomPropertyList.qml | 16 ++- .../ObjectLists/Editor/Dialog.qml | 8 +- .../ObjectLists/ObjectCreationGrid.qml | 4 +- .../ObjectLists/ObjectRow.qml | 6 +- .../LogarithmPlotter/PickLocationOverlay.qml | 6 +- 19 files changed, 479 insertions(+), 459 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 4876e02..59a9725 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -67,22 +67,22 @@ &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Preferences &Einstellung - + &Create &Erstellen @@ -123,52 +123,52 @@ Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -205,12 +205,12 @@ CustomPropertyList - + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -238,9 +238,8 @@ Name - Label content - Etikett + Etikett @@ -405,24 +404,20 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" HistoryBrowser - Filter... - Filtern… + Filtern… - Redo > - Wiederherstellen > + Wiederherstellen > - > Now - > Aktueller Stand + > Aktueller Stand - < Undo - < Rückgängig + < Rückgängig @@ -475,17 +470,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -613,109 +608,109 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Settings - + X Zoom Zoom auf X - + Y Zoom Zoom auf Y - + Min X Minimum X - + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern… - + Save plot as Grafik speichern unter… - + Load plot Grafik laden… @@ -1160,7 +1155,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1191,7 +1186,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler @@ -1308,27 +1303,27 @@ Ausdruck analysiert: %3 Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not load file: Datei konnte nicht geladen werden: @@ -1337,7 +1332,7 @@ Ausdruck analysiert: %3 Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. @@ -1731,6 +1726,11 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde color Farbe + + + labelContent + Etikett + repartition diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index b2dfaff..5f653a7 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -67,22 +67,22 @@ &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Preferences &Preferences - + &Create &Create @@ -123,52 +123,52 @@ Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -205,12 +205,12 @@ CustomPropertyList - + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -238,9 +238,8 @@ Name - Label content - Label content + Label content @@ -405,24 +404,20 @@ These settings can be changed at any time from the "Settings" menu. HistoryBrowser - Filter... - Filter… + Filter… - Redo > - Redo > + Redo > - > Now - > Now + > Now - < Undo - < Undo + < Undo @@ -475,17 +470,17 @@ These settings can be changed at any time from the "Settings" menu.Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -613,109 +608,109 @@ These settings can be changed at any time from the "Settings" menu.Settings - + X Zoom X Zoom - + Y Zoom Y Zoom - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot… - + Save plot as Save plot as… - + Load plot Open plot… @@ -1160,7 +1155,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1191,7 +1186,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error @@ -1308,27 +1303,27 @@ Evaluated expression: %3 History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not load file: Could not load file: @@ -1337,7 +1332,7 @@ Evaluated expression: %3 Could not save file: - + Loaded file '%1'. Loaded file '%1'. @@ -1731,6 +1726,11 @@ Please make sure your LaTeX installation is correct and report a bug if so.color Color + + + labelContent + Label content + repartition diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index ef79648..7a736b5 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -67,22 +67,22 @@ &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Preferences &Preferencias - + &Create &Crear @@ -119,52 +119,52 @@ Esquema de colores - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -205,12 +205,12 @@ CustomPropertyList - + + Create new %1 + Crear nuevo %1 - + Pick on graph Elegir en el gráfico @@ -237,11 +237,6 @@ Name - - - Label content - - null @@ -405,24 +400,16 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes HistoryBrowser - - Filter... - - - - Redo > - Rehacer > + Rehacer > - > Now - > Ahora + > Ahora - < Undo - < Deshacer + < Deshacer @@ -451,17 +438,17 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Historial - + Copied plot screenshot to clipboard! ¡Captura de pantalla del gráfico copiada al portapapeles! - + &Update &Actualizar - + &Update LogarithmPlotter &Actualizar LogarithmPlotter @@ -613,109 +600,109 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Settings - + X Zoom - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step Paso por eje X - + Y Axis Step Paso por eje Y - + Line width Anchura de la línea - + Text size (px) Tamaño del texto (px) - + X Label - + Y Label - + X Log scale Escala logarítmica en X - + Show X graduation Mostrar graduación del eje X - + Show Y graduation Mostrar graduación del eje Y - + Copy to clipboard Copiar al portapapeles - + Save plot Guardar gráfico… - + Save plot as Guardar gráfico como… - + Load plot Abrir gráfico… @@ -1147,7 +1134,7 @@ Evaluated expression: %3 Expresión evaluada: %3 - + Error while attempting to draw %1 %2: %3 @@ -1191,7 +1178,7 @@ Evaluated expression: %3 Expresión evaluada: %3 - + LogarithmPlotter - Drawing error @@ -1320,27 +1307,27 @@ Expresión evaluada: %3 Objetos - + Saved plot to '%1'. Gráfico guardado en '%1'. - + Loading file '%1'. Cargando el archivo '%1'. - + Unknown object type: %1. Tipo de objeto desconocido: %1 . - + Invalid file provided. Se ha proporcionado un archivo no válido. - + Could not load file: No se pudo cargar el archivo: @@ -1349,7 +1336,7 @@ Expresión evaluada: %3 No se ha podido guardar el archivo: - + Loaded file '%1'. Archivo cargado '%1'. @@ -1731,6 +1718,11 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u baseValues Valores de inicialización + + + labelContent + Contenido de la etiqueta + repartition diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index 2b1a26d..b693568 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -67,22 +67,22 @@ &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Preferences &Préférences - + &Create &Créer @@ -124,52 +124,52 @@ Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -206,12 +206,12 @@ CustomPropertyList - + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -239,9 +239,8 @@ Nom - Label content - Étiquette + Étiquette @@ -407,24 +406,20 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P HistoryBrowser - Filter... - Filtrer… + Filtrer… - Redo > - Rétablir > + Rétablir > - > Now - > État actuel + > État actuel - < Undo - < Annuler + < Annuler @@ -477,17 +472,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -615,109 +610,109 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Settings - + X Zoom Zoom en X - + Y Zoom Zoom en Y - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe… - + Save plot as Sauvegarder le graphe sous… - + Load plot Ouvrir un graphe… @@ -1163,7 +1158,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1194,7 +1189,7 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur @@ -1323,27 +1318,27 @@ Formule analysée : %3 &Mettre à jour LogarithmPlotter - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not load file: Impossible de charger le fichier : @@ -1352,7 +1347,7 @@ Formule analysée : %3 Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. @@ -1734,6 +1729,11 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c color Couleur + + + labelContent + Étiquette + repartition diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index 975c600..a43da4d 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -67,22 +67,22 @@ &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Preferences &Beállítások - + &Create &Létrehozás @@ -123,52 +123,52 @@ Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -205,12 +205,12 @@ CustomPropertyList - + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -238,9 +238,8 @@ Név - Label content - Címketartalom + Címketartalom @@ -405,24 +404,20 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. HistoryBrowser - Filter... - Szűrő… + Szűrő… - Redo > - Ismétlés > + Ismétlés > - > Now - > Most + > Most - < Undo - < Visszavonás + < Visszavonás @@ -475,17 +470,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -613,109 +608,109 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Settings - + X Zoom X-nagyítás - + Y Zoom Y-nagyítás - + Min X Legkisebb X - + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése… - + Save plot as Ábra mentése másként… - + Load plot Ábra megnyitása… @@ -1160,7 +1155,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1191,7 +1186,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba @@ -1304,27 +1299,27 @@ Kiértékelt kifejezés: %3 Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not load file: @@ -1333,7 +1328,7 @@ Kiértékelt kifejezés: %3 A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. @@ -1731,6 +1726,11 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents color Szín + + + labelContent + Címketartalom + repartition diff --git a/assets/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts index d278f03..79657f6 100644 --- a/assets/i18n/lp_nb_NO.ts +++ b/assets/i18n/lp_nb_NO.ts @@ -67,22 +67,22 @@ &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Preferences - + &Create &Opprett @@ -99,52 +99,52 @@ Tilbakestill angrehistorikk automatisk - + &Help &Hjelp - + &Source code - + &Report a bug &Rapporter en feil - + &User manual - + &Changelog &Endringslogg - + &Help translating! &Hjelp til å oversette! - + &Thanks &Erkjennelser - + &About &Om - + Save unsaved changes? Lagre ikke-lagrede endringer? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? @@ -181,12 +181,12 @@ CustomPropertyList - + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -214,9 +214,8 @@ Navn - Label content - Etikett-innhold + Etikett-innhold @@ -361,24 +360,16 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. HistoryBrowser - - Filter... - - - - Redo > - Angre > + Angre > - > Now - > Nå + > Nå - < Undo - < Angre + < Angre @@ -431,17 +422,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -569,109 +560,109 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Settings - + X Zoom X-forstørrelse - + Y Zoom Y-forstørrelse - + Min X Min. X - + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation Vis X-inndeling - + Show Y graduation Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott @@ -971,7 +962,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1122,7 +1113,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1235,27 +1226,27 @@ Evaluated expression: %3 Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not load file: @@ -1264,7 +1255,7 @@ Evaluated expression: %3 Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». @@ -1641,6 +1632,11 @@ Please make sure your latex installation is correct and report a bug if so.targetValuePosition + + + labelContent + Etikett-innhold + repartition diff --git a/assets/i18n/lp_template.ts b/assets/i18n/lp_template.ts index 0981f1b..81221dd 100644 --- a/assets/i18n/lp_template.ts +++ b/assets/i18n/lp_template.ts @@ -67,72 +67,72 @@ - + &Redo - + &Copy plot - + &Preferences - + &Create - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -162,12 +162,12 @@ CustomPropertyList - + + Create new %1 - + Pick on graph @@ -194,11 +194,6 @@ Name - - - Label content - - null @@ -294,29 +289,6 @@ - - HistoryBrowser - - - Filter... - - - - - Redo > - - - - - > Now - - - - - < Undo - - - ListSetting @@ -343,17 +315,17 @@ - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -457,109 +429,109 @@ Settings - + X Zoom - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot @@ -859,7 +831,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1010,7 +982,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1069,32 +1041,32 @@ Evaluated expression: %3 io - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not load file: - + Loaded file '%1'. @@ -1448,6 +1420,11 @@ Please make sure your latex installation is correct and report a bug if so.targetValuePosition + + + labelContent + + sequence diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 7406925..2a38730 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -23,9 +23,16 @@ import { Action, Actions } from "../history/index.mjs" -class UpdatedEvent extends BaseEvent { +class ClearedEvent extends BaseEvent { constructor() { - super("updated") + super("cleared") + } +} + +class AddedEvent extends BaseEvent { + constructor(action) { + super("added") + this.action = action } } @@ -44,7 +51,7 @@ class RedoneEvent extends BaseEvent { } class HistoryAPI extends Module { - static emits = ["updated", "undone", "redone"] + static emits = ["cleared", "added", "undone", "redone"] #helper @@ -113,7 +120,7 @@ class HistoryAPI extends Module { if(!this.initialized) throw new Error("Attempting clear before initialize!") this.undoStack = [] this.redoStack = [] - this.emit(new UpdatedEvent()) + this.emit(new ClearedEvent()) } /** @@ -127,7 +134,7 @@ class HistoryAPI extends Module { this.undoStack.push(action) if(this.#helper.getSettingBool("reset_redo_stack")) this.redoStack = [] - this.emit(new UpdatedEvent()) + this.emit(new AddedEvent(action)) } } diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index 1ee65a3..db65ea2 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -79,7 +79,6 @@ export class CanvasInterface extends Interface { export class RootInterface extends Interface { width = NUMBER height = NUMBER - updateObjectsLists = FUNCTION } export class DialogInterface extends Interface { diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 8ca4b2b..360a8fc 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -22,26 +22,59 @@ import History from "./history.mjs" import Canvas from "./canvas.mjs" import Settings from "./settings.mjs" import { DialogInterface, RootInterface } from "./interface.mjs" +import { BaseEvent } from "../events.mjs" +class LoadedEvent extends BaseEvent { + constructor() { + super("loaded") + } +} + +class SavedEvent extends BaseEvent { + constructor() { + super("saved") + } +} + +class ModifiedEvent extends BaseEvent { + constructor() { + super("modified") + } +} + class IOAPI extends Module { + static emits = ["loaded", "saved", "modified"] + /** @type {RootInterface} */ #rootElement /** @type {{show: function(string)}} */ #alert + #saved = true constructor() { super("IO", { alert: DialogInterface, root: RootInterface }) - /** - * Path of the currently opened file. Empty if no file is opened. - * @type {string} - */ - this.saveFileName = "" + + // Settings.on("changed", this.__emitModified.bind(this)) + console.log("Init IO", this) + History.on("added undone redone", this.__emitModified.bind(this)) } + __emitModified() { + this.#saved = false + this.emit(new ModifiedEvent()) + } + + + /** + * True if no changes have been made since last save, false otherwise. + * @return {boolean} + */ + get saved() { return this.#saved } + /** * Initializes module with QML elements. * @param {RootInterface} root @@ -92,7 +125,7 @@ class IOAPI extends Module { } Helper.write(filename, JSON.stringify(settings)) this.#alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) - History.history.saved = true + this.emit(new SavedEvent()) } /** @@ -159,8 +192,6 @@ class IOAPI extends Module { if("history" in data) History.unserialize(...data["history"]) - // Refreshing sidebar - this.#rootElement.updateObjectsLists() } else { error = qsTranslate("io", "Invalid file provided.") } @@ -172,7 +203,7 @@ class IOAPI extends Module { } Canvas.redraw() this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) - History.history.saved = true + this.emit(new LoadedEvent()) } } diff --git a/common/src/objs/bodephase.mjs b/common/src/objs/bodephase.mjs index 9c93bba..800671e 100644 --- a/common/src/objs/bodephase.mjs +++ b/common/src/objs/bodephase.mjs @@ -63,7 +63,7 @@ export default class BodePhase extends ExecutableObject { // Create new point om_0 = Objects.createNewRegisteredObject("Point", [Objects.getNewName("ω"), this.color, "name"]) om_0.labelPosition = this.phase.execute() >= 0 ? "above" : "below" - History.history.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export())) + History.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export())) labelPosition = "below" } om_0.requiredBy.push(this) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 8c3f2d1..f4e2f35 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -117,7 +117,7 @@ MenuBar { icon.color: sysPalette.buttonText onTriggered: { var newObj = Modules.Objects.createNewRegisteredObject(modelData) - history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) + Modules.History.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index d79cc84..aca7943 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -225,7 +225,7 @@ Item { imageDepth: Screen.devicePixelRatio, fontSize: 14 }) - Modules.History.on("updated undone redone", () => { + Modules.History.on("cleared added undone redone", () => { undoCount = Modules.History.undoStack.length redoCount = Modules.History.redoStack.length }) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 51abb46..33967aa 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -42,7 +42,7 @@ ApplicationWindow { width: 1000 height: 500 color: sysPalette.window - title: "LogarithmPlotter" + title: qsTr("untitled") SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } @@ -50,9 +50,7 @@ ApplicationWindow { menuBar: appMenu.trueItem AppMenuBar {id: appMenu} - - History { id: history } - + Popup.GreetScreen {} Popup.Preferences {id: preferences} @@ -185,7 +183,7 @@ ApplicationWindow { } onClosing: function(close) { - if(!history.saved) { + if(!Modules.History.saved) { close.accepted = false appMenu.openSaveUnsavedChangesDialog() } @@ -254,8 +252,20 @@ ApplicationWindow { if(evt.property === "saveFilename") { const fileName = evt.newValue.split('/').pop().split('\\').pop() if(fileName !== "") - title = `${fileName}` + title = fileName } }) + Modules.IO.on("saved loaded", (evt) => { + // Refreshing sidebar + console.log(evt.name) + updateObjectsLists() + if(title.endsWith("*")) + title = title.substring(0, title.length-1) + }) + Modules.IO.on("modified", () => { + console.log("modified") + if(!title.endsWith("*")) + title = title+"*" + }) } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 57ea4ae..1ca75e4 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -80,7 +80,7 @@ Repeater { variables: propertyType.variables onChanged: function(newExpr) { if(obj[propertyName].toString() != newExpr.toString()) { - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newExpr )) @@ -123,7 +123,7 @@ Repeater { // Ensuring old and new values are different to prevent useless adding to history. if(obj[propertyName] != newValueParsed) { - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newValueParsed )) @@ -168,7 +168,7 @@ Repeater { return obj[propertyName] } onClicked: { - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], this.checked )) @@ -209,7 +209,9 @@ Repeater { if(selectedObj == null) { // Creating new object. selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType) - history.addToHistory(new JS.HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) + Modules.History.addToHistory( + new JS.HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export()) + ) baseModel = Modules.Objects.getObjectsName(propertyType.objType).concat( isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) @@ -219,14 +221,14 @@ Repeater { //Modules.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], selectedObj )) obj[propertyName] = selectedObj } else if(baseModel[newIndex] != obj[propertyName]) { // Ensuring new property is different to not add useless history entries. - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], baseModel[newIndex] )) @@ -256,7 +258,7 @@ Repeater { onChanged: { var exported = exportModel() - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], exported )) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index e2b149b..715602a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -112,7 +112,7 @@ Popup.BaseDialog { if(newName in Modules.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { - history.addToHistory(new JS.HistoryLib.NameChanged( + Modules.History.addToHistory(new JS.HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) Modules.Objects.renameObject(obj.name, newName) @@ -127,13 +127,17 @@ Popup.BaseDialog { id: labelContentProperty height: 30 width: dlgProperties.width - label: qsTr("Label content") + label: qsTranslate("prop", "labelContent") model: [qsTr("null"), qsTr("name"), qsTr("name + value")] property var idModel: ["null", "name", "name + value"] icon: "common/label.svg" currentIndex: idModel.indexOf(objEditor.obj.labelContent) onActivated: function(newIndex) { if(idModel[newIndex] != objEditor.obj.labelContent) { + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + obj.name, objType, "labelContent", + objEditor.obj.labelContent, idModel[newIndex] + )) objEditor.obj.labelContent = idModel[newIndex] objEditor.obj.update() objectListList.update() diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 7aa9574..e8d4912 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -104,7 +104,9 @@ Column { onClicked: { let newObj = Modules.Objects.createNewRegisteredObject(modelData) - history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) + Modules.History.addToHistory(new JS.HistoryLib.CreateNewObject( + newObj.name, modelData, newObj.export() + )) objectLists.update() let hasXProp = newObj.constructor.properties().hasOwnProperty('x') diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 5018e5e..9624d23 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -72,7 +72,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 5 onClicked: { - history.addToHistory(new JS.HistoryLib.EditedVisibility( + Modules.History.addToHistory(new JS.HistoryLib.EditedVisibility( obj.name, obj.type, this.checked )) obj.visible = this.checked @@ -212,7 +212,7 @@ Item { selectedColor: obj.color title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name) onAccepted: { - history.addToHistory(new JS.HistoryLib.ColorChanged( + Modules.History.addToHistory(new JS.HistoryLib.ColorChanged( obj.name, obj.type, obj.color, selectedColor.toString() )) obj.color = selectedColor.toString() @@ -231,7 +231,7 @@ Item { // Object still exists // Temporary fix for objects require not being propertly updated. object.requiredBy = [] - history.addToHistory(new JS.HistoryLib.DeleteObject( + Modules.History.addToHistory(new JS.HistoryLib.DeleteObject( object.name, object.type, object.export() )) Modules.Objects.deleteObject(object.name) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 680c310..b364e73 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -115,7 +115,7 @@ Item { let obj = Modules.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { - history.addToHistory(new JS.HistoryLib.EditedPosition( + Modules.History.addToHistory(new JS.HistoryLib.EditedPosition( objName, objType, obj[propertyX], newValueX, obj[propertyY], newValueY )) obj[propertyX] = newValueX @@ -124,7 +124,7 @@ Item { objectLists.update() pickerRoot.picked(obj) } else if(parent.userPickX) { - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( objName, objType, propertyX, obj[propertyX], newValueX )) obj[propertyX] = newValueX @@ -132,7 +132,7 @@ Item { objectLists.update() pickerRoot.picked(obj) } else if(parent.userPickY) { - history.addToHistory(new JS.HistoryLib.EditedProperty( + Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValueY )) obj[propertyY] = newValueY From b91dbfb31100e221553d61657a5b2b1a3835dfc4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 02:14:42 +0200 Subject: [PATCH 175/249] Finishing touches on putting History off QML. --- common/src/events.mjs | 1 - common/src/module/history.mjs | 10 +- common/src/module/io.mjs | 3 +- .../LogarithmPlotter/History/History.qml | 112 ------------------ .../History/HistoryBrowser.qml | 2 +- .../eu/ad5001/LogarithmPlotter/History/qmldir | 1 - .../LogarithmPlotter/LogarithmPlotter.qml | 2 +- 7 files changed, 12 insertions(+), 119 deletions(-) delete mode 100644 runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml diff --git a/common/src/events.mjs b/common/src/events.mjs index fbc8228..dbdd00f 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -58,7 +58,6 @@ export class BaseEventEmitter { for(const type of eventType.split(" ")) this.on(type, eventListener) else { - console.log("Listening to", eventType) if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name const eventTypes = this.constructor.emits.join(", ") diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 2a38730..6e32fed 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -29,6 +29,12 @@ class ClearedEvent extends BaseEvent { } } +class LoadedEvent extends BaseEvent { + constructor() { + super("loaded") + } +} + class AddedEvent extends BaseEvent { constructor(action) { super("added") @@ -51,7 +57,7 @@ class RedoneEvent extends BaseEvent { } class HistoryAPI extends Module { - static emits = ["cleared", "added", "undone", "redone"] + static emits = ["cleared", "loaded", "added", "undone", "redone"] #helper @@ -154,7 +160,7 @@ class HistoryAPI extends Module { this.redoStack.push( new Actions[name](...args) ) - this.emit(new UpdatedEvent()) + this.emit(new LoadedEvent()) } /** diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 360a8fc..472b061 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -59,7 +59,6 @@ class IOAPI extends Module { }) // Settings.on("changed", this.__emitModified.bind(this)) - console.log("Init IO", this) History.on("added undone redone", this.__emitModified.bind(this)) } @@ -125,6 +124,7 @@ class IOAPI extends Module { } Helper.write(filename, JSON.stringify(settings)) this.#alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) + this.#saved = true this.emit(new SavedEvent()) } @@ -203,6 +203,7 @@ class IOAPI extends Module { } Canvas.redraw() this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) + this.#saved = true this.emit(new LoadedEvent()) } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml deleted file mode 100644 index 88579e7..0000000 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ /dev/null @@ -1,112 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import QtQuick -import QtQml -import QtQuick.Window -import "../js/index.mjs" as JS - -/*! - \qmltype History - \inqmlmodule eu.ad5001.LogarithmPlotter.History - \brief QObject holding persistantly for undo & redo stacks. - - \sa HistoryBrowser, HistoryLib -*/ -Item { - // Using a QtObject is necessary in order to have proper property propagation in QML - id: historyObj - - /*! - \qmlproperty int History::undoCount - Count of undo actions. - */ - property int undoCount: 0 - /*! - \qmlproperty int History::redoCount - Count of redo actions. - */ - property int redoCount: 0 - /*! - \qmlproperty var History::undoStack - Stack of undo actions. - */ - property var undoStack: [] - /*! - \qmlproperty var History::redoStack - Stack of redo actions. - */ - property var redoStack: [] - /*! - \qmlproperty bool History::saved - true when no modification was done to the current working file, false otherwise. - */ - property bool saved: true - - - /*! - \qmlmethod void History::clear() - Clears both undo and redo stacks completly. - */ - function clear() { - Modules.History.clear() - } - - - /*! - \qmlmethod var History::serialize() - Serializes history into JSON-able content. - */ - function serialize() { - return Modules.History.serialize() - } - - /*! - \qmlmethod void History::unserialize(var undoSt, var redoSt) - Unserializes both \c undoSt stack and \c redoSt stack from serialized content. - */ - function unserialize(undoSt, redoSt) { - Modules.History.unserialize(undoSt, redoSt) - } - - /*! - \qmlmethod void History::addToHistory(var action) - Adds an instance of HistoryLib.Action to history. - */ - function addToHistory(action) { - Modules.History.addToHistory(action) - } - - /*! - \qmlmethod void History::undo(bool updateObjectList = true) - Undoes the HistoryLib.Action at the top of the undo stack and pushes it to the top of the redo stack. - By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. - */ - function undo(updateObjectList = true) { - Modules.History.undo() - } - - /*! - \qmlmethod void History::redo(bool updateObjectList = true) - Redoes the HistoryLib.Action at the top of the redo stack and pushes it to the top of the undo stack. - By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. - */ - function redo(updateObjectList = true) { - Modules.History.redo() - } -} diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index aca7943..eb84340 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -225,7 +225,7 @@ Item { imageDepth: Screen.devicePixelRatio, fontSize: 14 }) - Modules.History.on("cleared added undone redone", () => { + Modules.History.on("cleared loaded added undone redone", () => { undoCount = Modules.History.undoStack.length redoCount = Modules.History.redoStack.length }) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir index 4f011a5..7f8a628 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir @@ -1,5 +1,4 @@ module eu.ad5001.LogarithmPlotter.History -History 1.0 History.qml HistoryBrowser 1.0 HistoryBrowser.qml HistoryItem 1.0 HistoryItem.qml diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 33967aa..e7cfc1a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -183,7 +183,7 @@ ApplicationWindow { } onClosing: function(close) { - if(!Modules.History.saved) { + if(!Modules.IO.saved) { close.accepted = false appMenu.openSaveUnsavedChangesDialog() } From 82e6d2ffe3524efb51061a502521e6c2c8a229d1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 02:35:13 +0200 Subject: [PATCH 176/249] Removing HistoryInterface (no longer needed) --- common/src/module/history.mjs | 2 +- common/src/module/interface.mjs | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 6e32fed..be70f87 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -17,7 +17,7 @@ */ import { Module } from "./common.mjs" -import { HelperInterface, HistoryInterface, NUMBER, STRING } from "./interface.mjs" +import { HelperInterface, NUMBER, STRING } from "./interface.mjs" import { BaseEvent } from "../events.mjs" import { Action, Actions } from "../history/index.mjs" diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index db65ea2..2886f73 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -85,15 +85,6 @@ export class DialogInterface extends Interface { show = FUNCTION } -export class HistoryInterface extends Interface { - undo = FUNCTION - redo = FUNCTION - clear = FUNCTION - addToHistory = FUNCTION - unserialize = FUNCTION - serialize = FUNCTION -} - export class LatexInterface extends Interface { /** * @param {string} markup - LaTeX markup to render From 00ab895b21212328ab74025e717d932fc175be72 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 02:38:11 +0200 Subject: [PATCH 177/249] Adding x value as argument for derivative objects. --- common/src/module/latex.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index a0e8401..8ccbeb5 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -157,7 +157,7 @@ class LatexAPI extends Module { if(args.length === 3) return `\\frac{d${args[0].removeEnclosure().replaceAll(args[1].removeEnclosure(), "x")}}{dx}` else - return `\\frac{d${args[0]}}{dx}(x)` + return `\\frac{d${args[0]}}{dx}(${args[1]})` case "integral": if(args.length === 4) return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2].removeEnclosure()} d${args[3].removeEnclosure()}` From 9017f84c0684399a3e8239d7bfa7c4a7c8a0ad30 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 18:21:03 +0200 Subject: [PATCH 178/249] Updating metadata and python package lock. --- README.md | 2 +- .../eu.ad5001.LogarithmPlotter.metainfo.xml | 38 ++-- runtime-pyside6/poetry.lock | 184 +++++++++--------- runtime-pyside6/pyproject.toml | 4 +- runtime-pyside6/setup.py | 42 ++-- 5 files changed, 132 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 8002fe0..ae252fe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![icon](https://git.ad5001.eu/Ad5001/LogarithmPlotter/raw/branch/master/LogarithmPlotter/logarithmplotter.svg) LogarithmPlotter +# ![icon](https://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg) LogarithmPlotter [![Build Status](https://ci.ad5001.eu/api/badges/Ad5001/LogarithmPlotter/status.svg)](https://ci.ad5001.eu/Ad5001/LogarithmPlotter) [![Translation status](https://hosted.weblate.org/widgets/logarithmplotter/-/logarithmplotter/svg-badge.svg)](https://hosted.weblate.org/engage/logarithmplotter/) diff --git a/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 6f90a1f..a9dbded 100644 --- a/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -66,50 +66,54 @@ Science Education - Qt https://apps.ad5001.eu/logarithmplotter/ https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues/ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ - - https://apps.ad5001.eu/img/en/logarithmplotter/gain.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/gain.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/gain.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/gain.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/en/logarithmplotter/gain.png?v=0.6 + https://apps.ad5001.eu/img/de/logarithmplotter/gain.png?v=0.6 + https://apps.ad5001.eu/img/fr/logarithmplotter/gain.png?v=0.6 + https://apps.ad5001.eu/img/hu/logarithmplotter/gain.png?v=0.6 + https://apps.ad5001.eu/img/no/logarithmplotter/gain.png?v=0.6 + https://apps.ad5001.eu/img/es/logarithmplotter/gain.png?v=0.6 Main view of LogarithmPlotter showing an asymptotic Bode magnitude plot. Die Hauptansicht des LogarithmPlotters zeigt eine asymptotische Bode-Magnitude-Darstellung. Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une magnitude de Bode. A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-magnitúdó ábrát mutat. Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-størrelsesplott. + Vista principal de LogarithmPlotter mostrando un gráfico asintótico de una magnitud de Bode. - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.6 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.6 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.6 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.6 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.6 + https://apps.ad5001.eu/img/es/logarithmplotter/phase.png?v=0.6 Main view of LogarithmPlotter showing an asymptotic Bode phase plot. Hauptansicht des LogarithmPlotters mit einer asymptotischen Bode-Phasendarstellung. Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une phase de Bode. A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-fázis ábrát mutat. Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-fasediagram. + Vista principal de LogarithmPlotter mostrando un gráfico asintótico de una fase de Bode. - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.6 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.6 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.6 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.6 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.6 + https://apps.ad5001.eu/img/es/logarithmplotter/welcome.png?v=0.6 LogarithmPlotter's welcome page. LogarithmPlotter's Willkommensseite. Page d'accueil de LogarithmPlotter. LogarithmPlotter üdvözlő oldala. LogarithmPlotters velkomstside. + Página de bienvenida de LogarithmPlotter. diff --git a/runtime-pyside6/poetry.lock b/runtime-pyside6/poetry.lock index a4727e1..07252a5 100644 --- a/runtime-pyside6/poetry.lock +++ b/runtime-pyside6/poetry.lock @@ -24,83 +24,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.1" +version = "7.6.2" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, + {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, + {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, + {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, + {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, + {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, + {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, + {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, + {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, + {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, + {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, + {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, + {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, + {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, + {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, + {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, + {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, + {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, + {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, + {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, + {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, + {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, + {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, + {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, + {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, + {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, + {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, + {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, + {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, + {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, + {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, + {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, + {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, + {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, ] [package.dependencies] @@ -261,36 +251,36 @@ setuptools = ">=42.0.0" [[package]] name = "pyside6-addons" -version = "6.7.3" +version = "6.8.0" description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Addons-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:3174cb3a373c09c98740b452e8e8f4945d64cfa18ed8d43964111d570f0dc647"}, - {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:bde1eb03dbffd089b50cd445847aaecaf4056cea84c49ea592d00f84f247251e"}, - {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:5a9e0df31345fe6caea677d916ea48b53ba86f95cc6499c57f89e392447ad6db"}, - {file = "PySide6_Addons-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:d8a19c2b2446407724c81c33ebf3217eaabd092f0f72da8130c17079e04a7813"}, + {file = "PySide6_Addons-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:aebab1e4fe63ebceccae4068768bf20959ab78f7fe01af832458837241334b5c"}, + {file = "PySide6_Addons-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4b3be260f9cc415d1a12b77a703ced18b8854f56985f4708cab5618a9554bbd6"}, + {file = "PySide6_Addons-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:7c153a685341683fac82d32926e2204747a83c13ef7b203db8ae9efe27f26a0f"}, + {file = "PySide6_Addons-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:8f7f20fb3758995580f1fb8342df3479be51958eca36db2d6f6a3304f31471de"}, ] [package.dependencies] -PySide6-Essentials = "6.7.3" -shiboken6 = "6.7.3" +PySide6-Essentials = "6.8.0" +shiboken6 = "6.8.0" [[package]] name = "pyside6-essentials" -version = "6.7.3" +version = "6.8.0" description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Essentials-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:f9e08a4e9e7dc7b5ab72fde20abce8c97df7af1b802d9743f098f577dfe1f649"}, - {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cda6fd26aead48f32e57f044d18aa75dc39265b49d7957f515ce7ac3989e7029"}, - {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:acdde06b74f26e7d26b4ae1461081b32a6cb17fcaa2a580050b5e0f0f12236c9"}, - {file = "PySide6_Essentials-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:f0950fcdcbcd4f2443336dc6a5fe692172adc225f876839583503ded0ab2f2a7"}, + {file = "PySide6_Essentials-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:c2ad37de574ed911ac2dd392e95888ee7354c4bc475259dafc31978efb710a6a"}, + {file = "PySide6_Essentials-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:da99a94806416ec1e386426a474e7d1e514c1cdf8ad171c005376f4f633e7216"}, + {file = "PySide6_Essentials-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:ae0732228e93eb882c9a93fd510819fb64b7d09d8e500912b485a604537215d6"}, + {file = "PySide6_Essentials-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:2ef7138dc7efb9f1153c1dda7a7bd6ac02badad1aa1971cc140d0b9bf962c3dc"}, ] [package.dependencies] -shiboken6 = "6.7.3" +shiboken6 = "6.8.0" [[package]] name = "pytest" @@ -384,15 +374,15 @@ type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11 [[package]] name = "shiboken6" -version = "6.7.3" +version = "6.8.0" description = "Python/C++ bindings helper module" optional = false python-versions = "<3.13,>=3.9" files = [ - {file = "shiboken6-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:285fe3cf79be3135fe1ad1e2b9ff6db3a48698887425af6aa6ed7a05a9abc3d6"}, - {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f0852e5781de78be5b13c140ec4c7fb9734e2aaf2986eb2d6a224363e03efccc"}, - {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:f0dd635178e64a45be2f84c9f33dd79ac30328da87f834f21a0baf69ae210e6e"}, - {file = "shiboken6-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:5f29325dfa86fde0274240f1f38e421303749d3174ce3ada178715b5f4719db9"}, + {file = "shiboken6-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:0d3171c496e7474ad29d73686e46e741317a9b29ae9fa30c421fa0360bc10af0"}, + {file = "shiboken6-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ad88c0e73c9e4de3723c6e6b846e651729433ff9d9086bb2b4e6d49965477d97"}, + {file = "shiboken6-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:0f62ee7c34337e2c39fff0985694224f7503328c450245c399846b72cd71c410"}, + {file = "shiboken6-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:cb98424a1f0c2d6ebf7f6be99660a121b9b22601a058e6b7efeadbc60bcd2182"}, ] [[package]] @@ -418,13 +408,13 @@ files = [ [[package]] name = "tomli" -version = "2.0.1" +version = "2.0.2" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, + {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] [[package]] @@ -449,4 +439,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "5636605737f21954e102a0110972e6bd3df07f2d5929f41fe541c7347c3ecf08" +content-hash = "fad810a5ba9b4cb5ab759c9b5641ccba2b735e12064e510c0bfe0f4766c576f1" diff --git a/runtime-pyside6/pyproject.toml b/runtime-pyside6/pyproject.toml index 5293365..cafc0cb 100644 --- a/runtime-pyside6/pyproject.toml +++ b/runtime-pyside6/pyproject.toml @@ -9,8 +9,8 @@ package-mode = false [tool.poetry.dependencies] python = ">=3.9,<3.13" -PySide6-Essentials = "^6.7" -PySide6-Addons = "^6.7" +PySide6-Essentials = "^6.8" +PySide6-Addons = "^6.8" [tool.poetry.group.packaging.dependencies] pyinstaller = "^6.10.0" diff --git a/runtime-pyside6/setup.py b/runtime-pyside6/setup.py index 08769a6..f76f1d7 100644 --- a/runtime-pyside6/setup.py +++ b/runtime-pyside6/setup.py @@ -26,27 +26,27 @@ print(sys.argv) current_dir = os.path.realpath(os.path.dirname(os.path.realpath(__file__))) # Check where to install by default -if "PREFIX" not in os.environ and sys.platform == 'linux': - from getopt import getopt - optlist, args = getopt(sys.argv, '', ['prefix=', 'root=']) - for arg,value in optlist: - if arg == "prefix" or arg == "root": - os.environ["PREFIX"] = value - if "PREFIX" not in os.environ and sys.platform == 'linux': - if "XDG_DATA_HOME" in os.environ: - os.environ["PREFIX"] = os.environ["XDG_DATA_HOME"] - else: - try: - # Checking if we have permission to write to root. - from os import makedirs, rmdir - makedirs("/usr/share/applications/test") - rmdir("/usr/share/applications/test") - os.environ["PREFIX"] = "/usr/share" - except: - if ".pybuild" in os.environ["HOME"]: # Launchpad building. - os.environ["PREFIX"] = "share" - else: - os.environ["PREFIX"] = os.environ["HOME"] + "/.local/share" +# if "PREFIX" not in os.environ and sys.platform == 'linux': +# from getopt import getopt +# optlist, args = getopt(sys.argv, '', ['prefix=', 'root=']) +# for arg,value in optlist: +# if arg == "prefix" or arg == "root": +# os.environ["PREFIX"] = value +# if "PREFIX" not in os.environ and sys.platform == 'linux': +# if "XDG_DATA_HOME" in os.environ: +# os.environ["PREFIX"] = os.environ["XDG_DATA_HOME"] +# else: +# try: +# # Checking if we have permission to write to root. +# from os import makedirs, rmdir +# makedirs("/usr/share/applications/test") +# rmdir("/usr/share/applications/test") +# os.environ["PREFIX"] = "/usr/share" +# except: +# if ".pybuild" in os.environ["HOME"]: # Launchpad building. +# os.environ["PREFIX"] = "share" +# else: +# os.environ["PREFIX"] = os.environ["HOME"] + "/.local/share" from LogarithmPlotter import __VERSION__ as pkg_version From f3307b47d98c17a95906aee5eae168400e623cd3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 19:05:34 +0200 Subject: [PATCH 179/249] Fixing bug with saving files --- common/src/module/settings.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 1530839..e6313c7 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -118,6 +118,12 @@ class SettingsAPI extends Module { this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) } + /** + * Name of the currently opened file. + * @returns {string} + */ + get saveFilename() { return this.#properties.get("saveFilename") } + /** * Zoom on the x axis of the diagram. * @returns {number} From 84adc787e5aaa1d25118da82fba00c304045712b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 19:05:53 +0200 Subject: [PATCH 180/249] Fixing typo in Spanish translation --- assets/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index 7a736b5..f365aef 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -335,7 +335,7 @@ Welcome to LogarithmPlotter - Bienvenid@ a LogarithmPlotter + Bienvenido a LogarithmPlotter From 5745587c728977be51c3a90082efd944794e1922 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 19:06:15 +0200 Subject: [PATCH 181/249] Fixing git version detection. --- runtime-pyside6/LogarithmPlotter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-pyside6/LogarithmPlotter/__init__.py b/runtime-pyside6/LogarithmPlotter/__init__.py index 2bd4967..0c5cbbb 100644 --- a/runtime-pyside6/LogarithmPlotter/__init__.py +++ b/runtime-pyside6/LogarithmPlotter/__init__.py @@ -29,7 +29,7 @@ if not is_release and which('git') is not None: # Command to check date of latest git commit cmd = ['git', 'log', '--format=%ci', '-n 1'] - cwd = realpath(join(dirname(__file__), '..')) # Root AccountFree directory. + cwd = realpath(join(dirname(__file__), '..', '..', '..')) # Root LogarithmPlotter directory. if exists(join(cwd, '.git')): date_str = check_output(cmd, cwd=cwd).decode('utf-8').split(' ')[0] try: From 7935d0134d89050111c5a14010371e22c04095de Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 19:06:33 +0200 Subject: [PATCH 182/249] Fixing wrap on Greet Screen buttons in certain locales. --- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 09e16e5..5a1ff21 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -141,7 +141,7 @@ Popup { horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 text: modelData.name - wrapMode: Text.WordWrap + wrapMode: Text.Wrap clip: true } } From c592b9221298de9565155f831e6bf1a0b837e4a8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 17:18:21 +0000 Subject: [PATCH 183/249] Translated using Weblate (Spanish) Currently translated at 100.0% (265 of 265 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- assets/i18n/lp_es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index f365aef..7a736b5 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -335,7 +335,7 @@ Welcome to LogarithmPlotter - Bienvenido a LogarithmPlotter + Bienvenid@ a LogarithmPlotter From 07e58a3a55e60d360be9f84041816bf74065151b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 19:59:13 +0000 Subject: [PATCH 184/249] Translated using Weblate (French) Currently translated at 100.0% (265 of 265 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- assets/i18n/lp_fr.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index b693568..42f084f 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -146,7 +146,7 @@ &Changelog - &Historique des modifications + &Notes de version @@ -194,7 +194,7 @@ Fetching changelog... - Récupération de l'historique des modifications… + Récupération des notes de version… @@ -341,7 +341,7 @@ Welcome to LogarithmPlotter - Bienvenue sur LogarithmPlotter + Bienvenu•e sur LogarithmPlotter @@ -382,7 +382,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Changelog - Historique des modifications + Notes de version @@ -879,12 +879,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Could not fetch changelog: Server error {}. - Impossible de récupérer l'historique des modifications : Erreur de serveur {}. + Impossible de récupérer les notes de version : Erreur de serveur {}. Could not fetch update: {}. - Impossible de récupérer l'historique des modifications : {}. + Impossible de récupérer les notes de version : {}. From 8a878b4cc12bd13a9546265dddc486cb9bc93c1a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 22:04:12 +0200 Subject: [PATCH 185/249] Storing LaTeX renders in cache directory instead of temporary to store them for later use. + Makes reponening files instantaneous. + Improves performance of 'base state' objects (e.g. A = (1, 0) or f(x) = x). --- .../LogarithmPlotter/logarithmplotter.py | 2 +- .../LogarithmPlotter/util/helper.py | 2 +- .../LogarithmPlotter/util/latex.py | 27 +++++++++++++------ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index 3264097..d620da8 100644 --- a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py +++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py @@ -164,7 +164,7 @@ def run(): app.installEventFilter(macos_file_open_handler) helper = Helper(pwd, tmpfile) - latex = Latex(tempdir) + latex = Latex() engine, js_globals = create_engine(helper, latex, dep_time) if len(engine.rootObjects()) == 0: # No root objects loaded diff --git a/runtime-pyside6/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index d2fe631..6db4570 100644 --- a/runtime-pyside6/LogarithmPlotter/util/helper.py +++ b/runtime-pyside6/LogarithmPlotter/util/helper.py @@ -42,7 +42,7 @@ def show_message(msg: str) -> None: Shows a GUI message if GUI messages are enabled """ if SHOW_GUI_MESSAGES: - QMessageBox.warning(None, "LogarithmPlotter", msg, QMessageBox.OK) + QMessageBox.warning(None, "LogarithmPlotter", msg) else: raise InvalidFileException(msg) diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 2c650ce..8f75aa8 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -20,13 +20,23 @@ from PySide6.QtCore import QObject, Slot, Property, QCoreApplication from PySide6.QtGui import QImage, QColor from PySide6.QtWidgets import QMessageBox -from os import path, remove +from os import path, remove, environ, makedirs from string import Template -from tempfile import TemporaryDirectory from subprocess import Popen, TimeoutExpired, PIPE +from platform import system +from hashlib import sha512 from shutil import which from sys import argv +CACHE_PATH = { + "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") + if "XDG_CONFIG_HOME" in environ else + path.join(path.expanduser("~"), ".cache", "LogarithmPlotter"), + "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "cache"), + "Darwin": path.join(path.expanduser("~"), "Library", "Caches", "LogarithmPlotter"), +}[system()] + + """ Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) installation and collects the binary path in the DVIPNG_PATH variable. @@ -75,9 +85,10 @@ class Latex(QObject): dvipng to be installed on the system. """ - def __init__(self, tempdir: TemporaryDirectory): + def __init__(self): QObject.__init__(self) - self.tempdir = tempdir + self.tempdir = path.join(CACHE_PATH, "latex") + makedirs(self.tempdir, exist_ok=True) @Property(bool) def latexSupported(self) -> bool: @@ -117,7 +128,7 @@ class Latex(QObject): if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file - latex_path = path.join(self.tempdir.name, str(markup_hash)) + latex_path = path.join(self.tempdir, str(markup_hash)) # If the formula is just recolored or the font is just changed, no need to recreate the DVI. if not path.exists(latex_path + ".dvi"): self.create_latex_doc(latex_path, latex_markup) @@ -148,8 +159,8 @@ class Latex(QObject): """ Standardizes export path for renders. """ - markup_hash = "render" + str(hash(latex_markup)) - export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') + markup_hash = "render" + str(sha512(latex_markup.encode()).hexdigest()) + export_path = path.join(self.tempdir, f'{markup_hash}_{int(font_size)}_{color.rgb()}') return markup_hash, export_path def create_latex_doc(self, export_path: str, latex_markup: str): @@ -193,7 +204,7 @@ class Latex(QObject): Runs a subprocess and handles exceptions and messages them to the user. """ cmd = " ".join(process) - proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) + proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir) try: out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: From e2d259f8669e74a1a5897d3264a066d5a6f71000 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 22:18:35 +0200 Subject: [PATCH 186/249] Fixing French localization. --- assets/i18n/lp_fr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index 42f084f..fd806a2 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -341,7 +341,7 @@ Welcome to LogarithmPlotter - Bienvenu•e sur LogarithmPlotter + Bienvenu·e sur LogarithmPlotter From 42d5add810932625335b9f675eb4e5a48c81560d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 11 Oct 2024 22:33:57 +0200 Subject: [PATCH 187/249] Fixing tests and LaTeX --- .../LogarithmPlotter/logarithmplotter.py | 33 ++++++++++++------- .../LogarithmPlotter/util/latex.py | 13 ++------ .../LogarithmPlotter/util/native.py | 4 +++ runtime-pyside6/tests/test_latex.py | 2 +- runtime-pyside6/tests/test_main.py | 11 +++---- runtime-pyside6/tests/test_update.py | 2 +- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index d620da8..115083a 100644 --- a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py +++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py @@ -17,9 +17,9 @@ """ from os import getcwd, chdir, environ, path -from platform import release as os_release +from platform import system as os_name, release as OS_RELEASE from sys import path as sys_path -from sys import platform, argv, exit +from sys import argv, exit from tempfile import TemporaryDirectory from time import time @@ -49,6 +49,18 @@ from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex from LogarithmPlotter.util.js import PyJSValue +OS_NAME = os_name() + + +CACHE_PATH = { + "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") + if "XDG_CONFIG_HOME" in environ else + path.join(path.expanduser("~"), ".cache", "LogarithmPlotter"), + "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "cache"), + "Darwin": path.join(path.expanduser("~"), "Library", "Caches", "LogarithmPlotter"), +}[OS_NAME] + + LINUX_THEMES = { # See https://specifications.freedesktop.org/menu-spec/latest/onlyshowin-registry.html "COSMIC": "Basic", "GNOME": "Basic", @@ -82,11 +94,10 @@ def get_linux_theme() -> str: def get_platform_qt_style(os) -> str: return { - "linux": get_linux_theme(), - "freebsd": get_linux_theme(), - "win32": "Universal" if os_release() in ["10", "11", "12", "13", "14"] else "Windows", - "cygwin": "Fusion", - "darwin": "macOS" + "Linux": get_linux_theme(), + "Windows": "Universal" if OS_RELEASE() in ["10", "11", "12", "13", "14"] else "Windows", + "Darwin": "macOS", + "Android": "Material" }[os] @@ -147,7 +158,7 @@ def run(): config.init() if not 'QT_QUICK_CONTROLS_STYLE' in environ: - QQuickStyle.setStyle(get_platform_qt_style(platform)) + QQuickStyle.setStyle(get_platform_qt_style(OS_NAME)) dep_time = time() print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") @@ -159,12 +170,12 @@ def run(): # Installing macOS file handler. macos_file_open_handler = None - if platform == "darwin": + if OS_NAME == "Darwin": macos_file_open_handler = native.MacOSFileOpenHandler() app.installEventFilter(macos_file_open_handler) helper = Helper(pwd, tmpfile) - latex = Latex() + latex = Latex(CACHE_PATH) engine, js_globals = create_engine(helper, latex, dep_time) if len(engine.rootObjects()) == 0: # No root objects loaded @@ -177,7 +188,7 @@ def run(): js_globals.Modules.IO.loadDiagram(argv[-1]) chdir(path.dirname(path.realpath(__file__))) - if platform == "darwin": + if OS_NAME == "Darwin": macos_file_open_handler.init_io(js_globals.Modules.IO) # Check for LaTeX installation if LaTeX support is enabled diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 8f75aa8..df32d46 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -23,19 +23,10 @@ from PySide6.QtWidgets import QMessageBox from os import path, remove, environ, makedirs from string import Template from subprocess import Popen, TimeoutExpired, PIPE -from platform import system from hashlib import sha512 from shutil import which from sys import argv -CACHE_PATH = { - "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") - if "XDG_CONFIG_HOME" in environ else - path.join(path.expanduser("~"), ".cache", "LogarithmPlotter"), - "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "cache"), - "Darwin": path.join(path.expanduser("~"), "Library", "Caches", "LogarithmPlotter"), -}[system()] - """ Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) @@ -85,9 +76,9 @@ class Latex(QObject): dvipng to be installed on the system. """ - def __init__(self): + def __init__(self, cache_path): QObject.__init__(self) - self.tempdir = path.join(CACHE_PATH, "latex") + self.tempdir = path.join(cache_path, "latex") makedirs(self.tempdir, exist_ok=True) @Property(bool) diff --git a/runtime-pyside6/LogarithmPlotter/util/native.py b/runtime-pyside6/LogarithmPlotter/util/native.py index 7e32119..aefc310 100644 --- a/runtime-pyside6/LogarithmPlotter/util/native.py +++ b/runtime-pyside6/LogarithmPlotter/util/native.py @@ -49,3 +49,7 @@ class MacOSFileOpenHandler(QObject): else: # standard event processing return QObject.eventFilter(self, obj, event) + + + + diff --git a/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index f02832e..d74f9f1 100644 --- a/runtime-pyside6/tests/test_latex.py +++ b/runtime-pyside6/tests/test_latex.py @@ -31,7 +31,7 @@ latex.SHOW_GUI_MESSAGES = False @pytest.fixture() def latex_obj(): directory = TemporaryDirectory() - obj = latex.Latex(directory) + obj = latex.Latex(directory.name) if not obj.checkLatexInstallation(): raise Exception("Cannot run LaTeX tests without a proper LaTeX installation. Make sure to install a LaTeX distribution, DVIPNG, and the calligra package, and run the tests again.") yield obj diff --git a/runtime-pyside6/tests/test_main.py b/runtime-pyside6/tests/test_main.py index d8a56b6..047e21f 100644 --- a/runtime-pyside6/tests/test_main.py +++ b/runtime-pyside6/tests/test_main.py @@ -39,11 +39,10 @@ THEMES = [ ] OS_PLATFORMS = [ - "linux", - "freebsd", - "win32", - "cygwin", - "darwin" + "Linux", + "Windows", + "Darwin", + "Android" ] @pytest.fixture() @@ -91,7 +90,7 @@ class TestMain: # Engine tmpfile, tempdir = temporary helper = Helper(".", tmpfile) - latex = Latex(tempdir) + latex = Latex(tempdir.name) engine, js_globals = create_engine(helper, latex, 0) assert len(engine.rootObjects()) > 0 # QML File loaded. assert type(engine.rootContext().contextProperty("TestBuild")) is bool diff --git a/runtime-pyside6/tests/test_update.py b/runtime-pyside6/tests/test_update.py index 9f65597..5e1a705 100644 --- a/runtime-pyside6/tests/test_update.py +++ b/runtime-pyside6/tests/test_update.py @@ -60,7 +60,7 @@ def test_update(qtbot): def test_update_checker(qtbot): update_info = check_for_updates('0.6.0', MockWindow()) - assert QThreadPool.globalInstance().activeThreadCount() == 1 + assert QThreadPool.globalInstance().activeThreadCount() >= 1 qtbot.waitSignal(update_info.got_update_info, timeout=10000) argv.append("--no-check-for-updates") update_info = check_for_updates('0.6.0', MockWindow()) From 0abb22130f4dca37a310afe9c7a09427ee068f47 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 00:40:46 +0200 Subject: [PATCH 188/249] Disable domain tests, started base tests. --- common/package-lock.json | 25 +++++++ common/package.json | 2 + common/src/events.mjs | 3 +- common/test/general/events.mjs | 122 +++++++++++++++++++++++++++++++++ common/test/hooks.mjs | 2 - common/test/math/domain.mjs | 86 +++++++++++------------ 6 files changed, 194 insertions(+), 46 deletions(-) create mode 100644 common/test/general/events.mjs diff --git a/common/package-lock.json b/common/package-lock.json index b90e4f5..ee15bf5 100644 --- a/common/package-lock.json +++ b/common/package-lock.json @@ -19,9 +19,11 @@ }, "devDependencies": { "@types/chai": "^5.0.0", + "@types/chai-spies": "^1.0.6", "@types/mocha": "^10.0.8", "chai": "^5.1.1", "chai-as-promised": "^8.0.0", + "chai-spies": "^1.1.0", "esm": "^3.2.25", "mocha": "^10.7.3" } @@ -2199,6 +2201,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/chai-spies": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/chai-spies/-/chai-spies-1.0.6.tgz", + "integrity": "sha512-xkk4HmhBB9OQeTAifa9MJ+6R5/Rq9+ungDe4JidZD+vqZVeiWZwc2i7/pd1ZKjyGlSBIQePoWdyUyFUGT0rv5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -2514,6 +2526,19 @@ "chai": ">= 2.1.2 < 6" } }, + "node_modules/chai-spies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chai-spies/-/chai-spies-1.1.0.tgz", + "integrity": "sha512-ikaUhQvQWchRYj2K54itFp3nrcxaFRpSDQxDlRzSn9aWgu9Pi7lD8yFxTso4WnQ39+WZ69oB/qOvqp+isJIIWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + }, + "peerDependencies": { + "chai": "*" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", diff --git a/common/package.json b/common/package.json index 9ef203c..6940d87 100644 --- a/common/package.json +++ b/common/package.json @@ -24,9 +24,11 @@ }, "devDependencies": { "@types/chai": "^5.0.0", + "@types/chai-spies": "^1.0.6", "@types/mocha": "^10.0.8", "chai": "^5.1.1", "chai-as-promised": "^8.0.0", + "chai-spies": "^1.1.0", "esm": "^3.2.25", "mocha": "^10.7.3" } diff --git a/common/src/events.mjs b/common/src/events.mjs index dbdd00f..702fc7d 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -79,7 +79,8 @@ export class BaseEventEmitter { if(eventType.includes(" ")) { // Unlisten to several different events with the same listener. let found = false for(const type of eventType.split(" ")) - found ||= this.off(eventType, eventListener) + found ||= this.off(type, eventListener) + return found } else { if(!this.constructor.emits.includes(eventType)) { const className = this.constructor.name diff --git a/common/test/general/events.mjs b/common/test/general/events.mjs new file mode 100644 index 0000000..f82875f --- /dev/null +++ b/common/test/general/events.mjs @@ -0,0 +1,122 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { BaseEventEmitter, BaseEvent } from "../../src/events.mjs" + +import { describe, it } from "mocha" +import { expect, use } from "chai" +import spies from "chai-spies" + +// Setting up modules +const { spy } = use(spies) + + +class MockEmitter extends BaseEventEmitter { + static emits = ["example1", "example2"] +} + +class MockEvent1 extends BaseEvent { + constructor() { + super("example1") + } +} + +class MockEvent2 extends BaseEvent { + constructor(parameter) { + super("example2") + this.parameter = parameter + } +} + +const sandbox = spy.sandbox() + +describe("Events", function() { + + afterEach(() => { + sandbox.restore() + }) + + it("should forward events to all of its listeners", function() { + const emitter = new MockEmitter() + const listener1 = spy() + const listener2 = spy() + emitter.on("example1", listener1) + emitter.on("example1", listener2) + emitter.emit(new MockEvent1()) + expect(listener1).to.have.been.called.once + expect(listener2).to.have.been.called.once + }) + + it("should forward multiple events to a singular listener", function() { + const emitter = new MockEmitter() + const listener = spy() + const mockEvent1 = new MockEvent1() + const mockEvent2 = new MockEvent2(3) + emitter.on("example1 example2", listener) + emitter.emit(mockEvent1) + emitter.emit(mockEvent2) + expect(listener).to.have.been.called.twice + expect(listener).to.have.been.called.with.exactly(mockEvent1) + expect(listener).to.have.been.called.with.exactly(mockEvent2) + }) + + it("should be able to remove listeners", function() { + const emitter = new MockEmitter() + const listener = spy() + emitter.on("example1", listener) + const removedFromEventItDoesntListenTo = emitter.off("example2", listener) + const removedFromEventItListensTo = emitter.off("example1", listener) + const removedFromEventASecondTime = emitter.off("example1", listener) + expect(removedFromEventItDoesntListenTo).to.be.false + expect(removedFromEventItListensTo).to.be.true + expect(removedFromEventASecondTime).to.be.false + emitter.on("example1 example2", listener) + const removedFromBothEvents = emitter.off("example1 example2", listener) + expect(removedFromBothEvents).to.be.true + emitter.on("example1", listener) + const removedFromOneOfTheEvents = emitter.off("example1 example2", listener) + expect(removedFromOneOfTheEvents).to.be.true + }) + + it("should be able to remove listening to one event when listener listens to multiple", function() { + const emitter = new MockEmitter() + const listener = spy() + const mockEvent1 = new MockEvent1() + const mockEvent2 = new MockEvent2(3) + emitter.on("example1 example2", listener) + // Disable listener for example1 + emitter.off("example1", listener) + emitter.emit(mockEvent1) + emitter.emit(mockEvent2) + expect(listener).to.have.been.called.once + expect(listener).to.have.been.called.with.exactly(mockEvent2) + }) + + it("shouldn't be able to listen/unlisten/emit inexistant events", function() { + const emitter = new MockEmitter() + const listener = spy() + expect(() => emitter.on("inexistant", listener)).to.throw(Error) + expect(() => emitter.off("inexistant", listener)).to.throw(Error) + expect(() => emitter.emit(new BaseEvent("inexistant"))).to.throw(Error) + }) + + it("shouldn't be able to emit non-events", function() { + const emitter = new MockEmitter() + expect(() => emitter.emit("not-an-event")).to.throw(Error) + }) +}) \ No newline at end of file diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index e48525e..0f3ebda 100644 --- a/common/test/hooks.mjs +++ b/common/test/hooks.mjs @@ -19,12 +19,10 @@ import * as fs from "./mock/fs.mjs"; import Qt from "./mock/qt.mjs"; import { MockHelper } from "./mock/helper.mjs"; import { MockLatex } from "./mock/latex.mjs"; -import Modules from "../src/module/index.mjs"; function setup() { globalThis.Helper = new MockHelper() globalThis.Latex = new MockLatex() - Modules.Latex.initialize({ latex: Latex, helper: Helper }) } setup() diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs index c00384f..e32dbd1 100644 --- a/common/test/math/domain.mjs +++ b/common/test/math/domain.mjs @@ -19,46 +19,46 @@ import { describe, it } from "mocha" import { expect } from "chai" -import { Domain, parseDomainSimple } from "../../src/math/domain.mjs" - -describe("math.domain", function() { - describe("#parseDomainSimple", function() { - it("returns predefined domains", function() { - const predefinedToCheck = [ - // Real domains - { domain: Domain.R, shortcuts: ["R", "ℝ"] }, - // Zero exclusive real domains - { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] }, - // Real positive domains - { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] }, - // Zero-exclusive real positive domains - { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] }, - // Real negative domain - { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] }, - // Zero-exclusive real negative domains - { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] }, - // Natural integers domain - { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] }, - // Zero-exclusive natural integers domain - { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] }, - // Logarithmic natural domains - { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] }, - // All integers domains - { domain: Domain.Z, shortcuts: ["Z", "ℤ"] }, - // Zero-exclusive all integers domain - { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] }, - // Negative integers domain - { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] }, - // Zero-exclusive negative integers domain - { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] }, - ] - - // Real domains - for(const { domain, shortcuts } of predefinedToCheck) - for(const shortcut of shortcuts) - expect(parseDomainSimple(shortcut)).to.be.equal(domain) - }) - - it("") - }) -}) +// import { Domain, parseDomainSimple } from "../../src/math/domain.mjs" +// +// describe("math.domain", function() { +// describe("#parseDomainSimple", function() { +// it("returns predefined domains", function() { +// const predefinedToCheck = [ +// // Real domains +// { domain: Domain.R, shortcuts: ["R", "ℝ"] }, +// // Zero exclusive real domains +// { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] }, +// // Real positive domains +// { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] }, +// // Zero-exclusive real positive domains +// { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] }, +// // Real negative domain +// { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] }, +// // Zero-exclusive real negative domains +// { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] }, +// // Natural integers domain +// { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] }, +// // Zero-exclusive natural integers domain +// { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] }, +// // Logarithmic natural domains +// { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] }, +// // All integers domains +// { domain: Domain.Z, shortcuts: ["Z", "ℤ"] }, +// // Zero-exclusive all integers domain +// { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] }, +// // Negative integers domain +// { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] }, +// // Zero-exclusive negative integers domain +// { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] }, +// ] +// +// // Real domains +// for(const { domain, shortcuts } of predefinedToCheck) +// for(const shortcut of shortcuts) +// expect(parseDomainSimple(shortcut)).to.be.equal(domain) +// }) +// +// it("") +// }) +// }) From 885d1f5dc321f31b0e655617d2f55dd659b96c9c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 03:22:49 +0200 Subject: [PATCH 189/249] Adding test for Utils --- common/src/module/latex.mjs | 4 +- common/src/utils.mjs | 405 +++++++++++++++++---------------- common/test/general/events.mjs | 14 +- common/test/general/utils.mjs | 183 +++++++++++++++ 4 files changed, 404 insertions(+), 202 deletions(-) create mode 100644 common/test/general/utils.mjs diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 8ccbeb5..4ff81cb 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -137,9 +137,9 @@ class LatexAPI extends Module { */ parif(elem, contents) { elem = elem.toString() - if(elem[0] !== "(" && elem[elem.length - 1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) + if(elem[0] !== "(" && elem.at(-1) !== ")" && contents.some(x => elem.indexOf(x) > 0)) return this.par(elem) - if(elem[0] === "(" && elem[elem.length - 1] === ")") + if(elem[0] === "(" && elem.at(-1) === ")") return elem.removeEnclosure() return elem } diff --git a/common/src/utils.mjs b/common/src/utils.mjs index 094147d..0e451f4 100644 --- a/common/src/utils.mjs +++ b/common/src/utils.mjs @@ -21,14 +21,16 @@ * Replaces latin characters with their uppercase versions. * @return {string} */ -String.prototype.toLatinUppercase = String.prototype.toLatinUppercase || function() { +String.prototype.toLatinUppercase = function() { return this.replace(/[a-z]/g, function(match) { return match.toUpperCase() }) } /** - * Removes the 'enclosers' of a string (e.g. quotes, parentheses, brackets...) + * Removes the first and last character of a string + * Used to remove enclosing characters like quotes, parentheses, brackets... + * @note Does NOT check for their existence ahead of time. * @return {string} */ String.prototype.removeEnclosure = function() { @@ -43,126 +45,126 @@ String.prototype.removeEnclosure = function() { * @return {number} */ Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) { - const p = Math.pow(10, decimalPlaces); - const n = (this * p) * (1 + Number.EPSILON); - return Math.round(n) / p; + const p = Math.pow(10, decimalPlaces) + const n = (this * p) * (1 + Number.EPSILON) + return Math.round(n) / p } -const powerpos = { - "-": "⁻", - "+": "⁺", - "=": "⁼", - " ": " ", - "(": "⁽", - ")": "⁾", - "0": "⁰", - "1": "¹", - "2": "²", - "3": "³", - "4": "⁴", - "5": "⁵", - "6": "⁶", - "7": "⁷", - "8": "⁸", - "9": "⁹", - "a": "ᵃ", - "b": "ᵇ", - "c": "ᶜ", - "d": "ᵈ", - "e": "ᵉ", - "f": "ᶠ", - "g": "ᵍ", - "h": "ʰ", - "i": "ⁱ", - "j": "ʲ", - "k": "ᵏ", - "l": "ˡ", - "m": "ᵐ", - "n": "ⁿ", - "o": "ᵒ", - "p": "ᵖ", - "r": "ʳ", - "s": "ˢ", - "t": "ᵗ", - "u": "ᵘ", - "v": "ᵛ", - "w": "ʷ", - "x": "ˣ", - "y": "ʸ", - "z": "ᶻ" -} +const CHARACTER_TO_POWER = new Map([ + ["-", "⁻"], + ["+", "⁺"], + ["=", "⁼"], + [" ", " "], + ["(", "⁽"], + [")", "⁾"], + ["0", "⁰"], + ["1", "¹"], + ["2", "²"], + ["3", "³"], + ["4", "⁴"], + ["5", "⁵"], + ["6", "⁶"], + ["7", "⁷"], + ["8", "⁸"], + ["9", "⁹"], + ["a", "ᵃ"], + ["b", "ᵇ"], + ["c", "ᶜ"], + ["d", "ᵈ"], + ["e", "ᵉ"], + ["f", "ᶠ"], + ["g", "ᵍ"], + ["h", "ʰ"], + ["i", "ⁱ"], + ["j", "ʲ"], + ["k", "ᵏ"], + ["l", "ˡ"], + ["m", "ᵐ"], + ["n", "ⁿ"], + ["o", "ᵒ"], + ["p", "ᵖ"], + ["r", "ʳ"], + ["s", "ˢ"], + ["t", "ᵗ"], + ["u", "ᵘ"], + ["v", "ᵛ"], + ["w", "ʷ"], + ["x", "ˣ"], + ["y", "ʸ"], + ["z", "ᶻ"] +]) -const exponents = [ - "⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹" +const CHARACTER_TO_INDICE = new Map([ + ["-", "₋"], + ["+", "₊"], + ["=", "₌"], + ["(", "₍"], + [")", "₎"], + [" ", " "], + ["0", "₀"], + ["1", "₁"], + ["2", "₂"], + ["3", "₃"], + ["4", "₄"], + ["5", "₅"], + ["6", "₆"], + ["7", "₇"], + ["8", "₈"], + ["9", "₉"], + ["a", "ₐ"], + ["e", "ₑ"], + ["h", "ₕ"], + ["i", "ᵢ"], + ["j", "ⱼ"], + ["k", "ₖ"], + ["l", "ₗ"], + ["m", "ₘ"], + ["n", "ₙ"], + ["o", "ₒ"], + ["p", "ₚ"], + ["r", "ᵣ"], + ["s", "ₛ"], + ["t", "ₜ"], + ["u", "ᵤ"], + ["v", "ᵥ"], + ["x", "ₓ"] +]) + +const EXPONENTS = [ + "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" ] -const exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') +const EXPONENTS_REG = new RegExp("([" + EXPONENTS.join("") + "]+)", "g") -const indicepos = { - "-": "₋", - "+": "₊", - "=": "₌", - "(": "₍", - ")": "₎", - " ": " ", - "0": "₀", - "1": "₁", - "2": "₂", - "3": "₃", - "4": "₄", - "5": "₅", - "6": "₆", - "7": "₇", - "8": "₈", - "9": "₉", - "a": "ₐ", - "e": "ₑ", - "h": "ₕ", - "i": "ᵢ", - "j": "ⱼ", - "k": "ₖ", - "l": "ₗ", - "m": "ₘ", - "n": "ₙ", - "o": "ₒ", - "p": "ₚ", - "r": "ᵣ", - "s": "ₛ", - "t": "ₜ", - "u": "ᵤ", - "v": "ᵥ", - "x": "ₓ", -} -// Put a text in sup position +/** + * Put a text in sup position + * @param {string} text + * @return {string} + */ export function textsup(text) { let ret = "" text = text.toString() - for (let i = 0; i < text.length; i++) { - if(Object.keys(powerpos).indexOf(text[i]) >= 0) { - ret += powerpos[text[i]] - } else { - ret += text[i] - } - } + for(let letter of text) + ret += CHARACTER_TO_POWER.has(letter) ? CHARACTER_TO_POWER.get(letter) : letter return ret } -// Put a text in sub position +/** + * Put a text in sub position + * @param {string} text + * @return {string} + */ export function textsub(text) { let ret = "" text = text.toString() - for (let i = 0; i < text.length; i++) { - if(Object.keys(indicepos).indexOf(text[i]) >= 0) { - ret += indicepos[text[i]] - } else { - ret += text[i] - } - } + for(let letter of text) + ret += CHARACTER_TO_INDICE.has(letter) ? CHARACTER_TO_INDICE.get(letter) : letter return ret } /** * Simplifies (mathematically) a mathematical expression. + * @deprecated * @param {string} str - Expression to parse * @returns {string} */ @@ -185,37 +187,43 @@ export function simplifyExpression(str) { // n1 & n3 are multiplied, opeM is the main operation (- or +). // Putting all n in form of number //n2 = n2 == undefined ? 1 : parseFloat(n) - n1 = m1 === undefined ? 1 : eval(m1 + '1') - n2 = m2 === undefined ? 1 : eval('1' + m2) - n3 = m3 === undefined ? 1 : eval(m3 + '1') - n4 = m4 === undefined ? 1 : eval('1' + m4) - //let [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) - // Falling back to * in case it does not exist (the corresponding n would be 1) - [ope2, ope4] = [ope2, ope4].map(ope => ope === '/' ? '/' : '*') - let coeff1 = n1*n2 - let coeff2 = n3*n4 - let coefficient = coeff1+coeff2-(opeM === '-' ? 2*coeff2 : 0) - + n1 = m1 === undefined ? 1 : eval(m1 + "1") + n2 = m2 === undefined ? 1 : eval("1" + m2) + n3 = m3 === undefined ? 1 : eval(m3 + "1") + n4 = m4 === undefined ? 1 : eval("1" + m4) + //let [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) + // Falling back to * in case it does not exist (the corresponding n would be 1) + [ope2, ope4] = [ope2, ope4].map(ope => ope === "/" ? "/" : "*") + let coeff1 = n1 * n2 + let coeff2 = n3 * n4 + let coefficient = coeff1 + coeff2 - (opeM === "-" ? 2 * coeff2 : 0) + return `${coefficient} * π` } ], [ // Removing parenthesis when content is only added from both sides. /(^|[+-] |\()\(([^)(]+)\)($| [+-]|\))/g, - function(match, b4, middle, after) {return `${b4}${middle}${after}`} + function(match, b4, middle, after) { + return `${b4}${middle}${after}` + } ], [ // Removing parenthesis when content is only multiplied. /(^|[*\/] |\()\(([^)(+-]+)\)($| [*\/+-]|\))/g, - function(match, b4, middle, after) {return `${b4}${middle}${after}`} + function(match, b4, middle, after) { + return `${b4}${middle}${after}` + } ], [ // Removing parenthesis when content is only multiplied. /(^|[*\/+-] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, - function(match, b4, middle, after) {return `${b4}${middle}${after}`} + function(match, b4, middle, after) { + return `${b4}${middle}${after}` + } ], [// Simplification additions/subtractions. /(^|[^*\/] |\()([-.\d]+) [+-] (\([^)(]+\)|[^)(]+) [+-] ([-.\d]+)($| [^*\/]|\))/g, function(match, b4, n1, op1, middle, op2, n2, after) { let total - if(op2 === '+') { + if(op2 === "+") { total = parseFloat(n1) + parseFloat(n2) } else { total = parseFloat(n1) - parseFloat(n2) @@ -224,14 +232,14 @@ export function simplifyExpression(str) { } ], [// Simplification multiplications/divisions. - /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, + /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, function(match, n1, op1, middle, op2, n2) { - if(parseInt(n1) === n1 && parseInt(n2) === n2 && op2 === '/' && - (parseInt(n1) / parseInt(n2)) % 1 !== 0) { + if(parseInt(n1) === n1 && parseInt(n2) === n2 && op2 === "/" && + (parseInt(n1) / parseInt(n2)) % 1 !== 0) { // Non int result for int division. return `(${n1} / ${n2}) ${op1} ${middle}` } else { - if(op2 === '*') { + if(op2 === "*") { return `${parseFloat(n1) * parseFloat(n2)} ${op1} ${middle}` } else { return `${parseFloat(n1) / parseFloat(n2)} ${op1} ${middle}` @@ -245,17 +253,17 @@ export function simplifyExpression(str) { let str = middle // Replace all groups while(/\([^)(]+\)/g.test(str)) - str = str.replace(/\([^)(]+\)/g, '') + str = str.replace(/\([^)(]+\)/g, "") // There shouldn't be any more parenthesis // If there is, that means the 2 parenthesis are needed. - if(!str.includes(')') && !str.includes('(')) { + if(!str.includes(")") && !str.includes("(")) { return middle } else { return `(${middle})` } - + } - ], + ] // Simple simplifications // [/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'], // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], @@ -268,7 +276,7 @@ export function simplifyExpression(str) { // [/(^| |\() /g, '$1'], // [/ ($|\))/g, '$1'], ] - + // Replacements let found do { @@ -286,24 +294,35 @@ export function simplifyExpression(str) { /** * Transforms a mathematical expression to make it readable by humans. * NOTE: Will break parsing of expression. + * @deprecated * @param {string} str - Expression to parse. * @returns {string} */ export function makeExpressionReadable(str) { let replacements = [ // letiables - [/pi/g, 'π'], - [/Infinity/g, '∞'], - [/inf/g, '∞'], + [/pi/g, "π"], + [/Infinity/g, "∞"], + [/inf/g, "∞"], // Other - [/ \* /g, '×'], - [/ \^ /g, '^'], - [/\^\(([\d\w+-]+)\)/g, function(match, p1) { return textsup(p1) }], - [/\^([\d\w+-]+)/g, function(match, p1) { return textsup(p1) }], - [/_\(([\d\w+-]+)\)/g, function(match, p1) { return textsub(p1) }], - [/_([\d\w+-]+)/g, function(match, p1) { return textsub(p1) }], - [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], - [/(\d|\))×/g, '$1'], + [/ \* /g, "×"], + [/ \^ /g, "^"], + [/\^\(([\d\w+-]+)\)/g, function(match, p1) { + return textsup(p1) + }], + [/\^([\d\w+-]+)/g, function(match, p1) { + return textsup(p1) + }], + [/_\(([\d\w+-]+)\)/g, function(match, p1) { + return textsub(p1) + }], + [/_([\d\w+-]+)/g, function(match, p1) { + return textsub(p1) + }], + [/\[([^\[\]]+)\]/g, function(match, p1) { + return textsub(p1) + }], + [/(\d|\))×/g, "$1"], [/integral\((.+),\s?(.+),\s?["'](.+)["'],\s?["'](.+)["']\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` @@ -312,10 +331,10 @@ export function makeExpressionReadable(str) { } }], [/derivative\(?["'](.+)["'], ?["'](.+)["'], ?(.+)\)?/g, function(match, p1, body, p2, p3, by, p4, x) { - return `d(${body.replace(new RegExp(by, 'g'), 'x')})/dx` + return `d(${body.replace(new RegExp(by, "g"), "x")})/dx` }] ] - + // str = simplifyExpression(str) // Replacements for(let replacement of replacements) @@ -324,6 +343,48 @@ export function makeExpressionReadable(str) { return str } +/** @type {[RegExp, string][]} */ +const replacements = [ + // Greek letters + [/(\W|^)al(pha)?(\W|$)/g, "$1α$3"], + [/(\W|^)be(ta)?(\W|$)/g, "$1β$3"], + [/(\W|^)ga(mma)?(\W|$)/g, "$1γ$3"], + [/(\W|^)de(lta)?(\W|$)/g, "$1δ$3"], + [/(\W|^)ep(silon)?(\W|$)/g, "$1ε$3"], + [/(\W|^)ze(ta)?(\W|$)/g, "$1ζ$3"], + [/(\W|^)et(a)?(\W|$)/g, "$1η$3"], + [/(\W|^)th(eta)?(\W|$)/g, "$1θ$3"], + [/(\W|^)io(ta)?(\W|$)/g, "$1ι$3"], + [/(\W|^)ka(ppa)?(\W|$)/g, "$1κ$3"], + [/(\W|^)la(mbda)?(\W|$)/g, "$1λ$3"], + [/(\W|^)mu(\W|$)/g, "$1μ$2"], + [/(\W|^)nu(\W|$)/g, "$1ν$2"], + [/(\W|^)xi(\W|$)/g, "$1ξ$2"], + [/(\W|^)rh(o)?(\W|$)/g, "$1ρ$3"], + [/(\W|^)si(gma)?(\W|$)/g, "$1σ$3"], + [/(\W|^)ta(u)?(\W|$)/g, "$1τ$3"], + [/(\W|^)up(silon)?(\W|$)/g, "$1υ$3"], + [/(\W|^)ph(i)?(\W|$)/g, "$1φ$3"], + [/(\W|^)ch(i)?(\W|$)/g, "$1χ$3"], + [/(\W|^)ps(i)?(\W|$)/g, "$1ψ$3"], + [/(\W|^)om(ega)?(\W|$)/g, "$1ω$3"], + // Capital greek letters + [/(\W|^)gga(mma)?(\W|$)/g, "$1Γ$3"], + [/(\W|^)gde(lta)?(\W|$)/g, "$1Δ$3"], + [/(\W|^)gth(eta)?(\W|$)/g, "$1Θ$3"], + [/(\W|^)gla(mbda)?(\W|$)/g, "$1Λ$3"], + [/(\W|^)gxi(\W|$)/g, "$1Ξ$2"], + [/(\W|^)gpi(\W|$)/g, "$1Π$2"], + [/(\W|^)gsi(gma)?(\W|$)/g, "$1Σ$3"], + [/(\W|^)gph(i)?(\W|$)/g, "$1Φ$3"], + [/(\W|^)gps(i)?(\W|$)/g, "$1Ψ$3"], + [/(\W|^)gom(ega)?(\W|$)/g, "$1Ω$3"], + // Array elements + [/\[([^\]\[]+)\]/g, function(match, p1) { + return textsub(p1) + }] +] + /** * Parses a variable name to make it readable by humans. * @@ -332,65 +393,24 @@ export function makeExpressionReadable(str) { * @returns {string} - The parsed name */ export function parseName(str, removeUnallowed = true) { - let replacements = [ - // Greek letters - [/([^a-z]|^)al(pha)?([^a-z]|$)/g, '$1α$3'], - [/([^a-z]|^)be(ta)?([^a-z]|$)/g, '$1β$3'], - [/([^a-z]|^)ga(mma)?([^a-z]|$)/g, '$1γ$3'], - [/([^a-z]|^)de(lta)?([^a-z]|$)/g, '$1δ$3'], - [/([^a-z]|^)ep(silon)?([^a-z]|$)/g, '$1ε$3'], - [/([^a-z]|^)ze(ta)?([^a-z]|$)/g, '$1ζ$3'], - [/([^a-z]|^)et(a)?([^a-z]|$)/g, '$1η$3'], - [/([^a-z]|^)th(eta)?([^a-z]|$)/g, '$1θ$3'], - [/([^a-z]|^)io(ta)?([^a-z]|$)/g, '$1ι$3'], - [/([^a-z]|^)ka(ppa)([^a-z]|$)?/g, '$1κ$3'], - [/([^a-z]|^)la(mbda)?([^a-z]|$)/g, '$1λ$3'], - [/([^a-z]|^)mu([^a-z]|$)/g, '$1μ$2'], - [/([^a-z]|^)nu([^a-z]|$)/g, '$1ν$2'], - [/([^a-z]|^)xi([^a-z]|$)/g, '$1ξ$2'], - [/([^a-z]|^)rh(o)?([^a-z]|$)/g, '$1ρ$3'], - [/([^a-z]|^)si(gma)?([^a-z]|$)/g, '$1σ$3'], - [/([^a-z]|^)ta(u)?([^a-z]|$)/g, '$1τ$3'], - [/([^a-z]|^)up(silon)?([^a-z]|$)/g, '$1υ$3'], - [/([^a-z]|^)ph(i)?([^a-z]|$)/g, '$1φ$3'], - [/([^a-z]|^)ch(i)?([^a-z]|$)/g, '$1χ$3'], - [/([^a-z]|^)ps(i)?([^a-z]|$)/g, '$1ψ$3'], - [/([^a-z]|^)om(ega)?([^a-z]|$)/g, '$1ω$3'], - // Capital greek letters - [/([^a-z]|^)gga(mma)?([^a-z]|$)/g, '$1Γ$3'], - [/([^a-z]|^)gde(lta)?([^a-z]|$)/g, '$1Δ$3'], - [/([^a-z]|^)gth(eta)?([^a-z]|$)/g, '$1Θ$3'], - [/([^a-z]|^)gla(mbda)?([^a-z]|$)/g, '$1Λ$3'], - [/([^a-z]|^)gxi([^a-z]|$)/g, '$1Ξ$2'], - [/([^a-z]|^)gpi([^a-z]|$)/g, '$1Π$2'], - [/([^a-z]|^)gsi(gma)([^a-z]|$)?/g, '$1Σ$3'], - [/([^a-z]|^)gph(i)?([^a-z]|$)/g, '$1Φ$3'], - [/([^a-z]|^)gps(i)?([^a-z]|$)/g, '$1Ψ$3'], - [/([^a-z]|^)gom(ega)?([^a-z]|$)/g, '$1Ω$3'], - // Underscores - // [/_\(([^_]+)\)/g, function(match, p1) { return textsub(p1) }], - // [/_([^" ]+)/g, function(match, p1) { return textsub(p1) }], - // Array elements - [/\[([^\]\[]+)\]/g, function(match, p1) { return textsub(p1) }], - // Removing - [/[xπℝℕ\\∪∩\]\[ ()^/÷*×+=\d-]/g , ''], - ] - if(!removeUnallowed) replacements.pop() - // Replacements - for(let replacement of replacements) + for(const replacement of replacements) str = str.replace(replacement[0], replacement[1]) + if(removeUnallowed) + str = str.replace(/[xnπℝℕ\\∪∩\]\[ ()^/÷*×+=\d¹²³⁴⁵⁶⁷⁸⁹⁰-]/g, "") + return str } /** * Transforms camel case strings to a space separated one. * + * @deprecated * @param {string} label - Camel case to parse * @returns {string} Parsed label. */ export function camelCase2readable(label) { let parsed = parseName(label, false) - return parsed.charAt(0).toLatinUppercase() + parsed.slice(1).replace(/([A-Z])/g," $1") + return parsed.charAt(0).toLatinUppercase() + parsed.slice(1).replace(/([A-Z])/g, " $1") } /** @@ -398,12 +418,12 @@ export function camelCase2readable(label) { * @returns {string} */ export function getRandomColor() { - let clrs = '0123456789ABCDEF'; - let color = '#'; + let clrs = "0123456789ABCDEF" + let color = "#" for(let i = 0; i < 6; i++) { - color += clrs[Math.floor(Math.random() * (16-5*(i%2===0)))]; + color += clrs[Math.floor(Math.random() * (16 - 5 * (i % 2 === 0)))] } - return color; + return color } /** @@ -412,16 +432,15 @@ export function getRandomColor() { * @returns {string} */ export function escapeHTML(str) { - return str.replace(/&/g,'&').replace(//g,'>') ; + return str.replace(/&/g, "&").replace(//g, ">") } - /** * Parses exponents and replaces them with expression values * @param {string} expression - The expression to replace in. * @return {string} The parsed expression */ export function exponentsToExpression(expression) { - return expression.replace(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join('')) + return expression.replace(EXPONENTS_REG, (m, exp) => "^" + exp.split("").map((x) => EXPONENTS.indexOf(x)).join("")) } diff --git a/common/test/general/events.mjs b/common/test/general/events.mjs index f82875f..15d44aa 100644 --- a/common/test/general/events.mjs +++ b/common/test/general/events.mjs @@ -45,7 +45,7 @@ class MockEvent2 extends BaseEvent { const sandbox = spy.sandbox() -describe("Events", function() { +describe("EventsEmitters", function() { afterEach(() => { sandbox.restore() @@ -71,11 +71,11 @@ describe("Events", function() { emitter.emit(mockEvent1) emitter.emit(mockEvent2) expect(listener).to.have.been.called.twice - expect(listener).to.have.been.called.with.exactly(mockEvent1) - expect(listener).to.have.been.called.with.exactly(mockEvent2) + expect(listener).to.also.have.been.called.with.exactly(mockEvent1) + expect(listener).to.also.have.been.called.with.exactly(mockEvent2) }) - it("should be able to remove listeners", function() { + it("should be able to have listeners remvoed", function() { const emitter = new MockEmitter() const listener = spy() emitter.on("example1", listener) @@ -93,7 +93,7 @@ describe("Events", function() { expect(removedFromOneOfTheEvents).to.be.true }) - it("should be able to remove listening to one event when listener listens to multiple", function() { + it("should be able to remove one listener listening to one event when said listener listens to multiple", function() { const emitter = new MockEmitter() const listener = spy() const mockEvent1 = new MockEvent1() @@ -104,10 +104,10 @@ describe("Events", function() { emitter.emit(mockEvent1) emitter.emit(mockEvent2) expect(listener).to.have.been.called.once - expect(listener).to.have.been.called.with.exactly(mockEvent2) + expect(listener).to.also.have.been.called.with.exactly(mockEvent2) }) - it("shouldn't be able to listen/unlisten/emit inexistant events", function() { + it("shouldn't be able to add listen/unlisten to, or emit inexistant events", function() { const emitter = new MockEmitter() const listener = spy() expect(() => emitter.on("inexistant", listener)).to.throw(Error) diff --git a/common/test/general/utils.mjs b/common/test/general/utils.mjs new file mode 100644 index 0000000..8078645 --- /dev/null +++ b/common/test/general/utils.mjs @@ -0,0 +1,183 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExpression } from "../../src/utils.mjs" + + +import { describe, it } from "mocha" +import { expect } from "chai" + +describe("Extensions", function() { + describe("#String.toLatinUppercase", function() { + it("should be able to transform latin characters from strings to their uppercase version", function() { + expect("abc".toLatinUppercase()).to.equal("ABC") + expect("abCd".toLatinUppercase()).to.equal("ABCD") + expect("ab123cd456".toLatinUppercase()).to.equal("AB123CD456") + expect("ABC".toLatinUppercase()).to.equal("ABC") + }) + + it("shouldn't transform non latin characters to their uppercase version", function() { + expect("abαπ".toLatinUppercase()).to.equal("ABαπ") + expect("abαπ".toLatinUppercase()).to.not.equal("abαπ".toUpperCase()) + }) + }) + + describe("#String.removeEnclosure", function() { + it("should be able to remove the first and last characters", function() { + expect("[1+t]".removeEnclosure()).to.equal("1+t") + expect('"a+b+c*d"'.removeEnclosure()).to.equal("a+b+c*d") + expect("(pi/2)".removeEnclosure()).to.equal("pi/2") + }) + }) + + describe("#Number.toDecimalPrecision", function() { + it("should be able to round a number to a fixed decimal precision", function() { + expect(123.456789.toDecimalPrecision()).to.equal(123) + expect(123.456789.toDecimalPrecision(1)).to.equal(123.5) + expect(123.456789.toDecimalPrecision(2)).to.equal(123.46) + expect(123.456789.toDecimalPrecision(3)).to.equal(123.457) + expect(123.456789.toDecimalPrecision(4)).to.equal(123.4568) + expect(123.456789.toDecimalPrecision(5)).to.equal(123.45679) + expect(123.456789.toDecimalPrecision(6)).to.equal(123.456789) + expect(123.111111.toDecimalPrecision(5)).to.equal(123.11111) + }) + }) +}) + +describe("Utils", function() { + describe("#textsup", function() { + it("should transform characters which have a sup unicode equivalent", function() { + expect(textsup("-+=()")).to.equal("⁻⁺⁼⁽⁾") + expect(textsup("0123456789")).to.equal("⁰¹²³⁴⁵⁶⁷⁸⁹") + expect(textsup("abcdefghijklmnoprstuvwxyz")).to.equal("ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖʳˢᵗᵘᵛʷˣʸᶻ") + }) + + it("shouldn't transform characters without a sup equivalent", function() { + expect(textsup("ABCDEFGHIJKLMNOPQRSTUVWXYZq")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZq") + }) + + it("should partially transform strings which only have a few characters with a sup equivalent", function() { + expect(textsup("ABCabcABC")).to.equal("ABCᵃᵇᶜABC") + }) + }) + + describe("#textsub", function() { + it("should transform characters which have a sub unicode equivalent", function() { + expect(textsub("-+=()")).to.equal("₋₊₌₍₎") + expect(textsub("0123456789")).to.equal("₀₁₂₃₄₅₆₇₈₉") + expect(textsub("aehijklmnoprstuvx")).to.equal("ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ") + }) + + it("shouldn't transform characters without a sub equivalent", function() { + expect(textsub("ABCDEFGHIJKLMNOPQRSTUVWXYZ")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ") + expect(textsub("bcdfgqyz")).to.equal("bcdfgqyz") + }) + + it("should partially transform strings which only have a few characters with a sub equivalent", function() { + expect(textsub("ABC123ABC")).to.equal("ABC₁₂₃ABC") + }) + }) + + describe("#parseName", function() { + it("should parse greek letter names", function() { + const shorthands = { + "α": ["al", "alpha"], + "β": ["be", "beta"], + "γ": ["ga", "gamma"], + "δ": ["de", "delta"], + "ε": ["ep", "epsilon"], + "ζ": ["ze", "zeta"], + "η": ["et", "eta"], + "θ": ["th", "theta"], + "κ": ["ka", "kappa"], + "λ": ["la", "lambda"], + "μ": ["mu"], + "ν": ["nu"], + "ξ": ["xi"], + "ρ": ["rh", "rho"], + "σ": ["si", "sigma"], + "τ": ["ta", "tau"], + "υ": ["up", "upsilon"], + "φ": ["ph", "phi"], + "χ": ["ch", "chi"], + "ψ": ["ps", "psi"], + "ω": ["om", "omega"], + "Γ": ["gga", "ggamma"], + "Δ": ["gde", "gdelta"], + "Θ": ["gth", "gtheta"], + "Λ": ["gla", "glambda"], + "Ξ": ["gxi"], + "Π": ["gpi"], + "Σ": ["gsi", "gsigma"], + "Φ": ["gph", "gphi"], + "Ψ": ["gps", "gpsi"], + "Ω": ["gom", "gomega"], + } + for(const [char, shorts] of Object.entries(shorthands)) { + expect(parseName(char)).to.equal(char) + for(const short of shorts) + expect(parseName(short)).to.equal(char) + } + }) + + it("should parse array elements into sub", function() { + expect(parseName("u[n+1]")).to.equal("uₙ₊₁") + expect(parseName("u[(n+x)]")).to.equal("u₍ₙ₊ₓ₎") + expect(parseName("u[A]")).to.equal("uA") + }) + + it("should remove disallowed characters when indicated", function() { + const disallowed = "xnπℝℕ\\∪∩[] ()^/^/÷*×+=1234567890¹²³⁴⁵⁶⁷⁸⁹⁰-" + expect(parseName(disallowed)).to.equal("") + expect(parseName("AA" + disallowed)).to.equal("AA") + expect(parseName(disallowed, false)).to.equal(disallowed) + }) + + it("should be able to do all three at once", function() { + expect(parseName("al[n+1]+n")).to.equal("αₙ₊₁") + expect(parseName("al[n+1]+n", false)).to.equal("αₙ₊₁+n") + }) + }) + + describe("#getRandomColor", function() { + it("should provide a valid color", function() { + const colorReg = /^#[A-F\d]{6}$/ + for(let i = 0; i < 50; i++) + expect(getRandomColor()).to.match(colorReg) + }) + }) + + describe("#escapeHTML", function() { + it("should should escape ampersands", function() { + expect(escapeHTML("&")).to.equal("&") + expect(escapeHTML("High & Mighty")).to.equal("High & Mighty") + }) + + it("should escape injected HTML tags", function() { + expect(escapeHTML("")).to.equal("<script>alert('Injected!')</script>") + expect(escapeHTML('Link')).to.equal('<a href="javascript:alert()">Link</a>') + }) + }) + + describe("#exponentsToExpression", function() { + it("should transform exponents to power expression", function() { + expect(exponentsToExpression("x¹²³⁴⁵⁶⁷⁸⁹⁰")).to.equal("x^1234567890") + expect(exponentsToExpression("x¹²+y³⁴")).to.equal("x^12+y^34") + }) + }) +}) From 4c1b7052404e138bbe6bc366c7f14caaad26cd66 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 04:57:07 +0200 Subject: [PATCH 190/249] Mocking interfaces (+adding new method to canvas to make it more JS-like) --- common/src/module/canvas.mjs | 5 +- common/src/module/common.mjs | 2 +- common/src/module/interface.mjs | 10 ++- common/test/{general => basics}/events.mjs | 0 common/test/basics/interface.mjs | 51 ++++++++++++++++ common/test/{general => basics}/utils.mjs | 0 common/test/mock/canvas.mjs | 59 ++++++++++++++++++ common/test/mock/dialog.mjs | 23 +++++++ common/test/mock/root.mjs | 61 +++++++++++++++++++ .../LogarithmPlotter/LogGraphCanvas.qml | 16 ++++- .../LogarithmPlotter/LogarithmPlotter.qml | 2 - 11 files changed, 216 insertions(+), 13 deletions(-) rename common/test/{general => basics}/events.mjs (100%) create mode 100644 common/test/basics/interface.mjs rename common/test/{general => basics}/utils.mjs (100%) create mode 100644 common/test/mock/canvas.mjs create mode 100644 common/test/mock/dialog.mjs create mode 100644 common/test/mock/root.mjs diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 5d42f5e..c46c9a1 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -522,8 +522,9 @@ class CanvasAPI extends Module { const onRendered = (imgData) => { if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) { // Wait until the image is loaded to callback. - this.#canvas.loadImage(imgData.source) - this.#canvas.imageLoaders[imgData.source] = [callback, imgData] + this.#canvas.loadImageAsync(imgData.source).then(() => { + callback(imgData) + }) } else { // Callback directly callback(imgData) diff --git a/common/src/module/common.mjs b/common/src/module/common.mjs index bdca62f..243fed2 100644 --- a/common/src/module/common.mjs +++ b/common/src/module/common.mjs @@ -57,7 +57,7 @@ export class Module extends BaseEventEmitter { if(!options.hasOwnProperty(name)) throw new Error(`Option '${name}' of initialize of module ${this.#name} does not exist.`) if(typeof value === "function" && value.prototype instanceof Interface) - Interface.check_implementation(value, options[name]) + Interface.checkImplementation(value, options[name]) else if(typeof value !== typeof options[name]) throw new Error(`Option '${name}' of initialize of module ${this.#name} is not a '${value}' (${typeof options[name]}).`) } diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index 2886f73..27fb7eb 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -35,9 +35,8 @@ export class Interface { * Throws an error if the implementation does not conform to the interface. * @param {typeof Interface} interface_ * @param {object} classToCheck - * @return {boolean} */ - static check_implementation(interface_, classToCheck) { + static checkImplementation(interface_, classToCheck) { const properties = new interface_() const interfaceName = interface_.name const toCheckName = classToCheck.constructor.name @@ -52,7 +51,7 @@ export class Interface { else if((typeof value) === "object") // Test type of object. if(value instanceof Interface) - Interface.check_implementation(value, classToCheck[property]) + Interface.checkImplementation(value, classToCheck[property]) else if(value.prototype && !(classToCheck[property] instanceof value)) throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is not '${value.constructor.name}'.`) } @@ -61,13 +60,12 @@ export class Interface { export class CanvasInterface extends Interface { - imageLoaders = OBJECT /** @type {function(string): CanvasRenderingContext2D} */ getContext = FUNCTION /** @type {function(rect)} */ markDirty = FUNCTION - /** @type {function(string)} */ - loadImage = FUNCTION + /** @type {function(string): Promise} */ + loadImageAsync = FUNCTION /** @type {function(string)} */ isImageLoading = FUNCTION /** @type {function(string)} */ diff --git a/common/test/general/events.mjs b/common/test/basics/events.mjs similarity index 100% rename from common/test/general/events.mjs rename to common/test/basics/events.mjs diff --git a/common/test/basics/interface.mjs b/common/test/basics/interface.mjs new file mode 100644 index 0000000..a8d8d32 --- /dev/null +++ b/common/test/basics/interface.mjs @@ -0,0 +1,51 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { describe, it } from "mocha" +import { expect } from "chai" + +import { MockLatex } from "../mock/latex.mjs" +import { MockHelper } from "../mock/helper.mjs" +import { + CanvasInterface, + DialogInterface, + HelperInterface, + Interface, + LatexInterface, + RootInterface +} from "../../src/module/interface.mjs" +import { MockDialog } from "../mock/dialog.mjs" +import { MockRootElement } from "../mock/root.mjs" +import { MockCanvas } from "../mock/canvas.mjs" + +describe("Interface", function() { + describe("#checkImplementation", function() { + it("should validate the implementation of mocks", function() { + const checkMockLatex = () => Interface.checkImplementation(LatexInterface, new MockLatex()) + const checkMockHelper = () => Interface.checkImplementation(HelperInterface, new MockHelper()) + const checkMockDialog = () => Interface.checkImplementation(DialogInterface, new MockDialog()) + const checkMockRoot = () => Interface.checkImplementation(RootInterface, new MockRootElement()) + const checkMockCanvas = () => Interface.checkImplementation(CanvasInterface, new MockCanvas()) + expect(checkMockLatex).to.not.throw() + expect(checkMockHelper).to.not.throw() + expect(checkMockDialog).to.not.throw() + expect(checkMockRoot).to.not.throw() + expect(checkMockCanvas).to.not.throw() + }) + }) +}) \ No newline at end of file diff --git a/common/test/general/utils.mjs b/common/test/basics/utils.mjs similarity index 100% rename from common/test/general/utils.mjs rename to common/test/basics/utils.mjs diff --git a/common/test/mock/canvas.mjs b/common/test/mock/canvas.mjs new file mode 100644 index 0000000..e770e10 --- /dev/null +++ b/common/test/mock/canvas.mjs @@ -0,0 +1,59 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +export class MockCanvas { + constructor(mockLoading = false) { + this.mockLoading = mockLoading + } + + getContext(context) { + throw new Error("MockCanvas.getContext not implemented") + } + + markDirty(rect) { + this.requestPaint() + } + + loadImageAsync(image) { + return new Promise((resolve, reject) => { + resolve() + }) + } + + /** + * Image loading is instantaneous. + * @param {string} image + * @return {boolean} + */ + isImageLoading(image) { + return this.mockLoading + } + + /** + * Image loading is instantaneous. + * @param {string} image + * @return {boolean} + */ + isImageLoaded(image) { + return !this.mockLoading + } + + requestPaint() { + } +} \ No newline at end of file diff --git a/common/test/mock/dialog.mjs b/common/test/mock/dialog.mjs new file mode 100644 index 0000000..3ff118f --- /dev/null +++ b/common/test/mock/dialog.mjs @@ -0,0 +1,23 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export class MockDialog { + constructor() {} + + show() {} +} \ No newline at end of file diff --git a/common/test/mock/root.mjs b/common/test/mock/root.mjs new file mode 100644 index 0000000..51807e2 --- /dev/null +++ b/common/test/mock/root.mjs @@ -0,0 +1,61 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * Mock for root element with width and height property. + * setWidth, setHeight, getWidth, and getHeight methods can be spied on to check + * when the accessor is called. + */ +export class MockRootElement { + #width = 0 + #height = 0 + + constructor() {} + + setWidth(width) { + this.#width = width; + } + + getWidth() { + return this.#width + } + + setHeight(height) { + this.#height = height; + } + + getHeight() { + return this.#height + } + + get width() { + return this.getWidth() + } + + set width(value) { + this.setWidth(value) + } + + get height() { + return this.getHeight() + } + + set height(value) { + this.setHeight(value) + } +} \ No newline at end of file diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 07b6002..e1583f6 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -36,7 +36,7 @@ Canvas { width: parent.width /*! \qmlproperty var LogGraphCanvas::imageLoaders - Dictionary of format {image: [callback.image data]} containing data for defered image loading. + Dictionary of format {image: callback} containing data for deferred image loading. */ property var imageLoaders: {} @@ -66,9 +66,21 @@ Canvas { Object.keys(imageLoaders).forEach((key) => { if(isImageLoaded(key)) { // Calling callback - imageLoaders[key][0](imageLoaders[key][1]) + imageLoaders[key]() delete imageLoaders[key] } }) } + + /*! + \qmlmethod void LogGraphCanvas::loadImageAsync(string imageSource) + Loads an image data onto the canvas asynchronously. + Returns a Promise that is resolved when the image is loaded. + */ + function loadImageAsync(imageSource) { + return new Promise((resolve) => { + this.loadImage(imageSource) + this.imageLoaders[imageSource] = resolve + }) + } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index e7cfc1a..d541a0c 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -257,13 +257,11 @@ ApplicationWindow { }) Modules.IO.on("saved loaded", (evt) => { // Refreshing sidebar - console.log(evt.name) updateObjectsLists() if(title.endsWith("*")) title = title.substring(0, title.length-1) }) Modules.IO.on("modified", () => { - console.log("modified") if(!title.endsWith("*")) title = title+"*" }) From 974baa6cc294dcc04a4e4dd0ef98979fb286ec13 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 05:31:42 +0200 Subject: [PATCH 191/249] Adding base module tests --- common/src/module/common.mjs | 14 +++-- common/test/basics/events.mjs | 14 ++--- common/test/basics/interface.mjs | 11 +++- common/test/basics/module.mjs | 89 ++++++++++++++++++++++++++++++++ common/test/basics/utils.mjs | 40 +++++++------- 5 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 common/test/basics/module.mjs diff --git a/common/src/module/common.mjs b/common/src/module/common.mjs index 243fed2..4cd7993 100644 --- a/common/src/module/common.mjs +++ b/common/src/module/common.mjs @@ -30,6 +30,8 @@ export class Module extends BaseEventEmitter { #name /** @type {Object.} */ #initializationParameters + /** @type {boolean} */ + #initialized = false /** * @@ -41,8 +43,14 @@ export class Module extends BaseEventEmitter { console.log(`Loading module ${name}...`) this.#name = name this.#initializationParameters = initializationParameters - this.initialized = false + } + get name() { + return this.#name; + } + + get initialized() { + return this.#initialized } /** @@ -50,7 +58,7 @@ export class Module extends BaseEventEmitter { * @param {Object.} options */ initialize(options) { - if(this.initialized) + if(this.#initialized) throw new Error(`Cannot reinitialize module ${this.#name}.`) console.log(`Initializing ${this.#name}...`) for(const [name, value] of Object.entries(this.#initializationParameters)) { @@ -61,6 +69,6 @@ export class Module extends BaseEventEmitter { else if(typeof value !== typeof options[name]) throw new Error(`Option '${name}' of initialize of module ${this.#name} is not a '${value}' (${typeof options[name]}).`) } - this.initialized = true + this.#initialized = true } } diff --git a/common/test/basics/events.mjs b/common/test/basics/events.mjs index 15d44aa..8261ff1 100644 --- a/common/test/basics/events.mjs +++ b/common/test/basics/events.mjs @@ -45,13 +45,13 @@ class MockEvent2 extends BaseEvent { const sandbox = spy.sandbox() -describe("EventsEmitters", function() { +describe("Lib/EventsEmitters", function() { afterEach(() => { sandbox.restore() }) - it("should forward events to all of its listeners", function() { + it("forwards events to all of its listeners", function() { const emitter = new MockEmitter() const listener1 = spy() const listener2 = spy() @@ -62,7 +62,7 @@ describe("EventsEmitters", function() { expect(listener2).to.have.been.called.once }) - it("should forward multiple events to a singular listener", function() { + it("forwards multiple events to a singular listener", function() { const emitter = new MockEmitter() const listener = spy() const mockEvent1 = new MockEvent1() @@ -75,7 +75,7 @@ describe("EventsEmitters", function() { expect(listener).to.also.have.been.called.with.exactly(mockEvent2) }) - it("should be able to have listeners remvoed", function() { + it("is able to have listeners removed", function() { const emitter = new MockEmitter() const listener = spy() emitter.on("example1", listener) @@ -93,7 +93,7 @@ describe("EventsEmitters", function() { expect(removedFromOneOfTheEvents).to.be.true }) - it("should be able to remove one listener listening to one event when said listener listens to multiple", function() { + it("is able to have one listener's listening to a single event removed when said listener listens to multiple", function() { const emitter = new MockEmitter() const listener = spy() const mockEvent1 = new MockEvent1() @@ -107,7 +107,7 @@ describe("EventsEmitters", function() { expect(listener).to.also.have.been.called.with.exactly(mockEvent2) }) - it("shouldn't be able to add listen/unlisten to, or emit inexistant events", function() { + it("is not able to emit or add/remove listeners for inexistant events", function() { const emitter = new MockEmitter() const listener = spy() expect(() => emitter.on("inexistant", listener)).to.throw(Error) @@ -115,7 +115,7 @@ describe("EventsEmitters", function() { expect(() => emitter.emit(new BaseEvent("inexistant"))).to.throw(Error) }) - it("shouldn't be able to emit non-events", function() { + it("isn't able to emit non-events", function() { const emitter = new MockEmitter() expect(() => emitter.emit("not-an-event")).to.throw(Error) }) diff --git a/common/test/basics/interface.mjs b/common/test/basics/interface.mjs index a8d8d32..aaf512e 100644 --- a/common/test/basics/interface.mjs +++ b/common/test/basics/interface.mjs @@ -33,9 +33,16 @@ import { MockDialog } from "../mock/dialog.mjs" import { MockRootElement } from "../mock/root.mjs" import { MockCanvas } from "../mock/canvas.mjs" -describe("Interface", function() { +describe("Interfaces", function() { + describe("#interface methods", function() { + it("throws an error when called directly", function() { + const obj = new CanvasInterface() + expect(() => obj.markDirty()).to.throw(Error) + }) + }) + describe("#checkImplementation", function() { - it("should validate the implementation of mocks", function() { + it("validates the implementation of mocks", function() { const checkMockLatex = () => Interface.checkImplementation(LatexInterface, new MockLatex()) const checkMockHelper = () => Interface.checkImplementation(HelperInterface, new MockHelper()) const checkMockDialog = () => Interface.checkImplementation(DialogInterface, new MockDialog()) diff --git a/common/test/basics/module.mjs b/common/test/basics/module.mjs new file mode 100644 index 0000000..5093096 --- /dev/null +++ b/common/test/basics/module.mjs @@ -0,0 +1,89 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior events +import "./events.mjs" +import "./interface.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" +import { BOOLEAN, DialogInterface, FUNCTION, NUMBER, STRING } from "../../src/module/interface.mjs" +import { Module } from "../../src/module/common.mjs" +import { MockDialog } from "../mock/dialog.mjs" + +class MockModule extends Module { + constructor() { + super("mock", { + number: NUMBER, + bool: BOOLEAN, + str: STRING, + func: FUNCTION, + dialog: DialogInterface + }) + } +} + +describe("Modules/Base", function() { + it("defined a Modules global", function() { + expect(globalThis.Modules).to.not.be.undefined + }) + + it("is not be initialized upon construction", function() { + const module = new MockModule() + expect(module.name).to.equal("mock") + expect(module.initialized).to.be.false + }) + + it("is only be initialized with the right arguments", function() { + const module = new MockModule() + const initializeWithNoArg = () => module.initialize({}) + const initializeWithSomeArg = () => module.initialize({ number: 0, str: "" }) + const initializeWithWrongType = () => module.initialize({ + number: () => {}, + str: 0, + bool: "", + func: false, + dialog: null + }) + const initializeProperly = () => module.initialize({ + number: 0, + str: "", + bool: true, + func: FUNCTION, + dialog: new MockDialog() + }) + expect(initializeWithNoArg).to.throw(Error) + expect(initializeWithSomeArg).to.throw(Error) + expect(initializeWithWrongType).to.throw(Error) + expect(initializeProperly).to.not.throw(Error) + expect(module.initialized).to.be.true + }) + + it("cannot be initialized twice", function() { + const module = new MockModule() + const initialize = () => module.initialize({ + number: 0, + str: "", + bool: true, + func: FUNCTION, + dialog: new MockDialog() + }) + expect(initialize).to.not.throw(Error) + expect(initialize).to.throw(Error) + }) +}) \ No newline at end of file diff --git a/common/test/basics/utils.mjs b/common/test/basics/utils.mjs index 8078645..aab2cf5 100644 --- a/common/test/basics/utils.mjs +++ b/common/test/basics/utils.mjs @@ -22,23 +22,23 @@ import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExp import { describe, it } from "mocha" import { expect } from "chai" -describe("Extensions", function() { +describe("Lib/PrototypeExtensions", function() { describe("#String.toLatinUppercase", function() { - it("should be able to transform latin characters from strings to their uppercase version", function() { + it("transforms latin characters from strings to their uppercase version", function() { expect("abc".toLatinUppercase()).to.equal("ABC") expect("abCd".toLatinUppercase()).to.equal("ABCD") expect("ab123cd456".toLatinUppercase()).to.equal("AB123CD456") expect("ABC".toLatinUppercase()).to.equal("ABC") }) - it("shouldn't transform non latin characters to their uppercase version", function() { + it("does not transform non latin characters to their uppercase version", function() { expect("abαπ".toLatinUppercase()).to.equal("ABαπ") expect("abαπ".toLatinUppercase()).to.not.equal("abαπ".toUpperCase()) }) }) describe("#String.removeEnclosure", function() { - it("should be able to remove the first and last characters", function() { + it("is able to remove the first and last characters", function() { expect("[1+t]".removeEnclosure()).to.equal("1+t") expect('"a+b+c*d"'.removeEnclosure()).to.equal("a+b+c*d") expect("(pi/2)".removeEnclosure()).to.equal("pi/2") @@ -46,7 +46,7 @@ describe("Extensions", function() { }) describe("#Number.toDecimalPrecision", function() { - it("should be able to round a number to a fixed decimal precision", function() { + it("rounds a number to a fixed decimal precision", function() { expect(123.456789.toDecimalPrecision()).to.equal(123) expect(123.456789.toDecimalPrecision(1)).to.equal(123.5) expect(123.456789.toDecimalPrecision(2)).to.equal(123.46) @@ -59,42 +59,42 @@ describe("Extensions", function() { }) }) -describe("Utils", function() { +describe("Lib/Utils", function() { describe("#textsup", function() { - it("should transform characters which have a sup unicode equivalent", function() { + it("transforms characters which have a sup unicode equivalent", function() { expect(textsup("-+=()")).to.equal("⁻⁺⁼⁽⁾") expect(textsup("0123456789")).to.equal("⁰¹²³⁴⁵⁶⁷⁸⁹") expect(textsup("abcdefghijklmnoprstuvwxyz")).to.equal("ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖʳˢᵗᵘᵛʷˣʸᶻ") }) - it("shouldn't transform characters without a sup equivalent", function() { + it("does not transform characters without a sup equivalent", function() { expect(textsup("ABCDEFGHIJKLMNOPQRSTUVWXYZq")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZq") }) - it("should partially transform strings which only have a few characters with a sup equivalent", function() { + it("partially transforms strings which only have a few characters with a sup equivalent", function() { expect(textsup("ABCabcABC")).to.equal("ABCᵃᵇᶜABC") }) }) describe("#textsub", function() { - it("should transform characters which have a sub unicode equivalent", function() { + it("transforms characters which have a sub unicode equivalent", function() { expect(textsub("-+=()")).to.equal("₋₊₌₍₎") expect(textsub("0123456789")).to.equal("₀₁₂₃₄₅₆₇₈₉") expect(textsub("aehijklmnoprstuvx")).to.equal("ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ") }) - it("shouldn't transform characters without a sub equivalent", function() { + it("does not transform characters without a sub equivalent", function() { expect(textsub("ABCDEFGHIJKLMNOPQRSTUVWXYZ")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ") expect(textsub("bcdfgqyz")).to.equal("bcdfgqyz") }) - it("should partially transform strings which only have a few characters with a sub equivalent", function() { + it("partially transforms strings which only have a few characters with a sub equivalent", function() { expect(textsub("ABC123ABC")).to.equal("ABC₁₂₃ABC") }) }) describe("#parseName", function() { - it("should parse greek letter names", function() { + it("parses greek letter names", function() { const shorthands = { "α": ["al", "alpha"], "β": ["be", "beta"], @@ -135,27 +135,27 @@ describe("Utils", function() { } }) - it("should parse array elements into sub", function() { + it("parses array elements into sub", function() { expect(parseName("u[n+1]")).to.equal("uₙ₊₁") expect(parseName("u[(n+x)]")).to.equal("u₍ₙ₊ₓ₎") expect(parseName("u[A]")).to.equal("uA") }) - it("should remove disallowed characters when indicated", function() { + it("removes disallowed characters when indicated", function() { const disallowed = "xnπℝℕ\\∪∩[] ()^/^/÷*×+=1234567890¹²³⁴⁵⁶⁷⁸⁹⁰-" expect(parseName(disallowed)).to.equal("") expect(parseName("AA" + disallowed)).to.equal("AA") expect(parseName(disallowed, false)).to.equal(disallowed) }) - it("should be able to do all three at once", function() { + it("is able to do all three at once", function() { expect(parseName("al[n+1]+n")).to.equal("αₙ₊₁") expect(parseName("al[n+1]+n", false)).to.equal("αₙ₊₁+n") }) }) describe("#getRandomColor", function() { - it("should provide a valid color", function() { + it("provides a valid color", function() { const colorReg = /^#[A-F\d]{6}$/ for(let i = 0; i < 50; i++) expect(getRandomColor()).to.match(colorReg) @@ -163,19 +163,19 @@ describe("Utils", function() { }) describe("#escapeHTML", function() { - it("should should escape ampersands", function() { + it("escapes ampersands", function() { expect(escapeHTML("&")).to.equal("&") expect(escapeHTML("High & Mighty")).to.equal("High & Mighty") }) - it("should escape injected HTML tags", function() { + it("escapes injected HTML tags", function() { expect(escapeHTML("")).to.equal("<script>alert('Injected!')</script>") expect(escapeHTML('Link')).to.equal('<a href="javascript:alert()">Link</a>') }) }) describe("#exponentsToExpression", function() { - it("should transform exponents to power expression", function() { + it("transforms exponents to power expression", function() { expect(exponentsToExpression("x¹²³⁴⁵⁶⁷⁸⁹⁰")).to.equal("x^1234567890") expect(exponentsToExpression("x¹²+y³⁴")).to.equal("x^12+y^34") }) From 345458f45372be27e1433a63b14687e55ff3d356 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 06:19:30 +0200 Subject: [PATCH 192/249] Adding new test for Settings Module --- common/src/events.mjs | 8 +- common/src/module/objects.mjs | 8 +- common/src/module/settings.mjs | 6 +- common/test/basics/events.mjs | 22 ++-- .../basics/{module.mjs => module-base.mjs} | 6 +- common/test/basics/module-objects.mjs | 30 ++++++ common/test/basics/module-settings.mjs | 101 ++++++++++++++++++ common/test/hooks.mjs | 14 ++- 8 files changed, 169 insertions(+), 26 deletions(-) rename common/test/basics/{module.mjs => module-base.mjs} (98%) create mode 100644 common/test/basics/module-objects.mjs create mode 100644 common/test/basics/module-settings.mjs diff --git a/common/src/events.mjs b/common/src/events.mjs index 702fc7d..25f5bf3 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -23,11 +23,17 @@ export class BaseEvent { + #name + /** * @property {string} name - Name of the event. */ constructor(name) { - this.name = name + this.#name = name + } + + get name() { + return this.#name } } diff --git a/common/src/module/objects.mjs b/common/src/module/objects.mjs index a95dc89..23801be 100644 --- a/common/src/module/objects.mjs +++ b/common/src/module/objects.mjs @@ -24,6 +24,10 @@ class ObjectsAPI extends Module { constructor() { super("Objects") + /** + * List of object constructors. + * @type {Object.} + */ this.types = {} /** * List of objects for each type of object. @@ -65,7 +69,7 @@ class ObjectsAPI extends Module { * @param {string} newName - Name to rename the object to. */ renameObject(oldName, newName) { - let obj = this.currentObjectsByName[oldName] + const obj = this.currentObjectsByName[oldName] delete this.currentObjectsByName[oldName] this.currentObjectsByName[newName] = obj obj.name = newName @@ -76,7 +80,7 @@ class ObjectsAPI extends Module { * @param {string} objName - Current name of the object. */ deleteObject(objName) { - let obj = this.currentObjectsByName[objName] + const obj = this.currentObjectsByName[objName] if(obj !== undefined) { this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj), 1) obj.delete() diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index e6313c7..64c39c2 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -49,7 +49,8 @@ class SettingsAPI extends Module { static emits = ["changed"] #nonConfigurable = ["saveFilename"] - + + /** @type {Map} */ #properties = new Map([ ["saveFilename", ""], ["xzoom", 100], @@ -105,9 +106,8 @@ class SettingsAPI extends Module { * @param {boolean} byUser - Set to true if the user is at the origin of this change. */ set(property, value, byUser) { - if(!this.#properties.has(property)) { + if(!this.#properties.has(property)) throw new Error(`Property ${property} is not a setting.`) - } const oldValue = this.#properties.get(property) const propType = typeof oldValue if(byUser) diff --git a/common/test/basics/events.mjs b/common/test/basics/events.mjs index 8261ff1..092f037 100644 --- a/common/test/basics/events.mjs +++ b/common/test/basics/events.mjs @@ -16,15 +16,12 @@ * along with this program. If not, see . */ -import { BaseEventEmitter, BaseEvent } from "../../src/events.mjs" - import { describe, it } from "mocha" -import { expect, use } from "chai" -import spies from "chai-spies" +import { expect } from "chai" -// Setting up modules -const { spy } = use(spies) +const { spy } = chaiPlugins +import { BaseEventEmitter, BaseEvent } from "../../src/events.mjs" class MockEmitter extends BaseEventEmitter { static emits = ["example1", "example2"] @@ -43,12 +40,11 @@ class MockEvent2 extends BaseEvent { } } -const sandbox = spy.sandbox() - describe("Lib/EventsEmitters", function() { - - afterEach(() => { - sandbox.restore() + it("sends events with unique and readonly names", function() { + const event = new MockEvent1() + expect(event.name).to.equal("example1") + expect(() => event.name = "not").to.throw() }) it("forwards events to all of its listeners", function() { @@ -71,8 +67,8 @@ describe("Lib/EventsEmitters", function() { emitter.emit(mockEvent1) emitter.emit(mockEvent2) expect(listener).to.have.been.called.twice - expect(listener).to.also.have.been.called.with.exactly(mockEvent1) - expect(listener).to.also.have.been.called.with.exactly(mockEvent2) + expect(listener).to.have.been.first.called.with.exactly(mockEvent1) + expect(listener).to.have.been.second.called.with.exactly(mockEvent2) }) it("is able to have listeners removed", function() { diff --git a/common/test/basics/module.mjs b/common/test/basics/module-base.mjs similarity index 98% rename from common/test/basics/module.mjs rename to common/test/basics/module-base.mjs index 5093096..9a38109 100644 --- a/common/test/basics/module.mjs +++ b/common/test/basics/module-base.mjs @@ -16,15 +16,15 @@ * along with this program. If not, see . */ -// Load prior events +// Load prior tests import "./events.mjs" import "./interface.mjs" import { describe, it } from "mocha" import { expect } from "chai" +import { MockDialog } from "../mock/dialog.mjs" import { BOOLEAN, DialogInterface, FUNCTION, NUMBER, STRING } from "../../src/module/interface.mjs" import { Module } from "../../src/module/common.mjs" -import { MockDialog } from "../mock/dialog.mjs" class MockModule extends Module { constructor() { @@ -38,7 +38,7 @@ class MockModule extends Module { } } -describe("Modules/Base", function() { +describe("Module/Base", function() { it("defined a Modules global", function() { expect(globalThis.Modules).to.not.be.undefined }) diff --git a/common/test/basics/module-objects.mjs b/common/test/basics/module-objects.mjs new file mode 100644 index 0000000..ffc8076 --- /dev/null +++ b/common/test/basics/module-objects.mjs @@ -0,0 +1,30 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests +import "./module-base.mjs" +import "./utils.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" + +import Objects from "../../src/module/objects.mjs" + +describe("Module/Objects", function() { + +}) \ No newline at end of file diff --git a/common/test/basics/module-settings.mjs b/common/test/basics/module-settings.mjs new file mode 100644 index 0000000..ea26556 --- /dev/null +++ b/common/test/basics/module-settings.mjs @@ -0,0 +1,101 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests +import "./module-base.mjs" +import "./utils.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" + +const { spy } = chaiPlugins + +import Settings from "../../src/module/settings.mjs" +import { BaseEvent } from "../../src/events.mjs" + +describe("Module/Settings", function() { + it("is defined as a global", function() { + expect(globalThis.Modules.Settings).to.equal(Settings) + }) + + it("has base defined properties even before initialization", function() { + expect(Settings.saveFilename).to.be.a("string") + expect(Settings.xzoom).to.be.a("number") + expect(Settings.yzoom).to.be.a("number") + expect(Settings.xmin).to.be.a("number") + expect(Settings.ymax).to.be.a("number") + expect(Settings.xaxisstep).to.be.a("string") + expect(Settings.yaxisstep).to.be.a("string") + expect(Settings.xlabel).to.be.a("string") + expect(Settings.ylabel).to.be.a("string") + expect(Settings.linewidth).to.be.a("number") + expect(Settings.textsize).to.be.a("number") + expect(Settings.logscalex).to.be.a("boolean") + expect(Settings.showxgrad).to.be.a("boolean") + expect(Settings.showygrad).to.be.a("boolean") + }) + + it("can be set values, but only of the right type", function() { + expect(() => Settings.set("xzoom", "", false)).to.throw() + expect(() => Settings.set("xlabel", true, false)).to.throw() + expect(() => Settings.set("showxgrad", 2, false)).to.throw() + + expect(() => Settings.set("xzoom", 200, false)).to.not.throw() + expect(() => Settings.set("xlabel", "x", false)).to.not.throw() + expect(() => Settings.set("showxgrad", false, false)).to.not.throw() + }) + + it("cannot be set unknown settings", function() { + expect(() => Settings.set("unknown", "", false)).to.throw() + }) + + it("sends an event when a value is set", function() { + const listener = spy((e) => { + expect(e).to.be.an.instanceof(BaseEvent) + expect(e.name).to.equal("changed") + expect(e.property).to.equal("xzoom") + expect(e.newValue).to.equal(300) + expect(e.byUser).to.be.true + }) + Settings.on("changed", listener) + Settings.set("xzoom", 300, true) + expect(listener).to.have.been.called.once + Settings.off("changed", listener) + }) + + it("requires a helper to set default values", function() { + spy.on(Settings, "set") + expect(() => Settings.initialize({})).to.throw() + expect(() => Settings.initialize({ helper: globalThis.Helper })).to.not.throw() + expect(Settings.set).to.have.been.called.exactly(13) + expect(Settings.set).to.not.have.been.called.with("saveFilename") + expect(Settings.set).to.have.been.called.with("xzoom") + expect(Settings.set).to.have.been.called.with("yzoom") + expect(Settings.set).to.have.been.called.with("xmin") + expect(Settings.set).to.have.been.called.with("ymax") + expect(Settings.set).to.have.been.called.with("xaxisstep") + expect(Settings.set).to.have.been.called.with("yaxisstep") + expect(Settings.set).to.have.been.called.with("xlabel") + expect(Settings.set).to.have.been.called.with("ylabel") + expect(Settings.set).to.have.been.called.with("linewidth") + expect(Settings.set).to.have.been.called.with("textsize") + expect(Settings.set).to.have.been.called.with("logscalex") + expect(Settings.set).to.have.been.called.with("showxgrad") + expect(Settings.set).to.have.been.called.with("showygrad") + }) +}) \ No newline at end of file diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index 0f3ebda..abe468f 100644 --- a/common/test/hooks.mjs +++ b/common/test/hooks.mjs @@ -15,14 +15,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import * as fs from "./mock/fs.mjs"; -import Qt from "./mock/qt.mjs"; -import { MockHelper } from "./mock/helper.mjs"; -import { MockLatex } from "./mock/latex.mjs"; +import * as fs from "./mock/fs.mjs" +import Qt from "./mock/qt.mjs" +import { MockHelper } from "./mock/helper.mjs" +import { MockLatex } from "./mock/latex.mjs" + +import { use } from "chai" +import spies from "chai-spies" function setup() { + const { spy } = use(spies) + globalThis.Helper = new MockHelper() globalThis.Latex = new MockLatex() + globalThis.chaiPlugins = { spy } } setup() From edf45184942f6c1a25f46157fc4727ea70284f15 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 12 Oct 2024 20:37:16 +0200 Subject: [PATCH 193/249] Starting expr-eval's tests. --- common/src/lib/expr-eval/expression.mjs | 3 - common/src/lib/expr-eval/parser.mjs | 3 - common/src/lib/expr-eval/tokens.mjs | 2 +- common/src/module/expreval.mjs | 8 +- .../module-base.mjs => module/base.mjs} | 4 +- common/test/module/expreval.mjs | 187 ++++++++++++++++++ .../module-objects.mjs => module/objects.mjs} | 14 +- .../settings.mjs} | 4 +- 8 files changed, 203 insertions(+), 22 deletions(-) rename common/test/{basics/module-base.mjs => module/base.mjs} (97%) create mode 100644 common/test/module/expreval.mjs rename common/test/{basics/module-objects.mjs => module/objects.mjs} (85%) rename common/test/{basics/module-settings.mjs => module/settings.mjs} (98%) diff --git a/common/src/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs index 89831c7..d89d67e 100644 --- a/common/src/lib/expr-eval/expression.mjs +++ b/common/src/lib/expr-eval/expression.mjs @@ -171,9 +171,6 @@ function evaluate(tokens, expr, values) { nstack.push(n1 ? !!evaluate(n2, expr, values) : false) } else if(item.value === "or") { nstack.push(n1 ? true : !!evaluate(n2, expr, values)) - } else if(item.value === "=") { - f = expr.binaryOps[item.value] - nstack.push(f(n1, evaluate(n2, expr, values), values)) } else { f = expr.binaryOps[item.value] nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values))) diff --git a/common/src/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs index 71a1c95..ba920c6 100644 --- a/common/src/lib/expr-eval/parser.mjs +++ b/common/src/lib/expr-eval/parser.mjs @@ -47,9 +47,7 @@ const optionNameMap = { "not": "logical", "?": "conditional", ":": "conditional", - //'=': 'assignment', // Disable assignment "[": "array" - //'()=': 'fndef' // Diable function definition } export class Parser { @@ -109,7 +107,6 @@ export class Parser { and: Polyfill.andOperator, or: Polyfill.orOperator, "in": Polyfill.inOperator, - "=": Polyfill.setVar, "[": Polyfill.arrayIndex } diff --git a/common/src/lib/expr-eval/tokens.mjs b/common/src/lib/expr-eval/tokens.mjs index 919433c..bfaad39 100644 --- a/common/src/lib/expr-eval/tokens.mjs +++ b/common/src/lib/expr-eval/tokens.mjs @@ -472,7 +472,7 @@ export class TokenStream { this.current = this.newToken(TOP, "==") this.pos++ } else { - this.current = this.newToken(TOP, c) + return false } } else if(c === "!") { if(this.expression.charAt(this.pos + 1) === "=") { diff --git a/common/src/module/expreval.mjs b/common/src/module/expreval.mjs index 964177c..7b40b2f 100644 --- a/common/src/module/expreval.mjs +++ b/common/src/module/expreval.mjs @@ -84,11 +84,11 @@ class ExprParserAPI extends Module { return this.#parser.parse(expression) } - integral(a, b, ...args) { + integral(a = null, b = null, ...args) { let usage1 = qsTranslate("usage", "integral(, , )") let usage2 = qsTranslate("usage", "integral(, , , )") let f = this.parseArgumentsForFunction(args, usage1, usage2) - if(a == null || b == null) + if(typeof a !== "number" || typeof b !== "number") throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) // https://en.wikipedia.org/wiki/Simpson%27s_rule @@ -101,10 +101,10 @@ class ExprParserAPI extends Module { let usage2 = qsTranslate("usage", "derivative(, , )") let x = args.pop() let f = this.parseArgumentsForFunction(args, usage1, usage2) - if(x == null) + if(typeof x !== "number") throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) - let derivative_precision = x / 10 + let derivative_precision = 1e-8 return (f(x + derivative_precision / 2) - f(x - derivative_precision / 2)) / derivative_precision } } diff --git a/common/test/basics/module-base.mjs b/common/test/module/base.mjs similarity index 97% rename from common/test/basics/module-base.mjs rename to common/test/module/base.mjs index 9a38109..be035c0 100644 --- a/common/test/basics/module-base.mjs +++ b/common/test/module/base.mjs @@ -17,8 +17,8 @@ */ // Load prior tests -import "./events.mjs" -import "./interface.mjs" +import "../basics/events.mjs" +import "../basics/interface.mjs" import { describe, it } from "mocha" import { expect } from "chai" diff --git a/common/test/module/expreval.mjs b/common/test/module/expreval.mjs new file mode 100644 index 0000000..c9361f0 --- /dev/null +++ b/common/test/module/expreval.mjs @@ -0,0 +1,187 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests +import "./base.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" + +import ExprEval from "../../src/module/expreval.mjs" + +describe("Module/ExprEval", function() { + describe("#parse", function() { + const evaluate = (expr, vals) => ExprEval.parse(expr).evaluate(vals) + it("parses simple mathematical expressions", function() { + expect(evaluate("1", {})).to.equal(1) + expect(evaluate("-1", {})).to.equal(-1) + expect(evaluate("-(-1)", {})).to.equal(1) + expect(evaluate("+(-1)", {})).to.equal(-1) + expect(evaluate("3!", {})).to.equal(6) + expect(evaluate("1+1", {})).to.equal(2) + expect(evaluate("4*3", {})).to.equal(12) + expect(evaluate("64/4", {})).to.equal(16) + expect(evaluate("2^10", {})).to.equal(1024) + expect(evaluate("10%3", {})).to.equal(1) + expect(evaluate("10%3", {})).to.equal(1) + // Test priorities + expect(evaluate("10*10+10*10", {})).to.equal(200) + expect(evaluate("10/10+10/10", {})).to.equal(2) + expect(evaluate("10/10+10/10", {})).to.equal(2) + expect(evaluate("2^2-2^2", {})).to.equal(0) + expect(evaluate("(2^2-2)^2", {})).to.equal(4) + }) + + it("parses equality and test statements", function() { + expect(evaluate("10%3 == 1 ? 2 : 1", {})).to.equal(2) + expect(evaluate("10%3 != 1 ? 2 : 1", {})).to.equal(1) + expect(evaluate("10 < 3 ? 2 : 1", {})).to.equal(1) + expect(evaluate("10 > 3 ? (2+1) : 1", {})).to.equal(3) + expect(evaluate("10 <= 3 ? 4 : 1", {})).to.equal(1) + expect(evaluate("10 >= 3 ? 4 : 1", {})).to.equal(4) + // Check equality + expect(evaluate("10 < 10 ? 2 : 1", {})).to.equal(1) + expect(evaluate("10 > 10 ? 2 : 1", {})).to.equal(1) + expect(evaluate("10 <= 10 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10 >= 10 ? 4 : 1", {})).to.equal(4) + // Check 'and' and 'or' + expect(evaluate("10 <= 3 and 10 < 10 ? 4 : 1", {})).to.equal(1) + expect(evaluate("10 <= 10 and 10 < 10 ? 4 : 1", {})).to.equal(1) + expect(evaluate("10 <= 10 and 10 < 20 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10 <= 3 or 10 < 10 ? 4 : 1", {})).to.equal(1) + expect(evaluate("10 <= 10 or 10 < 10 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10 <= 10 or 10 < 20 ? 4 : 1", {})).to.equal(4) + }) + + it("parses singular function operators (functions with one arguments and no parenthesis)", function() { + // Trigonometric functions + expect(evaluate("sin π", { })).to.be.approximately(0, Number.EPSILON) + expect(evaluate("cos π", { })).to.be.approximately(-1, Number.EPSILON) + expect(evaluate("tan π", { })).to.be.approximately(0, Number.EPSILON) + expect(evaluate("asin 1", { })).to.be.approximately(Math.PI/2, Number.EPSILON) + expect(evaluate("acos 1", { })).to.be.approximately(0, Number.EPSILON) + expect(evaluate("atan 1", { })).to.be.approximately(Math.PI/4, Number.EPSILON) + expect(evaluate("sinh 1", { })).to.be.approximately(Math.sinh(1), Number.EPSILON) + expect(evaluate("cosh 1", { })).to.be.approximately(Math.cosh(1), Number.EPSILON) + expect(evaluate("tanh 1", { })).to.be.approximately(Math.tanh(1), Number.EPSILON) + expect(evaluate("asinh 1", { })).to.be.approximately(Math.asinh(1), Number.EPSILON) + expect(evaluate("acosh 1", { })).to.be.approximately(Math.acosh(1), Number.EPSILON) + expect(evaluate("atanh 0.5", { })).to.be.approximately(Math.atanh(0.5), Number.EPSILON) + // Reverse trigonometric + expect(evaluate("asin sin 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("acos cos 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("atan tan 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("asinh sinh 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("acosh cosh 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("atanh tanh 1", { })).to.be.approximately(1, Number.EPSILON) + // Other functions + }) + }) + + + describe("#integral", function() { + it("returns the integral value between two integers", function() { + expect(ExprEval.integral(0, 1, "1", "t")).to.be.approximately(1, Number.EPSILON) + expect(ExprEval.integral(0, 1, "t", "t")).to.be.approximately(1 / 2, Number.EPSILON) + expect(ExprEval.integral(0, 1, "t^2", "t")).to.be.approximately(1 / 3, Number.EPSILON) + expect(ExprEval.integral(0, 1, "t^3", "t")).to.be.approximately(1 / 4, 0.01) + expect(ExprEval.integral(0, 1, "t^4", "t")).to.be.approximately(1 / 5, 0.01) + + expect(ExprEval.integral(10, 40, "1", "t")).to.equal(30) + expect(ExprEval.integral(20, 40, "1", "t")).to.equal(20) + + expect(ExprEval.integral(0, 10, { execute: (x) => 1 })).to.equal(10) + expect(ExprEval.integral(0, 10, { execute: (x) => x })).to.equal(50) + expect(ExprEval.integral(0, 1, { execute: (x) => Math.pow(x, 2) })).to.equal(1 / 3) + }) + + + it("throws error when provided with invalid arguments", function() { + const noArg1 = () => ExprEval.integral() + const noArg2 = () => ExprEval.integral(0) + const noFunction = () => ExprEval.integral(0, 1) + const invalidObjectProvided = () => ExprEval.integral(0, 1, { a: 2 }) + const notAnObjectProvided = () => ExprEval.integral(0, 1, "string") + const invalidFromProvided = () => ExprEval.integral("ze", 1, "t^2", "t") + const invalidToProvided = () => ExprEval.integral(0, "ze", "t^2", "t") + const notStringProvided1 = () => ExprEval.integral(0, 1, { a: 2 }, { b: 1 }) + const notStringProvided2 = () => ExprEval.integral(0, 1, { a: 2 }, "t") + const notStringProvided3 = () => ExprEval.integral(0, 1, "t^2", { b: 1 }) + const invalidVariableProvided = () => ExprEval.integral(0, 1, "t^2", "93IO74") + const invalidExpressionProvided = () => ExprEval.integral(0, 1, "t^2t", "t") + const invalidVariableInExpression = () => ExprEval.integral(0, 1, "t^2+x", "t") + expect(noArg1).to.throw() + expect(noArg2).to.throw() + expect(noFunction).to.throw() + expect(invalidObjectProvided).to.throw() + expect(invalidFromProvided).to.throw() + expect(invalidToProvided).to.throw() + expect(notAnObjectProvided).to.throw() + expect(notStringProvided1).to.throw() + expect(notStringProvided2).to.throw() + expect(notStringProvided3).to.throw() + expect(invalidVariableProvided).to.throw() + expect(invalidExpressionProvided).to.throw() + expect(invalidVariableInExpression).to.throw() + }) + }) + + describe("#derivative", function() { + const DELTA = 1e-5 + it("returns the derivative value between two integers", function() { + expect(ExprEval.derivative("1", "t", 2)).to.be.approximately(0, DELTA) + expect(ExprEval.derivative("t", "t", 2)).to.be.approximately(1, DELTA) + expect(ExprEval.derivative("t^2", "t", 2)).to.be.approximately(4, DELTA) + expect(ExprEval.derivative("t^3", "t", 2)).to.be.approximately(12, DELTA) + expect(ExprEval.derivative("t^4", "t", 2)).to.be.approximately(32, DELTA) + + expect(ExprEval.derivative({ execute: (x) => 1 }, 10)).to.equal(0) + expect(ExprEval.derivative({ execute: (x) => x }, 10)).to.be.approximately(1, DELTA) + expect(ExprEval.derivative({ execute: (x) => Math.pow(x, 2) }, 10)).to.be.approximately(20, DELTA) + }) + + it("throws error when provided with invalid arguments", function() { + const noArg1 = () => ExprEval.derivative() + const noArg2 = () => ExprEval.derivative("1") + const noValue1 = () => ExprEval.derivative("0", "1") + const noValue2 = () => ExprEval.derivative({ execute: (x) => 1 }) + const invalidObjectProvided = () => ExprEval.derivative({ a: 2 }, 1) + const notAnObjectProvided = () => ExprEval.derivative("string", 1) + const invalidXProvided = () => ExprEval.derivative("t^2+x", "t", "ze") + const notStringProvided1 = () => ExprEval.derivative({ a: 2 }, { b: 1 }, 1) + const notStringProvided2 = () => ExprEval.derivative({ a: 2 }, "t", 1) + const notStringProvided3 = () => ExprEval.derivative("t^2", { b: 1 }, 1) + const invalidVariableProvided = () => ExprEval.derivative("t^2", "93IO74", 1) + const invalidExpressionProvided = () => ExprEval.derivative("t^2t", "t", 1) + const invalidVariableInExpression = () => ExprEval.derivative("t^2+x", "t", 1) + expect(noArg1).to.throw() + expect(noArg2).to.throw() + expect(noValue1).to.throw() + expect(noValue2).to.throw() + expect(invalidObjectProvided).to.throw() + expect(invalidXProvided).to.throw() + expect(notAnObjectProvided).to.throw() + expect(notStringProvided1).to.throw() + expect(notStringProvided2).to.throw() + expect(notStringProvided3).to.throw() + expect(invalidVariableProvided).to.throw() + expect(invalidExpressionProvided).to.throw() + expect(invalidVariableInExpression).to.throw() + }) + }) +}) \ No newline at end of file diff --git a/common/test/basics/module-objects.mjs b/common/test/module/objects.mjs similarity index 85% rename from common/test/basics/module-objects.mjs rename to common/test/module/objects.mjs index ffc8076..4665232 100644 --- a/common/test/basics/module-objects.mjs +++ b/common/test/module/objects.mjs @@ -17,14 +17,14 @@ */ // Load prior tests -import "./module-base.mjs" -import "./utils.mjs" +import "./base.mjs" +import "../basics/utils.mjs" import { describe, it } from "mocha" import { expect } from "chai" -import Objects from "../../src/module/objects.mjs" - -describe("Module/Objects", function() { - -}) \ No newline at end of file +// import Objects from "../../src/module/objects.mjs" +// +// describe("Module/Objects", function() { +// +// }) \ No newline at end of file diff --git a/common/test/basics/module-settings.mjs b/common/test/module/settings.mjs similarity index 98% rename from common/test/basics/module-settings.mjs rename to common/test/module/settings.mjs index ea26556..7ad439a 100644 --- a/common/test/basics/module-settings.mjs +++ b/common/test/module/settings.mjs @@ -17,8 +17,8 @@ */ // Load prior tests -import "./module-base.mjs" -import "./utils.mjs" +import "./base.mjs" +import "../basics/utils.mjs" import { describe, it } from "mocha" import { expect } from "chai" From 3a81441d0bc37dfb7a1c8aeefba8b523885e2c1e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 13 Oct 2024 00:33:22 +0200 Subject: [PATCH 194/249] Finished expr-eval testing --- common/src/lib/expr-eval/expression.mjs | 14 +- common/src/lib/expr-eval/parser.mjs | 11 +- common/src/lib/expr-eval/polyfill.mjs | 55 +---- common/src/module/expreval.mjs | 4 +- common/test/module/expreval.mjs | 308 ++++++++++++++++++++---- 5 files changed, 260 insertions(+), 132 deletions(-) diff --git a/common/src/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs index d89d67e..f782fa3 100644 --- a/common/src/lib/expr-eval/expression.mjs +++ b/common/src/lib/expr-eval/expression.mjs @@ -111,7 +111,7 @@ function simplify(tokens, unaryOps, binaryOps, ternaryOps, values) { * In the given instructions, replaces variable by expr. * @param {Instruction[]} tokens * @param {string} variable - * @param {number} expr + * @param {ExprEvalExpression} expr * @return {Instruction[]} */ function substitute(tokens, variable, expr) { @@ -487,18 +487,6 @@ export class ExprEvalExpression { return evaluate(this.tokens, this, values) } - /** - * Returns a list of symbols (string of characters) in the expressions. - * Can be functions, constants, or variables. - * @returns {string[]} - */ - symbols(options) { - options = options || {} - const vars = [] - getSymbols(this.tokens, vars, options) - return vars - } - toString() { return expressionToString(this.tokens, false) } diff --git a/common/src/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs index ba920c6..e27d512 100644 --- a/common/src/lib/expr-eval/parser.mjs +++ b/common/src/lib/expr-eval/parser.mjs @@ -120,18 +120,13 @@ export class Parser { min: Polyfill.min, max: Polyfill.max, hypot: Math.hypot || Polyfill.hypot, - pyt: Math.hypot || Polyfill.hypot, // backward compat + pyt: Math.hypot || Polyfill.hypot, pow: Math.pow, atan2: Math.atan2, "if": Polyfill.condition, gamma: Polyfill.gamma, "Γ": Polyfill.gamma, roundTo: Polyfill.roundTo, - map: Polyfill.arrayMap, - fold: Polyfill.arrayFold, - filter: Polyfill.arrayFilter, - indexOf: Polyfill.stringOrArrayIndexOf, - join: Polyfill.arrayJoin } // These constants will automatically be replaced the MOMENT they are parsed. @@ -156,10 +151,6 @@ export class Parser { return new ExprEvalExpression(instr, this) } - evaluate(expr, variables) { - return this.parse(expr).evaluate(variables) - } - isOperatorEnabled(op) { const optionName = optionNameMap.hasOwnProperty(op) ? optionNameMap[op] : op const operators = this.options.operators || {} diff --git a/common/src/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs index 9e8e885..c618aaf 100644 --- a/common/src/lib/expr-eval/polyfill.mjs +++ b/common/src/lib/expr-eval/polyfill.mjs @@ -210,9 +210,8 @@ export function gamma(n) { } export function stringOrArrayLength(s) { - if(Array.isArray(s)) { + if(Array.isArray(s)) return s.length - } return String(s).length } @@ -296,58 +295,6 @@ export function min(array) { } } -export function arrayMap(f, a) { - if(typeof f !== "function") { - throw new EvalError(qsTranslate("error", "First argument to map is not a function.")) - } - if(!Array.isArray(a)) { - throw new EvalError(qsTranslate("error", "Second argument to map is not an array.")) - } - return a.map(function(x, i) { - return f(x, i) - }) -} - -export function arrayFold(f, init, a) { - if(typeof f !== "function") { - throw new EvalError(qsTranslate("error", "First argument to fold is not a function.")) - } - if(!Array.isArray(a)) { - throw new EvalError(qsTranslate("error", "Second argument to fold is not an array.")) - } - return a.reduce(function(acc, x, i) { - return f(acc, x, i) - }, init) -} - -export function arrayFilter(f, a) { - if(typeof f !== "function") { - throw new EvalError(qsTranslate("error", "First argument to filter is not a function.")) - } - if(!Array.isArray(a)) { - throw new EvalError(qsTranslate("error", "Second argument to filter is not an array.")) - } - return a.filter(function(x, i) { - return f(x, i) - }) -} - -export function stringOrArrayIndexOf(target, s) { - if(!(Array.isArray(s) || typeof s === "string")) { - throw new Error(qsTranslate("error", "Second argument to indexOf is not a string or array.")) - } - - return s.indexOf(target) -} - -export function arrayJoin(sep, a) { - if(!Array.isArray(a)) { - throw new Error(qsTranslate("error", "Second argument to join is not an array.")) - } - - return a.join(sep) -} - export function sign(x) { return ((x > 0) - (x < 0)) || +x } diff --git a/common/src/module/expreval.mjs b/common/src/module/expreval.mjs index 7b40b2f..8440282 100644 --- a/common/src/module/expreval.mjs +++ b/common/src/module/expreval.mjs @@ -19,7 +19,7 @@ import { Module } from "./common.mjs" import { Parser } from "../lib/expr-eval/parser.mjs" -const evalVariables = { +const EVAL_VARIABLES = { // Variables not provided by expr-eval.js, needs to be provided manually "pi": Math.PI, "PI": Math.PI, @@ -42,7 +42,7 @@ class ExprParserAPI extends Module { this.currentVars = {} this.#parser = new Parser() - this.#parser.consts = Object.assign({}, this.#parser.consts, evalVariables) + this.#parser.consts = Object.assign({}, this.#parser.consts, EVAL_VARIABLES) this.#parser.functions.integral = this.integral.bind(this) this.#parser.functions.derivative = this.derivative.bind(this) diff --git a/common/test/module/expreval.mjs b/common/test/module/expreval.mjs index c9361f0..2d075f6 100644 --- a/common/test/module/expreval.mjs +++ b/common/test/module/expreval.mjs @@ -25,72 +25,274 @@ import { expect } from "chai" import ExprEval from "../../src/module/expreval.mjs" describe("Module/ExprEval", function() { - describe("#parse", function() { - const evaluate = (expr, vals) => ExprEval.parse(expr).evaluate(vals) + describe("#parse.evaluate", function() { + const evaluate = (expr, vals = {}) => ExprEval.parse(expr).evaluate(vals) it("parses simple mathematical expressions", function() { - expect(evaluate("1", {})).to.equal(1) - expect(evaluate("-1", {})).to.equal(-1) - expect(evaluate("-(-1)", {})).to.equal(1) - expect(evaluate("+(-1)", {})).to.equal(-1) - expect(evaluate("3!", {})).to.equal(6) - expect(evaluate("1+1", {})).to.equal(2) - expect(evaluate("4*3", {})).to.equal(12) - expect(evaluate("64/4", {})).to.equal(16) - expect(evaluate("2^10", {})).to.equal(1024) - expect(evaluate("10%3", {})).to.equal(1) - expect(evaluate("10%3", {})).to.equal(1) + expect(evaluate(`"\\'\\"\\\\\\/\\b\\f\\n\\r\\t\\u3509"`)).to.equal(`'"\\/\b\f\n\r\t\u3509`) + expect(evaluate("1")).to.equal(1) + expect(evaluate(" 1 ")).to.equal(1) + expect(evaluate("0xFF")).to.equal(255) + expect(evaluate("0b11")).to.equal(3) + expect(evaluate("-1")).to.equal(-1) + expect(evaluate("-(-1)")).to.equal(1) + expect(evaluate("+(-1)")).to.equal(-1) + expect(evaluate("3!")).to.equal(6) + expect(evaluate("1+1")).to.equal(2) + expect(evaluate("4*3")).to.equal(12) + expect(evaluate("4•3")).to.equal(12) + expect(evaluate("64/4")).to.equal(16) + expect(evaluate("2^10")).to.equal(1024) + expect(evaluate("10%3")).to.equal(1) + expect(evaluate("10%3")).to.equal(1) // Test priorities - expect(evaluate("10*10+10*10", {})).to.equal(200) - expect(evaluate("10/10+10/10", {})).to.equal(2) - expect(evaluate("10/10+10/10", {})).to.equal(2) - expect(evaluate("2^2-2^2", {})).to.equal(0) - expect(evaluate("(2^2-2)^2", {})).to.equal(4) + expect(evaluate("10*10+10*10")).to.equal(200) + expect(evaluate("10/10+10/10")).to.equal(2) + expect(evaluate("10/10+10/10")).to.equal(2) + expect(evaluate("2^2-2^2")).to.equal(0) + expect(evaluate("(2^2-2)^2")).to.equal(4) }) it("parses equality and test statements", function() { - expect(evaluate("10%3 == 1 ? 2 : 1", {})).to.equal(2) - expect(evaluate("10%3 != 1 ? 2 : 1", {})).to.equal(1) - expect(evaluate("10 < 3 ? 2 : 1", {})).to.equal(1) - expect(evaluate("10 > 3 ? (2+1) : 1", {})).to.equal(3) - expect(evaluate("10 <= 3 ? 4 : 1", {})).to.equal(1) - expect(evaluate("10 >= 3 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10%3 == 1 ? 2 : 1")).to.equal(2) + expect(evaluate("not(10%3 == 1) ? 2 : 1")).to.equal(1) + expect(evaluate("10%3 != 1 ? 2 : 1")).to.equal(1) + expect(evaluate("10 < 3 ? 2 : 1")).to.equal(1) + expect(evaluate("10 > 3 ? (2+1) : 1")).to.equal(3) + expect(evaluate("10 <= 3 ? 4 : 1")).to.equal(1) + expect(evaluate("10 >= 3 ? 4 : 1")).to.equal(4) // Check equality - expect(evaluate("10 < 10 ? 2 : 1", {})).to.equal(1) - expect(evaluate("10 > 10 ? 2 : 1", {})).to.equal(1) - expect(evaluate("10 <= 10 ? 4 : 1", {})).to.equal(4) - expect(evaluate("10 >= 10 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10 < 10 ? 2 : 1")).to.equal(1) + expect(evaluate("10 > 10 ? 2 : 1")).to.equal(1) + expect(evaluate("10 <= 10 ? 4 : 1")).to.equal(4) + expect(evaluate("10 >= 10 ? 4 : 1")).to.equal(4) // Check 'and' and 'or' - expect(evaluate("10 <= 3 and 10 < 10 ? 4 : 1", {})).to.equal(1) - expect(evaluate("10 <= 10 and 10 < 10 ? 4 : 1", {})).to.equal(1) - expect(evaluate("10 <= 10 and 10 < 20 ? 4 : 1", {})).to.equal(4) - expect(evaluate("10 <= 3 or 10 < 10 ? 4 : 1", {})).to.equal(1) - expect(evaluate("10 <= 10 or 10 < 10 ? 4 : 1", {})).to.equal(4) - expect(evaluate("10 <= 10 or 10 < 20 ? 4 : 1", {})).to.equal(4) + expect(evaluate("10 <= 3 and 10 < 10 ? 4 : 1")).to.equal(1) + expect(evaluate("10 <= 10 and 10 < 10 ? 4 : 1")).to.equal(1) + expect(evaluate("10 <= 10 and 10 < 20 ? 4 : 1")).to.equal(4) + expect(evaluate("10 <= 3 or 10 < 10 ? 4 : 1")).to.equal(1) + expect(evaluate("10 <= 10 or 10 < 10 ? 4 : 1")).to.equal(4) + expect(evaluate("10 <= 10 or 10 < 20 ? 4 : 1")).to.equal(4) }) it("parses singular function operators (functions with one arguments and no parenthesis)", function() { // Trigonometric functions - expect(evaluate("sin π", { })).to.be.approximately(0, Number.EPSILON) - expect(evaluate("cos π", { })).to.be.approximately(-1, Number.EPSILON) - expect(evaluate("tan π", { })).to.be.approximately(0, Number.EPSILON) - expect(evaluate("asin 1", { })).to.be.approximately(Math.PI/2, Number.EPSILON) - expect(evaluate("acos 1", { })).to.be.approximately(0, Number.EPSILON) - expect(evaluate("atan 1", { })).to.be.approximately(Math.PI/4, Number.EPSILON) - expect(evaluate("sinh 1", { })).to.be.approximately(Math.sinh(1), Number.EPSILON) - expect(evaluate("cosh 1", { })).to.be.approximately(Math.cosh(1), Number.EPSILON) - expect(evaluate("tanh 1", { })).to.be.approximately(Math.tanh(1), Number.EPSILON) - expect(evaluate("asinh 1", { })).to.be.approximately(Math.asinh(1), Number.EPSILON) - expect(evaluate("acosh 1", { })).to.be.approximately(Math.acosh(1), Number.EPSILON) - expect(evaluate("atanh 0.5", { })).to.be.approximately(Math.atanh(0.5), Number.EPSILON) + expect(evaluate("sin 0")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("cos 0")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("tan 0")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("asin 1")).to.be.approximately(Math.PI / 2, Number.EPSILON) + expect(evaluate("acos 1")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("atan 1")).to.be.approximately(Math.PI / 4, Number.EPSILON) + expect(evaluate("sinh 1")).to.be.approximately(Math.sinh(1), Number.EPSILON) + expect(evaluate("cosh 1")).to.be.approximately(Math.cosh(1), Number.EPSILON) + expect(evaluate("tanh 1")).to.be.approximately(Math.tanh(1), Number.EPSILON) + expect(evaluate("asinh 1")).to.be.approximately(Math.asinh(1), Number.EPSILON) + expect(evaluate("acosh 1")).to.be.approximately(Math.acosh(1), Number.EPSILON) + expect(evaluate("atanh 0.5")).to.be.approximately(Math.atanh(0.5), Number.EPSILON) // Reverse trigonometric - expect(evaluate("asin sin 1", { })).to.be.approximately(1, Number.EPSILON) - expect(evaluate("acos cos 1", { })).to.be.approximately(1, Number.EPSILON) - expect(evaluate("atan tan 1", { })).to.be.approximately(1, Number.EPSILON) - expect(evaluate("asinh sinh 1", { })).to.be.approximately(1, Number.EPSILON) - expect(evaluate("acosh cosh 1", { })).to.be.approximately(1, Number.EPSILON) - expect(evaluate("atanh tanh 1", { })).to.be.approximately(1, Number.EPSILON) + expect(evaluate("asin sin 1")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("acos cos 1")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("atan tan 1")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("asinh sinh 1")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("acosh cosh 1")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("atanh tanh 1")).to.be.approximately(1, Number.EPSILON) // Other functions + expect(evaluate("sqrt 4")).to.be.approximately(2, Number.EPSILON) + expect(evaluate("sqrt 2")).to.be.approximately(Math.sqrt(2), Number.EPSILON) + expect(evaluate("cbrt 27")).to.be.approximately(3, Number.EPSILON) + expect(evaluate("cbrt 14")).to.be.approximately(Math.cbrt(14), Number.EPSILON) + expect(evaluate("log 1")).to.be.approximately(Math.log(1), Number.EPSILON) + expect(evaluate("ln 1")).to.be.approximately(Math.log(1), Number.EPSILON) + expect(evaluate("log2 8")).to.be.approximately(3, Number.EPSILON) + expect(evaluate("log10 100")).to.be.approximately(2, Number.EPSILON) + expect(evaluate("lg 100")).to.be.approximately(2, Number.EPSILON) + expect(evaluate("expm1 0")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("expm1 10")).to.be.approximately(Math.expm1(10), Number.EPSILON) + expect(evaluate("log1p 0")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("log1p 10")).to.be.approximately(Math.log1p(10), Number.EPSILON) + // Roundings/Sign transformations + expect(evaluate("abs -12.34")).to.equal(12.34) + expect(evaluate("abs 12.45")).to.equal(12.45) + expect(evaluate("ceil 12.45")).to.equal(13) + expect(evaluate("ceil 12.75")).to.equal(13) + expect(evaluate("ceil 12.0")).to.equal(12) + expect(evaluate("ceil -12.6")).to.equal(-12) + expect(evaluate("floor 12.45")).to.equal(12) + expect(evaluate("floor 12.75")).to.equal(12) + expect(evaluate("floor 12.0")).to.equal(12) + expect(evaluate("floor -12.2")).to.equal(-13) + expect(evaluate("round 12.45")).to.equal(12) + expect(evaluate("round 12.75")).to.equal(13) + expect(evaluate("round 12.0")).to.equal(12) + expect(evaluate("round -12.2")).to.equal(-12) + expect(evaluate("round -12.6")).to.equal(-13) + expect(evaluate("trunc 12.45")).to.equal(12) + expect(evaluate("trunc 12.75")).to.equal(12) + expect(evaluate("trunc 12.0")).to.equal(12) + expect(evaluate("trunc -12.2")).to.equal(-12) + expect(evaluate("exp 1")).to.be.approximately(Math.E, Number.EPSILON) + expect(evaluate("exp 10")).to.be.approximately(Math.pow(Math.E, 10), 1e-8) + expect(evaluate("length \"string\"")).to.equal(6) + expect(evaluate("sign 0")).to.equal(0) + expect(evaluate("sign -0")).to.equal(0) + expect(evaluate("sign -10")).to.equal(-1) + expect(evaluate("sign 80")).to.equal(1) }) + + it("parses regular functions", function() { + for(let i = 0; i < 1000; i++) { + expect(evaluate("random()")).to.be.within(0, 1) + expect(evaluate("random(100)")).to.be.within(0, 100) + } + expect(evaluate("fac(3)")).to.equal(6) + expect(evaluate("fac(10)")).to.equal(3628800) + expect(evaluate("min(10, 20)")).to.equal(10) + expect(evaluate("min(-10, -20)")).to.equal(-20) + expect(evaluate("max(10, 20)")).to.equal(20) + expect(evaluate("max(-10, -20)")).to.equal(-10) + expect(evaluate("hypot(3, 4)")).to.equal(5) + expect(evaluate("pyt(30, 40)")).to.equal(50) + expect(evaluate("atan2(1, 1)")).to.be.approximately(Math.PI / 4, Number.EPSILON) + expect(evaluate("atan2(1, 0)")).to.be.approximately(Math.PI / 2, Number.EPSILON) + expect(evaluate("atan2(0, 1)")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("if(10 == 10, 1, 0)")).to.be.approximately(1, Number.EPSILON) + expect(evaluate("if(10 != 10, 1, 0)")).to.be.approximately(0, Number.EPSILON) + expect(evaluate("gamma(10) == 9!")).to.be.true + expect(evaluate("Γ(30) == 29!")).to.be.true + expect(evaluate("Γ(25) == 23!")).to.be.false + expect(evaluate("roundTo(26.04)")).to.equal(26) + expect(evaluate("roundTo(26.04, 2)")).to.equal(26.04) + expect(evaluate("roundTo(26.04836432123, 5)")).to.equal(26.04836) + expect(evaluate("roundTo(26.04836432123, 5)")).to.equal(26.04836) + }) + + it("parses arrays and access their members", function() { + expect(evaluate("[6, 7, 9]")).to.have.lengthOf(3) + expect(evaluate("[6, 7, 9]")).to.deep.equal([6, 7, 9]) + expect(evaluate("[6, \"8\", 9]")).to.have.lengthOf(3) + expect(evaluate("[6, 7%2]")).to.deep.equal([6, 1]) + // Access array indices + expect(evaluate("[6, 7][1]")).to.equal(7) + expect(evaluate("[6, 7, 8, 9, 10][2*2-1]")).to.equal(9) + }) + + it("can apply functions to arrays", function() { + expect(evaluate("length [6, 7, 9]")).to.equal(3) + expect(evaluate("length [6, 7, 8, 9]")).to.equal(4) + expect(evaluate("[6, 7, 9]||[10,11,12]")).to.deep.equal([6, 7, 9, 10, 11, 12]) + expect(evaluate("6 in [6, 7, 9]")).to.be.true + expect(evaluate("2 in [6, 7, 9]")).to.be.false + expect(evaluate("min([10, 6, 7, 8, 9])")).to.equal(6) + expect(evaluate("max([6, 7, 8, 9, 2])")).to.equal(9) + }) + + it("throws errors when invalid function parameters are provided", function() { + expect(() => evaluate("max()")).to.throw() + expect(() => evaluate("min()")).to.throw() + }) + + it("parses constants", function() { + expect(evaluate("pi")).to.equal(Math.PI) + expect(evaluate("PI")).to.equal(Math.PI) + expect(evaluate("π")).to.equal(Math.PI) + expect(evaluate("e")).to.equal(Math.E) + expect(evaluate("E")).to.equal(Math.E) + expect(evaluate("true")).to.be.true + expect(evaluate("false")).to.be.false + // expect(evaluate("∞")).to.equal(Math.Infinity) + // expect(evaluate("infinity")).to.equal(Math.Infinity) + // expect(evaluate("Infinity")).to.equal(Math.Infinity) + }) + + it("can be provided variables", function() { + const u = [1, 2, 3, 4] + const x = 10 + const s_ = "string" + const f = (x) => x * 2 + expect(evaluate("u", { u })).to.deep.equal([...u]) + expect(evaluate("x", { x })).to.equal(x) + expect(evaluate("s_", { s_ })).to.equal(s_) + expect(evaluate("f", { f })).to.equal(f) + expect(evaluate("b", { b: true })).to.equal(true) + expect(evaluate("u[1]", { u })).to.equal(u[1]) + expect(evaluate("x/2", { x })).to.equal(x / 2) + expect(evaluate("f(2)", { f })).to.equal(f(2)) + expect(evaluate("if(x == f(2), u[0], s_)", { x, u, s_, f })).to.equal(s_) + }) + + it("can be provided objects", function() { + const obj = { execute: (x) => x * 3, x: 10, y: { cached: true, execute: () => 20 } } + expect(evaluate("O(3)+O(2)", { O: obj })).to.equal(9 + 6) + expect(evaluate("O.x+O.y", { O: obj })).to.equal(30) + }) + + it("throws errors when trying to use variables wrongly", function() { + const obj = { execute: (x) => x * 3 } + expect(() => evaluate("O()", { O: obj })).to.throw() + expect(() => evaluate("O.x", { O: obj })).to.throw() + expect(() => evaluate("x()", { x: 10 })).to.throw() + expect(() => evaluate("x")).to.throw() + expect(() => evaluate("n")).to.throw() + }) + + it("can do it all at once", function() { + const obj = { execute: (x) => x * 3, x: 20 } + const u = [1, 2, 3, 4] + const x = 10 + const s = "string" + const expr = "random(e) <= e ? fac(x)+u[2]+O(pi) : O.x+length s" + expect(evaluate(expr, { x, u, s, O: obj })).to.equal(3628803 + obj.execute(Math.PI)) + }) + + it("cannot parse invalid expressions", function() { + expect(() => evaluate("1+")).to.throw() + expect(() => evaluate("@")).to.throw() + expect(() => evaluate("]")).to.throw() + expect(() => evaluate("")).to.throw() + expect(() => evaluate(`"\\u35P2"`)).to.throw() + expect(() => evaluate(`"\\x"`)).to.throw() + }) + }) + + describe("#parse.toString", function() { + it("can be converted back into a string without changes", function() { + const expressions = ["pi+2*(e+2)^4", "sin(1+2!+pi+cos -3)^2", "[2,3,4][(2-1)*2]", "true ? false : true"] + for(const ogString of expressions) { + const expr = ExprEval.parse(ogString) + const convertedString = expr.toString() + expect(ExprEval.parse(convertedString)).to.deep.equal(expr) // Can be reparsed just the same + } + }) + }) + + describe("#parse.substitute", function() { + const parsed = ExprEval.parse("if(x == 0, 1, 2+x)") + it("can substitute a variable for a number", function() { + expect(parsed.substitute("x", 10).evaluate({})).to.equal(12) + expect(parsed.substitute("x", 0).evaluate({})).to.equal(1) + }) + + it("can substitute a variable for another", function() { + expect(parsed.substitute("x", "b").evaluate({ b: 10 })).to.equal(12) + expect(parsed.substitute("x", "b").evaluate({ b: 0 })).to.equal(1) + }) + + it("can substitute a variable for an expression", function() { + expect(parsed.substitute("x", "sin α").evaluate({ "α": Math.PI / 2 })).to.be.approximately(3, Number.EPSILON) + expect(parsed.substitute("x", "sin α").evaluate({ "α": 0 })).to.equal(1) + expect(parsed.substitute("x", "α == 1 ? 0 : 1").evaluate({ "α": 1 })).to.equal(1) + }) + }) + + describe("#parse.variables", function() { + it("can list all parsed undefined variables", function() { + expect(ExprEval.parse("a+b+x+pi+sin(b)").variables()).to.deep.equal(["a", "b", "x"]) + }) + }) + + describe("#parse.toJSFunction", function() { + const func = ExprEval.parse("not(false) ? a+b+x+1/x : x!+random()+A.x+[][0]").toJSFunction("x", { a: "10", b: "0" }) + expect(func(10)).to.equal(20.1) + expect(func(20)).to.equal(30.05) }) @@ -143,7 +345,7 @@ describe("Module/ExprEval", function() { describe("#derivative", function() { const DELTA = 1e-5 - it("returns the derivative value between two integers", function() { + it("returns the derivative value of a function at a given number", function() { expect(ExprEval.derivative("1", "t", 2)).to.be.approximately(0, DELTA) expect(ExprEval.derivative("t", "t", 2)).to.be.approximately(1, DELTA) expect(ExprEval.derivative("t^2", "t", 2)).to.be.approximately(4, DELTA) From c03afdf4eeb490808b9c16f8a1ef211a17b7ee46 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 14 Oct 2024 17:18:58 +0200 Subject: [PATCH 195/249] Upgrading deb packaging --- README.md | 8 +++++- assets/native/linux/debian/depends | 1 - assets/native/linux/debian/depends.packaged | 1 + assets/native/linux/debian/depends.wheels | 1 + common/package.json | 2 +- scripts/package-deb.sh | 13 ++++++++- scripts/sign-deb.sh | 31 +++++++++++---------- 7 files changed, 39 insertions(+), 18 deletions(-) delete mode 100644 assets/native/linux/debian/depends create mode 100644 assets/native/linux/debian/depends.packaged create mode 100644 assets/native/linux/debian/depends.wheels diff --git a/README.md b/README.md index ae252fe..5d4ba57 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,13 @@ To run LogarithmPlotter's tests, follow these steps: - Python - Install python3 and [poetry](https://python-poetry.org/) - - Run `poetry install --with test` + - Create and activate virtual env (recommended) + - Go into `runtime-pyside6` and run `poetry install --with test` +- ECMAScript + - Install node with npm + - Go into `common` and run `npm install -D` + +Finally, to actually run the tests: - Run `scripts/run-tests.sh` ## Legal notice diff --git a/assets/native/linux/debian/depends b/assets/native/linux/debian/depends deleted file mode 100644 index 5b7d902..0000000 --- a/assets/native/linux/debian/depends +++ /dev/null @@ -1 +0,0 @@ -python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng diff --git a/assets/native/linux/debian/depends.packaged b/assets/native/linux/debian/depends.packaged new file mode 100644 index 0000000..22f3322 --- /dev/null +++ b/assets/native/linux/debian/depends.packaged @@ -0,0 +1 @@ +python3 (>= 3.9), python3-pip, python3-pyside6.qtcore (>= 6), python3-pyside6.qtcore (>= 6), texlive-latex-base, dvipng diff --git a/assets/native/linux/debian/depends.wheels b/assets/native/linux/debian/depends.wheels new file mode 100644 index 0000000..9a874f7 --- /dev/null +++ b/assets/native/linux/debian/depends.wheels @@ -0,0 +1 @@ +python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7.0), texlive-latex-base, dvipng diff --git a/common/package.json b/common/package.json index 6940d87..e85d3ff 100644 --- a/common/package.json +++ b/common/package.json @@ -2,7 +2,7 @@ "name": "logarithmplotter", "version": "0.6.0", "description": "2D plotter software to make Bode plots, sequences and distribution functions.", - "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", + "main": "src/index.mjs", "scripts": { "build": "rollup --config rollup.config.mjs", "test": "c8 mocha test/**/*.mjs" diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh index 8ed03ee..eea10ba 100755 --- a/scripts/package-deb.sh +++ b/scripts/package-deb.sh @@ -26,7 +26,18 @@ mkdir assets cp -r ../../assets/{native,*.svg} assets/ cp ../../README.md . +# Build for noble python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \ - --suite noble --depends3 "$(cat assets/native/linux/debian/depends)" --section science \ + --suite noble --depends3 "$(cat assets/native/linux/debian/depends.wheels)" --section science \ bdist_deb + +mv deb_dist deb_dist.noble + +# Build for oracular (different dependencies) +python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ + --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \ + --suite oracular --depends3 "$(cat assets/native/linux/debian/depends.packaged)" --section science \ + bdist_deb + +mv deb_dist deb_dist.oracular diff --git a/scripts/sign-deb.sh b/scripts/sign-deb.sh index f8e0a9a..05bee26 100755 --- a/scripts/sign-deb.sh +++ b/scripts/sign-deb.sh @@ -1,23 +1,26 @@ #!/bin/bash # This script is used to sign the LogarithmPlotter deb directly from it's DSC file. # Adapted from https://github.com/astraw/stdeb/issues/181 -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/deb_dist" || exit 1 +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/" || exit 1 PPA_ARCHIVE="ppa:ad5001/logarithmplotter" -# create a temporary folder -mkdir tmp -p -cd tmp -rm -rf * +for dist in `echo noble oracular`; do + echo "Signing $dist deb..." + # create a temporary folder + mkdir "deb_dist.$dist/tmp" -p + cd "deb_dist.$dist/tmp" || exit 1 + rm -rf * -# DSC file variables -dsc_file="$(find ../ -regextype sed -regex ".*/*.dsc" | cut -c 4-)" -source_package_name="$(echo $dsc_file | cut -c -$(expr ${#dsc_file} - 4))" + # DSC file variables + dsc_file="$(find ../ -regextype sed -regex ".*/*.dsc" | cut -c 4-)" + source_package_name="$(echo $dsc_file | cut -c -$(expr ${#dsc_file} - 4))" -# extract and sign the files -dpkg-source -x "../$dsc_file" -cd "$(find . -type d | head -n 2 | tail -n 1 | cut -c 3-)" # go to the (only) directory. -debuild -S -sa -k"mail@ad5001.eu" + # extract and sign the files + dpkg-source -x "../$dsc_file" + cd "$(find . -type d | head -n 2 | tail -n 1 | cut -c 3-)" # go to the (only) directory. + debuild -S -sa -k"mail@ad5001.eu" -# upload package to my PPA -dput $PPA_ARCHIVE "../${source_package_name}_source.changes" + # upload package to my PPA + dput $PPA_ARCHIVE "../${source_package_name}_source.changes" +done From 89e78913de559471474c93d28bc2fc0c19cfd5ad Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 14 Oct 2024 17:28:43 +0200 Subject: [PATCH 196/249] Adding dependencies for Ubuntu 24.10. --- assets/native/linux/debian/{control => control.bkp} | 0 assets/native/linux/debian/depends.packaged | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename assets/native/linux/debian/{control => control.bkp} (100%) diff --git a/assets/native/linux/debian/control b/assets/native/linux/debian/control.bkp similarity index 100% rename from assets/native/linux/debian/control rename to assets/native/linux/debian/control.bkp diff --git a/assets/native/linux/debian/depends.packaged b/assets/native/linux/debian/depends.packaged index 22f3322..4ec21f5 100644 --- a/assets/native/linux/debian/depends.packaged +++ b/assets/native/linux/debian/depends.packaged @@ -1 +1 @@ -python3 (>= 3.9), python3-pip, python3-pyside6.qtcore (>= 6), python3-pyside6.qtcore (>= 6), texlive-latex-base, dvipng +python3 (>= 3.9), python3-pip, python3-pyside6.qtcore (>= 6), python3-pyside6.qtgui (>= 6), python3-pyside6.qtqml (>= 6), python3-pyside6.qtwidgets (>= 6), python3-pyside6.qtquick (>= 6), python3-pyside6.qtquickcontrols2 (>= 6), qml6-module-qt5compat-graphicaleffects (>= 6), qml6-module-qt-labs-platform (>= 6), qml6-module-qtquick-dialogs (>= 6), texlive-latex-base, dvipng From a26dbc8a0043267a93676aa45ec00aff52902589 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 14 Oct 2024 17:39:02 +0200 Subject: [PATCH 197/249] Getting rid of Qt5Compat, ridding dependency on PySide6-Addons --- assets/native/linux/debian/depends.packaged | 2 +- assets/native/linux/debian/depends.wheels | 2 +- .../eu/ad5001/LogarithmPlotter/History/HistoryItem.qml | 8 +++----- runtime-pyside6/setup.py | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/assets/native/linux/debian/depends.packaged b/assets/native/linux/debian/depends.packaged index 4ec21f5..0bace27 100644 --- a/assets/native/linux/debian/depends.packaged +++ b/assets/native/linux/debian/depends.packaged @@ -1 +1 @@ -python3 (>= 3.9), python3-pip, python3-pyside6.qtcore (>= 6), python3-pyside6.qtgui (>= 6), python3-pyside6.qtqml (>= 6), python3-pyside6.qtwidgets (>= 6), python3-pyside6.qtquick (>= 6), python3-pyside6.qtquickcontrols2 (>= 6), qml6-module-qt5compat-graphicaleffects (>= 6), qml6-module-qt-labs-platform (>= 6), qml6-module-qtquick-dialogs (>= 6), texlive-latex-base, dvipng +python3 (>= 3.9), python3-pip, python3-pyside6.qtcore (>= 6), python3-pyside6.qtgui (>= 6), python3-pyside6.qtqml (>= 6), python3-pyside6.qtwidgets (>= 6), python3-pyside6.qtquick (>= 6), python3-pyside6.qtquickcontrols2 (>= 6), qml6-module-qt-labs-platform (>= 6), qml6-module-qtquick-dialogs (>= 6), texlive-latex-base, dvipng diff --git a/assets/native/linux/debian/depends.wheels b/assets/native/linux/debian/depends.wheels index 9a874f7..5b7d902 100644 --- a/assets/native/linux/debian/depends.wheels +++ b/assets/native/linux/debian/depends.wheels @@ -1 +1 @@ -python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7.0), texlive-latex-base, dvipng +python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index f37eb3b..6ad6556 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -import QtQuick.Controls import QtQuick -import Qt5Compat.GraphicalEffects +import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting @@ -82,12 +81,11 @@ Button { height: hidden ? 8 : Math.max(actionHeight, label.height + 15) - LinearGradient { + Rectangle { anchors.fill: parent //opacity: hidden ? 0.6 : 1 - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) gradient: Gradient { + orientation: Gradient.Horizontal GradientStop { position: 0.1; color: "transparent" } GradientStop { position: 1.5; color: clr } } diff --git a/runtime-pyside6/setup.py b/runtime-pyside6/setup.py index f76f1d7..524ad29 100644 --- a/runtime-pyside6/setup.py +++ b/runtime-pyside6/setup.py @@ -122,7 +122,7 @@ if sys.platform == 'linux': # os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') setuptools.setup( - install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials", "PySide6-Addons"]), + install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials"]), python_requires='>=3.9', name='logarithmplotter', From 2995b2271a031aad5197efdc0aba8f96600db7eb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 14 Oct 2024 17:55:53 +0200 Subject: [PATCH 198/249] Fixing mind-bogingingly strange issue causing Qt crash when attempting to set WeakSet during mouse move events. --- common/src/events.mjs | 6 +++--- common/src/module/settings.mjs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/common/src/events.mjs b/common/src/events.mjs index 25f5bf3..75a7a52 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -23,17 +23,17 @@ export class BaseEvent { - #name + ___name = "" /** * @property {string} name - Name of the event. */ constructor(name) { - this.#name = name + this.___name = name } get name() { - return this.#name + return this.___name } } diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 64c39c2..8ea152d 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -115,7 +115,8 @@ class SettingsAPI extends Module { if(propType !== typeof value) throw new Error(`Value of ${property} must be a ${propType} (${typeof value} provided).`) this.#properties.set(property, value) - this.emit(new ChangedEvent(property, oldValue, value, byUser === true)) + const evt = new ChangedEvent(property, oldValue, value, byUser === true) + this.emit(evt) } /** From b33e1329dbbfc99a25f1cfeaca8c44514fdde6e8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 14 Oct 2024 23:22:57 +0200 Subject: [PATCH 199/249] Removing typed config functions in Helper. --- common/src/module/history.mjs | 2 +- common/src/module/interface.mjs | 28 +------- common/src/module/latex.mjs | 2 +- common/src/module/settings.mjs | 18 +---- common/src/preferences/common.mjs | 14 ++-- common/src/preferences/default.mjs | 2 +- common/test/mock/helper.mjs | 69 ++++--------------- .../Setting/ExpressionEditor.qml | 8 +-- .../eu/ad5001/LogarithmPlotter/Settings.qml | 18 ++--- .../LogarithmPlotter/util/helper.py | 31 ++------- runtime-pyside6/tests/test_helper.py | 10 +-- 11 files changed, 53 insertions(+), 149 deletions(-) diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index be70f87..4b07095 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -138,7 +138,7 @@ class HistoryAPI extends Module { if(action instanceof Action) { console.log("Added new entry to history: " + action.getReadableString()) this.undoStack.push(action) - if(this.#helper.getSettingBool("reset_redo_stack")) + if(this.#helper.getSetting("reset_redo_stack")) this.redoStack = [] this.emit(new AddedEvent(action)) } diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index 27fb7eb..b6d462f 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -109,37 +109,13 @@ export class HelperInterface extends Interface { /** * Gets a setting from the config * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {boolean} Value of the setting - */ - getSettingBool = FUNCTION - /** - * Gets a setting from the config - * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {number} Value of the setting - */ - getSettingInt = FUNCTION - /** - * Gets a setting from the config - * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {string} Value of the setting + * @returns {string|number|boolean} Value of the setting */ getSetting = FUNCTION /** * Sets a setting in the config * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {boolean} value - */ - setSettingBool = FUNCTION - /** - * Sets a setting in the config - * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {number} value - */ - setSettingInt = FUNCTION - /** - * Sets a setting in the config - * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {string} value + * @param {string|number|boolean} value */ setSetting = FUNCTION /** diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 4ff81cb..a6aa216 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -81,7 +81,7 @@ class LatexAPI extends Module { initialize({ latex, helper }) { super.initialize({ latex, helper }) this.#latex = latex - this.enabled = helper.getSettingBool("enable_latex") + this.enabled = helper.getSetting("enable_latex") } /** diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index 8ea152d..d630e7a 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -81,21 +81,9 @@ class SettingsAPI extends Module { initialize({ helper }) { super.initialize({ helper }) // Initialize default values. - for(const key of this.#properties.keys()) { - if(!this.#nonConfigurable.includes(key)) { - switch(typeof this.#properties.get(key)) { - case "boolean": - this.set(key, helper.getSettingBool("default_graph."+key), false) - break - case "number": - this.set(key, helper.getSettingInt("default_graph."+key), false) - break - case "string": - this.set(key, helper.getSetting("default_graph."+key), false) - break - } - } - } + for(const key of this.#properties.keys()) + if(!this.#nonConfigurable.includes(key)) + this.set(key, helper.getSetting("default_graph."+key), false) } /** diff --git a/common/src/preferences/common.mjs b/common/src/preferences/common.mjs index e456dc2..812263c 100644 --- a/common/src/preferences/common.mjs +++ b/common/src/preferences/common.mjs @@ -53,11 +53,11 @@ export class BoolSetting extends Setting { } value() { - return Helper.getSettingBool(this.nameInConfig) + return Helper.getSetting(this.nameInConfig) } set(value) { - Helper.setSettingBool(this.nameInConfig, value) + Helper.setSetting(this.nameInConfig, value === true) } } @@ -69,11 +69,11 @@ export class NumberSetting extends Setting { } value() { - return Helper.getSettingInt(this.nameInConfig) + return Helper.getSetting(this.nameInConfig) } set(value) { - Helper.setSettingInt(this.nameInConfig, value) + Helper.setSetting(this.nameInConfig, +value) } } @@ -84,11 +84,11 @@ export class EnumIntSetting extends Setting { } value() { - return Helper.getSettingInt(this.nameInConfig) + return Helper.getSetting(this.nameInConfig) } set(value) { - Helper.setSettingInt(this.nameInConfig, value) + Helper.setSetting(this.nameInConfig, +value) } } @@ -131,6 +131,6 @@ export class StringSetting extends Setting { } set(value) { - Helper.setSetting(this.nameInConfig, value) + Helper.setSetting(this.nameInConfig, ""+value) } } \ No newline at end of file diff --git a/common/src/preferences/default.mjs b/common/src/preferences/default.mjs index 20d62e3..1d7e4bd 100644 --- a/common/src/preferences/default.mjs +++ b/common/src/preferences/default.mjs @@ -37,7 +37,7 @@ const XMIN = new NumberSetting( qsTranslate("Settings", "Min X"), "default_graph.xmin", "xmin", - () => Helper.getSettingBool("default_graph.logscalex") ? 1e-100 : -Infinity + () => Helper.getSetting("default_graph.logscalex") ? 1e-100 : -Infinity ) const YMAX = new NumberSetting( diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs index 9f74b64..c2b024f 100644 --- a/common/test/mock/helper.mjs +++ b/common/test/mock/helper.mjs @@ -53,7 +53,13 @@ export class MockHelper { this.__settings = { ...DEFAULT_SETTINGS } } - __getSetting(settingName) { + + /** + * Gets a setting from the config + * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") + * @returns {string|number|boolean} Value of the setting + */ + getSetting(settingName) { const namespace = settingName.split(".") let data = this.__settings for(const name of namespace) @@ -64,7 +70,12 @@ export class MockHelper { return data } - __setSetting(settingName, value) { + /** + * Sets a setting in the config + * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") + * @param {string|number|boolean} value + */ + setSetting(settingName, value) { const namespace = settingName.split(".") const finalName = namespace.pop() let data = this.__settings @@ -76,60 +87,6 @@ export class MockHelper { data[finalName] = value } - /** - * Gets a setting from the config - * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {boolean} Value of the setting - */ - getSettingBool(settingName) { - return this.__getSetting(settingName) === true - } - - /** - * Gets a setting from the config - * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {number} Value of the setting - */ - getSettingInt(settingName) { - return +(this.__getSetting(settingName)) - } - - /** - * Gets a setting from the config - * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin") - * @returns {string} Value of the setting - */ - getSetting(settingName) { - return this.__getSetting(settingName).toString() - } - - /** - * Sets a setting in the config - * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {boolean} value - */ - setSettingBool(settingName, value) { - return this.__setSetting(settingName, value === true) - } - - /** - * Sets a setting in the config - * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {number} value - */ - setSettingInt(settingName, value) { - return this.__setSetting(settingName, +(value)) - } - - /** - * Sets a setting in the config - * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin") - * @param {string} value - */ - setSetting(settingName, value) { - return this.__setSetting(settingName, value.toString()) - } - /** * Sends data to be written * @param {string} file diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index a0c030a..bb99f52 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -221,9 +221,9 @@ Item { focus: true selectByMouse: true - property bool autocompleteEnabled: Helper.getSettingBool("autocompletion.enabled") - property bool syntaxHighlightingEnabled: Helper.getSettingBool("expression_editor.colorize") - property bool autoClosing: Helper.getSettingBool("expression_editor.autoclose") + property bool autocompleteEnabled: Helper.getSetting("autocompletion.enabled") + property bool syntaxHighlightingEnabled: Helper.getSetting("expression_editor.colorize") + property bool autoClosing: Helper.getSetting("expression_editor.autoclose") property var tokens: autocompleteEnabled || syntaxHighlightingEnabled ? parent.tokens(text) : [] Keys.priority: Keys.BeforeItem // Required for knowing which key the user presses. @@ -600,7 +600,7 @@ Item { */ function colorize(tokenList) { let parsedText = "" - let scheme = colorSchemes[Helper.getSettingInt("expression_editor.color_scheme")] + let scheme = colorSchemes[Helper.getSetting("expression_editor.color_scheme")] for(let token of tokenList) { switch(token.type) { case JS.Parsing.TokenType.VARIABLE: diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index b440d07..992e9b1 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -44,25 +44,25 @@ ScrollView { Zoom on the x axis of the diagram, provided from settings. \sa Settings */ - property double xzoom: Helper.getSettingInt('default_graph.xzoom') + property double xzoom: Helper.getSetting('default_graph.xzoom') /*! \qmlproperty double Settings::yzoom Zoom on the y axis of the diagram, provided from settings. \sa Settings */ - property double yzoom: Helper.getSettingInt('default_graph.yzoom') + property double yzoom: Helper.getSetting('default_graph.yzoom') /*! \qmlproperty double Settings::xmin Minimum x of the diagram, provided from settings. \sa Settings */ - property double xmin: Helper.getSettingInt('default_graph.xmin') + property double xmin: Helper.getSetting('default_graph.xmin') /*! \qmlproperty double Settings::ymax Maximum y of the diagram, provided from settings. \sa Settings */ - property double ymax: Helper.getSettingInt('default_graph.ymax') + property double ymax: Helper.getSetting('default_graph.ymax') /*! \qmlproperty string Settings::xaxisstep Step of the x axis graduation, provided from settings. @@ -93,34 +93,34 @@ ScrollView { Width of lines that will be drawn into the canvas, provided from settings. \sa Settings */ - property double linewidth: Helper.getSettingInt('default_graph.linewidth') + property double linewidth: Helper.getSetting('default_graph.linewidth') /*! \qmlproperty double Settings::textsize Font size of the text that will be drawn into the canvas, provided from settings. \sa Settings */ - property double textsize: Helper.getSettingInt('default_graph.textsize') + property double textsize: Helper.getSetting('default_graph.textsize') /*! \qmlproperty bool Settings::logscalex true if the canvas should be in logarithmic mode, false otherwise. Provided from settings. \sa Settings */ - property bool logscalex: Helper.getSettingBool('default_graph.logscalex') + property bool logscalex: Helper.getSetting('default_graph.logscalex') /*! \qmlproperty bool Settings::showxgrad true if the x graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showxgrad: Helper.getSettingBool('default_graph.showxgrad') + property bool showxgrad: Helper.getSetting('default_graph.showxgrad') /*! \qmlproperty bool Settings::showygrad true if the y graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showygrad: Helper.getSettingBool('default_graph.showygrad') + property bool showygrad: Helper.getSetting('default_graph.showygrad') Column { spacing: 10 diff --git a/runtime-pyside6/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index 6db4570..344e425 100644 --- a/runtime-pyside6/LogarithmPlotter/util/helper.py +++ b/runtime-pyside6/LogarithmPlotter/util/helper.py @@ -15,10 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ - from PySide6.QtWidgets import QMessageBox, QApplication from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication -from PySide6.QtQml import QQmlApplicationEngine +from PySide6.QtQml import QJSValue from PySide6.QtGui import QImage from PySide6 import __version__ as PySide6_version @@ -135,29 +134,13 @@ class Helper(QObject): def getVersion(self): return __VERSION__ - @Slot(str, result=str) - def getSetting(self, namespace): - return str(config.getSetting(namespace)) + @Slot(str, result=QJSValue) + def getSetting(self, namespace: str) -> QJSValue: + return QJSValue(config.getSetting(namespace)) - @Slot(str, result=float) - def getSettingInt(self, namespace): - return float(config.getSetting(namespace)) - - @Slot(str, result=bool) - def getSettingBool(self, namespace): - return bool(config.getSetting(namespace)) - - @Slot(str, str) - def setSetting(self, namespace, value): - return config.setSetting(namespace, str(value)) - - @Slot(str, bool) - def setSettingBool(self, namespace, value): - return config.setSetting(namespace, bool(value)) - - @Slot(str, float) - def setSettingInt(self, namespace, value): - return config.setSetting(namespace, float(value)) + @Slot(str, QJSValue) + def setSetting(self, namespace: str, value: QJSValue): + return config.setSetting(namespace, value.toPrimitive().toVariant()) @Slot(result=str) def getDebugInfos(self): diff --git a/runtime-pyside6/tests/test_helper.py b/runtime-pyside6/tests/test_helper.py index 412eac3..73dfb23 100644 --- a/runtime-pyside6/tests/test_helper.py +++ b/runtime-pyside6/tests/test_helper.py @@ -158,16 +158,16 @@ class TestHelper: obj = Helper(pwd, tmpfile) assert obj.getVersion() == version assert type(obj.getDebugInfos()) == str - assert type(obj.getSetting("check_for_updates")) == str - assert type(obj.getSettingInt("check_for_updates")) == float - assert type(obj.getSettingBool("check_for_updates")) == bool + assert type(obj.getSetting("last_install_greet").toVariant()) == str + assert type(obj.getSetting("check_for_updates").toVariant()) == bool + assert type(obj.getSetting("default_graph.xzoom").toVariant()) in [float, int] def test_set_config(self, temporary): tmpfile, directory = temporary obj = Helper(pwd, tmpfile) obj.setSetting("last_install_greet", obj.getSetting("last_install_greet")) - obj.setSettingBool("check_for_updates", obj.getSettingBool("check_for_updates")) - obj.setSettingInt("default_graph.xzoom", obj.getSettingInt("default_graph.xzoom")) + obj.setSetting("check_for_updates", obj.getSetting("check_for_updates")) + obj.setSetting("default_graph.xzoom", obj.getSetting("default_graph.xzoom")) def test_fetch_changelog(self, temporary, qtbot): tmpfile, directory = temporary From f734e40ad9e986357c2e591a7ce50e35c97799f9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 01:22:25 +0200 Subject: [PATCH 200/249] Starting PyPromise --- .../LogarithmPlotter/Popup/Changelog.qml | 20 ++-- .../LogarithmPlotter/util/helper.py | 57 ++++----- runtime-pyside6/LogarithmPlotter/util/js.py | 8 +- .../LogarithmPlotter/util/latex.py | 6 +- .../LogarithmPlotter/util/promise.py | 110 ++++++++++++++++++ 5 files changed, 157 insertions(+), 44 deletions(-) create mode 100644 runtime-pyside6/LogarithmPlotter/util/promise.py diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 844e22a..93d76db 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -45,17 +45,17 @@ Popup { property bool changelogNeedsFetching: true onAboutToShow: if(changelogNeedsFetching) { - Helper.fetchChangelog() - } - - Connections { - target: Helper - function onChangelogFetched(chl) { - changelogNeedsFetching = false; - changelog.text = chl + Helper.fetchChangelog().then((fetchedText) => { + changelogNeedsFetching = false + changelog.text = fetchedText changelogView.contentItem.implicitHeight = changelog.height - // console.log(changelog.height, changelogView.contentItem.implicitHeight) - } + }, (error) => { + const e = qsTranslate("changelog", "Could not fetch update: {}.").replace('{}', error) + console.error(e) + changelogNeedsFetching = false + changelog.text = e + changelogView.contentItem.implicitHeight = changelog.height + }) } ScrollView { diff --git a/runtime-pyside6/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index 344e425..7f7afb9 100644 --- a/runtime-pyside6/LogarithmPlotter/util/helper.py +++ b/runtime-pyside6/LogarithmPlotter/util/helper.py @@ -29,13 +29,16 @@ from urllib.error import HTTPError, URLError from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config +from LogarithmPlotter.util.promise import PyPromise SHOW_GUI_MESSAGES = "--test-build" not in argv CHANGELOG_VERSION = __VERSION__ +CHANGELOG_CACHE_PATH = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") class InvalidFileException(Exception): pass + def show_message(msg: str) -> None: """ Shows a GUI message if GUI messages are enabled @@ -46,31 +49,30 @@ def show_message(msg: str) -> None: raise InvalidFileException(msg) +def fetch_changelog(): + msg_text = "Unknown changelog error." + try: + # Fetching version + r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + CHANGELOG_VERSION) + lines = r.readlines() + r.close() + msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() + except HTTPError as e: + msg_text = QCoreApplication.translate("changelog", "Could not fetch changelog: Server error {}.").format( + str(e.code)) + except URLError as e: + msg_text = QCoreApplication.translate("changelog", "Could not fetch update: {}.").format(str(e.reason)) + return msg_text -class ChangelogFetcher(QRunnable): - def __init__(self, helper): - QRunnable.__init__(self) - self.helper = helper - def run(self): - msg_text = "Unknown changelog error." - try: - # Fetching version - r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + CHANGELOG_VERSION) - lines = r.readlines() - r.close() - msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() - except HTTPError as e: - msg_text = QCoreApplication.translate("changelog", "Could not fetch changelog: Server error {}.").format( - str(e.code)) - except URLError as e: - msg_text = QCoreApplication.translate("changelog", "Could not fetch update: {}.").format(str(e.reason)) - self.helper.changelogFetched.emit(msg_text) +def read_changelog(): + f = open(CHANGELOG_CACHE_PATH, 'r', -1) + data = f.read().strip() + f.close() + return data class Helper(QObject): - changelogFetched = Signal(str) - def __init__(self, cwd: str, tmpfile: str): QObject.__init__(self) self.cwd = cwd @@ -150,15 +152,14 @@ class Helper(QObject): msg = QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}") return msg.format(PySide6_version, sys_version.split("\n")[0]) - @Slot() + @Slot(result=PyPromise) def fetchChangelog(self): - changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") - if path.exists(changelog_cache_path): + """ + Fetches the changelog and returns a Promise. + """ + if path.exists(CHANGELOG_CACHE_PATH): # We have a cached version of the changelog, for env that don't have access to the internet. - f = open(changelog_cache_path); - self.changelogFetched.emit("".join(f.readlines()).strip()) - f.close() + return PyPromise(read_changelog) else: # Fetch it from the internet. - runnable = ChangelogFetcher(self) - QThreadPool.globalInstance().start(runnable) + return PyPromise(fetch_changelog) diff --git a/runtime-pyside6/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py index dbe60bc..05f30d5 100644 --- a/runtime-pyside6/LogarithmPlotter/util/js.py +++ b/runtime-pyside6/LogarithmPlotter/util/js.py @@ -16,13 +16,13 @@ * along with this program. If not, see . """ from re import Pattern +from typing import Callable from PySide6.QtCore import QMetaObject, QObject, QDateTime from PySide6.QtQml import QJSValue class InvalidAttributeValueException(Exception): pass class NotAPrimitiveException(Exception): pass -class Function: pass class URL: pass class PyJSValue: @@ -78,7 +78,7 @@ class PyJSValue: matcher = [ (lambda: self.qjs_value.isArray(), list), (lambda: self.qjs_value.isBool(), bool), - (lambda: self.qjs_value.isCallable(), Function), + (lambda: self.qjs_value.isCallable(), Callable), (lambda: self.qjs_value.isDate(), QDateTime), (lambda: self.qjs_value.isError(), Exception), (lambda: self.qjs_value.isNull(), None), @@ -103,4 +103,6 @@ class PyJSValue: """ if self.type() not in [bool, float, str, None]: raise NotAPrimitiveException() - return self.qjs_value.toPrimitive().toVariant() \ No newline at end of file + return self.qjs_value.toPrimitive().toVariant() + + diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index df32d46..aac5c5b 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -16,18 +16,17 @@ * along with this program. If not, see . """ -from PySide6.QtCore import QObject, Slot, Property, QCoreApplication +from PySide6.QtCore import QObject, Slot, Property, QCoreApplication, Signal from PySide6.QtGui import QImage, QColor from PySide6.QtWidgets import QMessageBox -from os import path, remove, environ, makedirs +from os import path, remove, makedirs from string import Template from subprocess import Popen, TimeoutExpired, PIPE from hashlib import sha512 from shutil import which from sys import argv - """ Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) installation and collects the binary path in the DVIPNG_PATH variable. @@ -76,6 +75,7 @@ class Latex(QObject): dvipng to be installed on the system. """ + def __init__(self, cache_path): QObject.__init__(self) self.tempdir = path.join(cache_path, "latex") diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py new file mode 100644 index 0000000..1ccfe8e --- /dev/null +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -0,0 +1,110 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from typing import Callable + +from PySide6.QtCore import QRunnable, Signal, QObject, Slot, QThreadPool +from PySide6.QtQml import QJSValue + +from LogarithmPlotter.util.js import PyJSValue + + +class InvalidReturnValue(Exception): pass + + +class PyPromiseRunner(QRunnable): + """ + QRunnable for running Promises in different threads. + """ + def __init__(self, runner, promise): + QRunnable.__init__(self) + self.runner = runner + self.promise = promise + print("Initialized", self.runner) + + def run(self): + try: + data = self.runner() + if isinstance(data, QObject): + data = data + elif type(data) in [int, str, float, bool, bytes]: + data = QJSValue(data) + elif data is None: + data = QJSValue.SpecialValue.UndefinedValue + elif isinstance(data, QJSValue): + data = data + elif isinstance(data, PyJSValue): + data = data.qjs_value + else: + raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.") + self.promise.finished.emit(data) + except Exception as e: + self.promise.errored.emit(repr(e)) + + +class PyPromise(QObject): + """ + Asynchronous Promise-like object meant to interface between Python and Javascript easily. + Runs to_run in another thread, and calls fulfilled (populated by then) with its return value. + """ + finished = Signal((QJSValue,), (QObject,)) + errored = Signal(Exception) + + def __init__(self, to_run: Callable): + QObject.__init__(self) + self._fulfills = [] + self._rejects = [] + self.finished.connect(self._fulfill) + self.errored.connect(self._reject) + self._runner = PyPromiseRunner(to_run, self) + QThreadPool.globalInstance().start(self._runner) + + + @Slot(QJSValue, result=QObject) + @Slot(QJSValue, QJSValue, result=QObject) + def then(self, on_fulfill: QJSValue | Callable, on_reject: QJSValue | Callable = None): + """ + Adds listeners for both fulfilment and catching errors of the Promise. + """ + if isinstance(on_fulfill, QJSValue): + self._fulfills.append(PyJSValue(on_fulfill)) + elif isinstance(on_fulfill, Callable): + self._fulfills.append(on_fulfill) + if isinstance(on_reject, QJSValue): + self._rejects.append(PyJSValue(on_reject)) + elif isinstance(on_reject, Callable): + self._rejects.append(on_reject) + + @Slot(QJSValue) + @Slot(QObject) + def _fulfill(self, data): + no_return = [None, QJSValue.SpecialValue.UndefinedValue] + for on_fulfill in self._fulfills: + try: + result = on_fulfill(data) + data = result if result not in no_return else data # Forward data. + except Exception as e: + self._reject(repr(e)) + break + + @Slot(QJSValue) + @Slot(str) + def _reject(self, error): + no_return = [None, QJSValue.SpecialValue.UndefinedValue] + for on_reject in self._rejects: + result = on_reject(error) + error = result if result not in no_return else error # Forward data. From cf73b35a9ab1494485006ec4dafcb9653a29e106 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 03:01:27 +0200 Subject: [PATCH 201/249] Adding experimental async LaTeX renderer (speeds up rendering ridiculously, but causes instability) --- common/src/module/interface.mjs | 10 +++++++- common/src/module/latex.mjs | 7 +++++- common/src/preferences/general.mjs | 9 ++++++- .../LogarithmPlotter/util/config.py | 1 + .../LogarithmPlotter/util/latex.py | 24 +++++++++++++++---- .../LogarithmPlotter/util/promise.py | 11 +++++---- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index b6d462f..a96621c 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -84,13 +84,21 @@ export class DialogInterface extends Interface { } export class LatexInterface extends Interface { + supportsAsyncRender = BOOLEAN /** * @param {string} markup - LaTeX markup to render * @param {number} fontSize - Font size (in pt) to render * @param {string} color - Color of the text to render * @returns {string} - Comma separated data of the image (source, width, height) */ - render = FUNCTION + renderSync = FUNCTION + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {Promise} - Comma separated data of the image (source, width, height) + */ + renderAsync = FUNCTION /** * @param {string} markup - LaTeX markup to render * @param {number} fontSize - Font size (in pt) to render diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index a6aa216..830f096 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -112,7 +112,12 @@ class LatexAPI extends Module { */ async requestAsyncRender(markup, fontSize, color) { if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") - let args = this.#latex.render(markup, fontSize, color).split(",") + let render + if(this.#latex.supportsAsyncRender) + render = await this.#latex.renderAsync(markup, fontSize, color) + else + render = this.#latex.renderSync(markup, fontSize, color) + const args = render.split(",") return new LatexRenderResult(...args) } diff --git a/common/src/preferences/general.mjs b/common/src/preferences/general.mjs index 81c5e3d..4a1098f 100644 --- a/common/src/preferences/general.mjs +++ b/common/src/preferences/general.mjs @@ -46,8 +46,15 @@ class EnableLatex extends BoolSetting { } } +const ENABLE_LATEX_ASYNC = new BoolSetting( + qsTranslate("general", "Enable asynchronous LaTeX renderer (experimental)"), + "enable_latex_async", + "new" +) + export default [ CHECK_FOR_UPDATES, RESET_REDO_STACK, - new EnableLatex() + new EnableLatex(), + ENABLE_LATEX_ASYNC ] diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index a5ee23c..ae10adb 100644 --- a/runtime-pyside6/LogarithmPlotter/util/config.py +++ b/runtime-pyside6/LogarithmPlotter/util/config.py @@ -26,6 +26,7 @@ DEFAULT_SETTINGS = { "reset_redo_stack": True, "last_install_greet": "0", "enable_latex": False, + "enable_latex_async": False, "expression_editor": { "autoclose": True, "colorize": True, diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index aac5c5b..0d720c3 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ +from time import sleep from PySide6.QtCore import QObject, Slot, Property, QCoreApplication, Signal from PySide6.QtGui import QImage, QColor @@ -27,6 +28,9 @@ from hashlib import sha512 from shutil import which from sys import argv +from LogarithmPlotter.util import config +from LogarithmPlotter.util.promise import PyPromise + """ Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) installation and collects the binary path in the DVIPNG_PATH variable. @@ -75,7 +79,6 @@ class Latex(QObject): dvipng to be installed on the system. """ - def __init__(self, cache_path): QObject.__init__(self) self.tempdir = path.join(cache_path, "latex") @@ -85,6 +88,10 @@ class Latex(QObject): def latexSupported(self) -> bool: return LATEX_PATH is not None and DVIPNG_PATH is not None + @Property(bool) + def supportsAsyncRender(self) -> bool: + return config.getSetting("enable_latex_async") + @Slot(result=bool) def checkLatexInstallation(self) -> bool: """ @@ -105,13 +112,20 @@ class Latex(QObject): valid_install = False else: try: - self.render("", 14, QColor(0, 0, 0, 255)) + self.renderSync("", 14, QColor(0, 0, 0, 255)) except MissingPackageException: valid_install = False # Should have sent an error message if failed to render return valid_install + @Slot(str, float, QColor, result=PyPromise) + def renderAsync(self, latex_markup: str, font_size: float, color: QColor) -> PyPromise: + """ + Prepares and renders a latex string into a png file asynchronously. + """ + return PyPromise(self.renderSync, [latex_markup, font_size, color]) + @Slot(str, float, QColor, result=str) - def render(self, latex_markup: str, font_size: float, color: QColor) -> str: + def renderSync(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Prepares and renders a latex string into a png file. """ @@ -124,12 +138,14 @@ class Latex(QObject): if not path.exists(latex_path + ".dvi"): self.create_latex_doc(latex_path, latex_markup) self.convert_latex_to_dvi(latex_path) - self.cleanup(latex_path) + # self.cleanup(latex_path) # Creating four pictures of different sizes to better handle dpi. self.convert_dvi_to_png(latex_path, export_path, font_size, color) # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) + else: + sleep(0) img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index 1ccfe8e..6868432 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -30,15 +30,15 @@ class PyPromiseRunner(QRunnable): """ QRunnable for running Promises in different threads. """ - def __init__(self, runner, promise): + def __init__(self, runner, promise, args): QRunnable.__init__(self) self.runner = runner self.promise = promise - print("Initialized", self.runner) + self.args = args def run(self): try: - data = self.runner() + data = self.runner(*self.args) if isinstance(data, QObject): data = data elif type(data) in [int, str, float, bool, bytes]: @@ -64,13 +64,13 @@ class PyPromise(QObject): finished = Signal((QJSValue,), (QObject,)) errored = Signal(Exception) - def __init__(self, to_run: Callable): + def __init__(self, to_run: Callable, args): QObject.__init__(self) self._fulfills = [] self._rejects = [] self.finished.connect(self._fulfill) self.errored.connect(self._reject) - self._runner = PyPromiseRunner(to_run, self) + self._runner = PyPromiseRunner(to_run, self, args) QThreadPool.globalInstance().start(self._runner) @@ -88,6 +88,7 @@ class PyPromise(QObject): self._rejects.append(PyJSValue(on_reject)) elif isinstance(on_reject, Callable): self._rejects.append(on_reject) + return self @Slot(QJSValue) @Slot(QObject) From 531342825095e0703d251c38e382e293289b263b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 03:52:06 +0200 Subject: [PATCH 202/249] Improving stability of asynchronous LaTeX renderer. --- common/src/module/canvas.mjs | 16 +++++++++++----- common/src/preferences/general.mjs | 2 +- runtime-pyside6/LogarithmPlotter/util/promise.py | 7 ++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index c46c9a1..62649cf 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -30,16 +30,18 @@ class CanvasAPI extends Module { #canvas = null /** @type {CanvasRenderingContext2D} */ #ctx = null + /** Lock to prevent asynchronous stuff from printing stuff that is outdated. */ + #redrawCount = 0 /** @type {{show(string, string, string)}} */ #drawingErrorDialog = null - - + + constructor() { super("Canvas", { canvas: CanvasInterface, drawingErrorDialog: DialogInterface }) - + /** * * @type {Object.} @@ -207,6 +209,7 @@ class CanvasAPI extends Module { */ redraw() { if(!this.initialized) throw new Error("Attempting redraw before initialize!") + this.#redrawCount = (this.#redrawCount + 1) % 10000 this.#ctx = this.#canvas.getContext("2d") this._computeAxes() this._reset() @@ -519,15 +522,18 @@ class CanvasAPI extends Module { * @param {function(LatexRenderResult|{width: number, height: number, source: string})} callback */ renderLatexImage(ltxText, color, callback) { + const currentRedrawCount = this.#redrawCount const onRendered = (imgData) => { if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) { // Wait until the image is loaded to callback. this.#canvas.loadImageAsync(imgData.source).then(() => { - callback(imgData) + if(this.#redrawCount === currentRedrawCount) + callback(imgData) }) } else { // Callback directly - callback(imgData) + if(this.#redrawCount === currentRedrawCount) + callback(imgData) } } const prerendered = Latex.findPrerendered(ltxText, this.textsize, color) diff --git a/common/src/preferences/general.mjs b/common/src/preferences/general.mjs index 4a1098f..a6957c6 100644 --- a/common/src/preferences/general.mjs +++ b/common/src/preferences/general.mjs @@ -47,7 +47,7 @@ class EnableLatex extends BoolSetting { } const ENABLE_LATEX_ASYNC = new BoolSetting( - qsTranslate("general", "Enable asynchronous LaTeX renderer (experimental)"), + qsTranslate("general", "Enable asynchronous LaTeX renderer"), "enable_latex_async", "new" ) diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index 6868432..f129d41 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -53,7 +53,12 @@ class PyPromiseRunner(QRunnable): raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.") self.promise.finished.emit(data) except Exception as e: - self.promise.errored.emit(repr(e)) + try: + self.promise.errored.emit(repr(e)) + except RuntimeError as e2: + # Happens when the PyPromise has already been garbage collected. + # In other words, nothing to report to nowhere. + pass class PyPromise(QObject): From 37ac400f230591edb0e14efaaff50de127b7e19a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 03:52:47 +0200 Subject: [PATCH 203/249] Enabling latex async generation by default, default LaTeX setting now depends on state of installation. --- runtime-pyside6/LogarithmPlotter/util/config.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index ae10adb..e01deae 100644 --- a/runtime-pyside6/LogarithmPlotter/util/config.py +++ b/runtime-pyside6/LogarithmPlotter/util/config.py @@ -19,14 +19,16 @@ from os import path, environ, makedirs from platform import system from json import load, dumps +from shutil import which + from PySide6.QtCore import QLocale, QTranslator DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, "last_install_greet": "0", - "enable_latex": False, - "enable_latex_async": False, + "enable_latex": which("latex") is not None and which("dvipng") is not None, + "enable_latex_async": True, "expression_editor": { "autoclose": True, "colorize": True, From ccddb068a670ceb607c9e034c4dfb0accdebf2e9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 18:06:24 +0200 Subject: [PATCH 204/249] Fixing tests for Promises (new ones need to be written) --- runtime-pyside6/.coverage | Bin 0 -> 53248 bytes .../LogarithmPlotter/util/promise.py | 22 +++-- runtime-pyside6/tests/test_helper.py | 83 ++++++++---------- runtime-pyside6/tests/test_latex.py | 10 +-- 4 files changed, 57 insertions(+), 58 deletions(-) create mode 100644 runtime-pyside6/.coverage diff --git a/runtime-pyside6/.coverage b/runtime-pyside6/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..8eab2ed6efa5c8f1c8ebd2f83154347499e04eff GIT binary patch literal 53248 zcmeI4Uu+yl9mn^dZ*T99CykY!ToW=tsbkfDVxWm=B~q70q7X<+LtjwY?%j>;EqA-; z-95)fRM9m>k&s#m5aI#aClC+tzynD92`LpX1PM@t5J*rWifHpd2^B4hlm_#g{o}if z?W!+6tMPYrH?uoCGr!;OGryVHxxL+oA3E+vg3tRw(~0;8l|728D)(}(D2hejGJUhn zq#YwWpjhqM-)h%VroXUMW{)VP+|vsCT=@i>Dt)VbNAY5*X??l)oatCKI)M!YKmY_l zV0RPfJXA6(qoeARPee|&A)>&ki69BfAN};Pxs%8E$+`QEALB_HKUmCgD*wD# zos2W2(ju`EB?(lCa2Gt8gC9(bPw+s@i$Hia5hhw3bn6p^i8H4QW@ThVJu70HoS;UZ zVxKjX&^6_Od8(-92X(1^HE_Jzq6jCsvuY>vuyh+J4ds=v&l=J)yYqy{jO@(8fy>_!o z$RBSvTe5MeL?Sryw<@_+*~m|gecNrbNn3X9?Q6~qxopv-RNHfx+G4%&CwaHzWNe1# zPjYDldBFRNxypw}RE4}!tb|Jqy56##cI3y$HZ{IIOF`+WTk>Y*zybB_QtT)ak6m@6 zaDB(>bDH(!EnG*Q-`a0vFX?v@*^3$t?$5_vMwaGDf#bIO|k#E#p zCX?dhL%GU5`?gYCs$kE`Fn8v&TCDQf(U^Xd27UR}`&5=GU6nr}R;QMo28|{y#|@~< z(ioh~09l$~qR7$77wc$wdzHC#lnA{fl;* zO~s4kg}?sp;)xlO@kmROnCu}(Q5uLXim(p)+*uD_KV$kwuFWhht4d3h<SLAkPXI@z4^MxfKvrq&vcfL2 zH{O{BLTeBJ0T2KI5C8!X009sH0T2KI5CDOUKuO=PX1@Yx1%1p)e*}>C|BJ;jg?)wX zAO7C(-Q{1EKT~?8v|L;(K26EkKmY_l00ck)1V8`;Kw!5JXcY~mBW9YS?m9D0{jNiY zW@o~%E+0~!nQOJendAO~6S&c0^TCE6MIzXk5VSq{Q1Mi2HFWFZ@Wu@7$ZgEDTU4i@ zhnHK00ZH`eH()%aoT`4ipNTNG{ zcC>BRb0ga(nN5{s+S@C$N1VL>Uo5^$VP7pN?A^oPAHJu2p>(-)s`yO#5lY4e0w4ea zAOHd&00JNY0=tI5lFwhyaItzo4)?NSS2IV^I>;IuawPCjYHwIm;$mD4{x@{6DUY;5d3dks2whoLDy{?G5mXFv8A`^2|bZ`CPn zS|=l}`)fyE|N2wc_l{pZ{_k>5qx4}-wN%5hZq<|zJ*UUd|Fa({>>7KWegSxyU1EP? z7um1bFWEUt#s&f)00JNY0w4eaAOHd&00JNY0wAzc1mv#-YOxqcg+d%zRvhK?ab%it zl*`4@&`=y1MjYvS9BGH^_To3>O5C8!X009sH0T2KI5C8!X7zhD* z{~zoBfuM#E5C8!X009sH0T2KI5C8!X009u#F#^f+{}<%{|NqNgWB+8Yu$S12^bEl7 z*>Bl}9a9T}K>!3m00ck)1V8`;KmY_l00ck)1U4g}7wK*OdO-%34DvECWssA>kPHkN M=rYh`Am9K0e?Y`G00000 literal 0 HcmV?d00001 diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index f129d41..41b916d 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -17,7 +17,7 @@ """ from typing import Callable -from PySide6.QtCore import QRunnable, Signal, QObject, Slot, QThreadPool +from PySide6.QtCore import QRunnable, Signal, Property, QObject, Slot, QThreadPool from PySide6.QtQml import QJSValue from LogarithmPlotter.util.js import PyJSValue @@ -51,10 +51,10 @@ class PyPromiseRunner(QRunnable): data = data.qjs_value else: raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.") - self.promise.finished.emit(data) + self.promise.fulfilled.emit(data) except Exception as e: try: - self.promise.errored.emit(repr(e)) + self.promise.rejected.emit(repr(e)) except RuntimeError as e2: # Happens when the PyPromise has already been garbage collected. # In other words, nothing to report to nowhere. @@ -66,18 +66,22 @@ class PyPromise(QObject): Asynchronous Promise-like object meant to interface between Python and Javascript easily. Runs to_run in another thread, and calls fulfilled (populated by then) with its return value. """ - finished = Signal((QJSValue,), (QObject,)) - errored = Signal(Exception) + fulfilled = Signal((QJSValue,), (QObject,)) + rejected = Signal(Exception) - def __init__(self, to_run: Callable, args): + def __init__(self, to_run: Callable, args=[]): QObject.__init__(self) self._fulfills = [] self._rejects = [] - self.finished.connect(self._fulfill) - self.errored.connect(self._reject) + self._state = "pending" + self.fulfilled.connect(self._fulfill) + self.rejected.connect(self._reject) self._runner = PyPromiseRunner(to_run, self, args) QThreadPool.globalInstance().start(self._runner) + @Property(str) + def state(self): + return self._state @Slot(QJSValue, result=QObject) @Slot(QJSValue, QJSValue, result=QObject) @@ -98,6 +102,7 @@ class PyPromise(QObject): @Slot(QJSValue) @Slot(QObject) def _fulfill(self, data): + self._state = "fulfilled" no_return = [None, QJSValue.SpecialValue.UndefinedValue] for on_fulfill in self._fulfills: try: @@ -110,6 +115,7 @@ class PyPromise(QObject): @Slot(QJSValue) @Slot(str) def _reject(self, error): + self._state = "rejected" no_return = [None, QJSValue.SpecialValue.UndefinedValue] for on_reject in self._rejects: result = on_reject(error) diff --git a/runtime-pyside6/tests/test_helper.py b/runtime-pyside6/tests/test_helper.py index 73dfb23..5cfb239 100644 --- a/runtime-pyside6/tests/test_helper.py +++ b/runtime-pyside6/tests/test_helper.py @@ -17,7 +17,7 @@ """ import pytest -from os import getcwd, remove +from os import getcwd, remove, path from os.path import join from tempfile import TemporaryDirectory from json import loads @@ -25,11 +25,12 @@ from shutil import copy2 from PySide6.QtCore import QObject, Signal, QThreadPool from PySide6.QtGui import QImage +from PySide6.QtQml import QJSValue from PySide6.QtWidgets import QApplication from LogarithmPlotter import __VERSION__ as version from LogarithmPlotter.util import config, helper -from LogarithmPlotter.util.helper import ChangelogFetcher, Helper, InvalidFileException +from LogarithmPlotter.util.helper import Helper, InvalidFileException pwd = getcwd() helper.SHOW_GUI_MESSAGES = False @@ -43,41 +44,45 @@ def temporary(): directory.cleanup() -class MockHelperSignals(QObject): - changelogFetched = Signal(str) +def create_changelog_callback_asserter(promise, expect_404=False): + def cb(changelog, expect_404=expect_404): + # print("Got changelog", changelog) + assert isinstance(changelog, QJSValue) + assert changelog.isString() + changlogValue = changelog.toVariant() + assert ('404' in changlogValue) == expect_404 + def error(e): + raise eval(e) + promise.then(cb, error) - def __init__(self, expect_404): - QObject.__init__(self) - self.expect_404 = expect_404 - self.changelogFetched.connect(self.changelog_fetched) - self.changelog = None - - def changelog_fetched(self, changelog): - self.changelog = changelog - - -class TestChangelog: - - def test_exists(self, qtbot): - helper.CHANGELOG_VERSION = '0.5.0' - mock_helper = MockHelperSignals(False) - fetcher = ChangelogFetcher(mock_helper) - fetcher.run() # Does not raise an exception - qtbot.waitSignal(mock_helper.changelogFetched, timeout=10000) - assert type(mock_helper.changelog) == str - assert '404' not in mock_helper.changelog - - def tests_no_exist(self, qtbot): - mock_helper = MockHelperSignals(True) - helper.CHANGELOG_VERSION = '1.0.0' - fetcher = ChangelogFetcher(mock_helper) - fetcher.run() - qtbot.waitSignal(mock_helper.changelogFetched, timeout=10000) - assert type(mock_helper.changelog) == str - assert '404' in mock_helper.changelog +CHANGELOG_BASE_PATH = path.realpath(path.join(path.dirname(path.realpath(__file__)), "..", "CHANGELOG.md")) class TestHelper: + def test_changelog(self, temporary, qtbot): + helper.CHANGELOG_VERSION = '0.5.0' + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + promise = obj.fetchChangelog() + create_changelog_callback_asserter(promise, expect_404=False) + qtbot.waitSignal(promise.fulfilled, timeout=10000) + # No exist + helper.CHANGELOG_VERSION = '2.0.0' + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + promise = obj.fetchChangelog() + create_changelog_callback_asserter(promise, expect_404=True) + qtbot.waitSignal(promise.fulfilled, timeout=10000) + # Local + tmpfile, directory = temporary + obj = Helper(pwd, tmpfile) + assert path.exists(CHANGELOG_BASE_PATH) + copy2(CHANGELOG_BASE_PATH, helper.CHANGELOG_CACHE_PATH) + assert path.exists(helper.CHANGELOG_CACHE_PATH) + promise = obj.fetchChangelog() + create_changelog_callback_asserter(promise, expect_404=False) + qtbot.waitSignal(promise.fulfilled, timeout=10000) # Local + def test_read(self, temporary): # Test file reading and information loading. tmpfile, directory = temporary @@ -168,15 +173,3 @@ class TestHelper: obj.setSetting("last_install_greet", obj.getSetting("last_install_greet")) obj.setSetting("check_for_updates", obj.getSetting("check_for_updates")) obj.setSetting("default_graph.xzoom", obj.getSetting("default_graph.xzoom")) - - def test_fetch_changelog(self, temporary, qtbot): - tmpfile, directory = temporary - obj = Helper(pwd, tmpfile) - copy2("../../CHANGELOG.md", "../../LogarithmPlotter/util/CHANGELOG.md") - obj.fetchChangelog() - assert QThreadPool.globalInstance().activeThreadCount() == 0 - qtbot.waitSignal(obj.changelogFetched, timeout=10000) - remove("../../LogarithmPlotter/util/CHANGELOG.md") - obj.fetchChangelog() - assert QThreadPool.globalInstance().activeThreadCount() > 0 - qtbot.waitSignal(obj.changelogFetched, timeout=10000) \ No newline at end of file diff --git a/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index d74f9f1..6fd5c97 100644 --- a/runtime-pyside6/tests/test_latex.py +++ b/runtime-pyside6/tests/test_latex.py @@ -54,8 +54,8 @@ class TestLatex: # Reset [latex.DVIPNG_PATH, latex.LATEX_PATH] = bkp - def test_render(self, latex_obj: latex.Latex) -> None: - result = latex_obj.render(r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)) + def test_render_sync(self, latex_obj: latex.Latex) -> None: + result = latex_obj.renderSync(r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)) # Ensure result format assert type(result) == str [path, width, height] = result.split(",") @@ -64,17 +64,17 @@ class TestLatex: assert match(r"\d+", height) # Ensure it returns errors on invalid latex. with pytest.raises(latex.RenderError): - latex_obj.render(r"\nonexistant", 14, QColor(0, 0, 0, 255)) + latex_obj.renderSync(r"\nonexistant", 14, QColor(0, 0, 0, 255)) # Replace latex bin with one that returns errors bkp = latex.LATEX_PATH latex.LATEX_PATH = which("false") with pytest.raises(latex.RenderError): - latex_obj.render(r"\mathrm{f}(x)", 14, QColor(0, 0, 0, 255)) + latex_obj.renderSync(r"\mathrm{f}(x)", 14, QColor(0, 0, 0, 255)) latex.LATEX_PATH = bkp def test_prerendered(self, latex_obj: latex.Latex) -> None: args = [r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)] - latex_obj.render(*args) + latex_obj.renderSync(*args) prerendered = latex_obj.findPrerendered(*args) assert type(prerendered) == str [path, width, height] = prerendered.split(",") From aeaaba759f90a86100c69cabf08531f385d50e85 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 19:21:40 +0200 Subject: [PATCH 205/249] Starting latex render locking. --- common/src/module/canvas.mjs | 4 + runtime-pyside6/.coverage | Bin 53248 -> 0 bytes .../LogarithmPlotter/util/latex.py | 69 ++++++++++++++++-- .../LogarithmPlotter/util/promise.py | 43 ++++++++--- 4 files changed, 99 insertions(+), 17 deletions(-) delete mode 100644 runtime-pyside6/.coverage diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 62649cf..6abbf2d 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -529,11 +529,15 @@ class CanvasAPI extends Module { this.#canvas.loadImageAsync(imgData.source).then(() => { if(this.#redrawCount === currentRedrawCount) callback(imgData) + else + console.log("2Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) }) } else { // Callback directly if(this.#redrawCount === currentRedrawCount) callback(imgData) + else + console.log("2Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) } } const prerendered = Latex.findPrerendered(ltxText, this.textsize, color) diff --git a/runtime-pyside6/.coverage b/runtime-pyside6/.coverage deleted file mode 100644 index 8eab2ed6efa5c8f1c8ebd2f83154347499e04eff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI4Uu+yl9mn^dZ*T99CykY!ToW=tsbkfDVxWm=B~q70q7X<+LtjwY?%j>;EqA-; z-95)fRM9m>k&s#m5aI#aClC+tzynD92`LpX1PM@t5J*rWifHpd2^B4hlm_#g{o}if z?W!+6tMPYrH?uoCGr!;OGryVHxxL+oA3E+vg3tRw(~0;8l|728D)(}(D2hejGJUhn zq#YwWpjhqM-)h%VroXUMW{)VP+|vsCT=@i>Dt)VbNAY5*X??l)oatCKI)M!YKmY_l zV0RPfJXA6(qoeARPee|&A)>&ki69BfAN};Pxs%8E$+`QEALB_HKUmCgD*wD# zos2W2(ju`EB?(lCa2Gt8gC9(bPw+s@i$Hia5hhw3bn6p^i8H4QW@ThVJu70HoS;UZ zVxKjX&^6_Od8(-92X(1^HE_Jzq6jCsvuY>vuyh+J4ds=v&l=J)yYqy{jO@(8fy>_!o z$RBSvTe5MeL?Sryw<@_+*~m|gecNrbNn3X9?Q6~qxopv-RNHfx+G4%&CwaHzWNe1# zPjYDldBFRNxypw}RE4}!tb|Jqy56##cI3y$HZ{IIOF`+WTk>Y*zybB_QtT)ak6m@6 zaDB(>bDH(!EnG*Q-`a0vFX?v@*^3$t?$5_vMwaGDf#bIO|k#E#p zCX?dhL%GU5`?gYCs$kE`Fn8v&TCDQf(U^Xd27UR}`&5=GU6nr}R;QMo28|{y#|@~< z(ioh~09l$~qR7$77wc$wdzHC#lnA{fl;* zO~s4kg}?sp;)xlO@kmROnCu}(Q5uLXim(p)+*uD_KV$kwuFWhht4d3h<SLAkPXI@z4^MxfKvrq&vcfL2 zH{O{BLTeBJ0T2KI5C8!X009sH0T2KI5CDOUKuO=PX1@Yx1%1p)e*}>C|BJ;jg?)wX zAO7C(-Q{1EKT~?8v|L;(K26EkKmY_l00ck)1V8`;Kw!5JXcY~mBW9YS?m9D0{jNiY zW@o~%E+0~!nQOJendAO~6S&c0^TCE6MIzXk5VSq{Q1Mi2HFWFZ@Wu@7$ZgEDTU4i@ zhnHK00ZH`eH()%aoT`4ipNTNG{ zcC>BRb0ga(nN5{s+S@C$N1VL>Uo5^$VP7pN?A^oPAHJu2p>(-)s`yO#5lY4e0w4ea zAOHd&00JNY0=tI5lFwhyaItzo4)?NSS2IV^I>;IuawPCjYHwIm;$mD4{x@{6DUY;5d3dks2whoLDy{?G5mXFv8A`^2|bZ`CPn zS|=l}`)fyE|N2wc_l{pZ{_k>5qx4}-wN%5hZq<|zJ*UUd|Fa({>>7KWegSxyU1EP? z7um1bFWEUt#s&f)00JNY0w4eaAOHd&00JNY0wAzc1mv#-YOxqcg+d%zRvhK?ab%it zl*`4@&`=y1MjYvS9BGH^_To3>O5C8!X009sH0T2KI5C8!X7zhD* z{~zoBfuM#E5C8!X009sH0T2KI5C8!X009u#F#^f+{}<%{|NqNgWB+8Yu$S12^bEl7 z*>Bl}9a9T}K>!3m00ck)1V8`;KmY_l00ck)1U4g}7wK*OdO-%34DvECWssA>kPHkN M=rYh`Am9K0e?Y`G00000 diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 0d720c3..2db62eb 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -82,6 +82,7 @@ class Latex(QObject): def __init__(self, cache_path): QObject.__init__(self) self.tempdir = path.join(cache_path, "latex") + self.render_pipeline_locks = {} makedirs(self.tempdir, exist_ok=True) @Property(bool) @@ -116,20 +117,71 @@ class Latex(QObject): except MissingPackageException: valid_install = False # Should have sent an error message if failed to render return valid_install + + def lock(self, markup_hash, render_hash, promise): + """ + Locks the render pipeline for a given markup hash and render hash. + """ + # print("Locking", markup_hash, render_hash) + if markup_hash not in self.render_pipeline_locks: + self.render_pipeline_locks[markup_hash] = promise + self.render_pipeline_locks[render_hash] = promise + + + def release_lock(self, markup_hash, render_hash): + """ + Release locks on the markup and render hashes. + """ + # print("Releasing", markup_hash, render_hash) + if markup_hash in self.render_pipeline_locks: + del self.render_pipeline_locks[markup_hash] + del self.render_pipeline_locks[render_hash] @Slot(str, float, QColor, result=PyPromise) def renderAsync(self, latex_markup: str, font_size: float, color: QColor) -> PyPromise: """ Prepares and renders a latex string into a png file asynchronously. """ - return PyPromise(self.renderSync, [latex_markup, font_size, color]) + markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) + promise = None + if render_hash in self.render_pipeline_locks: + # A PyPromise for this specific render is already running. + # print("Already running render of", latex_markup) + promise = self.render_pipeline_locks[render_hash] + elif markup_hash in self.render_pipeline_locks: + # A PyPromise with the same markup, but not the same color or font size is already running. + print("Chaining render of", latex_markup) + existing_promise = self.render_pipeline_locks[markup_hash] + promise = self._create_async_promise(latex_markup, font_size, color) + existing_promise.then(lambda x, latex_markup=latex_markup: print("> Starting chained render of", latex_markup)) + promise.then(lambda x, latex_markup=latex_markup: print("> Fulfilled chained render of", latex_markup, "\n with", x.toVariant())) + existing_promise.then(promise.start) + else: + # No such PyPromise is running. + promise = self._create_async_promise(latex_markup, font_size, color) + promise.start() + return promise + + def _create_async_promise(self, latex_markup: str, font_size: float, color: QColor) -> PyPromise: + """ + Createsa PyPromise to render a latex string into a PNG file. + Internal method. Use renderAsync that makes use of locks. + """ + markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) + promise = PyPromise(self.renderSync, [latex_markup, font_size, color], start_automatically=False) + self.lock(markup_hash, render_hash, promise) + # Make the lock release at the end. + def unlock(data, markup_hash=markup_hash, render_hash=render_hash): + self.release_lock(markup_hash, render_hash) + promise.then(unlock, unlock) + return promise @Slot(str, float, QColor, result=str) def renderSync(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Prepares and renders a latex string into a png file. """ - markup_hash, export_path = self.create_export_path(latex_markup, font_size, color) + markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file @@ -138,14 +190,12 @@ class Latex(QObject): if not path.exists(latex_path + ".dvi"): self.create_latex_doc(latex_path, latex_markup) self.convert_latex_to_dvi(latex_path) - # self.cleanup(latex_path) + self.cleanup(latex_path) # Creating four pictures of different sizes to better handle dpi. self.convert_dvi_to_png(latex_path, export_path, font_size, color) # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) - else: - sleep(0) img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -155,7 +205,7 @@ class Latex(QObject): """ Finds a prerendered image and returns its data if possible, and an empty string if not. """ - markup_hash, export_path = self.create_export_path(latex_markup, font_size, color) + markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) data = "" if path.exists(export_path + ".png"): img = QImage(export_path) @@ -165,10 +215,13 @@ class Latex(QObject): def create_export_path(self, latex_markup: str, font_size: float, color: QColor): """ Standardizes export path for renders. + Markup hash is unique for the markup + Render hash is unique for the markup, the font size and the color. """ markup_hash = "render" + str(sha512(latex_markup.encode()).hexdigest()) - export_path = path.join(self.tempdir, f'{markup_hash}_{int(font_size)}_{color.rgb()}') - return markup_hash, export_path + render_hash = f'{markup_hash}_{int(font_size)}_{color.rgb()}' + export_path = path.join(self.tempdir, render_hash) + return markup_hash, render_hash, export_path def create_latex_doc(self, export_path: str, latex_markup: str): """ diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index 41b916d..e475b36 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -23,6 +23,18 @@ from PySide6.QtQml import QJSValue from LogarithmPlotter.util.js import PyJSValue +def check_callable(function: Callable|QJSValue) -> Callable|None: + """ + Checks if the given function can be called (either a python callable + or a QJSValue function), and returns the object that can be called directly. + Returns None if not a function. + """ + if isinstance(function, QJSValue) and function.isCallable(): + return PyJSValue(function) + elif isinstance(function, Callable): + return function + return None + class InvalidReturnValue(Exception): pass @@ -69,16 +81,30 @@ class PyPromise(QObject): fulfilled = Signal((QJSValue,), (QObject,)) rejected = Signal(Exception) - def __init__(self, to_run: Callable, args=[]): + def __init__(self, to_run: Callable|QJSValue, args=[], start_automatically=True): QObject.__init__(self) self._fulfills = [] self._rejects = [] self._state = "pending" + self._started = False self.fulfilled.connect(self._fulfill) self.rejected.connect(self._reject) + to_run = check_callable(to_run) + if to_run is None: + raise ValueError("New PyPromise created with invalid function") self._runner = PyPromiseRunner(to_run, self, args) - QThreadPool.globalInstance().start(self._runner) - + if start_automatically: + self._start() + + @Slot() + def start(self, *args, **kwargs): + """ + Starts the thread that will run the promise. + """ + if not self._started: # Avoid getting started twice. + QThreadPool.globalInstance().start(self._runner) + self._started = True + @Property(str) def state(self): return self._state @@ -89,13 +115,11 @@ class PyPromise(QObject): """ Adds listeners for both fulfilment and catching errors of the Promise. """ - if isinstance(on_fulfill, QJSValue): - self._fulfills.append(PyJSValue(on_fulfill)) - elif isinstance(on_fulfill, Callable): + on_fulfill = check_callable(on_fulfill) + on_reject = check_callable(on_reject) + if on_fulfill is not None: self._fulfills.append(on_fulfill) - if isinstance(on_reject, QJSValue): - self._rejects.append(PyJSValue(on_reject)) - elif isinstance(on_reject, Callable): + if on_reject is not None: self._rejects.append(on_reject) return self @@ -107,6 +131,7 @@ class PyPromise(QObject): for on_fulfill in self._fulfills: try: result = on_fulfill(data) + result = result.qjs_value if isinstance(result, PyJSValue) else result data = result if result not in no_return else data # Forward data. except Exception as e: self._reject(repr(e)) From a85a4721e3988756e3da1524219381214f8d599b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 15 Oct 2024 20:39:03 +0200 Subject: [PATCH 206/249] Fixing double redraw when opening a file. --- common/src/module/canvas.mjs | 2 +- common/src/module/io.mjs | 1 - runtime-pyside6/LogarithmPlotter/util/debug.py | 3 +++ runtime-pyside6/LogarithmPlotter/util/latex.py | 4 +--- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 6abbf2d..913442f 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -530,7 +530,7 @@ class CanvasAPI extends Module { if(this.#redrawCount === currentRedrawCount) callback(imgData) else - console.log("2Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) + console.log("1Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) }) } else { // Callback directly diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 472b061..92096e9 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -201,7 +201,6 @@ class IOAPI extends Module { // TODO: Error handling return } - Canvas.redraw() this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) this.#saved = true this.emit(new LoadedEvent()) diff --git a/runtime-pyside6/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py index 8b57687..f899fd5 100644 --- a/runtime-pyside6/LogarithmPlotter/util/debug.py +++ b/runtime-pyside6/LogarithmPlotter/util/debug.py @@ -19,10 +19,12 @@ from PySide6.QtCore import QtMsgType, qInstallMessageHandler, QMessageLogContext from math import ceil, log10 from os import path +from re import compile CURRENT_PATH = path.dirname(path.realpath(__file__)) SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map") SOURCEMAP_INDEX = None +INDEX_REG = compile(r"build\/runtime-pyside6\/LogarithmPlotter\/qml\/eu\/ad5001\/LogarithmPlotter\/js\/index.mjs:(\d+)") class LOG_COLORS: @@ -77,6 +79,7 @@ def create_log_terminal_message(mode: QtMsgType, context: QMessageLogContext, me # Check MJS if line is not None and source_file is not None and source_file.endswith("index.mjs"): source_file, line = map_javascript_source(source_file, line) + # Parse message prefix = f"{LOG_COLORS.INVERT}{mode[1]}[{mode[0].upper()}]{LOG_COLORS.RESET_INVERT}" message = message + LOG_COLORS.RESET context = f"{context.function} at {source_file}:{line}" diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 2db62eb..f36f07f 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -150,11 +150,9 @@ class Latex(QObject): promise = self.render_pipeline_locks[render_hash] elif markup_hash in self.render_pipeline_locks: # A PyPromise with the same markup, but not the same color or font size is already running. - print("Chaining render of", latex_markup) + # print("Chaining render of", latex_markup) existing_promise = self.render_pipeline_locks[markup_hash] promise = self._create_async_promise(latex_markup, font_size, color) - existing_promise.then(lambda x, latex_markup=latex_markup: print("> Starting chained render of", latex_markup)) - promise.then(lambda x, latex_markup=latex_markup: print("> Fulfilled chained render of", latex_markup, "\n with", x.toVariant())) existing_promise.then(promise.start) else: # No such PyPromise is running. From 34caf20593859dcd4d2cd111487d51927d2eda0e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 16 Oct 2024 05:38:49 +0200 Subject: [PATCH 207/249] Fixing LaTeX tests, adding new sexy natural language method spy, started testing Promises. --- common/src/module/canvas.mjs | 4 +- common/test/mock/latex.mjs | 18 +- runtime-pyside6/LogarithmPlotter/util/js.py | 6 +- .../LogarithmPlotter/util/promise.py | 41 ++- runtime-pyside6/tests/spy.py | 254 ++++++++++++++++++ runtime-pyside6/tests/test_config.py | 18 ++ runtime-pyside6/tests/test_helper.py | 16 +- runtime-pyside6/tests/test_latex.py | 57 +++- runtime-pyside6/tests/test_native.py | 1 - runtime-pyside6/tests/test_promise.py | 115 ++++++++ runtime-pyside6/tests/test_update.py | 15 +- scripts/run-tests.sh | 1 + 12 files changed, 511 insertions(+), 35 deletions(-) create mode 100644 runtime-pyside6/tests/spy.py create mode 100644 runtime-pyside6/tests/test_promise.py diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 913442f..ba6d5ca 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -530,14 +530,14 @@ class CanvasAPI extends Module { if(this.#redrawCount === currentRedrawCount) callback(imgData) else - console.log("1Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) + console.log("1. Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) }) } else { // Callback directly if(this.#redrawCount === currentRedrawCount) callback(imgData) else - console.log("2Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) + console.log("2. Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) } } const prerendered = Latex.findPrerendered(ltxText, this.textsize, color) diff --git a/common/test/mock/latex.mjs b/common/test/mock/latex.mjs index ab56999..c0a029c 100644 --- a/common/test/mock/latex.mjs +++ b/common/test/mock/latex.mjs @@ -23,6 +23,10 @@ const PIXEL = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAA export class MockLatex { constructor() { } + + get supportsAsyncRender() { + return true + } /** * Creates a simple string hash. @@ -55,13 +59,23 @@ export class MockLatex { return `${TMP}/${name}.png` } + /** + * @param {string} markup - LaTeX markup to render + * @param {number} fontSize - Font size (in pt) to render + * @param {string} color - Color of the text to render + * @returns {Promise} - Comma separated data of the image (source, width, height) + */ + async renderAsync(markup, fontSize, color) { + return this.renderSync(markup, fontSize, color) + } + /** * @param {string} markup - LaTeX markup to render * @param {number} fontSize - Font size (in pt) to render * @param {string} color - Color of the text to render * @returns {string} - Comma separated data of the image (source, width, height) */ - render(markup, fontSize, color) { + renderSync(markup, fontSize, color) { const file = this.__getFileName(markup, fontSize, color) writeFileSync(file, PIXEL, "base64") return `${file},1,1` @@ -87,4 +101,4 @@ export class MockLatex { checkLatexInstallation() { return true // We're not *actually* doing any latex. } -} \ No newline at end of file +} diff --git a/runtime-pyside6/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py index 05f30d5..944c2b0 100644 --- a/runtime-pyside6/LogarithmPlotter/util/js.py +++ b/runtime-pyside6/LogarithmPlotter/util/js.py @@ -75,6 +75,7 @@ class PyJSValue: return value def type(self) -> any: + ret = None matcher = [ (lambda: self.qjs_value.isArray(), list), (lambda: self.qjs_value.isBool(), bool), @@ -93,8 +94,9 @@ class PyJSValue: ] for (test, value) in matcher: if test(): - return value - return None + ret = value + break + return ret def primitive(self): """ diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index e475b36..3c2d223 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -31,7 +31,7 @@ def check_callable(function: Callable|QJSValue) -> Callable|None: """ if isinstance(function, QJSValue) and function.isCallable(): return PyJSValue(function) - elif isinstance(function, Callable): + elif callable(function): return function return None @@ -51,9 +51,7 @@ class PyPromiseRunner(QRunnable): def run(self): try: data = self.runner(*self.args) - if isinstance(data, QObject): - data = data - elif type(data) in [int, str, float, bool, bytes]: + if type(data) in [int, str, float, bool]: data = QJSValue(data) elif data is None: data = QJSValue.SpecialValue.UndefinedValue @@ -62,7 +60,7 @@ class PyPromiseRunner(QRunnable): elif isinstance(data, PyJSValue): data = data.qjs_value else: - raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.") + raise InvalidReturnValue("Must return either a primitive, a JS Value, or None.") self.promise.fulfilled.emit(data) except Exception as e: try: @@ -79,7 +77,7 @@ class PyPromise(QObject): Runs to_run in another thread, and calls fulfilled (populated by then) with its return value. """ fulfilled = Signal((QJSValue,), (QObject,)) - rejected = Signal(Exception) + rejected = Signal(str) def __init__(self, to_run: Callable|QJSValue, args=[], start_automatically=True): QObject.__init__(self) @@ -94,7 +92,7 @@ class PyPromise(QObject): raise ValueError("New PyPromise created with invalid function") self._runner = PyPromiseRunner(to_run, self, args) if start_automatically: - self._start() + self.start() @Slot() def start(self, *args, **kwargs): @@ -122,6 +120,35 @@ class PyPromise(QObject): if on_reject is not None: self._rejects.append(on_reject) return self + + def calls_upon_fulfillment(self, function: Callable | QJSValue) -> bool: + """ + Returns True if the given function will be callback upon the promise fulfillment. + False otherwise. + """ + return self._calls_in(function, self._fulfills) + + def calls_upon_rejection(self, function: Callable | QJSValue) -> bool: + """ + Returns True if the given function will be callback upon the promise rejection. + False otherwise. + """ + return self._calls_in(function, self._rejects) + + def _calls_in(self, function: Callable | QJSValue, within: list) -> bool: + """ + Returns True if the given function resides in the given within list, False otherwise. + Internal method of calls_upon_fulfill + """ + function = check_callable(function) + ret = False + if isinstance(function, PyJSValue): + found = next((f for f in within if f.qjs_value == function.qjs_value), None) + ret = found is not None + elif callable(function): + found = next((f for f in within if f == function), None) + ret = found is not None + return ret @Slot(QJSValue) @Slot(QObject) diff --git a/runtime-pyside6/tests/spy.py b/runtime-pyside6/tests/spy.py new file mode 100644 index 0000000..01f9aa0 --- /dev/null +++ b/runtime-pyside6/tests/spy.py @@ -0,0 +1,254 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from typing import Callable, Self + +from PySide6.QtQml import QJSValue + +PRINT_PREFIX = (" " * 24) + +class SpyAssertionFailed(Exception): + def __init__(self, message, calls): + self.message = message + "\n" + if len(calls) > 0: + self.message += self.render_calls(calls) + else: + self.message += f"{PRINT_PREFIX}0 registered calls." + + def repr(self, data): + if isinstance(data, QJSValue): + variant = data.toVariant() + return f"QJSValue<{type(variant).__name__}>({repr(variant)})" + else: + return repr(data) + + def render_calls(self, calls): + lines = [f"{PRINT_PREFIX}{len(calls)} registered call(s):"] + for call in calls: + repr_args = [self.repr(arg) for arg in call[0]] + repr_kwargs =[f"{key}={self.repr(arg)}" for key, arg in call[1].items()] + lines.append(f" - {', '.join([*repr_args, *repr_kwargs])}") + return ("\n" + PRINT_PREFIX).join(lines) + + def __str__(self): + return self.message + +class Methods: + AT_LEAST_ONCE = "AT_LEAST_ONCE" + EXACTLY = "EXACTLY" + AT_LEAST = "AT_LEAST" + AT_MOST = "AT_MOST" + MORE_THAN = "AT_LEAST" + LESS_THAN = "AT_MOST" + +class CalledInterface: + """ + Internal class generated by Spy.was_called. + """ + + def __init__(self, calls: list[tuple[list, dict]]): + self.__calls = calls + self.__method = Methods.AT_LEAST_ONCE + self.__times = None + + def __apply_method(self, calls): + required = self.__times + calls_count = len(calls) + match self.__method: + case Methods.AT_LEAST_ONCE: + compare = len(calls) >= 1 + error = "Method was not called" + case Methods.EXACTLY: + compare = len(calls) == required + error = f"Method was not called {required} times ({required} != {calls_count})" + case Methods.AT_LEAST: + compare = len(calls) >= required + error = f"Method was not called at least {required} times ({required} > {calls_count})" + case Methods.AT_MOST: + compare = len(calls) <= required + error = f"Method was not called at most {required} times ({required} < {calls_count})" + case Methods.MORE_THAN: + compare = len(calls) > required + error = f"Method was not called more than {required} times ({required} >= {calls_count})" + case Methods.LESS_THAN: + compare = len(calls) < required + error = f"Method was not called less than {required} times ({required} <= {calls_count})" + case _: + raise RuntimeError(f"Unknown method {self.__method}.") + return compare, error + + def __bool__(self): + """ + Converts to boolean on assertion. + """ + compare, error = self.__apply_method(self.__calls) + if not compare: + raise SpyAssertionFailed(error+".") + return compare + + + """ + Chaining methods + """ + def __call__(self, *args, **kwargs) -> Self: + if len(args) != 1: + raise RuntimeError("Cannot call called interface with more than one argument.") + self.__times = int(args[0]) + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.EXACTLY + return self + + @property + def never(self) -> Self: + return self(0) + + @property + def once(self) -> Self: + return self(1) + + @property + def twice(self) -> Self: + return self(2) + + @property + def thrice(self) -> Self: + return self(3) + + @property + def at_least(self) -> Self: + self.__method = Methods.AT_LEAST + return self + + @property + def at_most(self) -> Self: + self.__method = Methods.AT_MOST + return self + + @property + def more_than(self) -> Self: + self.__method = Methods.MORE_THAN + return self + + @property + def less_than(self) -> Self: + self.__method = Methods.LESS_THAN + return self + + @property + def times(self) -> Self: + return self + + """ + Class properties. + """ + def __match_calls_for_condition(self, condition: Callable[[list, dict], bool]) -> tuple[bool, str]: + calls = [] + for call in self.__calls: + if condition(call[0], call[1]): + calls.append(call) + compare, error = self.__apply_method(calls) + return compare, error + + + def with_arguments(self, *args, **kwargs): + """ + Checks if the Spy has been called the given number of times + with at least the given arguments. + """ + def some_args_matched(a, kw): + args_matched = all(( + arg in a + for arg in args + )) + kwargs_matched = all(( + key in kw and kw[key] == arg + for key, arg in kwargs.items() + )) + return args_matched and kwargs_matched + compare, error = self.__match_calls_for_condition(some_args_matched) + if not compare: + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + raise SpyAssertionFailed(f"{error} with arguments ({repr_args}) and keyword arguments ({repr_kwargs}).", self.__calls) + return compare + + + def with_arguments_matching(self, test_condition: Callable[[list, dict], bool]): + """ + Checks if the Spy has been called the given number of times + with arguments matching the given conditions. + """ + compare, error = self.__match_calls_for_condition(test_condition) + if not compare: + raise SpyAssertionFailed(f"{error} with arguments matching given conditions.", self.__calls) + return compare + + + def with_exact_arguments(self, *args, **kwargs): + """ + Checks if the Spy has been called the given number of times + with all the given arguments. + """ + compare, error = self.__match_calls_for_condition(lambda a, kw: a == args and kw == kwargs) + if not compare: + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + raise SpyAssertionFailed(f"{error} with exact arguments ({repr_args}) and keyword arguments ({repr_kwargs}).", self.__calls) + return compare + + def with_no_argument(self): + """ + Checks if the Spy has been called the given number of times + with all the given arguments. + """ + compare, error = self.__match_calls_for_condition(lambda a, kw: len(a) == 0 and len(kw) == 0) + if not compare: + raise SpyAssertionFailed(f"{error} with no arguments.", self.__calls) + return compare + + + +class Spy: + """ + Class to spy into method calls with natural language expressions. + """ + + def __init__(self, function: Callable = None): + self.function = function + self.calls = [] + + def __call__(self, *args, **kwargs): + self.calls.append((args, kwargs)) + if self.function is not None: + self.function(*args, **kwargs) + + @property + def was_called(self) -> CalledInterface: + """ + Returns a boolean-able interface to check conditions for a given number of + time the spy was called. + """ + return CalledInterface(self.calls) + + @property + def was_not_called(self) -> CalledInterface: + """ + Returns a boolean-able interface to check that conditions were never fulfilled + in the times the spy was called. + """ + ret = CalledInterface(self.calls) + return ret(0) diff --git a/runtime-pyside6/tests/test_config.py b/runtime-pyside6/tests/test_config.py index c919c6f..cef3673 100644 --- a/runtime-pyside6/tests/test_config.py +++ b/runtime-pyside6/tests/test_config.py @@ -1,3 +1,21 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + import pytest from LogarithmPlotter.util import config from tempfile import TemporaryDirectory diff --git a/runtime-pyside6/tests/test_helper.py b/runtime-pyside6/tests/test_helper.py index 5cfb239..6bc1f0d 100644 --- a/runtime-pyside6/tests/test_helper.py +++ b/runtime-pyside6/tests/test_helper.py @@ -30,7 +30,7 @@ from PySide6.QtWidgets import QApplication from LogarithmPlotter import __VERSION__ as version from LogarithmPlotter.util import config, helper -from LogarithmPlotter.util.helper import Helper, InvalidFileException +from LogarithmPlotter.util.helper import Helper, fetch_changelog, read_changelog, InvalidFileException pwd = getcwd() helper.SHOW_GUI_MESSAGES = False @@ -60,19 +60,23 @@ CHANGELOG_BASE_PATH = path.realpath(path.join(path.dirname(path.realpath(__file_ class TestHelper: def test_changelog(self, temporary, qtbot): + # Exists helper.CHANGELOG_VERSION = '0.5.0' tmpfile, directory = temporary obj = Helper(pwd, tmpfile) promise = obj.fetchChangelog() create_changelog_callback_asserter(promise, expect_404=False) - qtbot.waitSignal(promise.fulfilled, timeout=10000) - # No exist + with qtbot.waitSignal(promise.fulfilled, timeout=10000): + pass + assert type(fetch_changelog()) == str + # Does not exist helper.CHANGELOG_VERSION = '2.0.0' tmpfile, directory = temporary obj = Helper(pwd, tmpfile) promise = obj.fetchChangelog() create_changelog_callback_asserter(promise, expect_404=True) - qtbot.waitSignal(promise.fulfilled, timeout=10000) + with qtbot.waitSignal(promise.fulfilled, timeout=10000): + pass # Local tmpfile, directory = temporary obj = Helper(pwd, tmpfile) @@ -81,7 +85,9 @@ class TestHelper: assert path.exists(helper.CHANGELOG_CACHE_PATH) promise = obj.fetchChangelog() create_changelog_callback_asserter(promise, expect_404=False) - qtbot.waitSignal(promise.fulfilled, timeout=10000) # Local + with qtbot.waitSignal(promise.fulfilled, timeout=100): # Local + pass + assert type(read_changelog()) == str def test_read(self, temporary): # Test file reading and information loading. diff --git a/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index 6fd5c97..124186b 100644 --- a/runtime-pyside6/tests/test_latex.py +++ b/runtime-pyside6/tests/test_latex.py @@ -22,6 +22,7 @@ from shutil import which from os.path import exists from re import match from PySide6.QtGui import QColor +from PySide6.QtQml import QJSValue from LogarithmPlotter.util import latex @@ -38,10 +39,24 @@ def latex_obj(): directory.cleanup() +BLACK = QColor(0, 0, 0, 255) +BLUE = QColor(128, 128, 255, 255) + +def check_render_results(result): + if isinstance(result, QJSValue): + result = result.toVariant() + assert type(result) == str + [path, width, height] = result.split(",") + assert exists(path) + assert match(r"\d+", width) + assert match(r"\d+", height) + return True + class TestLatex: def test_check_install(self, latex_obj: latex.Latex) -> None: assert latex_obj.latexSupported == True assert latex_obj.checkLatexInstallation() == True + assert type(latex_obj.supportsAsyncRender) is bool bkp = [latex.DVIPNG_PATH, latex.LATEX_PATH] # Check what happens when one is missing. latex.DVIPNG_PATH = None @@ -55,25 +70,25 @@ class TestLatex: [latex.DVIPNG_PATH, latex.LATEX_PATH] = bkp def test_render_sync(self, latex_obj: latex.Latex) -> None: - result = latex_obj.renderSync(r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)) + result = latex_obj.renderSync("\\frac{d \\sqrt{\\mathrm{f}(x \\times 2.3)}}{dx}", 14, BLACK) # Ensure result format - assert type(result) == str - [path, width, height] = result.split(",") - assert exists(path) - assert match(r"\d+", width) - assert match(r"\d+", height) + check_render_results(result) # Ensure it returns errors on invalid latex. with pytest.raises(latex.RenderError): - latex_obj.renderSync(r"\nonexistant", 14, QColor(0, 0, 0, 255)) + latex_obj.renderSync("\\nonexistant", 14, BLACK) # Replace latex bin with one that returns errors bkp = latex.LATEX_PATH latex.LATEX_PATH = which("false") with pytest.raises(latex.RenderError): - latex_obj.renderSync(r"\mathrm{f}(x)", 14, QColor(0, 0, 0, 255)) + latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) + # Replace latex bin with one goes indefinitely + latex.LATEX_PATH = which("import") + with pytest.raises(latex.RenderError): + latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) latex.LATEX_PATH = bkp def test_prerendered(self, latex_obj: latex.Latex) -> None: - args = [r"\frac{d\sqrt{\mathrm{f}(x \times 2.3)}}{dx}", 14, QColor(0, 0, 0, 255)] + args = ["\\frac{d \\sqrt{\\mathrm{f}(x \\times 2.3)}}{dx}", 14, BLACK] latex_obj.renderSync(*args) prerendered = latex_obj.findPrerendered(*args) assert type(prerendered) == str @@ -84,3 +99,27 @@ class TestLatex: prerendered2 = latex_obj.findPrerendered(args[0], args[1]+2, args[2]) assert prerendered2 == "" + def test_render_async(self, latex_obj: latex.Latex, qtbot) -> None: + formula = "\\int\\limits^{3x}_{-\\infty}9\\mathrm{f}(x)^3+t dx" + og_promise = latex_obj.renderAsync(formula, 14, BLACK) + # Ensure we get the same locked one if we try to render it again. + assert og_promise == latex_obj.renderAsync(formula, 14, BLACK) + # Ensure queued renders. + promises = [ + latex_obj.renderAsync(formula, 14, BLUE), + latex_obj.renderAsync(formula, 10, BLACK), + latex_obj.renderAsync(formula, 10, BLUE), + ] + for prom in promises: + assert og_promise.calls_upon_fulfillment(prom.start) + # Ensure other renders get done in parallel. + other_promise = latex_obj.renderAsync(formula+" dt", 10, BLACK) + assert not og_promise.calls_upon_fulfillment(other_promise.start) + # Ensure all of them render. + proms = [og_promise, *promises, other_promise] + with qtbot.waitSignals( + [p.fulfilled for p in proms], + raising=True, timeout=10000, + check_params_cbs=[check_render_results]*len(proms) + ): + pass diff --git a/runtime-pyside6/tests/test_native.py b/runtime-pyside6/tests/test_native.py index 6fc2d65..3ca4834 100644 --- a/runtime-pyside6/tests/test_native.py +++ b/runtime-pyside6/tests/test_native.py @@ -17,7 +17,6 @@ """ import pytest -from os.path import exists from PySide6.QtCore import QEvent, QObject, QUrl from PySide6.QtGui import QActionEvent, QFileOpenEvent diff --git a/runtime-pyside6/tests/test_promise.py b/runtime-pyside6/tests/test_promise.py new file mode 100644 index 0000000..06c0b8a --- /dev/null +++ b/runtime-pyside6/tests/test_promise.py @@ -0,0 +1,115 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from time import sleep + +import pytest +from PySide6.QtCore import QObject +from PySide6.QtQml import QJSValue + +from spy import Spy +from LogarithmPlotter.util.js import PyJSValue +from LogarithmPlotter.util.promise import PyPromise + + +def check_promise_result(value): + def got_result(args, kwargs, val=value): + valid = len(args) == 1 and len(kwargs) == 0 + if valid: + got_value = args[0].toVariant() if isinstance(args[0], QJSValue) else args[0] + valid = got_value == val + return valid + return got_result + +def create_async_func(value): + def async_function(val=value): + sleep(1) + return val + + return async_function + + +def qjs_eq(origin): + def compare(result): + res = result.toVariant() == origin + print("Unknown res!", res, repr(result.toVariant()), repr(origin)) + return res + return compare + + +def async_throw(): + sleep(1) + raise Exception("aaaa") + + +class TestPyPromise: + + def test_fulfill_values(self, qtbot): + qjsv = QJSValue(3) + values = [ + [True, qjs_eq(True)], + [3, qjs_eq(3)], + [2.2, qjs_eq(2.2)], + ["String", qjs_eq("String")], + [qjsv, qjs_eq(3)], + [None, qjs_eq(None)], + [PyJSValue(QJSValue("aaa")), qjs_eq("aaa")] + ] + for [value, test] in values: + promise = PyPromise(create_async_func(value)) + with qtbot.assertNotEmitted(promise.rejected, wait=1000): + print("Testing", value) + with qtbot.waitSignal(promise.fulfilled, check_params_cb=test, timeout=2000): + assert promise.state == "pending" + assert promise.state == "fulfilled" + + def test_reject(self, qtbot): + promise = PyPromise(async_throw) + with qtbot.assertNotEmitted(promise.fulfilled, wait=1000): + with qtbot.waitSignal(promise.rejected, timeout=10000, + check_params_cb=lambda t: t == "Exception('aaaa')"): + assert promise.state == "pending" + assert promise.state == "rejected" + + def test_fulfill(self, qtbot): + spy_fulfilled = Spy() + spy_rejected = Spy() + promise = PyPromise(create_async_func(3)) + then_res = promise.then(spy_fulfilled, spy_rejected) + # Check if the return value is the same promise (so we can chain then) + assert then_res == promise + # Check on our spy. + with qtbot.waitSignal(promise.fulfilled, timeout=10000): + pass + assert spy_fulfilled.was_called.once + assert spy_fulfilled.was_not_called.with_arguments(3) + assert spy_fulfilled.was_called.with_arguments_matching(check_promise_result(3)) + assert spy_rejected.was_not_called + + def test_rejected(self, qtbot): + spy_fulfilled = Spy() + spy_rejected = Spy() + promise = PyPromise(async_throw) + then_res = promise.then(spy_fulfilled, spy_rejected) + # Check if the return value is the same promise (so we can chain then) + assert then_res == promise + # Check on our spies. + with qtbot.waitSignal(promise.rejected, timeout=10000): + pass + assert spy_rejected.was_called.once + assert spy_rejected.was_called.with_arguments("Exception('aaaa')") + assert spy_fulfilled.was_not_called diff --git a/runtime-pyside6/tests/test_update.py b/runtime-pyside6/tests/test_update.py index 5e1a705..ff71e61 100644 --- a/runtime-pyside6/tests/test_update.py +++ b/runtime-pyside6/tests/test_update.py @@ -49,19 +49,20 @@ def test_update(qtbot): update_info_newer = UpdateInformation() update_info_newer.got_update_info.connect(check_newer) runnable = UpdateCheckerRunnable('1.0.0', update_info_newer) - runnable.run() - qtbot.waitSignal(update_info_newer.got_update_info, timeout=10000) + with qtbot.waitSignal(update_info_newer.got_update_info, timeout=10000): + runnable.run() runnable = UpdateCheckerRunnable('0.1.0', update_info_older) - runnable.run() - qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) + with qtbot.waitSignal(update_info_older.got_update_info, timeout=10000): + runnable.run() runnable = UpdateCheckerRunnable('0.5.0+dev0+git20240101', update_info_older) - runnable.run() - qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) + with qtbot.waitSignal(update_info_older.got_update_info, timeout=10000): + runnable.run() def test_update_checker(qtbot): update_info = check_for_updates('0.6.0', MockWindow()) assert QThreadPool.globalInstance().activeThreadCount() >= 1 - qtbot.waitSignal(update_info.got_update_info, timeout=10000) + with qtbot.waitSignal(update_info.got_update_info, timeout=10000): + pass argv.append("--no-check-for-updates") update_info = check_for_updates('0.6.0', MockWindow()) assert QThreadPool.globalInstance().activeThreadCount() < 2 # No new update checks where added diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 1410244..ac1fdc5 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -23,6 +23,7 @@ fi # Run python tests +rm -rf build/runtime-pyside6/tests cp -r runtime-pyside6/tests build/runtime-pyside6 cp -r ci CHANGELOG.md build/runtime-pyside6 cd build/runtime-pyside6 || exit 1 From 8fab9d8e529772a1dfcde801996d03002d3e829f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 16 Oct 2024 22:18:53 +0200 Subject: [PATCH 208/249] Starting natural language plugin. --- runtime-pyside6/tests/__init__.py | 0 runtime-pyside6/tests/plugins/__init__.py | 0 .../tests/plugins/natural/__init__.py | 21 ++ .../plugins/natural/interfaces/__init__.py | 0 .../plugins/natural/interfaces/assertion.py | 30 +++ .../tests/plugins/natural/interfaces/base.py | 101 ++++++++ .../tests/plugins/natural/interfaces/basic.py | 61 +++++ .../tests/plugins/natural/interfaces/int.py | 229 ++++++++++++++++++ .../tests/plugins/natural/interfaces/utils.py | 27 +++ .../tests/{ => plugins/natural}/spy.py | 128 +++++----- runtime-pyside6/tests/plugins/natural/that.py | 57 +++++ runtime-pyside6/tests/test_promise.py | 20 +- 12 files changed, 593 insertions(+), 81 deletions(-) create mode 100644 runtime-pyside6/tests/__init__.py create mode 100644 runtime-pyside6/tests/plugins/__init__.py create mode 100644 runtime-pyside6/tests/plugins/natural/__init__.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/__init__.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/assertion.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/base.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/basic.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/int.py create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/utils.py rename runtime-pyside6/tests/{ => plugins/natural}/spy.py (69%) create mode 100644 runtime-pyside6/tests/plugins/natural/that.py diff --git a/runtime-pyside6/tests/__init__.py b/runtime-pyside6/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/runtime-pyside6/tests/plugins/__init__.py b/runtime-pyside6/tests/plugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/runtime-pyside6/tests/plugins/natural/__init__.py b/runtime-pyside6/tests/plugins/natural/__init__.py new file mode 100644 index 0000000..7a67869 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/__init__.py @@ -0,0 +1,21 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from .spy import Spy +from .that import that + diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/__init__.py b/runtime-pyside6/tests/plugins/natural/interfaces/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py new file mode 100644 index 0000000..f2504a2 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py @@ -0,0 +1,30 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +class Assertion(Exception): + def __init__(self, assertion: bool, message: str): + self.assertion = assertion + self.message = message + + def __str__(self): + return self.message + + def __bool__(self): + if not self.assertion: + raise self + return self.assertion \ No newline at end of file diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/base.py b/runtime-pyside6/tests/plugins/natural/interfaces/base.py new file mode 100644 index 0000000..88b9e06 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/base.py @@ -0,0 +1,101 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from typing import Self + +from tests.plugins.natural.interfaces.assertion import Assertion +from tests.plugins.natural.interfaces.utils import repr_ + + +class AssertionInterface: + """ + Most basic assertion interface. + You probably want to use BaseAssertionInterface + """ + def __init__(self, value): + self._value = value + + @property + def was(self) -> Self: + return self + + @property + def be(self) -> Self: + return self + + @property + def been(self) -> Self: + return self + + @property + def have(self) -> Self: + return self + + @property + def has(self) -> Self: + return self + + @property + def a(self) -> Self: + return self + + @property + def an(self) -> Self: + return self + + def is_a(self, type_) -> Assertion: + """ + Checks if the current value is equal to the provided value + """ + value_type_name = type(self._value).__name__ + return Assertion(isinstance(type_, type_), f"The value ({value_type_name} {repr_(self._value)}) is not a {type_.__name__}.") + + + +class EqualAssertionInterface(AssertionInterface): + """ + Interface created for when its value should be checked for equality + """ + def __init__(self, value): + super().__init__(value) + + def __call__(self, value) -> Assertion: + return Assertion(value == self._value, f"The value ({repr_(self._value)}) is not equal to {repr(value)}.") + + def to(self, value) -> Self: + return self(value) + + def of(self, value) -> Self: + return self(value) + + + +class BaseAssertionInterface(AssertionInterface): + + @property + def equals(self) -> EqualAssertionInterface: + """ + Checks if the current value is equal to the provided value + """ + return EqualAssertionInterface(self._value) + + @property + def is_equal(self) -> EqualAssertionInterface: + """ + Checks if the current value is equal to the provided value + """ + return self.equals \ No newline at end of file diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py new file mode 100644 index 0000000..1d5a878 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py @@ -0,0 +1,61 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from tests.plugins.natural.interfaces.assertion import Assertion +from tests.plugins.natural.interfaces.base import BaseAssertionInterface +from tests.plugins.natural.interfaces.int import IntInterface +from tests.plugins.natural.interfaces.utils import repr_ + + +class FixedIteratorInterface(BaseAssertionInterface): + @property + def length(self) -> IntInterface: + return IntInterface(len(self._value)) + + def elements(self, *elements) -> Assertion: + tests = [elem for elem in elements if elem in self._value] + return Assertion( + len(tests) == 0, + f"This value ({repr_(self._value)}) does not have elements ({repr_(tests)})" + ) + + def element(self, element) -> Assertion: + return Assertion( + element in self._value, + f"This value ({repr_(self._value)}) does not have element ({repr_(element)})" + ) + + def contains(self, *elements) -> Assertion: + return self.elements(*elements) + +class BoolInterface(BaseAssertionInterface): + @property + def is_true(self): + return Assertion( + self._value == True, + f"The value ({repr_(self._value)}) is not True." + ) + + @property + def is_false(self): + return Assertion( + self._value == False, + f"The value ({repr_(self._value)}) is not False." + ) + +class StringInterface(LengthInterface): + pass \ No newline at end of file diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/int.py b/runtime-pyside6/tests/plugins/natural/interfaces/int.py new file mode 100644 index 0000000..aaf0511 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/int.py @@ -0,0 +1,229 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from typing import Self + +from tests.plugins.natural.interfaces.assertion import Assertion +from tests.plugins.natural.interfaces.base import BaseAssertionInterface, EqualAssertionInterface, AssertionInterface +from tests.plugins.natural.interfaces.utils import repr_ + + +class IntComparisonAssertionInterface(AssertionInterface): + def __init__(self, value): + super().__init__(value) + self._compare_to = None + + def _compare(self) -> Assertion: + raise RuntimeError(f"No comparison method defined in {type(self).__name__}.") + + def __bool__(self) -> bool: + return bool(self._compare()) + + def __call__(self, compare_to: int) -> Self: + if self._compare_to is None: + self._compare_to = int(compare_to) + else: + self._compare_to *= int(compare_to) + return self + + @property + def time(self) -> Self: + return self + + @property + def times(self) -> Self: + return self + + @property + def never(self) -> Self: + return self(0) + + @property + def once(self) -> Self: + return self(1) + + @property + def twice(self) -> Self: + return self(2) + + @property + def thrice(self) -> Self: + return self(3) + + @property + def zero(self) -> Self: + return self(0) + + @property + def one(self) -> Self: + return self(1) + + @property + def two(self) -> Self: + return self(2) + + @property + def three(self) -> Self: + return self(3) + + @property + def four(self) -> Self: + return self(4) + + @property + def five(self) -> Self: + return self(5) + + @property + def six(self) -> Self: + return self(6) + + @property + def seven(self) -> Self: + return self(7) + + @property + def eight(self) -> Self: + return self(8) + + @property + def nine(self) -> Self: + return self(9) + + @property + def ten(self) -> Self: + return self(10) + + @property + def twenty(self) -> Self: + return self(20) + + @property + def thirty(self) -> Self: + return self(30) + + @property + def forty(self) -> Self: + return self(40) + + @property + def fifty(self) -> Self: + return self(50) + + @property + def sixty(self) -> Self: + return self(60) + + @property + def seventy(self) -> Self: + return self(70) + + @property + def eighty(self) -> Self: + return self(70) + + @property + def ninety(self) -> Self: + return self(70) + + @property + def hundred(self) -> Self: + return self(100) + + @property + def thousand(self) -> Self: + return self(1_000) + + @property + def million(self) -> Self: + return self(1_000_000) + + @property + def billion(self) -> Self: + return self(1_000_000_000) + + +class LessThanComparisonInterface(IntComparisonAssertionInterface): + def _compare(self) -> Assertion: + return Assertion( + self._value < self._compare_to, + f"The value ({repr_(self._value)}) is not less than to {repr_(self._compare_to)}." + ) + +class MoreThanComparisonInterface(IntComparisonAssertionInterface): + def _compare(self) -> Assertion: + return Assertion( + self._value > self._compare_to, + f"The value ({repr_(self._value)}) is not more than to {repr_(self._compare_to)}." + ) + +class AtLeastComparisonInterface(IntComparisonAssertionInterface): + def _compare(self) -> Assertion: + return Assertion( + self._value >= self._compare_to, + f"The value ({repr_(self._value)}) is not at least to {repr_(self._compare_to)}." + ) + +class AtMostComparisonInterface(IntComparisonAssertionInterface): + def _compare(self) -> Assertion: + return Assertion( + self._value <= self._compare_to, + f"The value ({repr_(self._value)}) is not at least to {repr_(self._compare_to)}." + ) + +class EqualComparisonInterface(IntComparisonAssertionInterface): + def _compare(self) -> Assertion: + return Assertion( + self._value == self._compare_to, + f"The value ({repr_(self._value)}) is not equal to {repr_(self._compare_to)}." + ) + + def to(self) -> Self: + return self + + def of(self) -> Self: + return self + + +class IntInterface(AssertionInterface): + def less_than(self) -> LessThanComparisonInterface: + return LessThanComparisonInterface(self._value) + + @property + def more_than(self) -> MoreThanComparisonInterface: + return MoreThanComparisonInterface(self._value) + + @property + def at_least(self) -> AtLeastComparisonInterface: + return AtLeastComparisonInterface(self._value) + + @property + def at_most(self) -> AtMostComparisonInterface: + return AtMostComparisonInterface(self._value) + + @property + def equals(self) -> EqualComparisonInterface: + return EqualComparisonInterface(self._value) + + @property + def is_equal(self) -> EqualComparisonInterface: + return EqualComparisonInterface(self._value) + + @property + def exactly(self) -> EqualComparisonInterface: + return EqualComparisonInterface(self._value) + diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/utils.py b/runtime-pyside6/tests/plugins/natural/interfaces/utils.py new file mode 100644 index 0000000..50e3777 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/utils.py @@ -0,0 +1,27 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from PySide6.QtQml import QJSValue + + +def repr_(data): + if isinstance(data, QJSValue): + variant = data.toVariant() + return f"QJSValue<{type(variant).__name__}>({repr(variant)})" + else: + return repr(data) \ No newline at end of file diff --git a/runtime-pyside6/tests/spy.py b/runtime-pyside6/tests/plugins/natural/spy.py similarity index 69% rename from runtime-pyside6/tests/spy.py rename to runtime-pyside6/tests/plugins/natural/spy.py index 01f9aa0..1d77629 100644 --- a/runtime-pyside6/tests/spy.py +++ b/runtime-pyside6/tests/plugins/natural/spy.py @@ -17,35 +17,29 @@ """ from typing import Callable, Self -from PySide6.QtQml import QJSValue +from tests.plugins.natural.interfaces.base import Assertion, repr_, AssertionInterface +from tests.plugins.natural.interfaces.int import IntComparisonAssertionInterface PRINT_PREFIX = (" " * 24) -class SpyAssertionFailed(Exception): - def __init__(self, message, calls): - self.message = message + "\n" + +class SpyAssertion(Assertion): + def __init__(self, assertion: bool, message: str, calls: list): + super().__init__(assertion, message + "\n") if len(calls) > 0: self.message += self.render_calls(calls) else: self.message += f"{PRINT_PREFIX}0 registered calls." - def repr(self, data): - if isinstance(data, QJSValue): - variant = data.toVariant() - return f"QJSValue<{type(variant).__name__}>({repr(variant)})" - else: - return repr(data) def render_calls(self, calls): lines = [f"{PRINT_PREFIX}{len(calls)} registered call(s):"] for call in calls: - repr_args = [self.repr(arg) for arg in call[0]] - repr_kwargs =[f"{key}={self.repr(arg)}" for key, arg in call[1].items()] + repr_args = [repr_(arg) for arg in call[0]] + repr_kwargs = [f"{key}={repr_(arg)}" for key, arg in call[1].items()] lines.append(f" - {', '.join([*repr_args, *repr_kwargs])}") return ("\n" + PRINT_PREFIX).join(lines) - def __str__(self): - return self.message class Methods: AT_LEAST_ONCE = "AT_LEAST_ONCE" @@ -55,18 +49,19 @@ class Methods: MORE_THAN = "AT_LEAST" LESS_THAN = "AT_MOST" -class CalledInterface: + +class CalledInterface(IntComparisonAssertionInterface): """ Internal class generated by Spy.was_called. """ def __init__(self, calls: list[tuple[list, dict]]): + super().__init__(len(calls)) self.__calls = calls self.__method = Methods.AT_LEAST_ONCE - self.__times = None def __apply_method(self, calls): - required = self.__times + required = self._compare_to calls_count = len(calls) match self.__method: case Methods.AT_LEAST_ONCE: @@ -91,61 +86,59 @@ class CalledInterface: raise RuntimeError(f"Unknown method {self.__method}.") return compare, error - def __bool__(self): + def __bool__(self) -> bool: """ Converts to boolean on assertion. """ compare, error = self.__apply_method(self.__calls) - if not compare: - raise SpyAssertionFailed(error+".") - return compare - + return bool(SpyAssertion(compare, error + ".", self.__calls)) """ Chaining methods """ + def __call__(self, *args, **kwargs) -> Self: if len(args) != 1: raise RuntimeError("Cannot call called interface with more than one argument.") - self.__times = int(args[0]) + self._compare_to = int(args[0]) if self.__method == Methods.AT_LEAST_ONCE: self.__method = Methods.EXACTLY return self - @property - def never(self) -> Self: - return self(0) - - @property - def once(self) -> Self: - return self(1) - - @property - def twice(self) -> Self: - return self(2) - - @property - def thrice(self) -> Self: - return self(3) - @property def at_least(self) -> Self: - self.__method = Methods.AT_LEAST + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.AT_LEAST + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") return self @property def at_most(self) -> Self: - self.__method = Methods.AT_MOST + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.AT_MOST + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") return self @property def more_than(self) -> Self: - self.__method = Methods.MORE_THAN + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.MORE_THAN + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.MORE_THAN}") return self @property def less_than(self) -> Self: - self.__method = Methods.LESS_THAN + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.LESS_THAN + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.LESS_THAN}") + return self + + @property + def time(self) -> Self: return self @property @@ -155,6 +148,7 @@ class CalledInterface: """ Class properties. """ + def __match_calls_for_condition(self, condition: Callable[[list, dict], bool]) -> tuple[bool, str]: calls = [] for call in self.__calls: @@ -163,12 +157,12 @@ class CalledInterface: compare, error = self.__apply_method(calls) return compare, error - - def with_arguments(self, *args, **kwargs): + def with_arguments(self, *args, **kwargs) -> SpyAssertion: """ Checks if the Spy has been called the given number of times with at least the given arguments. """ + def some_args_matched(a, kw): args_matched = all(( arg in a @@ -179,55 +173,49 @@ class CalledInterface: for key, arg in kwargs.items() )) return args_matched and kwargs_matched + compare, error = self.__match_calls_for_condition(some_args_matched) - if not compare: - repr_args = ', '.join([repr(arg) for arg in args]) - repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) - raise SpyAssertionFailed(f"{error} with arguments ({repr_args}) and keyword arguments ({repr_kwargs}).", self.__calls) - return compare + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + msg = f"{error} with arguments ({repr_args}) and keyword arguments ({repr_kwargs})." + return SpyAssertion(compare, msg, self.__calls) - - def with_arguments_matching(self, test_condition: Callable[[list, dict], bool]): + def with_arguments_matching(self, test_condition: Callable[[list, dict], bool]) -> SpyAssertion: """ Checks if the Spy has been called the given number of times with arguments matching the given conditions. """ compare, error = self.__match_calls_for_condition(test_condition) - if not compare: - raise SpyAssertionFailed(f"{error} with arguments matching given conditions.", self.__calls) - return compare + msg = f"{error} with arguments matching given conditions." + return SpyAssertion(compare, msg, self.__calls) - - def with_exact_arguments(self, *args, **kwargs): + def with_exact_arguments(self, *args, **kwargs) -> SpyAssertion: """ Checks if the Spy has been called the given number of times with all the given arguments. """ compare, error = self.__match_calls_for_condition(lambda a, kw: a == args and kw == kwargs) - if not compare: - repr_args = ', '.join([repr(arg) for arg in args]) - repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) - raise SpyAssertionFailed(f"{error} with exact arguments ({repr_args}) and keyword arguments ({repr_kwargs}).", self.__calls) - return compare + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + msg = f"{error} with exact arguments ({repr_args}) and keyword arguments ({repr_kwargs})." + return SpyAssertion(compare, msg, self.__calls) - def with_no_argument(self): + def with_no_argument(self) -> SpyAssertion: """ Checks if the Spy has been called the given number of times with all the given arguments. """ compare, error = self.__match_calls_for_condition(lambda a, kw: len(a) == 0 and len(kw) == 0) - if not compare: - raise SpyAssertionFailed(f"{error} with no arguments.", self.__calls) - return compare + return SpyAssertion(compare, f"{error} with no arguments.", self.__calls) - -class Spy: +class Spy(AssertionInterface): """ Class to spy into method calls with natural language expressions. """ def __init__(self, function: Callable = None): + super().__init__(function) self.function = function self.calls = [] @@ -237,7 +225,7 @@ class Spy: self.function(*args, **kwargs) @property - def was_called(self) -> CalledInterface: + def called(self) -> CalledInterface: """ Returns a boolean-able interface to check conditions for a given number of time the spy was called. @@ -245,7 +233,7 @@ class Spy: return CalledInterface(self.calls) @property - def was_not_called(self) -> CalledInterface: + def not_called(self) -> CalledInterface: """ Returns a boolean-able interface to check that conditions were never fulfilled in the times the spy was called. diff --git a/runtime-pyside6/tests/plugins/natural/that.py b/runtime-pyside6/tests/plugins/natural/that.py new file mode 100644 index 0000000..38ee54e --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/that.py @@ -0,0 +1,57 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +from typing import overload, Generic, TypeVar + +from .spy import Spy +from .interfaces.base import AssertionInterface, BaseAssertionInterface +from .interfaces.basic import StringInterface, BoolInterface +from .interfaces.int import IntInterface + +Interface = TypeVar("Interface", bound=AssertionInterface) + +MATCHES = [ + (str, StringInterface), + (int, IntInterface), + (bool, BoolInterface), +] + + +@overload +def that(value: str) -> StringInterface: ... + + +@overload +def that(value: int) -> IntInterface: ... + + +@overload +def that(value: bool) -> BoolInterface: ... + + +@overload +def that[Interface](value: Interface) -> Interface: ... + + +def that(value: any) -> AssertionInterface: + if not isinstance(value, AssertionInterface): + interface = next((i for t, i in MATCHES if isinstance(value, t)), None) + if interface is not None: + value = interface(value) + else: + value = BaseAssertionInterface(value) + return value diff --git a/runtime-pyside6/tests/test_promise.py b/runtime-pyside6/tests/test_promise.py index 06c0b8a..a97f864 100644 --- a/runtime-pyside6/tests/test_promise.py +++ b/runtime-pyside6/tests/test_promise.py @@ -17,11 +17,9 @@ """ from time import sleep -import pytest -from PySide6.QtCore import QObject from PySide6.QtQml import QJSValue -from spy import Spy +from tests.plugins.natural import that, Spy from LogarithmPlotter.util.js import PyJSValue from LogarithmPlotter.util.promise import PyPromise @@ -95,10 +93,10 @@ class TestPyPromise: # Check on our spy. with qtbot.waitSignal(promise.fulfilled, timeout=10000): pass - assert spy_fulfilled.was_called.once - assert spy_fulfilled.was_not_called.with_arguments(3) - assert spy_fulfilled.was_called.with_arguments_matching(check_promise_result(3)) - assert spy_rejected.was_not_called + assert that(spy_fulfilled).was.called.once + assert that(spy_fulfilled).was.not_called.with_arguments(3) + assert that(spy_fulfilled).was.called.with_arguments_matching(check_promise_result(3)) + assert spy_rejected.was.not_called def test_rejected(self, qtbot): spy_fulfilled = Spy() @@ -106,10 +104,10 @@ class TestPyPromise: promise = PyPromise(async_throw) then_res = promise.then(spy_fulfilled, spy_rejected) # Check if the return value is the same promise (so we can chain then) - assert then_res == promise + assert that(then_res).is_equal.to(promise) # Check on our spies. with qtbot.waitSignal(promise.rejected, timeout=10000): pass - assert spy_rejected.was_called.once - assert spy_rejected.was_called.with_arguments("Exception('aaaa')") - assert spy_fulfilled.was_not_called + assert that(spy_rejected).was.called.once + assert that(spy_rejected).was.called.with_arguments("Exception('aaaa')") + assert that(spy_fulfilled).was.not_called From ef465b34e7f9cf9d78d4dd9aa25a14af5b7050a5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 02:08:24 +0200 Subject: [PATCH 209/249] Finishing natural language plugin. --- .../tests/plugins/natural/__init__.py | 1 + .../plugins/natural/interfaces/assertion.py | 15 +- .../tests/plugins/natural/interfaces/base.py | 122 +++++++--- .../tests/plugins/natural/interfaces/basic.py | 54 +++-- .../tests/plugins/natural/interfaces/int.py | 208 ++++++++++++----- .../tests/plugins/natural/interfaces/spy.py | 218 ++++++++++++++++++ runtime-pyside6/tests/plugins/natural/spy.py | 213 +---------------- runtime-pyside6/tests/plugins/natural/that.py | 23 +- .../tests/plugins/tests/__init__.py | 0 .../tests/plugins/tests/test_natural.py | 217 +++++++++++++++++ 10 files changed, 751 insertions(+), 320 deletions(-) create mode 100644 runtime-pyside6/tests/plugins/natural/interfaces/spy.py create mode 100644 runtime-pyside6/tests/plugins/tests/__init__.py create mode 100644 runtime-pyside6/tests/plugins/tests/test_natural.py diff --git a/runtime-pyside6/tests/plugins/natural/__init__.py b/runtime-pyside6/tests/plugins/natural/__init__.py index 7a67869..4cfe179 100644 --- a/runtime-pyside6/tests/plugins/natural/__init__.py +++ b/runtime-pyside6/tests/plugins/natural/__init__.py @@ -18,4 +18,5 @@ from .spy import Spy from .that import that +from .interfaces.base import Assertion diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py index f2504a2..e1e43c4 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py @@ -17,14 +17,23 @@ """ class Assertion(Exception): - def __init__(self, assertion: bool, message: str): + def __init__(self, assertion: bool, message: str, invert: bool): self.assertion = assertion self.message = message + self.invert = invert + + def _invert_message(self): + for verb in ('is', 'was', 'has', 'have'): + for negative in ("n't", ' not', ' never', ' no'): + self.message = self.message.replace(f"{verb}{negative}", verb.upper()) def __str__(self): return self.message def __bool__(self): - if not self.assertion: + if not self.invert and not self.assertion: raise self - return self.assertion \ No newline at end of file + if self.invert and self.assertion: + self._invert_message() + raise self + return True # Raises otherwise. \ No newline at end of file diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/base.py b/runtime-pyside6/tests/plugins/natural/interfaces/base.py index 88b9e06..0786285 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/base.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/base.py @@ -15,10 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -from typing import Self +from typing import Self, Callable, Any -from tests.plugins.natural.interfaces.assertion import Assertion -from tests.plugins.natural.interfaces.utils import repr_ +from .assertion import Assertion +from .utils import repr_ class AssertionInterface: @@ -26,15 +26,91 @@ class AssertionInterface: Most basic assertion interface. You probably want to use BaseAssertionInterface """ - def __init__(self, value): + + def __init__(self, value, parent: Self = None): self._value = value + self._parent = parent + if parent is None: + self.__not = False @property - def was(self) -> Self: + def _not(self) -> bool: + """ + Internal state of whether the expression was negated. + Use "not_" to set it. + :return: + """ + return self.__not if self._parent is None else self._parent._not + + @_not.setter + def _not(self, value: bool): + if self._not is True: + raise RuntimeError("Cannot call is_not or was_not twice in the same statement.") + if self._parent is None: + self.__not = True + else: + self._parent._not = True + + def instance_of(self, type_: type) -> Assertion: + """ + Checks if the current value is equal to the provided value + """ + value_type_name = type(self._value).__name__ + if not isinstance(type_, type): + raise RuntimeError("Provided 'type' provided is not a class.") + return Assertion( + isinstance(self._value, type_), + f"The value ({value_type_name} {repr_(self._value)}) is not a {type_.__name__}.", + self._not + ) + + def __call__(self, condition: Callable[[Any], bool]) -> Assertion: + """ + Apply condition to value that returns whether or not the value is valid. + """ + return Assertion( + condition(self._value), + f"The value ({repr_(self._value)}) did not match given conditions.", + self._not + ) + + """ + NOT Properties. + """ + + @property + def NOT(self) -> Self: + self._not = True return self @property - def be(self) -> Self: + def not_(self) -> Self: + self._not = True + return self + + @property + def never(self) -> Self: + self._not = True + return self + + """ + Chain self properties to sound natural + """ + + @property + def that(self) -> Self: + return self + + @property + def is_(self) -> Self: + return self + + @property + def does(self) -> Self: + return self + + @property + def was(self) -> Self: return self @property @@ -57,31 +133,25 @@ class AssertionInterface: def an(self) -> Self: return self - def is_a(self, type_) -> Assertion: - """ - Checks if the current value is equal to the provided value - """ - value_type_name = type(self._value).__name__ - return Assertion(isinstance(type_, type_), f"The value ({value_type_name} {repr_(self._value)}) is not a {type_.__name__}.") - - class EqualAssertionInterface(AssertionInterface): """ Interface created for when its value should be checked for equality """ - def __init__(self, value): - super().__init__(value) + + def __init__(self, value, parent: AssertionInterface = None): + super().__init__(value, parent) def __call__(self, value) -> Assertion: - return Assertion(value == self._value, f"The value ({repr_(self._value)}) is not equal to {repr(value)}.") - - def to(self, value) -> Self: - return self(value) - - def of(self, value) -> Self: - return self(value) + return Assertion( + value == self._value, + f"The value {repr_(self._value)} is different from {repr(value)}.", + self._not + ) + @property + def to(self) -> Self: + return self class BaseAssertionInterface(AssertionInterface): @@ -91,11 +161,11 @@ class BaseAssertionInterface(AssertionInterface): """ Checks if the current value is equal to the provided value """ - return EqualAssertionInterface(self._value) + return EqualAssertionInterface(self._value, self) @property - def is_equal(self) -> EqualAssertionInterface: + def equal(self) -> EqualAssertionInterface: """ Checks if the current value is equal to the provided value """ - return self.equals \ No newline at end of file + return self.equals diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py index 1d5a878..25d45cb 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py @@ -15,47 +15,69 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -from tests.plugins.natural.interfaces.assertion import Assertion -from tests.plugins.natural.interfaces.base import BaseAssertionInterface -from tests.plugins.natural.interfaces.int import IntInterface -from tests.plugins.natural.interfaces.utils import repr_ +from .assertion import Assertion +from .base import BaseAssertionInterface +from .int import NumberInterface +from .utils import repr_ class FixedIteratorInterface(BaseAssertionInterface): @property - def length(self) -> IntInterface: - return IntInterface(len(self._value)) + def length(self) -> NumberInterface: + return NumberInterface(len(self._value), self) def elements(self, *elements) -> Assertion: - tests = [elem for elem in elements if elem in self._value] + tests = [repr_(elem) for elem in elements if elem not in self._value] return Assertion( len(tests) == 0, - f"This value ({repr_(self._value)}) does not have elements ({repr_(tests)})" + f"This value ({repr_(self._value)}) does not have elements {', '.join(tests)}.", + self._not ) def element(self, element) -> Assertion: return Assertion( element in self._value, - f"This value ({repr_(self._value)}) does not have element ({repr_(element)})" + f"This value ({repr_(self._value)}) does not have element {repr_(element)}.", + self._not ) def contains(self, *elements) -> Assertion: - return self.elements(*elements) + """ + Check if the element(s) are contained in the iterator. + """ + if len(elements) == 1: + return self.element(elements[0]) + else: + return self.elements(*elements) + + def contain(self, *elements): + """ + Check if the element(s) are contained in the iterator. + """ + return self.contains(*elements) + class BoolInterface(BaseAssertionInterface): @property - def is_true(self): + def true(self): return Assertion( self._value == True, - f"The value ({repr_(self._value)}) is not True." + f"The value ({repr_(self._value)}) is not True.", + self._not ) @property - def is_false(self): + def false(self): return Assertion( self._value == False, - f"The value ({repr_(self._value)}) is not False." + f"The value ({repr_(self._value)}) is not False.", + self._not ) -class StringInterface(LengthInterface): - pass \ No newline at end of file + +class StringInterface(FixedIteratorInterface): + pass + + +class ListInterface(FixedIteratorInterface): + pass diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/int.py b/runtime-pyside6/tests/plugins/natural/interfaces/int.py index aaf0511..7ac8871 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/int.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/int.py @@ -15,17 +15,47 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ +from idlelib.configdialog import is_int +from math import log10, floor, ceil from typing import Self -from tests.plugins.natural.interfaces.assertion import Assertion -from tests.plugins.natural.interfaces.base import BaseAssertionInterface, EqualAssertionInterface, AssertionInterface -from tests.plugins.natural.interfaces.utils import repr_ +from .assertion import Assertion +from .base import AssertionInterface +from .utils import repr_ -class IntComparisonAssertionInterface(AssertionInterface): - def __init__(self, value): - super().__init__(value) - self._compare_to = None +class NumberComparisonAssertionInterface(AssertionInterface): + def __init__(self, value, parent: AssertionInterface = None): + super().__init__(value, parent) + self._compare_stack = [] + + def _generate_compare_to(self) -> int: + """ + The number generated by the comparison stack. + E.g. can parse one.hundred.million.and.thirty.three.thousand.and.twelve.hundred.and.seven + as ['one', 'hundred', 'million', 'thirty', 'three', 'thousand', 'twelve', 'hundred', 'seven'] + which results 100,034,207 + """ + minus = len(self._compare_stack) > 0 and self._compare_stack[0] == -1 + if len(self._compare_stack) < (2 if minus else 1): + raise RuntimeError("No number to compare the value to provided.") + if minus: + self._compare_stack.pop(0) + # Compute the number + add_stack = [self._compare_stack.pop(0)] + for element in self._compare_stack: + last_power = floor(log10(abs(add_stack[-1]))) + current_power = floor(log10(abs(element))) + if last_power < current_power: # E.g. one hundred + add_stack[-1] *= element + elif last_power == 1 and current_power == 0: # E.g thirty four + add_stack[-1] += element + elif last_power > current_power: # E.g a hundred and five + add_stack.append(element) + else: + raise RuntimeError(f"Cannot chain two numbers with the same power ({add_stack[-1]} => {element}.") + total = sum(add_stack) + return -total if minus else total def _compare(self) -> Assertion: raise RuntimeError(f"No comparison method defined in {type(self).__name__}.") @@ -34,23 +64,26 @@ class IntComparisonAssertionInterface(AssertionInterface): return bool(self._compare()) def __call__(self, compare_to: int) -> Self: - if self._compare_to is None: - self._compare_to = int(compare_to) - else: - self._compare_to *= int(compare_to) + if type(compare_to) not in (float, int): + raise RuntimeError(f"Cannot compare number ({self._value}) to non number ({repr_(compare_to)}).") + self._compare_stack.append(compare_to) + return self + + """ + Chain self properties + """ + + @property + def and_(self) -> Self: return self @property - def time(self) -> Self: + def AND(self) -> Self: return self - @property - def times(self) -> Self: - return self - - @property - def never(self) -> Self: - return self(0) + """ + Number shorthands + """ @property def once(self) -> Self: @@ -64,6 +97,10 @@ class IntComparisonAssertionInterface(AssertionInterface): def thrice(self) -> Self: return self(3) + @property + def minus(self) -> Self: + return self(-1) + @property def zero(self) -> Self: return self(0) @@ -108,6 +145,42 @@ class IntComparisonAssertionInterface(AssertionInterface): def ten(self) -> Self: return self(10) + @property + def eleven(self) -> Self: + return self(11) + + @property + def twelve(self) -> Self: + return self(12) + + @property + def thirteen(self) -> Self: + return self(13) + + @property + def fourteen(self) -> Self: + return self(14) + + @property + def fifteen(self) -> Self: + return self(15) + + @property + def sixteen(self) -> Self: + return self(16) + + @property + def seventeen(self) -> Self: + return self(17) + + @property + def eighteen(self) -> Self: + return self(18) + + @property + def nineteen(self) -> Self: + return self(19) + @property def twenty(self) -> Self: return self(20) @@ -134,11 +207,11 @@ class IntComparisonAssertionInterface(AssertionInterface): @property def eighty(self) -> Self: - return self(70) + return self(80) @property def ninety(self) -> Self: - return self(70) + return self(90) @property def hundred(self) -> Self: @@ -157,73 +230,92 @@ class IntComparisonAssertionInterface(AssertionInterface): return self(1_000_000_000) -class LessThanComparisonInterface(IntComparisonAssertionInterface): +class LessThanComparisonInterface(NumberComparisonAssertionInterface): def _compare(self) -> Assertion: + compare = self._generate_compare_to() return Assertion( - self._value < self._compare_to, - f"The value ({repr_(self._value)}) is not less than to {repr_(self._compare_to)}." + self._value < compare, + f"The value ({repr_(self._value)}) is not less than to {repr_(compare)}.", + self._not ) -class MoreThanComparisonInterface(IntComparisonAssertionInterface): + +class MoreThanComparisonInterface(NumberComparisonAssertionInterface): def _compare(self) -> Assertion: + compare = self._generate_compare_to() return Assertion( - self._value > self._compare_to, - f"The value ({repr_(self._value)}) is not more than to {repr_(self._compare_to)}." + self._value > compare, + f"The value ({repr_(self._value)}) is not more than to {repr_(compare)}.", + self._not ) -class AtLeastComparisonInterface(IntComparisonAssertionInterface): + +class AtLeastComparisonInterface(NumberComparisonAssertionInterface): def _compare(self) -> Assertion: + compare = self._generate_compare_to() return Assertion( - self._value >= self._compare_to, - f"The value ({repr_(self._value)}) is not at least to {repr_(self._compare_to)}." + self._value >= compare, + f"The value ({repr_(self._value)}) is not at least to {repr_(compare)}.", + self._not ) -class AtMostComparisonInterface(IntComparisonAssertionInterface): + +class AtMostComparisonInterface(NumberComparisonAssertionInterface): def _compare(self) -> Assertion: + compare = self._generate_compare_to() return Assertion( - self._value <= self._compare_to, - f"The value ({repr_(self._value)}) is not at least to {repr_(self._compare_to)}." + self._value <= compare, + f"The value ({repr_(self._value)}) is not at least to {repr_(compare)}.", + self._not ) -class EqualComparisonInterface(IntComparisonAssertionInterface): + +class EqualComparisonInterface(NumberComparisonAssertionInterface): def _compare(self) -> Assertion: + compare = self._generate_compare_to() return Assertion( - self._value == self._compare_to, - f"The value ({repr_(self._value)}) is not equal to {repr_(self._compare_to)}." + self._value == compare, + f"The value ({repr_(self._value)}) is not equal to {repr_(compare)}.", + self._not ) + @property def to(self) -> Self: return self - def of(self) -> Self: - return self - -class IntInterface(AssertionInterface): - def less_than(self) -> LessThanComparisonInterface: - return LessThanComparisonInterface(self._value) - - @property - def more_than(self) -> MoreThanComparisonInterface: - return MoreThanComparisonInterface(self._value) - - @property - def at_least(self) -> AtLeastComparisonInterface: - return AtLeastComparisonInterface(self._value) - - @property - def at_most(self) -> AtMostComparisonInterface: - return AtMostComparisonInterface(self._value) +class NumberInterface(AssertionInterface): + def __call__(self, value): + return EqualComparisonInterface(self._value, self)(value) @property def equals(self) -> EqualComparisonInterface: - return EqualComparisonInterface(self._value) + return EqualComparisonInterface(self._value, self) @property - def is_equal(self) -> EqualComparisonInterface: - return EqualComparisonInterface(self._value) + def equal(self) -> EqualComparisonInterface: + return EqualComparisonInterface(self._value, self) @property def exactly(self) -> EqualComparisonInterface: - return EqualComparisonInterface(self._value) + return EqualComparisonInterface(self._value, self) + @property + def of(self) -> EqualComparisonInterface: + return EqualComparisonInterface(self._value, self) + + @property + def less_than(self) -> LessThanComparisonInterface: + return LessThanComparisonInterface(self._value, self) + + @property + def more_than(self) -> MoreThanComparisonInterface: + return MoreThanComparisonInterface(self._value, self) + + @property + def at_least(self) -> AtLeastComparisonInterface: + return AtLeastComparisonInterface(self._value, self) + + @property + def at_most(self) -> AtMostComparisonInterface: + return AtMostComparisonInterface(self._value, self) diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py new file mode 100644 index 0000000..59b09d3 --- /dev/null +++ b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py @@ -0,0 +1,218 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from typing import Callable, Self + +from .base import Assertion, repr_, AssertionInterface +from .int import NumberComparisonAssertionInterface + +PRINT_PREFIX = (" " * 24) + + +class SpyAssertion(Assertion): + def __init__(self, assertion: bool, message: str, calls: list, invert: bool): + super().__init__(assertion, message + "\n", invert) + if len(calls) > 0: + self.message += self.render_calls(calls) + else: + self.message += f"{PRINT_PREFIX}0 registered calls." + + def render_calls(self, calls): + lines = [f"{PRINT_PREFIX}{len(calls)} registered call(s):"] + for call in calls: + repr_args = [repr_(arg) for arg in call[0]] + repr_kwargs = [f"{key}={repr_(arg)}" for key, arg in call[1].items()] + lines.append(f" - {', '.join([*repr_args, *repr_kwargs])}") + return ("\n" + PRINT_PREFIX).join(lines) + + +class Methods: + AT_LEAST_ONCE = "AT_LEAST_ONCE" + EXACTLY = "EXACTLY" + AT_LEAST = "AT_LEAST" + AT_MOST = "AT_MOST" + MORE_THAN = "MORE_THAN" + LESS_THAN = "LESS_THAN" + + +class CalledInterface(NumberComparisonAssertionInterface): + """ + Internal class generated by Spy.called. + """ + + def __init__(self, calls: list[tuple[list, dict]], parent: AssertionInterface): + super().__init__(len(calls), parent) + self.__calls = calls + self.__method = Methods.AT_LEAST_ONCE + + def __apply_method(self, calls): + required = None if self._compare_stack == [] else self._generate_compare_to() + calls_count = len(calls) + match self.__method: + case Methods.AT_LEAST_ONCE: + compare = len(calls) >= 1 + error = f"Method was not called" + case Methods.EXACTLY: + compare = len(calls) == required + error = f"Method was not called {required} times ({required} != {calls_count})" + case Methods.AT_LEAST: + compare = len(calls) >= required + error = f"Method was not called at least {required} times ({required} >= {calls_count})" + case Methods.AT_MOST: + compare = len(calls) <= required + error = f"Method was not called at most {required} times ({required} <= {calls_count})" + case Methods.MORE_THAN: + compare = len(calls) > required + error = f"Method was not called more than {required} times ({required} > {calls_count})" + case Methods.LESS_THAN: + compare = len(calls) < required + error = f"Method was not called less than {required} times ({required} < {calls_count})" + case _: + raise RuntimeError(f"Unknown method {self.__method}.") + return compare, error + + def __bool__(self) -> bool: + """ + Converts to boolean on assertion. + """ + compare, error = self.__apply_method(self.__calls) + return bool(SpyAssertion(compare, error + ".", self.__calls, self._not)) + + """ + Chaining methods + """ + + def __call__(self, compare_to: int) -> Self: + super().__call__(compare_to) + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.EXACTLY + return self + + @property + def at_least(self) -> Self: + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.AT_LEAST + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") + return self + + @property + def at_most(self) -> Self: + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.AT_MOST + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") + return self + + @property + def more_than(self) -> Self: + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.MORE_THAN + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.MORE_THAN}") + return self + + @property + def less_than(self) -> Self: + if self.__method == Methods.AT_LEAST_ONCE: + self.__method = Methods.LESS_THAN + else: + raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.LESS_THAN}") + return self + + @property + def time(self) -> Self: + return self + + @property + def times(self) -> Self: + return self + + """ + Class properties. + """ + + def __match_calls_for_condition(self, condition: Callable[[list, dict], bool]) -> tuple[bool, str]: + calls = [] + for call in self.__calls: + if condition(call[0], call[1]): + calls.append(call) + compare, error = self.__apply_method(calls) + return compare, error + + def with_arguments(self, *args, **kwargs) -> SpyAssertion: + """ + Checks if the Spy has been called the given number of times + with at least the given arguments. + """ + + def some_args_matched(a, kw): + args_matched = all(( + arg in a + for arg in args + )) + kwargs_matched = all(( + key in kw and kw[key] == arg + for key, arg in kwargs.items() + )) + return args_matched and kwargs_matched + + compare, error = self.__match_calls_for_condition(some_args_matched) + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + msg = f"{error} with arguments ({repr_args}) and keyword arguments ({repr_kwargs})." + return SpyAssertion(compare, msg, self.__calls, self._not) + + def with_arguments_matching(self, test_condition: Callable[[list, dict], bool]) -> SpyAssertion: + """ + Checks if the Spy has been called the given number of times + with arguments matching the given conditions. + """ + compare, error = self.__match_calls_for_condition(test_condition) + msg = f"{error} with arguments matching given conditions." + return SpyAssertion(compare, msg, self.__calls, self._not) + + def with_exact_arguments(self, *args, **kwargs) -> SpyAssertion: + """ + Checks if the Spy has been called the given number of times + with all the given arguments. + """ + compare, error = self.__match_calls_for_condition(lambda a, kw: a == args and kw == kwargs) + repr_args = ', '.join([repr(arg) for arg in args]) + repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) + msg = f"{error} with exact arguments ({repr_args}) and keyword arguments ({repr_kwargs})." + return SpyAssertion(compare, msg, self.__calls, self._not) + + def with_no_argument(self) -> SpyAssertion: + """ + Checks if the Spy has been called the given number of times + with all the given arguments. + """ + compare, error = self.__match_calls_for_condition(lambda a, kw: len(a) == 0 and len(kw) == 0) + return SpyAssertion(compare, f"{error} with no arguments.", self.__calls, self._not) + + +class SpyAssertionInterface(AssertionInterface): + + @property + def called(self) -> CalledInterface: + """ + Returns a boolean-able interface to check conditions for a given number of + time the spy was called. + """ + return CalledInterface(self._value.calls, self) diff --git a/runtime-pyside6/tests/plugins/natural/spy.py b/runtime-pyside6/tests/plugins/natural/spy.py index 1d77629..fbd8e17 100644 --- a/runtime-pyside6/tests/plugins/natural/spy.py +++ b/runtime-pyside6/tests/plugins/natural/spy.py @@ -15,207 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -from typing import Callable, Self - -from tests.plugins.natural.interfaces.base import Assertion, repr_, AssertionInterface -from tests.plugins.natural.interfaces.int import IntComparisonAssertionInterface - -PRINT_PREFIX = (" " * 24) +from typing import Callable -class SpyAssertion(Assertion): - def __init__(self, assertion: bool, message: str, calls: list): - super().__init__(assertion, message + "\n") - if len(calls) > 0: - self.message += self.render_calls(calls) - else: - self.message += f"{PRINT_PREFIX}0 registered calls." - - - def render_calls(self, calls): - lines = [f"{PRINT_PREFIX}{len(calls)} registered call(s):"] - for call in calls: - repr_args = [repr_(arg) for arg in call[0]] - repr_kwargs = [f"{key}={repr_(arg)}" for key, arg in call[1].items()] - lines.append(f" - {', '.join([*repr_args, *repr_kwargs])}") - return ("\n" + PRINT_PREFIX).join(lines) - - -class Methods: - AT_LEAST_ONCE = "AT_LEAST_ONCE" - EXACTLY = "EXACTLY" - AT_LEAST = "AT_LEAST" - AT_MOST = "AT_MOST" - MORE_THAN = "AT_LEAST" - LESS_THAN = "AT_MOST" - - -class CalledInterface(IntComparisonAssertionInterface): - """ - Internal class generated by Spy.was_called. - """ - - def __init__(self, calls: list[tuple[list, dict]]): - super().__init__(len(calls)) - self.__calls = calls - self.__method = Methods.AT_LEAST_ONCE - - def __apply_method(self, calls): - required = self._compare_to - calls_count = len(calls) - match self.__method: - case Methods.AT_LEAST_ONCE: - compare = len(calls) >= 1 - error = "Method was not called" - case Methods.EXACTLY: - compare = len(calls) == required - error = f"Method was not called {required} times ({required} != {calls_count})" - case Methods.AT_LEAST: - compare = len(calls) >= required - error = f"Method was not called at least {required} times ({required} > {calls_count})" - case Methods.AT_MOST: - compare = len(calls) <= required - error = f"Method was not called at most {required} times ({required} < {calls_count})" - case Methods.MORE_THAN: - compare = len(calls) > required - error = f"Method was not called more than {required} times ({required} >= {calls_count})" - case Methods.LESS_THAN: - compare = len(calls) < required - error = f"Method was not called less than {required} times ({required} <= {calls_count})" - case _: - raise RuntimeError(f"Unknown method {self.__method}.") - return compare, error - - def __bool__(self) -> bool: - """ - Converts to boolean on assertion. - """ - compare, error = self.__apply_method(self.__calls) - return bool(SpyAssertion(compare, error + ".", self.__calls)) - - """ - Chaining methods - """ - - def __call__(self, *args, **kwargs) -> Self: - if len(args) != 1: - raise RuntimeError("Cannot call called interface with more than one argument.") - self._compare_to = int(args[0]) - if self.__method == Methods.AT_LEAST_ONCE: - self.__method = Methods.EXACTLY - return self - - @property - def at_least(self) -> Self: - if self.__method == Methods.AT_LEAST_ONCE: - self.__method = Methods.AT_LEAST - else: - raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") - return self - - @property - def at_most(self) -> Self: - if self.__method == Methods.AT_LEAST_ONCE: - self.__method = Methods.AT_MOST - else: - raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.AT_MOST}") - return self - - @property - def more_than(self) -> Self: - if self.__method == Methods.AT_LEAST_ONCE: - self.__method = Methods.MORE_THAN - else: - raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.MORE_THAN}") - return self - - @property - def less_than(self) -> Self: - if self.__method == Methods.AT_LEAST_ONCE: - self.__method = Methods.LESS_THAN - else: - raise RuntimeError(f"Cannot redefine method from {self.__method} to {Methods.LESS_THAN}") - return self - - @property - def time(self) -> Self: - return self - - @property - def times(self) -> Self: - return self - - """ - Class properties. - """ - - def __match_calls_for_condition(self, condition: Callable[[list, dict], bool]) -> tuple[bool, str]: - calls = [] - for call in self.__calls: - if condition(call[0], call[1]): - calls.append(call) - compare, error = self.__apply_method(calls) - return compare, error - - def with_arguments(self, *args, **kwargs) -> SpyAssertion: - """ - Checks if the Spy has been called the given number of times - with at least the given arguments. - """ - - def some_args_matched(a, kw): - args_matched = all(( - arg in a - for arg in args - )) - kwargs_matched = all(( - key in kw and kw[key] == arg - for key, arg in kwargs.items() - )) - return args_matched and kwargs_matched - - compare, error = self.__match_calls_for_condition(some_args_matched) - repr_args = ', '.join([repr(arg) for arg in args]) - repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) - msg = f"{error} with arguments ({repr_args}) and keyword arguments ({repr_kwargs})." - return SpyAssertion(compare, msg, self.__calls) - - def with_arguments_matching(self, test_condition: Callable[[list, dict], bool]) -> SpyAssertion: - """ - Checks if the Spy has been called the given number of times - with arguments matching the given conditions. - """ - compare, error = self.__match_calls_for_condition(test_condition) - msg = f"{error} with arguments matching given conditions." - return SpyAssertion(compare, msg, self.__calls) - - def with_exact_arguments(self, *args, **kwargs) -> SpyAssertion: - """ - Checks if the Spy has been called the given number of times - with all the given arguments. - """ - compare, error = self.__match_calls_for_condition(lambda a, kw: a == args and kw == kwargs) - repr_args = ', '.join([repr(arg) for arg in args]) - repr_kwargs = ', '.join([f"{key}={repr(arg)}" for key, arg in kwargs.items()]) - msg = f"{error} with exact arguments ({repr_args}) and keyword arguments ({repr_kwargs})." - return SpyAssertion(compare, msg, self.__calls) - - def with_no_argument(self) -> SpyAssertion: - """ - Checks if the Spy has been called the given number of times - with all the given arguments. - """ - compare, error = self.__match_calls_for_condition(lambda a, kw: len(a) == 0 and len(kw) == 0) - return SpyAssertion(compare, f"{error} with no arguments.", self.__calls) - - -class Spy(AssertionInterface): +class Spy: """ Class to spy into method calls with natural language expressions. """ def __init__(self, function: Callable = None): - super().__init__(function) self.function = function self.calls = [] @@ -223,20 +31,3 @@ class Spy(AssertionInterface): self.calls.append((args, kwargs)) if self.function is not None: self.function(*args, **kwargs) - - @property - def called(self) -> CalledInterface: - """ - Returns a boolean-able interface to check conditions for a given number of - time the spy was called. - """ - return CalledInterface(self.calls) - - @property - def not_called(self) -> CalledInterface: - """ - Returns a boolean-able interface to check that conditions were never fulfilled - in the times the spy was called. - """ - ret = CalledInterface(self.calls) - return ret(0) diff --git a/runtime-pyside6/tests/plugins/natural/that.py b/runtime-pyside6/tests/plugins/natural/that.py index 38ee54e..05a3e31 100644 --- a/runtime-pyside6/tests/plugins/natural/that.py +++ b/runtime-pyside6/tests/plugins/natural/that.py @@ -17,17 +17,21 @@ """ from typing import overload, Generic, TypeVar -from .spy import Spy +from . import Spy from .interfaces.base import AssertionInterface, BaseAssertionInterface -from .interfaces.basic import StringInterface, BoolInterface -from .interfaces.int import IntInterface +from .interfaces.basic import StringInterface, BoolInterface, ListInterface +from .interfaces.int import NumberInterface +from .interfaces.spy import SpyAssertionInterface Interface = TypeVar("Interface", bound=AssertionInterface) MATCHES = [ (str, StringInterface), - (int, IntInterface), (bool, BoolInterface), + (int, NumberInterface), + (float, NumberInterface), + (list, ListInterface), + (Spy, SpyAssertionInterface) ] @@ -36,11 +40,18 @@ def that(value: str) -> StringInterface: ... @overload -def that(value: int) -> IntInterface: ... +def that(value: bool) -> BoolInterface: ... @overload -def that(value: bool) -> BoolInterface: ... +def that(value: int) -> NumberInterface: ... + + +@overload +def that(value: float) -> NumberInterface: ... + +@overload +def that(value: Spy) -> SpyAssertionInterface: ... @overload diff --git a/runtime-pyside6/tests/plugins/tests/__init__.py b/runtime-pyside6/tests/plugins/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/runtime-pyside6/tests/plugins/tests/test_natural.py b/runtime-pyside6/tests/plugins/tests/test_natural.py new file mode 100644 index 0000000..d7fe26c --- /dev/null +++ b/runtime-pyside6/tests/plugins/tests/test_natural.py @@ -0,0 +1,217 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" +import pytest + +from ..natural import that, Assertion, Spy + + +def test_string(): + assert that("QWERTY").is_.an.instance_of(str) + assert that("QWERTY").is_.not_.an.instance_of(int) + assert that("QWERTY").is_.equal.to("QWERTY") + assert that("QWERTY").is_.NOT.equal.to("QWERTYUIOP") + assert that("QWERTY").is_.NOT.equal.to(3) + assert that("QWERTY").has.a.length.of(6) + assert that("QWERTY").does.NOT.have.a.length.of(7) + assert that("QWERTY").has.a.length.that.is_.NOT(5) + assert that("QWERTY").contains("WER") + assert that("QWERTY").contains("WER", "TY") + assert that("QWERTY").does.not_.contain("AZERTY") + with pytest.raises(Assertion): + assert that("QWERTY").is_.an.instance_of(int) + with pytest.raises(Assertion): + assert that("QWERTY").is_.equal.to(False) + with pytest.raises(Assertion): + assert that("QWERTY").has.a.length.of(1) + with pytest.raises(Assertion): + assert that("QWERTY").contains("AZERTY") + with pytest.raises(Assertion): + assert that("QWERTY").does.NOT.contain("QWE") + +def test_bool(): + assert that(True).is_.an.instance_of(bool) + assert that(True).is_.an.instance_of(int) + assert that(True).is_.NOT.an.instance_of(str) + assert that(True).equals(True) + assert that(True).is_.true + assert that(True).is_.NOT.false + assert that(False).is_.equal.to(False) + assert that(False).is_.false + assert that(False).is_.NOT.true + with pytest.raises(Assertion): + assert that(True).is_.false + with pytest.raises(Assertion): + assert that(True).is_.NOT.true + +def test_int(): + assert that(2).is_.an.instance_of(int) + assert that(2).is_.NOT.an.instance_of(bool) + assert that(2).is_.NOT.an.instance_of(str) + assert that(2).is_.more_than(1) + assert that(2).is_.NOT.less_than(1) + assert that(2).is_.less_than(3) + assert that(2).is_.NOT.more_than(3) + assert that(2).is_.at_least(1) + assert that(2).is_.NOT.at_most(1) + assert that(2).is_.at_most(3) + assert that(2).is_.NOT.at_least(3) + assert that(2).is_.at_most(2) + assert that(2).is_.at_least(2) + # Equality + assert that(2).is_(2) + assert that(2).was(2) + assert that(2).is_.exactly(2) + assert that(2).is_.equal.to(2) + assert that(2).equals(2) + assert that(2).is_.NOT(3) + assert that(2).does.NOT.equal(3) + +def test_int_shorthands(): + # Direct numbers + assert that(0).equals.zero + assert that(1).equals.one + assert that(2).equals.two + assert that(3).equals.three + assert that(4).equals.four + assert that(5).equals.five + assert that(6).equals.six + assert that(7).equals.seven + assert that(8).equals.eight + assert that(9).equals.nine + assert that(10).equals.ten + assert that(11).equals.eleven + assert that(12).equals.twelve + assert that(13).equals.thirteen + assert that(14).equals.fourteen + assert that(15).equals.fifteen + assert that(16).equals.sixteen + assert that(17).equals.seventeen + assert that(18).equals.eighteen + assert that(19).equals.nineteen + assert that(20).equals.twenty + assert that(30).equals.thirty + assert that(40).equals.forty + assert that(50).equals.fifty + assert that(60).equals.sixty + assert that(70).equals.seventy + assert that(80).equals.eighty + assert that(90).equals.ninety + assert that(100).equals.a.hundred + assert that(1000).equals.a.thousand + assert that(1_000_000).equals.a.million + +def test_add_natural_complex(): + # Test composed + assert that(34).equals.thirty.four + assert that(-34).equals.minus.thirty.four + assert that(100_033_207).equals.one.hundred.million.AND.thirty.three.thousand.AND.two.hundred.AND.seven + assert that(-1_200_033_207).equals.minus.one.billion.AND.two.hundred.million.AND.thirty.three.thousand.AND.two.hundred.AND.seven + assert that(7890).equals.seven.thousand.eight.hundred.and_.ninety + assert that(7890).equals.seventy.eight.hundred.and_.ninety + assert that(7890).equals(78)(100)(90) + with pytest.raises(RuntimeError): + assert that(1_000_000).equals.a.thousand.thousand + with pytest.raises(RuntimeError): + assert that(600).equals.one.twenty.thirty + with pytest.raises(RuntimeError): + assert that(2).equals + with pytest.raises(RuntimeError): + assert that(2).equals.one.minus.two + +def test_spy(): + spy = Spy() + assert that(spy).is_.an.instance_of(Spy) + assert that(spy).is_(callable) + # Check calls + assert that(spy).was.never.called + assert that(spy).was.called.zero.times + spy(30, arg="string") + assert that(spy).was.called + assert that(spy).was.called.once + assert that(spy).was.called.one.time + assert that(spy).was.NOT.called.more_than.once + assert that(spy).was.called.with_arguments(30) + assert that(spy).was.called.with_arguments_matching(lambda args, kwargs: len(args) == 1 and len(kwargs) == 1) + assert that(spy).was.NOT.called.with_arguments(50) + assert that(spy).was.NOT.called.with_exact_arguments(30) + assert that(spy).was.NOT.called.with_no_argument() + assert that(spy).was.called.with_exact_arguments(30, arg="string") + with pytest.raises(Assertion): + assert that(spy).was.called.with_arguments(50) + with pytest.raises(Assertion): + assert that(spy).was.called.with_exact_arguments(30) + with pytest.raises(Assertion): + assert that(spy).was.called.with_no_argument() + +def test_spy_seral_calls(): + spy = Spy(lambda *args, **kw: None) + obj = object() + spy() + spy(30, arg="string") + spy(obj, 30, example=obj, none=None) + assert that(spy).was.called + assert that(spy).was.called.more_than.once + assert that(spy).was.called.more_than.twice + assert that(spy).was.NOT.called.more_than.thrice + assert that(spy).was.called.at_most.thrice + assert that(spy).was.called.at_least.thrice + assert that(spy).was.called.three.times + assert that(spy).was.called.less_than(4).times + # Check arguments + assert that(spy).was.called.once.with_no_argument() + assert that(spy).was.called.at_most.once.with_no_argument() + assert that(spy).was.called.twice.with_arguments(30) + assert that(spy).was.NOT.called.less_than.twice.with_arguments(30) + assert that(spy).was.called.once.with_arguments(obj) + assert that(spy).was.called.once.with_arguments(arg="string") + assert that(spy).was.called.once.with_arguments(30, obj) + assert that(spy).was.called.once.with_arguments(none=None) + assert that(spy).was.NOT.called.with_arguments(None) + assert that(spy).was.NOT.called.with_arguments(obj, 30, arg="string") + with pytest.raises(Assertion): + assert that(spy).was.called.with_arguments(obj, 30, arg="string") + # Checking with exact arguments + assert that(spy).was.called.once.with_exact_arguments(30, arg="string") + assert that(spy).was.called.once.with_exact_arguments(obj, 30, example=obj, none=None) + assert that(spy).was.NOT.called.with_exact_arguments(obj, 30, arg="string") + with pytest.raises(Assertion): + assert that(spy).was.called.with_exact_arguments(obj, 30, arg="string") + # Check arguments matching + assert that(spy).has.NOT.been.called.with_arguments_matching(lambda a, kw: len(a) + len(kw) == 3) + assert that(spy).was.called.once.with_arguments_matching(lambda a, kw: len(a) + len(kw) == 2) + assert that(spy).was.called.once.with_arguments_matching(lambda a, kw: len(a) + len(kw) == 4) + with pytest.raises(Assertion): + assert that(spy).was.called.with_arguments_matching(lambda a, kw: len(a) + len(kw) == 3) + + +def test_wrongful_expressions(): + spy = Spy() + with pytest.raises(RuntimeError): + assert that(3).is_.less_than("str") + with pytest.raises(RuntimeError): + assert that(3).does.NOT.NOT.equal(3) + with pytest.raises(RuntimeError): + assert that(3).is_.an.instance_of("non type") + with pytest.raises(RuntimeError): + assert that(spy).was.called.more_than.at_least.once + with pytest.raises(RuntimeError): + assert that(spy).was.called.more_than.at_most.once + with pytest.raises(RuntimeError): + assert that(spy).was.called.more_than.less_than.once + with pytest.raises(RuntimeError): + assert that(spy).was.called.more_than.more_than.once \ No newline at end of file From a182c703f43a9542bb55662b0dd68bc12872b48a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 03:38:36 +0200 Subject: [PATCH 210/249] Finishing testing promises. --- .../LogarithmPlotter/util/promise.py | 24 ++--- .../tests/plugins/natural/interfaces/spy.py | 2 +- runtime-pyside6/tests/plugins/natural/spy.py | 2 +- .../tests/plugins/tests/test_natural.py | 6 +- runtime-pyside6/tests/test_main.py | 3 +- runtime-pyside6/tests/test_promise.py | 98 +++++++++++++++---- runtime-pyside6/tests/test_pyjs.py | 1 - scripts/run-tests.sh | 14 +++ 8 files changed, 114 insertions(+), 36 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index 3c2d223..f43e85b 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -73,10 +73,10 @@ class PyPromiseRunner(QRunnable): class PyPromise(QObject): """ - Asynchronous Promise-like object meant to interface between Python and Javascript easily. + Threaded A+/Promise implementation meant to interface between Python and Javascript easily. Runs to_run in another thread, and calls fulfilled (populated by then) with its return value. """ - fulfilled = Signal((QJSValue,), (QObject,)) + fulfilled = Signal(QJSValue) rejected = Signal(str) def __init__(self, to_run: Callable|QJSValue, args=[], start_automatically=True): @@ -115,10 +115,8 @@ class PyPromise(QObject): """ on_fulfill = check_callable(on_fulfill) on_reject = check_callable(on_reject) - if on_fulfill is not None: - self._fulfills.append(on_fulfill) - if on_reject is not None: - self._rejects.append(on_reject) + self._fulfills.append(on_fulfill) + self._rejects.append(on_reject) return self def calls_upon_fulfillment(self, function: Callable | QJSValue) -> bool: @@ -155,20 +153,22 @@ class PyPromise(QObject): def _fulfill(self, data): self._state = "fulfilled" no_return = [None, QJSValue.SpecialValue.UndefinedValue] - for on_fulfill in self._fulfills: + print("Fulfill") + for i in range(len(self._fulfills)): try: - result = on_fulfill(data) + result = self._fulfills[i](data) result = result.qjs_value if isinstance(result, PyJSValue) else result data = result if result not in no_return else data # Forward data. except Exception as e: - self._reject(repr(e)) + self._reject(repr(e), start_at=i) break @Slot(QJSValue) @Slot(str) - def _reject(self, error): + def _reject(self, error, start_at=0): self._state = "rejected" no_return = [None, QJSValue.SpecialValue.UndefinedValue] - for on_reject in self._rejects: - result = on_reject(error) + for i in range(start_at, len(self._rejects)): + result = self._rejects[i](error) + result = result.qjs_value if isinstance(result, PyJSValue) else result error = result if result not in no_return else error # Forward data. diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py index 59b09d3..524fd71 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py @@ -21,7 +21,7 @@ from typing import Callable, Self from .base import Assertion, repr_, AssertionInterface from .int import NumberComparisonAssertionInterface -PRINT_PREFIX = (" " * 24) +PRINT_PREFIX = (" " * 3) class SpyAssertion(Assertion): diff --git a/runtime-pyside6/tests/plugins/natural/spy.py b/runtime-pyside6/tests/plugins/natural/spy.py index fbd8e17..2f9211a 100644 --- a/runtime-pyside6/tests/plugins/natural/spy.py +++ b/runtime-pyside6/tests/plugins/natural/spy.py @@ -30,4 +30,4 @@ class Spy: def __call__(self, *args, **kwargs): self.calls.append((args, kwargs)) if self.function is not None: - self.function(*args, **kwargs) + return self.function(*args, **kwargs) diff --git a/runtime-pyside6/tests/plugins/tests/test_natural.py b/runtime-pyside6/tests/plugins/tests/test_natural.py index d7fe26c..f381639 100644 --- a/runtime-pyside6/tests/plugins/tests/test_natural.py +++ b/runtime-pyside6/tests/plugins/tests/test_natural.py @@ -134,13 +134,13 @@ def test_add_natural_complex(): assert that(2).equals.one.minus.two def test_spy(): - spy = Spy() + spy = Spy(lambda *args, **kw: 10) assert that(spy).is_.an.instance_of(Spy) assert that(spy).is_(callable) # Check calls assert that(spy).was.never.called assert that(spy).was.called.zero.times - spy(30, arg="string") + assert spy(30, arg="string") == 10 assert that(spy).was.called assert that(spy).was.called.once assert that(spy).was.called.one.time @@ -159,7 +159,7 @@ def test_spy(): assert that(spy).was.called.with_no_argument() def test_spy_seral_calls(): - spy = Spy(lambda *args, **kw: None) + spy = Spy() obj = object() spy() spy(30, arg="string") diff --git a/runtime-pyside6/tests/test_main.py b/runtime-pyside6/tests/test_main.py index 047e21f..6b161ad 100644 --- a/runtime-pyside6/tests/test_main.py +++ b/runtime-pyside6/tests/test_main.py @@ -22,12 +22,13 @@ from os.path import exists, join from PySide6.QtGui import QIcon from tempfile import TemporaryDirectory +from .globals import app + from LogarithmPlotter.logarithmplotter import get_linux_theme, LINUX_THEMES, get_platform_qt_style, \ register_icon_directories, install_translation, create_engine from LogarithmPlotter.util import config from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex -from globals import app THEMES = [ "Basic", diff --git a/runtime-pyside6/tests/test_promise.py b/runtime-pyside6/tests/test_promise.py index a97f864..30f0a1e 100644 --- a/runtime-pyside6/tests/test_promise.py +++ b/runtime-pyside6/tests/test_promise.py @@ -17,9 +17,10 @@ """ from time import sleep +import pytest from PySide6.QtQml import QJSValue -from tests.plugins.natural import that, Spy +from .plugins.natural import that, Spy from LogarithmPlotter.util.js import PyJSValue from LogarithmPlotter.util.promise import PyPromise @@ -56,6 +57,10 @@ def async_throw(): class TestPyPromise: + def test_invalid_function(self): + with pytest.raises(ValueError): + promise = PyPromise("not a function") + def test_fulfill_values(self, qtbot): qjsv = QJSValue(3) values = [ @@ -70,7 +75,6 @@ class TestPyPromise: for [value, test] in values: promise = PyPromise(create_async_func(value)) with qtbot.assertNotEmitted(promise.rejected, wait=1000): - print("Testing", value) with qtbot.waitSignal(promise.fulfilled, check_params_cb=test, timeout=2000): assert promise.state == "pending" assert promise.state == "fulfilled" @@ -84,30 +88,90 @@ class TestPyPromise: assert promise.state == "rejected" def test_fulfill(self, qtbot): - spy_fulfilled = Spy() - spy_rejected = Spy() + fulfilled = Spy() + rejected = Spy() promise = PyPromise(create_async_func(3)) - then_res = promise.then(spy_fulfilled, spy_rejected) + then_res = promise.then(fulfilled, rejected) # Check if the return value is the same promise (so we can chain then) - assert then_res == promise + assert that(then_res).does.equal(promise) # Check on our spy. with qtbot.waitSignal(promise.fulfilled, timeout=10000): pass - assert that(spy_fulfilled).was.called.once - assert that(spy_fulfilled).was.not_called.with_arguments(3) - assert that(spy_fulfilled).was.called.with_arguments_matching(check_promise_result(3)) - assert spy_rejected.was.not_called + assert that(fulfilled).was.called.once + assert that(fulfilled).was.NOT.called.with_arguments(3) + assert that(fulfilled).was.called.with_arguments_matching(check_promise_result(3)) + assert that(rejected).was.never.called def test_rejected(self, qtbot): - spy_fulfilled = Spy() - spy_rejected = Spy() + fulfilled = Spy() + rejected = Spy() promise = PyPromise(async_throw) - then_res = promise.then(spy_fulfilled, spy_rejected) + then_res = promise.then(fulfilled, rejected) # Check if the return value is the same promise (so we can chain then) - assert that(then_res).is_equal.to(promise) + assert that(then_res).does.equal(promise) # Check on our spies. with qtbot.waitSignal(promise.rejected, timeout=10000): pass - assert that(spy_rejected).was.called.once - assert that(spy_rejected).was.called.with_arguments("Exception('aaaa')") - assert that(spy_fulfilled).was.not_called + assert that(rejected).was.called.once + assert that(rejected).was.called.with_arguments("Exception('aaaa')") + assert that(fulfilled).has.never.been.called + + def test_chain_fulfill(self, qtbot): + convert = Spy(lambda v: v.toVariant()) + plus = Spy(lambda v: v + 1) + rejected = Spy() + promise = PyPromise(create_async_func(5)) + then_res = promise.then(convert, rejected).then(plus, rejected).then(plus, rejected).then(plus, rejected) + # Check if the return value is the same promise (so we can chain then) + assert that(then_res).does.equal(promise) + with qtbot.waitSignal(promise.fulfilled, timeout=10000): + pass + assert that(convert).was.called.once.with_arguments_matching(check_promise_result(5)) + assert that(rejected).was.never.called + assert that(plus).was.called.three.times + assert that(plus).was.called.once.with_exact_arguments(5) + assert that(plus).was.called.once.with_exact_arguments(6) + assert that(plus).was.called.once.with_exact_arguments(7) + + def test_chain_reject(self, qtbot): + fulfilled = Spy() + convert = Spy(lambda v: len(v)) + minus = Spy(lambda v: v - 1) + promise = PyPromise(async_throw) + then_res = promise.then(fulfilled, convert).then(fulfilled, minus).then(fulfilled, minus).then(fulfilled, minus) + # Check if the return value is the same promise (so we can chain then) + assert that(then_res).does.equal(promise) + with qtbot.waitSignal(promise.rejected, timeout=10000): + pass + assert that(fulfilled).was.never.called + assert that(convert).was.called.once.with_arguments_matching(check_promise_result("Exception('aaaa')")) + assert that(minus).was.called.three.times + assert that(minus).was.called.once.with_exact_arguments(17) + assert that(minus).was.called.once.with_exact_arguments(16) + assert that(minus).was.called.once.with_exact_arguments(15) + + def test_check_calls_upon(self): + promise = PyPromise(async_throw) + fulfilled = Spy() + rejected = Spy() + promise.then(fulfilled, rejected) + assert promise.calls_upon_fulfillment(fulfilled) + assert promise.calls_upon_rejection(rejected) + assert not promise.calls_upon_fulfillment(rejected) + assert not promise.calls_upon_rejection(fulfilled) + + def test_reject_in_fulfill(self, qtbot): + def fulfilled_throw(x): + raise Exception('noooo') + promise = PyPromise(create_async_func("3")) + fulfilled_throw = Spy(fulfilled_throw) + fulfilled = Spy() + rejected = Spy() + then_res = promise.then(fulfilled, rejected).then(fulfilled_throw, rejected).then(fulfilled, rejected).then(fulfilled, rejected) + # Check if the return value is the same promise (so we can chain then) + assert that(then_res).does.equal(promise) + with qtbot.waitSignal(promise.fulfilled, timeout=10000): + pass + assert that(fulfilled_throw).has.been.called.once + assert that(rejected).has.been.called.three.times + assert that(rejected).has.been.called.three.times.with_arguments("Exception('noooo')") \ No newline at end of file diff --git a/runtime-pyside6/tests/test_pyjs.py b/runtime-pyside6/tests/test_pyjs.py index 5742cfc..95c3cf6 100644 --- a/runtime-pyside6/tests/test_pyjs.py +++ b/runtime-pyside6/tests/test_pyjs.py @@ -21,7 +21,6 @@ from re import Pattern from PySide6.QtQml import QJSEngine, QJSValue from LogarithmPlotter.util.js import PyJSValue, InvalidAttributeValueException, NotAPrimitiveException -from globals import app @pytest.fixture() def data(): diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index ac1fdc5..8c09c54 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,8 +1,20 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1 +box() { + len=${#1} + echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐" + echo "│ $1 │" + echo "└─$(printf '─%.0s' $(seq 1 "$len"))─┘" +} + rebuild=true +cd runtime-pyside6/tests/plugins || exit 1 +box "Testing pytest natural plugins..." +PYTHONPATH="$PYTHONPATH:." pytest --cov=natural --cov-report term-missing . +cd ../../../ + while [ $# -gt 0 ]; do case "$1" in --no-rebuild) @@ -27,10 +39,12 @@ rm -rf build/runtime-pyside6/tests cp -r runtime-pyside6/tests build/runtime-pyside6 cp -r ci CHANGELOG.md build/runtime-pyside6 cd build/runtime-pyside6 || exit 1 +box "Testing runtime-pyside6..." PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . cd ../../ # Run js tests cd common || exit 1 +box "Testing common..." npm test From 2899ac6cde0c8cdca2efd60edd7b325314c0fe80 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 03:41:41 +0200 Subject: [PATCH 211/249] Fixing unit testing importing unexpected and unused libraries. --- .gitignore | 6 ++++-- runtime-pyside6/tests/plugins/natural/interfaces/int.py | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3961125..e2308a5 100644 --- a/.gitignore +++ b/.gitignore @@ -37,8 +37,10 @@ docs/html *.lpf *.lgg +# Tests +common/coverage/ +**/.coverage + # npm common/node_modules -common/coverage/ -common/.coverage runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs* diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/int.py b/runtime-pyside6/tests/plugins/natural/interfaces/int.py index 7ac8871..75bd8b8 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/int.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/int.py @@ -15,8 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . """ -from idlelib.configdialog import is_int -from math import log10, floor, ceil +from math import log10, floor from typing import Self from .assertion import Assertion From 3c0d99d9c037b1d153f776024098951f29eb71df Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 03:44:35 +0200 Subject: [PATCH 212/249] Exiting when not all tests are fulfilled. --- scripts/run-tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 8c09c54..3f73e37 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -12,7 +12,7 @@ rebuild=true cd runtime-pyside6/tests/plugins || exit 1 box "Testing pytest natural plugins..." -PYTHONPATH="$PYTHONPATH:." pytest --cov=natural --cov-report term-missing . +PYTHONPATH="$PYTHONPATH:." pytest --cov=natural --cov-report term-missing . || exit 1 cd ../../../ while [ $# -gt 0 ]; do @@ -40,11 +40,11 @@ cp -r runtime-pyside6/tests build/runtime-pyside6 cp -r ci CHANGELOG.md build/runtime-pyside6 cd build/runtime-pyside6 || exit 1 box "Testing runtime-pyside6..." -PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . +PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . || exit 1 cd ../../ # Run js tests cd common || exit 1 box "Testing common..." -npm test +npm test || exit 1 From 811262b1fbbabf8933c7b6ac222d7815d7b7b7fc Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 05:09:33 +0200 Subject: [PATCH 213/249] Changing lupdate and lrelease to use pyside6 versions, updating images so I no longer have to install node to build. --- assets/i18n/release.sh | 2 +- assets/i18n/update.sh | 2 +- ci/drone.yml | 13 +++---------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/assets/i18n/release.sh b/assets/i18n/release.sh index 93475b5..58477c3 100755 --- a/assets/i18n/release.sh +++ b/assets/i18n/release.sh @@ -1,2 +1,2 @@ #!/bin/bash -lrelease *.ts +pyside6-lrelease *.ts diff --git a/assets/i18n/update.sh b/assets/i18n/update.sh index ff96ef8..98f4201 100755 --- a/assets/i18n/update.sh +++ b/assets/i18n/update.sh @@ -40,7 +40,7 @@ done echo "----------------------------" echo "| Updating translations... |" echo "----------------------------" -lupdate -extensions js,qs,qml,py -recursive ../../common/src -recursive ../../runtime-pyside6/LogarithmPlotter -ts lp_*.ts +pyside6-lupdate -extensions js,qs,qml,py -recursive ../../common/src -recursive ../../runtime-pyside6/LogarithmPlotter -ts lp_*.ts # Updating locations in files for lp in *.ts; do echo "Replacing locations in $lp..." diff --git a/ci/drone.yml b/ci/drone.yml index da7d1c7..d49a6d4 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -12,28 +12,21 @@ steps: - git submodule update --init --recursive - name: Build - image: node:18-bookworm + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex-node commands: - cd common && npm install && cd .. - - apt update - - apt install -y qtchooser qttools5-dev-tools - # Start building - bash scripts/build.sh - when: - event: [ push, tag ] - name: Unit Tests - image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex-node commands: - - apt update - - apt install -y npm - cd common && npm install -D && cd .. - xvfb-run bash scripts/run-tests.sh --no-rebuild when: event: [ push, tag ] - name: File Tests - image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex-node commands: - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf From 14c092b9fa87b1f09e3f56226bb7439487267a0c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 17 Oct 2024 05:28:03 +0200 Subject: [PATCH 214/249] Fixing tests --- README.md | 2 +- runtime-pyside6/tests/test_latex.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5d4ba57..249792a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ First, you'll need to install all the required dependencies: - [npm](https://npmjs.com) (or [yarn](https://yarnpkg.com/)), go to the `common` directory, and run `npm install` (or `yarn install`). You can simply run LogarithmPlotter using `python3 run.py`. It automatically compiles the language files (requires -`lrelease` to be installed and in path), and the JavaScript modules. +`pyside6-lrelease` to be installed and in path), and the JavaScript modules. If you do not wish do recompile the files again on every run, you can use the build script (`scripts/build.sh`) and run `python3 build/runtime-pyside6/LogarithmPlotter/logarithmplotter.py`. diff --git a/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index 124186b..ee87fa5 100644 --- a/runtime-pyside6/tests/test_latex.py +++ b/runtime-pyside6/tests/test_latex.py @@ -82,9 +82,9 @@ class TestLatex: with pytest.raises(latex.RenderError): latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) # Replace latex bin with one goes indefinitely - latex.LATEX_PATH = which("import") - with pytest.raises(latex.RenderError): - latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) + # latex.LATEX_PATH = which("import") # TODO: Find one such executable + # with pytest.raises(latex.RenderError): + # latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) latex.LATEX_PATH = bkp def test_prerendered(self, latex_obj: latex.Latex) -> None: From 6251835aa0c1d96ec0e4752260c90a34b297cd3a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 18 Oct 2024 14:08:31 +0000 Subject: [PATCH 215/249] Translated using Weblate (German) Currently translated at 100.0% (265 of 265 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- assets/i18n/lp_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 59a9725..7d66a7a 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -145,7 +145,7 @@ &Changelog - &Changelog + &Versionshinweise @@ -388,7 +388,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Changelog - Changelog + Versionshinweise From e35f6cebecdcdbf9db28ffb1491fefd04268ca6a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 20 Oct 2024 00:11:35 +0200 Subject: [PATCH 216/249] Starting Latex tests. --- common/package-lock.json | 11 ++- common/package.json | 1 + common/src/module/latex.mjs | 7 +- common/test/hooks.mjs | 2 + common/test/mock/helper.mjs | 3 +- common/test/mock/latex.mjs | 5 +- common/test/module/latex.mjs | 144 +++++++++++++++++++++++++++++++++++ 7 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 common/test/module/latex.mjs diff --git a/common/package-lock.json b/common/package-lock.json index ee15bf5..5df6794 100644 --- a/common/package-lock.json +++ b/common/package-lock.json @@ -13,6 +13,7 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", + "@types/chai-as-promised": "^8.0.1", "c8": "^10.1.2", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" @@ -2198,9 +2199,17 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.0.tgz", "integrity": "sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA==", - "dev": true, "license": "MIT" }, + "node_modules/@types/chai-as-promised": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.1.tgz", + "integrity": "sha512-dAlDhLjJlABwAVYObo9TPWYTRg9NaQM5CXeaeJYcYAkvzUf0JRLIiog88ao2Wqy/20WUnhbbUZcgvngEbJ3YXQ==", + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/chai-spies": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/chai-spies/-/chai-spies-1.0.6.tgz", diff --git a/common/package.json b/common/package.json index e85d3ff..a368ef5 100644 --- a/common/package.json +++ b/common/package.json @@ -25,6 +25,7 @@ "devDependencies": { "@types/chai": "^5.0.0", "@types/chai-spies": "^1.0.6", + "@types/chai-as-promised": "^8.0.1", "@types/mocha": "^10.0.8", "chai": "^5.1.1", "chai-as-promised": "^8.0.0", diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 830f096..dca9422 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -62,7 +62,7 @@ class LatexRenderResult { class LatexAPI extends Module { /** @type {LatexInterface} */ #latex = null - + constructor() { super("Latex", { latex: LatexInterface, @@ -142,9 +142,10 @@ class LatexAPI extends Module { */ parif(elem, contents) { elem = elem.toString() - if(elem[0] !== "(" && elem.at(-1) !== ")" && contents.some(x => elem.indexOf(x) > 0)) + const contains = contents.some(x => elem.indexOf(x) > 0) + if(elem[0] !== "(" && elem.at(-1) !== ")" && contains) return this.par(elem) - if(elem[0] === "(" && elem.at(-1) === ")") + if(elem[0] === "(" && elem.at(-1) === ")" && !contains) return elem.removeEnclosure() return elem } diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index abe468f..66e9da9 100644 --- a/common/test/hooks.mjs +++ b/common/test/hooks.mjs @@ -22,8 +22,10 @@ import { MockLatex } from "./mock/latex.mjs" import { use } from "chai" import spies from "chai-spies" +import promised from "chai-as-promised" function setup() { + use(promised) const { spy } = use(spies) globalThis.Helper = new MockHelper() diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs index c2b024f..4cab472 100644 --- a/common/test/mock/helper.mjs +++ b/common/test/mock/helper.mjs @@ -22,7 +22,8 @@ const DEFAULT_SETTINGS = { "check_for_updates": true, "reset_redo_stack": true, "last_install_greet": "0", - "enable_latex": false, + "enable_latex": true, + "enable_latex_async": true, "expression_editor": { "autoclose": true, "colorize": true, diff --git a/common/test/mock/latex.mjs b/common/test/mock/latex.mjs index c0a029c..2d6fb5f 100644 --- a/common/test/mock/latex.mjs +++ b/common/test/mock/latex.mjs @@ -22,10 +22,7 @@ const PIXEL = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAA export class MockLatex { constructor() { - } - - get supportsAsyncRender() { - return true + this.supportsAsyncRender = true } /** diff --git a/common/test/module/latex.mjs b/common/test/module/latex.mjs new file mode 100644 index 0000000..13ffd03 --- /dev/null +++ b/common/test/module/latex.mjs @@ -0,0 +1,144 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests +import "./base.mjs" +import "./expreval.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" +import { existsSync } from "../mock/fs.mjs" + +const { spy } = chaiPlugins + +import LatexAPI from "../../src/module/latex.mjs" + +describe("Module/Latex", function() { + it("is defined as a global", function() { + expect(globalThis.Modules.Latex).to.equal(LatexAPI) + }) + + describe("#initialize", function() { + it("isn't enabled before initialization", function() { + expect(LatexAPI.enabled).to.be.false + }) + + it("is enabled after initialization", function() { + LatexAPI.initialize({ latex: Latex, helper: Helper }) + expect(LatexAPI.enabled).to.equal(Helper.getSetting("enable_latex")) + expect(LatexAPI.initialized).to.be.true + }) + }) + + describe("#requestAsyncRender", function() { + it("should return a render result with a valid source, a width, and a height", async function() { + const data = await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") + expect(data).to.be.an("object") + expect(data.source).to.be.a("string") + expect(data.source).to.satisfy(existsSync) + expect(data.height).to.be.a("number") + expect(data.width).to.be.a("number") + }) + + it("should call functions from the LaTeX module", async function() { + const renderSyncSpy = spy.on(Latex, "renderSync") + const renderAsyncSpy = spy.on(Latex, "renderAsync") + Latex.supportsAsyncRender = true + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") + expect(renderAsyncSpy).to.have.been.called.once + expect(renderSyncSpy).to.have.been.called.once // Called async + Latex.supportsAsyncRender = false + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") + expect(renderAsyncSpy).to.have.been.called.once // From the time before + expect(renderSyncSpy).to.have.been.called.twice + Latex.supportsAsyncRender = true + }) + + it("should not reply with the same source for different markup, font size, or color.", async function() { + const datas = [ + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033"), + await LatexAPI.requestAsyncRender("\\frac{x}{4}", 13, "#AA0033"), + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 14, "#AA0033"), + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#0033AA") + ] + const sources = datas.map(x => x.source) + expect(new Set(sources)).to.have.a.lengthOf(4) + }) + }) + + describe("#findPrerendered", function() { + it("should return the same data as async render for the same markup, font size, and color", async function() { + const data = await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") + const found = LatexAPI.findPrerendered("\\frac{x}{3}", 13, "#AA0033") + expect(found).to.not.be.null + expect(found.source).to.equal(data.source) + expect(found.width).to.equal(data.width) + }) + + it("should return null if the markup hasn't been prerendered with the same markup, font size, and color", async function() { + await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") + expect(LatexAPI.findPrerendered("\\frac{y}{3}", 13, "#AA0033")).to.be.null + expect(LatexAPI.findPrerendered("\\frac{x}{3}", 12, "#AA0033")).to.be.null + expect(LatexAPI.findPrerendered("\\frac{x}{3}", 13, "#3300AA")).to.be.null + }) + }) + + describe("#par", function() { + it("should add parentheses to strings", function() { + expect(LatexAPI.par("string")).to.equal("(string)") + expect(LatexAPI.par("aaaa")).to.equal("(aaaa)") + expect(LatexAPI.par("")).to.equal("()") + expect(LatexAPI.par("(example)")).to.equal("((example))") + }) + }) + + describe("#parif", function() { + it("should add parentheses to strings that contain one of the ones in the list", function() { + expect(LatexAPI.parif("string", ["+"])).to.equal("string") + expect(LatexAPI.parif("string+assert", ["+"])).to.equal("(string+assert)") + expect(LatexAPI.parif("string+assert", ["+", "-"])).to.equal("(string+assert)") + expect(LatexAPI.parif("string-assert", ["+", "-"])).to.equal("(string-assert)") + }) + + it("shouldn't add new parentheses to strings that contains one of the ones in the list if they already have one", function() { + expect(LatexAPI.parif("(string+assert", ["+"])).to.equal("((string+assert)") + expect(LatexAPI.parif("string+assert)", ["+"])).to.equal("(string+assert))") + expect(LatexAPI.parif("(string+assert)", ["+"])).to.equal("(string+assert)") + expect(LatexAPI.parif("(string+assert)", ["+", "-"])).to.equal("(string+assert)") + expect(LatexAPI.parif("(string-assert)", ["+", "-"])).to.equal("(string-assert)") + }) + + it("shouldn't add parentheses to strings that does not contains one of the ones in the list", function() { + expect(LatexAPI.parif("string", ["+"])).to.equal("string") + expect(LatexAPI.parif("string+assert", ["-"])).to.equal("string+assert)") + expect(LatexAPI.parif("(string*assert", ["+", "-"])).to.equal("(string*assert") + expect(LatexAPI.parif("string/assert)", ["+", "-"])).to.equal("string/assert)") + }) + + it("should remove parentheses from strings that does not contains one of the ones in the list", function() { + expect(LatexAPI.parif("(string)", ["+"])).to.equal("string") + expect(LatexAPI.parif("(string+assert)", ["-"])).to.equal("string+assert") + expect(LatexAPI.parif("((string*assert)", ["+", "-"])).to.equal("(string*assert") + expect(LatexAPI.parif("(string/assert))", ["+", "-"])).to.equal("string/assert)") + }) + }) + + describe("#variable", function() { + + }) +}) \ No newline at end of file From b989a685e9bbca5a8343c95d4dfcd3ff623ccb6b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 22 Oct 2024 01:05:06 +0200 Subject: [PATCH 217/249] Fixing issue with LaTeX sqrt. --- common/src/module/latex.mjs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index dca9422..c9904de 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -143,9 +143,9 @@ class LatexAPI extends Module { parif(elem, contents) { elem = elem.toString() const contains = contents.some(x => elem.indexOf(x) > 0) - if(elem[0] !== "(" && elem.at(-1) !== ")" && contains) + if((elem[0] !== "(" || elem.at(-1) !== ")") && contains) return this.par(elem) - if(elem[0] === "(" && elem.at(-1) === ")" && !contains) + if((elem[0] === "(" || elem.at(-1) === ")") && !contains) return elem.removeEnclosure() return elem } @@ -170,13 +170,14 @@ class LatexAPI extends Module { else return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2]}(t) dt` case "sqrt": - return `\\sqrt\\left(${args.join(", ")}\\right)` + const arg = this.parif(args.join(", "), []) + return `\\sqrt{${arg}}` case "abs": return `\\left|${args.join(", ")}\\right|` case "floor": - return `\\left\\lfloor${args.join(", ")}\\right\\rfloor` + return `\\left\\lfloor{${args.join(", ")}}\\right\\rfloor` case "ceil": - return `\\left\\lceil${args.join(", ")}\\right\\rceil` + return `\\left\\lceil{${args.join(", ")}}\\right\\rceil` default: return `\\mathrm{${f}}\\left(${args.join(", ")}\\right)` } @@ -294,7 +295,7 @@ class LatexAPI extends Module { nstack.push(this.parif(n1, ["+", "-", "*", "/", "^"]) + "!") break default: - nstack.push(f + this.parif(n1, ["+", "-", "*", "/", "^"])) + nstack.push(this.functionToLatex(f, [this.parif(n1, ["+", "-", "*", "/", "^"])])) break } break @@ -332,6 +333,7 @@ class LatexAPI extends Module { if(nstack.length > 1) { nstack = [nstack.join(";")] } + console.log(nstack[0]) return String(nstack[0]) } } From 14e8cef6af89decfe44866d84598366cf344bc29 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 22 Oct 2024 02:50:00 +0200 Subject: [PATCH 218/249] Fixing issues with LaTeX and rendering variable pi. --- common/src/lib/expr-eval/polyfill.mjs | 5 ----- common/src/module/latex.mjs | 23 ++++++++++------------- common/test/basics/polyfill.mjs | 0 3 files changed, 10 insertions(+), 18 deletions(-) create mode 100644 common/test/basics/polyfill.mjs diff --git a/common/src/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs index c618aaf..a15c741 100644 --- a/common/src/lib/expr-eval/polyfill.mjs +++ b/common/src/lib/expr-eval/polyfill.mjs @@ -266,11 +266,6 @@ export function roundTo(value, exp) { return +(value[0] + "e" + (value[1] ? (+value[1] + exp) : exp)) } -export function setVar(name, value, variables) { - if(variables) variables[name] = value - return value -} - export function arrayIndex(array, index) { return array[index | 0] } diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index c9904de..216e3be 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -21,7 +21,7 @@ import * as Instruction from "../lib/expr-eval/instruction.mjs" import { escapeValue } from "../lib/expr-eval/expression.mjs" import { HelperInterface, LatexInterface } from "./interface.mjs" -const unicodechars = [ +const unicodechars = ["pi", "∞", "α", "β", "γ", "δ", "ε", "ζ", "η", "π", "θ", "κ", "λ", "μ", "ξ", "ρ", "ς", "σ", "τ", "φ", "χ", "ψ", "ω", @@ -30,9 +30,9 @@ const unicodechars = [ "ₕ", "ₖ", "ₗ", "ₘ", "ₙ", "ₚ", "ₛ", "ₜ", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", - "₄", "₅", "₆", "₇", "₈", "₉", "₀", - "pi", "∞"] -const equivalchars = [ + "₄", "₅", "₆", "₇", "₈", "₉", "₀" +] +const equivalchars = ["\\pi", "\\infty", "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", "\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho", "\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega", @@ -42,7 +42,7 @@ const equivalchars = [ "{}_{t}", "{}^{1}", "{}^{2}", "{}^{3}", "{}^{4}", "{}^{5}", "{}^{6}", "{}^{7}", "{}^{8}", "{}^{9}", "{}^{0}", "{}_{1}", "{}_{2}", "{}_{3}", "{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}", - "\\pi", "\\infty"] +] /** * Class containing the result of a LaTeX render. @@ -143,9 +143,9 @@ class LatexAPI extends Module { parif(elem, contents) { elem = elem.toString() const contains = contents.some(x => elem.indexOf(x) > 0) - if((elem[0] !== "(" || elem.at(-1) !== ")") && contains) + if(contains && (elem[0] !== "(" || elem.at(-1) !== ")")) return this.par(elem) - if((elem[0] === "(" || elem.at(-1) === ")") && !contains) + if(!contains && elem[0] === "(" && elem.at(-1) === ")") return elem.removeEnclosure() return elem } @@ -191,16 +191,17 @@ class LatexAPI extends Module { * @returns {string} */ variable(vari, wrapIn$ = false) { - if(wrapIn$) + if(wrapIn$) { for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) vari = vari.replaceAll(unicodechars[i], "$" + equivalchars[i] + "$") } - else + } else { for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) vari = vari.replaceAll(unicodechars[i], equivalchars[i]) } + } return vari } @@ -330,10 +331,6 @@ class LatexAPI extends Module { throw new EvalError("invalid Expression") } } - if(nstack.length > 1) { - nstack = [nstack.join(";")] - } - console.log(nstack[0]) return String(nstack[0]) } } diff --git a/common/test/basics/polyfill.mjs b/common/test/basics/polyfill.mjs new file mode 100644 index 0000000..e69de29 From d53f50193a1988a002e35ce0bdac91f001ce6ac4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 22 Oct 2024 02:50:24 +0200 Subject: [PATCH 219/249] Finishing latex and polyfill tests. --- common/test/basics/polyfill.mjs | 231 ++++++++++++++++++++++++++++++++ common/test/module/latex.mjs | 91 ++++++++++++- 2 files changed, 320 insertions(+), 2 deletions(-) diff --git a/common/test/basics/polyfill.mjs b/common/test/basics/polyfill.mjs index e69de29..ce018f2 100644 --- a/common/test/basics/polyfill.mjs +++ b/common/test/basics/polyfill.mjs @@ -0,0 +1,231 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests + +import { describe, it } from "mocha" +import { expect } from "chai" + +import * as Polyfill from "../../src/lib/expr-eval/polyfill.mjs" +import { + andOperator, + cbrt, + equal, + expm1, + hypot, + lessThan, + log1p, + log2, + notEqual +} from "../../src/lib/expr-eval/polyfill.mjs" + +describe("Math/Polyfill", () => { + describe("#AADDDD", function() { + it("should add two numbers", function() { + expect(Polyfill.add(2, 3)).to.equal(5) + expect(Polyfill.add("2", "3")).to.equal(5) + }) + }) + + describe("#sub", function() { + it("should subtract two numbers", function() { + expect(Polyfill.sub(2, 1)).to.equal(1) + expect(Polyfill.sub("2", "1")).to.equal(1) + }) + }) + + describe("#mul", function() { + it("should multiply two numbers", function() { + expect(Polyfill.mul(2, 3)).to.equal(6) + expect(Polyfill.mul("2", "3")).to.equal(6) + }) + }) + + describe("#div", function() { + it("should divide two numbers", function() { + expect(Polyfill.div(10, 2)).to.equal(5) + expect(Polyfill.div("10", "2")).to.equal(5) + }) + }) + + describe("#mod", function() { + it("should return the modulo of two numbers", function() { + expect(Polyfill.mod(10, 3)).to.equal(1) + expect(Polyfill.mod("10", "3")).to.equal(1) + }) + }) + + describe("#concat", function() { + it("should return the concatenation of two strings", function() { + expect(Polyfill.concat(10, 3)).to.equal("103") + expect(Polyfill.concat("abc", "def")).to.equal("abcdef") + }) + }) + + describe("#equal", function() { + it("should return whether its two arguments are equal", function() { + expect(Polyfill.equal(10, 3)).to.be.false + expect(Polyfill.equal(10, 10)).to.be.true + expect(Polyfill.equal("abc", "def")).to.be.false + expect(Polyfill.equal("abc", "abc")).to.be.true + }) + }) + + describe("#notEqual", function() { + it("should return whether its two arguments are not equal", function() { + expect(Polyfill.notEqual(10, 3)).to.be.true + expect(Polyfill.notEqual(10, 10)).to.be.false + expect(Polyfill.notEqual("abc", "def")).to.be.true + expect(Polyfill.notEqual("abc", "abc")).to.be.false + }) + }) + + describe("#greaterThan", function() { + it("should return whether its first argument is strictly greater than its second", function() { + expect(Polyfill.greaterThan(10, 3)).to.be.true + expect(Polyfill.greaterThan(10, 10)).to.be.false + expect(Polyfill.greaterThan(10, 30)).to.be.false + }) + }) + + describe("#lessThan", function() { + it("should return whether its first argument is strictly less than its second", function() { + expect(Polyfill.lessThan(10, 3)).to.be.false + expect(Polyfill.lessThan(10, 10)).to.be.false + expect(Polyfill.lessThan(10, 30)).to.be.true + }) + }) + + describe("#greaterThanEqual", function() { + it("should return whether its first argument is greater or equal to its second", function() { + expect(Polyfill.greaterThanEqual(10, 3)).to.be.true + expect(Polyfill.greaterThanEqual(10, 10)).to.be.true + expect(Polyfill.greaterThanEqual(10, 30)).to.be.false + }) + }) + + describe("#lessThanEqual", function() { + it("should return whether its first argument is strictly less than its second", function() { + expect(Polyfill.lessThanEqual(10, 3)).to.be.false + expect(Polyfill.lessThanEqual(10, 10)).to.be.true + expect(Polyfill.lessThanEqual(10, 30)).to.be.true + }) + }) + + describe("#andOperator", function() { + it("should return whether its arguments are both true", function() { + expect(Polyfill.andOperator(true, true)).to.be.true + expect(Polyfill.andOperator(true, false)).to.be.false + expect(Polyfill.andOperator(false, true)).to.be.false + expect(Polyfill.andOperator(false, false)).to.be.false + expect(Polyfill.andOperator(10, 3)).to.be.true + expect(Polyfill.andOperator(10, 0)).to.be.false + expect(Polyfill.andOperator(0, 0)).to.be.false + }) + }) + + describe("#orOperator", function() { + it("should return whether one of its arguments is true", function() { + expect(Polyfill.orOperator(true, true)).to.be.true + expect(Polyfill.orOperator(true, false)).to.be.true + expect(Polyfill.orOperator(false, true)).to.be.true + expect(Polyfill.orOperator(false, false)).to.be.false + expect(Polyfill.orOperator(10, 3)).to.be.true + expect(Polyfill.orOperator(10, 0)).to.be.true + expect(Polyfill.orOperator(0, 0)).to.be.false + }) + }) + + describe("#inOperator", function() { + it("should check if second argument contains first", function() { + expect(Polyfill.inOperator("a", ["a", "b", "c"])).to.be.true + expect(Polyfill.inOperator(3, [0, 1, 2])).to.be.false + expect(Polyfill.inOperator(3, [0, 1, 3, 2])).to.be.true + expect(Polyfill.inOperator("a", "abcdef")).to.be.true + expect(Polyfill.inOperator("a", "bcdefg")).to.be.false + }) + }) + + describe("#sinh, #cosh, #tanh, #asinh, #acosh, #atanh", function() { + const EPSILON = 1e-12 + for(let x = -.9; x < 1; x += 0.1) { + expect(Polyfill.sinh(x)).to.be.approximately(Math.sinh(x), EPSILON) + expect(Polyfill.cosh(x)).to.be.approximately(Math.cosh(x), EPSILON) + expect(Polyfill.tanh(x)).to.be.approximately(Math.tanh(x), EPSILON) + expect(Polyfill.asinh(x)).to.be.approximately(Math.asinh(x), EPSILON) + expect(Polyfill.atanh(x)).to.be.approximately(Math.atanh(x), EPSILON) + } + for(let x = 1.1; x < 10; x += 0.1) { + expect(Polyfill.sinh(x)).to.be.approximately(Math.sinh(x), EPSILON) + expect(Polyfill.cosh(x)).to.be.approximately(Math.cosh(x), EPSILON) + expect(Polyfill.tanh(x)).to.be.approximately(Math.tanh(x), EPSILON) + expect(Polyfill.asinh(x)).to.be.approximately(Math.asinh(x), EPSILON) + expect(Polyfill.acosh(x)).to.be.approximately(Math.acosh(x), EPSILON) + expect(Polyfill.log10(x)).to.be.approximately(Math.log10(x), EPSILON) + } + }) + + describe("#trunc", function() { + it("should return the decimal part of floats", function() { + for(let x = -10; x < 10; x += 0.1) + expect(Polyfill.trunc(x)).to.equal(Math.trunc(x)) + }) + }) + + describe("#gamma", function() { + it("should return the product of factorial(x - 1)", function() { + expect(Polyfill.gamma(0)).to.equal(Infinity) + expect(Polyfill.gamma(1)).to.equal(1) + expect(Polyfill.gamma(2)).to.equal(1) + expect(Polyfill.gamma(3)).to.equal(2) + expect(Polyfill.gamma(4)).to.equal(6) + expect(Polyfill.gamma(5)).to.equal(24) + expect(Polyfill.gamma(172)).to.equal(Infinity) + expect(Polyfill.gamma(172.3)).to.equal(Infinity) + expect(Polyfill.gamma(.2)).to.approximately(4.590_843_712, 1e-8) + expect(Polyfill.gamma(5.5)).to.be.approximately(52.34277778, 1e-8) + expect(Polyfill.gamma(90.2)).to.equal(4.0565358202825355e+136) + }) + }) + + describe("#hypot", function() { + it("should return the hypothenus length of a triangle whose length are provided in arguments", function() { + for(let x = 0; x < 10; x += 0.3) { + expect(Polyfill.hypot(x)).to.be.approximately(Math.hypot(x), Number.EPSILON) + for(let y = 0; y < 10; y += 0.3) { + expect(Polyfill.hypot(x, y)).to.be.approximately(Math.hypot(x, y), Number.EPSILON) + } + } + }) + }) + + describe("#sign, #cbrt, #exmp1", function() { + for(let x = -10; x < 10; x += 0.3) { + expect(Polyfill.sign(x)).to.approximately(Math.sign(x), 1e-12) + expect(Polyfill.cbrt(x)).to.approximately(Math.cbrt(x), 1e-12) + expect(Polyfill.expm1(x)).to.approximately(Math.expm1(x), 1e-12) + } + }) + + describe("#log1p, #log2", function() { + for(let x = 1; x < 10; x += 0.3) { + expect(Polyfill.log1p(x)).to.be.approximately(Math.log1p(x), 1e-12) + expect(Polyfill.log2(x)).to.be.approximately(Math.log2(x), 1e-12) + } + }) +}) \ No newline at end of file diff --git a/common/test/module/latex.mjs b/common/test/module/latex.mjs index 13ffd03..02aaca5 100644 --- a/common/test/module/latex.mjs +++ b/common/test/module/latex.mjs @@ -17,6 +17,7 @@ */ // Load prior tests +import "../basics/utils.mjs" import "./base.mjs" import "./expreval.mjs" @@ -26,6 +27,7 @@ import { existsSync } from "../mock/fs.mjs" const { spy } = chaiPlugins +import ExprEval from "../../src/module/expreval.mjs" import LatexAPI from "../../src/module/latex.mjs" describe("Module/Latex", function() { @@ -125,7 +127,7 @@ describe("Module/Latex", function() { it("shouldn't add parentheses to strings that does not contains one of the ones in the list", function() { expect(LatexAPI.parif("string", ["+"])).to.equal("string") - expect(LatexAPI.parif("string+assert", ["-"])).to.equal("string+assert)") + expect(LatexAPI.parif("string+assert", ["-"])).to.equal("string+assert") expect(LatexAPI.parif("(string*assert", ["+", "-"])).to.equal("(string*assert") expect(LatexAPI.parif("string/assert)", ["+", "-"])).to.equal("string/assert)") }) @@ -139,6 +141,91 @@ describe("Module/Latex", function() { }) describe("#variable", function() { - + const from = [ + "α", "β", "γ", "δ", "ε", "ζ", "η", + "π", "θ", "κ", "λ", "μ", "ξ", "ρ", + "ς", "σ", "τ", "φ", "χ", "ψ", "ω", + "Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Σ", + "Φ", "Ψ", "Ω", "ₐ", "ₑ", "ₒ", "ₓ", + "ₕ", "ₖ", "ₗ", "ₘ", "ₙ", "ₚ", "ₛ", + "ₜ", "¹", "²", "³", "⁴", "⁵", "⁶", + "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", + "₄", "₅", "₆", "₇", "₈", "₉", "₀", + "pi", "∞"] + const to = [ + "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", + "\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho", + "\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega", + "\\Gamma", "\\Delta", "\\Theta", "\\Lambda", "\\Xi", "\\Pi", "\\Sigma", + "\\Phy", "\\Psi", "\\Omega", "{}_{a}", "{}_{e}", "{}_{o}", "{}_{x}", + "{}_{h}", "{}_{k}", "{}_{l}", "{}_{m}", "{}_{n}", "{}_{p}", "{}_{s}", + "{}_{t}", "{}^{1}", "{}^{2}", "{}^{3}", "{}^{4}", "{}^{5}", "{}^{6}", + "{}^{7}", "{}^{8}", "{}^{9}", "{}^{0}", "{}_{1}", "{}_{2}", "{}_{3}", + "{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}", + "\\pi", "\\infty"] + + it("should convert unicode characters to their latex equivalent", function() { + for(let i = 0; i < from.length; i++) + expect(LatexAPI.variable(from[i])).to.include(to[i]) + }) + + it("should wrap within dollar signs when the option is included", function() { + for(let i = 0; i < from.length; i++) { + expect(LatexAPI.variable(from[i], false)).to.equal(to[i]) + expect(LatexAPI.variable(from[i], true)).to.equal(`$${to[i]}$`) + } + }) + + it("should be able to convert multiple of them", function() { + expect(LatexAPI.variable("α₂", false)).to.equal("\\alpha{}_{2}") + expect(LatexAPI.variable("∞piΠ", false)).to.equal("\\infty\\pi\\Pi") + }) + }) + + describe("#functionToLatex", function() { + it("should transform derivatives into latex fractions", function() { + const d1 = LatexAPI.functionToLatex("derivative", ["'3t'", "'t'", "x+2"]) + const d2 = LatexAPI.functionToLatex("derivative", ["f", "x+2"]) + expect(d1).to.equal("\\frac{d3x}{dx}") + expect(d2).to.equal("\\frac{df}{dx}(x+2)") + }) + + it("should transform integrals into latex limits", function() { + const i1 = LatexAPI.functionToLatex("integral", ["0", "x", "'3y'", "'y'"]) + const i2 = LatexAPI.functionToLatex("integral", ["1", "2", "f"]) + expect(i1).to.equal("\\int\\limits_{0}^{x}3y dy") + expect(i2).to.equal("\\int\\limits_{1}^{2}f(t) dt") + }) + + it("should transform sqrt functions to sqrt latex", function() { + const sqrt1 = LatexAPI.functionToLatex("sqrt", ["(x+2)"]) + const sqrt2 = LatexAPI.functionToLatex("sqrt", ["\\frac{x}{2}"]) + expect(sqrt1).to.equal("\\sqrt{x+2}") + expect(sqrt2).to.equal("\\sqrt{\\frac{x}{2}}") + }) + + it("should transform abs, floor and ceil", function() { + const abs = LatexAPI.functionToLatex("abs", ["x+3"]) + const floor = LatexAPI.functionToLatex("floor", ["x+3"]) + const ceil = LatexAPI.functionToLatex("ceil", ["x+3"]) + expect(abs).to.equal("\\left|x+3\\right|") + expect(floor).to.equal("\\left\\lfloor{x+3}\\right\\rfloor") + expect(ceil).to.equal("\\left\\lceil{x+3}\\right\\rceil") + }) + + it("should transform regular functions into latex", function() { + const f1 = LatexAPI.functionToLatex("f", ["x+3", true]) + const f2 = LatexAPI.functionToLatex("h_1", ["10"]) + expect(f1).to.equal("\\mathrm{f}\\left(x+3, true\\right)") + expect(f2).to.equal("\\mathrm{h_1}\\left(10\\right)") + }) + }) + + describe("#expression", function() { + it("should transform parsed expressions", function() { + const expr = ExprEval.parse("(+1! == 2/2 ? sin [-2.2][0] : f(t)^(1+1-1) + sqrt(A.t)) * 3 % 1") + const expected = "((((+1!))==(\\frac{2}{2}) ? (\\mathrm{sin}\\left(([(-2.2)][0])\\right)) : (\\mathrm{f}\\left(t\\right)^{1+1-1}+\\sqrt{A.t})) \\times 3) \\mathrm{mod} 1" + expect(LatexAPI.expression(expr.tokens)).to.equal(expected) + }) }) }) \ No newline at end of file From 67799e99083dae45e480a319c0bc82093142a2e8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 22 Oct 2024 02:50:56 +0200 Subject: [PATCH 220/249] Removing debug from python. --- runtime-pyside6/LogarithmPlotter/util/latex.py | 2 +- runtime-pyside6/LogarithmPlotter/util/promise.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index f36f07f..71064fa 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -181,7 +181,7 @@ class Latex(QObject): """ markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) if self.latexSupported and not path.exists(export_path + ".png"): - print("Rendering", latex_markup, export_path) + print("Rendering", latex_markup) # Generating file latex_path = path.join(self.tempdir, str(markup_hash)) # If the formula is just recolored or the font is just changed, no need to recreate the DVI. diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index f43e85b..f65efa8 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -153,7 +153,6 @@ class PyPromise(QObject): def _fulfill(self, data): self._state = "fulfilled" no_return = [None, QJSValue.SpecialValue.UndefinedValue] - print("Fulfill") for i in range(len(self._fulfills)): try: result = self._fulfills[i](data) From 2594fd68442113819f62dcef988adcd1555d8c54 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 01:06:24 +0200 Subject: [PATCH 221/249] Adding new expression tests. --- README.md | 6 +- common/src/math/expression.mjs | 53 +++++++--- common/src/module/io.mjs | 1 - common/src/objs/common.mjs | 2 +- common/test/basics/polyfill.mjs | 41 ++++---- common/test/math/expression.mjs | 181 ++++++++++++++++++++++++++++++++ common/test/mock/qt.mjs | 13 ++- common/test/module/latex.mjs | 36 +++---- common/test/module/objects.mjs | 3 +- 9 files changed, 274 insertions(+), 62 deletions(-) create mode 100644 common/test/math/expression.mjs diff --git a/README.md b/README.md index 249792a..976df53 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,8 @@ Finally, to actually run the tests: You should have received a copy of the GNU General Public License along with this program. If not, see . -Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their -original authors. See LICENSE.md for more details: +See LICENSE.md for more details. Language files translations located at assets/i18n are licensed under GNU GPL3.0+ and +are copyrighted by their original authors: - 🇭🇺 Hungarian translation by [Óvári](https://github.com/ovari) - 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) @@ -109,5 +109,5 @@ of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined <r@undefined.ch>, ported to javascript by Matthew Crumley <email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. -All files in (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/) except integration.mjs are licensed +All files in (common/src/lib/expr-eval/) except integration.mjs are licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). diff --git a/common/src/math/expression.mjs b/common/src/math/expression.mjs index 2862183..5701ac6 100644 --- a/common/src/math/expression.mjs +++ b/common/src/math/expression.mjs @@ -21,24 +21,34 @@ import * as Utils from "../utils.mjs" import Latex from "../module/latex.mjs" import ExprParser from "../module/expreval.mjs" import Objects from "../module/objects.mjs" +import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs" + +const NUMBER_MATCHER = /^\d*\.\d+(e[+-]\d+)?$/ /** * Represents any kind of x-based or non variable based expression. */ export class Expression { + /** + * + * @param {string|ExprEvalExpression} expr + */ constructor(expr) { if(typeof expr === "string") { this.expr = Utils.exponentsToExpression(expr) this.calc = ExprParser.parse(this.expr).simplify() - } else { + } else if(expr instanceof ExprEvalExpression) { // Passed an expression here directly. this.calc = expr.simplify() this.expr = expr.toString() + } else { + const type = expr != null ? "a " + expr.constructor.name : expr + throw new Error(`Cannot create an expression with ${type}.`) } - this.cached = this.isConstant() + this.canBeCached = this.isConstant() this.cachedValue = null - if(this.cached && this.allRequirementsFulfilled()) - this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) + if(this.canBeCached && this.allRequirementsFulfilled()) + this.recache() this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -77,21 +87,20 @@ export class Expression { /** * Returns a list of names whose corresponding objects this expression is dependant on and are missing. - * @return {boolean} + * @return {string[]} */ undefinedVariables() { return this.requiredObjects().filter(objName => !(objName in Objects.currentObjectsByName)) } recache() { - if(this.cached) - this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) } execute(x = 1) { - if(this.cached) { + if(this.canBeCached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) + this.recache() return this.cachedValue } ExprParser.currentVars = Object.assign({ "x": x }, Objects.currentObjectsByName) @@ -99,9 +108,10 @@ export class Expression { } simplify(x) { - let expr = this.calc.substitute("x", x).simplify() - if(expr.evaluate() === 0) expr = "0" - return new Expression(expr) + let expr = new Expression(this.calc.substitute("x", x).simplify()) + if(expr.allRequirementsFulfilled() && expr.execute() === 0) + expr = new Expression("0") + return expr } toEditableString() { @@ -110,17 +120,28 @@ export class Expression { toString(forceSign = false) { let str = Utils.makeExpressionReadable(this.calc.toString()) - if(str !== undefined && str.match(/^\d*\.\d+$/)) { - if(str.split(".")[1].split("0").length > 7) { + if(str !== undefined && str.match(NUMBER_MATCHER)) { + const decimals = str.split(".")[1].split("e")[0] + const zeros = decimals.split("0").length + const nines = decimals.split("9").length + if(zeros > 7 || nines > 7) { // Likely rounding error - str = parseFloat(str.substring(0, str.length - 1)).toString() + str = parseFloat(str).toDecimalPrecision(8).toString() } } - if(str[0] !== "-" && forceSign) str = "+" + str + if(str[0] === "(" && str.at(-1) === ")") + str = str.substring(1, str.length - 1) + if(str[0] !== "-" && forceSign) + str = "+" + str return str } } +/** + * Parses and executes the given expression + * @param {string} expr + * @return {number} + */ export function executeExpression(expr) { return (new Expression(expr.toString())).execute() } diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 92096e9..1ac6e58 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -19,7 +19,6 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" -import Canvas from "./canvas.mjs" import Settings from "./settings.mjs" import { DialogInterface, RootInterface } from "./interface.mjs" import { BaseEvent } from "../events.mjs" diff --git a/common/src/objs/common.mjs b/common/src/objs/common.mjs index 891fdd5..1534a9a 100644 --- a/common/src/objs/common.mjs +++ b/common/src/objs/common.mjs @@ -224,7 +224,7 @@ export class DrawableObject { currentObjectsByName[objName].requiredBy.push(this) } } - if(this[property].cached && this[property].requiredObjects().length > 0) + if(this[property].canBeCached && this[property].requiredObjects().length > 0) // Recalculate this[property].recache() diff --git a/common/test/basics/polyfill.mjs b/common/test/basics/polyfill.mjs index ce018f2..4c44514 100644 --- a/common/test/basics/polyfill.mjs +++ b/common/test/basics/polyfill.mjs @@ -35,50 +35,50 @@ import { } from "../../src/lib/expr-eval/polyfill.mjs" describe("Math/Polyfill", () => { - describe("#AADDDD", function() { - it("should add two numbers", function() { + describe("#add", function() { + it("adds two numbers", function() { expect(Polyfill.add(2, 3)).to.equal(5) expect(Polyfill.add("2", "3")).to.equal(5) }) }) describe("#sub", function() { - it("should subtract two numbers", function() { + it("subtracts two numbers", function() { expect(Polyfill.sub(2, 1)).to.equal(1) expect(Polyfill.sub("2", "1")).to.equal(1) }) }) describe("#mul", function() { - it("should multiply two numbers", function() { + it("multiplies two numbers", function() { expect(Polyfill.mul(2, 3)).to.equal(6) expect(Polyfill.mul("2", "3")).to.equal(6) }) }) describe("#div", function() { - it("should divide two numbers", function() { + it("divides two numbers", function() { expect(Polyfill.div(10, 2)).to.equal(5) expect(Polyfill.div("10", "2")).to.equal(5) }) }) describe("#mod", function() { - it("should return the modulo of two numbers", function() { + it("returns the modulo of two numbers", function() { expect(Polyfill.mod(10, 3)).to.equal(1) expect(Polyfill.mod("10", "3")).to.equal(1) }) }) describe("#concat", function() { - it("should return the concatenation of two strings", function() { + it("returns the concatenation of two strings", function() { expect(Polyfill.concat(10, 3)).to.equal("103") expect(Polyfill.concat("abc", "def")).to.equal("abcdef") }) }) describe("#equal", function() { - it("should return whether its two arguments are equal", function() { + it("returns whether its two arguments are equal", function() { expect(Polyfill.equal(10, 3)).to.be.false expect(Polyfill.equal(10, 10)).to.be.true expect(Polyfill.equal("abc", "def")).to.be.false @@ -87,7 +87,7 @@ describe("Math/Polyfill", () => { }) describe("#notEqual", function() { - it("should return whether its two arguments are not equal", function() { + it("returns whether its two arguments are not equal", function() { expect(Polyfill.notEqual(10, 3)).to.be.true expect(Polyfill.notEqual(10, 10)).to.be.false expect(Polyfill.notEqual("abc", "def")).to.be.true @@ -96,7 +96,7 @@ describe("Math/Polyfill", () => { }) describe("#greaterThan", function() { - it("should return whether its first argument is strictly greater than its second", function() { + it("returns whether its first argument is strictly greater than its second", function() { expect(Polyfill.greaterThan(10, 3)).to.be.true expect(Polyfill.greaterThan(10, 10)).to.be.false expect(Polyfill.greaterThan(10, 30)).to.be.false @@ -104,7 +104,7 @@ describe("Math/Polyfill", () => { }) describe("#lessThan", function() { - it("should return whether its first argument is strictly less than its second", function() { + it("returns whether its first argument is strictly less than its second", function() { expect(Polyfill.lessThan(10, 3)).to.be.false expect(Polyfill.lessThan(10, 10)).to.be.false expect(Polyfill.lessThan(10, 30)).to.be.true @@ -112,7 +112,7 @@ describe("Math/Polyfill", () => { }) describe("#greaterThanEqual", function() { - it("should return whether its first argument is greater or equal to its second", function() { + it("returns whether its first argument is greater or equal to its second", function() { expect(Polyfill.greaterThanEqual(10, 3)).to.be.true expect(Polyfill.greaterThanEqual(10, 10)).to.be.true expect(Polyfill.greaterThanEqual(10, 30)).to.be.false @@ -120,7 +120,7 @@ describe("Math/Polyfill", () => { }) describe("#lessThanEqual", function() { - it("should return whether its first argument is strictly less than its second", function() { + it("returns whether its first argument is strictly less than its second", function() { expect(Polyfill.lessThanEqual(10, 3)).to.be.false expect(Polyfill.lessThanEqual(10, 10)).to.be.true expect(Polyfill.lessThanEqual(10, 30)).to.be.true @@ -128,7 +128,7 @@ describe("Math/Polyfill", () => { }) describe("#andOperator", function() { - it("should return whether its arguments are both true", function() { + it("returns whether its arguments are both true", function() { expect(Polyfill.andOperator(true, true)).to.be.true expect(Polyfill.andOperator(true, false)).to.be.false expect(Polyfill.andOperator(false, true)).to.be.false @@ -140,7 +140,7 @@ describe("Math/Polyfill", () => { }) describe("#orOperator", function() { - it("should return whether one of its arguments is true", function() { + it("returns whether one of its arguments is true", function() { expect(Polyfill.orOperator(true, true)).to.be.true expect(Polyfill.orOperator(true, false)).to.be.true expect(Polyfill.orOperator(false, true)).to.be.true @@ -152,7 +152,7 @@ describe("Math/Polyfill", () => { }) describe("#inOperator", function() { - it("should check if second argument contains first", function() { + it("checks if second argument contains first", function() { expect(Polyfill.inOperator("a", ["a", "b", "c"])).to.be.true expect(Polyfill.inOperator(3, [0, 1, 2])).to.be.false expect(Polyfill.inOperator(3, [0, 1, 3, 2])).to.be.true @@ -181,14 +181,14 @@ describe("Math/Polyfill", () => { }) describe("#trunc", function() { - it("should return the decimal part of floats", function() { + it("returns the decimal part of floats", function() { for(let x = -10; x < 10; x += 0.1) expect(Polyfill.trunc(x)).to.equal(Math.trunc(x)) }) }) describe("#gamma", function() { - it("should return the product of factorial(x - 1)", function() { + it("returns the product of factorial(x - 1)", function() { expect(Polyfill.gamma(0)).to.equal(Infinity) expect(Polyfill.gamma(1)).to.equal(1) expect(Polyfill.gamma(2)).to.equal(1) @@ -204,7 +204,7 @@ describe("Math/Polyfill", () => { }) describe("#hypot", function() { - it("should return the hypothenus length of a triangle whose length are provided in arguments", function() { + it("returns the hypothenus length of a triangle whose length are provided in arguments", function() { for(let x = 0; x < 10; x += 0.3) { expect(Polyfill.hypot(x)).to.be.approximately(Math.hypot(x), Number.EPSILON) for(let y = 0; y < 10; y += 0.3) { @@ -224,7 +224,8 @@ describe("Math/Polyfill", () => { describe("#log1p, #log2", function() { for(let x = 1; x < 10; x += 0.3) { - expect(Polyfill.log1p(x)).to.be.approximately(Math.log1p(x), 1e-12) + expect(Polyfill.log1p(x)).to + .be.approximately(Math.log1p(x), 1e-12) expect(Polyfill.log2(x)).to.be.approximately(Math.log2(x), 1e-12) } }) diff --git a/common/test/math/expression.mjs b/common/test/math/expression.mjs new file mode 100644 index 0000000..a0ee113 --- /dev/null +++ b/common/test/math/expression.mjs @@ -0,0 +1,181 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Load prior tests +import "../basics/utils.mjs" +import "../module/latex.mjs" +import "../module/expreval.mjs" +import "../module/objects.mjs" + +import { describe, it } from "mocha" +import { expect } from "chai" + +import { executeExpression, Expression } from "../../src/math/expression.mjs" +import ExprEval from "../../src/module/expreval.mjs" + + +describe("Math/Expression", function() { + describe("#constructor", function() { + it("accepts strings", function() { + expect(() => new Expression("2+3")).to.not.throw + expect(() => new Expression("x+2")).to.not.throw + }) + + it("accepts already parsed expressions", function() { + expect(() => new Expression(ExprEval.parse("2+3"))).to.not.throw + expect(() => new Expression(ExprEval.parse("x+2"))).to.not.throw + }) + + it("doesn't accept anything else", function() { + expect(() => new Expression()).to.throw("Cannot create an expression with undefined.") + expect(() => new Expression(12)).to.throw("Cannot create an expression with a Number.") + expect(() => new Expression({})).to.throw("Cannot create an expression with a Object.") + expect(() => new Expression(true)).to.throw("Cannot create an expression with a Boolean.") + }) + }) + + describe("#variables", function() { + it("returns a list of variables for non-constant expressions", function() { + expect(new Expression("x+1").variables()).to.deep.equal(["x"]) + expect(new Expression("x+n").variables()).to.deep.equal(["x", "n"]) + expect(new Expression("u[n] + A.x").variables()).to.deep.equal(["u", "n", "A"]) + }) + + it("returns an empty array if the expression is constant", function() { + expect(new Expression("2+1").variables()).to.deep.equal([]) + expect(new Expression("sin π").variables()).to.deep.equal([]) + expect(new Expression("e^3").variables()).to.deep.equal([]) + }) + }) + + describe("#isConstant", function() { + it("returns true if neither x nor n are included into the expression", function() { + expect(new Expression("2+1").isConstant()).to.be.true + expect(new Expression("e^3").isConstant()).to.be.true + expect(new Expression("2+f(3)").isConstant()).to.be.true + expect(new Expression("sin A.x").isConstant()).to.be.true + }) + + it("returns false if either x or n are included into the expression", function() { + expect(new Expression("2+x").isConstant()).to.be.false + expect(new Expression("e^n").isConstant()).to.be.false + expect(new Expression("2+f(x)").isConstant()).to.be.false + expect(new Expression("n + sin x").isConstant()).to.be.false + }) + }) + + describe("#requiredObjects", function() { + it("returns the list of objects that need to be registered for this expression", function() { + expect(new Expression("x^n").requiredObjects()).to.deep.equal([]) + expect(new Expression("2+f(3)").requiredObjects()).to.deep.equal(["f"]) + expect(new Expression("A.x+x").requiredObjects()).to.deep.equal(["A"]) + expect(new Expression("2+f(sin A.x)+n").requiredObjects()).to.deep.equal(["f", "A"]) + }) + }) + + describe.skip("#allRequirementsFulfilled", function() { + // TODO: Make tests for objects + }) + + describe.skip("#undefinedVariables", function() { + // TODO: Make tests for objects + }) + + describe("#toEditableString", function() { + it("should return a readable expression", function() { + expect(new Expression("2+1").toEditableString()).to.equal("3") + expect(new Expression("2+x").toEditableString()).to.equal("(2 + x)") + expect(new Expression("x*2+x/3").toEditableString()).to.equal("((x * 2) + (x / 3))") + }) + + it("should be able to be reparsed and equal the same expression", function() { + const exprs = ["5", "x/2", "4/2", "sin x"] + for(const expr of exprs) { + const exprObj = new Expression(expr) + expect(new Expression(exprObj.toEditableString()).calc).to.deep.equal(exprObj.calc) + } + }) + }) + + describe("#execute", function() { + it("returns the result of the computation of the expression", function() { + expect(new Expression("2+3").execute()).to.equal(5) + expect(new Expression("2+3").execute(10)).to.equal(5) + expect(new Expression("2+x").execute(10)).to.equal(12) + expect(new Expression("sin x").execute(Math.PI)).to.be.approximately(0, Number.EPSILON) + }) + + it("returns the cached value if the expression can be cached", function() { + const exprs = ["2+3", "x/2", "4/2", "sin x"] + for(const expr of exprs) { + const exprObj = new Expression(expr) + if(exprObj.canBeCached) + expect(exprObj.execute()).to.equal(exprObj.cachedValue) + else + expect(exprObj.execute()).to.not.equal(exprObj.cachedValue) + } + }) + + it("throws an error if some variables are undefined.", function() { + expect(() => new Expression("x+n").execute()).to.throw("Undefined variable n.") + expect(() => new Expression("sin A.t").execute()).to.throw("Undefined variable A.") + expect(() => new Expression("f(3)").execute()).to.throw("Undefined variable f.") + }) + }) + + describe("#simplify", function() { + it("returns an expression with just the result when no constant or object are used", function() { + expect(new Expression("2+2").simplify(Math.PI/2)).to.deep.equal(new Expression("4")) + expect(new Expression("x+3").simplify(5)).to.deep.equal(new Expression("8")) + expect(new Expression("sin x").simplify(Math.PI/2)).to.deep.equal(new Expression("1")) + expect(new Expression("0*e^x").simplify(Math.PI/2)).to.deep.equal(new Expression("0")) + }) + + it("returns a simplified version of the expression if constants are used", function() { + const original = new Expression("e^x").simplify(2) + const to = new Expression("e^2") + expect(original.toEditableString()).to.deep.equal(to.toEditableString()) + }) + }) + + describe("#toString", function() { + it("returns a human readable string of the expression", function() { + expect(new Expression("-2-3").toString()).to.equal("-5") + expect(new Expression("0.2+0.1").toString()).to.equal("0.3") + expect(new Expression("sin x").toString()).to.equal("sin x") + expect(new Expression("sin π").toString()).to.equal("sin π") + }) + + it("should add a sign if the option is passed", function() { + expect(new Expression("-2-3").toString(true)).to.equal("-5") + expect(new Expression("2+3").toString(true)).to.equal("+5") + }) + }) + + describe("#executeExpression", function() { + it("directly computes the result of the expression with no variable", function() { + expect(executeExpression("2+3")).to.equal(5) + expect(executeExpression("sin (π/2)")).to.equal(1) + expect(executeExpression("e^3")).to.be.approximately(Math.pow(Math.E, 3), Number.EPSILON) + }) + + it("throws an error if variables are employed", function() { + expect(() => executeExpression("x+n")).to.throw("Undefined variable n.") + }) + }) +}) \ No newline at end of file diff --git a/common/test/mock/qt.mjs b/common/test/mock/qt.mjs index 50ec349..58ceae0 100644 --- a/common/test/mock/qt.mjs +++ b/common/test/mock/qt.mjs @@ -40,6 +40,17 @@ function QT_TRANSLATE_NOOP(category, string) { return string } +/** + * Polyfilling Qt arg function. + * @param {string} argument + */ +String.prototype.arg = function(argument) { + for(let i = 0; i < 10; i++) + if(this.includes("%"+i)) + return this.replaceAll("%" + i, argument) + throw new Error("Too many arguments used.") +} + function setup() { globalThis.Qt = { rect @@ -47,8 +58,6 @@ function setup() { globalThis.QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP globalThis.qsTranslate = QT_TRANSLATE_NOOP - - String.prototype.arg = function() { return this; } // No need to reimplement it for now. } setup() diff --git a/common/test/module/latex.mjs b/common/test/module/latex.mjs index 02aaca5..e038e63 100644 --- a/common/test/module/latex.mjs +++ b/common/test/module/latex.mjs @@ -48,7 +48,7 @@ describe("Module/Latex", function() { }) describe("#requestAsyncRender", function() { - it("should return a render result with a valid source, a width, and a height", async function() { + it("returns a render result with a valid source, a width, and a height", async function() { const data = await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") expect(data).to.be.an("object") expect(data.source).to.be.a("string") @@ -57,7 +57,7 @@ describe("Module/Latex", function() { expect(data.width).to.be.a("number") }) - it("should call functions from the LaTeX module", async function() { + it("calls functions from the LaTeX module", async function() { const renderSyncSpy = spy.on(Latex, "renderSync") const renderAsyncSpy = spy.on(Latex, "renderAsync") Latex.supportsAsyncRender = true @@ -84,7 +84,7 @@ describe("Module/Latex", function() { }) describe("#findPrerendered", function() { - it("should return the same data as async render for the same markup, font size, and color", async function() { + it("returns the same data as async render for the same markup, font size, and color", async function() { const data = await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") const found = LatexAPI.findPrerendered("\\frac{x}{3}", 13, "#AA0033") expect(found).to.not.be.null @@ -92,7 +92,7 @@ describe("Module/Latex", function() { expect(found.width).to.equal(data.width) }) - it("should return null if the markup hasn't been prerendered with the same markup, font size, and color", async function() { + it("returns null if the markup hasn't been prerendered with the same markup, font size, and color", async function() { await LatexAPI.requestAsyncRender("\\frac{x}{3}", 13, "#AA0033") expect(LatexAPI.findPrerendered("\\frac{y}{3}", 13, "#AA0033")).to.be.null expect(LatexAPI.findPrerendered("\\frac{x}{3}", 12, "#AA0033")).to.be.null @@ -101,7 +101,7 @@ describe("Module/Latex", function() { }) describe("#par", function() { - it("should add parentheses to strings", function() { + it("adds parentheses to strings", function() { expect(LatexAPI.par("string")).to.equal("(string)") expect(LatexAPI.par("aaaa")).to.equal("(aaaa)") expect(LatexAPI.par("")).to.equal("()") @@ -110,14 +110,14 @@ describe("Module/Latex", function() { }) describe("#parif", function() { - it("should add parentheses to strings that contain one of the ones in the list", function() { + it("adds parentheses to strings that contain one of the ones in the list", function() { expect(LatexAPI.parif("string", ["+"])).to.equal("string") expect(LatexAPI.parif("string+assert", ["+"])).to.equal("(string+assert)") expect(LatexAPI.parif("string+assert", ["+", "-"])).to.equal("(string+assert)") expect(LatexAPI.parif("string-assert", ["+", "-"])).to.equal("(string-assert)") }) - it("shouldn't add new parentheses to strings that contains one of the ones in the list if they already have one", function() { + it("doesn't add new parentheses to strings that contains one of the ones in the list if they already have one", function() { expect(LatexAPI.parif("(string+assert", ["+"])).to.equal("((string+assert)") expect(LatexAPI.parif("string+assert)", ["+"])).to.equal("(string+assert))") expect(LatexAPI.parif("(string+assert)", ["+"])).to.equal("(string+assert)") @@ -125,14 +125,14 @@ describe("Module/Latex", function() { expect(LatexAPI.parif("(string-assert)", ["+", "-"])).to.equal("(string-assert)") }) - it("shouldn't add parentheses to strings that does not contains one of the ones in the list", function() { + it("doesn't add parentheses to strings that does not contains one of the ones in the list", function() { expect(LatexAPI.parif("string", ["+"])).to.equal("string") expect(LatexAPI.parif("string+assert", ["-"])).to.equal("string+assert") expect(LatexAPI.parif("(string*assert", ["+", "-"])).to.equal("(string*assert") expect(LatexAPI.parif("string/assert)", ["+", "-"])).to.equal("string/assert)") }) - it("should remove parentheses from strings that does not contains one of the ones in the list", function() { + it("removes parentheses from strings that does not contains one of the ones in the list", function() { expect(LatexAPI.parif("(string)", ["+"])).to.equal("string") expect(LatexAPI.parif("(string+assert)", ["-"])).to.equal("string+assert") expect(LatexAPI.parif("((string*assert)", ["+", "-"])).to.equal("(string*assert") @@ -164,47 +164,47 @@ describe("Module/Latex", function() { "{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}", "\\pi", "\\infty"] - it("should convert unicode characters to their latex equivalent", function() { + it("converts unicode characters to their latex equivalent", function() { for(let i = 0; i < from.length; i++) expect(LatexAPI.variable(from[i])).to.include(to[i]) }) - it("should wrap within dollar signs when the option is included", function() { + it("wraps within dollar signs when the option is included", function() { for(let i = 0; i < from.length; i++) { expect(LatexAPI.variable(from[i], false)).to.equal(to[i]) expect(LatexAPI.variable(from[i], true)).to.equal(`$${to[i]}$`) } }) - it("should be able to convert multiple of them", function() { + it("can convert multiple of them", function() { expect(LatexAPI.variable("α₂", false)).to.equal("\\alpha{}_{2}") expect(LatexAPI.variable("∞piΠ", false)).to.equal("\\infty\\pi\\Pi") }) }) describe("#functionToLatex", function() { - it("should transform derivatives into latex fractions", function() { + it("transforms derivatives into latex fractions", function() { const d1 = LatexAPI.functionToLatex("derivative", ["'3t'", "'t'", "x+2"]) const d2 = LatexAPI.functionToLatex("derivative", ["f", "x+2"]) expect(d1).to.equal("\\frac{d3x}{dx}") expect(d2).to.equal("\\frac{df}{dx}(x+2)") }) - it("should transform integrals into latex limits", function() { + it("transforms integrals into latex limits", function() { const i1 = LatexAPI.functionToLatex("integral", ["0", "x", "'3y'", "'y'"]) const i2 = LatexAPI.functionToLatex("integral", ["1", "2", "f"]) expect(i1).to.equal("\\int\\limits_{0}^{x}3y dy") expect(i2).to.equal("\\int\\limits_{1}^{2}f(t) dt") }) - it("should transform sqrt functions to sqrt latex", function() { + it("transforms sqrt functions to sqrt latex", function() { const sqrt1 = LatexAPI.functionToLatex("sqrt", ["(x+2)"]) const sqrt2 = LatexAPI.functionToLatex("sqrt", ["\\frac{x}{2}"]) expect(sqrt1).to.equal("\\sqrt{x+2}") expect(sqrt2).to.equal("\\sqrt{\\frac{x}{2}}") }) - it("should transform abs, floor and ceil", function() { + it("transforms abs, floor and ceil", function() { const abs = LatexAPI.functionToLatex("abs", ["x+3"]) const floor = LatexAPI.functionToLatex("floor", ["x+3"]) const ceil = LatexAPI.functionToLatex("ceil", ["x+3"]) @@ -213,7 +213,7 @@ describe("Module/Latex", function() { expect(ceil).to.equal("\\left\\lceil{x+3}\\right\\rceil") }) - it("should transform regular functions into latex", function() { + it("transforms regular functions into latex", function() { const f1 = LatexAPI.functionToLatex("f", ["x+3", true]) const f2 = LatexAPI.functionToLatex("h_1", ["10"]) expect(f1).to.equal("\\mathrm{f}\\left(x+3, true\\right)") @@ -222,7 +222,7 @@ describe("Module/Latex", function() { }) describe("#expression", function() { - it("should transform parsed expressions", function() { + it("transforms parsed expressions", function() { const expr = ExprEval.parse("(+1! == 2/2 ? sin [-2.2][0] : f(t)^(1+1-1) + sqrt(A.t)) * 3 % 1") const expected = "((((+1!))==(\\frac{2}{2}) ? (\\mathrm{sin}\\left(([(-2.2)][0])\\right)) : (\\mathrm{f}\\left(t\\right)^{1+1-1}+\\sqrt{A.t})) \\times 3) \\mathrm{mod} 1" expect(LatexAPI.expression(expr.tokens)).to.equal(expected) diff --git a/common/test/module/objects.mjs b/common/test/module/objects.mjs index 4665232..d598097 100644 --- a/common/test/module/objects.mjs +++ b/common/test/module/objects.mjs @@ -26,5 +26,6 @@ import { expect } from "chai" // import Objects from "../../src/module/objects.mjs" // // describe("Module/Objects", function() { -// +// describe("#getNewName", function() { +// }) // }) \ No newline at end of file From c39498c60fdb5a5ecebc48819397c0387749d088 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 05:55:34 +0200 Subject: [PATCH 222/249] Finally got rid of the camelCase2Readable Utils function. --- .../definitionDomain.svg} | 0 .../destinationDomain.svg} | 0 assets/icons/properties/displayMode.svg | 1 + assets/icons/properties/displayStyle.svg | 1 + .../Expression.svg => properties/expression.svg} | 0 .../custom/Gain.svg => properties/gain.svg} | 0 assets/icons/properties/labelPosition.svg | 1 + assets/icons/properties/labelX.svg | 1 + assets/icons/properties/om_0.svg | 1 + .../custom/Pass.svg => properties/pass.svg} | 0 assets/icons/properties/phase.svg | 1 + assets/icons/properties/pointStyle.svg | 1 + .../custom/Rounding.svg => properties/rounding.svg} | 0 assets/icons/properties/targetElement.svg | 1 + assets/icons/properties/targetValuePosition.svg | 1 + assets/icons/properties/text.svg | 1 + assets/icons/properties/unit.svg | 1 + assets/icons/properties/x.svg | 1 + assets/icons/properties/y.svg | 1 + assets/icons/settings/custom/Display Mode.svg | 1 - assets/icons/settings/custom/Display Style.svg | 1 - assets/icons/settings/custom/Label Position.svg | 1 - assets/icons/settings/custom/Label X.svg | 1 - assets/icons/settings/custom/Phase.svg | 1 - assets/icons/settings/custom/Point Style.svg | 1 - assets/icons/settings/custom/Target Element.svg | 1 - .../icons/settings/custom/Target Value Position.svg | 1 - assets/icons/settings/custom/Text.svg | 1 - assets/icons/settings/custom/Unit.svg | 1 - assets/icons/settings/custom/X.svg | 1 - assets/icons/settings/custom/Y.svg | 1 - assets/icons/settings/custom/ω_0.svg | 1 - common/src/utils.mjs | 12 ------------ runtime-pyside6/LogarithmPlotter/logarithmplotter.py | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 12 ++++++------ 35 files changed, 20 insertions(+), 32 deletions(-) rename assets/icons/{settings/custom/Definition Domain.svg => properties/definitionDomain.svg} (100%) rename assets/icons/{settings/custom/Destination Domain.svg => properties/destinationDomain.svg} (100%) create mode 120000 assets/icons/properties/displayMode.svg create mode 120000 assets/icons/properties/displayStyle.svg rename assets/icons/{settings/custom/Expression.svg => properties/expression.svg} (100%) rename assets/icons/{settings/custom/Gain.svg => properties/gain.svg} (100%) create mode 120000 assets/icons/properties/labelPosition.svg create mode 120000 assets/icons/properties/labelX.svg create mode 120000 assets/icons/properties/om_0.svg rename assets/icons/{settings/custom/Pass.svg => properties/pass.svg} (100%) create mode 120000 assets/icons/properties/phase.svg create mode 120000 assets/icons/properties/pointStyle.svg rename assets/icons/{settings/custom/Rounding.svg => properties/rounding.svg} (100%) create mode 120000 assets/icons/properties/targetElement.svg create mode 120000 assets/icons/properties/targetValuePosition.svg create mode 120000 assets/icons/properties/text.svg create mode 120000 assets/icons/properties/unit.svg create mode 120000 assets/icons/properties/x.svg create mode 120000 assets/icons/properties/y.svg delete mode 120000 assets/icons/settings/custom/Display Mode.svg delete mode 120000 assets/icons/settings/custom/Display Style.svg delete mode 120000 assets/icons/settings/custom/Label Position.svg delete mode 120000 assets/icons/settings/custom/Label X.svg delete mode 120000 assets/icons/settings/custom/Phase.svg delete mode 120000 assets/icons/settings/custom/Point Style.svg delete mode 120000 assets/icons/settings/custom/Target Element.svg delete mode 120000 assets/icons/settings/custom/Target Value Position.svg delete mode 120000 assets/icons/settings/custom/Text.svg delete mode 120000 assets/icons/settings/custom/Unit.svg delete mode 120000 assets/icons/settings/custom/X.svg delete mode 120000 assets/icons/settings/custom/Y.svg delete mode 120000 assets/icons/settings/custom/ω_0.svg diff --git a/assets/icons/settings/custom/Definition Domain.svg b/assets/icons/properties/definitionDomain.svg similarity index 100% rename from assets/icons/settings/custom/Definition Domain.svg rename to assets/icons/properties/definitionDomain.svg diff --git a/assets/icons/settings/custom/Destination Domain.svg b/assets/icons/properties/destinationDomain.svg similarity index 100% rename from assets/icons/settings/custom/Destination Domain.svg rename to assets/icons/properties/destinationDomain.svg diff --git a/assets/icons/properties/displayMode.svg b/assets/icons/properties/displayMode.svg new file mode 120000 index 0000000..41b711b --- /dev/null +++ b/assets/icons/properties/displayMode.svg @@ -0,0 +1 @@ +../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/displayStyle.svg b/assets/icons/properties/displayStyle.svg new file mode 120000 index 0000000..41b711b --- /dev/null +++ b/assets/icons/properties/displayStyle.svg @@ -0,0 +1 @@ +../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Expression.svg b/assets/icons/properties/expression.svg similarity index 100% rename from assets/icons/settings/custom/Expression.svg rename to assets/icons/properties/expression.svg diff --git a/assets/icons/settings/custom/Gain.svg b/assets/icons/properties/gain.svg similarity index 100% rename from assets/icons/settings/custom/Gain.svg rename to assets/icons/properties/gain.svg diff --git a/assets/icons/properties/labelPosition.svg b/assets/icons/properties/labelPosition.svg new file mode 120000 index 0000000..3e4c849 --- /dev/null +++ b/assets/icons/properties/labelPosition.svg @@ -0,0 +1 @@ +../common/arrow.svg \ No newline at end of file diff --git a/assets/icons/properties/labelX.svg b/assets/icons/properties/labelX.svg new file mode 120000 index 0000000..4eecad3 --- /dev/null +++ b/assets/icons/properties/labelX.svg @@ -0,0 +1 @@ +../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/om_0.svg b/assets/icons/properties/om_0.svg new file mode 120000 index 0000000..e4130be --- /dev/null +++ b/assets/icons/properties/om_0.svg @@ -0,0 +1 @@ +../common/angle.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Pass.svg b/assets/icons/properties/pass.svg similarity index 100% rename from assets/icons/settings/custom/Pass.svg rename to assets/icons/properties/pass.svg diff --git a/assets/icons/properties/phase.svg b/assets/icons/properties/phase.svg new file mode 120000 index 0000000..e4130be --- /dev/null +++ b/assets/icons/properties/phase.svg @@ -0,0 +1 @@ +../common/angle.svg \ No newline at end of file diff --git a/assets/icons/properties/pointStyle.svg b/assets/icons/properties/pointStyle.svg new file mode 120000 index 0000000..41b711b --- /dev/null +++ b/assets/icons/properties/pointStyle.svg @@ -0,0 +1 @@ +../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Rounding.svg b/assets/icons/properties/rounding.svg similarity index 100% rename from assets/icons/settings/custom/Rounding.svg rename to assets/icons/properties/rounding.svg diff --git a/assets/icons/properties/targetElement.svg b/assets/icons/properties/targetElement.svg new file mode 120000 index 0000000..659962b --- /dev/null +++ b/assets/icons/properties/targetElement.svg @@ -0,0 +1 @@ +../common/target.svg \ No newline at end of file diff --git a/assets/icons/properties/targetValuePosition.svg b/assets/icons/properties/targetValuePosition.svg new file mode 120000 index 0000000..4eecad3 --- /dev/null +++ b/assets/icons/properties/targetValuePosition.svg @@ -0,0 +1 @@ +../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/text.svg b/assets/icons/properties/text.svg new file mode 120000 index 0000000..280f9ad --- /dev/null +++ b/assets/icons/properties/text.svg @@ -0,0 +1 @@ +../common/label.svg \ No newline at end of file diff --git a/assets/icons/properties/unit.svg b/assets/icons/properties/unit.svg new file mode 120000 index 0000000..e4130be --- /dev/null +++ b/assets/icons/properties/unit.svg @@ -0,0 +1 @@ +../common/angle.svg \ No newline at end of file diff --git a/assets/icons/properties/x.svg b/assets/icons/properties/x.svg new file mode 120000 index 0000000..4eecad3 --- /dev/null +++ b/assets/icons/properties/x.svg @@ -0,0 +1 @@ +../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/y.svg b/assets/icons/properties/y.svg new file mode 120000 index 0000000..4eecad3 --- /dev/null +++ b/assets/icons/properties/y.svg @@ -0,0 +1 @@ +../common/position.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Display Mode.svg b/assets/icons/settings/custom/Display Mode.svg deleted file mode 120000 index 7a5ba45..0000000 --- a/assets/icons/settings/custom/Display Mode.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Display Style.svg b/assets/icons/settings/custom/Display Style.svg deleted file mode 120000 index 7a5ba45..0000000 --- a/assets/icons/settings/custom/Display Style.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Label Position.svg b/assets/icons/settings/custom/Label Position.svg deleted file mode 120000 index 43aa15f..0000000 --- a/assets/icons/settings/custom/Label Position.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/arrow.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Label X.svg b/assets/icons/settings/custom/Label X.svg deleted file mode 120000 index 6b40925..0000000 --- a/assets/icons/settings/custom/Label X.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/position.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Phase.svg b/assets/icons/settings/custom/Phase.svg deleted file mode 120000 index 21699e9..0000000 --- a/assets/icons/settings/custom/Phase.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/angle.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Point Style.svg b/assets/icons/settings/custom/Point Style.svg deleted file mode 120000 index 7a5ba45..0000000 --- a/assets/icons/settings/custom/Point Style.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Target Element.svg b/assets/icons/settings/custom/Target Element.svg deleted file mode 120000 index 50124dc..0000000 --- a/assets/icons/settings/custom/Target Element.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/target.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Target Value Position.svg b/assets/icons/settings/custom/Target Value Position.svg deleted file mode 120000 index 6b40925..0000000 --- a/assets/icons/settings/custom/Target Value Position.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/position.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Text.svg b/assets/icons/settings/custom/Text.svg deleted file mode 120000 index 69be9e1..0000000 --- a/assets/icons/settings/custom/Text.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/label.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Unit.svg b/assets/icons/settings/custom/Unit.svg deleted file mode 120000 index 21699e9..0000000 --- a/assets/icons/settings/custom/Unit.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/angle.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/X.svg b/assets/icons/settings/custom/X.svg deleted file mode 120000 index 6b40925..0000000 --- a/assets/icons/settings/custom/X.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/position.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/Y.svg b/assets/icons/settings/custom/Y.svg deleted file mode 120000 index 6b40925..0000000 --- a/assets/icons/settings/custom/Y.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/position.svg \ No newline at end of file diff --git a/assets/icons/settings/custom/ω_0.svg b/assets/icons/settings/custom/ω_0.svg deleted file mode 120000 index 21699e9..0000000 --- a/assets/icons/settings/custom/ω_0.svg +++ /dev/null @@ -1 +0,0 @@ -../../common/angle.svg \ No newline at end of file diff --git a/common/src/utils.mjs b/common/src/utils.mjs index 0e451f4..5c51f62 100644 --- a/common/src/utils.mjs +++ b/common/src/utils.mjs @@ -401,18 +401,6 @@ export function parseName(str, removeUnallowed = true) { return str } -/** - * Transforms camel case strings to a space separated one. - * - * @deprecated - * @param {string} label - Camel case to parse - * @returns {string} Parsed label. - */ -export function camelCase2readable(label) { - let parsed = parseName(label, false) - return parsed.charAt(0).toLatinUppercase() + parsed.slice(1).replace(/([A-Z])/g, " $1") -} - /** * Creates a randomized color string. * @returns {string} diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index 115083a..c4c16b9 100644 --- a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py +++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py @@ -104,7 +104,7 @@ def get_platform_qt_style(os) -> str: def register_icon_directories() -> None: icon_fallbacks = QIcon.fallbackSearchPaths() base_icon_path = path.join(logarithmplotter_path, "qml", "eu", "ad5001", "LogarithmPlotter", "icons") - paths = [["common"], ["objects"], ["history"], ["settings"], ["settings", "custom"]] + paths = [["common"], ["objects"], ["history"], ["settings"], ["properties"]] for p in paths: icon_fallbacks.append(path.realpath(path.join(base_icon_path, *p))) QIcon.setFallbackSearchPaths(icon_fallbacks) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 1ca75e4..49cea8e 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -74,7 +74,7 @@ Repeater { Setting.ExpressionEditor { height: 30 label: propertyLabel - icon: `settings/custom/${propertyIcon}.svg` + icon: `properties/${propertyIcon}.svg` defValue: JS.Utils.simplifyExpression(obj[propertyName].toEditableString()) self: obj.name variables: propertyType.variables @@ -99,7 +99,7 @@ Repeater { Setting.TextSetting { height: 30 label: propertyLabel - icon: `settings/custom/${propertyIcon}.svg` + icon: `properties/${propertyIcon}.svg` min: propertyType == "int" ? 0 : -Infinity isInt: propertyType == "int" isDouble: propertyType == "number" @@ -159,7 +159,7 @@ Repeater { CheckBox { height: 20 text: propertyLabel - //icon: `settings/custom/${propertyIcon}.svg` + //icon: `properties/${propertyIcon}.svg` checked: { //if(obj[propertyName] == null) { @@ -185,7 +185,7 @@ Repeater { Setting.ComboBoxSetting { height: 30 label: propertyLabel - icon: `settings/custom/${propertyIcon}.svg` + icon: `properties/${propertyIcon}.svg` // True to select an object of type, false for enums. property bool selectObjMode: paramTypeIn(propertyType, ['ObjectType']) property bool isRealObject: !selectObjMode || (propertyType.objType != "ExecutableObject" && propertyType.objType != "DrawableObject") @@ -246,7 +246,7 @@ Repeater { Setting.ListSetting { label: propertyLabel - //icon: `settings/custom/${propertyIcon}.svg` + //icon: `properties/${propertyIcon}.svg` dictionaryMode: paramTypeIn(propertyType, ['Dict']) keyType: dictionaryMode ? propertyType.keyType : 'string' valueType: propertyType.valueType @@ -283,7 +283,7 @@ Repeater { property string propertyName: modelData[0] property var propertyType: modelData[1] property string propertyLabel: qsTranslate('prop',propertyName) - property string propertyIcon: JS.Utils.camelCase2readable(propertyName) + property string propertyIcon: propertyName sourceComponent: { if(propertyName.startsWith('comment')) From 90f4691c54e936e33e9690716d04e7c13ae1ee6f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 22:44:18 +0200 Subject: [PATCH 223/249] Updating icons to comply with KDE HIG. --- assets/logarithmplotter.svg | 187 ++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 40 deletions(-) diff --git a/assets/logarithmplotter.svg b/assets/logarithmplotter.svg index 77a2817..1f3a5e0 100644 --- a/assets/logarithmplotter.svg +++ b/assets/logarithmplotter.svg @@ -1,64 +1,171 @@ + + LogarithmPlotter Icon v1.0image/svg+xmlLogarithmPlotter Icon v1.02021Ad5001(c) Ad5001 2021 - All rights reserved + LogarithmPlotter Icon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + d="m 18,3.5 c 0,7 -4,12 -13,12" /> + + + + + LogarithmPlotter Icon + 2024-10-06 + + + Adsooi <mail@ad5001.eu> + + + + + (c) Adsooi 2021-2024 + + + + + + + + + + + + + + + + From 5d0542ffcc4f8ea102b60a68f46ee06633357f0f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 22:46:22 +0200 Subject: [PATCH 224/249] Ensuring app icons are white. --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index f4e2f35..87dd625 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -41,6 +41,7 @@ MenuBar { shortcut: StandardKey.Open onTriggered: settings.load() icon.name: 'document-open' + icon.color: sysPalette.windowText } Action { @@ -48,13 +49,14 @@ MenuBar { shortcut: StandardKey.Save onTriggered: settings.save() icon.name: 'document-save' + icon.color: sysPalette.windowText } Action { text: qsTr("Save &As...") shortcut: StandardKey.SaveAs onTriggered: settings.saveAs() - icon.name: 'document-save-as' - + icon.color: sysPalette.windowText + icon.name: 'document-save-as' } MenuSeparator { } Action { @@ -68,6 +70,7 @@ MenuBar { } icon.name: 'application-exit' + icon.color: sysPalette.windowText } } @@ -92,6 +95,7 @@ MenuBar { shortcut: StandardKey.Copy onTriggered: root.copyDiagramToClipboard() icon.name: 'edit-copy' + icon.color: sysPalette.windowText } MenuSeparator { } Action { @@ -99,6 +103,7 @@ MenuBar { shortcut: StandardKey.Copy onTriggered: preferences.open() icon.name: 'settings' + icon.color: sysPalette.windowText } } @@ -129,38 +134,45 @@ MenuBar { Action { text: qsTr("&Source code") icon.name: 'software-sources' + icon.color: sysPalette.windowText onTriggered: Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter") } Action { text: qsTr("&Report a bug") icon.name: 'tools-report-bug' + icon.color: sysPalette.windowText onTriggered: Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues") } Action { text: qsTr("&User manual") icon.name: 'documentation' + icon.color: sysPalette.windowText onTriggered: Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_Sidebar") } Action { text: qsTr("&Changelog") icon.name: 'state-information' + icon.color: sysPalette.windowText onTriggered: changelog.open() } Action { text: qsTr("&Help translating!") - icon.name: 'translator' + icon.name: 'translate' + icon.color: sysPalette.windowText onTriggered: Qt.openUrlExternally("https://hosted.weblate.org/engage/logarithmplotter/") } MenuSeparator { } Action { text: qsTr("&Thanks") - icon.name: 'about' + icon.name: 'help-about' + icon.color: sysPalette.windowText onTriggered: thanksTo.open() } Action { text: qsTr("&About") shortcut: StandardKey.HelpContents - icon.name: 'about' + icon.name: 'help-about' + icon.color: sysPalette.windowText onTriggered: about.open() } } From 8da10497d232c38bcf0805308028c19449530f50 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 22:46:41 +0200 Subject: [PATCH 225/249] Adding different revisions for different debian packages depending on their dependencies --- scripts/package-deb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh index eea10ba..e01c370 100755 --- a/scripts/package-deb.sh +++ b/scripts/package-deb.sh @@ -30,7 +30,7 @@ cp ../../README.md . python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \ --suite noble --depends3 "$(cat assets/native/linux/debian/depends.wheels)" --section science \ - bdist_deb + --debian-version +wheels-1 bdist_deb mv deb_dist deb_dist.noble @@ -38,6 +38,6 @@ mv deb_dist deb_dist.noble python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \ --suite oracular --depends3 "$(cat assets/native/linux/debian/depends.packaged)" --section science \ - bdist_deb + --debian-version +packaged-1 bdist_deb mv deb_dist deb_dist.oracular From f52ee65c56ad243877a7ea41a33fbba45d4a18ad Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 26 Oct 2024 23:37:20 +0200 Subject: [PATCH 226/249] Improving stability of Function drawing. --- common/src/objs/function.mjs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/common/src/objs/function.mjs b/common/src/objs/function.mjs index 1e345cb..b056cc3 100644 --- a/common/src/objs/function.mjs +++ b/common/src/objs/function.mjs @@ -122,7 +122,9 @@ export default class Function extends ExecutableObject { */ static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { let pxprecision = 10 - let previousX = canvas.px2x(0) + const startDrawFrom = canvas.x2px(1)%pxprecision-pxprecision + let previousX = canvas.px2x(startDrawFrom) + // console.log("Starting draw from", previousX, startDrawFrom, canvas.x2px(1)) let previousY = null if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) { // Point based functions. @@ -160,7 +162,7 @@ export default class Function extends ExecutableObject { // Calculate the previousY at the start of the canvas if(definitionDomain.includes(previousX)) previousY = expr.execute(previousX) - for(let px = pxprecision; px < canvas.width; px += pxprecision) { + for(let px = pxprecision; px-pxprecision < canvas.width; px += pxprecision) { let currentX = canvas.px2x(px) if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { // Should draw up to currentX, but NOT at previousX. @@ -169,7 +171,7 @@ export default class Function extends ExecutableObject { do { tmpPx++ previousX = canvas.px2x(tmpPx) - } while(!definitionDomain.includes(previousX)) + } while(!definitionDomain.includes(previousX) && currentX > previousX) // Recaclulate previousY previousY = expr.execute(previousX) } else if(!definitionDomain.includes(currentX)) { @@ -179,7 +181,7 @@ export default class Function extends ExecutableObject { do { tmpPx-- currentX = canvas.px2x(tmpPx) - } while(!definitionDomain.includes(currentX) && currentX !== previousX) + } while(!definitionDomain.includes(currentX) && currentX > previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) let maxvariation = (canvas.px2y(0) - canvas.px2y(canvas.height)) From e6de739d0cce9ed202f4b6e82445591aa8184149 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 27 Oct 2024 00:45:04 +0200 Subject: [PATCH 227/249] Rewirring paths to improve import names and such. --- common/rollup.config.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Common/qmldir | 3 +++ .../{HistoryBrowser.qml => Browser.qml} | 6 +++--- .../{HistoryItem.qml => SingleItem.qml} | 2 +- .../eu/ad5001/LogarithmPlotter/History/qmldir | 4 ++-- .../LogarithmPlotter/LogarithmPlotter.qml | 21 ++++++++++++------- .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../ObjectLists/Editor/Dialog.qml | 3 +-- .../ObjectLists/ObjectCreationGrid.qml | 2 +- .../ObjectLists/ObjectRow.qml | 2 +- .../LogarithmPlotter/Overlay/Loading.qml | 19 +++++++++++++++++ .../PickLocation.qml} | 19 +++++++---------- .../ViewPositionChange.qml} | 2 +- .../eu/ad5001/LogarithmPlotter/Overlay/qmldir | 4 ++++ .../LogarithmPlotter/Popup/Preferences.qml | 2 +- .../Setting/ExpressionEditor.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/qmldir | 2 -- .../LogarithmPlotter/util/latex.py | 1 - .../LogarithmPlotter/util/promise.py | 2 ++ scripts/build.sh | 20 +++++++++++------- 22 files changed, 79 insertions(+), 45 deletions(-) create mode 100644 runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir rename runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/{HistoryBrowser.qml => Browser.qml} (98%) rename runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/{HistoryItem.qml => SingleItem.qml} (99%) create mode 100644 runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml rename runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/{PickLocationOverlay.qml => Overlay/PickLocation.qml} (97%) rename runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/{ViewPositionChangeOverlay.qml => Overlay/ViewPositionChange.qml} (99%) create mode 100644 runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir diff --git a/common/rollup.config.mjs b/common/rollup.config.mjs index 6a18a41..6156873 100644 --- a/common/rollup.config.mjs +++ b/common/rollup.config.mjs @@ -22,7 +22,7 @@ import { babel } from "@rollup/plugin-babel" import cleanup from "rollup-plugin-cleanup" const src = "./src/index.mjs" -const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs" +const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/index.mjs" export default { input: src, diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 87dd625..79fa6b0 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -20,7 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import "js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir new file mode 100644 index 0000000..af9eb16 --- /dev/null +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir @@ -0,0 +1,3 @@ +module eu.ad5001.LogarithmPlotter.Common + +JS 1.0 index.mjs diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml similarity index 98% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml index eb84340..645916c 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml @@ -24,7 +24,7 @@ import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! - \qmltype HistoryBrowser + \qmltype Browser \inqmlmodule eu.ad5001.LogarithmPlotter.History \brief Tab of the drawer that allows to navigate through the undo and redo history. @@ -95,7 +95,7 @@ Item { Repeater { model: historyBrowser.redoCount - HistoryItem { + SingleItem { id: redoButton width: historyBrowser.actionWidth //height: actionHeight @@ -147,7 +147,7 @@ Item { model: historyBrowser.undoCount - HistoryItem { + SingleItem { id: undoButton width: historyBrowser.actionWidth //height: actionHeight diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml similarity index 99% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml index 6ad6556..bffdb9b 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml @@ -22,7 +22,7 @@ import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! - \qmltype HistoryItem + \qmltype SingleItem \inqmlmodule eu.ad5001.LogarithmPlotter.History \brief Item representing an history action. diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir index 7f8a628..66c4408 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir @@ -1,4 +1,4 @@ module eu.ad5001.LogarithmPlotter.History -HistoryBrowser 1.0 HistoryBrowser.qml -HistoryItem 1.0 HistoryItem.qml +Browser 1.0 Browser.qml +SingleItem 1.0 SingleItem.qml diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index d541a0c..b8799de 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,10 +23,11 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common -import eu.ad5001.LogarithmPlotter.History 1.0 +import eu.ad5001.LogarithmPlotter.History 1.0 as History import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 +import eu.ad5001.LogarithmPlotter.Overlay 1.0 as Overlay import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup /*! @@ -120,16 +121,16 @@ ApplicationWindow { ObjectLists { id: objectLists - onChanged: drawCanvas.requestPaint() + onChanged: Modules.Canvas.requestPaint() } Settings { id: settings canvas: drawCanvas - onChanged: drawCanvas.requestPaint() + onChanged: Modules.Canvas.requestPaint() } - HistoryBrowser { + History.Browser { id: historyBrowser } } @@ -154,18 +155,24 @@ ApplicationWindow { } } - ViewPositionChangeOverlay { + Overlay.ViewPositionChange { id: viewPositionChanger anchors.fill: parent canvas: parent settingsInstance: settings } - PickLocationOverlay { + Overlay.PickLocation { id: positionPicker anchors.fill: parent canvas: parent } + + // Overlay.Loading { + // id: loadingOverlay + // anchors.fill: parent + // canvas: parent + // } } Timer { diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 49cea8e..e688202 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -20,7 +20,7 @@ import QtQuick import QtQuick.Controls import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! \qmltype CustomPropertyList diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 715602a..ced0cdd 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -18,11 +18,10 @@ import QtQuick import QtQuick.Controls -import QtQuick.Dialogs as D import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "../../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! \qmltype Dialog diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index e8d4912..e3894cd 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -19,7 +19,7 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 9624d23..5812252 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -21,7 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml new file mode 100644 index 0000000..a69f2cd --- /dev/null +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml @@ -0,0 +1,19 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml similarity index 97% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml index b364e73..f005756 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml @@ -18,12 +18,12 @@ import QtQuick import QtQuick.Controls -import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Setting as Setting +import eu.ad5001.LogarithmPlotter.Common /*! - \qmltype PickLocationOverlay - \inqmlmodule eu.ad5001.LogarithmPlotter + \qmltype PickLocation + \inqmlmodule eu.ad5001.LogarithmPlotter.Overlay \brief Overlay used to pick a new location for an object. Provides an overlay over the canvas that can be shown when the user clicks the "Set position" button @@ -32,11 +32,13 @@ import "js/index.mjs" as JS \sa LogarithmPlotter, LogGraphCanvas */ -Item { +Rectangle { id: pickerRoot visible: false clip: true - + color: sysPalette.window + opacity: 0.35 + /*! \qmlsignal PickLocationOverlay::picked(var obj) @@ -96,11 +98,6 @@ Item { */ readonly property bool userPickY: pickY && pickYCheckbox.checked - Rectangle { - color: sysPalette.window - opacity: 0.35 - anchors.fill: parent - } MouseArea { id: picker diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml similarity index 99% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml index 7a7072b..1931536 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml @@ -19,7 +19,7 @@ import QtQuick /*! - \qmltype ViewPositionChangeOverlay + \qmltype ViewPositionChange.Overlay \inqmlmodule eu.ad5001.LogarithmPlotter \brief Overlay used allow the user to drag the canvas' position and change the zoom level. diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir new file mode 100644 index 0000000..8daae21 --- /dev/null +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir @@ -0,0 +1,4 @@ +module eu.ad5001.LogarithmPlotter.Overlay + +PickLocation 1.0 PickLocation.qml +ViewPositionChange 1.0 ViewPositionChange.qml diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index a76410f..70d77a9 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -20,7 +20,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! \qmltype Preferences diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index bb99f52..8251a3f 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -20,7 +20,7 @@ import QtQuick.Controls import QtQuick import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P -import "../js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 992e9b1..3f17ea3 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -20,7 +20,7 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "js/index.mjs" as JS +import eu.ad5001.LogarithmPlotter.Common /*! \qmltype Settings diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir index 3aeaa15..c80cae5 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir @@ -2,6 +2,4 @@ module eu.ad5001.LogarithmPlotter AppMenuBar 1.0 AppMenuBar.qml LogGraphCanvas 1.0 LogGraphCanvas.qml -PickLocationOverlay 1.0 PickLocationOverlay.qml Settings 1.0 Settings.qml -ViewPositionChangeOverlay 1.0 ViewPositionChangeOverlay.qml \ No newline at end of file diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 71064fa..78c9d44 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -181,7 +181,6 @@ class Latex(QObject): """ markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) if self.latexSupported and not path.exists(export_path + ".png"): - print("Rendering", latex_markup) # Generating file latex_path = path.join(self.tempdir, str(markup_hash)) # If the formula is just recolored or the font is just changed, no need to recreate the DVI. diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index f65efa8..c917660 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -100,6 +100,7 @@ class PyPromise(QObject): Starts the thread that will run the promise. """ if not self._started: # Avoid getting started twice. + print("Starting", self._runner.args) QThreadPool.globalInstance().start(self._runner) self._started = True @@ -153,6 +154,7 @@ class PyPromise(QObject): def _fulfill(self, data): self._state = "fulfilled" no_return = [None, QJSValue.SpecialValue.UndefinedValue] + print("Finished", self._runner.args) for i in range(len(self._fulfills)): try: result = self._fulfills[i](data) diff --git a/scripts/build.sh b/scripts/build.sh index be25274..b63d7f6 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -22,6 +22,10 @@ DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$DIR/.." || exit 1 +BUILD_DIR="build/runtime-pyside6" +BUILD_QML_DIR="$BUILD_DIR/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter" + + box() { len=${#1} echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐" @@ -30,20 +34,22 @@ box() { } rm -rf build -mkdir -p build/runtime-pyside6 +mkdir -p "$BUILD_DIR" # Copy python box "Copying pyside6 python runtime..." -cp -r runtime-pyside6/{setup.py,LogarithmPlotter} build/runtime-pyside6 +cp -r runtime-pyside6/{setup.py,LogarithmPlotter} "$BUILD_DIR" box "Building ecmascript modules..." -mkdir -p build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js -cd common && (npm run build || exit) && cd .. +mkdir -p "$BUILD_QML_DIR/js" +cd common && \ + (npm run build || exit) && \ + cd .. box "Building translations..." cd assets/i18n/ && (bash release.sh || exit) && cd ../../ -mkdir -p build/runtime-pyside6/LogarithmPlotter/i18n && cp assets/i18n/*.qm build/runtime-pyside6/LogarithmPlotter/i18n/ +mkdir -p "$BUILD_DIR/LogarithmPlotter/i18n" && cp assets/i18n/*.qm "$BUILD_DIR/LogarithmPlotter/i18n/" box "Building icons..." -cp -r assets/icons build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ -cp assets/logarithmplotter.svg build/runtime-pyside6/LogarithmPlotter/ +cp -r assets/icons "$BUILD_QML_DIR" +cp assets/logarithmplotter.svg "$BUILD_DIR/LogarithmPlotter/" From 27c9fe0473f61cec7758108dff0a4d8d7f5b6468 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 27 Oct 2024 00:46:42 +0200 Subject: [PATCH 228/249] Fixing newly made issue with PickLocation. --- .../eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml index f005756..60eb90e 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml @@ -32,12 +32,10 @@ import eu.ad5001.LogarithmPlotter.Common \sa LogarithmPlotter, LogGraphCanvas */ -Rectangle { +Item { id: pickerRoot visible: false clip: true - color: sysPalette.window - opacity: 0.35 /*! \qmlsignal PickLocationOverlay::picked(var obj) @@ -98,6 +96,11 @@ Rectangle { */ readonly property bool userPickY: pickY && pickYCheckbox.checked + Rectangle { + anchors.fill: parent + color: sysPalette.window + opacity: 0.35 + } MouseArea { id: picker From 727dda26235ecb57829d97667e2305610b5185bf Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 27 Oct 2024 02:40:42 +0200 Subject: [PATCH 229/249] Adding loading screen for rendering LaTeX formula when threaded setting is enabled. --- common/src/history/common.mjs | 8 +- common/src/module/canvas.mjs | 3 + common/src/module/latex.mjs | 33 +++++- common/src/preferences/general.mjs | 4 +- common/test/mock/helper.mjs | 4 +- .../LogarithmPlotter/LogarithmPlotter.qml | 18 ++- .../ObjectLists/ObjectLists.qml | 2 +- .../LogarithmPlotter/Overlay/Loading.qml | 111 ++++++++++++++++++ .../Overlay/ViewPositionChange.qml | 10 -- .../eu/ad5001/LogarithmPlotter/Overlay/qmldir | 1 + .../LogarithmPlotter/util/config.py | 2 +- .../LogarithmPlotter/util/debug.py | 4 +- .../LogarithmPlotter/util/latex.py | 2 +- 13 files changed, 168 insertions(+), 34 deletions(-) diff --git a/common/src/history/common.mjs b/common/src/history/common.mjs index 33f9118..e8e5795 100644 --- a/common/src/history/common.mjs +++ b/common/src/history/common.mjs @@ -95,11 +95,15 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") const imgDepth = History.imageDepth - const { source, width, height } = await Latex.requestAsyncRender( + const renderArguments = [ latexString, imgDepth * (History.fontSize + 2), History.themeTextColor - ) + ] + let render = Latex.findPrerendered(...renderArguments) + if(render === null) + render = await Latex.requestAsyncRender(...renderArguments) + const { source, width, height } = render return `` } diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index ba6d5ca..5736cfc 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -25,7 +25,10 @@ import Objects from "./objects.mjs" import History from "./history.mjs" import Settings from "./settings.mjs" + class CanvasAPI extends Module { + + /** @type {CanvasInterface} */ #canvas = null /** @type {CanvasRenderingContext2D} */ diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 216e3be..65ce689 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -17,6 +17,7 @@ */ import { Module } from "./common.mjs" +import { BaseEvent } from "../events.mjs" import * as Instruction from "../lib/expr-eval/instruction.mjs" import { escapeValue } from "../lib/expr-eval/expression.mjs" import { HelperInterface, LatexInterface } from "./interface.mjs" @@ -44,6 +45,28 @@ const equivalchars = ["\\pi", "\\infty", "{}_{4}", "{}_{5}", "{}_{6}", "{}_{7}", "{}_{8}", "{}_{9}", "{}_{0}", ] + + + +class AsyncRenderStartedEvent extends BaseEvent { + constructor(markup, fontSize, color) { + super("async-render-started") + this.markup = markup + this.fontSize = fontSize + this.color = color + } +} + + +class AsyncRenderFinishedEvent extends BaseEvent { + constructor(markup, fontSize, color) { + super("async-render-finished") + this.markup = markup + this.fontSize = fontSize + this.color = color + } +} + /** * Class containing the result of a LaTeX render. * @@ -60,6 +83,8 @@ class LatexRenderResult { } class LatexAPI extends Module { + static emits = ["async-render-started", "async-render-finished"] + /** @type {LatexInterface} */ #latex = null @@ -113,10 +138,14 @@ class LatexAPI extends Module { async requestAsyncRender(markup, fontSize, color) { if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") let render - if(this.#latex.supportsAsyncRender) + if(this.#latex.supportsAsyncRender) { + console.trace() + this.emit(new AsyncRenderStartedEvent(markup, fontSize, color)) render = await this.#latex.renderAsync(markup, fontSize, color) - else + this.emit(new AsyncRenderFinishedEvent(markup, fontSize, color)) + } else { render = this.#latex.renderSync(markup, fontSize, color) + } const args = render.split(",") return new LatexRenderResult(...args) } diff --git a/common/src/preferences/general.mjs b/common/src/preferences/general.mjs index a6957c6..a00a813 100644 --- a/common/src/preferences/general.mjs +++ b/common/src/preferences/general.mjs @@ -47,8 +47,8 @@ class EnableLatex extends BoolSetting { } const ENABLE_LATEX_ASYNC = new BoolSetting( - qsTranslate("general", "Enable asynchronous LaTeX renderer"), - "enable_latex_async", + qsTranslate("general", "Enable threaded LaTeX renderer (experimental)"), + "enable_latex_threaded", "new" ) diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs index 4cab472..b912b44 100644 --- a/common/test/mock/helper.mjs +++ b/common/test/mock/helper.mjs @@ -23,7 +23,7 @@ const DEFAULT_SETTINGS = { "reset_redo_stack": true, "last_install_greet": "0", "enable_latex": true, - "enable_latex_async": true, + "enable_latex_threaded": true, "expression_editor": { "autoclose": true, "colorize": true, @@ -113,4 +113,4 @@ export class MockHelper { throw new Error(`File not found.`) } -} \ No newline at end of file +} diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index b8799de..064a0be 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -17,10 +17,10 @@ */ import QtQml -import QtQuick.Controls -import eu.ad5001.MixedMenu 1.1 -import QtQuick.Layouts 1.12 import QtQuick +import QtQuick.Controls +import QtQuick.Layouts 1.12 +import eu.ad5001.MixedMenu 1.1 // Auto loading all modules. import eu.ad5001.LogarithmPlotter.Common @@ -158,21 +158,17 @@ ApplicationWindow { Overlay.ViewPositionChange { id: viewPositionChanger anchors.fill: parent - canvas: parent - settingsInstance: settings } Overlay.PickLocation { id: positionPicker anchors.fill: parent - canvas: parent } + } - // Overlay.Loading { - // id: loadingOverlay - // anchors.fill: parent - // canvas: parent - // } + Overlay.Loading { + id: loadingOverlay + anchors.fill: parent } Timer { diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index f755a6f..c2a5a23 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -56,7 +56,7 @@ ScrollView { property var editingRows: [] model: Modules.Objects.currentObjects[objType] width: objectsListView.width - implicitHeight: contentItem.childrenRect.height + height: contentItem.childrenRect.height + 10 visible: model != undefined && model.length > 0 interactive: false diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml index a69f2cd..6aec616 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml @@ -17,3 +17,114 @@ */ import QtQuick +import QtQuick.Controls + + +/*! + \qmltype Loading + \inqmlmodule eu.ad5001.LogarithmPlotter.Overlay + \brief Overlay notifiying the user when a file is loading. + + Provides an overlay over the canvas that is shown when the user loads a new file, both to lock the ViewPositionChange + overlay and inform the user of what is loading and how much remains. + + \sa Common, ViewPositionChange +*/ +Item { + id: loadingRoot + opacity: 0 + visible: opacity !== 0 + clip: true + + property int currentlyLoading: 0 + property int maxCurrentLoadingSteps: 0 + + Behavior on opacity { PropertyAnimation {} } + + Rectangle { + anchors.fill: parent + color: sysPalette.window + opacity: 0.85 + } + + Column { + spacing: 5 + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + right: parent.right + } + + Text { + id: loadingTitle + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 20 + color: sysPalette.windowText + } + + ProgressBar { + id: progress + anchors.horizontalCenter: parent.horizontalCenter + width: 300 + from: 0 + value: loadingRoot.maxCurrentLoadingSteps - loadingRoot.currentlyLoading + to: loadingRoot.maxCurrentLoadingSteps + } + + Text { + id: lastFinishedStep + anchors.horizontalCenter: parent.horizontalCenter + color: sysPalette.windowText + } + } + + MouseArea { + id: picker + anchors.fill: parent + hoverEnabled: parent.visible + cursorShape: Qt.ArrowCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + } + + + + /*! + \qmlmethod void Loading::addedLoadingStep() + Registers one new loading step that will eventually call \c finishedLoadingStep. + */ + function addedLoadingStep() { + if(loadingRoot.maxCurrentLoadingSteps === 1) { + // Only when several ones need to be loaded. + const fileName = Modules.Settings.saveFilename.split('/').pop().split('\\').pop() + loadingTitle.text = qsTr("Loading...") + loadingRoot.opacity = 1 + } + loadingRoot.currentlyLoading++ + loadingRoot.maxCurrentLoadingSteps++ + } + + /*! + \qmlmethod void Loading::finishedLoadingStep() + Marks a loading step as finished and displays the message to the user. + */ + function finishedLoadingStep(message) { + loadingRoot.currentlyLoading-- + const current = loadingRoot.maxCurrentLoadingSteps - loadingRoot.currentlyLoading + lastFinishedStep.text = `${message} (${current}/${loadingRoot.maxCurrentLoadingSteps})` + if(loadingRoot.currentlyLoading === 0) { + loadingRoot.maxCurrentLoadingSteps = 0 + loadingRoot.opacity = 0 + } + } + + + Component.onCompleted: function() { + Modules.Latex.on("async-render-started", (e) => { + addedLoadingStep() + }) + Modules.Latex.on("async-render-finished", (e) => { + const markup = e.markup.length > 20 ? e.markup.substring(0, 15)+"..." : e.markup + finishedLoadingStep(qsTr("Finished rendering of %1").arg(markup)) + }) + } +} diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml index 1931536..41ce60a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml @@ -57,16 +57,6 @@ Item { */ signal endPositionChange(int deltaX, int deltaY) - /*! - \qmlproperty var ViewPositionChangeOverlay::canvas - LogGraphCanvas instance. - */ - property var canvas - /*! - \qmlproperty var ViewPositionChangeOverlay::settingsInstance - Settings instance. - */ - property var settingsInstance /*! \qmlproperty int ViewPositionChangeOverlay::prevX The x coordinate (on the mousearea) at the last change of the canvas position. diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir index 8daae21..0288c9e 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir @@ -1,4 +1,5 @@ module eu.ad5001.LogarithmPlotter.Overlay +Loading 1.0 Loading.qml PickLocation 1.0 PickLocation.qml ViewPositionChange 1.0 ViewPositionChange.qml diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index e01deae..020569a 100644 --- a/runtime-pyside6/LogarithmPlotter/util/config.py +++ b/runtime-pyside6/LogarithmPlotter/util/config.py @@ -28,7 +28,7 @@ DEFAULT_SETTINGS = { "reset_redo_stack": True, "last_install_greet": "0", "enable_latex": which("latex") is not None and which("dvipng") is not None, - "enable_latex_async": True, + "enable_latex_threaded": True, "expression_editor": { "autoclose": True, "colorize": True, diff --git a/runtime-pyside6/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py index f899fd5..ef02d62 100644 --- a/runtime-pyside6/LogarithmPlotter/util/debug.py +++ b/runtime-pyside6/LogarithmPlotter/util/debug.py @@ -22,9 +22,9 @@ from os import path from re import compile CURRENT_PATH = path.dirname(path.realpath(__file__)) -SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map") +SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/Common/index.mjs.map") SOURCEMAP_INDEX = None -INDEX_REG = compile(r"build\/runtime-pyside6\/LogarithmPlotter\/qml\/eu\/ad5001\/LogarithmPlotter\/js\/index.mjs:(\d+)") +INDEX_REG = compile(r"build\/runtime-pyside6\/LogarithmPlotter\/qml\/eu\/ad5001\/LogarithmPlotter\/Common\/index.mjs:(\d+)") class LOG_COLORS: diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 78c9d44..570e083 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -91,7 +91,7 @@ class Latex(QObject): @Property(bool) def supportsAsyncRender(self) -> bool: - return config.getSetting("enable_latex_async") + return config.getSetting("enable_latex_threaded") @Slot(result=bool) def checkLatexInstallation(self) -> bool: From 49e94317d4f3de3868c5329840238ef817e22170 Mon Sep 17 00:00:00 2001 From: ovari Date: Sun, 27 Oct 2024 07:13:26 +0000 Subject: [PATCH 230/249] Translated using Weblate (Hungarian) Currently translated at 100.0% (265 of 265 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- assets/i18n/lp_hu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index a43da4d..ac521eb 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -1321,7 +1321,7 @@ Kiértékelt kifejezés: %3 Could not load file: - + Nem sikerült betölteni a fájlt: Could not save file: From 687b14429a17b627935acf6b51d41f3ae0431811 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 28 Oct 2024 18:45:34 +0100 Subject: [PATCH 231/249] Improving reliability of threaded rendering, separating JS Utils into separate files. --- common/src/history/position.mjs | 2 +- common/src/index.mjs | 5 +- common/src/math/expression.mjs | 4 +- common/src/math/sequence.mjs | 2 +- common/src/module/canvas.mjs | 2 +- common/src/module/latex.mjs | 8 +- common/src/module/objects.mjs | 2 +- common/src/objs/common.mjs | 2 +- common/src/objs/function.mjs | 2 +- .../src/{utils.mjs => utils/expression.mjs} | 178 +----------------- common/src/utils/index.mjs | 22 +++ common/src/utils/other.mjs | 41 ++++ common/src/utils/prototype.mjs | 51 +++++ common/src/utils/subsup.mjs | 140 ++++++++++++++ common/test/basics/utils.mjs | 2 +- common/test/math/expression.mjs | 2 +- .../LogarithmPlotter/logarithmplotter.py | 9 +- .../LogarithmPlotter/util/promise.py | 8 +- 18 files changed, 285 insertions(+), 197 deletions(-) rename common/src/{utils.mjs => utils/expression.mjs} (72%) create mode 100644 common/src/utils/index.mjs create mode 100644 common/src/utils/other.mjs create mode 100644 common/src/utils/prototype.mjs create mode 100644 common/src/utils/subsup.mjs diff --git a/common/src/history/position.mjs b/common/src/history/position.mjs index 4c1af60..3bf2fe8 100644 --- a/common/src/history/position.mjs +++ b/common/src/history/position.mjs @@ -19,7 +19,7 @@ import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" import * as MathLib from "../math/index.mjs" -import { escapeHTML } from "../utils.mjs" +import { escapeHTML } from "../utils/index.mjs" import { Action } from "./common.mjs" /** diff --git a/common/src/index.mjs b/common/src/index.mjs index c19e2fe..9b5684c 100644 --- a/common/src/index.mjs +++ b/common/src/index.mjs @@ -18,10 +18,11 @@ import js from "./lib/polyfills/js.mjs" -import * as Modules from "./module/index.mjs" +export * as Utils from "./utils/index.mjs" + import * as ObjsAutoload from "./objs/autoload.mjs" +export * as Modules from "./module/index.mjs" export * as MathLib from "./math/index.mjs" export * as HistoryLib from "./history/index.mjs" export * as Parsing from "./parsing/index.mjs" -export * as Utils from "./utils.mjs" diff --git a/common/src/math/expression.mjs b/common/src/math/expression.mjs index 5701ac6..7c7170b 100644 --- a/common/src/math/expression.mjs +++ b/common/src/math/expression.mjs @@ -17,11 +17,11 @@ */ -import * as Utils from "../utils.mjs" +import * as Utils from "../utils/index.mjs" +import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs" import Latex from "../module/latex.mjs" import ExprParser from "../module/expreval.mjs" import Objects from "../module/objects.mjs" -import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs" const NUMBER_MATCHER = /^\d*\.\d+(e[+-]\d+)?$/ diff --git a/common/src/math/sequence.mjs b/common/src/math/sequence.mjs index 5394237..b295708 100644 --- a/common/src/math/sequence.mjs +++ b/common/src/math/sequence.mjs @@ -17,7 +17,7 @@ */ import * as Expr from "./expression.mjs" -import * as Utils from "../utils.mjs" +import * as Utils from "../utils/index.mjs" import Latex from "../module/latex.mjs" import Objects from "../module/objects.mjs" import ExprParser from "../module/expreval.mjs" diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 5736cfc..dcc3f33 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -18,7 +18,7 @@ import { Module } from "./common.mjs" import { CanvasInterface, DialogInterface } from "./interface.mjs" -import { textsup } from "../utils.mjs" +import { textsup } from "../utils/index.mjs" import { Expression } from "../math/index.mjs" import Latex from "./latex.mjs" import Objects from "./objects.mjs" diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 65ce689..3b48ebc 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -97,6 +97,7 @@ class LatexAPI extends Module { * true if latex has been enabled by the user, false otherwise. */ this.enabled = false + this.promises = new Set() } /** @@ -139,9 +140,12 @@ class LatexAPI extends Module { if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!") let render if(this.#latex.supportsAsyncRender) { - console.trace() this.emit(new AsyncRenderStartedEvent(markup, fontSize, color)) - render = await this.#latex.renderAsync(markup, fontSize, color) + // Storing promise so that it does not get dereferenced. + const promise = this.#latex.renderAsync(markup, fontSize, color) + this.promises.add(promise) + render = await promise + this.promises.delete(promise) this.emit(new AsyncRenderFinishedEvent(markup, fontSize, color)) } else { render = this.#latex.renderSync(markup, fontSize, color) diff --git a/common/src/module/objects.mjs b/common/src/module/objects.mjs index 23801be..979dba4 100644 --- a/common/src/module/objects.mjs +++ b/common/src/module/objects.mjs @@ -17,7 +17,7 @@ */ import { Module } from "./common.mjs" -import { textsub } from "../utils.mjs" +import { textsub } from "../utils/index.mjs" class ObjectsAPI extends Module { diff --git a/common/src/objs/common.mjs b/common/src/objs/common.mjs index 1534a9a..380ac5d 100644 --- a/common/src/objs/common.mjs +++ b/common/src/objs/common.mjs @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import { getRandomColor } from "../utils.mjs" import Objects from "../module/objects.mjs" import Latex from "../module/latex.mjs" +import { getRandomColor } from "../utils/index.mjs" import { ensureTypeSafety, serializesByPropertyType } from "../parameters.mjs" // This file contains the default data to be imported from all other objects diff --git a/common/src/objs/function.mjs b/common/src/objs/function.mjs index b056cc3..70d0b69 100644 --- a/common/src/objs/function.mjs +++ b/common/src/objs/function.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { textsub } from "../utils.mjs" +import { textsub } from "../utils/index.mjs" import Objects from "../module/objects.mjs" import { ExecutableObject } from "./common.mjs" import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs" diff --git a/common/src/utils.mjs b/common/src/utils/expression.mjs similarity index 72% rename from common/src/utils.mjs rename to common/src/utils/expression.mjs index 5c51f62..ef20b27 100644 --- a/common/src/utils.mjs +++ b/common/src/utils/expression.mjs @@ -16,151 +16,7 @@ * along with this program. If not, see . */ -// Add string methods -/** - * Replaces latin characters with their uppercase versions. - * @return {string} - */ -String.prototype.toLatinUppercase = function() { - return this.replace(/[a-z]/g, function(match) { - return match.toUpperCase() - }) -} - -/** - * Removes the first and last character of a string - * Used to remove enclosing characters like quotes, parentheses, brackets... - * @note Does NOT check for their existence ahead of time. - * @return {string} - */ -String.prototype.removeEnclosure = function() { - return this.substring(1, this.length - 1) -} - -/** - * Rounds to a certain number of decimal places. - * From https://stackoverflow.com/a/48764436 - * - * @param {number} decimalPlaces - * @return {number} - */ -Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) { - const p = Math.pow(10, decimalPlaces) - const n = (this * p) * (1 + Number.EPSILON) - return Math.round(n) / p -} - -const CHARACTER_TO_POWER = new Map([ - ["-", "⁻"], - ["+", "⁺"], - ["=", "⁼"], - [" ", " "], - ["(", "⁽"], - [")", "⁾"], - ["0", "⁰"], - ["1", "¹"], - ["2", "²"], - ["3", "³"], - ["4", "⁴"], - ["5", "⁵"], - ["6", "⁶"], - ["7", "⁷"], - ["8", "⁸"], - ["9", "⁹"], - ["a", "ᵃ"], - ["b", "ᵇ"], - ["c", "ᶜ"], - ["d", "ᵈ"], - ["e", "ᵉ"], - ["f", "ᶠ"], - ["g", "ᵍ"], - ["h", "ʰ"], - ["i", "ⁱ"], - ["j", "ʲ"], - ["k", "ᵏ"], - ["l", "ˡ"], - ["m", "ᵐ"], - ["n", "ⁿ"], - ["o", "ᵒ"], - ["p", "ᵖ"], - ["r", "ʳ"], - ["s", "ˢ"], - ["t", "ᵗ"], - ["u", "ᵘ"], - ["v", "ᵛ"], - ["w", "ʷ"], - ["x", "ˣ"], - ["y", "ʸ"], - ["z", "ᶻ"] -]) - -const CHARACTER_TO_INDICE = new Map([ - ["-", "₋"], - ["+", "₊"], - ["=", "₌"], - ["(", "₍"], - [")", "₎"], - [" ", " "], - ["0", "₀"], - ["1", "₁"], - ["2", "₂"], - ["3", "₃"], - ["4", "₄"], - ["5", "₅"], - ["6", "₆"], - ["7", "₇"], - ["8", "₈"], - ["9", "₉"], - ["a", "ₐ"], - ["e", "ₑ"], - ["h", "ₕ"], - ["i", "ᵢ"], - ["j", "ⱼ"], - ["k", "ₖ"], - ["l", "ₗ"], - ["m", "ₘ"], - ["n", "ₙ"], - ["o", "ₒ"], - ["p", "ₚ"], - ["r", "ᵣ"], - ["s", "ₛ"], - ["t", "ₜ"], - ["u", "ᵤ"], - ["v", "ᵥ"], - ["x", "ₓ"] -]) - -const EXPONENTS = [ - "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" -] - -const EXPONENTS_REG = new RegExp("([" + EXPONENTS.join("") + "]+)", "g") - -/** - * Put a text in sup position - * @param {string} text - * @return {string} - */ -export function textsup(text) { - let ret = "" - text = text.toString() - for(let letter of text) - ret += CHARACTER_TO_POWER.has(letter) ? CHARACTER_TO_POWER.get(letter) : letter - return ret -} - -/** - * Put a text in sub position - * @param {string} text - * @return {string} - */ -export function textsub(text) { - let ret = "" - text = text.toString() - for(let letter of text) - ret += CHARACTER_TO_INDICE.has(letter) ? CHARACTER_TO_INDICE.get(letter) : letter - return ret -} +import { textsub, textsup } from "./subsup.mjs" /** * Simplifies (mathematically) a mathematical expression. @@ -400,35 +256,3 @@ export function parseName(str, removeUnallowed = true) { return str } - -/** - * Creates a randomized color string. - * @returns {string} - */ -export function getRandomColor() { - let clrs = "0123456789ABCDEF" - let color = "#" - for(let i = 0; i < 6; i++) { - color += clrs[Math.floor(Math.random() * (16 - 5 * (i % 2 === 0)))] - } - return color -} - -/** - * Escapes text to html entities. - * @param {string} str - * @returns {string} - */ -export function escapeHTML(str) { - return str.replace(/&/g, "&").replace(//g, ">") -} - - -/** - * Parses exponents and replaces them with expression values - * @param {string} expression - The expression to replace in. - * @return {string} The parsed expression - */ -export function exponentsToExpression(expression) { - return expression.replace(EXPONENTS_REG, (m, exp) => "^" + exp.split("").map((x) => EXPONENTS.indexOf(x)).join("")) -} diff --git a/common/src/utils/index.mjs b/common/src/utils/index.mjs new file mode 100644 index 0000000..02adfd6 --- /dev/null +++ b/common/src/utils/index.mjs @@ -0,0 +1,22 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export * from "./prototype.mjs" +export * from "./subsup.mjs" +export * from "./expression.mjs" +export * from "./other.mjs" diff --git a/common/src/utils/other.mjs b/common/src/utils/other.mjs new file mode 100644 index 0000000..bcafd6b --- /dev/null +++ b/common/src/utils/other.mjs @@ -0,0 +1,41 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + + +/** + * Creates a randomized color string. + * @returns {string} + */ +export function getRandomColor() { + let clrs = "0123456789ABCDEF" + let color = "#" + for(let i = 0; i < 6; i++) { + color += clrs[Math.floor(Math.random() * (16 - 5 * (i % 2 === 0)))] + } + return color +} + +/** + * Escapes text to html entities. + * @param {string} str + * @returns {string} + */ +export function escapeHTML(str) { + return str.replace(/&/g, "&").replace(//g, ">") +} diff --git a/common/src/utils/prototype.mjs b/common/src/utils/prototype.mjs new file mode 100644 index 0000000..cb2cc15 --- /dev/null +++ b/common/src/utils/prototype.mjs @@ -0,0 +1,51 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Add string methods +/** + * Replaces latin characters with their uppercase versions. + * @return {string} + */ +String.prototype.toLatinUppercase = function() { + return this.replace(/[a-z]/g, function(match) { + return match.toUpperCase() + }) +} + +/** + * Removes the first and last character of a string + * Used to remove enclosing characters like quotes, parentheses, brackets... + * @note Does NOT check for their existence ahead of time. + * @return {string} + */ +String.prototype.removeEnclosure = function() { + return this.substring(1, this.length - 1) +} + +/** + * Rounds to a certain number of decimal places. + * From https://stackoverflow.com/a/48764436 + * + * @param {number} decimalPlaces + * @return {number} + */ +Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) { + const p = Math.pow(10, decimalPlaces) + const n = (this * p) * (1 + Number.EPSILON) + return Math.round(n) / p +} diff --git a/common/src/utils/subsup.mjs b/common/src/utils/subsup.mjs new file mode 100644 index 0000000..ff6ed50 --- /dev/null +++ b/common/src/utils/subsup.mjs @@ -0,0 +1,140 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +const CHARACTER_TO_POWER = new Map([ + ["-", "⁻"], + ["+", "⁺"], + ["=", "⁼"], + [" ", " "], + ["(", "⁽"], + [")", "⁾"], + ["0", "⁰"], + ["1", "¹"], + ["2", "²"], + ["3", "³"], + ["4", "⁴"], + ["5", "⁵"], + ["6", "⁶"], + ["7", "⁷"], + ["8", "⁸"], + ["9", "⁹"], + ["a", "ᵃ"], + ["b", "ᵇ"], + ["c", "ᶜ"], + ["d", "ᵈ"], + ["e", "ᵉ"], + ["f", "ᶠ"], + ["g", "ᵍ"], + ["h", "ʰ"], + ["i", "ⁱ"], + ["j", "ʲ"], + ["k", "ᵏ"], + ["l", "ˡ"], + ["m", "ᵐ"], + ["n", "ⁿ"], + ["o", "ᵒ"], + ["p", "ᵖ"], + ["r", "ʳ"], + ["s", "ˢ"], + ["t", "ᵗ"], + ["u", "ᵘ"], + ["v", "ᵛ"], + ["w", "ʷ"], + ["x", "ˣ"], + ["y", "ʸ"], + ["z", "ᶻ"] +]) + +const CHARACTER_TO_INDICE = new Map([ + ["-", "₋"], + ["+", "₊"], + ["=", "₌"], + ["(", "₍"], + [")", "₎"], + [" ", " "], + ["0", "₀"], + ["1", "₁"], + ["2", "₂"], + ["3", "₃"], + ["4", "₄"], + ["5", "₅"], + ["6", "₆"], + ["7", "₇"], + ["8", "₈"], + ["9", "₉"], + ["a", "ₐ"], + ["e", "ₑ"], + ["h", "ₕ"], + ["i", "ᵢ"], + ["j", "ⱼ"], + ["k", "ₖ"], + ["l", "ₗ"], + ["m", "ₘ"], + ["n", "ₙ"], + ["o", "ₒ"], + ["p", "ₚ"], + ["r", "ᵣ"], + ["s", "ₛ"], + ["t", "ₜ"], + ["u", "ᵤ"], + ["v", "ᵥ"], + ["x", "ₓ"] +]) + +const EXPONENTS = [ + "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" +] + +const EXPONENTS_REG = new RegExp("([" + EXPONENTS.join("") + "]+)", "g") + +/** + * Put a text in sup position + * @param {string} text + * @return {string} + */ +export function textsup(text) { + let ret = "" + text = text.toString() + for(let letter of text) + ret += CHARACTER_TO_POWER.has(letter) ? CHARACTER_TO_POWER.get(letter) : letter + return ret +} + +/** + * Put a text in sub position + * @param {string} text + * @return {string} + */ +export function textsub(text) { + let ret = "" + text = text.toString() + for(let letter of text) + ret += CHARACTER_TO_INDICE.has(letter) ? CHARACTER_TO_INDICE.get(letter) : letter + return ret +} + + +/** + * Parses exponents and replaces them with expression values + * @param {string} expression - The expression to replace in. + * @return {string} The parsed expression + */ +export function exponentsToExpression(expression) { + return expression.replace(EXPONENTS_REG, (m, exp) => "^" + exp.split("").map((x) => EXPONENTS.indexOf(x)).join("")) +} + diff --git a/common/test/basics/utils.mjs b/common/test/basics/utils.mjs index aab2cf5..42adead 100644 --- a/common/test/basics/utils.mjs +++ b/common/test/basics/utils.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExpression } from "../../src/utils.mjs" +import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExpression } from "../../src/utils/index.mjs" import { describe, it } from "mocha" diff --git a/common/test/math/expression.mjs b/common/test/math/expression.mjs index a0ee113..0c15f9c 100644 --- a/common/test/math/expression.mjs +++ b/common/test/math/expression.mjs @@ -178,4 +178,4 @@ describe("Math/Expression", function() { expect(() => executeExpression("x+n")).to.throw("Undefined variable n.") }) }) -}) \ No newline at end of file +}) diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index c4c16b9..8940e56 100644 --- a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py +++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py @@ -21,9 +21,10 @@ from platform import system as os_name, release as OS_RELEASE from sys import path as sys_path from sys import argv, exit from tempfile import TemporaryDirectory +from math import ceil from time import time -from PySide6.QtCore import QTranslator, QLocale +from PySide6.QtCore import QTranslator, QLocale, QThreadPool, QThread from PySide6.QtGui import QIcon from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtQuickControls2 import QQuickStyle @@ -162,7 +163,11 @@ def run(): dep_time = time() print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") - + + # Maxing thread count to half the computer's thread count to avoid maxing CPU + # with too many threads (and also leaving some for rendering). + QThreadPool.globalInstance().setMaxThreadCount(int(ceil(QThread.idealThreadCount() / 2))) + register_icon_directories() app = create_qapp() translator = install_translation(app) diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index c917660..f4f21c2 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -22,6 +22,8 @@ from PySide6.QtQml import QJSValue from LogarithmPlotter.util.js import PyJSValue +NO_RETURN = [None, QJSValue.SpecialValue.UndefinedValue] + def check_callable(function: Callable|QJSValue) -> Callable|None: """ @@ -153,13 +155,12 @@ class PyPromise(QObject): @Slot(QObject) def _fulfill(self, data): self._state = "fulfilled" - no_return = [None, QJSValue.SpecialValue.UndefinedValue] print("Finished", self._runner.args) for i in range(len(self._fulfills)): try: result = self._fulfills[i](data) result = result.qjs_value if isinstance(result, PyJSValue) else result - data = result if result not in no_return else data # Forward data. + data = result if result not in NO_RETURN else data # Forward data. except Exception as e: self._reject(repr(e), start_at=i) break @@ -168,8 +169,7 @@ class PyPromise(QObject): @Slot(str) def _reject(self, error, start_at=0): self._state = "rejected" - no_return = [None, QJSValue.SpecialValue.UndefinedValue] for i in range(start_at, len(self._rejects)): result = self._rejects[i](error) result = result.qjs_value if isinstance(result, PyJSValue) else result - error = result if result not in no_return else error # Forward data. + error = result if result not in NO_RETURN else error # Forward data. From 43e41a5da4f4f7b7f9c8bfe66da5898c1f1ca3af Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 28 Oct 2024 18:51:13 +0100 Subject: [PATCH 232/249] Adding new test files Including: - magnitude.lpf & phase.lpf: regular use case magnitude and phase - all.lpf: tests all objects - stress.lpf: over 200 objects to be rendered --- ci/all.lpf | 1 + ci/drone.yml | 4 ++++ ci/magnitude.lpf | 1 + ci/phase.lpf | 1 + ci/stress.lpf | 1 + 5 files changed, 8 insertions(+) create mode 100644 ci/all.lpf create mode 100644 ci/magnitude.lpf create mode 100644 ci/phase.lpf create mode 100644 ci/stress.lpf diff --git a/ci/all.lpf b/ci/all.lpf new file mode 100644 index 0000000..9eeb0b9 --- /dev/null +++ b/ci/all.lpf @@ -0,0 +1 @@ +LPFv1{"xzoom":100,"yzoom":10,"xmin":0.2696454905834007,"ymax":33.115625,"xaxisstep":"4","yaxisstep":"π","xaxislabel":"","yaxislabel":"","logscalex":true,"linewidth":1,"showxgrad":true,"showygrad":true,"textsize":18,"history":[[["CreateNewObject",["A","Point",["A",true,"#941A97","name + value","1","0","above","●"]]],["EditedPosition",["A","Point","1","175.36","0","9.9"]],["CreateNewObject",["f","Function",["f",true,"#6E590E","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["f","Function","expression","x","((x / 2) - 1)",true]],["CreateNewObject",["t","Text",["t",true,"#118455","null","1","0","center","New text",false]]],["EditedPosition",["t","Text","1","36.48","0","(-13.7)"]],["EditedProperty",["t","Text","text","New text","AEZA",false]],["CreateNewObject",["ω","Point",["ω",true,"#5A3A52","name","1","0","above","●"]]],["CreateNewObject",["G₀","Gain Bode",["G₀",true,"#5A3A52","name + value","ω","high","20","below",1,false]]],["EditedPosition",["ω","Point","1","17.76","0","(-8.9)"]],["EditedProperty",["G₀","Gain Bode","gain","20","10",true]],["EditedProperty",["G₀","Gain Bode","labelPosition","below","below-left",false]],["EditedProperty",["G₀","Gain Bode","pass","high","low",false]],["EditedProperty",["G₀","Gain Bode","labelX",1,62.61,false]],["CreateNewObject",["X","X Cursor",["X",true,"#5909A9","name + value","1",null,"left",true,3,"— — — — — — —","Next to target"]]],["EditedProperty",["X","X Cursor","x","1","5.04",true]],["CreateNewObject",["u","Sequence",["u",true,"#78929E","name + value",true,true,{"1":"n"},{"0":0},"above",1]]],["EditedProperty",["u","Sequence","defaultExpression",{"1":"n"},{"1":"n+1"},false]],["EditedProperty",["u","Sequence","defaultExpression",{"1":"n+1"},{"1":"n+1"},false]],["EditedProperty",["u","Sequence","baseValues",{"0":0},{"0":"-1"},false]],["EditedProperty",["u","Sequence","baseValues",{"0":"-1"},{"0":"-1"},false]],["CreateNewObject",["F_X","Repartition",["F_X",true,"#231931","name + value",{"0":"0"},"above",1]]],["EditedProperty",["F_X","Repartition","labelX",1,12.64,false]],["EditedProperty",["f","Function","labelPosition","above","right",false]],["EditedProperty",["f","Function","labelX",1,30,false]],["EditedProperty",["u","Sequence","labelX",1,3,false]],["EditedProperty",["F_X","Repartition","labelX",12.64,40,false]],["EditedProperty",["ω","Point","labelPosition","above","below",false]],["CreateNewObject",["ω₀","Point",["ω₀","#7C2981","name","name + value","1","0","above","●"]]],["CreateNewObject",["φ₀","Phase Bode",["φ₀",true,"#7C2981","name + value","ω₀","90","°","below",1]]],["EditedPosition",["ω₀","Point","1","3","0","(-8)"]],["EditedPosition",["ω₀","Point","3","2","(-8)","8"]],["EditedProperty",["ω₀","Point","labelPosition","above","above-right",false]],["EditedProperty",["u","Sequence","labelPosition","above","above-left",false]],["EditedProperty",["u","Sequence","labelX",3,20,false]],["EditedProperty",["G","Somme gains Bode","labelX",1,2,false]]],[]],"width":1000,"height":500,"objects":{"Point":[["A",true,"#941A97","name + value","175.36","9.9","above","●"],["ω",true,"#5A3A52","name","17.76","(-8.9)","below","●"],["ω₀",false,"name","name","2","8","above-right","●"]],"Function":[["f",true,"#6E590E","name + value","((x / 2) - 1)","ℝ⁺*","ℝ","application","right",30,true,true]],"Text":[["t",true,"#118455","null","36.48","(-13.7)","center","AEZA",false]],"Gain Bode":[["G₀",true,"#5A3A52","name + value","ω","low","10","below-left",62.61,false]],"Somme gains Bode":[["G",true,"#A83C72","name + value","above",2]],"X Cursor":[["X",true,"#5909A9","name + value","5.04",null,"left",true,null,"— — — — — — —","Next to target"]],"Sequence":[["u",true,"#78929E","name + value",true,true,{"1":"n+1"},{"0":"-1"},"above-left",20]],"Repartition":[["F_X",true,"#231931","name + value",{"0":"0"},"above",40]],"Phase Bode":[["φ₀",true,"#7C2981","name + value","ω₀","90","°","below",1]],"Somme phases Bode":[["φ",true,"#A08B14","name + value","above",1]]},"type":"logplotv1"} \ No newline at end of file diff --git a/ci/drone.yml b/ci/drone.yml index d49a6d4..54ef658 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -31,6 +31,10 @@ steps: - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/all.lpf + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/magnitude.lpf + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/phase.lpf + - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/stress.lpf when: event: [ push, tag ] diff --git a/ci/magnitude.lpf b/ci/magnitude.lpf new file mode 100644 index 0000000..35ac7ae --- /dev/null +++ b/ci/magnitude.lpf @@ -0,0 +1 @@ +LPFv1{"xzoom":120,"yzoom":10,"xmin":0.5,"ymax":25,"xaxisstep":"4","yaxisstep":"4","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":true,"linewidth":2,"showxgrad":false,"showygrad":true,"textsize":17,"history":[[["CreateNewObject",["ω","Point",["ω",true,"#94AE66","name","1","0","top","●"]]],["CreateNewObject",["G₀","Gain Bode",["G₀",true,"#94AE66","name + value","ω","high","20","below",1,false]]],["EditedProperty",["G₀","Gain Bode","gain","20","0",true]],["EditedProperty",["ω","Point","y","0","10",true]],["EditedVisibility",["ω","Point","visible"]],["EditedProperty",["G","Somme gains Bode","labelX",1,10,false]],["CreateNewObject",["ω₀","Point",["ω₀",true,"#A38B4D","name","1","0","top","●"]]],["CreateNewObject",["G₁","Gain Bode",["G₁",true,"#A38B4D","name + value","ω₀","high","20","below",1,false]]],["EditedProperty",["G₁","Gain Bode","pass","high","low",false]],["EditedProperty",["G₁","Gain Bode","gain","20","(-20)",true]],["EditedVisibility",["ω₀","Point","visible"]],["EditedProperty",["ω₁","Point","x","1","10",true]],["CreateNewObject",["ω₀","Point",["ω₀",true,"#5F04A2","name","1","0","top","●"]]],["CreateNewObject",["G₂","Gain Bode",["G₂",true,"#5F04A2","name + value","ω₀","high","20","below",1,false]]],["EditedVisibility",["ω₀","Point","visible"]],["EditedProperty",["G₂","Gain Bode","labelX",1,5,false]],["EditedProperty",["ω₂","Point","x","1","5",true]],["EditedProperty",["G₂","Gain Bode","pass","high","low",false]],["EditedProperty",["G₂","Gain Bode","gain","20","(-20)",true]],["EditedProperty",["ω₁","Point","x","10","13",true]],["EditedProperty",["ω₁","Point","x","13","30",true]],["EditedProperty",["G₀","Gain Bode","labelPosition","below","below",false]],["EditedProperty",["G₀","Gain Bode","labelX",1,2,false]],["EditedProperty",["G₀","Gain Bode","labelPosition","below","above",false]],["EditedProperty",["G₂","Gain Bode","labelX",5,40,false]],["EditedProperty",["G₂","Gain Bode","labelX",40,20,false]],["EditedProperty",["G₂","Gain Bode","labelX",20,10,false]],["EditedProperty",["G₁","Gain Bode","labelX",1,40,false]],["EditedProperty",["G₁","Gain Bode","labelPosition","below","above-left",false]],["EditedProperty",["G₁","Gain Bode","labelPosition","above-left","above-right",false]],["EditedProperty",["G₁","Gain Bode","labelX",40,45,false]],["EditedProperty",["G","Somme gains Bode","labelX",10,4,false]],["EditedProperty",["G₀","Gain Bode","labelX",2,20,false]],["EditedProperty",["G₁","Gain Bode","omGraduation",false,true,false]],["EditedProperty",["G₂","Gain Bode","omGraduation",false,true,false]],["EditedProperty",["G","Somme gains Bode","labelX",4,2,false]],["EditedProperty",["G","Somme gains Bode","labelPosition","above","below",false]],["EditedProperty",["G₁","Gain Bode","omGraduation",true,false,false]],["EditedProperty",["ω₁","Point","x","30","0",true]],["EditedVisibility",["ω₁","Point","visible"]],["EditedProperty",["G₁","Gain Bode","gain","(-20)","20",true]],["EditedProperty",["ω₁","Point","x","1","0.05",true]],["EditedProperty",["ω₁","Point","y","0","(-20)",true]],["EditedProperty",["ω₁","Point","x","0.05","0.1",true]],["EditedProperty",["G₁","Gain Bode","labelX",45,2,false]],["EditedProperty",["ω","Point","y","10","(-10)",true]],["EditedProperty",["ω","Point","y","(-10)","(-5)",true]],["EditedProperty",["G","Somme gains Bode","labelX",2,15,false]],["CreateNewObject",["X","X Cursor",["X",true,"#61AD9E","name + value","1",null,"left",true,3,"— — — — — — —","Next to target"]]],["EditedProperty",["X","X Cursor","x","1","50",true]],["EditedProperty",["G₂","Gain Bode","color","#5F04A2","#5f04a2",false]],["EditedProperty",["X","X Cursor","color","#61AD9E","#5f04a2",false]],["CreateNewObject",["text","Text",["text",true,"#242159","null","1","0","center","New text"]]],["EditedProperty",["text","Text","x","1","20",true]],["EditedProperty",["text","Text","x","20","50",true]],["EditedProperty",["text","Text","labelPosition","center","right",false]],["EditedProperty",["text","Text","labelPosition","right","left",false]],["EditedProperty",["text","Text","y","0","20",true]],["EditedProperty",["text","Text","text","New text","10",false]],["EditedProperty",["text","Text","text","10","10ω",false]],["EditedProperty",["text","Text","text","10ω","10ω₂",false]],["EditedProperty",["X","X Cursor","color","#5f04a2","#5f04a2",false]],["EditedProperty",["text","Text","color","#242159","#5f04a2",false]],["EditedProperty",["text","Text","disableLatex",false,true,false]],["EditedProperty",["G₁","Gain Bode","labelPosition","above-right","above-left",false]],["ColorChanged",["G₀","Gain Bode","#94AE66","#00aa00"]],["ColorChanged",["G₀","Gain Bode","#00aa00","#0000ff"]],["ColorChanged",["ω","Point","#94AE66","#0000ff"]],["EditedProperty",["ω₂","Point","labelPosition","top","above-left",false]],["EditedProperty",["ω₂","Point","labelPosition","above-left","below-left",false]],["EditedProperty",["ω₂","Point","labelPosition","below-left","above-right",false]],["EditedProperty",["text","Text","disableLatex",false,true,false]]],[]],"width":961,"height":500,"objects":{"Point":[["ω",false,"#0000ff","name","1","(-5)","top","●"],["ω₁",false,"#A38B4D","name","0.1","(-20)","top","●"],["ω₂",true,"#5F04A2","name","5","0","above-right","●"]],"Gain Bode":[["G₀",true,"#0000ff","name","ω","high","0","above",20,false],["G₁",true,"#A38B4D","name","ω₁","low","20","above-left",2,false],["G₂",true,"#5f04a2","name","ω₂","low","(-20)","below",10,true]],"Somme gains Bode":[["G",true,"#3E6E2A","name + value","below",15]],"X Cursor":[["X",true,"#5f04a2","null","50",null,"left",true,3,"— — — — — — —","Next to target"]],"Text":[["text",true,"#5f04a2","null","50","20","left","10ω₂",false]]},"type":"logplotv1"} diff --git a/ci/phase.lpf b/ci/phase.lpf new file mode 100644 index 0000000..361d157 --- /dev/null +++ b/ci/phase.lpf @@ -0,0 +1 @@ +LPFv1{"xzoom":100,"yzoom":100,"xmin":0.5,"ymax":2,"xaxisstep":"4","yaxisstep":"pi/4","xaxislabel":"ω (rad/s)","yaxislabel":"φ (rad)","logscalex":true,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":20,"history":[[["CreateNewObject",["f","Function",["f",true,"#989E2D","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["f","Function","expression","x","(x ^ 20)",true]],["EditedProperty",["f","Function","expression","(x ^ 20)","(20 * (log10 x))",true]],["DeleteObject",["f","Function",["f",true,"#989E2D","name + value","(20 * (log10 x))","ℝ⁺*","ℝ","application","above",1,true,true]]],["CreateNewObject",["ω","Point",["ω",true,"#995178","name","1","0","bottom","●"]]],["CreateNewObject",["φ₀","Phase Bode",["φ₀",true,"#995178","name + value","ω","90","°","below",1]]],["EditedProperty",["φ₀","Phase Bode","phase","90","0",true]],["EditedProperty",["φ₀","Phase Bode","unit","°","rad",false]],["EditedProperty",["ω","Point","y","0","((-pi) / 2)",true]],["EditedVisibility",["ω","Point","visible"]],["EditedProperty",["φ₀","Phase Bode","labelX",1,10,false]],["CreateNewObject",["ω₀","Point",["ω₀",true,"#037753","name","1","0","bottom","●"]]],["CreateNewObject",["φ₁","Phase Bode",["φ₁",true,"#037753","name + value","ω₀","90","°","below",1]]],["EditedProperty",["ω₀","Point","x","1","10",true]],["EditedProperty",["φ₁","Phase Bode","unit","°","rad",false]],["EditedProperty",["φ₁","Phase Bode","phase","90","(pi / 2)",true]],["EditedProperty",["ω₀","Point","x","10","5",true]],["EditedProperty",["ω₀","Point","labelPosition","bottom","top-left",false]],["EditedProperty",["φ₁","Phase Bode","labelX",1,2,false]],["EditedProperty",["φ","Somme phases Bode","labelX",1,2,false]],["ColorChanged",["φ","Somme phases Bode","#665B74","#550000"]],["EditedProperty",["ω₀","Point","labelPosition","top-left","above-left",false]],["EditedProperty",["ω₀","Point","labelPosition","above-left","above-right",false]]],[]],"width":1000,"height":500,"objects":{"Function":[],"Point":[["ω",false,"#995178","name","1","((-pi) / 2)","below","●"],["ω₀",true,"#037753","name","5","0","above-right","●"]],"Phase Bode":[["φ₀",true,"#995178","name","ω","0","rad","below",10],["φ₁",true,"#037753","name","ω₀","(pi / 2)","rad","below",2]],"Somme phases Bode":[["φ",true,"#550000","name + value","above",2]]},"type":"logplotv1"} \ No newline at end of file diff --git a/ci/stress.lpf b/ci/stress.lpf new file mode 100644 index 0000000..05e171c --- /dev/null +++ b/ci/stress.lpf @@ -0,0 +1 @@ +LPFv1{"xzoom":150,"yzoom":10,"xmin":0.49556664658184385,"ymax":25.120703,"xaxisstep":"4","yaxisstep":"4","xaxislabel":"","yaxislabel":"","logscalex":true,"linewidth":1,"showxgrad":true,"showygrad":true,"textsize":18,"history":[[["CreateNewObject",["A","Point",["A",true,"#A35D32","name + value","1","0","above","●"]]],["CreateNewObject",["B","Point",["B",true,"#AF370C","name + value","1","0","above","●"]]],["CreateNewObject",["C","Point",["C",true,"#AB9221","name + value","1","0","above","●"]]],["CreateNewObject",["D","Point",["D",true,"#43A98E","name + value","1","0","above","●"]]],["CreateNewObject",["E","Point",["E",true,"#1F1C6A","name + value","1","0","above","●"]]],["CreateNewObject",["F","Point",["F",true,"#407099","name + value","1","0","above","●"]]],["CreateNewObject",["J","Point",["J",true,"#9B4B7A","name + value","1","0","above","●"]]],["CreateNewObject",["K","Point",["K",true,"#3B5698","name + value","1","0","above","●"]]],["CreateNewObject",["L","Point",["L",true,"#0C6A4D","name + value","1","0","above","●"]]],["CreateNewObject",["M","Point",["M",true,"#350945","name + value","1","0","above","●"]]],["CreateNewObject",["N","Point",["N",true,"#46511E","name + value","1","0","above","●"]]],["CreateNewObject",["O","Point",["O",true,"#0B318B","name + value","1","0","above","●"]]],["CreateNewObject",["P","Point",["P",true,"#354125","name + value","1","0","above","●"]]],["CreateNewObject",["Q","Point",["Q",true,"#598608","name + value","1","0","above","●"]]],["CreateNewObject",["R","Point",["R",true,"#733D64","name + value","1","0","above","●"]]],["CreateNewObject",["S","Point",["S",true,"#7477A8","name + value","1","0","above","●"]]],["CreateNewObject",["T","Point",["T",true,"#5B6034","name + value","1","0","above","●"]]],["CreateNewObject",["U","Point",["U",true,"#951A57","name + value","1","0","above","●"]]],["CreateNewObject",["V","Point",["V",true,"#72804E","name + value","1","0","above","●"]]],["CreateNewObject",["W","Point",["W",true,"#7B1070","name + value","1","0","above","●"]]],["CreateNewObject",["A₀","Point",["A₀",true,"#AFA71F","name + value","1","0","above","●"]]],["CreateNewObject",["B₀","Point",["B₀",true,"#121733","name + value","1","0","above","●"]]],["CreateNewObject",["C₀","Point",["C₀",true,"#363740","name + value","1","0","above","●"]]],["CreateNewObject",["D₀","Point",["D₀",true,"#96896E","name + value","1","0","above","●"]]],["CreateNewObject",["E₀","Point",["E₀",true,"#051126","name + value","1","0","above","●"]]],["CreateNewObject",["F₀","Point",["F₀",true,"#2F004D","name + value","1","0","above","●"]]],["CreateNewObject",["J₀","Point",["J₀",true,"#4B064D","name + value","1","0","above","●"]]],["CreateNewObject",["K₀","Point",["K₀",true,"#7D6527","name + value","1","0","above","●"]]],["CreateNewObject",["L₀","Point",["L₀",true,"#55725F","name + value","1","0","above","●"]]],["CreateNewObject",["M₀","Point",["M₀",true,"#A09E28","name + value","1","0","above","●"]]],["CreateNewObject",["N₀","Point",["N₀",true,"#3A7E1A","name + value","1","0","above","●"]]],["CreateNewObject",["O₀","Point",["O₀",true,"#905361","name + value","1","0","above","●"]]],["CreateNewObject",["P₀","Point",["P₀",true,"#824C96","name + value","1","0","above","●"]]],["CreateNewObject",["t","Text",["t",true,"#7F6A2B","null","1","0","center","New text",false]]],["CreateNewObject",["Q₀","Point",["Q₀",true,"#0B919F","name + value","1","0","above","●"]]],["CreateNewObject",["R₀","Point",["R₀",true,"#308188","name + value","1","0","above","●"]]],["CreateNewObject",["S₀","Point",["S₀",true,"#434DA2","name + value","1","0","above","●"]]],["CreateNewObject",["T₀","Point",["T₀",true,"#5A4455","name + value","1","0","above","●"]]],["CreateNewObject",["U₀","Point",["U₀",true,"#289954","name + value","1","0","above","●"]]],["CreateNewObject",["V₀","Point",["V₀",true,"#5D2371","name + value","1","0","above","●"]]],["CreateNewObject",["W₀","Point",["W₀",true,"#9E9F13","name + value","1","0","above","●"]]],["CreateNewObject",["A₁","Point",["A₁",true,"#6B8E7A","name + value","1","0","above","●"]]],["CreateNewObject",["B₁","Point",["B₁",true,"#25186C","name + value","1","0","above","●"]]],["CreateNewObject",["C₁","Point",["C₁",true,"#8FA8AD","name + value","1","0","above","●"]]],["CreateNewObject",["D₁","Point",["D₁",true,"#5D4528","name + value","1","0","above","●"]]],["CreateNewObject",["E₁","Point",["E₁",true,"#26435D","name + value","1","0","above","●"]]],["CreateNewObject",["F₁","Point",["F₁",true,"#6B7C9C","name + value","1","0","above","●"]]],["CreateNewObject",["J₁","Point",["J₁",true,"#96275E","name + value","1","0","above","●"]]],["CreateNewObject",["K₁","Point",["K₁",true,"#3DAF12","name + value","1","0","above","●"]]],["CreateNewObject",["L₁","Point",["L₁",true,"#1EA902","name + value","1","0","above","●"]]],["CreateNewObject",["t₀","Text",["t₀",true,"#511C6A","null","1","0","center","New text",false]]],["CreateNewObject",["M₁","Point",["M₁",true,"#515D07","name + value","1","0","above","●"]]],["CreateNewObject",["N₁","Point",["N₁",true,"#711764","name + value","1","0","above","●"]]],["CreateNewObject",["O₁","Point",["O₁",true,"#732C94","name + value","1","0","above","●"]]],["CreateNewObject",["P₁","Point",["P₁",true,"#66174C","name + value","1","0","above","●"]]],["CreateNewObject",["Q₁","Point",["Q₁",true,"#75816A","name + value","1","0","above","●"]]],["CreateNewObject",["R₁","Point",["R₁",true,"#AF8C59","name + value","1","0","above","●"]]],["CreateNewObject",["S₁","Point",["S₁",true,"#1E446B","name + value","1","0","above","●"]]],["CreateNewObject",["T₁","Point",["T₁",true,"#A58DA6","name + value","1","0","above","●"]]],["CreateNewObject",["U₁","Point",["U₁",true,"#912D54","name + value","1","0","above","●"]]],["CreateNewObject",["V₁","Point",["V₁",true,"#8E8886","name + value","1","0","above","●"]]],["CreateNewObject",["W₁","Point",["W₁",true,"#26602E","name + value","1","0","above","●"]]],["CreateNewObject",["A₂","Point",["A₂",true,"#8C6064","name + value","1","0","above","●"]]],["CreateNewObject",["B₂","Point",["B₂",true,"#431889","name + value","1","0","above","●"]]],["CreateNewObject",["C₂","Point",["C₂",true,"#8D6959","name + value","1","0","above","●"]]],["CreateNewObject",["D₂","Point",["D₂",true,"#A57776","name + value","1","0","above","●"]]],["CreateNewObject",["E₂","Point",["E₂",true,"#312374","name + value","1","0","above","●"]]],["CreateNewObject",["F₂","Point",["F₂",true,"#3D3150","name + value","1","0","above","●"]]],["CreateNewObject",["J₂","Point",["J₂",true,"#6F9C66","name + value","1","0","above","●"]]],["CreateNewObject",["t₁","Text",["t₁",true,"#84223B","null","1","0","center","New text",false]]],["CreateNewObject",["K₂","Point",["K₂",true,"#3C2899","name + value","1","0","above","●"]]],["CreateNewObject",["L₂","Point",["L₂",true,"#753355","name + value","1","0","above","●"]]],["CreateNewObject",["M₂","Point",["M₂",true,"#3F046A","name + value","1","0","above","●"]]],["CreateNewObject",["N₂","Point",["N₂",true,"#9E4B51","name + value","1","0","above","●"]]],["CreateNewObject",["O₂","Point",["O₂",true,"#199B64","name + value","1","0","above","●"]]],["CreateNewObject",["P₂","Point",["P₂",true,"#59893D","name + value","1","0","above","●"]]],["CreateNewObject",["Q₂","Point",["Q₂",true,"#944D3E","name + value","1","0","above","●"]]],["CreateNewObject",["R₂","Point",["R₂",true,"#8D8836","name + value","1","0","above","●"]]],["CreateNewObject",["S₂","Point",["S₂",true,"#A52589","name + value","1","0","above","●"]]],["CreateNewObject",["t₂","Text",["t₂",true,"#A10A90","null","1","0","center","New text",false]]],["CreateNewObject",["T₂","Point",["T₂",true,"#7F723D","name + value","1","0","above","●"]]],["CreateNewObject",["U₂","Point",["U₂",true,"#78AB96","name + value","1","0","above","●"]]],["CreateNewObject",["V₂","Point",["V₂",true,"#626A23","name + value","1","0","above","●"]]],["CreateNewObject",["W₂","Point",["W₂",true,"#401362","name + value","1","0","above","●"]]],["CreateNewObject",["A₃","Point",["A₃",true,"#9F0E30","name + value","1","0","above","●"]]],["CreateNewObject",["B₃","Point",["B₃",true,"#100C0E","name + value","1","0","above","●"]]],["CreateNewObject",["C₃","Point",["C₃",true,"#858161","name + value","1","0","above","●"]]],["CreateNewObject",["D₃","Point",["D₃",true,"#7482A8","name + value","1","0","above","●"]]],["CreateNewObject",["E₃","Point",["E₃",true,"#0D03A3","name + value","1","0","above","●"]]],["CreateNewObject",["F₃","Point",["F₃",true,"#652922","name + value","1","0","above","●"]]],["CreateNewObject",["J₃","Point",["J₃",true,"#39A671","name + value","1","0","above","●"]]],["CreateNewObject",["K₃","Point",["K₃",true,"#4E0481","name + value","1","0","above","●"]]],["CreateNewObject",["L₃","Point",["L₃",true,"#1F9239","name + value","1","0","above","●"]]],["CreateNewObject",["M₃","Point",["M₃",true,"#986A07","name + value","1","0","above","●"]]],["CreateNewObject",["N₃","Point",["N₃",true,"#4AAE1F","name + value","1","0","above","●"]]],["CreateNewObject",["O₃","Point",["O₃",true,"#3C0911","name + value","1","0","above","●"]]],["CreateNewObject",["P₃","Point",["P₃",true,"#400A42","name + value","1","0","above","●"]]],["CreateNewObject",["Q₃","Point",["Q₃",true,"#9A9C5F","name + value","1","0","above","●"]]],["CreateNewObject",["R₃","Point",["R₃",true,"#AB7FA9","name + value","1","0","above","●"]]],["CreateNewObject",["S₃","Point",["S₃",true,"#4E9D33","name + value","1","0","above","●"]]],["CreateNewObject",["T₃","Point",["T₃",true,"#564E4C","name + value","1","0","above","●"]]],["CreateNewObject",["U₃","Point",["U₃",true,"#674739","name + value","1","0","above","●"]]],["CreateNewObject",["V₃","Point",["V₃",true,"#5D689B","name + value","1","0","above","●"]]],["CreateNewObject",["W₃","Point",["W₃",true,"#6B8E57","name + value","1","0","above","●"]]],["CreateNewObject",["A₄","Point",["A₄",true,"#169C3E","name + value","1","0","above","●"]]],["CreateNewObject",["B₄","Point",["B₄",true,"#95104E","name + value","1","0","above","●"]]],["CreateNewObject",["C₄","Point",["C₄",true,"#73379E","name + value","1","0","above","●"]]],["CreateNewObject",["D₄","Point",["D₄",true,"#98143F","name + value","1","0","above","●"]]],["CreateNewObject",["E₄","Point",["E₄",true,"#A8926F","name + value","1","0","above","●"]]],["CreateNewObject",["F₄","Point",["F₄",true,"#3172AB","name + value","1","0","above","●"]]],["CreateNewObject",["J₄","Point",["J₄",true,"#8A9C96","name + value","1","0","above","●"]]],["CreateNewObject",["K₄","Point",["K₄",true,"#AF001D","name + value","1","0","above","●"]]],["CreateNewObject",["L₄","Point",["L₄",true,"#711495","name + value","1","0","above","●"]]],["CreateNewObject",["M₄","Point",["M₄",true,"#082241","name + value","1","0","above","●"]]],["CreateNewObject",["N₄","Point",["N₄",true,"#631582","name + value","1","0","above","●"]]],["CreateNewObject",["O₄","Point",["O₄",true,"#895378","name + value","1","0","above","●"]]],["CreateNewObject",["P₄","Point",["P₄",true,"#812404","name + value","1","0","above","●"]]],["CreateNewObject",["Q₄","Point",["Q₄",true,"#3B2755","name + value","1","0","above","●"]]],["CreateNewObject",["R₄","Point",["R₄",true,"#5B6E03","name + value","1","0","above","●"]]],["CreateNewObject",["S₄","Point",["S₄",true,"#AF4237","name + value","1","0","above","●"]]],["CreateNewObject",["T₄","Point",["T₄",true,"#9C75AC","name + value","1","0","above","●"]]],["CreateNewObject",["U₄","Point",["U₄",true,"#926178","name + value","1","0","above","●"]]],["CreateNewObject",["V₄","Point",["V₄",true,"#8C3DA7","name + value","1","0","above","●"]]],["CreateNewObject",["W₄","Point",["W₄",true,"#95843C","name + value","1","0","above","●"]]],["CreateNewObject",["A₅","Point",["A₅",true,"#022359","name + value","1","0","above","●"]]],["CreateNewObject",["B₅","Point",["B₅",true,"#8B906E","name + value","1","0","above","●"]]],["CreateNewObject",["C₅","Point",["C₅",true,"#317B9A","name + value","1","0","above","●"]]],["CreateNewObject",["D₅","Point",["D₅",true,"#559232","name + value","1","0","above","●"]]],["CreateNewObject",["E₅","Point",["E₅",true,"#9324A5","name + value","1","0","above","●"]]],["CreateNewObject",["F₅","Point",["F₅",true,"#574940","name + value","1","0","above","●"]]],["CreateNewObject",["J₅","Point",["J₅",true,"#A93968","name + value","1","0","above","●"]]],["CreateNewObject",["K₅","Point",["K₅",true,"#1F6266","name + value","1","0","above","●"]]],["CreateNewObject",["L₅","Point",["L₅",true,"#181928","name + value","1","0","above","●"]]],["CreateNewObject",["M₅","Point",["M₅",true,"#760C13","name + value","1","0","above","●"]]],["CreateNewObject",["N₅","Point",["N₅",true,"#366B7E","name + value","1","0","above","●"]]],["CreateNewObject",["O₅","Point",["O₅",true,"#8E6060","name + value","1","0","above","●"]]],["CreateNewObject",["P₅","Point",["P₅",true,"#A8158D","name + value","1","0","above","●"]]],["CreateNewObject",["Q₅","Point",["Q₅",true,"#1D206C","name + value","1","0","above","●"]]],["CreateNewObject",["R₅","Point",["R₅",true,"#9C6169","name + value","1","0","above","●"]]],["CreateNewObject",["S₅","Point",["S₅",true,"#6F412F","name + value","1","0","above","●"]]],["CreateNewObject",["T₅","Point",["T₅",true,"#0B2453","name + value","1","0","above","●"]]],["CreateNewObject",["U₅","Point",["U₅",true,"#04839E","name + value","1","0","above","●"]]],["CreateNewObject",["V₅","Point",["V₅",true,"#8B29A5","name + value","1","0","above","●"]]],["CreateNewObject",["W₅","Point",["W₅",true,"#491438","name + value","1","0","above","●"]]],["CreateNewObject",["A₆","Point",["A₆",true,"#00087B","name + value","1","0","above","●"]]],["CreateNewObject",["B₆","Point",["B₆",true,"#0F431C","name + value","1","0","above","●"]]],["CreateNewObject",["C₆","Point",["C₆",true,"#1D3B07","name + value","1","0","above","●"]]],["CreateNewObject",["D₆","Point",["D₆",true,"#7F695A","name + value","1","0","above","●"]]],["CreateNewObject",["E₆","Point",["E₆",true,"#AB4383","name + value","1","0","above","●"]]],["CreateNewObject",["F₆","Point",["F₆",true,"#9C9E78","name + value","1","0","above","●"]]],["CreateNewObject",["J₆","Point",["J₆",true,"#243945","name + value","1","0","above","●"]]],["CreateNewObject",["K₆","Point",["K₆",true,"#A49EAA","name + value","1","0","above","●"]]],["CreateNewObject",["L₆","Point",["L₆",true,"#822C32","name + value","1","0","above","●"]]],["CreateNewObject",["M₆","Point",["M₆",true,"#095D68","name + value","1","0","above","●"]]],["CreateNewObject",["N₆","Point",["N₆",true,"#AA361D","name + value","1","0","above","●"]]],["CreateNewObject",["O₆","Point",["O₆",true,"#045B40","name + value","1","0","above","●"]]],["CreateNewObject",["P₆","Point",["P₆",true,"#2B10AD","name + value","1","0","above","●"]]],["CreateNewObject",["Q₆","Point",["Q₆",true,"#8F0607","name + value","1","0","above","●"]]],["CreateNewObject",["R₆","Point",["R₆",true,"#953472","name + value","1","0","above","●"]]],["CreateNewObject",["S₆","Point",["S₆",true,"#7F7663","name + value","1","0","above","●"]]],["CreateNewObject",["T₆","Point",["T₆",true,"#9A4294","name + value","1","0","above","●"]]],["CreateNewObject",["U₆","Point",["U₆",true,"#924762","name + value","1","0","above","●"]]],["CreateNewObject",["V₆","Point",["V₆",true,"#006385","name + value","1","0","above","●"]]],["CreateNewObject",["W₆","Point",["W₆",true,"#8C0504","name + value","1","0","above","●"]]],["CreateNewObject",["A₇","Point",["A₇",true,"#337BA0","name + value","1","0","above","●"]]],["CreateNewObject",["B₇","Point",["B₇",true,"#970A47","name + value","1","0","above","●"]]],["CreateNewObject",["C₇","Point",["C₇",true,"#8D071F","name + value","1","0","above","●"]]],["CreateNewObject",["D₇","Point",["D₇",true,"#241417","name + value","1","0","above","●"]]],["CreateNewObject",["E₇","Point",["E₇",true,"#8DAB44","name + value","1","0","above","●"]]],["CreateNewObject",["F₇","Point",["F₇",true,"#555D7B","name + value","1","0","above","●"]]],["CreateNewObject",["J₇","Point",["J₇",true,"#537A31","name + value","1","0","above","●"]]],["CreateNewObject",["K₇","Point",["K₇",true,"#298D88","name + value","1","0","above","●"]]],["CreateNewObject",["L₇","Point",["L₇",true,"#55249C","name + value","1","0","above","●"]]],["CreateNewObject",["M₇","Point",["M₇",true,"#AB5E71","name + value","1","0","above","●"]]],["CreateNewObject",["N₇","Point",["N₇",true,"#834D89","name + value","1","0","above","●"]]],["CreateNewObject",["O₇","Point",["O₇",true,"#7B4EAC","name + value","1","0","above","●"]]],["CreateNewObject",["P₇","Point",["P₇",true,"#451133","name + value","1","0","above","●"]]],["CreateNewObject",["Q₇","Point",["Q₇",true,"#07410B","name + value","1","0","above","●"]]],["CreateNewObject",["R₇","Point",["R₇",true,"#5D0B61","name + value","1","0","above","●"]]],["CreateNewObject",["S₇","Point",["S₇",true,"#1F184F","name + value","1","0","above","●"]]],["CreateNewObject",["T₇","Point",["T₇",true,"#897283","name + value","1","0","above","●"]]],["CreateNewObject",["U₇","Point",["U₇",true,"#079906","name + value","1","0","above","●"]]],["CreateNewObject",["V₇","Point",["V₇",true,"#1DA545","name + value","1","0","above","●"]]],["CreateNewObject",["W₇","Point",["W₇",true,"#4E4A71","name + value","1","0","above","●"]]],["CreateNewObject",["A₈","Point",["A₈",true,"#563577","name + value","1","0","above","●"]]],["CreateNewObject",["B₈","Point",["B₈",true,"#6FA324","name + value","1","0","above","●"]]],["CreateNewObject",["C₈","Point",["C₈",true,"#099187","name + value","1","0","above","●"]]],["CreateNewObject",["D₈","Point",["D₈",true,"#0F976A","name + value","1","0","above","●"]]],["CreateNewObject",["E₈","Point",["E₈",true,"#525B2F","name + value","1","0","above","●"]]],["CreateNewObject",["F₈","Point",["F₈",true,"#249C5A","name + value","1","0","above","●"]]],["CreateNewObject",["J₈","Point",["J₈",true,"#359EAD","name + value","1","0","above","●"]]],["CreateNewObject",["K₈","Point",["K₈",true,"#014113","name + value","1","0","above","●"]]],["CreateNewObject",["L₈","Point",["L₈",true,"#992D2C","name + value","1","0","above","●"]]],["CreateNewObject",["M₈","Point",["M₈",true,"#2A9D50","name + value","1","0","above","●"]]],["CreateNewObject",["N₈","Point",["N₈",true,"#3BA6A8","name + value","1","0","above","●"]]],["CreateNewObject",["O₈","Point",["O₈",true,"#2F2BAB","name + value","1","0","above","●"]]],["CreateNewObject",["P₈","Point",["P₈",true,"#A35282","name + value","1","0","above","●"]]],["CreateNewObject",["Q₈","Point",["Q₈",true,"#346C86","name + value","1","0","above","●"]]],["CreateNewObject",["R₈","Point",["R₈",true,"#738755","name + value","1","0","above","●"]]],["CreateNewObject",["S₈","Point",["S₈",true,"#2E302D","name + value","1","0","above","●"]]],["CreateNewObject",["T₈","Point",["T₈",true,"#187E5B","name + value","1","0","above","●"]]],["CreateNewObject",["U₈","Point",["U₈",true,"#4B868E","name + value","1","0","above","●"]]],["CreateNewObject",["V₈","Point",["V₈",true,"#13937C","name + value","1","0","above","●"]]],["CreateNewObject",["W₈","Point",["W₈",true,"#938E72","name + value","1","0","above","●"]]]],[]],"width":1000,"height":500,"objects":{"Point":[["A",true,"#A35D32","name + value","1","0","above","●"],["B",true,"#AF370C","name + value","1","0","above","●"],["C",true,"#AB9221","name + value","1","0","above","●"],["D",true,"#43A98E","name + value","1","0","above","●"],["E",true,"#1F1C6A","name + value","1","0","above","●"],["F",true,"#407099","name + value","1","0","above","●"],["J",true,"#9B4B7A","name + value","1","0","above","●"],["K",true,"#3B5698","name + value","1","0","above","●"],["L",true,"#0C6A4D","name + value","1","0","above","●"],["M",true,"#350945","name + value","1","0","above","●"],["N",true,"#46511E","name + value","1","0","above","●"],["O",true,"#0B318B","name + value","1","0","above","●"],["P",true,"#354125","name + value","1","0","above","●"],["Q",true,"#598608","name + value","1","0","above","●"],["R",true,"#733D64","name + value","1","0","above","●"],["S",true,"#7477A8","name + value","1","0","above","●"],["T",true,"#5B6034","name + value","1","0","above","●"],["U",true,"#951A57","name + value","1","0","above","●"],["V",true,"#72804E","name + value","1","0","above","●"],["W",true,"#7B1070","name + value","1","0","above","●"],["A₀",true,"#AFA71F","name + value","1","0","above","●"],["B₀",true,"#121733","name + value","1","0","above","●"],["C₀",true,"#363740","name + value","1","0","above","●"],["D₀",true,"#96896E","name + value","1","0","above","●"],["E₀",true,"#051126","name + value","1","0","above","●"],["F₀",true,"#2F004D","name + value","1","0","above","●"],["J₀",true,"#4B064D","name + value","1","0","above","●"],["K₀",true,"#7D6527","name + value","1","0","above","●"],["L₀",true,"#55725F","name + value","1","0","above","●"],["M₀",true,"#A09E28","name + value","1","0","above","●"],["N₀",true,"#3A7E1A","name + value","1","0","above","●"],["O₀",true,"#905361","name + value","1","0","above","●"],["P₀",true,"#824C96","name + value","1","0","above","●"],["Q₀",true,"#0B919F","name + value","1","0","above","●"],["R₀",true,"#308188","name + value","1","0","above","●"],["S₀",true,"#434DA2","name + value","1","0","above","●"],["T₀",true,"#5A4455","name + value","1","0","above","●"],["U₀",true,"#289954","name + value","1","0","above","●"],["V₀",true,"#5D2371","name + value","1","0","above","●"],["W₀",true,"#9E9F13","name + value","1","0","above","●"],["A₁",true,"#6B8E7A","name + value","1","0","above","●"],["B₁",true,"#25186C","name + value","1","0","above","●"],["C₁",true,"#8FA8AD","name + value","1","0","above","●"],["D₁",true,"#5D4528","name + value","1","0","above","●"],["E₁",true,"#26435D","name + value","1","0","above","●"],["F₁",true,"#6B7C9C","name + value","1","0","above","●"],["J₁",true,"#96275E","name + value","1","0","above","●"],["K₁",true,"#3DAF12","name + value","1","0","above","●"],["L₁",true,"#1EA902","name + value","1","0","above","●"],["M₁",true,"#515D07","name + value","1","0","above","●"],["N₁",true,"#711764","name + value","1","0","above","●"],["O₁",true,"#732C94","name + value","1","0","above","●"],["P₁",true,"#66174C","name + value","1","0","above","●"],["Q₁",true,"#75816A","name + value","1","0","above","●"],["R₁",true,"#AF8C59","name + value","1","0","above","●"],["S₁",true,"#1E446B","name + value","1","0","above","●"],["T₁",true,"#A58DA6","name + value","1","0","above","●"],["U₁",true,"#912D54","name + value","1","0","above","●"],["V₁",true,"#8E8886","name + value","1","0","above","●"],["W₁",true,"#26602E","name + value","1","0","above","●"],["A₂",true,"#8C6064","name + value","1","0","above","●"],["B₂",true,"#431889","name + value","1","0","above","●"],["C₂",true,"#8D6959","name + value","1","0","above","●"],["D₂",true,"#A57776","name + value","1","0","above","●"],["E₂",true,"#312374","name + value","1","0","above","●"],["F₂",true,"#3D3150","name + value","1","0","above","●"],["J₂",true,"#6F9C66","name + value","1","0","above","●"],["K₂",true,"#3C2899","name + value","1","0","above","●"],["L₂",true,"#753355","name + value","1","0","above","●"],["M₂",true,"#3F046A","name + value","1","0","above","●"],["N₂",true,"#9E4B51","name + value","1","0","above","●"],["O₂",true,"#199B64","name + value","1","0","above","●"],["P₂",true,"#59893D","name + value","1","0","above","●"],["Q₂",true,"#944D3E","name + value","1","0","above","●"],["R₂",true,"#8D8836","name + value","1","0","above","●"],["S₂",true,"#A52589","name + value","1","0","above","●"],["T₂",true,"#7F723D","name + value","1","0","above","●"],["U₂",true,"#78AB96","name + value","1","0","above","●"],["V₂",true,"#626A23","name + value","1","0","above","●"],["W₂",true,"#401362","name + value","1","0","above","●"],["A₃",true,"#9F0E30","name + value","1","0","above","●"],["B₃",true,"#100C0E","name + value","1","0","above","●"],["C₃",true,"#858161","name + value","1","0","above","●"],["D₃",true,"#7482A8","name + value","1","0","above","●"],["E₃",true,"#0D03A3","name + value","1","0","above","●"],["F₃",true,"#652922","name + value","1","0","above","●"],["J₃",true,"#39A671","name + value","1","0","above","●"],["K₃",true,"#4E0481","name + value","1","0","above","●"],["L₃",true,"#1F9239","name + value","1","0","above","●"],["M₃",true,"#986A07","name + value","1","0","above","●"],["N₃",true,"#4AAE1F","name + value","1","0","above","●"],["O₃",true,"#3C0911","name + value","1","0","above","●"],["P₃",true,"#400A42","name + value","1","0","above","●"],["Q₃",true,"#9A9C5F","name + value","1","0","above","●"],["R₃",true,"#AB7FA9","name + value","1","0","above","●"],["S₃",true,"#4E9D33","name + value","1","0","above","●"],["T₃",true,"#564E4C","name + value","1","0","above","●"],["U₃",true,"#674739","name + value","1","0","above","●"],["V₃",true,"#5D689B","name + value","1","0","above","●"],["W₃",true,"#6B8E57","name + value","1","0","above","●"],["A₄",true,"#169C3E","name + value","1","0","above","●"],["B₄",true,"#95104E","name + value","1","0","above","●"],["C₄",true,"#73379E","name + value","1","0","above","●"],["D₄",true,"#98143F","name + value","1","0","above","●"],["E₄",true,"#A8926F","name + value","1","0","above","●"],["F₄",true,"#3172AB","name + value","1","0","above","●"],["J₄",true,"#8A9C96","name + value","1","0","above","●"],["K₄",true,"#AF001D","name + value","1","0","above","●"],["L₄",true,"#711495","name + value","1","0","above","●"],["M₄",true,"#082241","name + value","1","0","above","●"],["N₄",true,"#631582","name + value","1","0","above","●"],["O₄",true,"#895378","name + value","1","0","above","●"],["P₄",true,"#812404","name + value","1","0","above","●"],["Q₄",true,"#3B2755","name + value","1","0","above","●"],["R₄",true,"#5B6E03","name + value","1","0","above","●"],["S₄",true,"#AF4237","name + value","1","0","above","●"],["T₄",true,"#9C75AC","name + value","1","0","above","●"],["U₄",true,"#926178","name + value","1","0","above","●"],["V₄",true,"#8C3DA7","name + value","1","0","above","●"],["W₄",true,"#95843C","name + value","1","0","above","●"],["A₅",true,"#022359","name + value","1","0","above","●"],["B₅",true,"#8B906E","name + value","1","0","above","●"],["C₅",true,"#317B9A","name + value","1","0","above","●"],["D₅",true,"#559232","name + value","1","0","above","●"],["E₅",true,"#9324A5","name + value","1","0","above","●"],["F₅",true,"#574940","name + value","1","0","above","●"],["J₅",true,"#A93968","name + value","1","0","above","●"],["K₅",true,"#1F6266","name + value","1","0","above","●"],["L₅",true,"#181928","name + value","1","0","above","●"],["M₅",true,"#760C13","name + value","1","0","above","●"],["N₅",true,"#366B7E","name + value","1","0","above","●"],["O₅",true,"#8E6060","name + value","1","0","above","●"],["P₅",true,"#A8158D","name + value","1","0","above","●"],["Q₅",true,"#1D206C","name + value","1","0","above","●"],["R₅",true,"#9C6169","name + value","1","0","above","●"],["S₅",true,"#6F412F","name + value","1","0","above","●"],["T₅",true,"#0B2453","name + value","1","0","above","●"],["U₅",true,"#04839E","name + value","1","0","above","●"],["V₅",true,"#8B29A5","name + value","1","0","above","●"],["W₅",true,"#491438","name + value","1","0","above","●"],["A₆",true,"#00087B","name + value","1","0","above","●"],["B₆",true,"#0F431C","name + value","1","0","above","●"],["C₆",true,"#1D3B07","name + value","1","0","above","●"],["D₆",true,"#7F695A","name + value","1","0","above","●"],["E₆",true,"#AB4383","name + value","1","0","above","●"],["F₆",true,"#9C9E78","name + value","1","0","above","●"],["J₆",true,"#243945","name + value","1","0","above","●"],["K₆",true,"#A49EAA","name + value","1","0","above","●"],["L₆",true,"#822C32","name + value","1","0","above","●"],["M₆",true,"#095D68","name + value","1","0","above","●"],["N₆",true,"#AA361D","name + value","1","0","above","●"],["O₆",true,"#045B40","name + value","1","0","above","●"],["P₆",true,"#2B10AD","name + value","1","0","above","●"],["Q₆",true,"#8F0607","name + value","1","0","above","●"],["R₆",true,"#953472","name + value","1","0","above","●"],["S₆",true,"#7F7663","name + value","1","0","above","●"],["T₆",true,"#9A4294","name + value","1","0","above","●"],["U₆",true,"#924762","name + value","1","0","above","●"],["V₆",true,"#006385","name + value","1","0","above","●"],["W₆",true,"#8C0504","name + value","1","0","above","●"],["A₇",true,"#337BA0","name + value","1","0","above","●"],["B₇",true,"#970A47","name + value","1","0","above","●"],["C₇",true,"#8D071F","name + value","1","0","above","●"],["D₇",true,"#241417","name + value","1","0","above","●"],["E₇",true,"#8DAB44","name + value","1","0","above","●"],["F₇",true,"#555D7B","name + value","1","0","above","●"],["J₇",true,"#537A31","name + value","1","0","above","●"],["K₇",true,"#298D88","name + value","1","0","above","●"],["L₇",true,"#55249C","name + value","1","0","above","●"],["M₇",true,"#AB5E71","name + value","1","0","above","●"],["N₇",true,"#834D89","name + value","1","0","above","●"],["O₇",true,"#7B4EAC","name + value","1","0","above","●"],["P₇",true,"#451133","name + value","1","0","above","●"],["Q₇",true,"#07410B","name + value","1","0","above","●"],["R₇",true,"#5D0B61","name + value","1","0","above","●"],["S₇",true,"#1F184F","name + value","1","0","above","●"],["T₇",true,"#897283","name + value","1","0","above","●"],["U₇",true,"#079906","name + value","1","0","above","●"],["V₇",true,"#1DA545","name + value","1","0","above","●"],["W₇",true,"#4E4A71","name + value","1","0","above","●"],["A₈",true,"#563577","name + value","1","0","above","●"],["B₈",true,"#6FA324","name + value","1","0","above","●"],["C₈",true,"#099187","name + value","1","0","above","●"],["D₈",true,"#0F976A","name + value","1","0","above","●"],["E₈",true,"#525B2F","name + value","1","0","above","●"],["F₈",true,"#249C5A","name + value","1","0","above","●"],["J₈",true,"#359EAD","name + value","1","0","above","●"],["K₈",true,"#014113","name + value","1","0","above","●"],["L₈",true,"#992D2C","name + value","1","0","above","●"],["M₈",true,"#2A9D50","name + value","1","0","above","●"],["N₈",true,"#3BA6A8","name + value","1","0","above","●"],["O₈",true,"#2F2BAB","name + value","1","0","above","●"],["P₈",true,"#A35282","name + value","1","0","above","●"],["Q₈",true,"#346C86","name + value","1","0","above","●"],["R₈",true,"#738755","name + value","1","0","above","●"],["S₈",true,"#2E302D","name + value","1","0","above","●"],["T₈",true,"#187E5B","name + value","1","0","above","●"],["U₈",true,"#4B868E","name + value","1","0","above","●"],["V₈",true,"#13937C","name + value","1","0","above","●"],["W₈",true,"#938E72","name + value","1","0","above","●"]],"Text":[["t",true,"#7F6A2B","null","1","0","center","New text",false],["t₀",true,"#511C6A","null","1","0","center","New text",false],["t₁",true,"#84223B","null","1","0","center","New text",false],["t₂",true,"#A10A90","null","1","0","center","New text",false]]},"type":"logplotv1"} \ No newline at end of file From 45fef876ecca035d14955dee8319aaa8ebd20fe5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 28 Oct 2024 19:09:25 +0100 Subject: [PATCH 233/249] Fixing issue with margins being shown despite an object not being displayed. --- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index c2a5a23..3b59e0a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -56,7 +56,7 @@ ScrollView { property var editingRows: [] model: Modules.Objects.currentObjects[objType] width: objectsListView.width - height: contentItem.childrenRect.height + 10 + height: contentItem.childrenRect.height + (visible ? 10 : 0) visible: model != undefined && model.length > 0 interactive: false From 440575325e6d3e7934fa7b8362d546e783d55c97 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 28 Oct 2024 23:04:42 +0100 Subject: [PATCH 234/249] Fixing Helper version importing. --- runtime-pyside6/LogarithmPlotter/util/helper.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index 7f7afb9..cc6bff4 100644 --- a/runtime-pyside6/LogarithmPlotter/util/helper.py +++ b/runtime-pyside6/LogarithmPlotter/util/helper.py @@ -16,10 +16,9 @@ * along with this program. If not, see . """ from PySide6.QtWidgets import QMessageBox, QApplication -from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication +from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication, __version__ as PySide6_version from PySide6.QtQml import QJSValue from PySide6.QtGui import QImage -from PySide6 import __version__ as PySide6_version from os import chdir, path from json import loads From 8429ff3739866dafffdbada43feddfdc60480db7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 28 Oct 2024 23:05:55 +0100 Subject: [PATCH 235/249] Updating dependencies locK. --- common/package-lock.json | 4 +- runtime-pyside6/poetry.lock | 216 ++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 109 deletions(-) diff --git a/common/package-lock.json b/common/package-lock.json index 5df6794..0e01b59 100644 --- a/common/package-lock.json +++ b/common/package-lock.json @@ -13,13 +13,13 @@ "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", - "@types/chai-as-promised": "^8.0.1", "c8": "^10.1.2", "rollup": "^4.22.4", "rollup-plugin-cleanup": "^3.2.1" }, "devDependencies": { "@types/chai": "^5.0.0", + "@types/chai-as-promised": "^8.0.1", "@types/chai-spies": "^1.0.6", "@types/mocha": "^10.0.8", "chai": "^5.1.1", @@ -2199,12 +2199,14 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.0.tgz", "integrity": "sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA==", + "dev": true, "license": "MIT" }, "node_modules/@types/chai-as-promised": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.1.tgz", "integrity": "sha512-dAlDhLjJlABwAVYObo9TPWYTRg9NaQM5CXeaeJYcYAkvzUf0JRLIiog88ao2Wqy/20WUnhbbUZcgvngEbJ3YXQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/chai": "*" diff --git a/runtime-pyside6/poetry.lock b/runtime-pyside6/poetry.lock index 07252a5..250fc64 100644 --- a/runtime-pyside6/poetry.lock +++ b/runtime-pyside6/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "altgraph" @@ -24,73 +24,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.2" +version = "7.6.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, - {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, - {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, - {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, - {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, - {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, - {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, - {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, - {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, - {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, - {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, - {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, - {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, - {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, - {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, - {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, + {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, + {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, + {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, + {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, + {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, + {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, + {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, + {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, + {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, + {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, + {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, + {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, + {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, + {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, + {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, + {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, + {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, + {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, + {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, + {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, + {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, + {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, + {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, + {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, + {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, + {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, ] [package.dependencies] @@ -174,13 +174,13 @@ files = [ [[package]] name = "pefile" -version = "2024.8.26" +version = "2023.2.7" description = "Python PE parsing module" optional = false python-versions = ">=3.6.0" files = [ - {file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"}, - {file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"}, + {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"}, + {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"}, ] [[package]] @@ -200,23 +200,23 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyinstaller" -version = "6.10.0" +version = "6.11.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false python-versions = "<3.14,>=3.8" files = [ - {file = "pyinstaller-6.10.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d60fb22859e11483af735aec115fdde09467cdbb29edd9844839f2c920b748c0"}, - {file = "pyinstaller-6.10.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:46d75359668993ddd98630a3669dc5249f3c446e35239b43bc7f4155bc574748"}, - {file = "pyinstaller-6.10.0-py3-none-manylinux2014_i686.whl", hash = "sha256:3398a98fa17d47ccb31f8779ecbdacec025f7adb2f22757a54b706ac8b4fe906"}, - {file = "pyinstaller-6.10.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e9989f354ae4ed8a3bec7bdb37ae0d170751d6520e500f049c7cd0632d31d5c3"}, - {file = "pyinstaller-6.10.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b7c90c91921b3749083115b28f30f40abf2bb481ceff196d2b2ce0eaa2b3d429"}, - {file = "pyinstaller-6.10.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf876d7d93b8b4f28d1ad57fa24645cf43119c79e985dd5e5f7a801245e6f53"}, - {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:db05e3f2f10f9f78c56f1fb163d9cb453433429fe4281218ebaf1ebfd39ba942"}, - {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:28eca3817f176fdc19747e1afcf434f13bb9f17a644f611be2c5a61b1f498ed7"}, - {file = "pyinstaller-6.10.0-py3-none-win32.whl", hash = "sha256:703e041718987e46ba0568a2c71ecf2459fddef57cf9edf3efeed4a53e3dae3f"}, - {file = "pyinstaller-6.10.0-py3-none-win_amd64.whl", hash = "sha256:95b55966e563e8b8f31a43882aea10169e9a11fdf38e626d86a2907b640c0701"}, - {file = "pyinstaller-6.10.0-py3-none-win_arm64.whl", hash = "sha256:308e0a8670c9c9ac0cebbf1bbb492e71b6675606f2ec78bc4adfc830d209e087"}, - {file = "pyinstaller-6.10.0.tar.gz", hash = "sha256:143840f8056ff7b910bf8f16f6cd92cc10a6c2680bb76d0a25d558d543d21270"}, + {file = "pyinstaller-6.11.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:6fd68a3c1207635c49326c54881b89d5c3bd9ba061bbc9daa58c0902db1be39e"}, + {file = "pyinstaller-6.11.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:eddd53f231e51adc65088eac4f40057ca803a990239828d4a9229407fb866239"}, + {file = "pyinstaller-6.11.0-py3-none-manylinux2014_i686.whl", hash = "sha256:e6d229009e815542833fe00332b589aa6984a06f794dc16f2ce1acab1c567590"}, + {file = "pyinstaller-6.11.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:7d2cd2ebdcd6860f8a4abe2977264a7b6d260a7147047008971c7cfc66a656a4"}, + {file = "pyinstaller-6.11.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:d9ec6d4398b4eebc1d4c00437716264ba8406bc2746f594e253070a82378a584"}, + {file = "pyinstaller-6.11.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:04f71828aa9531ab18c9656985c1f09b83d10332c73a1f4a113a48b491906955"}, + {file = "pyinstaller-6.11.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:a843d470768d68b05684ccf4860c45b2eb13727f41667c0b2cd8f57ae231bd18"}, + {file = "pyinstaller-6.11.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:963dedc1f37144a4385f58f7f65f1c69c004a67faae522a2085b5ddb230c908b"}, + {file = "pyinstaller-6.11.0-py3-none-win32.whl", hash = "sha256:c71024c8a19c7b221b9152b2baff4c3ba849cada68dcdd34382ba09f0107451f"}, + {file = "pyinstaller-6.11.0-py3-none-win_amd64.whl", hash = "sha256:0e229610c22b96d741d905706f9496af472c1a9216a118988f393c98ecc3f51f"}, + {file = "pyinstaller-6.11.0-py3-none-win_arm64.whl", hash = "sha256:a5f716bb507517912fda39d109dead91fc0dd2e7b2859562522b63c61aa21676"}, + {file = "pyinstaller-6.11.0.tar.gz", hash = "sha256:cb4d433a3db30d9d17cf5f2cf7bb4df80a788d493c1d67dd822dc5791d9864af"}, ] [package.dependencies] @@ -224,7 +224,7 @@ altgraph = "*" importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} packaging = ">=22.0" -pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} +pefile = {version = ">=2022.5.30,<2024.8.26 || >2024.8.26", markers = "sys_platform == \"win32\""} pyinstaller-hooks-contrib = ">=2024.8" pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} setuptools = ">=42.0.0" @@ -235,13 +235,13 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2024.8" +version = "2024.9" description = "Community maintained hooks for PyInstaller" optional = false python-versions = ">=3.8" files = [ - {file = "pyinstaller_hooks_contrib-2024.8-py3-none-any.whl", hash = "sha256:0057fe9a5c398d3f580e73e58793a1d4a8315ca91c3df01efea1c14ed557825a"}, - {file = "pyinstaller_hooks_contrib-2024.8.tar.gz", hash = "sha256:29b68d878ab739e967055b56a93eb9b58e529d5b054fbab7a2f2bacf80cef3e2"}, + {file = "pyinstaller_hooks_contrib-2024.9-py3-none-any.whl", hash = "sha256:1ddf9ba21d586afa84e505bb5c65fca10b22500bf3fdb89ee2965b99da53b891"}, + {file = "pyinstaller_hooks_contrib-2024.9.tar.gz", hash = "sha256:4793869f370d1dc4806c101efd2890e3c3e703467d8d27bb5a3db005ebfb008d"}, ] [package.dependencies] @@ -251,36 +251,36 @@ setuptools = ">=42.0.0" [[package]] name = "pyside6-addons" -version = "6.8.0" +version = "6.8.0.2" description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" optional = false -python-versions = "<3.13,>=3.9" +python-versions = "<3.14,>=3.9" files = [ - {file = "PySide6_Addons-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:aebab1e4fe63ebceccae4068768bf20959ab78f7fe01af832458837241334b5c"}, - {file = "PySide6_Addons-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4b3be260f9cc415d1a12b77a703ced18b8854f56985f4708cab5618a9554bbd6"}, - {file = "PySide6_Addons-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:7c153a685341683fac82d32926e2204747a83c13ef7b203db8ae9efe27f26a0f"}, - {file = "PySide6_Addons-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:8f7f20fb3758995580f1fb8342df3479be51958eca36db2d6f6a3304f31471de"}, + {file = "PySide6_Addons-6.8.0.2-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:30c9ca570dd18ffbfd34ee95e0a319c34313a80425c4011d6ccc9f4cca0dc4c8"}, + {file = "PySide6_Addons-6.8.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:754a9822ab2dc313f9998edef69d8a12bc9fd61727543f8d30806ed272ae1e52"}, + {file = "PySide6_Addons-6.8.0.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:553f3fa412f423929b5cd8b7d43fd5f02161851f10a438174a198b0f1a044df7"}, + {file = "PySide6_Addons-6.8.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:ae4377a3e10fe720a9119677b31d8de13e2a5221c06b332df045af002f5f4c3d"}, ] [package.dependencies] -PySide6-Essentials = "6.8.0" -shiboken6 = "6.8.0" +PySide6-Essentials = "6.8.0.2" +shiboken6 = "6.8.0.2" [[package]] name = "pyside6-essentials" -version = "6.8.0" +version = "6.8.0.2" description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" optional = false -python-versions = "<3.13,>=3.9" +python-versions = "<3.14,>=3.9" files = [ - {file = "PySide6_Essentials-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:c2ad37de574ed911ac2dd392e95888ee7354c4bc475259dafc31978efb710a6a"}, - {file = "PySide6_Essentials-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:da99a94806416ec1e386426a474e7d1e514c1cdf8ad171c005376f4f633e7216"}, - {file = "PySide6_Essentials-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:ae0732228e93eb882c9a93fd510819fb64b7d09d8e500912b485a604537215d6"}, - {file = "PySide6_Essentials-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:2ef7138dc7efb9f1153c1dda7a7bd6ac02badad1aa1971cc140d0b9bf962c3dc"}, + {file = "PySide6_Essentials-6.8.0.2-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:3df4ed75bbb74d74ac338b330819b1a272e7f5cec206765c7176a197c8bc9c79"}, + {file = "PySide6_Essentials-6.8.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7df6d6c1da4858dbdea77c74d7270d9c68e8d1bbe3362892abd1a5ade3815a50"}, + {file = "PySide6_Essentials-6.8.0.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:cf490145d18812a6cff48b0b0afb0bfaf7066744bfbd09eb071c3323f1d6d00d"}, + {file = "PySide6_Essentials-6.8.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:d2f029b8c9f0106f57b26aa8c435435d7f509c80525075343e07177b283f862e"}, ] [package.dependencies] -shiboken6 = "6.8.0" +shiboken6 = "6.8.0.2" [[package]] name = "pytest" @@ -354,13 +354,13 @@ files = [ [[package]] name = "setuptools" -version = "75.1.0" +version = "75.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, + {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, ] [package.extras] @@ -374,15 +374,15 @@ type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11 [[package]] name = "shiboken6" -version = "6.8.0" +version = "6.8.0.2" description = "Python/C++ bindings helper module" optional = false -python-versions = "<3.13,>=3.9" +python-versions = "<3.14,>=3.9" files = [ - {file = "shiboken6-6.8.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:0d3171c496e7474ad29d73686e46e741317a9b29ae9fa30c421fa0360bc10af0"}, - {file = "shiboken6-6.8.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ad88c0e73c9e4de3723c6e6b846e651729433ff9d9086bb2b4e6d49965477d97"}, - {file = "shiboken6-6.8.0-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:0f62ee7c34337e2c39fff0985694224f7503328c450245c399846b72cd71c410"}, - {file = "shiboken6-6.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:cb98424a1f0c2d6ebf7f6be99660a121b9b22601a058e6b7efeadbc60bcd2182"}, + {file = "shiboken6-6.8.0.2-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:9019e1fcfeed8bb350222e981748ef05a2fec11e31ddf616657be702f0b7a468"}, + {file = "shiboken6-6.8.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:fa7d411c3c67b4296847b3f5f572268e219d947d029ff9d8bce72fe6982d92bc"}, + {file = "shiboken6-6.8.0.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:1aaa8b7f9138818322ef029b2c487d1c6e00dc3f53084e62e1d11bdea47e47c2"}, + {file = "shiboken6-6.8.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:b11e750e696bb565d897e0f5836710edfb86bd355f87b09988bd31b2aad404d3"}, ] [[package]] From f5b489ef4461f43e2996ee703a11c630cbd21e4f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 29 Oct 2024 01:37:44 +0100 Subject: [PATCH 236/249] Fixing macOS build script. --- scripts/build-macosx.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 2ccd626..8f3f38d 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -27,9 +27,9 @@ rm $(find . -name "*.pyc") pyinstaller --add-data "LogarithmPlotter/qml:qml" \ --add-data "LogarithmPlotter/i18n:i18n" \ - --add-data "LICENSE.md:." \ - --add-data "../assets/native/mac/logarithmplotterfile.icns:." \ - --add-data "README.md:." \ + --add-data "../../LICENSE.md:." \ + --add-data "../../assets/native/mac/logarithmplotterfile.icns:." \ + --add-data "../../README.md:." \ --exclude-module "FixTk" \ --exclude-module "tcl" \ --exclude-module "tk" \ From da8aa59b0a069a20d51d175bd3d43c5b8c34ac3b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 29 Oct 2024 02:50:11 +0100 Subject: [PATCH 237/249] Improving characters choosing popup. + No longer covering the input + No longer cut off when editing the name + Improved keyboard navigation. --- .../Popup/InsertCharacter.qml | 57 ++++++++++++------- .../Setting/ExpressionEditor.qml | 22 +++++-- .../LogarithmPlotter/Setting/TextSetting.qml | 22 +++++-- 3 files changed, 71 insertions(+), 30 deletions(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index 7002539..8162b09 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -16,8 +16,9 @@ * along with this program. If not, see . */ -import QtQuick.Controls import QtQuick +import QtQuick.Controls +import QtQml.Models /*! \qmltype InsertCharacter @@ -42,15 +43,18 @@ Popup { */ property string category: 'all' - width: 280 - height: Math.ceil(insertGrid.insertChars.length/insertGrid.columns)*(width/insertGrid.columns)+5 + width: insertGrid.width + 10 + height: insertGrid.height + 10 modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - Grid { + GridView { id: insertGrid - width: parent.width - columns: 7 + width: 280 + height: Math.ceil(model.count/columns)*cellHeight + property int columns: 7 + cellWidth: width/columns + cellHeight: cellWidth property var insertCharsExpression: [ "∞","π","¹","²","³","⁴","⁵", @@ -86,21 +90,34 @@ Popup { }[insertPopup.category] } - Repeater { - model: parent.insertChars.length - - Button { - id: insertBtn - width: insertGrid.width/insertGrid.columns - height: width - text: insertGrid.insertChars[modelData] - flat: text == " " - font.pixelSize: 18 - - onClicked: { - selected(text) - } + model: ListModel {} + + delegate: Button { + id: insertBtn + width: insertGrid.cellWidth + height: insertGrid.cellHeight + text: chr + flat: text == " " + font.pixelSize: 18 + + onClicked: { + insertPopup.selected(text) + insertPopup.close() + } + } + + Component.onCompleted: function() { + for(const chr of insertChars) { + console.log("Appending", chr) + model.append({ 'chr': chr }) } } } + + function setFocus() { + insertGrid.currentIndex = 0 + insertGrid.forceActiveFocus() + } + + Keys.onEscapePressed: close() } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 8251a3f..af32b43 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -500,29 +500,41 @@ Item { Button { id: insertButton - text: "α" anchors.right: parent.right anchors.rightMargin: 5 anchors.verticalCenter: parent.verticalCenter width: 20 height: width + + Icon { + id: icon + width: 12 + height: 12 + anchors.centerIn: parent + + color: sysPalette.windowText + source: '../icons/properties/expression.svg' + } + onClicked: { insertPopup.open() - insertPopup.focus = true + insertPopup.setFocus() } } P.InsertCharacter { id: insertPopup - x: Math.round((parent.width - width) / 2) - y: Math.round((parent.height - height) / 2) + x: parent.width - width + y: parent.height category: "expression" onSelected: function(c) { editor.insert(editor.cursorPosition, c) - insertPopup.close() + } + + onClosed: function() { focus = false editor.focus = true } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 3689dc1..8d1ca41 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -144,28 +144,40 @@ Item { Button { id: insertButton - text: "α" anchors.right: parent.right anchors.rightMargin: 5 anchors.verticalCenter: parent.verticalCenter width: 20 height: width visible: !isInt && !isDouble + + Icon { + id: icon + width: 12 + height: 12 + anchors.centerIn: parent + + color: sysPalette.windowText + source: '../icons/properties/expression.svg' + } + onClicked: { insertPopup.open() - insertPopup.focus = true + insertPopup.setFocus() } } Popup.InsertCharacter { id: insertPopup - x: Math.round((parent.width - width) / 2) - y: Math.round((parent.height - height) / 2) + x: parent.width - width + y: parent.height onSelected: function(c) { input.insert(input.cursorPosition, c) - insertPopup.close() + } + + onClosed: function() { focus = false input.focus = true } From fdcc8105babb8bd37fa2e577cb94861231691ac5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 29 Oct 2024 02:58:32 +0100 Subject: [PATCH 238/249] Removing debug --- .../qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index 8162b09..7ef1794 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -108,7 +108,6 @@ Popup { Component.onCompleted: function() { for(const chr of insertChars) { - console.log("Appending", chr) model.append({ 'chr': chr }) } } From 6025742e869323b11da537863d20a56b5c1c8cc8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 6 Jan 2025 16:23:06 +0100 Subject: [PATCH 239/249] Fixing bugs. --- common/src/math/domain.mjs | 68 +++++---- common/test/math/domain.mjs | 130 ++++++++++++------ .../Popup/InsertCharacter.qml | 3 +- 3 files changed, 132 insertions(+), 69 deletions(-) diff --git a/common/src/math/domain.mjs b/common/src/math/domain.mjs index 48bf8ad..19586ee 100644 --- a/common/src/math/domain.mjs +++ b/common/src/math/domain.mjs @@ -24,6 +24,7 @@ import { Expression, executeExpression } from "./expression.mjs" */ export class Domain { constructor() { + this.latexMarkup = "#INVALID" } /** @@ -206,8 +207,8 @@ export class Range extends Domain { } includes(x) { - if(x instanceof Expression) x = x.execute() if(typeof x == "string") x = executeExpression(x) + if(x instanceof Expression) x = x.execute() return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) } @@ -249,15 +250,17 @@ export class SpecialDomain extends Domain { /** * @constructs SpecialDomain * @param {string} displayName + * @param {string} latexMarkup - markup representing the domain. * @param {function} isValid - function returning true when number is in domain false when it isn't. * @param {function} next - function provides the next positive value in the domain after the one given. * @param {function} previous - function provides the previous positive value in the domain before the one given. * @param {boolean} moveSupported - Only true if next and previous functions are valid. */ - constructor(displayName, isValid, next = () => true, previous = () => true, + constructor(displayName, latexMarkup, isValid, next = () => true, previous = () => true, moveSupported = true) { super() this.displayName = displayName + this.latexMarkup = latexMarkup this.isValid = isValid this.nextValue = next this.prevValue = previous @@ -562,39 +565,54 @@ Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}" Domain.RME = new Range(-Infinity, 0, true, true) Domain.RME.displayName = "ℝ⁻*" Domain.RME.latexMarkup = "\\mathbb{R}^{+*}" -Domain.N = new SpecialDomain("ℕ", x => x % 1 === 0 && x >= 0, +Domain.N = new SpecialDomain( + "ℕ", "\\mathbb{N}", + x => x % 1 === 0 && x >= 0, x => Math.max(Math.floor(x) + 1, 0), - x => Math.max(Math.ceil(x) - 1, 0)) -Domain.N.latexMarkup = "\\mathbb{N}" -Domain.NE = new SpecialDomain("ℕ*", x => x % 1 === 0 && x > 0, + x => Math.max(Math.ceil(x) - 1, 0) +) +Domain.NE = new SpecialDomain( + "ℕ*", "\\mathbb{N}^{*}", + x => x % 1 === 0 && x > 0, x => Math.max(Math.floor(x) + 1, 1), - x => Math.max(Math.ceil(x) - 1, 1)) -Domain.NE.latexMarkup = "\\mathbb{N}^{*}" -Domain.Z = new SpecialDomain("ℤ", x => x % 1 === 0, x => Math.floor(x) + 1, x => Math.ceil(x) - 1) -Domain.Z.latexMarkup = "\\mathbb{Z}" -Domain.ZE = new SpecialDomain("ℤ*", x => x % 1 === 0 && x !== 0, + x => Math.max(Math.ceil(x) - 1, 1) +) +Domain.Z = new SpecialDomain( + "ℤ", "\\mathbb{Z}", + x => x % 1 === 0, + x => Math.floor(x) + 1, + x => Math.ceil(x) - 1 +) +Domain.ZE = new SpecialDomain( + "ℤ*", "\\mathbb{Z}^{*}", + x => x % 1 === 0 && x !== 0, x => Math.floor(x) + 1 === 0 ? Math.floor(x) + 2 : Math.floor(x) + 1, - x => Math.ceil(x) - 1 === 0 ? Math.ceil(x) - 2 : Math.ceil(x) - 1) -Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}" -Domain.ZM = new SpecialDomain("ℤ⁻", x => x % 1 === 0 && x <= 0, + x => Math.ceil(x) - 1 === 0 ? Math.ceil(x) - 2 : Math.ceil(x) - 1 +) +Domain.ZM = new SpecialDomain( + "ℤ⁻", "\\mathbb{Z}^{-}", + x => x % 1 === 0 && x <= 0, x => Math.min(Math.floor(x) + 1, 0), - x => Math.min(Math.ceil(x) - 1, 0)) -Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}" -Domain.ZME = new SpecialDomain("ℤ⁻*", x => x % 1 === 0 && x < 0, + x => Math.min(Math.ceil(x) - 1, 0) +) +Domain.ZME = new SpecialDomain( + "ℤ⁻*", "\\mathbb{Z}^{-*}", + x => x % 1 === 0 && x < 0, x => Math.min(Math.floor(x) + 1, -1), - x => Math.min(Math.ceil(x) - 1, -1)) -Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" -Domain.NLog = new SpecialDomain("ℕˡᵒᵍ", + x => Math.min(Math.ceil(x) - 1, -1) +) +Domain.NLog = new SpecialDomain( + "ℕˡᵒᵍ", "\\mathbb{N}^{log}", x => x / Math.pow(10, Math.ceil(Math.log10(x))) % 1 === 0 && x > 0, - function(x) { + x => { let x10pow = Math.pow(10, Math.ceil(Math.log10(x))) return Math.max(1, (Math.floor(x / x10pow) + 1) * x10pow) }, - function(x) { + x => { let x10pow = Math.pow(10, Math.ceil(Math.log10(x))) return Math.max(1, (Math.ceil(x / x10pow) - 1) * x10pow) - }) -Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" + } +) let refedDomains = [] @@ -626,7 +644,7 @@ export function parseDomainSimple(domain) { if(domain.includes("U") || domain.includes("∪")) return UnionDomain.import(domain) if(domain.includes("∩")) return IntersectionDomain.import(domain) if(domain.includes("∖") || domain.includes("\\")) return MinusDomain.import(domain) - if(domain.charAt(0) === "{" && domain.charAt(domain.length - 1) === "}") return DomainSet.import(domain) + if(domain.at(0) === "{" && domain.at(-1) === "}") return DomainSet.import(domain) if(domain.includes("]") || domain.includes("[")) return Range.import(domain) if(["R", "ℝ", "N", "ℕ", "Z", "ℤ"].some(str => domain.toUpperCase().includes(str))) return Domain.import(domain) diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs index e32dbd1..6c2b93e 100644 --- a/common/test/math/domain.mjs +++ b/common/test/math/domain.mjs @@ -19,46 +19,90 @@ import { describe, it } from "mocha" import { expect } from "chai" -// import { Domain, parseDomainSimple } from "../../src/math/domain.mjs" -// -// describe("math.domain", function() { -// describe("#parseDomainSimple", function() { -// it("returns predefined domains", function() { -// const predefinedToCheck = [ -// // Real domains -// { domain: Domain.R, shortcuts: ["R", "ℝ"] }, -// // Zero exclusive real domains -// { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] }, -// // Real positive domains -// { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] }, -// // Zero-exclusive real positive domains -// { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] }, -// // Real negative domain -// { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] }, -// // Zero-exclusive real negative domains -// { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] }, -// // Natural integers domain -// { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] }, -// // Zero-exclusive natural integers domain -// { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] }, -// // Logarithmic natural domains -// { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] }, -// // All integers domains -// { domain: Domain.Z, shortcuts: ["Z", "ℤ"] }, -// // Zero-exclusive all integers domain -// { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] }, -// // Negative integers domain -// { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] }, -// // Zero-exclusive negative integers domain -// { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] }, -// ] -// -// // Real domains -// for(const { domain, shortcuts } of predefinedToCheck) -// for(const shortcut of shortcuts) -// expect(parseDomainSimple(shortcut)).to.be.equal(domain) -// }) -// -// it("") -// }) -// }) +import { Domain, EmptySet, parseDomainSimple } from "../../src/math/domain.mjs" + +describe("math.domain", function() { + describe("#parseDomainSimple", function() { + it("returns empty sets when a domain cannot be parsed", function() { + expect(parseDomainSimple("∅")).to.be.an.instanceof(EmptySet) + expect(parseDomainSimple("O")).to.be.an.instanceof(EmptySet) + expect(parseDomainSimple("AAAAAAAAA")).to.be.an.instanceof(EmptySet) + expect(parseDomainSimple("???")).to.be.an.instanceof(EmptySet) + expect(parseDomainSimple("∅").latexMarkup).to.equal("\\emptyset") + expect(parseDomainSimple("???").toString()).to.equal("∅") + expect(parseDomainSimple("∅").includes(0)).to.be.false + expect(parseDomainSimple("∅").includes(Infinity)).to.be.false + expect(parseDomainSimple("∅").includes(-3)).to.be.false + + }) + + it("returns predefined domains", function() { + const predefinedToCheck = [ + // Real domains + { domain: Domain.R, shortcuts: ["R", "ℝ"] }, + // Zero exclusive real domains + { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] }, + // Real positive domains + { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] }, + // Zero-exclusive real positive domains + { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] }, + // Real negative domain + { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] }, + // Zero-exclusive real negative domains + { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] }, + // Natural integers domain + { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] }, + // Zero-exclusive natural integers domain + { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] }, + // Logarithmic natural domains + { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] }, + // All integers domains + { domain: Domain.Z, shortcuts: ["Z", "ℤ"] }, + // Zero-exclusive all integers domain + { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] }, + // Negative integers domain + { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] }, + // Zero-exclusive negative integers domain + { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] }, + ] + + // Real domains + for(const { domain, shortcuts } of predefinedToCheck) + for(const shortcut of shortcuts) + expect(parseDomainSimple(shortcut)).to.be.equal(domain) + }) + + it("returns parsed ranges", function() { + const parsedClosed = parseDomainSimple("[1;3]") + expect(parsedClosed.includes(1)).to.be.true + expect(parsedClosed.includes(2.4)).to.be.true + expect(parsedClosed.includes(3)).to.be.true + expect(parsedClosed.includes(3.01)).to.be.false + expect(parsedClosed.includes(0.99)).to.be.false + const parsedOpen = parseDomainSimple("]1;3[") + expect(parsedOpen.includes(1)).to.be.false + expect(parsedOpen.includes(3)).to.be.false + expect(parsedOpen.includes(2.4)).to.be.true + expect(parsedOpen.includes(1.01)).to.be.true + expect(parsedOpen.includes(2.99)).to.be.true + const parsedOpenBefore = parseDomainSimple("]1;3]") + expect(parsedOpenBefore.includes(1)).to.be.false + expect(parsedOpenBefore.includes(3)).to.be.true + expect(parsedOpenBefore.includes(2.4)).to.be.true + expect(parsedOpenBefore.includes(1.01)).to.be.true + expect(parsedOpenBefore.includes(3.01)).to.be.false + const parsedOpenAfter = parseDomainSimple("[1;3[") + expect(parsedOpenAfter.includes(1)).to.be.true + expect(parsedOpenAfter.includes(3)).to.be.false + expect(parsedOpenAfter.includes(2.4)).to.be.true + expect(parsedOpenAfter.includes(0.99)).to.be.false + expect(parsedOpenAfter.includes(2.99)).to.be.true + }) + + it("does not parse invalid ranges", function() { + expect(() => parseDomainSimple("]1;2;3[")).to.throw + expect(() => parseDomainSimple("]1,2;3[")).to.throw + expect(() => parseDomainSimple("](12);3[")).to.throw + }) + }) +}) diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index 7ef1794..9bf8f06 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -111,6 +111,8 @@ Popup { model.append({ 'chr': chr }) } } + + Keys.onEscapePressed: parent.close() } function setFocus() { @@ -118,5 +120,4 @@ Popup { insertGrid.forceActiveFocus() } - Keys.onEscapePressed: close() } From 004b3f5612e28caa50b6f710edc7587f638bf1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=A4=E0=AE=AE=E0=AE=BF=E0=AE=B4=E0=AF=8D=E0=AE=A8?= =?UTF-8?q?=E0=AF=87=E0=AE=B0=E0=AE=AE=E0=AF=8D?= Date: Sun, 12 Jan 2025 17:22:40 +0100 Subject: [PATCH 240/249] Added translation using Weblate (Tamil) --- assets/i18n/lp_ta.ts | 1563 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1563 insertions(+) create mode 100644 assets/i18n/lp_ta.ts diff --git a/assets/i18n/lp_ta.ts b/assets/i18n/lp_ta.ts new file mode 100644 index 0000000..780a6b9 --- /dev/null +++ b/assets/i18n/lp_ta.ts @@ -0,0 +1,1563 @@ + + + + + About + + + About LogarithmPlotter + + + + + LogarithmPlotter v%1 + + + + + 2D plotter software to make BODE plots, sequences and repartition functions. + + + + + Report a bug + + + + + Official website + + + + + AppMenuBar + + + &File + + + + + &Load... + + + + + &Save + + + + + Save &As... + + + + + &Quit + + + + + &Edit + + + + + &Undo + + + + + &Redo + + + + + &Copy plot + + + + + &Preferences + + + + + &Create + + + + + &Help + + + + + &Source code + + + + + &Report a bug + + + + + &User manual + + + + + &Changelog + + + + + &Help translating! + + + + + &Thanks + + + + + &About + + + + + Save unsaved changes? + + + + + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? + + + + + BaseDialog + + + Close + + + + + Changelog + + + Fetching changelog... + + + + + Close + + + + + CustomPropertyList + + + + + Create new %1 + + + + + Pick on graph + + + + + Dialog + + + Edit properties of %1 %2 + + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + + + + + null + + + + + name + + + + + name + value + + + + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + + + + + Executable Objects + + + + + Objects + + + + + FileDialog + + + Export Logarithm Plot file + + + + + Import Logarithm Plot file + + + + + GreetScreen + + + Welcome to LogarithmPlotter + + + + + Version %1 + + + + + User manual + + + + + Changelog + + + + + Preferences + + + + + Close + + + + + ListSetting + + + + Add Entry + + + + + LogarithmPlotter + + + Objects + + + + + Settings + + + + + History + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter + + + + + ObjectCreationGrid + + + + Create new: + + + + + ObjectLists + + + Hide all %1 + + + + + Show all %1 + + + + + ObjectRow + + + Hide %1 %2 + + + + + Show %1 %2 + + + + + Set %1 %2 position + + + + + Delete %1 %2 + + + + + Pick new color for %1 %2 + + + + + PickLocationOverlay + + + Pointer precision: + + + + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + + Open picker settings + + + + + Hide picker settings + + + + + (no pick selected) + + + + + Preferences + + + Close + + + + + Settings + + + + X Zoom + + + + + + Y Zoom + + + + + + Min X + + + + + + Max Y + + + + + Max X + + + + + Min Y + + + + + + X Axis Step + + + + + + Y Axis Step + + + + + + Line width + + + + + + Text size (px) + + + + + + X Label + + + + + + Y Label + + + + + + X Log scale + + + + + + Show X graduation + + + + + + Show Y graduation + + + + + Copy to clipboard + + + + + Save plot + + + + + Save plot as + + + + + Load plot + + + + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + + Github + + + + + Norwegian + + + + + Spanish + + + + + Translations included + + + + + Improve + + + + + bodemagnitude + + + Bode Magnitude + + + + + Bode Magnitudes + + + + + + low-pass + + + + + + high-pass + + + + + bodemagnitudesum + + + + Bode Magnitudes Sum + + + + + bodephase + + + Bode Phase + + + + + Bode Phases + + + + + bodephasesum + + + + Bode Phases Sum + + + + + changelog + + + Could not fetch changelog: Server error {}. + + + + + Could not fetch update: {}. + + + + + color + + + + %1 %2's color changed from %3 to %4. + + + + + comment + + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + + + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + + + + + Note: Specify the probability for each value. + + + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + + + + control + + + + + + + %1: + + + + + create + + + + New %1 %2 created. + + + + + delete + + + + %1 %2 deleted. + + + + + distribution + + + Repartition + + + + + Repartition functions + + + + + editproperty + + + %1 of %2 %3 changed from "%4" to "%5". + + + + + %1 of %2 changed from %3 to %4. + + + + + error + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + In order to be executed, object %1 must have at least one argument. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + EOF + + + + + + Parse error [position %1]: %2 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + + Function %1 must have at least one argument. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + expression + + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + + + LogarithmPlotter - Drawing error + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + + Color Scheme + + + + + function + + + Function + + + + + Functions + + + + + general + + + Check for updates on startup + + + + + Reset redo stack automaticly + + + + + Enable LaTeX rendering + + + + + io + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not load file: + + + + + Loaded file '%1'. + + + + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + Your LaTeX installation does not include some required packages: + +- {} (https://ctan.org/pkg/{}) + +Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + name + + + + %1 %2 renamed to %3. + + + + + parameters + + + above + + + + + below + + + + + + left + + + + + + right + + + + + above-left + + + + + above-right + + + + + below-left + + + + + below-right + + + + + center + + + + + top + + + + + bottom + + + + + top-left + + + + + top-right + + + + + bottom-left + + + + + bottom-right + + + + + application + + + + + function + + + + + high + + + + + low + + + + + Next to target + + + + + With label + + + + + Hidden + + + + + point + + + Point + + + + + Points + + + + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + + + prop + + + expression + + + + + definitionDomain + + + + + destinationDomain + + + + + displayMode + + + + + + + + + + + + + + labelPosition + + + + + + + + + + + labelX + + + + + + drawPoints + + + + + + drawDashedLines + + + + + + om_0 + + + + + pass + + + + + gain + + + + + omGraduation + + + + + phase + + + + + unit + + + + + + + x + + + + + + y + + + + + pointStyle + + + + + probabilities + + + + + defaultExpression + + + + + baseValues + + + + + text + + + + + disableLatex + + + + + targetElement + + + + + approximate + + + + + rounding + + + + + displayStyle + + + + + targetValuePosition + + + + + labelContent + + + + + sequence + + + Sequence + + + + + Sequences + + + + + settingCategory + + + general + + + + + editor + + + + + default + + + + + text + + + Text + + + + + Texts + + + + + update + + + An update for LogarithmPlotter (v{}) is available. + + + + + No update available. + + + + + Could not fetch update information: Server error {}. + + + + + Could not fetch update information: {}. + + + + + usage + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + + Usage: +%1 + + + + + + + Usage: +%1 +%2 + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + + + visibility + + + + %1 %2 shown. + + + + + + %1 %2 hidden. + + + + + xcursor + + + X Cursor + + + + + X Cursors + + + + From 3b244fad2c5f263c1ba951759b68670230d817a7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 12 Jan 2025 17:42:48 +0100 Subject: [PATCH 241/249] Updating translations + credits for Tamil. --- assets/i18n/lp_de.ts | 316 ++++++++++------ assets/i18n/lp_en.ts | 316 ++++++++++------ assets/i18n/lp_es.ts | 304 +++++++++------ assets/i18n/lp_fr.ts | 316 ++++++++++------ assets/i18n/lp_hu.ts | 316 ++++++++++------ assets/i18n/lp_nb_NO.ts | 352 ++++++++++-------- assets/i18n/lp_ta.ts | 298 +++++++-------- assets/i18n/lp_template.ts | 312 ++++++++-------- .../LogarithmPlotter/Popup/ThanksTo.qml | 10 + 9 files changed, 1539 insertions(+), 1001 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 7d66a7a..56a80ff 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -42,47 +42,47 @@ &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Preferences &Einstellung - + &Create &Erstellen @@ -123,52 +123,52 @@ Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Versionshinweise - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -188,6 +188,29 @@ Beim Starten auf Updates prüfen + + Browser + + + Filter... + Filtern… + + + + Redo > + Wiederherstellen > + + + + > Now + > Aktueller Stand + + + + < Undo + < Rückgängig + + Changelog @@ -218,22 +241,22 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name @@ -242,17 +265,17 @@ Etikett - + null leer - + name Name - + name + value Name + Wert @@ -428,20 +451,38 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" + Neuer Eintrag + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Objekte - + Settings Einstellungen - + History Verlauf @@ -470,17 +511,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -555,45 +596,76 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - PickLocationOverlay + PickLocation - + Pointer precision: Genauigkeit des Zeigers: + + + Snap to grid: + Am Raster einrasten: + + + + Pick X + X nehmen + + + + Pick Y + Y nehmen + + + + Open picker settings + Zeigereinstellungen öffnen + + + + Hide picker settings + Zeigereinstellungen ausblenden + + + + (no pick selected) + (keine Auswahl ausgewählt) + + + + PickLocationOverlay + + Pointer precision: + Genauigkeit des Zeigers: + Snap to grid Am Gitter einrasten - Snap to grid: - Am Raster einrasten: + Am Raster einrasten: - Pick X - X nehmen + X nehmen - Pick Y - Y nehmen + Y nehmen - Open picker settings - Zeigereinstellungen öffnen + Zeigereinstellungen öffnen - Hide picker settings - Zeigereinstellungen ausblenden + Zeigereinstellungen ausblenden - (no pick selected) - (keine Auswahl ausgewählt) + (keine Auswahl ausgewählt) @@ -769,22 +841,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" E-Mail - + English Englisch - + French Französisch - + German Deutsch - + Hungarian Ungarisch @@ -792,26 +864,32 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" + Github GitHub - + Norwegian Norwegisch - + Spanish Spanisch - + + Tamil + + + + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -875,12 +953,13 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -982,34 +1061,34 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). @@ -1068,78 +1147,70 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - First argument to map is not a function. - Der erste Parameter von map ist keine Formel. + Der erste Parameter von map ist keine Formel. - Second argument to map is not an array. - Der zweite Parameter von map ist kein Array. + Der zweite Parameter von map ist kein Array. - First argument to fold is not a function. - Der erste Parameter für fold ist keine Formel. + Der erste Parameter für fold ist keine Formel. - Second argument to fold is not an array. - Der zweite Parameter für fold ist kein Array. + Der zweite Parameter für fold ist kein Array. - First argument to filter is not a function. - Der erste Parameter für filter ist keine Formel. + Der erste Parameter für filter ist keine Formel. - Second argument to filter is not an array. - Der zweite Parameter von filter ist kein Array. + Der zweite Parameter von filter ist kein Array. - Second argument to indexOf is not a string or array. - Der zweite Parameter von indexOf ist kein String oder Array. + Der zweite Parameter von indexOf ist kein String oder Array. - Second argument to join is not an array. - Der zweite Parameter von join ist kein Array. + Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. @@ -1260,6 +1331,11 @@ Ausdruck analysiert: %3 Enable LaTeX rendering LaTeX-Rendering aktivieren + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1303,38 +1379,32 @@ Ausdruck analysiert: %3 Verlauf - Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. - Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. - Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. - Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. - Could not load file: - Datei konnte nicht geladen werden: + Datei konnte nicht geladen werden: Could not save file: Die Datei konnte nicht gespeichert werden: - Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. Copied plot screenshot to clipboard! @@ -1352,7 +1422,7 @@ Ausdruck analysiert: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1361,12 +1431,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1379,7 +1449,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1392,7 +1462,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Stellen Sie sicher, dass diese Pakete installiert sind, oder deaktivieren Sie das LaTeX-Rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1403,6 +1473,32 @@ Der Prozess '{}' brauchte zu lange, um beendet zu werden: Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1727,7 +1823,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Farbe - + labelContent Etikett @@ -1804,22 +1900,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde update - + An update for LogarithmPlotter (v{}) is available. Ein Update für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index 5f653a7..0f9b887 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -42,47 +42,47 @@ &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Preferences &Preferences - + &Create &Create @@ -123,52 +123,52 @@ Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -188,6 +188,29 @@ Check for updates on startup + + Browser + + + Filter... + Filter… + + + + Redo > + Redo > + + + + > Now + > Now + + + + < Undo + < Undo + + Changelog @@ -218,22 +241,22 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name @@ -242,17 +265,17 @@ Label content - + null null - + name name - + name + value name + value @@ -428,20 +451,38 @@ These settings can be changed at any time from the "Settings" menu.+ Add Entry + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Objects - + Settings Settings - + History History @@ -470,17 +511,17 @@ These settings can be changed at any time from the "Settings" menu.Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -555,45 +596,76 @@ These settings can be changed at any time from the "Settings" menu. - PickLocationOverlay + PickLocation - + Pointer precision: Pointer precision: + + + Snap to grid: + Snap to grid: + + + + Pick X + Pick X + + + + Pick Y + Pick Y + + + + Open picker settings + Open picker settings + + + + Hide picker settings + Hide picker settings + + + + (no pick selected) + (no pick selected) + + + + PickLocationOverlay + + Pointer precision: + Pointer precision: + Snap to grid Snap to grid - Snap to grid: - Snap to grid: + Snap to grid: - Pick X - Pick X + Pick X - Pick Y - Pick Y + Pick Y - Open picker settings - Open picker settings + Open picker settings - Hide picker settings - Hide picker settings + Hide picker settings - (no pick selected) - (no pick selected) + (no pick selected) @@ -769,22 +841,22 @@ These settings can be changed at any time from the "Settings" menu.Email - + English English - + French French - + German German - + Hungarian Hungarian @@ -792,26 +864,32 @@ These settings can be changed at any time from the "Settings" menu. + Github GitHub - + Norwegian Norwegian - + Spanish Spanish - + + Tamil + + + + Translations included Translations included - + Improve Improve @@ -875,12 +953,13 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + + Could not fetch update: {}. Could not fetch changelog: {}. @@ -982,34 +1061,34 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). @@ -1068,78 +1147,70 @@ These settings can be changed at any time from the "Settings" menu.Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - First argument to map is not a function. - First argument to map is not a function. + First argument to map is not a function. - Second argument to map is not an array. - Second argument to map is not an array. + Second argument to map is not an array. - First argument to fold is not a function. - First argument to fold is not a function. + First argument to fold is not a function. - Second argument to fold is not an array. - Second argument to fold is not an array. + Second argument to fold is not an array. - First argument to filter is not a function. - First argument to filter is not a function. + First argument to filter is not a function. - Second argument to filter is not an array. - Second argument to filter is not an array. + Second argument to filter is not an array. - Second argument to indexOf is not a string or array. - Second argument to indexOf is not a string or array. + Second argument to indexOf is not a string or array. - Second argument to join is not an array. - Second argument to join is not an array. + Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. @@ -1260,6 +1331,11 @@ Evaluated expression: %3 Enable LaTeX rendering Enable LaTeX rendering + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1303,38 +1379,32 @@ Evaluated expression: %3 History - Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. - Loading file '%1'. - Loading file '%1'. + Loading file '%1'. - Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. - Invalid file provided. - Invalid file provided. + Invalid file provided. - Could not load file: - Could not load file: + Could not load file: Could not save file: Could not save file: - Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. Copied plot screenshot to clipboard! @@ -1352,7 +1422,7 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1361,12 +1431,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1379,7 +1449,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1392,7 +1462,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1403,6 +1473,32 @@ Process '{}' took too long to finish: Please make sure your LaTeX installation is correct and report a bug if so. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1727,7 +1823,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.Color - + labelContent Label content @@ -1804,22 +1900,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index 7a736b5..b1e5d0a 100644 --- a/assets/i18n/lp_es.ts +++ b/assets/i18n/lp_es.ts @@ -42,47 +42,47 @@ &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Preferences &Preferencias - + &Create &Crear @@ -119,52 +119,52 @@ Esquema de colores - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -188,6 +188,29 @@ Comprobación de las actualizaciones al arrancar + + Browser + + + Filter... + + + + + Redo > + Rehacer > + + + + > Now + > Ahora + + + + < Undo + < Deshacer + + Changelog @@ -218,37 +241,37 @@ Dialog - + Edit properties of %1 %2 Editar las propiedades de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nombre de objeto no válido - + An object with the name '%1' already exists. Ya existe un objeto con el nombre '%1'. - + Name - + null - + name - + name + value nombre + valor @@ -420,35 +443,53 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + Añadir entrada + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Objetos - + Settings Ajustes - + History Historial - + Copied plot screenshot to clipboard! ¡Captura de pantalla del gráfico copiada al portapapeles! - + &Update &Actualizar - + &Update LogarithmPlotter &Actualizar LogarithmPlotter @@ -547,42 +588,73 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes - PickLocationOverlay + PickLocation - + Pointer precision: Precisión del puntero: - + Snap to grid: Ajustar a la cuadrícula: - + Pick X Elige X - + Pick Y Elige Y - + Open picker settings Abrir los ajustes del selector - + Hide picker settings Ocultar ajustes del selector - + (no pick selected) (sin selección) + + + PickLocationOverlay + + Pointer precision: + Precisión del puntero: + + + Snap to grid: + Ajustar a la cuadrícula: + + + Pick X + Elige X + + + Pick Y + Elige Y + + + Open picker settings + Abrir los ajustes del selector + + + Hide picker settings + Ocultar ajustes del selector + + + (no pick selected) + (sin selección) + Snap to grid Ajustar a la cuadrícula @@ -761,22 +833,22 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes - + English - + French - + German - + Hungarian @@ -784,26 +856,32 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes + Github GitHub - + Norwegian - + Spanish Español - + + Tamil + + + + Translations included Traducciones incluidas - + Improve Mejorar @@ -867,12 +945,13 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes changelog - + Could not fetch changelog: Server error {}. No se ha podido recuperar el registro de cambios: Error del servidor {}. - + + Could not fetch update: {}. No se pudo obtener el registro de cambios: {}. @@ -974,34 +1053,34 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes error - + Cannot find property %1 of object %2. No se puede encontrar la propiedad %1 del objeto %2. - + Undefined variable %1. Variable %1 no definida. - + In order to be executed, object %1 must have at least one argument. Para ser ejecutado, el objeto %1 debe tener al menos un argumento. - + %1 cannot be executed. %1 no es una función. - - - + + + Invalid expression. Expresión incorrecta. - + Invalid expression (parity). Expresión no válida (paridad). @@ -1052,73 +1131,65 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Símbolo inesperado: %1. - - + + Function %1 must have at least one argument. La función %1 debe tener al menos un argumento. - First argument to map is not a function. - El primer argumento de map no es una función. + El primer argumento de map no es una función. - Second argument to map is not an array. - El segundo argumento de map no es una matriz. + El segundo argumento de map no es una matriz. - First argument to fold is not a function. - El primer argumento de fold no es una función. + El primer argumento de fold no es una función. - Second argument to fold is not an array. - El segundo argumento de fold no es una matriz. + El segundo argumento de fold no es una matriz. - First argument to filter is not a function. - El primer argumento del filtro no es una función. + El primer argumento del filtro no es una función. - Second argument to filter is not an array. - El segundo argumento del filtro no es una matriz. + El segundo argumento del filtro no es una matriz. - Second argument to indexOf is not a string or array. - El segundo argumento de indexOf no es una cadena ni una matriz. + El segundo argumento de indexOf no es una cadena ni una matriz. - Second argument to join is not an array. - El segundo argumento para unirse no es una matriz. + El segundo argumento para unirse no es una matriz. - + No object found with names %1. No se ha encontrado ningún objeto con el nombre %1. - + No object found with name %1. Ningún objeto con el nombre %1 encontrado. - + Object cannot be dependent on itself. El objeto no puede depender de sí mismo. - + Circular dependency detected. Object %1 depends on %2. Dependencia circular detectada. El objeto %1 depende de %2. - + Circular dependency detected. Objects %1 depend on %2. Dependencia circular detectada. Los objetos %1 dependen de %2. @@ -1153,7 +1224,7 @@ Deshaciendo el último cambio. Variable de asignación esperada. - + EOF Fin de la expresión @@ -1252,6 +1323,11 @@ Expresión evaluada: %3 Enable LaTeX rendering Activar el renderizado de LaTeX + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1307,44 +1383,38 @@ Expresión evaluada: %3 Objetos - Saved plot to '%1'. - Gráfico guardado en '%1'. + Gráfico guardado en '%1'. - Loading file '%1'. - Cargando el archivo '%1'. + Cargando el archivo '%1'. - Unknown object type: %1. - Tipo de objeto desconocido: %1 . + Tipo de objeto desconocido: %1 . - Invalid file provided. - Se ha proporcionado un archivo no válido. + Se ha proporcionado un archivo no válido. - Could not load file: - No se pudo cargar el archivo: + No se pudo cargar el archivo: Could not save file: No se ha podido guardar el archivo: - Loaded file '%1'. - Archivo cargado '%1'. + Archivo cargado '%1'. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1353,12 +1423,12 @@ Si ya tiene instalada una distribución de LaTeX, asegúrese de que está instal De lo contrario, puede descargar una distribución de LaTeX como TeX Live en https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. No se ha encontrado DVIPNG. Asegúrese de incluirlo en tu distribución LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1371,7 +1441,7 @@ El proceso '{}' terminó con un código de retorno distinto de cero {} Por favor, asegúrate de que tu instalación de LaTeX es correcta e informe de un error si es así. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1384,7 +1454,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Asegúrate de que dicho paquete está instalado, o desactive el renderizado LaTeX en LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1395,6 +1465,32 @@ El proceso '{}' tardó demasiado en finalizar: Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de un error si es así. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1719,7 +1815,7 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u Valores de inicialización - + labelContent Contenido de la etiqueta @@ -1796,22 +1892,22 @@ Por favor, asegúrese de que su instalación de LaTeX es correcta e informe de u update - + An update for LogarithmPlotter (v{}) is available. Una actualización para LogarithmPlotter (v{}) está disponible. - + No update available. No hay ninguna actualización disponible. - + Could not fetch update information: Server error {}. No se ha podido obtener la información de la actualización: Error del servidor {}. - + Could not fetch update information: {}. No se pudo obtener información de la actualización: {}. diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index fd806a2..93fd60e 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -42,47 +42,47 @@ &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Preferences &Préférences - + &Create &Créer @@ -124,52 +124,52 @@ Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Notes de version - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -189,6 +189,29 @@ Vérifier la présence de mise à jour au démarrage + + Browser + + + Filter... + Filtrer… + + + + Redo > + Rétablir > + + + + > Now + > État actuel + + + + < Undo + < Annuler + + Changelog @@ -219,22 +242,22 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom @@ -243,17 +266,17 @@ Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -430,20 +453,38 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P + Nouvelle entrée + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Objets - + Settings Paramètres - + History Historique @@ -472,17 +513,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -557,45 +598,76 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P - PickLocationOverlay + PickLocation - + Pointer precision: Précision du pointeur : + + + Snap to grid: + Placer sur la grille : + + + + Pick X + Prendre la position X + + + + Pick Y + Prendre la position Y + + + + Open picker settings + Ouvrir les paramètres du pointeur + + + + Hide picker settings + Cacher les paramètres du pointeur + + + + (no pick selected) + (aucun axe sélectionné) + + + + PickLocationOverlay + + Pointer precision: + Précision du pointeur : + Snap to grid Placement sur la grille - Snap to grid: - Placer sur la grille : + Placer sur la grille : - Pick X - Prendre la position X + Prendre la position X - Pick Y - Prendre la position Y + Prendre la position Y - Open picker settings - Ouvrir les paramètres du pointeur + Ouvrir les paramètres du pointeur - Hide picker settings - Cacher les paramètres du pointeur + Cacher les paramètres du pointeur - (no pick selected) - (aucun axe sélectionné) + (aucun axe sélectionné) @@ -771,22 +843,22 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Email - + English Anglais - + French Français - + German Allemand - + Hungarian Hongrois @@ -794,26 +866,32 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P + Github GitHub - + Norwegian Norvégien - + Spanish Espagnol - + + Tamil + + + + Translations included Traductions incluses - + Improve Améliorer @@ -877,12 +955,13 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer les notes de version : Erreur de serveur {}. - + + Could not fetch update: {}. Impossible de récupérer les notes de version : {}. @@ -985,34 +1064,34 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P error - + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). @@ -1071,78 +1150,70 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - First argument to map is not a function. - Le premier argument de map n'est pas une fonction. + Le premier argument de map n'est pas une fonction. - Second argument to map is not an array. - Le deuxième argument de map n'est pas un tableau. + Le deuxième argument de map n'est pas un tableau. - First argument to fold is not a function. - Le premier argument de fold n'est pas une fonction. + Le premier argument de fold n'est pas une fonction. - Second argument to fold is not an array. - Le deuxième argument de fold n'est pas un tableau. + Le deuxième argument de fold n'est pas un tableau. - First argument to filter is not a function. - Le premier argument de filter n'est pas une fonction. + Le premier argument de filter n'est pas une fonction. - Second argument to filter is not an array. - Le deuxième argument de filter n'est pas un tableau. + Le deuxième argument de filter n'est pas un tableau. - Second argument to indexOf is not a string or array. - Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. + Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - Second argument to join is not an array. - Le deuxième argument de join n'est pas un tableau. + Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. @@ -1263,6 +1334,11 @@ Formule analysée : %3 Enable LaTeX rendering Activer le rendu LaTeX + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1318,44 +1394,38 @@ Formule analysée : %3 &Mettre à jour LogarithmPlotter - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. - Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. - Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. - Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. - Could not load file: - Impossible de charger le fichier : + Impossible de charger le fichier : Could not save file: Impossible de sauvegarder le fichier : - Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1364,12 +1434,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1382,7 +1452,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1395,7 +1465,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Assurez-vous que ce paquetage est installé, ou désactivez le rendu LaTeX dans LogarithmPlotter. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1406,6 +1476,32 @@ Le processus '{}' a mis trop de temps à se terminer : Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1730,7 +1826,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Couleur - + labelContent Étiquette @@ -1807,22 +1903,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c update - + An update for LogarithmPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index ac521eb..bff8a44 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -42,47 +42,47 @@ &Megnyitás… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Preferences &Beállítások - + &Create &Létrehozás @@ -123,52 +123,52 @@ Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -188,6 +188,29 @@ Frissítések keresése indításkor + + Browser + + + Filter... + Szűrő… + + + + Redo > + Ismétlés > + + + + > Now + > Most + + + + < Undo + < Visszavonás + + Changelog @@ -218,22 +241,22 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név @@ -242,17 +265,17 @@ Címketartalom - + null üres - + name név - + name + value név + érték @@ -428,20 +451,38 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. + Bejegyzés hozzáadása + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Tárgyak - + Settings Beállítások - + History Előzmények @@ -470,17 +511,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -555,45 +596,76 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - PickLocationOverlay + PickLocation - + Pointer precision: Mutató pontossága: + + + Snap to grid: + Rácshoz igazítás: + + + + Pick X + X kijelölése + + + + Pick Y + Y kijelölése + + + + Open picker settings + Kijelölési beállítások megnyitása + + + + Hide picker settings + Kijelölési beállítások elrejtése + + + + (no pick selected) + (nincs kijelölés kiválasztva) + + + + PickLocationOverlay + + Pointer precision: + Mutató pontossága: + Snap to grid Rácshoz illesztés - Snap to grid: - Rácshoz igazítás: + Rácshoz igazítás: - Pick X - X kijelölése + X kijelölése - Pick Y - Y kijelölése + Y kijelölése - Open picker settings - Kijelölési beállítások megnyitása + Kijelölési beállítások megnyitása - Hide picker settings - Kijelölési beállítások elrejtése + Kijelölési beállítások elrejtése - (no pick selected) - (nincs kijelölés kiválasztva) + (nincs kijelölés kiválasztva) @@ -769,22 +841,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. E-mail - + English angol - + French francia - + German német - + Hungarian magyar @@ -792,26 +864,32 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. + Github GitHub - + Norwegian norvég - + Spanish spanyol - + + Tamil + + + + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -875,12 +953,13 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -982,34 +1061,34 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). @@ -1068,78 +1147,70 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - First argument to map is not a function. - Az első leképezési argumentum nem függvény. + Az első leképezési argumentum nem függvény. - Second argument to map is not an array. - A második leképezési argumentum nem tömb. + A második leképezési argumentum nem tömb. - First argument to fold is not a function. - Az első behajtási argumentum nem függvény. + Az első behajtási argumentum nem függvény. - Second argument to fold is not an array. - A második behajtási argumentum nem tömb. + A második behajtási argumentum nem tömb. - First argument to filter is not a function. - Az első szűrési argumentum nem függvény. + Az első szűrési argumentum nem függvény. - Second argument to filter is not an array. - A második szűrési argumentum nem tömb. + A második szűrési argumentum nem tömb. - Second argument to indexOf is not a string or array. - Az indexOf második argumentuma nem karakterlánc vagy tömb. + Az indexOf második argumentuma nem karakterlánc vagy tömb. - Second argument to join is not an array. - A második csatlakozási argumentum nem tömb. + A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. @@ -1260,6 +1331,11 @@ Kiértékelt kifejezés: %3 Enable LaTeX rendering LaTeX-megjelenítés engedélyezése + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1299,38 +1375,32 @@ Kiértékelt kifejezés: %3 Előzmények - Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. - Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. - Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. - Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. - Could not load file: - Nem sikerült betölteni a fájlt: + Nem sikerült betölteni a fájlt: Could not save file: A fájl mentése nem sikerült: - Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. Copied plot screenshot to clipboard! @@ -1352,7 +1422,7 @@ Kiértékelt kifejezés: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1361,12 +1431,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1379,7 +1449,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1392,7 +1462,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Győződjön meg arról, hogy az említett csomag telepítve van, vagy tiltsa le a LaTeX megjelenítést a LogarithmPlotterben. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1403,6 +1473,32 @@ A(z) „{}” folyamat túl sokáig tartott a befejezéshez: Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1727,7 +1823,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Szín - + labelContent Címketartalom @@ -1804,22 +1900,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents update - + An update for LogarithmPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. diff --git a/assets/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts index 79657f6..97799c6 100644 --- a/assets/i18n/lp_nb_NO.ts +++ b/assets/i18n/lp_nb_NO.ts @@ -42,47 +42,47 @@ &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Preferences - + &Create &Opprett @@ -99,52 +99,52 @@ Tilbakestill angrehistorikk automatisk - + &Help &Hjelp - + &Source code - + &Report a bug &Rapporter en feil - + &User manual - + &Changelog &Endringslogg - + &Help translating! &Hjelp til å oversette! - + &Thanks &Erkjennelser - + &About &Om - + Save unsaved changes? Lagre ikke-lagrede endringer? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Dette plottet inneholder ikke-lagrede endringer. Hvis du gjør dette, vil alle ikke-lagrede data gå tapt. Fortsette? @@ -164,6 +164,29 @@ Se etter nye versjoner ved programstart + + Browser + + + Filter... + + + + + Redo > + Angre > + + + + > Now + > Nå + + + + < Undo + < Angre + + Changelog @@ -194,22 +217,22 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ugyldig objektnavn - + An object with the name '%1' already exists. Et objekt med navnet '%1' finnes allerede. - + Name Navn @@ -218,17 +241,17 @@ Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -380,20 +403,38 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects Objekter - + Settings Innstillinger - + History Historikk @@ -422,17 +463,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -507,46 +548,53 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - PickLocationOverlay + PickLocation - + Pointer precision: Peker-presisjon: + + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + + Open picker settings + + + + + Hide picker settings + + + + + (no pick selected) + + + + + PickLocationOverlay + + Pointer precision: + Peker-presisjon: + Snap to grid Fest til rutenett - - - Snap to grid: - - - - - Pick X - - - - - Pick Y - - - - - Open picker settings - - - - - Hide picker settings - - - - - (no pick selected) - - Preferences @@ -654,17 +702,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Save plot - Lagre plott + Lagre plott Save plot as - Lagre plott som + Lagre plott som Load plot - Last inn plott + Last inn plott @@ -717,22 +765,22 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + English - + French - + German - + Hungarian @@ -740,26 +788,32 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + Github GitHub - + Norwegian - + Spanish - + + Tamil + + + + Translations included - + Improve @@ -823,12 +877,13 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - + + Could not fetch update: {}. @@ -929,27 +984,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. error - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -971,39 +1026,39 @@ Undoing last change. - + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + EOF @@ -1039,51 +1094,11 @@ Undoing last change. - - + + Function %1 must have at least one argument. - - - First argument to map is not a function. - - - - - Second argument to map is not an array. - - - - - First argument to fold is not a function. - - - - - Second argument to fold is not an array. - - - - - First argument to filter is not a function. - - - - - Second argument to filter is not an array. - - - - - Second argument to indexOf is not a string or array. - - - - - Second argument to join is not an array. - - Unknown character "%1". @@ -1187,6 +1202,11 @@ Evaluated expression: %3 Enable LaTeX rendering + + + Enable threaded LaTeX renderer (experimental) + + historylib @@ -1226,38 +1246,28 @@ Evaluated expression: %3 Historikk - Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». - Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. - Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. - Invalid file provided. - Ugyldig fil angitt. - - - - Could not load file: - + Ugyldig fil angitt. Could not save file: Kunne ikke lagre fil: - Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». Copied plot screenshot to clipboard! @@ -1275,19 +1285,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1296,7 +1306,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1305,7 +1315,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1313,6 +1323,32 @@ Please make sure your latex installation is correct and report a bug if so. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1633,7 +1669,7 @@ Please make sure your latex installation is correct and report a bug if so. - + labelContent Etikett-innhold @@ -1710,22 +1746,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig. - + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. diff --git a/assets/i18n/lp_ta.ts b/assets/i18n/lp_ta.ts index 780a6b9..89125eb 100644 --- a/assets/i18n/lp_ta.ts +++ b/assets/i18n/lp_ta.ts @@ -42,97 +42,97 @@ - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Preferences - + &Create - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -145,6 +145,29 @@ + + Browser + + + Filter... + + + + + Redo > + + + + + > Now + + + + + < Undo + + + Changelog @@ -175,37 +198,37 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + null - + name - + name + value @@ -297,35 +320,53 @@ + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects - + Settings - + History - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -380,39 +421,39 @@ - PickLocationOverlay + PickLocation - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -586,22 +627,22 @@ - + English - + French - + German - + Hungarian @@ -609,26 +650,32 @@ + Github - + Norwegian - + Spanish - + + Tamil + + + + Translations included - + Improve @@ -692,12 +739,13 @@ changelog - + Could not fetch changelog: Server error {}. - + + Could not fetch update: {}. @@ -798,27 +846,27 @@ error - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -840,39 +888,39 @@ Undoing last change. - + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + EOF @@ -908,51 +956,11 @@ Undoing last change. - - + + Function %1 must have at least one argument. - - - First argument to map is not a function. - - - - - Second argument to map is not an array. - - - - - First argument to fold is not a function. - - - - - Second argument to fold is not an array. - - - - - First argument to filter is not a function. - - - - - Second argument to filter is not an array. - - - - - Second argument to indexOf is not a string or array. - - - - - Second argument to join is not an array. - - Unknown character "%1". @@ -1037,56 +1045,28 @@ Evaluated expression: %3 Enable LaTeX rendering - - - io - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not load file: - - - - - Loaded file '%1'. + + Enable threaded LaTeX renderer (experimental) latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1095,7 +1075,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1104,7 +1084,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1112,6 +1092,32 @@ Please make sure your latex installation is correct and report a bug if so. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1421,7 +1427,7 @@ Please make sure your latex installation is correct and report a bug if so. - + labelContent @@ -1473,22 +1479,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. diff --git a/assets/i18n/lp_template.ts b/assets/i18n/lp_template.ts index 81221dd..7f1bc28 100644 --- a/assets/i18n/lp_template.ts +++ b/assets/i18n/lp_template.ts @@ -42,97 +42,97 @@ - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Preferences - + &Create - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -145,6 +145,29 @@ + + Browser + + + Filter... + + + + + Redo > + + + + + > Now + + + + + < Undo + + + Changelog @@ -175,37 +198,37 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + null - + name - + name + value @@ -297,35 +320,53 @@ + + Loading + + + Loading... + + + + + Finished rendering of %1 + + + LogarithmPlotter - + + untitled + + + + Objects - + Settings - + History - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -380,41 +421,41 @@ - PickLocationOverlay + PickLocation - + Pointer precision: - + - + Snap to grid: - + - + Pick X - + - + Pick Y - + - + Open picker settings - + - + Hide picker settings - + - + (no pick selected) - + @@ -586,22 +627,22 @@ - + English - + French - + German - + Hungarian @@ -609,26 +650,32 @@ + Github - + Norwegian - + Spanish - + + Tamil + + + + Translations included - + Improve @@ -692,12 +739,13 @@ changelog - + Could not fetch changelog: Server error {}. - + + Could not fetch update: {}. @@ -798,27 +846,27 @@ error - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -840,39 +888,39 @@ Undoing last change. - + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + EOF @@ -908,51 +956,11 @@ Undoing last change. - - + + Function %1 must have at least one argument. - - - First argument to map is not a function. - - - - - Second argument to map is not an array. - - - - - First argument to fold is not a function. - - - - - Second argument to fold is not an array. - - - - - First argument to filter is not a function. - - - - - Second argument to filter is not an array. - - - - - Second argument to indexOf is not a string or array. - - - - - Second argument to join is not an array. - - Unknown character "%1". @@ -1037,56 +1045,28 @@ Evaluated expression: %3 Enable LaTeX rendering - - - io - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not load file: - - - - - Loaded file '%1'. + + Enable threaded LaTeX renderer (experimental) latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1095,7 +1075,7 @@ Please make sure your latex installation is correct and report a bug if so. - + Your LaTeX installation does not include some required packages: - {} (https://ctan.org/pkg/{}) @@ -1104,7 +1084,7 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1112,6 +1092,32 @@ Please make sure your latex installation is correct and report a bug if so. + + main + + + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. + + + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name @@ -1421,7 +1427,7 @@ Please make sure your latex installation is correct and report a bug if so. - + labelContent @@ -1473,22 +1479,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithmPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index 107eac5..c2001a2 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -232,6 +232,11 @@ BaseDialog { authorLine: 'gallegonovato', website: '', websiteName: '' + }, + TamilNeram: { + authorLine: 'தமிழ் நேரம்', + website: 'https://github.com/TamilNeram', + websiteName: qsTr('Github') } } @@ -265,6 +270,11 @@ BaseDialog { link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/', authors: [authors.IngrownMink4, authors.gallegonovato] }) + append({ + tranName: '🇱🇰 ' + qsTr('Tamil'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/ta/', + authors: [authors.TamilNeram] + }) } } From b673038b1592d946fda7189e8374e131442e5a6f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 12 Jan 2025 16:44:21 +0000 Subject: [PATCH 242/249] Translated using Weblate (English) Currently translated at 100.0% (264 of 264 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- assets/i18n/lp_en.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index 0f9b887..68590af 100644 --- a/assets/i18n/lp_en.ts +++ b/assets/i18n/lp_en.ts @@ -456,12 +456,12 @@ These settings can be changed at any time from the "Settings" menu. Loading... - + Loading… Finished rendering of %1 - + Finished rendering of %1 @@ -469,7 +469,7 @@ These settings can be changed at any time from the "Settings" menu. untitled - + untitled @@ -881,7 +881,7 @@ These settings can be changed at any time from the "Settings" menu. Tamil - + Tamil @@ -1334,7 +1334,7 @@ Evaluated expression: %3 Enable threaded LaTeX renderer (experimental) - + Enable threaded LaTeX renderer (experimental) @@ -1479,24 +1479,27 @@ Please make sure your LaTeX installation is correct and report a bug if so. This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. Please update LogarithmPlotter to open this file. - + This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. +Please update LogarithmPlotter to open this file. Could not open file "{}": {} - + Could not open file "{}": +{} Could not open file: "{}" File does not exist. - + Could not open file: "{}" +File does not exist. Built with PySide6 (Qt) v{} and python v{} - + Built with PySide6 (Qt) v{} and python v{} From 6101c0c6451d308d214873013e59afbd9c511f7f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 12 Jan 2025 17:07:29 +0000 Subject: [PATCH 243/249] Translated using Weblate (German) Currently translated at 100.0% (264 of 264 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- assets/i18n/lp_de.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 56a80ff..9ed0e8c 100644 --- a/assets/i18n/lp_de.ts +++ b/assets/i18n/lp_de.ts @@ -456,12 +456,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Loading... - + Laden… Finished rendering of %1 - + Beendetes Rendering von %1 @@ -469,7 +469,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" untitled - + unbetitelt @@ -881,7 +881,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Tamil - + Tamil @@ -1334,7 +1334,7 @@ Ausdruck analysiert: %3 Enable threaded LaTeX renderer (experimental) - + LaTeX-Renderer mit Threads aktivieren (experimentell) @@ -1479,24 +1479,27 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. Please update LogarithmPlotter to open this file. - + Diese Datei wurde mit einer neueren Version von LogarithmPlotter erstellt und kann nicht in LogarithmPlotter v{} zurückgeladen werden. +Bitte aktualisieren Sie LogarithmPlotter, um diese Datei zu öffnen. Could not open file "{}": {} - + Die Datei „{}“ konnte nicht geöffnet werden: +{} Could not open file: "{}" File does not exist. - + Die Datei „{}“ konnte nicht geöffnet werden: +Die Datei existiert nicht. Built with PySide6 (Qt) v{} and python v{} - + Kompiliert mit PySide6 (Qt) v{} und python v{} From 54f82eab92723aa41ba5db76b77fc4a6b8cab4b4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 12 Jan 2025 16:58:58 +0000 Subject: [PATCH 244/249] Translated using Weblate (French) Currently translated at 100.0% (264 of 264 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- assets/i18n/lp_fr.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index 93fd60e..d2e6380 100644 --- a/assets/i18n/lp_fr.ts +++ b/assets/i18n/lp_fr.ts @@ -458,12 +458,12 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Loading... - + Chargement… Finished rendering of %1 - + Rendu de %1 terminé @@ -471,7 +471,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P untitled - + sans titre @@ -883,7 +883,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Tamil - + Tamoul @@ -1337,7 +1337,7 @@ Formule analysée : %3 Enable threaded LaTeX renderer (experimental) - + Activer le moteur de rendu LaTeX asynchrone (expérimental) @@ -1482,24 +1482,27 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. Please update LogarithmPlotter to open this file. - + Ce fichier a été créé par une version plus récente de LogarithmPlotter et ne peut pas être rechargé dans LogarithmPlotter v{}. +Veuillez mettre à jour LogarithmPlotter pour ouvrir ce fichier. Could not open file "{}": {} - + Impossible d'ouvrir le fichier "{}": +{} Could not open file: "{}" File does not exist. - + Impossible d'ouvrir le fichier "{}": +Le fichier n'existe pas. Built with PySide6 (Qt) v{} and python v{} - + Compilé avec PySide6 (Qt) v{} et python v{} From 2c8011056de43b28b8be01274dcbff8efd120fa2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 12 Jan 2025 18:08:44 +0100 Subject: [PATCH 245/249] Fixing not recreating canvas context if it already exists. --- common/src/module/canvas.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index dcc3f33..22166d5 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -212,8 +212,9 @@ class CanvasAPI extends Module { */ redraw() { if(!this.initialized) throw new Error("Attempting redraw before initialize!") + if(this.#ctx == null) + this.#ctx = this.#canvas.getContext("2d") this.#redrawCount = (this.#redrawCount + 1) % 10000 - this.#ctx = this.#canvas.getContext("2d") this._computeAxes() this._reset() this._drawGrid() From 5fa118233c1db0e000dca68a3778c0c61ef9eab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=A4=E0=AE=AE=E0=AE=BF=E0=AE=B4=E0=AF=8D=E0=AE=A8?= =?UTF-8?q?=E0=AF=87=E0=AE=B0=E0=AE=AE=E0=AF=8D?= Date: Mon, 13 Jan 2025 00:23:27 +0000 Subject: [PATCH 246/249] Translated using Weblate (Tamil) Currently translated at 99.6% (263 of 264 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/ta/ --- assets/i18n/lp_ta.ts | 556 +++++++++++++++++++++++-------------------- 1 file changed, 292 insertions(+), 264 deletions(-) diff --git a/assets/i18n/lp_ta.ts b/assets/i18n/lp_ta.ts index 89125eb..2f3048c 100644 --- a/assets/i18n/lp_ta.ts +++ b/assets/i18n/lp_ta.ts @@ -6,27 +6,27 @@ About LogarithmPlotter - + மடக்கை பற்றி LogarithmPlotter v%1 - + மடக்கை சதித்திட்டம் வி 1 2D plotter software to make BODE plots, sequences and repartition functions. - + போட் அடுக்கு, காட்சிகள் மற்றும் விநியோக செயல்பாடுகளை உருவாக்க 2 டி ப்ளாட்டர் மென்பொருள். Report a bug - + ஒரு பிழையைப் புகாரளிக்கவும் Official website - + அதிகாரப்பூர்வ வலைத்தளம் @@ -34,107 +34,107 @@ &File - + கோப்பு (&f) &Load... - + & திறந்த… &Save - + சேமி (&s) Save &As... - + சேமிக்கவும்… &Quit - + &வெளியேறு &Edit - + திருத்து (&e) &Undo - + செயல்தவிர் (&u) &Redo - + மீண்டும்செய் (&r) &Copy plot - + & சூழ்ச்சி நகலெடுக்கவும் &Preferences - + &விருப்பத்தேர்வுகள் &Create - + & உருவாக்கு &Help - + உதவி (&h) &Source code - + & மூலக் குறியீடு &Report a bug - + ஒரு பிழையைப் புகாரளிக்கவும் &User manual - + & பயனர் கையேடு &Changelog - + & சேஞ்ச்லாக் &Help translating! - + & மொழிபெயர்க்க உதவுங்கள்! &Thanks - + & நன்றி &About - + &பற்றி Save unsaved changes? - + சேமிக்கப்படாத மாற்றங்களைச் சேமிக்கவா? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + இந்த சதித்திட்டத்தில் சேமிக்கப்படாத மாற்றங்கள் உள்ளன. இதைச் செய்வதன் மூலம், சேமிக்கப்படாத அனைத்து தரவும் இழக்கப்படும். தொடரவா? @@ -142,7 +142,7 @@ Close - + மூடு @@ -150,22 +150,22 @@ Filter... - + வடிகட்டி… Redo > - + மீண்டும்> > Now - + > இப்போது < Undo - + <செயல்தவிர்க்கவும் @@ -173,12 +173,12 @@ Fetching changelog... - + சேஞ்ச்லாக் பெறுதல்… Close - + மூடு @@ -187,12 +187,12 @@ + Create new %1 - + + புதிய %1 ஐ உருவாக்கவும் Pick on graph - + வரைபடத்தைத் தேர்ந்தெடுங்கள் @@ -200,37 +200,37 @@ Edit properties of %1 %2 - + %1 %2 இன் பண்புகளைத் திருத்தவும் LogarithmPlotter - Invalid object name - + மடக்கை - தவறான பொருள் பெயர் An object with the name '%1' already exists. - + '%1' என்ற பெயரைக் கொண்ட ஒரு பொருள் ஏற்கனவே உள்ளது. Name - + பெயர் null - + சுழியம் name - + பெயர் name + value - + பெயர் + மதிப்பு @@ -238,32 +238,32 @@ Object Properties - + பொருள் பண்புகள் Variables - + மாறிகள் Constants - + மாறிலிகள் Functions - + செயல்பாடுகள் Executable Objects - + செயல்பாடு பொருள்கள் Objects - + பொருள்கள் @@ -271,12 +271,12 @@ Export Logarithm Plot file - + மடக்கை சூழ்ச்சி கோப்பை ஏற்றுமதி செய்யுங்கள் Import Logarithm Plot file - + மடக்கை சூழ்ச்சி கோப்பை இறக்குமதி செய்க @@ -284,32 +284,32 @@ Welcome to LogarithmPlotter - + மடக்கை பிளாட்டருக்கு வருக Version %1 - + பதிப்பு %1 User manual - + பயனர் கையேடு Changelog - + மாற்றபதிவு Preferences - + விருப்பத்தேர்வுகள் Close - + மூடு @@ -317,7 +317,7 @@ + Add Entry - + + உள்ளீட்டைச் சேர்க்கவும் @@ -325,12 +325,12 @@ Loading... - + ஏற்றுகிறது… Finished rendering of %1 - + %1 இன் வழங்குதல் முடிந்தது @@ -338,37 +338,37 @@ untitled - + தலைப்பிடப்படாத Objects - + பொருள்கள் Settings - + அமைப்புகள் History - + வரலாறு Copied plot screenshot to clipboard! - + இடைநிலைப்பலகைக்கு சூழ்ச்சி திரை சாட்டை நகலெடுத்தது! &Update - + & புதுப்பிக்கவும் &Update LogarithmPlotter - + & மடக்கை புதுப்பிக்கவும் @@ -376,7 +376,7 @@ + Create new: - + + புதியதை உருவாக்கு: @@ -384,12 +384,12 @@ Hide all %1 - + அனைத்து %1 ஐ மறைக்கவும் Show all %1 - + அனைத்து %1 ஐக் காட்டு @@ -397,27 +397,27 @@ Hide %1 %2 - + %1 %2 ஐ மறைக்கவும் Show %1 %2 - + %1 %2 ஐக் காட்டு Set %1 %2 position - + %1 %2 நிலையை அமைக்கவும் Delete %1 %2 - + %1 %2 ஐ நீக்கு Pick new color for %1 %2 - + %1 %2 க்கு புதிய வண்ணத்தைத் தேர்ந்தெடுங்கள் @@ -425,37 +425,37 @@ Pointer precision: - + சுட்டிக்காட்டி துல்லியம்: Snap to grid: - + கட்டம் வரை: Pick X - + ஃச் பிக் Pick Y - + ஒய் ஐ தேர்வு செய்யுங்கள் Open picker settings - + திறந்த பிக்கர் அமைப்புகள் Hide picker settings - + பிக்கர் அமைப்புகளை மறைக்கவும் (no pick selected) - + (தேர்ந்தெடுக்கப்பட்ட தேர்வு இல்லை) @@ -463,7 +463,7 @@ Close - + மூடு @@ -472,109 +472,109 @@ X Zoom - + ஃச் சூம் Y Zoom - + மற்றும் பெரிதாக்கு Min X - + என் ஃச் Max Y - + அதிகபட்சம் மற்றும் Max X - + அதிகபட்ச ஃச் Min Y - + Min ஒய் X Axis Step - + ஃச் அச்சு படி Y Axis Step - + ஒய் அச்சு படி Line width - + வரி அகலம் Text size (px) - + உரை அளவு (பிஎக்ச்) X Label - + ஃச் சிட்டை Y Label - + ஒய் சிட்டை X Log scale - + ஃச் பதிவு அளவுகோல் Show X graduation - + ஃச் பட்டப்படிப்பைக் காட்டு Show Y graduation - + ஒய் பட்டப்படிப்பைக் காட்டு Copy to clipboard - + இடைநிலைப்பலகைக்கு நகலெடுக்கவும் Save plot - + சதித்திட்டத்தை சேமிக்கவும்… Save plot as - + சூழ்ச்சி சேமிக்கவும்… Load plot - + திறந்த சதி… @@ -582,69 +582,69 @@ Thanks and Contributions - LogarithmPlotter - + நன்றி மற்றும் பங்களிப்புகள் - மடக்கை Source code - + மூலக் குறியீடு Original library by Raphael Graf - + ரபேல் கிராஃப் எழுதிய அசல் நூலகம் Source - + மூலம் Ported to Javascript by Matthew Crumley - + மத்தேயு க்ரம்லி எழுதிய சாவாச்கிரிப்டுக்கு அனுப்பப்பட்டது Website - + வலைத்தளம் Ported to QMLJS by Ad5001 - + AD5001 ஆல் QMLJS க்கு அனுப்பப்பட்டது Libraries included - + நூலகங்கள் சேர்க்கப்பட்டுள்ளன Email - + மின்னஞ்சல் English - + ஆங்கிலம் French - + பிரஞ்சு German - + செர்மன் Hungarian - + அங்கேரியன் @@ -652,32 +652,32 @@ Github - + கிரப் Norwegian - + நோர்வே Spanish - + ச்பானிச் Tamil - + தமிழ் Translations included - + மொழிபெயர்ப்புகள் சேர்க்கப்பட்டுள்ளன Improve - + மேம்படுத்தவும் @@ -685,24 +685,24 @@ Bode Magnitude - + போட் அளவு Bode Magnitudes - + போட் அளவுகள் low-pass - + குறைந்த பாச் high-pass - + உயர்-பாச் @@ -711,7 +711,7 @@ Bode Magnitudes Sum - + போட் அளவு தொகை @@ -719,12 +719,12 @@ Bode Phase - + போட் கட்டம் Bode Phases - + போட் கட்டங்கள் @@ -733,7 +733,7 @@ Bode Phases Sum - + போட் கட்டங்கள் தொகை @@ -741,13 +741,13 @@ Could not fetch changelog: Server error {}. - + சேஞ்ச்லாக் பெற முடியவில்லை: சேவையக பிழை {}. Could not fetch update: {}. - + சேஞ்ச்லாக் பெற முடியவில்லை: {}. @@ -756,7 +756,7 @@ %1 %2's color changed from %3 to %4. - + %1 %2 இன் நிறம் %3 முதல் %4 வரை மாற்றப்பட்டது. @@ -764,27 +764,27 @@ Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + Ex: r+* (ℝ⁺*), n (ℕ), z-* (ℤ⁻*),] 0; 1 [, {3; 4; 5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + டொமைன் ஒரு தொடர்ச்சியான தொகுப்பாக இருக்கும்போது பின்வரும் அளவுருக்கள் பயன்படுத்தப்படுகின்றன. (எ.கா: ℕ, ℤ, {0; 3}…) Note: Specify the probability for each value. - + குறிப்பு: ஒவ்வொரு மதிப்புக்கும் நிகழ்தகவைக் குறிப்பிடவும். Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - + குறிப்பு: %1ₙ, %1 [n+1] ஐ %1ₙ₊₁ க்கு குறிக்க %1 [n] ஐப் பயன்படுத்தவும்… If you have latex enabled, you can use use latex markup in between $$ to create equations. - + நீங்கள் லேடெக்ச் இயக்கப்பட்டிருந்தால், சமன்பாடுகளை உருவாக்க லேடெக்ச் மார்க்அப்பைப் பயன்படுத்தலாம். @@ -796,7 +796,7 @@ %1: - + %1: @@ -805,7 +805,7 @@ New %1 %2 created. - + புதிய %1 %2 உருவாக்கப்பட்டது. @@ -814,7 +814,7 @@ %1 %2 deleted. - + %1 %2 நீக்கப்பட்டது. @@ -822,12 +822,12 @@ Repartition - + பரவல் Repartition functions - + விநியோக செயல்பாடுகள் @@ -835,12 +835,12 @@ %1 of %2 %3 changed from "%4" to "%5". - + %2 %3 இல் %1 " %4" இலிருந்து " %5" ஆக மாற்றப்பட்டது. %1 of %2 changed from %3 to %4. - + %2 இல் %1 %3 முதல் %4 வரை மாற்றப்பட்டது. @@ -848,27 +848,27 @@ No object found with names %1. - + %1 பெயர்களைக் கொண்ட எந்த பொருளும் காணப்படவில்லை. No object found with name %1. - + %1 என்ற பெயருடன் எந்த பொருளும் காணப்படவில்லை. Object cannot be dependent on itself. - + பொருள் தன்னைச் சார்ந்து இருக்க முடியாது. Circular dependency detected. Object %1 depends on %2. - + வட்ட சார்பு கண்டறியப்பட்டது. பொருள் %1 %2 ஐப் பொறுத்தது. Circular dependency detected. Objects %1 depend on %2. - + வட்ட சார்பு கண்டறியப்பட்டது. பொருள்கள் %1 %2 ஐ சார்ந்துள்ளது. @@ -876,7 +876,10 @@ %2 Evaluated expression: %3 - + சொத்து %1 க்கான வெளிப்பாட்டை பாகுபடுத்தும்போது பிழை: + %2 + + மதிப்பீடு செய்யப்பட்ட வெளிப்பாடு: %3 @@ -884,93 +887,96 @@ Evaluated expression: %3 %3 Undoing last change. - + %1 %2 ஐ வரைய முயற்சிக்கும் போது பிழை: + %3 + + கடைசி மாற்றத்தை செயல்தவிர்க்கவும். Cannot find property %1 of object %2. - + பொருள் %2 இன் சொத்து %1 ஐக் கண்டுபிடிக்க முடியாது. Undefined variable %1. - + வரையறுக்கப்படாத மாறி %1. In order to be executed, object %1 must have at least one argument. - + செயல்படுத்தப்படுவதற்கு, பொருள் %1 க்கு குறைந்தது ஒரு உரையாடல் இருக்க வேண்டும். %1 cannot be executed. - + %1 ஒரு செயல்பாடு அல்ல. Invalid expression. - + தவறான வெளிப்பாடு. Invalid expression (parity). - + தவறான வெளிப்பாடு (சமநிலை). EOF - + வெளிப்பாட்டின் முடிவு Parse error [position %1]: %2 - + பாகுபடுத்தும் பிழை [நிலை %1]: %2 Expected %1 - + எதிர்பார்க்கப்படும் %1 Unexpected %1 - + எதிர்பாராத %1 Unexpected ".": member access is not permitted - + எதிர்பாராதது ".": உறுப்பினர் அணுகல் அனுமதிக்கப்படவில்லை Unexpected "[]": arrays are disabled. - + எதிர்பாராத "[]": வரிசைகள் முடக்கப்பட்டுள்ளன. Unexpected symbol: %1. - + எதிர்பாராத சின்னம்: %1. Function %1 must have at least one argument. - + செயல்பாடு %1 க்கு குறைந்தது ஒரு உரையாடல் இருக்க வேண்டும். Unknown character "%1". - + அறியப்படாத எழுத்து "%1". Illegal escape sequence: %1. - + சட்டவிரோத தப்பிக்கும் வரிசை: %1. @@ -979,7 +985,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + மடக்கை பிளாட்டர் - பாகுபடுத்தும் பிழை @@ -987,32 +993,35 @@ Undoing last change. %2 Evaluated expression: %3 - + சொத்து %1 க்கான வெளிப்பாட்டை பாகுபடுத்தும்போது பிழை: + %2 + + மதிப்பீடு செய்யப்பட்ட வெளிப்பாடு: %3 LogarithmPlotter - Drawing error - + மடக்கை - வரைதல் பிழை Automatically close parenthesises and brackets - + தானாகவே அடைப்புக்குறிப்புகள் மற்றும் அடைப்புக்குறிகளை மூடு Enable syntax highlighting - + தொடரியல் சிறப்பம்சத்தை இயக்கவும் Enable autocompletion - + தன்னியக்கவியல் இயக்கவும் Color Scheme - + வண்ணத் திட்டம் @@ -1020,12 +1029,12 @@ Evaluated expression: %3 Function - + சார்பு Functions - + செயல்பாடுகள் @@ -1033,22 +1042,22 @@ Evaluated expression: %3 Check for updates on startup - + தொடக்கத்தின் புதுப்பிப்புகளைச் சரிபார்க்கவும் Reset redo stack automaticly - + மீண்டும் அடுக்கை மீட்டமைக்கவும் Enable LaTeX rendering - + லேடெக்ச் வழங்குதல் இயக்கவும் Enable threaded LaTeX renderer (experimental) - + திரிக்கப்பட்ட லேடெக்ச் ரெண்டரரை இயக்கவும் (சோதனை) @@ -1058,12 +1067,14 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + லேடெக்ச் நிறுவல் எதுவும் கிடைக்கவில்லை. + உங்களிடம் ஏற்கனவே லேடெக்ச் வழங்கல் நிறுவப்பட்டிருந்தால், அது உங்கள் பாதையில் நிறுவப்பட்டுள்ளதா என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள். + இல்லையெனில், டெக்ச் லைவ் போன்ற லேடெக்ச் விநியோகத்தை https://tug.org/texlive/ இல் பதிவிறக்கம் செய்யலாம். DVIPNG was not found. Make sure you include it from your Latex distribution. - + Dvipng கண்டுபிடிக்கப்படவில்லை. உங்கள் லேடெக்ச் விநியோகத்திலிருந்து இதைச் சேர்த்துள்ளீர்கள் என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள். @@ -1072,7 +1083,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + லேடெக்ச் சூத்திரத்தை உருவாக்குவதற்குள் விதிவிலக்கு ஏற்பட்டது. + '{}' ஐ பூச்சியமற்ற வருவாய் குறியீட்டோடு முடிந்தது {}: + + {} + உங்கள் லேடெக்ச் நிறுவல் சரியானது என்பதை உறுதிப்படுத்தவும், அப்படியானால் ஒரு பிழையைப் புகாரளிக்கவும். @@ -1081,7 +1096,11 @@ Please make sure your latex installation is correct and report a bug if so. - + உங்கள் லேடெக்ச் நிறுவலில் தேவையான சில தொகுப்புகள் இல்லை: + + - {} (https://ctan.org/pkg/ {}) + + தொகுப்பு நிறுவப்பட்டிருப்பதை உறுதிசெய்து கொள்ளுங்கள், அல்லது லோகரிதம்லட்டரில் லேடெக்ச் வழங்குதல் முடக்கவும். @@ -1089,7 +1108,10 @@ Make sure said package is installed, or disable the LaTeX rendering in Logarithm Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + லேடெக்ச் சூத்திரத்தை உருவாக்குவதற்குள் விதிவிலக்கு ஏற்பட்டது. + '{}' செயல்முறை முடிக்க அதிக நேரம் எடுத்தது: + {} + உங்கள் லேடெக்ச் நிறுவல் சரியானது என்பதை உறுதிப்படுத்தவும், அப்படியானால் ஒரு பிழையைப் புகாரளிக்கவும். @@ -1098,24 +1120,27 @@ Please make sure your latex installation is correct and report a bug if so. This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. Please update LogarithmPlotter to open this file. - + இந்த கோப்பு மடக்கை படத்தின் மிக அண்மைக் கால பதிப்பால் உருவாக்கப்பட்டது, மேலும் லோகரிதம் பிளாட்டர் v {fol இல் பின்வாங்க முடியாது. + இந்த கோப்பைத் திறக்க லோகரிதில் பிளாட்டரைப் புதுப்பிக்கவும். Could not open file "{}": {} - + "{}" கோப்பைத் திறக்க முடியவில்லை: + {} Could not open file: "{}" File does not exist. - + கோப்பைத் திறக்க முடியவில்லை: "{}" + கோப்பு இல்லை. Built with PySide6 (Qt) v{} and python v{} - + Pyside6 (qt) V {} மற்றும் பைதான் V {with உடன் கட்டப்பட்டுள்ளது @@ -1124,7 +1149,7 @@ File does not exist. %1 %2 renamed to %3. - + %1 %2 %3 என மறுபெயரிடப்பட்டது. @@ -1132,114 +1157,114 @@ File does not exist. above - + மேலே below - + கீழே left - + . இடது right - + சரி above-left - + இடதுபுறம் மேலே above-right - + ↗ மேலே வலதுபுறம் below-left - + இடதுபுறமாக கீழே below-right - + ↘ கீழே வலது கீழே center - + > | <மையம் top - + . மேல் bottom - + கீழே top-left - + ↖ மேல் இடது top-right - + ↗ மேல் வலது bottom-left - + ↙ கீழ் இடது bottom-right - + வலது வலது application - + பயன்பாடு function - + சார்பு high - + உயர்ந்த low - + குறைந்த Next to target - + இலக்கு அடுத்து With label - + லேபிளுடன் Hidden - + மறைக்கப்பட்ட @@ -1247,12 +1272,12 @@ File does not exist. Point - + புள்ளியம் Points - + பிரிவகம் @@ -1260,12 +1285,12 @@ File does not exist. Position of %1 %2 set from "%3" to "%4". - + %1%2 "%3" இலிருந்து "%4" க்கு நகர்ந்தது. Position of %1 set from %2 to %3. - + %1 %2 முதல் %3 வரை நகர்ந்தது. @@ -1273,22 +1298,22 @@ File does not exist. expression - + கோவை definitionDomain - + டொமைன் destinationDomain - + வீச்சு displayMode - + காட்சி முறை @@ -1302,7 +1327,7 @@ File does not exist. labelPosition - + சிட்டை நிலை @@ -1313,123 +1338,123 @@ File does not exist. labelX - + லேபிளின் ஃச் நிலை drawPoints - + புள்ளிகளைக் காட்டு drawDashedLines - + கோடு கோடுகளைக் காட்டு om_0 - + pass - + கணவாய் gain - + அளவு ஆதாயம் omGraduation - + Ω₀ இல் பட்டப்படிப்பைக் காட்டு phase - + கட்டம் unit - + பயன்படுத்த அலகு x - + ஃச் y - + ஒய் pointStyle - + புள்ளி நடை probabilities - + நிகழ்தகவுகள் பட்டியல் defaultExpression - + இயல்புநிலை வெளிப்பாடு baseValues - + துவக்க மதிப்புகள் text - + உள்ளடக்கம் disableLatex - + இந்த உரைக்கு லேடெக்ச் வழங்குதல் முடக்கு targetElement - + இலக்கை எதிர்க்கவும் approximate - + வட்டமான கணக்கிடப்பட்ட மதிப்பைக் காட்டு rounding - + சுற்று displayStyle - + காட்சி நடை targetValuePosition - + இலக்கின் மதிப்பு நிலை labelContent - + சிட்டை உள்ளடக்கம் @@ -1437,12 +1462,12 @@ File does not exist. Sequence - + வரிசை Sequences - + வரிசைகள் @@ -1450,17 +1475,17 @@ File does not exist. general - + பொது editor - + வெளிப்பாடு ஆசிரியர் default - + இயல்புநிலை அமைப்புகள் @@ -1468,12 +1493,12 @@ File does not exist. Text - + உரை Texts - + நூல்கள் @@ -1481,22 +1506,22 @@ File does not exist. An update for LogarithmPlotter (v{}) is available. - + மடக்கை (v {}) க்கான புதுப்பிப்பு கிடைக்கிறது. No update available. - + புதுப்பிப்பு எதுவும் கிடைக்கவில்லை. Could not fetch update information: Server error {}. - + புதுப்பிப்பு தகவலைப் பெற முடியவில்லை: சேவையக பிழை {}. Could not fetch update information: {}. - + புதுப்பிப்பு தகவல்களைப் பெற முடியவில்லை: {}. @@ -1504,14 +1529,15 @@ File does not exist. integral(<from: number>, <to: number>, <f: ExecutableObject>) - + ஒருங்கிணைந்த (<இலிருந்து: எண்>, <க்கு: எண்>, <f: செயல்பாடு போன்ற பொருள்>) Usage: %1 - + பயன்பாடு: + %1 @@ -1520,22 +1546,24 @@ File does not exist. Usage: %1 %2 - + பயன்பாடு: + %1 + %2 integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + ஒருங்கிணைந்த (<இலிருந்து: எண்>, <க்கு: எண்>, <f: சரம்>, <மாறி: சரம்>) derivative(<f: ExecutableObject>, <x: number>) - + வழித்தோன்றல் (<f: செயல்பாடு போன்ற பொருள்>, <x: எண்>) derivative(<f: string>, <variable: string>, <x: number>) - + வழித்தோன்றல் (<f: சரம்>, <மாறி: சரம்>, <x: எண்>) @@ -1544,13 +1572,13 @@ File does not exist. %1 %2 shown. - + %1 %2 காட்டப்பட்டுள்ளது. %1 %2 hidden. - + %1 %2 மறைக்கப்பட்டுள்ளது. @@ -1558,12 +1586,12 @@ File does not exist. X Cursor - + ஃச் கர்சர் X Cursors - + ஃச் கர்சர்கள் From 310afa5672660b64b6e8bf62901e333cc03c1e08 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 6 Feb 2025 19:08:39 +0100 Subject: [PATCH 247/249] Disabling experimental threaded rendering by default for now. --- runtime-pyside6/LogarithmPlotter/util/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index 020569a..a7b2ffb 100644 --- a/runtime-pyside6/LogarithmPlotter/util/config.py +++ b/runtime-pyside6/LogarithmPlotter/util/config.py @@ -28,7 +28,7 @@ DEFAULT_SETTINGS = { "reset_redo_stack": True, "last_install_greet": "0", "enable_latex": which("latex") is not None and which("dvipng") is not None, - "enable_latex_threaded": True, + "enable_latex_threaded": False, "expression_editor": { "autoclose": True, "colorize": True, From fbef5dc28aa566bd1250a94ad4805575bfdfaf91 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 6 Feb 2025 19:14:00 +0100 Subject: [PATCH 248/249] Updating copyrights to 2025. --- README.md | 2 +- assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 2 +- assets/native/win/installer.nsi | 2 +- common/rollup.config.mjs | 2 +- common/src/events.mjs | 2 +- common/src/history/color.mjs | 2 +- common/src/history/common.mjs | 2 +- common/src/history/create.mjs | 2 +- common/src/history/delete.mjs | 2 +- common/src/history/editproperty.mjs | 2 +- common/src/history/index.mjs | 2 +- common/src/history/name.mjs | 2 +- common/src/history/position.mjs | 2 +- common/src/history/visibility.mjs | 2 +- common/src/index.mjs | 2 +- common/src/lib/expr-eval/expression.mjs | 2 +- common/src/lib/expr-eval/instruction.mjs | 2 +- common/src/lib/expr-eval/parser.mjs | 2 +- common/src/lib/expr-eval/parserstate.mjs | 2 +- common/src/lib/expr-eval/polyfill.mjs | 2 +- common/src/lib/expr-eval/tokens.mjs | 2 +- common/src/lib/polyfills/js.mjs | 4 ++-- common/src/lib/polyfills/qt.mjs | 2 +- common/src/math/domain.mjs | 2 +- common/src/math/expression.mjs | 2 +- common/src/math/index.mjs | 2 +- common/src/math/sequence.mjs | 2 +- common/src/module/canvas.mjs | 2 +- common/src/module/common.mjs | 2 +- common/src/module/expreval.mjs | 2 +- common/src/module/history.mjs | 2 +- common/src/module/index.mjs | 2 +- common/src/module/interface.mjs | 2 +- common/src/module/io.mjs | 2 +- common/src/module/latex.mjs | 2 +- common/src/module/objects.mjs | 2 +- common/src/module/preferences.mjs | 2 +- common/src/module/settings.mjs | 2 +- common/src/objs/autoload.mjs | 2 +- common/src/objs/bodemagnitude.mjs | 2 +- common/src/objs/bodemagnitudesum.mjs | 2 +- common/src/objs/bodephase.mjs | 2 +- common/src/objs/bodephasesum.mjs | 2 +- common/src/objs/common.mjs | 2 +- common/src/objs/distribution.mjs | 2 +- common/src/objs/function.mjs | 2 +- common/src/objs/point.mjs | 2 +- common/src/objs/sequence.mjs | 2 +- common/src/objs/text.mjs | 2 +- common/src/objs/xcursor.mjs | 2 +- common/src/parameters.mjs | 2 +- common/src/parsing/common.mjs | 2 +- common/src/parsing/index.mjs | 2 +- common/src/parsing/reference.mjs | 2 +- common/src/parsing/tokenizer.mjs | 2 +- common/src/preferences/common.mjs | 2 +- common/src/preferences/default.mjs | 2 +- common/src/preferences/expression.mjs | 2 +- common/src/preferences/general.mjs | 2 +- common/src/utils/expression.mjs | 2 +- common/src/utils/index.mjs | 2 +- common/src/utils/other.mjs | 2 +- common/src/utils/prototype.mjs | 2 +- common/src/utils/subsup.mjs | 2 +- common/test/basics/events.mjs | 2 +- common/test/basics/interface.mjs | 2 +- common/test/basics/polyfill.mjs | 2 +- common/test/basics/utils.mjs | 2 +- common/test/hooks.mjs | 2 +- common/test/math/domain.mjs | 2 +- common/test/math/expression.mjs | 2 +- common/test/mock/canvas.mjs | 2 +- common/test/mock/dialog.mjs | 2 +- common/test/mock/fs.mjs | 2 +- common/test/mock/helper.mjs | 2 +- common/test/mock/latex.mjs | 2 +- common/test/mock/qt.mjs | 2 +- common/test/mock/root.mjs | 2 +- common/test/module/base.mjs | 2 +- common/test/module/expreval.mjs | 2 +- common/test/module/latex.mjs | 2 +- common/test/module/objects.mjs | 2 +- common/test/module/settings.mjs | 2 +- run.py | 2 +- runtime-pyside6/LogarithmPlotter/__init__.py | 2 +- runtime-pyside6/LogarithmPlotter/logarithmplotter.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/Browser.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml | 2 +- .../LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/About.qml | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml | 2 +- .../LogarithmPlotter/Setting/AutocompletionCategory.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- runtime-pyside6/LogarithmPlotter/util/config.py | 2 +- runtime-pyside6/LogarithmPlotter/util/debug.py | 2 +- runtime-pyside6/LogarithmPlotter/util/helper.py | 2 +- runtime-pyside6/LogarithmPlotter/util/js.py | 2 +- runtime-pyside6/LogarithmPlotter/util/latex.py | 2 +- runtime-pyside6/LogarithmPlotter/util/native.py | 2 +- runtime-pyside6/LogarithmPlotter/util/promise.py | 2 +- runtime-pyside6/LogarithmPlotter/util/update.py | 2 +- runtime-pyside6/setup.py | 2 +- runtime-pyside6/tests/globals.py | 2 +- runtime-pyside6/tests/plugins/natural/__init__.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/assertion.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/base.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/basic.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/int.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/spy.py | 2 +- runtime-pyside6/tests/plugins/natural/interfaces/utils.py | 2 +- runtime-pyside6/tests/plugins/natural/spy.py | 2 +- runtime-pyside6/tests/plugins/natural/that.py | 2 +- runtime-pyside6/tests/plugins/tests/test_natural.py | 2 +- runtime-pyside6/tests/test_config.py | 2 +- runtime-pyside6/tests/test_debug.py | 2 +- runtime-pyside6/tests/test_helper.py | 2 +- runtime-pyside6/tests/test_latex.py | 2 +- runtime-pyside6/tests/test_main.py | 2 +- runtime-pyside6/tests/test_native.py | 2 +- runtime-pyside6/tests/test_promise.py | 2 +- runtime-pyside6/tests/test_pyjs.py | 2 +- runtime-pyside6/tests/test_update.py | 2 +- scripts/build.sh | 2 +- 145 files changed, 147 insertions(+), 147 deletions(-) diff --git a/README.md b/README.md index 976df53..f06d009 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Finally, to actually run the tests: ## Legal notice LogarithmPlotter - 2D plotter software to make Bode plots, sequences and repartition functions. - Copyright (C) 2021-2024 Ad5001 + Copyright (C) 2021-2025 Ad5001 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index a9dbded..f7e4c9d 100644 --- a/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,5 +1,5 @@ - + eu.ad5001.LogarithmPlotter logarithmplotter.desktop diff --git a/assets/native/win/installer.nsi b/assets/native/win/installer.nsi index ebb84c9..bf38199 100644 --- a/assets/native/win/installer.nsi +++ b/assets/native/win/installer.nsi @@ -13,7 +13,7 @@ Unicode True !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" !define VERSION_SHORT "0.6.0" !define APP_VERSION "${VERSION_SHORT}.0" -!define COPYRIGHT "Ad5001 (c) 2021-2024" +!define COPYRIGHT "Ad5001 (c) 2021-2025" !define DESCRIPTION "Create graphs with logarithmic scales." !define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter" diff --git a/common/rollup.config.mjs b/common/rollup.config.mjs index 6156873..5c4d38a 100644 --- a/common/rollup.config.mjs +++ b/common/rollup.config.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/events.mjs b/common/src/events.mjs index 75a7a52..1ef3777 100644 --- a/common/src/events.mjs +++ b/common/src/events.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/color.mjs b/common/src/history/color.mjs index 1d395ed..0efa29d 100644 --- a/common/src/history/color.mjs +++ b/common/src/history/color.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/common.mjs b/common/src/history/common.mjs index e8e5795..8c46757 100644 --- a/common/src/history/common.mjs +++ b/common/src/history/common.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/create.mjs b/common/src/history/create.mjs index 1308d9e..fb27f62 100644 --- a/common/src/history/create.mjs +++ b/common/src/history/create.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/delete.mjs b/common/src/history/delete.mjs index f9674c5..2f8d8fe 100644 --- a/common/src/history/delete.mjs +++ b/common/src/history/delete.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/editproperty.mjs b/common/src/history/editproperty.mjs index 886f100..2a81e7a 100644 --- a/common/src/history/editproperty.mjs +++ b/common/src/history/editproperty.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/index.mjs b/common/src/history/index.mjs index aa57307..a2ef1ea 100644 --- a/common/src/history/index.mjs +++ b/common/src/history/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/name.mjs b/common/src/history/name.mjs index 5c5b397..61bb6b5 100644 --- a/common/src/history/name.mjs +++ b/common/src/history/name.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/position.mjs b/common/src/history/position.mjs index 3bf2fe8..2b9c0ff 100644 --- a/common/src/history/position.mjs +++ b/common/src/history/position.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/history/visibility.mjs b/common/src/history/visibility.mjs index e911c1b..9254d67 100644 --- a/common/src/history/visibility.mjs +++ b/common/src/history/visibility.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/index.mjs b/common/src/index.mjs index 9b5684c..57efb01 100644 --- a/common/src/index.mjs +++ b/common/src/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs index f782fa3..45854e8 100644 --- a/common/src/lib/expr-eval/expression.mjs +++ b/common/src/lib/expr-eval/expression.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/expr-eval/instruction.mjs b/common/src/lib/expr-eval/instruction.mjs index df0e2d7..9157fea 100644 --- a/common/src/lib/expr-eval/instruction.mjs +++ b/common/src/lib/expr-eval/instruction.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs index e27d512..98f4539 100644 --- a/common/src/lib/expr-eval/parser.mjs +++ b/common/src/lib/expr-eval/parser.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/expr-eval/parserstate.mjs b/common/src/lib/expr-eval/parserstate.mjs index 801c424..d4b3a3b 100644 --- a/common/src/lib/expr-eval/parserstate.mjs +++ b/common/src/lib/expr-eval/parserstate.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs index a15c741..65f05c7 100644 --- a/common/src/lib/expr-eval/polyfill.mjs +++ b/common/src/lib/expr-eval/polyfill.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/expr-eval/tokens.mjs b/common/src/lib/expr-eval/tokens.mjs index bfaad39..254d30a 100644 --- a/common/src/lib/expr-eval/tokens.mjs +++ b/common/src/lib/expr-eval/tokens.mjs @@ -7,7 +7,7 @@ * * Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) * - * Copyright (c) 2015 Matthew Crumley, 2021-2024 Ad5001 + * Copyright (c) 2015 Matthew Crumley, 2021-2025 Ad5001 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs index f8b910b..75d149c 100644 --- a/common/src/lib/polyfills/js.mjs +++ b/common/src/lib/polyfills/js.mjs @@ -1,6 +1,6 @@ /*! * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -119,7 +119,7 @@ const polyfills = { [Array.prototype, "toSpliced", notPolyfilled("Array.prototype.toSpliced")], [Array.prototype, "with", notPolyfilled("Array.prototype.with")] ], - 2024: [ + 2025: [ [Object, "groupBy", notPolyfilled("Object.groupBy")], [Map, "groupBy", notPolyfilled("Map.groupBy")] ] diff --git a/common/src/lib/polyfills/qt.mjs b/common/src/lib/polyfills/qt.mjs index 6559423..0e9a9b5 100644 --- a/common/src/lib/polyfills/qt.mjs +++ b/common/src/lib/polyfills/qt.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/math/domain.mjs b/common/src/math/domain.mjs index 19586ee..b81e527 100644 --- a/common/src/math/domain.mjs +++ b/common/src/math/domain.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/math/expression.mjs b/common/src/math/expression.mjs index 7c7170b..2502110 100644 --- a/common/src/math/expression.mjs +++ b/common/src/math/expression.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/math/index.mjs b/common/src/math/index.mjs index 27be49e..c517958 100644 --- a/common/src/math/index.mjs +++ b/common/src/math/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/math/sequence.mjs b/common/src/math/sequence.mjs index b295708..6049e53 100644 --- a/common/src/math/sequence.mjs +++ b/common/src/math/sequence.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/canvas.mjs b/common/src/module/canvas.mjs index 22166d5..1137ae5 100644 --- a/common/src/module/canvas.mjs +++ b/common/src/module/canvas.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/common.mjs b/common/src/module/common.mjs index 4cd7993..f5fa8aa 100644 --- a/common/src/module/common.mjs +++ b/common/src/module/common.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/expreval.mjs b/common/src/module/expreval.mjs index 8440282..dd89f4d 100644 --- a/common/src/module/expreval.mjs +++ b/common/src/module/expreval.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 4b07095..45a37f0 100644 --- a/common/src/module/history.mjs +++ b/common/src/module/history.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/index.mjs b/common/src/module/index.mjs index 2530a00..6fdff97 100644 --- a/common/src/module/index.mjs +++ b/common/src/module/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs index a96621c..6947acd 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -3,7 +3,7 @@ * * @author Ad5001 * @license GPL-3.0-or-later - * @copyright (C) 2021-2024 Ad5001 + * @copyright (C) 2021-2025 Ad5001 * @preserve * * This program is free software: you can redistribute it and/or modify diff --git a/common/src/module/io.mjs b/common/src/module/io.mjs index 1ac6e58..4887954 100644 --- a/common/src/module/io.mjs +++ b/common/src/module/io.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/latex.mjs b/common/src/module/latex.mjs index 3b48ebc..27fbdd4 100644 --- a/common/src/module/latex.mjs +++ b/common/src/module/latex.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/objects.mjs b/common/src/module/objects.mjs index 979dba4..e98a15f 100644 --- a/common/src/module/objects.mjs +++ b/common/src/module/objects.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/preferences.mjs b/common/src/module/preferences.mjs index dea8677..5d20f92 100644 --- a/common/src/module/preferences.mjs +++ b/common/src/module/preferences.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs index d630e7a..c740383 100644 --- a/common/src/module/settings.mjs +++ b/common/src/module/settings.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/autoload.mjs b/common/src/objs/autoload.mjs index 26a6003..7ecac04 100644 --- a/common/src/objs/autoload.mjs +++ b/common/src/objs/autoload.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/bodemagnitude.mjs b/common/src/objs/bodemagnitude.mjs index 82d9728..4dbcd28 100644 --- a/common/src/objs/bodemagnitude.mjs +++ b/common/src/objs/bodemagnitude.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/bodemagnitudesum.mjs b/common/src/objs/bodemagnitudesum.mjs index eb81663..701a4b9 100644 --- a/common/src/objs/bodemagnitudesum.mjs +++ b/common/src/objs/bodemagnitudesum.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/bodephase.mjs b/common/src/objs/bodephase.mjs index 800671e..75776b1 100644 --- a/common/src/objs/bodephase.mjs +++ b/common/src/objs/bodephase.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/bodephasesum.mjs b/common/src/objs/bodephasesum.mjs index 90864d7..55b3b6c 100644 --- a/common/src/objs/bodephasesum.mjs +++ b/common/src/objs/bodephasesum.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/common.mjs b/common/src/objs/common.mjs index 380ac5d..602856a 100644 --- a/common/src/objs/common.mjs +++ b/common/src/objs/common.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/distribution.mjs b/common/src/objs/distribution.mjs index 16aa4d4..b63717c 100644 --- a/common/src/objs/distribution.mjs +++ b/common/src/objs/distribution.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/function.mjs b/common/src/objs/function.mjs index 70d0b69..fec90ac 100644 --- a/common/src/objs/function.mjs +++ b/common/src/objs/function.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/point.mjs b/common/src/objs/point.mjs index d179481..841308e 100644 --- a/common/src/objs/point.mjs +++ b/common/src/objs/point.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/sequence.mjs b/common/src/objs/sequence.mjs index 0328041..b424ac0 100644 --- a/common/src/objs/sequence.mjs +++ b/common/src/objs/sequence.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/text.mjs b/common/src/objs/text.mjs index af79824..f4dd993 100644 --- a/common/src/objs/text.mjs +++ b/common/src/objs/text.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/objs/xcursor.mjs b/common/src/objs/xcursor.mjs index 11f6a5a..4ad511c 100644 --- a/common/src/objs/xcursor.mjs +++ b/common/src/objs/xcursor.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/parameters.mjs b/common/src/parameters.mjs index 1078518..0da11a8 100644 --- a/common/src/parameters.mjs +++ b/common/src/parameters.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/parsing/common.mjs b/common/src/parsing/common.mjs index 72a9a4b..998f038 100644 --- a/common/src/parsing/common.mjs +++ b/common/src/parsing/common.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/parsing/index.mjs b/common/src/parsing/index.mjs index 6d0de80..f0fde37 100644 --- a/common/src/parsing/index.mjs +++ b/common/src/parsing/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/parsing/reference.mjs b/common/src/parsing/reference.mjs index 36d4c8c..80365aa 100644 --- a/common/src/parsing/reference.mjs +++ b/common/src/parsing/reference.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/parsing/tokenizer.mjs b/common/src/parsing/tokenizer.mjs index a8552fc..8725bf3 100644 --- a/common/src/parsing/tokenizer.mjs +++ b/common/src/parsing/tokenizer.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/preferences/common.mjs b/common/src/preferences/common.mjs index 812263c..4e3ecc8 100644 --- a/common/src/preferences/common.mjs +++ b/common/src/preferences/common.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/preferences/default.mjs b/common/src/preferences/default.mjs index 1d7e4bd..c6864d1 100644 --- a/common/src/preferences/default.mjs +++ b/common/src/preferences/default.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/preferences/expression.mjs b/common/src/preferences/expression.mjs index 85e1fbe..bda6899 100644 --- a/common/src/preferences/expression.mjs +++ b/common/src/preferences/expression.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/preferences/general.mjs b/common/src/preferences/general.mjs index a00a813..093afaf 100644 --- a/common/src/preferences/general.mjs +++ b/common/src/preferences/general.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/utils/expression.mjs b/common/src/utils/expression.mjs index ef20b27..2caf5ea 100644 --- a/common/src/utils/expression.mjs +++ b/common/src/utils/expression.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/utils/index.mjs b/common/src/utils/index.mjs index 02adfd6..2c11c1b 100644 --- a/common/src/utils/index.mjs +++ b/common/src/utils/index.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/utils/other.mjs b/common/src/utils/other.mjs index bcafd6b..50f84f4 100644 --- a/common/src/utils/other.mjs +++ b/common/src/utils/other.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/utils/prototype.mjs b/common/src/utils/prototype.mjs index cb2cc15..b0fd27f 100644 --- a/common/src/utils/prototype.mjs +++ b/common/src/utils/prototype.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/src/utils/subsup.mjs b/common/src/utils/subsup.mjs index ff6ed50..6eb4280 100644 --- a/common/src/utils/subsup.mjs +++ b/common/src/utils/subsup.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/basics/events.mjs b/common/test/basics/events.mjs index 092f037..7dac6e2 100644 --- a/common/test/basics/events.mjs +++ b/common/test/basics/events.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/basics/interface.mjs b/common/test/basics/interface.mjs index aaf512e..48af62e 100644 --- a/common/test/basics/interface.mjs +++ b/common/test/basics/interface.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/basics/polyfill.mjs b/common/test/basics/polyfill.mjs index 4c44514..1fc9599 100644 --- a/common/test/basics/polyfill.mjs +++ b/common/test/basics/polyfill.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/basics/utils.mjs b/common/test/basics/utils.mjs index 42adead..66ecd92 100644 --- a/common/test/basics/utils.mjs +++ b/common/test/basics/utils.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index 66e9da9..39a25d7 100644 --- a/common/test/hooks.mjs +++ b/common/test/hooks.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs index 6c2b93e..b9161c8 100644 --- a/common/test/math/domain.mjs +++ b/common/test/math/domain.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/math/expression.mjs b/common/test/math/expression.mjs index 0c15f9c..588480c 100644 --- a/common/test/math/expression.mjs +++ b/common/test/math/expression.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/canvas.mjs b/common/test/mock/canvas.mjs index e770e10..82bcbff 100644 --- a/common/test/mock/canvas.mjs +++ b/common/test/mock/canvas.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/dialog.mjs b/common/test/mock/dialog.mjs index 3ff118f..ec8628d 100644 --- a/common/test/mock/dialog.mjs +++ b/common/test/mock/dialog.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/fs.mjs b/common/test/mock/fs.mjs index bccb71f..7cb00dd 100644 --- a/common/test/mock/fs.mjs +++ b/common/test/mock/fs.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs index b912b44..9186947 100644 --- a/common/test/mock/helper.mjs +++ b/common/test/mock/helper.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/latex.mjs b/common/test/mock/latex.mjs index 2d6fb5f..54d427d 100644 --- a/common/test/mock/latex.mjs +++ b/common/test/mock/latex.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/qt.mjs b/common/test/mock/qt.mjs index 58ceae0..46f5b3d 100644 --- a/common/test/mock/qt.mjs +++ b/common/test/mock/qt.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/mock/root.mjs b/common/test/mock/root.mjs index 51807e2..0539342 100644 --- a/common/test/mock/root.mjs +++ b/common/test/mock/root.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/module/base.mjs b/common/test/module/base.mjs index be035c0..0cc73ea 100644 --- a/common/test/module/base.mjs +++ b/common/test/module/base.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/module/expreval.mjs b/common/test/module/expreval.mjs index 2d075f6..c04290e 100644 --- a/common/test/module/expreval.mjs +++ b/common/test/module/expreval.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/module/latex.mjs b/common/test/module/latex.mjs index e038e63..6581850 100644 --- a/common/test/module/latex.mjs +++ b/common/test/module/latex.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/module/objects.mjs b/common/test/module/objects.mjs index d598097..73b9e25 100644 --- a/common/test/module/objects.mjs +++ b/common/test/module/objects.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/common/test/module/settings.mjs b/common/test/module/settings.mjs index 7ad439a..b266bb2 100644 --- a/common/test/module/settings.mjs +++ b/common/test/module/settings.mjs @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/run.py b/run.py index 783e23b..058ca94 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/__init__.py b/runtime-pyside6/LogarithmPlotter/__init__.py index 0c5cbbb..08914d3 100644 --- a/runtime-pyside6/LogarithmPlotter/__init__.py +++ b/runtime-pyside6/LogarithmPlotter/__init__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index 8940e56..562231a 100644 --- a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py +++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 79fa6b0..d271cb6 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml index 645916c..09b6feb 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml index bffdb9b..fac19e3 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index e1583f6..30bf6ca 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 064a0be..ddbd2bd 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index e688202..6e33b71 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index ced0cdd..d762da2 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index e3894cd..21559a9 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 3b59e0a..d37a015 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 5812252..0f7003f 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml index 6aec616..10f3665 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml index 60eb90e..6ba8bb6 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml index 41ce60a..78329a7 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml index d74c101..e82f39c 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -102,7 +102,7 @@ BaseDialog { wrapMode: Text.WordWrap textFormat: Text.RichText font.pixelSize: 13 - text: "Copyright © 2021-2024 Ad5001 <mail@ad5001.eu>
                        + text: "Copyright © 2021-2025 Ad5001 <mail@ad5001.eu>

                        This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

                        diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml index 0220956..98e37d4 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml index 10fe87e..a9c73a6 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 93d76db..1797b9d 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml index 4b7ff8a..00dbdae 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 5a1ff21..a083d64 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index 9bf8f06..8111f85 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 70d77a9..9ed40c8 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index c2001a2..85e4a64 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index 304b704..897af70 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index d29ab7c..a4dc93b 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index af32b43..35bba0a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index aeffe53..6ba76aa 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index 221b3a3..daad433 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 8d1ca41..bc105aa 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 3f17ea3..58db0e9 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index a7b2ffb..2cce4dc 100644 --- a/runtime-pyside6/LogarithmPlotter/util/config.py +++ b/runtime-pyside6/LogarithmPlotter/util/config.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py index ef02d62..c977253 100644 --- a/runtime-pyside6/LogarithmPlotter/util/debug.py +++ b/runtime-pyside6/LogarithmPlotter/util/debug.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index cc6bff4..8adb81e 100644 --- a/runtime-pyside6/LogarithmPlotter/util/helper.py +++ b/runtime-pyside6/LogarithmPlotter/util/helper.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py index 944c2b0..380ab97 100644 --- a/runtime-pyside6/LogarithmPlotter/util/js.py +++ b/runtime-pyside6/LogarithmPlotter/util/js.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 570e083..b446295 100644 --- a/runtime-pyside6/LogarithmPlotter/util/latex.py +++ b/runtime-pyside6/LogarithmPlotter/util/latex.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/native.py b/runtime-pyside6/LogarithmPlotter/util/native.py index aefc310..3adf153 100644 --- a/runtime-pyside6/LogarithmPlotter/util/native.py +++ b/runtime-pyside6/LogarithmPlotter/util/native.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py index f4f21c2..8e17651 100644 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ b/runtime-pyside6/LogarithmPlotter/util/promise.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/LogarithmPlotter/util/update.py b/runtime-pyside6/LogarithmPlotter/util/update.py index 1d2ecec..e18b93e 100644 --- a/runtime-pyside6/LogarithmPlotter/util/update.py +++ b/runtime-pyside6/LogarithmPlotter/util/update.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/setup.py b/runtime-pyside6/setup.py index 524ad29..4100042 100644 --- a/runtime-pyside6/setup.py +++ b/runtime-pyside6/setup.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/globals.py b/runtime-pyside6/tests/globals.py index def1415..67a1356 100644 --- a/runtime-pyside6/tests/globals.py +++ b/runtime-pyside6/tests/globals.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/__init__.py b/runtime-pyside6/tests/plugins/natural/__init__.py index 4cfe179..180969f 100644 --- a/runtime-pyside6/tests/plugins/natural/__init__.py +++ b/runtime-pyside6/tests/plugins/natural/__init__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py index e1e43c4..b81d0e5 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/base.py b/runtime-pyside6/tests/plugins/natural/interfaces/base.py index 0786285..c96c146 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/base.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/base.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py index 25d45cb..85720da 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/int.py b/runtime-pyside6/tests/plugins/natural/interfaces/int.py index 75bd8b8..b282e4d 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/int.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/int.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py index 524fd71..ce0b8ff 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/spy.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/utils.py b/runtime-pyside6/tests/plugins/natural/interfaces/utils.py index 50e3777..5200975 100644 --- a/runtime-pyside6/tests/plugins/natural/interfaces/utils.py +++ b/runtime-pyside6/tests/plugins/natural/interfaces/utils.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/spy.py b/runtime-pyside6/tests/plugins/natural/spy.py index 2f9211a..4026b20 100644 --- a/runtime-pyside6/tests/plugins/natural/spy.py +++ b/runtime-pyside6/tests/plugins/natural/spy.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/natural/that.py b/runtime-pyside6/tests/plugins/natural/that.py index 05a3e31..60ad4b6 100644 --- a/runtime-pyside6/tests/plugins/natural/that.py +++ b/runtime-pyside6/tests/plugins/natural/that.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/plugins/tests/test_natural.py b/runtime-pyside6/tests/plugins/tests/test_natural.py index f381639..31f85c0 100644 --- a/runtime-pyside6/tests/plugins/tests/test_natural.py +++ b/runtime-pyside6/tests/plugins/tests/test_natural.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_config.py b/runtime-pyside6/tests/test_config.py index cef3673..a95a9d9 100644 --- a/runtime-pyside6/tests/test_config.py +++ b/runtime-pyside6/tests/test_config.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_debug.py b/runtime-pyside6/tests/test_debug.py index 4799024..467e5b8 100644 --- a/runtime-pyside6/tests/test_debug.py +++ b/runtime-pyside6/tests/test_debug.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_helper.py b/runtime-pyside6/tests/test_helper.py index 6bc1f0d..f2f6d70 100644 --- a/runtime-pyside6/tests/test_helper.py +++ b/runtime-pyside6/tests/test_helper.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index ee87fa5..4ffbc6c 100644 --- a/runtime-pyside6/tests/test_latex.py +++ b/runtime-pyside6/tests/test_latex.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_main.py b/runtime-pyside6/tests/test_main.py index 6b161ad..1595236 100644 --- a/runtime-pyside6/tests/test_main.py +++ b/runtime-pyside6/tests/test_main.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_native.py b/runtime-pyside6/tests/test_native.py index 3ca4834..d60b907 100644 --- a/runtime-pyside6/tests/test_native.py +++ b/runtime-pyside6/tests/test_native.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_promise.py b/runtime-pyside6/tests/test_promise.py index 30f0a1e..ef71a55 100644 --- a/runtime-pyside6/tests/test_promise.py +++ b/runtime-pyside6/tests/test_promise.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_pyjs.py b/runtime-pyside6/tests/test_pyjs.py index 95c3cf6..9177b4e 100644 --- a/runtime-pyside6/tests/test_pyjs.py +++ b/runtime-pyside6/tests/test_pyjs.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/runtime-pyside6/tests/test_update.py b/runtime-pyside6/tests/test_update.py index ff71e61..16b562e 100644 --- a/runtime-pyside6/tests/test_update.py +++ b/runtime-pyside6/tests/test_update.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 + * Copyright (C) 2021-2025 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/scripts/build.sh b/scripts/build.sh index b63d7f6..257b2c4 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # # LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. -# Copyright (C) 2021-2024 Ad5001 +# Copyright (C) 2021-2025 Ad5001 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From a2f8a924e0a9812e054e61051e0a94649af80ce1 Mon Sep 17 00:00:00 2001 From: ovari Date: Thu, 13 Mar 2025 05:57:01 +0100 Subject: [PATCH 249/249] Translated using Weblate (Hungarian) Currently translated at 100.0% (264 of 264 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- assets/i18n/lp_hu.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index bff8a44..7e2856d 100644 --- a/assets/i18n/lp_hu.ts +++ b/assets/i18n/lp_hu.ts @@ -456,12 +456,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Loading... - + Betöltés… Finished rendering of %1 - + %1 renderelése befejeződött
                        @@ -469,7 +469,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. untitled - + névtelen @@ -881,7 +881,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Tamil - + Tamil @@ -1334,7 +1334,7 @@ Kiértékelt kifejezés: %3 Enable threaded LaTeX renderer (experimental) - + A szálas LaTeX renderer engedélyezése (kísérleti) @@ -1479,24 +1479,27 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}. Please update LogarithmPlotter to open this file. - + Ezt a fájlt a LogarithmPlotter egy újabb verziója hozta létre, és nem tölthető vissza a LogarithmPlotter v{} alkalmazásban. +Kérjük, frissítse a LogarithmPlottert a fájl megnyitásához. Could not open file "{}": {} - + Nem sikerült megnyitni a(z) „{}”-fájlt: +{} Could not open file: "{}" File does not exist. - + Nem sikerült megnyitni a(z) „{}”-fájlt: +A fájl nem létezik. Built with PySide6 (Qt) v{} and python v{} - + PySide6 (Qt) v{} és python v{} segítségével épült