diff --git a/.gitignore b/.gitignore index e2308a5..3961125 100644 --- a/.gitignore +++ b/.gitignore @@ -37,10 +37,8 @@ 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/CHANGELOG.md b/CHANGELOG.md index 4a756a3..c4b7c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,55 +1,5 @@ # Changelog -## v0.6.0 (?? Apr 2025) - -**New** - - * Revamped the update greet screan. - * Settings now have their dedicated configuration screen. - * Default settings for graphs can now be configured. - * LaTeX rendering now support both concurent and (experimental) threaded rendering, making graph render up to 20x times faster. - * Added a loading screen for the threaded LaTeX renderer. - -**Changes** - - * Settings menu removed, use `Edit > Preferences` to access LogarithmPlotter's settings. - * Logarithmic graduation limit upped from 10^20 to 10^309 (and conversively). - * Error messages should now all be properly translated. - * LaTeX renders are now persistantly cached. Closing and reopening files will be instantaneous. - * Special character choosing popup is now keyboard navigable and no longer covers the input. - * Domains are now rendered with LaTeX. - -**Fixed bugs** - - * Fixed sequence rendering method. - * Picker's 'snap to grid' option caused issues when picking. - * Outzooming with mousescroll no longer prevents you from being able to zoom back in. - * Several bugs related to X Cursors, namely certain function causing LogarithmPlotter to crash, and rounding errors. - * When using derivatives, the value passed as parameter is now properly rendered instead of a placeholder `x`. - * LaTeX renderer now uses native square root function look instead of `sqrt` function. - * LaTeX renderer now properly renders pi as π. - * Improved the stability of complex function drawing. - * (Linux) Certain links in 'About' were broken. - -**Translations** - - * New translation in Tamil (thanks @TamilNeram!) - * Completed Spanish translation (thanks @gallegonovato and @IngrownMink4!) - * We're still looking for Norwegian speakers who could help complete the [translation](https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/nb_NO/). - * If your language is not yet supported by LogarithmPlotter, feel free to add it on [Weblate](https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/)! - -**Internal changes** - - * The near entirety of the logic was refractored from QML JS to modern ECMAScript (added Babel and rollup as dependancies). - * PySide6 and ES codebases were completely separated (in preparation of a web-based renderer). - * Added Python unit tests (complete). - * Added ES unit tests (WIP). - * Internal tooling for translations was overalled to allow lupdate to parse newer ES syntax. - * Flushed a great many deals of hacks and bugs this way. - * Type safety is now properly enforced at every step of IO. - * Several new test files were added in the `ci` folder. - * Updated to PySide6 v6.9.0 - ## v0.5.0 (11 Jan 2024) **New** diff --git a/README.md b/README.md index f06d009..4a44ced 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![icon](https://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg) LogarithmPlotter +# ![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/) @@ -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 -`pyside6-lrelease` to be installed and in path), and the JavaScript modules. +`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`. @@ -68,19 +68,13 @@ To run LogarithmPlotter's tests, follow these steps: - Python - Install python3 and [poetry](https://python-poetry.org/) - - 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 `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-2025 Ad5001 + 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 @@ -95,8 +89,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 . -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: +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) @@ -109,5 +103,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 (common/src/lib/expr-eval/) except integration.mjs are licensed +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). diff --git a/assets/i18n/lp_de.ts b/assets/i18n/lp_de.ts index 9ed0e8c..0dbfa98 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 - &Versionshinweise + &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 @@ -188,38 +188,15 @@ Beim Starten auf Updates prüfen - - Browser - - - Filter... - Filtern… - - - - Redo > - Wiederherstellen > - - - - > Now - > Aktueller Stand - - - - < Undo - < Rückgängig - - Changelog - + Fetching changelog... Changelog abrufen… - + Close Schließen @@ -227,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -241,41 +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 + Etikett - + null leer - + name Name - + name + value Name + Wert @@ -314,32 +292,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktionen - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -347,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Logarithmusgrafik exportieren - + Import Logarithm Plot file Logarithmusgrafik importieren @@ -360,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 @@ -404,22 +382,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog - Versionshinweise + Changelog - + Preferences Einstellung - + Close Schließen @@ -427,62 +405,48 @@ 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 ListSetting - + + Add Entry + Neuer Eintrag - - Loading - - - Loading... - Laden… - - - - Finished rendering of %1 - Beendetes Rendering von %1 - - LogarithmPlotter - - untitled - unbetitelt - - - + Objects Objekte - + Settings Einstellungen - + History Verlauf @@ -511,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 @@ -529,7 +493,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectCreationGrid - + + Create new: + Neu erstellen: @@ -537,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 @@ -570,108 +534,77 @@ 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 - - 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: + 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) Preferences - + Close Schließen @@ -679,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… @@ -794,102 +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 - - Tamil - Tamil - - - + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -897,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 @@ -922,8 +849,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodemagnitudesum - - + + Bode Magnitudes Sum Bode-Magnituden Summe @@ -931,12 +858,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodephase - + Bode Phase Bode-Phase - + Bode Phases Bode-Phasen @@ -944,8 +871,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" bodephasesum - - + + Bode Phases Sum Bode-Phasen Summe @@ -953,13 +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: {}. @@ -967,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. @@ -976,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. @@ -1004,11 +930,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - - - - - + + + + + %1: %1: @@ -1016,8 +942,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - - + + New %1 %2 created. Neu %1 %2 erstellt. @@ -1025,8 +951,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete - - + + %1 %2 deleted. %1 %2 gelöscht. @@ -1034,12 +960,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" distribution - + Repartition Verteilungsfunktion - + Repartition functions Verteilungsfunktionen @@ -1047,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. @@ -1060,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. @@ -1108,12 +1034,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 @@ -1126,96 +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. + 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. - + Error while parsing expression for property %1: %2 @@ -1226,7 +1160,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1240,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 @@ -1257,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 @@ -1285,12 +1219,12 @@ Ausdruck analysiert: %3 function - + Function Funktion - + Functions Funktionen @@ -1317,25 +1251,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - LaTeX-Renderer mit Threads aktivieren (experimentell) - historylib @@ -1379,32 +1308,34 @@ 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. - - - Could not load file: - Datei konnte nicht geladen werden: + 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! @@ -1422,7 +1353,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/. @@ -1431,12 +1362,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 {}: @@ -1449,7 +1380,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/{}) @@ -1462,7 +1393,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: {} @@ -1473,40 +1404,11 @@ 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. - 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{} - - name - - + + %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -1514,114 +1416,114 @@ Die Datei existiert nicht. 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 @@ -1640,12 +1542,12 @@ Die Datei existiert nicht. point - + Point Punkt - + Points Punkte @@ -1653,12 +1555,12 @@ Die Datei existiert nicht. 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. @@ -1666,158 +1568,158 @@ Die Datei existiert nicht. 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 @@ -1825,11 +1727,6 @@ Die Datei existiert nicht. color Farbe - - - labelContent - Etikett - repartition @@ -1845,12 +1742,12 @@ Die Datei existiert nicht. sequence - + Sequence Folge - + Sequences Folgen @@ -1858,17 +1755,17 @@ Die Datei existiert nicht. settingCategory - + default Standardeinstellungen - + general Allgemeine - + editor Ausdruckseditor @@ -1890,12 +1787,12 @@ Die Datei existiert nicht. text - + Text Text - + Texts Texte @@ -1903,22 +1800,22 @@ Die Datei existiert nicht. 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:{}. @@ -1926,22 +1823,22 @@ Die Datei existiert nicht. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<von: Zahl>, <bis: Zahl>, <f: Funktionsähnliches Objekt>) + integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 %2 @@ -1950,17 +1847,17 @@ Die Datei existiert nicht. %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>) @@ -1968,14 +1865,14 @@ Die Datei existiert nicht. visibility - - + + %1 %2 shown. %1 %2 angezeigt. - - + + %1 %2 hidden. %1 %2 ausgeblendet. @@ -1983,12 +1880,12 @@ Die Datei existiert nicht. xcursor - + X Cursor X Zeiger - + X Cursors X Zeiger diff --git a/assets/i18n/lp_en.ts b/assets/i18n/lp_en.ts index 68590af..92baeb1 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 @@ -188,38 +188,15 @@ Check for updates on startup - - Browser - - - Filter... - Filter… - - - - Redo > - Redo > - - - - > Now - > Now - - - - < Undo - < Undo - - Changelog - + Fetching changelog... Fetching changelog… - + Close Close @@ -227,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -241,41 +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 + Label content - + null null - + name name - + name + value name + value @@ -314,32 +292,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -347,12 +325,12 @@ FileDialog - + Export Logarithm Plot file Export Logarithm Plot file - + Import Logarithm Plot file Import Logarithm Plot file @@ -360,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 @@ -404,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 @@ -427,62 +405,48 @@ 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 ListSetting - + + Add Entry + Add Entry - - Loading - - - Loading... - Loading… - - - - Finished rendering of %1 - Finished rendering of %1 - - LogarithmPlotter - - untitled - untitled - - - + Objects Objects - + Settings Settings - + History History @@ -511,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 @@ -529,7 +493,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: + Create new: @@ -537,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 @@ -570,108 +534,77 @@ 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 - - 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: + 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) Preferences - + Close Close @@ -679,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… @@ -794,102 +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 - - Tamil - Tamil - - - + Translations included Translations included - + Improve Improve @@ -897,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 @@ -922,8 +849,8 @@ These settings can be changed at any time from the "Settings" menu. bodemagnitudesum - - + + Bode Magnitudes Sum Bode Magnitudes Sum @@ -931,12 +858,12 @@ These settings can be changed at any time from the "Settings" menu. bodephase - + Bode Phase Bode Phase - + Bode Phases Bode Phases @@ -944,8 +871,8 @@ These settings can be changed at any time from the "Settings" menu. bodephasesum - - + + Bode Phases Sum Bode Phases Sum @@ -953,13 +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: {}. @@ -967,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. @@ -976,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. @@ -1004,11 +930,11 @@ These settings can be changed at any time from the "Settings" menu. control - - - - - + + + + + %1: %1: @@ -1016,8 +942,8 @@ These settings can be changed at any time from the "Settings" menu. create - - + + New %1 %2 created. New %1 %2 created. @@ -1025,8 +951,8 @@ These settings can be changed at any time from the "Settings" menu. delete - - + + %1 %2 deleted. %1 %2 deleted. @@ -1034,12 +960,12 @@ These settings can be changed at any time from the "Settings" menu. distribution - + Repartition Distribution - + Repartition functions Distribution functions @@ -1047,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. @@ -1060,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. @@ -1108,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 @@ -1126,96 +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. + 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. - + Error while parsing expression for property %1: %2 @@ -1226,7 +1160,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1240,13 +1174,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1257,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 @@ -1285,12 +1219,12 @@ Evaluated expression: %3 function - + Function Function - + Functions Functions @@ -1317,25 +1251,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - Enable threaded LaTeX renderer (experimental) - historylib @@ -1379,32 +1308,34 @@ 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. - - - Could not load file: - Could not load file: + 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! @@ -1422,7 +1353,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/. @@ -1431,12 +1362,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 {}: @@ -1449,7 +1380,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/{}) @@ -1462,7 +1393,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: {} @@ -1473,40 +1404,11 @@ 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. - 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{} - - name - - + + %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -1514,114 +1416,114 @@ File does not exist. 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 @@ -1640,12 +1542,12 @@ File does not exist. point - + Point Point - + Points Points @@ -1653,12 +1555,12 @@ File does not exist. 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. @@ -1666,158 +1568,158 @@ File does not exist. 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 @@ -1825,11 +1727,6 @@ File does not exist. color Color - - - labelContent - Label content - repartition @@ -1845,12 +1742,12 @@ File does not exist. sequence - + Sequence Sequence - + Sequences Sequences @@ -1858,17 +1755,17 @@ File does not exist. settingCategory - + general General - + editor Expression Editor - + default Default settings @@ -1890,12 +1787,12 @@ File does not exist. text - + Text Text - + Texts Texts @@ -1903,22 +1800,22 @@ File does not exist. 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: {}. @@ -1926,22 +1823,22 @@ File does not exist. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: Function-like object>) - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 %2 @@ -1950,17 +1847,17 @@ File does not exist. %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: Function-like object>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1968,14 +1865,14 @@ File does not exist. visibility - - + + %1 %2 shown. %1 %2 shown. - - + + %1 %2 hidden. %1 %2 hidden. @@ -1983,12 +1880,12 @@ File does not exist. xcursor - + X Cursor X Cursor - + X Cursors X Cursors diff --git a/assets/i18n/lp_es.ts b/assets/i18n/lp_es.ts index b1e5d0a..96cb5de 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 @@ -188,38 +188,15 @@ Comprobación de las actualizaciones al arrancar - - Browser - - - Filter... - - - - - Redo > - Rehacer > - - - - > Now - > Ahora - - - - < Undo - < Deshacer - - Changelog - + Fetching changelog... Obteniendo el registro de cambios… - + Close Cerrar @@ -227,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Crear nuevo %1 - + Pick on graph Elegir en el gráfico @@ -241,37 +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 @@ -310,32 +292,32 @@ ExpressionEditor - + Object Properties Propiedades de los objetos - + Variables - + Constants Constantes - + Functions Funciones - + Executable Objects Objetos de función - + Objects Objetos @@ -343,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 @@ -356,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenid@ a LogarithmPlotter - + Version %1 @@ -370,22 +352,22 @@ Activar el renderizado de LaTeX - + User manual - + Changelog Registro de cambios - + Preferences Preferencias - + Close Cerrar @@ -423,73 +405,63 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes HistoryBrowser + + Filter... + + + + Redo > - Rehacer > + Rehacer > + > Now - > Ahora + > Ahora + < Undo - < Deshacer + < Deshacer ListSetting - + + Add Entry + 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 @@ -521,7 +493,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes ObjectCreationGrid - + + Create new: + Crear nuevo: @@ -529,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 @@ -562,99 +534,68 @@ 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 - PickLocation + 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) - - - 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 @@ -663,7 +604,7 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes Preferences - + Close Cerrar @@ -671,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… @@ -786,102 +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 - - Tamil - - - - + Translations included Traducciones incluidas - + Improve Mejorar @@ -889,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 @@ -914,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 @@ -923,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 @@ -936,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 @@ -945,13 +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: {}. @@ -959,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. @@ -968,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. @@ -996,11 +930,11 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes control - - - - - + + + + + %1: @@ -1008,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. @@ -1017,8 +951,8 @@ Estos ajustes se pueden cambiar en cualquier momento desde el menú “Ajustes delete - - + + %1 %2 deleted. %1 %2 borrados. @@ -1026,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 @@ -1039,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. @@ -1052,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 . @@ -1100,101 +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. + 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. - + Error while parsing expression for property %1: %2 @@ -1205,7 +1147,7 @@ Evaluated expression: %3 Expresión evaluada: %3 - + Error while attempting to draw %1 %2: %3 @@ -1224,7 +1166,7 @@ Deshaciendo el último cambio. Variable de asignación esperada. - + EOF Fin de la expresión @@ -1232,13 +1174,13 @@ Deshaciendo el último cambio. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Error de procesamiento - + Error while parsing expression for property %1: %2 @@ -1249,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 @@ -1277,12 +1219,12 @@ Expresión evaluada: %3 function - + Function Función - + Functions Funciones @@ -1309,25 +1251,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - - historylib @@ -1383,38 +1320,40 @@ 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. - - - Could not load file: - No se pudo cargar el archivo: + 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'. 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/. @@ -1423,12 +1362,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 {}: @@ -1441,7 +1380,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/{}) @@ -1454,7 +1393,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: {} @@ -1465,37 +1404,11 @@ 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 - - + + %1 %2 renamed to %3. %1 %2 ha sido renombrado a %3. @@ -1503,114 +1416,114 @@ File does not exist. 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 @@ -1629,12 +1542,12 @@ File does not exist. point - + Point Punto - + Points Puntos @@ -1642,12 +1555,12 @@ File does not exist. 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. @@ -1655,153 +1568,153 @@ File does not exist. 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 @@ -1810,15 +1723,10 @@ File does not exist. Color - + baseValues Valores de inicialización - - - labelContent - Contenido de la etiqueta - repartition @@ -1834,12 +1742,12 @@ File does not exist. sequence - + Sequences Secuencias - + Sequence Secuencia @@ -1847,17 +1755,17 @@ File does not exist. settingCategory - + general General - + editor Editor de expresiones - + default Ajustes por defecto @@ -1879,12 +1787,12 @@ File does not exist. text - + Texts Textos - + Text Texto @@ -1892,22 +1800,22 @@ File does not exist. 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: {}. @@ -1915,22 +1823,22 @@ File does not exist. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<desde: número>, <hasta: número>, <f: Objeto similar a una función>) + integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) - - + + Usage: %1 Uso: %1 - - - + + + Usage: %1 %2 @@ -1939,32 +1847,32 @@ File does not exist. %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>) + derivada(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - derivative(<f: cadena>, <variable: cadena>, <x: número>) + derivada(<f: string>, <variable: string>, <x: number>) visibility - - + + %1 %2 shown. Se muestra %1 %2. - - + + %1 %2 hidden. Se oculta %1 %2. @@ -1972,12 +1880,12 @@ File does not exist. xcursor - + X Cursor Cursor X - + X Cursors Cursores X diff --git a/assets/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts index d2e6380..eeaa500 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 - &Notes de version + &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 @@ -189,38 +189,15 @@ Vérifier la présence de mise à jour au démarrage - - Browser - - - Filter... - Filtrer… - - - - Redo > - Rétablir > - - - - > Now - > État actuel - - - - < Undo - < Annuler - - Changelog - + Fetching changelog... - Récupération des notes de version… + Récupération de l'historique des modifications… - + Close Fermer @@ -228,13 +205,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -242,41 +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 + Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -316,32 +294,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -349,12 +327,12 @@ FileDialog - + Export Logarithm Plot file Exporter le graphe Logarithmique - + Import Logarithm Plot file Importer un graphe Logarithmique @@ -362,12 +340,12 @@ GreetScreen - + Welcome to LogarithmPlotter - Bienvenu·e sur LogarithmPlotter + Bienvenue sur LogarithmPlotter - + Version %1 Version %1 @@ -398,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 - Notes de version + Historique des modifications - + Preferences Préférences - + Close Fermer @@ -429,62 +407,48 @@ 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 ListSetting - + + Add Entry + Nouvelle entrée - - Loading - - - Loading... - Chargement… - - - - Finished rendering of %1 - Rendu de %1 terminé - - LogarithmPlotter - - untitled - sans titre - - - + Objects Objets - + Settings Paramètres - + History Historique @@ -513,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 @@ -531,7 +495,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P ObjectCreationGrid - + + Create new: + Créer : @@ -539,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 @@ -572,108 +536,77 @@ 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 - - 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 : + 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é) Preferences - + Close Fermer @@ -681,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… @@ -796,102 +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 - - Tamil - Tamoul - - - + Translations included Traductions incluses - + Improve Améliorer @@ -899,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 @@ -924,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 @@ -933,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 @@ -946,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 @@ -955,22 +882,21 @@ 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 {}. + Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - - + Could not fetch update: {}. - Impossible de récupérer les notes de version : {}. + Impossible de récupérer l'historique des modifications : {}. color - - + + %1 %2's color changed from %3 to %4. La couleur du %1 %2 a été changée du %3 au %4. @@ -978,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. @@ -1007,11 +933,11 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P control - - - - - + + + + + %1: %1 : @@ -1019,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éé. @@ -1028,8 +954,8 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P delete - - + + %1 %2 deleted. %1 %2 supprimé(e). @@ -1037,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 @@ -1050,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. @@ -1063,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. @@ -1111,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 @@ -1129,96 +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. + 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. - + Error while parsing expression for property %1: %2 @@ -1229,7 +1163,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1243,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 @@ -1260,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 @@ -1288,12 +1222,12 @@ Formule analysée : %3 function - + Function Fonction - + Functions Fonctions @@ -1320,25 +1254,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - Activer le moteur de rendu LaTeX asynchrone (expérimental) - historylib @@ -1394,38 +1323,40 @@ 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. - - - Could not load file: - Impossible de charger le fichier : + 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é. 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/. @@ -1434,12 +1365,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 {}: @@ -1452,7 +1383,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/{}) @@ -1465,7 +1396,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: {} @@ -1476,40 +1407,11 @@ 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. - 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{} - - name - - + + %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -1517,114 +1419,114 @@ Le fichier n'existe pas. 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é @@ -1643,12 +1545,12 @@ Le fichier n'existe pas. point - + Point Point - + Points Points @@ -1656,12 +1558,12 @@ Le fichier n'existe pas. 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. @@ -1669,158 +1571,158 @@ Le fichier n'existe pas. 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 @@ -1828,11 +1730,6 @@ Le fichier n'existe pas. color Couleur - - - labelContent - Étiquette - repartition @@ -1848,12 +1745,12 @@ Le fichier n'existe pas. sequence - + Sequence Suite - + Sequences Suites @@ -1861,17 +1758,17 @@ Le fichier n'existe pas. settingCategory - + general Général - + editor Éditeur de formule - + default Paramètres par défaut @@ -1893,12 +1790,12 @@ Le fichier n'existe pas. text - + Text Texte - + Texts Textes @@ -1906,22 +1803,22 @@ Le fichier n'existe pas. 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. {}. @@ -1929,22 +1826,22 @@ Le fichier n'existe pas. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet fonction>) - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 %2 @@ -1953,17 +1850,17 @@ Le fichier n'existe pas. %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>) @@ -1971,14 +1868,14 @@ Le fichier n'existe pas. visibility - - + + %1 %2 shown. %1 %2 affiché(e). - - + + %1 %2 hidden. %1 %2 cachée(e). @@ -1986,12 +1883,12 @@ Le fichier n'existe pas. xcursor - + X Cursor Curseur X - + X Cursors Curseurs X diff --git a/assets/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts index 7e2856d..8618a0b 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… + &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 - &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 @@ -188,38 +188,15 @@ Frissítések keresése indításkor - - Browser - - - Filter... - Szűrő… - - - - Redo > - Ismétlés > - - - - > Now - > Most - - - - < Undo - < Visszavonás - - Changelog - + Fetching changelog... Változásnapló lekérése… - + Close Kész @@ -227,13 +204,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -241,41 +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 + Címketartalom - + null üres - + name név - + name + value név + érték @@ -314,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 @@ -347,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 @@ -360,12 +338,12 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió @@ -404,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 @@ -427,62 +405,48 @@ 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 ListSetting - + + Add Entry + Bejegyzés hozzáadása - - Loading - - - Loading... - Betöltés… - - - - Finished rendering of %1 - %1 renderelése befejeződött - - LogarithmPlotter - - untitled - névtelen - - - + Objects Tárgyak - + Settings Beállítások - + History Előzmények @@ -511,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 @@ -529,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: @@ -537,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 @@ -570,221 +534,190 @@ 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 - - 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: + 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) Preferences - + Close - Bezárás + 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… + Ábra mentése - + Save plot as - Ábra mentése másként… + Ábra mentése másként - + Load plot - Ábra megnyitása… + Ábra betöltése Close @@ -794,102 +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 + - - Tamil - Tamil - - - + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -897,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ő @@ -922,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 @@ -931,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 @@ -944,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 @@ -953,13 +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: {}. @@ -967,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. @@ -976,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. @@ -1004,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: @@ -1016,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. @@ -1025,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. @@ -1034,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 @@ -1047,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. @@ -1060,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. @@ -1108,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 @@ -1126,96 +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. + 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. - + Error while parsing expression for property %1: %2 @@ -1226,7 +1160,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1240,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 @@ -1257,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 @@ -1285,12 +1219,12 @@ Kiértékelt kifejezés: %3 function - + Function Függvény - + Functions Függvények @@ -1317,25 +1251,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - A szálas LaTeX renderer engedélyezése (kísérleti) - historylib @@ -1375,32 +1304,34 @@ 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. - - - Could not load file: - Nem sikerült betölteni a fájlt: + 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! @@ -1422,7 +1353,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/. @@ -1431,12 +1362,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 {}: @@ -1449,20 +1380,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 some required packages: - {} (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. + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1473,40 +1400,11 @@ 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. - 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 - - name - - + + %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -1514,114 +1412,114 @@ A fájl nem létezik. 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 @@ -1640,12 +1538,12 @@ A fájl nem létezik. point - + Point Pont - + Points Pontok @@ -1653,12 +1551,12 @@ A fájl nem létezik. 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. @@ -1666,170 +1564,165 @@ A fájl nem létezik. 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 + 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 + Kezdeményezési értékek color Szín - - - labelContent - Címketartalom - repartition @@ -1845,12 +1738,12 @@ A fájl nem létezik. sequence - + Sequence Sorozat - + Sequences Sorozatok @@ -1858,17 +1751,17 @@ A fájl nem létezik. settingCategory - + general - Általános + - + editor Kifejezésszerkesztő - + default Alapértelmezett ábra @@ -1890,12 +1783,12 @@ A fájl nem létezik. text - + Text Szöveg - + Texts Szövegek @@ -1903,22 +1796,22 @@ A fájl nem létezik. 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: {}. @@ -1926,22 +1819,22 @@ A fájl nem létezik. usage - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - integral(<alsó korlát: szám>, <felső korlát: szám>, <f: függvényszerű objektum>) + 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 @@ -1950,17 +1843,17 @@ A fájl nem létezik. %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ü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>) @@ -1968,14 +1861,14 @@ A fájl nem létezik. visibility - - + + %1 %2 shown. %1 %2 megjelenítve. - - + + %1 %2 hidden. %1 %2 rejtve. @@ -1983,12 +1876,12 @@ A fájl nem létezik. 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 97799c6..5e94d77 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 @@ -164,38 +164,15 @@ Se etter nye versjoner ved programstart - - Browser - - - Filter... - - - - - Redo > - Angre > - - - - > Now - > Nå - - - - < Undo - < Angre - - Changelog - + Fetching changelog... Henter endringslogg… - + Close Lukk @@ -203,13 +180,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -217,41 +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 + Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -290,32 +268,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -323,12 +301,12 @@ FileDialog - + Export Logarithm Plot file Eksporter logaritmeplott-fil - + Import Logarithm Plot file Importer logaritmeplott-fil @@ -336,12 +314,12 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 @@ -360,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 @@ -383,58 +361,48 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. HistoryBrowser + + Filter... + + + + Redo > - Angre > + Angre > + > Now - > Nå + > Nå + < Undo - < Angre + < Angre ListSetting - + + Add Entry - - Loading - - - Loading... - - - - - Finished rendering of %1 - - - LogarithmPlotter - - untitled - - - - + Objects Objekter - + Settings Innstillinger - + History Historikk @@ -463,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 @@ -481,7 +449,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectCreationGrid - + + Create new: + Opprett ny: @@ -489,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 @@ -522,84 +490,77 @@ 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 - - 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: + 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 - + Close Lukk @@ -607,213 +568,207 @@ 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 + Lagre plott - + Save plot as - Lagre plott som + Lagre plott som - + Load plot - Last inn plott + Last inn plott 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 - - Tamil - - - - + Translations included - + Improve @@ -821,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 @@ -846,8 +801,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodemagnitudesum - - + + Bode Magnitudes Sum Bode-magnitudesum @@ -855,12 +810,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodephase - + Bode Phase Bode-fase - + Bode Phases Bode-faser @@ -868,8 +823,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. bodephasesum - - + + Bode Phases Sum Bode-fasesum @@ -877,13 +832,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - - + Could not fetch update: {}. @@ -891,8 +845,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. color - - + + %1 %2's color changed from %3 to %4. @@ -900,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. @@ -928,11 +882,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. control - - - - - + + + + + %1: @@ -940,8 +894,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create - - + + New %1 %2 created. Ny %1 %2 opprettet. @@ -949,8 +903,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. delete - - + + %1 %2 deleted. %1 %2 slettet. @@ -958,12 +912,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. distribution - + Repartition Distribusjon - + Repartition functions Distribusjonsfunksjoner @@ -971,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. @@ -984,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 @@ -1017,7 +971,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1025,88 +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. @@ -1114,13 +1108,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1128,27 +1122,27 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme @@ -1156,12 +1150,12 @@ Evaluated expression: %3 function - + Function Funksjon - + Functions Funksjoner @@ -1188,25 +1182,20 @@ 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 - - - Enable threaded LaTeX renderer (experimental) - - historylib @@ -1246,28 +1235,34 @@ 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. + 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! @@ -1285,19 +1280,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 {}: @@ -1306,7 +1301,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/{}) @@ -1315,7 +1310,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: {} @@ -1323,37 +1318,11 @@ 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 - - + + %1 %2 renamed to %3. @@ -1361,114 +1330,114 @@ File does not exist. 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 @@ -1487,12 +1456,12 @@ File does not exist. point - + Point Punkt - + Points Punkter @@ -1500,12 +1469,12 @@ File does not exist. position - + Position of %1 %2 set from "%3" to "%4". - + Position of %1 set from %2 to %3. @@ -1513,166 +1482,161 @@ File does not exist. 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 - Etikett-innhold - repartition @@ -1688,12 +1652,12 @@ File does not exist. sequence - + Sequence Følge - + Sequences Følger @@ -1701,17 +1665,17 @@ File does not exist. settingCategory - + general - + editor - + default @@ -1733,12 +1697,12 @@ File does not exist. text - + Text Tekst - + Texts Tekster @@ -1746,22 +1710,22 @@ File does not exist. 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: {}. @@ -1769,38 +1733,38 @@ File does not exist. 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>) @@ -1808,14 +1772,14 @@ File does not exist. visibility - - + + %1 %2 shown. %1 %2 vist. - - + + %1 %2 hidden. %1 %2 skjult. @@ -1823,12 +1787,12 @@ File does not exist. xcursor - + X Cursor X-peker - + X Cursors X-pekere diff --git a/assets/i18n/lp_ta.ts b/assets/i18n/lp_ta.ts deleted file mode 100644 index 2f3048c..0000000 --- a/assets/i18n/lp_ta.ts +++ /dev/null @@ -1,1597 +0,0 @@ - - - - - About - - - About LogarithmPlotter - மடக்கை பற்றி - - - - LogarithmPlotter v%1 - மடக்கை சதித்திட்டம் வி 1 - - - - 2D plotter software to make BODE plots, sequences and repartition functions. - போட் அடுக்கு, காட்சிகள் மற்றும் விநியோக செயல்பாடுகளை உருவாக்க 2 டி ப்ளாட்டர் மென்பொருள். - - - - Report a bug - ஒரு பிழையைப் புகாரளிக்கவும் - - - - Official website - அதிகாரப்பூர்வ வலைத்தளம் - - - - AppMenuBar - - - &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? - இந்த சதித்திட்டத்தில் சேமிக்கப்படாத மாற்றங்கள் உள்ளன. இதைச் செய்வதன் மூலம், சேமிக்கப்படாத அனைத்து தரவும் இழக்கப்படும். தொடரவா? - - - - BaseDialog - - - Close - மூடு - - - - Browser - - - Filter... - வடிகட்டி… - - - - Redo > - மீண்டும்> - - - - > Now - > இப்போது - - - - < Undo - <செயல்தவிர்க்கவும் - - - - Changelog - - - Fetching changelog... - சேஞ்ச்லாக் பெறுதல்… - - - - Close - மூடு - - - - CustomPropertyList - - - - + Create new %1 - + புதிய %1 ஐ உருவாக்கவும் - - - - Pick on graph - வரைபடத்தைத் தேர்ந்தெடுங்கள் - - - - Dialog - - - 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 - பெயர் + மதிப்பு - - - - ExpressionEditor - - - Object Properties - பொருள் பண்புகள் - - - - Variables - மாறிகள் - - - - Constants - மாறிலிகள் - - - - Functions - செயல்பாடுகள் - - - - Executable Objects - செயல்பாடு பொருள்கள் - - - - Objects - பொருள்கள் - - - - FileDialog - - - Export Logarithm Plot file - மடக்கை சூழ்ச்சி கோப்பை ஏற்றுமதி செய்யுங்கள் - - - - Import Logarithm Plot file - மடக்கை சூழ்ச்சி கோப்பை இறக்குமதி செய்க - - - - GreetScreen - - - Welcome to LogarithmPlotter - மடக்கை பிளாட்டருக்கு வருக - - - - Version %1 - பதிப்பு %1 - - - - User manual - பயனர் கையேடு - - - - Changelog - மாற்றபதிவு - - - - Preferences - விருப்பத்தேர்வுகள் - - - - Close - மூடு - - - - ListSetting - - - + Add Entry - + உள்ளீட்டைச் சேர்க்கவும் - - - - Loading - - - Loading... - ஏற்றுகிறது… - - - - Finished rendering of %1 - %1 இன் வழங்குதல் முடிந்தது - - - - LogarithmPlotter - - - untitled - தலைப்பிடப்படாத - - - - Objects - பொருள்கள் - - - - Settings - அமைப்புகள் - - - - History - வரலாறு - - - - Copied plot screenshot to clipboard! - இடைநிலைப்பலகைக்கு சூழ்ச்சி திரை சாட்டை நகலெடுத்தது! - - - - &Update - & புதுப்பிக்கவும் - - - - &Update LogarithmPlotter - & மடக்கை புதுப்பிக்கவும் - - - - ObjectCreationGrid - - - + Create new: - + புதியதை உருவாக்கு: - - - - ObjectLists - - - Hide all %1 - அனைத்து %1 ஐ மறைக்கவும் - - - - Show all %1 - அனைத்து %1 ஐக் காட்டு - - - - ObjectRow - - - 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 க்கு புதிய வண்ணத்தைத் தேர்ந்தெடுங்கள் - - - - PickLocation - - - 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 - 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 - திறந்த சதி… - - - - 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 - AD5001 ஆல் QMLJS க்கு அனுப்பப்பட்டது - - - - Libraries included - நூலகங்கள் சேர்க்கப்பட்டுள்ளன - - - - Email - மின்னஞ்சல் - - - - English - ஆங்கிலம் - - - - French - பிரஞ்சு - - - - German - செர்மன் - - - - Hungarian - அங்கேரியன் - - - - - - - Github - கிரப் - - - - Norwegian - நோர்வே - - - - Spanish - ச்பானிச் - - - - Tamil - தமிழ் - - - - 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. - %1 %2 இன் நிறம் %3 முதல் %4 வரை மாற்றப்பட்டது. - - - - 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}...) - டொமைன் ஒரு தொடர்ச்சியான தொகுப்பாக இருக்கும்போது பின்வரும் அளவுருக்கள் பயன்படுத்தப்படுகின்றன. (எ.கா: ℕ, ℤ, {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. - நீங்கள் லேடெக்ச் இயக்கப்பட்டிருந்தால், சமன்பாடுகளை உருவாக்க லேடெக்ச் மார்க்அப்பைப் பயன்படுத்தலாம். - - - - control - - - - - - - %1: - %1: - - - - create - - - - New %1 %2 created. - புதிய %1 %2 உருவாக்கப்பட்டது. - - - - delete - - - - %1 %2 deleted. - %1 %2 நீக்கப்பட்டது. - - - - distribution - - - Repartition - பரவல் - - - - Repartition functions - விநியோக செயல்பாடுகள் - - - - editproperty - - - %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 வரை மாற்றப்பட்டது. - - - - error - - - 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 ஐ சார்ந்துள்ளது. - - - - Error while parsing expression for property %1: -%2 - -Evaluated expression: %3 - சொத்து %1 க்கான வெளிப்பாட்டை பாகுபடுத்தும்போது பிழை: - %2 - - மதிப்பீடு செய்யப்பட்ட வெளிப்பாடு: %3 - - - - Error while attempting to draw %1 %2: -%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. - - - - expression - - - - LogarithmPlotter - Parsing error - மடக்கை பிளாட்டர் - பாகுபடுத்தும் பிழை - - - - Error while parsing expression for property %1: -%2 - -Evaluated expression: %3 - சொத்து %1 க்கான வெளிப்பாட்டை பாகுபடுத்தும்போது பிழை: - %2 - - மதிப்பீடு செய்யப்பட்ட வெளிப்பாடு: %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 - லேடெக்ச் வழங்குதல் இயக்கவும் - - - - 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/. - லேடெக்ச் நிறுவல் எதுவும் கிடைக்கவில்லை. - உங்களிடம் ஏற்கனவே லேடெக்ச் வழங்கல் நிறுவப்பட்டிருந்தால், அது உங்கள் பாதையில் நிறுவப்பட்டுள்ளதா என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள். - இல்லையெனில், டெக்ச் லைவ் போன்ற லேடெக்ச் விநியோகத்தை https://tug.org/texlive/ இல் பதிவிறக்கம் செய்யலாம். - - - - DVIPNG was not found. Make sure you include it from your Latex distribution. - Dvipng கண்டுபிடிக்கப்படவில்லை. உங்கள் லேடெக்ச் விநியோகத்திலிருந்து இதைச் சேர்த்துள்ளீர்கள் என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள். - - - - 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. - உங்கள் லேடெக்ச் நிறுவலில் தேவையான சில தொகுப்புகள் இல்லை: - - - {} (https://ctan.org/pkg/ {}) - - தொகுப்பு நிறுவப்பட்டிருப்பதை உறுதிசெய்து கொள்ளுங்கள், அல்லது லோகரிதம்லட்டரில் லேடெக்ச் வழங்குதல் முடக்கவும். - - - - 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. - லேடெக்ச் சூத்திரத்தை உருவாக்குவதற்குள் விதிவிலக்கு ஏற்பட்டது. - '{}' செயல்முறை முடிக்க அதிக நேரம் எடுத்தது: - {} - உங்கள் லேடெக்ச் நிறுவல் சரியானது என்பதை உறுதிப்படுத்தவும், அப்படியானால் ஒரு பிழையைப் புகாரளிக்கவும். - - - - 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. - இந்த கோப்பு மடக்கை படத்தின் மிக அண்மைக் கால பதிப்பால் உருவாக்கப்பட்டது, மேலும் லோகரிதம் பிளாட்டர் 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 உடன் கட்டப்பட்டுள்ளது - - - - name - - - - %1 %2 renamed to %3. - %1 %2 %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". - %1%2 "%3" இலிருந்து "%4" க்கு நகர்ந்தது. - - - - Position of %1 set from %2 to %3. - %1 %2 முதல் %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. - மடக்கை (v {}) க்கான புதுப்பிப்பு கிடைக்கிறது. - - - - No update available. - புதுப்பிப்பு எதுவும் கிடைக்கவில்லை. - - - - Could not fetch update information: Server error {}. - புதுப்பிப்பு தகவலைப் பெற முடியவில்லை: சேவையக பிழை {}. - - - - Could not fetch update information: {}. - புதுப்பிப்பு தகவல்களைப் பெற முடியவில்லை: {}. - - - - usage - - - integral(<from: number>, <to: number>, <f: ExecutableObject>) - ஒருங்கிணைந்த (<இலிருந்து: எண்>, <க்கு: எண்>, <f: செயல்பாடு போன்ற பொருள்>) - - - - - Usage: -%1 - பயன்பாடு: - %1 - - - - - - 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: எண்>) - - - - visibility - - - - %1 %2 shown. - %1 %2 காட்டப்பட்டுள்ளது. - - - - - %1 %2 hidden. - %1 %2 மறைக்கப்பட்டுள்ளது. - - - - xcursor - - - X Cursor - ஃச் கர்சர் - - - - X Cursors - ஃச் கர்சர்கள் - - - diff --git a/assets/i18n/lp_template.ts b/assets/i18n/lp_template.ts index 7f1bc28..7626f7b 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,43 +140,20 @@ BaseDialog - + Close - - Browser - - - Filter... - - - - - Redo > - - - - - > Now - - - - - < Undo - - - Changelog - + Fetching changelog... - + Close @@ -184,13 +161,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -198,37 +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 @@ -236,32 +218,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -269,12 +251,12 @@ FileDialog - + Export Logarithm Plot file - + Import Logarithm Plot file @@ -282,91 +264,96 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + User manual - + Changelog - + Preferences - + Close + + HistoryBrowser + + + Filter... + + + + + Redo > + + + + + > Now + + + + + < Undo + + + ListSetting - + + Add Entry - - Loading - - - Loading... - - - - - Finished rendering of %1 - - - LogarithmPlotter - - untitled - - - - + Objects - + Settings - + History - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -374,7 +361,7 @@ ObjectCreationGrid - + + Create new: @@ -382,12 +369,12 @@ ObjectLists - + Hide all %1 - + Show all %1 @@ -395,73 +382,73 @@ ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 - PickLocation + PickLocationOverlay - + Pointer precision: - + - + Snap to grid: - + - + Pick X - + - + Pick Y - + - + Open picker settings - + - + Hide picker settings - + - + (no pick selected) - + Preferences - + Close @@ -469,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 @@ -580,102 +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 - - Tamil - - - - + Translations included - + Improve @@ -683,24 +664,24 @@ bodemagnitude - + Bode Magnitude - + Bode Magnitudes - - + + low-pass - - + + high-pass @@ -708,8 +689,8 @@ bodemagnitudesum - - + + Bode Magnitudes Sum @@ -717,12 +698,12 @@ bodephase - + Bode Phase - + Bode Phases @@ -730,8 +711,8 @@ bodephasesum - - + + Bode Phases Sum @@ -739,13 +720,12 @@ changelog - + Could not fetch changelog: Server error {}. - - + Could not fetch update: {}. @@ -753,8 +733,8 @@ color - - + + %1 %2's color changed from %3 to %4. @@ -762,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. @@ -790,11 +770,11 @@ control - - - - - + + + + + %1: @@ -802,8 +782,8 @@ create - - + + New %1 %2 created. @@ -811,8 +791,8 @@ delete - - + + %1 %2 deleted. @@ -820,12 +800,12 @@ distribution - + Repartition - + Repartition functions @@ -833,12 +813,12 @@ editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -846,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 @@ -879,7 +859,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -887,88 +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. @@ -976,13 +996,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -990,27 +1010,27 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme @@ -1018,12 +1038,12 @@ Evaluated expression: %3 function - + Function - + Functions @@ -1031,42 +1051,70 @@ Evaluated expression: %3 general - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering + + + io - - Enable threaded LaTeX renderer (experimental) + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save 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 {}: @@ -1075,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/{}) @@ -1084,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: {} @@ -1092,37 +1140,11 @@ 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 - - + + %1 %2 renamed to %3. @@ -1130,114 +1152,114 @@ File does not exist. 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 @@ -1245,12 +1267,12 @@ File does not exist. point - + Point - + Points @@ -1258,12 +1280,12 @@ File does not exist. position - + Position of %1 %2 set from "%3" to "%4". - + Position of %1 set from %2 to %3. @@ -1271,176 +1293,171 @@ File does not exist. 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 @@ -1448,17 +1465,17 @@ File does not exist. settingCategory - + general - + editor - + default @@ -1466,12 +1483,12 @@ File does not exist. text - + Text - + Texts @@ -1479,22 +1496,22 @@ File does not exist. update - + An update for LogarithmPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. @@ -1502,38 +1519,38 @@ File does not exist. 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>) @@ -1541,14 +1558,14 @@ File does not exist. visibility - - + + %1 %2 shown. - - + + %1 %2 hidden. @@ -1556,12 +1573,12 @@ File does not exist. xcursor - + X Cursor - + X Cursors diff --git a/assets/i18n/release.sh b/assets/i18n/release.sh index 58477c3..93475b5 100755 --- a/assets/i18n/release.sh +++ b/assets/i18n/release.sh @@ -1,2 +1,2 @@ #!/bin/bash -pyside6-lrelease *.ts +lrelease *.ts diff --git a/assets/i18n/update.sh b/assets/i18n/update.sh index 98f4201..8d589d5 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 ../../common/src -name '*.mjs') +files=$(find .. -name *.mjs) for file in $files; do echo "Moving '$file' to '${file%.*}.js'..." mv "$file" "${file%.*}.js" @@ -33,14 +33,12 @@ 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 "----------------------------" echo "| Updating translations... |" echo "----------------------------" -pyside6-lupdate -extensions js,qs,qml,py -recursive ../../common/src -recursive ../../runtime-pyside6/LogarithmPlotter -ts lp_*.ts +lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts # Updating locations in files for lp in *.ts; do echo "Replacing locations in $lp..." @@ -57,9 +55,7 @@ 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" "// #" " #" - replace "$file" "/*this.#*/" "this.#" + replace "$file" '.mjs"*/$' '.mjs"' done diff --git a/assets/icons/logarithmplotter.svg b/assets/icons/logarithmplotter.svg new file mode 120000 index 0000000..0497bab --- /dev/null +++ b/assets/icons/logarithmplotter.svg @@ -0,0 +1 @@ +../../../../../logarithmplotter.svg \ No newline at end of file diff --git a/assets/icons/properties/displayMode.svg b/assets/icons/properties/displayMode.svg deleted file mode 120000 index 41b711b..0000000 --- a/assets/icons/properties/displayMode.svg +++ /dev/null @@ -1 +0,0 @@ -../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/displayStyle.svg b/assets/icons/properties/displayStyle.svg deleted file mode 120000 index 41b711b..0000000 --- a/assets/icons/properties/displayStyle.svg +++ /dev/null @@ -1 +0,0 @@ -../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/labelPosition.svg b/assets/icons/properties/labelPosition.svg deleted file mode 120000 index 3e4c849..0000000 --- a/assets/icons/properties/labelPosition.svg +++ /dev/null @@ -1 +0,0 @@ -../common/arrow.svg \ No newline at end of file diff --git a/assets/icons/properties/labelX.svg b/assets/icons/properties/labelX.svg deleted file mode 120000 index 4eecad3..0000000 --- a/assets/icons/properties/labelX.svg +++ /dev/null @@ -1 +0,0 @@ -../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 deleted file mode 120000 index e4130be..0000000 --- a/assets/icons/properties/om_0.svg +++ /dev/null @@ -1 +0,0 @@ -../common/angle.svg \ No newline at end of file diff --git a/assets/icons/properties/phase.svg b/assets/icons/properties/phase.svg deleted file mode 120000 index e4130be..0000000 --- a/assets/icons/properties/phase.svg +++ /dev/null @@ -1 +0,0 @@ -../common/angle.svg \ No newline at end of file diff --git a/assets/icons/properties/pointStyle.svg b/assets/icons/properties/pointStyle.svg deleted file mode 120000 index 41b711b..0000000 --- a/assets/icons/properties/pointStyle.svg +++ /dev/null @@ -1 +0,0 @@ -../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/targetElement.svg b/assets/icons/properties/targetElement.svg deleted file mode 120000 index 659962b..0000000 --- a/assets/icons/properties/targetElement.svg +++ /dev/null @@ -1 +0,0 @@ -../common/target.svg \ No newline at end of file diff --git a/assets/icons/properties/targetValuePosition.svg b/assets/icons/properties/targetValuePosition.svg deleted file mode 120000 index 4eecad3..0000000 --- a/assets/icons/properties/targetValuePosition.svg +++ /dev/null @@ -1 +0,0 @@ -../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/text.svg b/assets/icons/properties/text.svg deleted file mode 120000 index 280f9ad..0000000 --- a/assets/icons/properties/text.svg +++ /dev/null @@ -1 +0,0 @@ -../common/label.svg \ No newline at end of file diff --git a/assets/icons/properties/unit.svg b/assets/icons/properties/unit.svg deleted file mode 120000 index e4130be..0000000 --- a/assets/icons/properties/unit.svg +++ /dev/null @@ -1 +0,0 @@ -../common/angle.svg \ No newline at end of file diff --git a/assets/icons/properties/x.svg b/assets/icons/properties/x.svg deleted file mode 120000 index 4eecad3..0000000 --- a/assets/icons/properties/x.svg +++ /dev/null @@ -1 +0,0 @@ -../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/y.svg b/assets/icons/properties/y.svg deleted file mode 120000 index 4eecad3..0000000 --- a/assets/icons/properties/y.svg +++ /dev/null @@ -1 +0,0 @@ -../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/definitionDomain.svg b/assets/icons/settings/custom/Definition Domain.svg similarity index 100% rename from assets/icons/properties/definitionDomain.svg rename to assets/icons/settings/custom/Definition Domain.svg diff --git a/assets/icons/properties/destinationDomain.svg b/assets/icons/settings/custom/Destination Domain.svg similarity index 100% rename from assets/icons/properties/destinationDomain.svg rename to assets/icons/settings/custom/Destination Domain.svg diff --git a/assets/icons/settings/custom/Display Mode.svg b/assets/icons/settings/custom/Display Mode.svg new file mode 120000 index 0000000..7a5ba45 --- /dev/null +++ b/assets/icons/settings/custom/Display Mode.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..7a5ba45 --- /dev/null +++ b/assets/icons/settings/custom/Display Style.svg @@ -0,0 +1 @@ +../../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/expression.svg b/assets/icons/settings/custom/Expression.svg similarity index 100% rename from assets/icons/properties/expression.svg rename to assets/icons/settings/custom/Expression.svg diff --git a/assets/icons/properties/gain.svg b/assets/icons/settings/custom/Gain.svg similarity index 100% rename from assets/icons/properties/gain.svg rename to assets/icons/settings/custom/Gain.svg diff --git a/assets/icons/settings/custom/Label Position.svg b/assets/icons/settings/custom/Label Position.svg new file mode 120000 index 0000000..43aa15f --- /dev/null +++ b/assets/icons/settings/custom/Label Position.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..6b40925 --- /dev/null +++ b/assets/icons/settings/custom/Label X.svg @@ -0,0 +1 @@ +../../common/position.svg \ No newline at end of file diff --git a/assets/icons/properties/pass.svg b/assets/icons/settings/custom/Pass.svg similarity index 100% rename from assets/icons/properties/pass.svg rename to assets/icons/settings/custom/Pass.svg diff --git a/assets/icons/settings/custom/Phase.svg b/assets/icons/settings/custom/Phase.svg new file mode 120000 index 0000000..21699e9 --- /dev/null +++ b/assets/icons/settings/custom/Phase.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..7a5ba45 --- /dev/null +++ b/assets/icons/settings/custom/Point Style.svg @@ -0,0 +1 @@ +../../common/appearance.svg \ No newline at end of file diff --git a/assets/icons/properties/rounding.svg b/assets/icons/settings/custom/Rounding.svg similarity index 100% rename from assets/icons/properties/rounding.svg rename to assets/icons/settings/custom/Rounding.svg diff --git a/assets/icons/settings/custom/Target Element.svg b/assets/icons/settings/custom/Target Element.svg new file mode 120000 index 0000000..50124dc --- /dev/null +++ b/assets/icons/settings/custom/Target Element.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..6b40925 --- /dev/null +++ b/assets/icons/settings/custom/Target Value Position.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..69be9e1 --- /dev/null +++ b/assets/icons/settings/custom/Text.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..21699e9 --- /dev/null +++ b/assets/icons/settings/custom/Unit.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..6b40925 --- /dev/null +++ b/assets/icons/settings/custom/X.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..6b40925 --- /dev/null +++ b/assets/icons/settings/custom/Y.svg @@ -0,0 +1 @@ +../../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 new file mode 120000 index 0000000..21699e9 --- /dev/null +++ b/assets/icons/settings/custom/ω_0.svg @@ -0,0 +1 @@ +../../common/angle.svg \ No newline at end of file diff --git a/assets/logarithmplotter.svg b/assets/logarithmplotter.svg index 1f3a5e0..77a2817 100644 --- a/assets/logarithmplotter.svg +++ b/assets/logarithmplotter.svg @@ -1,171 +1,64 @@ - - - LogarithmPlotter Icon - - - - - - - - - - - - - - - - - - - LogarithmPlotter Icon v1.0image/svg+xmlLogarithmPlotter Icon v1.02021Ad5001(c) Ad5001 2021 - All rights reserved - - - - - - - - - - - - - - LogarithmPlotter Icon - 2024-10-06 - - - Adsooi <mail@ad5001.eu> - - - - - (c) Adsooi 2021-2024 - - - - - - - - - - - - - - - - + d="M 18,4 C 18,10.017307 13.40948,15.5 5,15.5" /> diff --git a/assets/native/linux/debian/control.bkp b/assets/native/linux/debian/control similarity index 84% rename from assets/native/linux/debian/control.bkp rename to assets/native/linux/debian/control index 1df7fd8..a1089e7 100644 --- a/assets/native/linux/debian/control.bkp +++ b/assets/native/linux/debian/control @@ -3,7 +3,7 @@ Source: logarithmplotter Version: 0.6.0 Architecture: all Maintainer: Ad5001 -Depends: python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7), 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 Section: science diff --git a/assets/native/linux/debian/depends.wheels b/assets/native/linux/debian/depends similarity index 100% rename from assets/native/linux/debian/depends.wheels rename to assets/native/linux/debian/depends diff --git a/assets/native/linux/debian/depends.packaged b/assets/native/linux/debian/depends.packaged deleted file mode 100644 index 0bace27..0000000 --- a/assets/native/linux/debian/depends.packaged +++ /dev/null @@ -1 +0,0 @@ -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/eu.ad5001.LogarithmPlotter.metainfo.xml b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index f7e4c9d..6f90a1f 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 @@ -66,54 +66,50 @@ 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.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 + 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. - 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.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 + 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. - 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.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 + 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. - Página de bienvenida de LogarithmPlotter. diff --git a/assets/native/linux/x-logarithm-plot.xml b/assets/native/linux/x-logarithm-plot.xml index 888641e..31b5c9d 100644 --- a/assets/native/linux/x-logarithm-plot.xml +++ b/assets/native/linux/x-logarithm-plot.xml @@ -1,7 +1,7 @@ - Logarithmic Plot File + Logarithm Plot File Fichier Graphe Logarithmique diff --git a/assets/native/win/installer.nsi b/assets/native/win/installer.nsi index bf38199..ebb84c9 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-2025" +!define COPYRIGHT "Ad5001 (c) 2021-2024" !define DESCRIPTION "Create graphs with logarithmic scales." !define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter" diff --git a/ci/all.lpf b/ci/all.lpf deleted file mode 100644 index 9eeb0b9..0000000 --- a/ci/all.lpf +++ /dev/null @@ -1 +0,0 @@ -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 54ef658..da7d1c7 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -12,29 +12,32 @@ steps: - git submodule update --init --recursive - name: Build - image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex-node + image: node:18-bookworm 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-node + image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex 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-node + 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 - 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 deleted file mode 100644 index 35ac7ae..0000000 --- a/ci/magnitude.lpf +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 361d157..0000000 --- a/ci/phase.lpf +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 05e171c..0000000 --- a/ci/stress.lpf +++ /dev/null @@ -1 +0,0 @@ -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 diff --git a/common/package-lock.json b/common/package-lock.json index 9ca31b3..0b60cac 100644 --- a/common/package-lock.json +++ b/common/package-lock.json @@ -19,12 +19,9 @@ }, "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", "chai-as-promised": "^8.0.0", - "chai-spies": "^1.1.0", "esm": "^3.2.25", "mocha": "^10.7.3" } @@ -44,13 +41,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "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/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -58,31 +54,31 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "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.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "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.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@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", @@ -98,42 +94,54 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", - "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "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/parser": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "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.25.9" + "@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.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", - "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "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.26.8", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", + "@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" }, @@ -142,17 +150,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz", - "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==", + "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.25.9", - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.26.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.27.0", + "@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": { @@ -163,13 +171,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz", - "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==", + "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.25.9", - "regexpu-core": "^6.2.0", + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", "semver": "^6.3.1" }, "engines": { @@ -180,9 +188,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "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", @@ -196,40 +204,41 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "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.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "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.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "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.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@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" @@ -239,35 +248,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "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.25.9" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "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.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", - "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "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.25.9", - "@babel/helper-wrap-function": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@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" @@ -277,14 +286,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", - "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "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.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.26.5" + "@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" @@ -293,81 +302,109 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "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.25.9", - "@babel/types": "^7.25.9" + "@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.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "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.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "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.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "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.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", - "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "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.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@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.27.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "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.27.0", - "@babel/types": "^7.27.0" + "@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.27.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "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.27.0" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -377,13 +414,13 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", - "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "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.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" }, "engines": { "node": ">=6.9.0" @@ -393,12 +430,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", - "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -408,12 +445,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.9", - "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.9.tgz", - "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -423,14 +460,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "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.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9" + "@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" @@ -440,13 +477,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", - "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "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.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -467,13 +504,76 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", - "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "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.25.9" + "@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" @@ -483,12 +583,138 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "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.25.9" + "@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" @@ -514,12 +740,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", - "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -529,14 +755,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", - "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "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.26.5", - "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.26.8" + "@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" @@ -546,14 +773,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", - "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-remap-async-to-generator": "^7.25.9" + "@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" @@ -563,12 +790,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", - "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "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.26.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -578,12 +805,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz", - "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==", + "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.26.5" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -593,13 +820,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", - "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "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.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -609,13 +836,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", - "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@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" @@ -625,16 +853,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", - "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "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.25.9", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", - "@babel/traverse": "^7.25.9", + "@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": { @@ -645,13 +873,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", - "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "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.25.9", - "@babel/template": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -661,12 +889,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", - "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -676,13 +904,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", - "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -692,12 +920,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", - "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -707,13 +935,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "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.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -723,12 +951,13 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", - "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -738,12 +967,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", - "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "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-plugin-utils": "^7.25.9" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -753,12 +983,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", - "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -768,13 +999,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", - "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "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.26.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -784,14 +1015,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", - "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" }, "engines": { "node": ">=6.9.0" @@ -801,12 +1032,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", - "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -816,12 +1048,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", - "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -831,12 +1063,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", - "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -846,12 +1079,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", - "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -861,13 +1094,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", - "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -877,13 +1110,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "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.26.0", - "@babel/helper-plugin-utils": "^7.25.9" + "@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" @@ -893,15 +1127,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", - "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "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.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@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" @@ -911,13 +1145,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", - "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -927,13 +1161,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -943,12 +1177,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", - "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -958,12 +1192,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.26.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", - "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "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.26.5" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -973,12 +1208,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", - "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -988,14 +1224,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", - "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9" + "@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" @@ -1005,13 +1242,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", - "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "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.25.9", - "@babel/helper-replace-supers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1021,12 +1258,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", - "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1036,13 +1274,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "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.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@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" @@ -1052,12 +1291,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", - "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1067,13 +1306,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", - "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "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.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1083,14 +1322,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", - "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "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.25.9", - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@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" @@ -1100,12 +1340,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", - "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1115,12 +1355,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz", - "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==", + "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.26.5", + "@babel/helper-plugin-utils": "^7.24.7", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1130,29 +1370,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", - "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", - "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1162,12 +1386,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", - "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1177,13 +1401,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", - "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "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.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1193,12 +1417,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", - "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1208,12 +1432,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", - "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", + "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.26.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1223,12 +1447,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz", - "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==", + "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.26.5" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1238,12 +1462,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", - "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "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.25.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1253,13 +1477,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", - "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1269,13 +1493,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", - "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "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.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1285,13 +1509,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", - "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "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.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1301,79 +1525,93 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", - "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "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.26.8", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@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-import-assertions": "^7.26.0", - "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@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.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.26.8", - "@babel/plugin-transform-async-to-generator": "^7.25.9", - "@babel/plugin-transform-block-scoped-functions": "^7.26.5", - "@babel/plugin-transform-block-scoping": "^7.25.9", - "@babel/plugin-transform-class-properties": "^7.25.9", - "@babel/plugin-transform-class-static-block": "^7.26.0", - "@babel/plugin-transform-classes": "^7.25.9", - "@babel/plugin-transform-computed-properties": "^7.25.9", - "@babel/plugin-transform-destructuring": "^7.25.9", - "@babel/plugin-transform-dotall-regex": "^7.25.9", - "@babel/plugin-transform-duplicate-keys": "^7.25.9", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-dynamic-import": "^7.25.9", - "@babel/plugin-transform-exponentiation-operator": "^7.26.3", - "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.26.9", - "@babel/plugin-transform-function-name": "^7.25.9", - "@babel/plugin-transform-json-strings": "^7.25.9", - "@babel/plugin-transform-literals": "^7.25.9", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", - "@babel/plugin-transform-member-expression-literals": "^7.25.9", - "@babel/plugin-transform-modules-amd": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.26.3", - "@babel/plugin-transform-modules-systemjs": "^7.25.9", - "@babel/plugin-transform-modules-umd": "^7.25.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-new-target": "^7.25.9", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", - "@babel/plugin-transform-numeric-separator": "^7.25.9", - "@babel/plugin-transform-object-rest-spread": "^7.25.9", - "@babel/plugin-transform-object-super": "^7.25.9", - "@babel/plugin-transform-optional-catch-binding": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9", - "@babel/plugin-transform-private-methods": "^7.25.9", - "@babel/plugin-transform-private-property-in-object": "^7.25.9", - "@babel/plugin-transform-property-literals": "^7.25.9", - "@babel/plugin-transform-regenerator": "^7.25.9", - "@babel/plugin-transform-regexp-modifiers": "^7.26.0", - "@babel/plugin-transform-reserved-words": "^7.25.9", - "@babel/plugin-transform-shorthand-properties": "^7.25.9", - "@babel/plugin-transform-spread": "^7.25.9", - "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.26.8", - "@babel/plugin-transform-typeof-symbol": "^7.26.7", - "@babel/plugin-transform-unicode-escapes": "^7.25.9", - "@babel/plugin-transform-unicode-property-regex": "^7.25.9", - "@babel/plugin-transform-unicode-regex": "^7.25.9", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@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.11.0", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", + "core-js-compat": "^3.37.1", "semver": "^6.3.1" }, "engines": { @@ -1397,10 +1635,16 @@ "@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.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "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" @@ -1410,30 +1654,30 @@ } }, "node_modules/@babel/template": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "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.26.2", - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0" + "@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.27.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "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.26.2", - "@babel/generator": "^7.27.0", - "@babel/parser": "^7.27.0", - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0", + "@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" }, @@ -1442,26 +1686,24 @@ } }, "node_modules/@babel/types": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "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.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@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/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", - "license": "MIT", - "engines": { - "node": ">=18" - } + "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", @@ -1569,9 +1811,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "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", @@ -1653,18 +1895,18 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz", - "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==", + "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.2.0", + "fdir": "^6.1.1", "is-reference": "1.2.1", "magic-string": "^0.30.3", - "picomatch": "^4.0.2" + "picomatch": "^2.3.1" }, "engines": { "node": ">=16.0.0 || 14 >= 14.17" @@ -1678,10 +1920,22 @@ } } }, + "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.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", - "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "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", @@ -1703,14 +1957,14 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", - "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "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": "^4.0.2" + "picomatch": "^2.3.1" }, "engines": { "node": ">=14.0.0" @@ -1724,10 +1978,22 @@ } } }, + "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.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz", - "integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==", + "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" ], @@ -1738,9 +2004,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.0.tgz", - "integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==", + "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" ], @@ -1751,9 +2017,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.0.tgz", - "integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==", + "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" ], @@ -1764,9 +2030,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.0.tgz", - "integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==", + "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" ], @@ -1776,36 +2042,10 @@ "darwin" ] }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.0.tgz", - "integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.0.tgz", - "integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.0.tgz", - "integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==", + "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" ], @@ -1816,9 +2056,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.0.tgz", - "integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==", + "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" ], @@ -1829,9 +2069,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.0.tgz", - "integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==", + "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" ], @@ -1842,9 +2082,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.0.tgz", - "integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==", + "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" ], @@ -1854,23 +2094,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.0.tgz", - "integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.0.tgz", - "integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==", + "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" ], @@ -1881,22 +2108,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.0.tgz", - "integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.0.tgz", - "integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==", + "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" ], @@ -1907,9 +2121,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.0.tgz", - "integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==", + "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" ], @@ -1920,9 +2134,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz", - "integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==", + "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" ], @@ -1933,9 +2147,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.0.tgz", - "integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==", + "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" ], @@ -1946,9 +2160,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.0.tgz", - "integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==", + "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" ], @@ -1959,9 +2173,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.0.tgz", - "integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==", + "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" ], @@ -1972,9 +2186,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz", - "integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==", + "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" ], @@ -1985,46 +2199,16 @@ ] }, "node_modules/@types/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-iu1JLYmGmITRzUgNiLMZD3WCoFzpYtueuyAgHTXqgwSRAMIlFTnZqG6/xenkpUGRJEzSfklUTI4GNSzks/dc0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*" - } - }, - "node_modules/@types/chai-as-promised": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.2.tgz", - "integrity": "sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==", - "dev": true, - "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", - "integrity": "sha512-xkk4HmhBB9OQeTAifa9MJ+6R5/Rq9+ungDe4JidZD+vqZVeiWZwc2i7/pd1ZKjyGlSBIQePoWdyUyFUGT0rv5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "*" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "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.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "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/istanbul-lib-coverage": { @@ -2034,9 +2218,9 @@ "license": "MIT" }, "node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "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" }, @@ -2066,18 +2250,15 @@ } }, "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==", + "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": "^2.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=4" } }, "node_modules/anymatch": { @@ -2125,13 +2306,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", - "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "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.4", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -2139,25 +2320,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "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.3", - "core-js-compat": "^3.40.0" + "@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.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", - "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "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.4" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -2212,9 +2393,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "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", @@ -2231,10 +2412,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "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" @@ -2244,12 +2425,12 @@ } }, "node_modules/c8": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", - "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==", + "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": "^1.0.1", + "@bcoe/v8-coverage": "^0.2.3", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", "foreground-child": "^3.1.1", @@ -2276,6 +2457,96 @@ } } }, + "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", @@ -2290,9 +2561,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001715", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz", - "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "funding": [ { "type": "opencollective", @@ -2310,9 +2581,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", - "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "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": { @@ -2327,11 +2598,11 @@ } }, "node_modules/chai-as-promised": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.1.tgz", - "integrity": "sha512-OIEJtOL8xxJSH8JJWbIoRjybbzR52iFuDHuF8eb+nTPD6tgXLjRqsgnUGqQfFODxYvq5QdirT0pN9dZ0+Gz6rA==", + "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": "MIT", + "license": "WTFPL", "dependencies": { "check-error": "^2.0.0" }, @@ -2339,34 +2610,18 @@ "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": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "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": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=4" } }, "node_modules/check-error": { @@ -2405,35 +2660,30 @@ } }, "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==", + "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.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" } }, "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==", + "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.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "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==", + "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/commondir": { @@ -2449,12 +2699,12 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.41.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", - "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", + "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.24.4" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -2462,9 +2712,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "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", @@ -2476,9 +2726,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "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" @@ -2541,9 +2791,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.140", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.140.tgz", - "integrity": "sha512-o82Rj+ONp4Ip7Cl1r7lrqx/pXhbp/lh9DpKcMNscFJdh8ebyRofnc7Sh01B4jx403RI0oqTBvlZ7OBIZLMr2+Q==", + "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": { @@ -2562,16 +2812,12 @@ } }, "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, + "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": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8.0" } }, "node_modules/esm": { @@ -2600,9 +2846,9 @@ } }, "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "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" @@ -2653,12 +2899,12 @@ } }, "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "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.6", + "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" }, "engines": { @@ -2668,6 +2914,18 @@ "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", @@ -2717,6 +2975,16 @@ "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", @@ -2761,12 +3029,12 @@ } }, "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==", + "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": ">=8" + "node": ">=4" } }, "node_modules/hasown": { @@ -2830,9 +3098,9 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "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" @@ -2953,6 +3221,54 @@ "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", @@ -3024,15 +3340,15 @@ } }, "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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": ">=6" + "node": ">=4" } }, "node_modules/json5": { @@ -3086,13 +3402,92 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "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", @@ -3103,41 +3498,14 @@ } }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "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/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.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "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", @@ -3161,9 +3529,9 @@ } }, "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "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": { @@ -3196,16 +3564,27 @@ "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==", + "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": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "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": { @@ -3224,35 +3603,6 @@ "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", @@ -3260,9 +3610,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "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/normalize-path": { @@ -3387,9 +3737,9 @@ } }, "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "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": { @@ -3397,6 +3747,8 @@ "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" }, @@ -3474,15 +3826,15 @@ } }, "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "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.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", + "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" }, @@ -3490,34 +3842,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.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "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": "~3.0.2" + "jsesc": "~0.5.0" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "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", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "bin": { "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" } }, "node_modules/require-directory": { @@ -3530,32 +3872,29 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "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.16.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/rollup": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz", - "integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==", + "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.7" + "@types/estree": "1.0.5" }, "bin": { "rollup": "dist/bin/rollup" @@ -3565,26 +3904,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.40.0", - "@rollup/rollup-android-arm64": "4.40.0", - "@rollup/rollup-darwin-arm64": "4.40.0", - "@rollup/rollup-darwin-x64": "4.40.0", - "@rollup/rollup-freebsd-arm64": "4.40.0", - "@rollup/rollup-freebsd-x64": "4.40.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.40.0", - "@rollup/rollup-linux-arm-musleabihf": "4.40.0", - "@rollup/rollup-linux-arm64-gnu": "4.40.0", - "@rollup/rollup-linux-arm64-musl": "4.40.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.40.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.40.0", - "@rollup/rollup-linux-riscv64-gnu": "4.40.0", - "@rollup/rollup-linux-riscv64-musl": "4.40.0", - "@rollup/rollup-linux-s390x-gnu": "4.40.0", - "@rollup/rollup-linux-x64-gnu": "4.40.0", - "@rollup/rollup-linux-x64-musl": "4.40.0", - "@rollup/rollup-win32-arm64-msvc": "4.40.0", - "@rollup/rollup-win32-ia32-msvc": "4.40.0", - "@rollup/rollup-win32-x64-msvc": "4.40.0", + "@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" } }, @@ -3619,6 +3954,12 @@ "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", @@ -3680,18 +4021,6 @@ "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", @@ -3776,15 +4105,15 @@ } }, "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==", + "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": "^4.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -3799,53 +4128,13 @@ "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" - }, + "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": ">=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": ">=4" } }, "node_modules/to-regex-range": { @@ -3902,9 +4191,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "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", @@ -3921,8 +4210,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -4002,6 +4291,72 @@ "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==", + "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==", + "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==", + "license": "MIT" + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4025,30 +4380,32 @@ "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "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": "^8.0.1", + "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^4.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=12" + "node": ">=10" } }, "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==", + "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": ">=12" + "node": ">=10" } }, "node_modules/yargs-unparser": { diff --git a/common/package.json b/common/package.json index a368ef5..9ef203c 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": "src/index.mjs", + "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs", "scripts": { "build": "rollup --config rollup.config.mjs", "test": "c8 mocha test/**/*.mjs" @@ -24,12 +24,9 @@ }, "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", - "chai-spies": "^1.1.0", "esm": "^3.2.25", "mocha": "^10.7.3" } diff --git a/common/rollup.config.mjs b/common/rollup.config.mjs index 5c4d38a..6a18a41 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-2025 Ad5001 + * 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 @@ -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/Common/index.mjs" +const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs" export default { input: src, diff --git a/common/src/events.mjs b/common/src/events.mjs deleted file mode 100644 index 1ef3777..0000000 --- a/common/src/events.mjs +++ /dev/null @@ -1,116 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 { - ___name = "" - - /** - * @property {string} name - Name of the event. - */ - constructor(name) { - this.___name = name - } - - get name() { - return this.___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. - */ - on(eventType, eventListener) { - if(eventType.includes(" ")) // Listen to several different events with the same listener. - for(const type of eventType.split(" ")) - this.on(type, 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}`) - } - if(!this.#listeners[eventType].has(eventListener)) - this.#listeners[eventType].add(eventListener) - } - } - - /** - * 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(eventType.includes(" ")) { // Unlisten to several different events with the same listener. - let found = false - for(const type of eventType.split(" ")) - found ||= this.off(type, eventListener) - return found - } 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) - } - } - - /** - * 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.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/history/color.mjs b/common/src/history/color.mjs index 0efa29d..1d395ed 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-2025 Ad5001 + * 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 diff --git a/common/src/history/common.mjs b/common/src/history/common.mjs index 8c46757..33f9118 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-2025 Ad5001 + * 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 @@ -95,15 +95,11 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") const imgDepth = History.imageDepth - const renderArguments = [ + const { source, width, height } = await Latex.requestAsyncRender( 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/history/create.mjs b/common/src/history/create.mjs index fb27f62..1308d9e 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-2025 Ad5001 + * 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 diff --git a/common/src/history/delete.mjs b/common/src/history/delete.mjs index 2f8d8fe..f9674c5 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-2025 Ad5001 + * 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 diff --git a/common/src/history/editproperty.mjs b/common/src/history/editproperty.mjs index 2a81e7a..886f100 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-2025 Ad5001 + * 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 diff --git a/common/src/history/index.mjs b/common/src/history/index.mjs index a2ef1ea..aa57307 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-2025 Ad5001 + * 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 diff --git a/common/src/history/name.mjs b/common/src/history/name.mjs index 61bb6b5..5c5b397 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-2025 Ad5001 + * 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 diff --git a/common/src/history/position.mjs b/common/src/history/position.mjs index 2b9c0ff..4c1af60 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-2025 Ad5001 + * 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 @@ -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/index.mjs" +import { escapeHTML } from "../utils.mjs" import { Action } from "./common.mjs" /** diff --git a/common/src/history/visibility.mjs b/common/src/history/visibility.mjs index 9254d67..e911c1b 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-2025 Ad5001 + * 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 diff --git a/common/src/index.mjs b/common/src/index.mjs index 57efb01..c19e2fe 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-2025 Ad5001 + * 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 @@ -18,11 +18,10 @@ import js from "./lib/polyfills/js.mjs" -export * as Utils from "./utils/index.mjs" - +import * as Modules from "./module/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/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs index 45854e8..89831c7 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-2025 Ad5001 + * 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, @@ -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 {ExprEvalExpression} expr + * @param {number} expr * @return {Instruction[]} */ function substitute(tokens, variable, expr) { @@ -171,6 +171,9 @@ 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))) @@ -487,6 +490,18 @@ 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/instruction.mjs b/common/src/lib/expr-eval/instruction.mjs index 9157fea..df0e2d7 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-2025 Ad5001 + * 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, diff --git a/common/src/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs index 98f4539..71a1c95 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-2025 Ad5001 + * 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, @@ -47,7 +47,9 @@ const optionNameMap = { "not": "logical", "?": "conditional", ":": "conditional", + //'=': 'assignment', // Disable assignment "[": "array" + //'()=': 'fndef' // Diable function definition } export class Parser { @@ -107,6 +109,7 @@ export class Parser { and: Polyfill.andOperator, or: Polyfill.orOperator, "in": Polyfill.inOperator, + "=": Polyfill.setVar, "[": Polyfill.arrayIndex } @@ -120,13 +123,18 @@ export class Parser { min: Polyfill.min, max: Polyfill.max, hypot: Math.hypot || Polyfill.hypot, - pyt: 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. @@ -151,6 +159,10 @@ 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/parserstate.mjs b/common/src/lib/expr-eval/parserstate.mjs index d4b3a3b..801c424 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-2025 Ad5001 + * 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, diff --git a/common/src/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs index 65f05c7..9e8e885 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-2025 Ad5001 + * 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, @@ -210,8 +210,9 @@ export function gamma(n) { } export function stringOrArrayLength(s) { - if(Array.isArray(s)) + if(Array.isArray(s)) { return s.length + } return String(s).length } @@ -266,6 +267,11 @@ 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] } @@ -290,6 +296,58 @@ 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/lib/expr-eval/tokens.mjs b/common/src/lib/expr-eval/tokens.mjs index 254d30a..919433c 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-2025 Ad5001 + * 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, @@ -472,7 +472,7 @@ export class TokenStream { this.current = this.newToken(TOP, "==") this.pos++ } else { - return false + this.current = this.newToken(TOP, c) } } else if(c === "!") { if(this.expression.charAt(this.pos + 1) === "=") { diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs index 75d149c..43ed375 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-2025 Ad5001 + * 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 @@ -64,20 +64,10 @@ function arrayFlatMap(callbackFn, thisArg) { * @return {String} */ 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] + let str = this + while(str.includes(from)) + str = str.replace(from, to) + return str } @@ -108,8 +98,8 @@ const polyfills = { [String.prototype, "replaceAll", stringReplaceAll] ], 2022: [ - [Array.prototype, "at", arrayAt], - [String.prototype, "at", arrayAt], + [Array.prototype, "at", notPolyfilled("Array.prototype.at")], + [String.prototype, "at", notPolyfilled("String.prototype.at")], [Object, "hasOwn", notPolyfilled("Object.hasOwn")] ], 2023: [ @@ -119,7 +109,7 @@ const polyfills = { [Array.prototype, "toSpliced", notPolyfilled("Array.prototype.toSpliced")], [Array.prototype, "with", notPolyfilled("Array.prototype.with")] ], - 2025: [ + 2024: [ [Object, "groupBy", notPolyfilled("Object.groupBy")], [Map, "groupBy", notPolyfilled("Map.groupBy")] ] @@ -133,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/lib/polyfills/qt.mjs b/common/src/lib/polyfills/qt.mjs index 0e9a9b5..6559423 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-2025 Ad5001 + * 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 diff --git a/common/src/math/domain.mjs b/common/src/math/domain.mjs index b81e527..48bf8ad 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-2025 Ad5001 + * 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 @@ -24,7 +24,6 @@ import { Expression, executeExpression } from "./expression.mjs" */ export class Domain { constructor() { - this.latexMarkup = "#INVALID" } /** @@ -207,8 +206,8 @@ export class Range extends Domain { } includes(x) { - if(typeof x == "string") x = executeExpression(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())) } @@ -250,17 +249,15 @@ 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, latexMarkup, isValid, next = () => true, previous = () => true, + constructor(displayName, isValid, next = () => true, previous = () => true, moveSupported = true) { super() this.displayName = displayName - this.latexMarkup = latexMarkup this.isValid = isValid this.nextValue = next this.prevValue = previous @@ -565,54 +562,39 @@ 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( - "ℕ", "\\mathbb{N}", - 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.NE = new SpecialDomain( - "ℕ*", "\\mathbb{N}^{*}", - x => x % 1 === 0 && x > 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.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.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.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.ZM = new SpecialDomain( - "ℤ⁻", "\\mathbb{Z}^{-}", - x => x % 1 === 0 && x <= 0, + 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.ZME = new SpecialDomain( - "ℤ⁻*", "\\mathbb{Z}^{-*}", - x => x % 1 === 0 && x < 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.NLog = new SpecialDomain( - "ℕˡᵒᵍ", "\\mathbb{N}^{log}", + x => Math.min(Math.ceil(x) - 1, -1)) +Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" +Domain.NLog = new SpecialDomain("ℕˡᵒᵍ", x => x / Math.pow(10, Math.ceil(Math.log10(x))) % 1 === 0 && x > 0, - x => { + function(x) { let x10pow = Math.pow(10, Math.ceil(Math.log10(x))) return Math.max(1, (Math.floor(x / x10pow) + 1) * x10pow) }, - x => { + function(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 = [] @@ -644,7 +626,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.at(0) === "{" && domain.at(-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) diff --git a/common/src/math/expression.mjs b/common/src/math/expression.mjs index 2502110..2862183 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-2025 Ad5001 + * 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 @@ -17,38 +17,28 @@ */ -import * as Utils from "../utils/index.mjs" -import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs" +import * as Utils from "../utils.mjs" import Latex from "../module/latex.mjs" import ExprParser from "../module/expreval.mjs" import Objects from "../module/objects.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 if(expr instanceof ExprEvalExpression) { + } else { // 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.canBeCached = this.isConstant() + this.cached = this.isConstant() this.cachedValue = null - if(this.canBeCached && this.allRequirementsFulfilled()) - this.recache() + if(this.cached && this.allRequirementsFulfilled()) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -87,20 +77,21 @@ export class Expression { /** * Returns a list of names whose corresponding objects this expression is dependant on and are missing. - * @return {string[]} + * @return {boolean} */ undefinedVariables() { return this.requiredObjects().filter(objName => !(objName in Objects.currentObjectsByName)) } recache() { - this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) + if(this.cached) + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) } execute(x = 1) { - if(this.canBeCached) { + if(this.cached) { if(this.cachedValue == null) - this.recache() + this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName) return this.cachedValue } ExprParser.currentVars = Object.assign({ "x": x }, Objects.currentObjectsByName) @@ -108,10 +99,9 @@ export class Expression { } simplify(x) { - let expr = new Expression(this.calc.substitute("x", x).simplify()) - if(expr.allRequirementsFulfilled() && expr.execute() === 0) - expr = new Expression("0") - return expr + let expr = this.calc.substitute("x", x).simplify() + if(expr.evaluate() === 0) expr = "0" + return new Expression(expr) } toEditableString() { @@ -120,28 +110,17 @@ export class Expression { toString(forceSign = false) { let str = Utils.makeExpressionReadable(this.calc.toString()) - 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) { + if(str !== undefined && str.match(/^\d*\.\d+$/)) { + if(str.split(".")[1].split("0").length > 7) { // Likely rounding error - str = parseFloat(str).toDecimalPrecision(8).toString() + str = parseFloat(str.substring(0, str.length - 1)).toString() } } - if(str[0] === "(" && str.at(-1) === ")") - str = str.substring(1, str.length - 1) - if(str[0] !== "-" && forceSign) - str = "+" + str + 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/math/index.mjs b/common/src/math/index.mjs index c517958..27be49e 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-2025 Ad5001 + * 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 diff --git a/common/src/math/sequence.mjs b/common/src/math/sequence.mjs index 6049e53..5394237 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-2025 Ad5001 + * 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 @@ -17,7 +17,7 @@ */ import * as Expr from "./expression.mjs" -import * as Utils from "../utils/index.mjs" +import * as Utils from "../utils.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 1137ae5..e623034 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-2025 Ad5001 + * 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 @@ -18,33 +18,30 @@ import { Module } from "./common.mjs" import { CanvasInterface, DialogInterface } from "./interface.mjs" -import { textsup } from "../utils/index.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" -import Settings from "./settings.mjs" - class CanvasAPI extends Module { - - - /** @type {CanvasInterface} */ - #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 {CanvasInterface} */ + this._canvas = null + + /** @type {CanvasRenderingContext2D} */ + this._ctx = null + + /** + * @type {{show(string, string, string)}} + * @private + */ + this._drawingErrorDialog = null /** * * @type {Object.} @@ -70,18 +67,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 } /** @@ -90,7 +87,7 @@ class CanvasAPI extends Module { */ get xmin() { if(!this.initialized) throw new Error("Attempting xmin before initialize!") - return Settings.xmin + return this._canvas.xmin } /** @@ -99,7 +96,7 @@ class CanvasAPI extends Module { */ get xzoom() { if(!this.initialized) throw new Error("Attempting xzoom before initialize!") - return Settings.xzoom + return this._canvas.xzoom } /** @@ -108,7 +105,7 @@ class CanvasAPI extends Module { */ get ymax() { if(!this.initialized) throw new Error("Attempting ymax before initialize!") - return Settings.ymax + return this._canvas.ymax } /** @@ -117,7 +114,7 @@ class CanvasAPI extends Module { */ get yzoom() { if(!this.initialized) throw new Error("Attempting yzoom before initialize!") - return Settings.yzoom + return this._canvas.yzoom } /** @@ -126,7 +123,7 @@ class CanvasAPI extends Module { */ get xlabel() { if(!this.initialized) throw new Error("Attempting xlabel before initialize!") - return Settings.xlabel + return this._canvas.xlabel } /** @@ -135,7 +132,7 @@ class CanvasAPI extends Module { */ get ylabel() { if(!this.initialized) throw new Error("Attempting ylabel before initialize!") - return Settings.ylabel + return this._canvas.ylabel } /** @@ -144,7 +141,7 @@ class CanvasAPI extends Module { */ get linewidth() { if(!this.initialized) throw new Error("Attempting linewidth before initialize!") - return Settings.linewidth + return this._canvas.linewidth } /** @@ -153,7 +150,7 @@ class CanvasAPI extends Module { */ get textsize() { if(!this.initialized) throw new Error("Attempting textsize before initialize!") - return Settings.textsize + return this._canvas.textsize } /** @@ -162,7 +159,7 @@ class CanvasAPI extends Module { */ get logscalex() { if(!this.initialized) throw new Error("Attempting logscalex before initialize!") - return Settings.logscalex + return this._canvas.logscalex } /** @@ -171,7 +168,7 @@ class CanvasAPI extends Module { */ get showxgrad() { if(!this.initialized) throw new Error("Attempting showxgrad before initialize!") - return Settings.showxgrad + return this._canvas.showxgrad } /** @@ -180,7 +177,7 @@ class CanvasAPI extends Module { */ get showygrad() { if(!this.initialized) throw new Error("Attempting showygrad before initialize!") - return Settings.showygrad + return this._canvas.showygrad } /** @@ -204,7 +201,7 @@ class CanvasAPI extends Module { requestPaint() { if(!this.initialized) throw new Error("Attempting requestPaint before initialize!") - this.#canvas.requestPaint() + this._canvas.requestPaint() } /** @@ -212,19 +209,17 @@ 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() 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) @@ -232,12 +227,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 } /** @@ -245,9 +240,9 @@ class CanvasAPI extends Module { * @private */ _computeAxes() { - let exprY = new Expression(`x*(${Settings.yaxisstep})`) + let exprY = new Expression(`x*(${this._canvas.yaxisstep})`) let y1 = exprY.execute(1) - let exprX = new Expression(`x*(${Settings.xaxisstep})`) + let exprX = new Expression(`x*(${this._canvas.xaxisstep})`) let x1 = exprX.execute(1) this.axesSteps = { x: { @@ -269,10 +264,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) } /** @@ -280,7 +275,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++) { @@ -304,7 +299,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) @@ -325,19 +320,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))) } @@ -355,13 +350,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" } // @@ -399,7 +394,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)) }) } } @@ -414,8 +409,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) } /** @@ -429,7 +424,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 } } @@ -499,10 +494,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() } /** @@ -514,9 +509,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([]) } /** @@ -526,22 +521,14 @@ 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)) { + 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(() => { - if(this.#redrawCount === currentRedrawCount) - callback(imgData) - else - console.log("1. Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) - }) + this._canvas.loadImage(imgData.source) + this._canvas.imageLoaders[imgData.source] = [callback, imgData] } else { // Callback directly - if(this.#redrawCount === currentRedrawCount) - callback(imgData) - else - console.log("2. Discard render of", imgData.source, this.#redrawCount, currentRedrawCount) + callback(imgData) } } const prerendered = Latex.findPrerendered(ltxText, this.textsize, color) @@ -556,11 +543,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 } /** @@ -573,9 +560,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() } /** @@ -585,9 +572,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() } /** @@ -598,7 +585,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 f5fa8aa..b757f14 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-2025 Ad5001 + * 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 @@ -17,7 +17,6 @@ */ import { Interface } from "./interface.mjs" -import { BaseEventEmitter } from "../events.mjs" // Define Modules interface before they are imported. globalThis.Modules = globalThis.Modules || {} @@ -25,13 +24,7 @@ globalThis.Modules = globalThis.Modules || {} /** * Base class for global APIs in runtime. */ -export class Module extends BaseEventEmitter { - /** @type {string} */ - #name - /** @type {Object.} */ - #initializationParameters - /** @type {boolean} */ - #initialized = false +export class Module { /** * @@ -39,18 +32,11 @@ export class Module extends BaseEventEmitter { * @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 - } + this.__name = name + this.__initializationParameters = initializationParameters + this.initialized = false - get name() { - return this.#name; - } - - get initialized() { - return this.#initialized } /** @@ -58,17 +44,17 @@ export class Module extends BaseEventEmitter { * @param {Object.} options */ 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(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.`) + throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`) if(typeof value === "function" && value.prototype instanceof Interface) - Interface.checkImplementation(value, options[name]) + 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 + this.initialized = true } } diff --git a/common/src/module/expreval.mjs b/common/src/module/expreval.mjs index dd89f4d..854f928 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-2025 Ad5001 + * 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 @@ -19,7 +19,7 @@ import { Module } from "./common.mjs" import { Parser } from "../lib/expr-eval/parser.mjs" -const EVAL_VARIABLES = { +const evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually "pi": Math.PI, "PI": Math.PI, @@ -35,17 +35,15 @@ const EVAL_VARIABLES = { } 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, EVAL_VARIABLES) + 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) } /** @@ -70,7 +68,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 @@ -81,14 +79,14 @@ class ExprParserAPI extends Module { * @returns {ExprEvalExpression} */ parse(expression) { - return this.#parser.parse(expression) + return this._parser.parse(expression) } - integral(a = null, b = null, ...args) { + integral(a, b, ...args) { let usage1 = qsTranslate("usage", "integral(, , )") let usage2 = qsTranslate("usage", "integral(, , , )") let f = this.parseArgumentsForFunction(args, usage1, usage2) - if(typeof a !== "number" || typeof b !== "number") + if(a == null || b == null) throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) // https://en.wikipedia.org/wiki/Simpson%27s_rule @@ -101,10 +99,10 @@ class ExprParserAPI extends Module { let usage2 = qsTranslate("usage", "derivative(, , )") let x = args.pop() let f = this.parseArgumentsForFunction(args, usage1, usage2) - if(typeof x !== "number") + if(x == null) throw EvalError(qsTranslate("usage", "Usage:\n%1\n%2").arg(usage1).arg(usage2)) - let derivative_precision = 1e-8 + let derivative_precision = x / 10 return (f(x + derivative_precision / 2) - f(x - derivative_precision / 2)) / derivative_precision } } diff --git a/common/src/module/history.mjs b/common/src/module/history.mjs index 45a37f0..8cd3f60 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-2025 Ad5001 + * 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 @@ -17,164 +17,60 @@ */ import { Module } from "./common.mjs" -import { HelperInterface, NUMBER, STRING } from "./interface.mjs" -import { BaseEvent } from "../events.mjs" -import { Action, Actions } from "../history/index.mjs" +import { HistoryInterface, NUMBER, STRING } from "./interface.mjs" - -class ClearedEvent extends BaseEvent { - constructor() { - super("cleared") - } -} - -class LoadedEvent extends BaseEvent { - constructor() { - super("loaded") - } -} - -class AddedEvent extends BaseEvent { - constructor(action) { - super("added") - this.action = action - } -} - -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 = ["cleared", "loaded", "added", "undone", "redone"] - - #helper - constructor() { super("History", { - helper: HelperInterface, + historyObj: HistoryInterface, themeTextColor: STRING, imageDepth: NUMBER, fontSize: NUMBER }) // History QML object - /** @type {Action[]} */ - this.undoStack = [] - /** @type {Action[]} */ - this.redoStack = [] - + this.history = null this.themeTextColor = "#FF0000" this.imageDepth = 2 this.fontSize = 28 } - /** - * @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 + initialize({ historyObj, themeTextColor, imageDepth, fontSize }) { + super.initialize({ historyObj, themeTextColor, imageDepth, fontSize }) + this.history = historyObj 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!") - if(this.undoStack.length > 0) { - const action = this.undoStack.pop() - action.undo() - this.redoStack.push(action) - this.emit(new UndoneEvent(action)) - } + this.history.undo() } - /** - * 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!") - if(this.redoStack.length > 0) { - const action = this.redoStack.pop() - action.redo() - this.undoStack.push(action) - this.emit(new RedoneEvent(action)) - } + this.history.redo() } - /** - * Clears both undo and redo stacks completely. - */ clear() { if(!this.initialized) throw new Error("Attempting clear before initialize!") - this.undoStack = [] - this.redoStack = [] - this.emit(new ClearedEvent()) + this.history.clear() } - /** - * Adds an instance of HistoryLib.Action to history. - * @param action - */ addToHistory(action) { if(!this.initialized) throw new Error("Attempting addToHistory before initialize!") - if(action instanceof Action) { - console.log("Added new entry to history: " + action.getReadableString()) - this.undoStack.push(action) - if(this.#helper.getSetting("reset_redo_stack")) - this.redoStack = [] - this.emit(new AddedEvent(action)) - } + this.history.addToHistory(action) } - /** - * Unserializes both the undo stack and redo stack from serialized content. - * @param {[string, any[]][]} undoSt - * @param {[string, any[]][]} redoSt - */ - unserialize(undoSt, redoSt) { + unserialize(...data) { if(!this.initialized) throw new Error("Attempting unserialize before initialize!") - 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 LoadedEvent()) + this.history.unserialize(...data) } - /** - * Serializes history into JSON-able content. - * @return {[[string, any[]], [string, any[]]]} - */ serialize() { if(!this.initialized) throw new Error("Attempting serialize before initialize!") - 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] + return this.history.serialize() } } diff --git a/common/src/module/index.mjs b/common/src/module/index.mjs index 6fdff97..fe2e8d9 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-2025 Ad5001 + * 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 @@ -17,7 +17,6 @@ */ 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" @@ -27,7 +26,6 @@ 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 6947acd..9273c8f 100644 --- a/common/src/module/interface.mjs +++ b/common/src/module/interface.mjs @@ -1,9 +1,9 @@ -/** +/*! * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * * @author Ad5001 * @license GPL-3.0-or-later - * @copyright (C) 2021-2025 Ad5001 + * @copyright (C) 2021-2024 Ad5001 * @preserve * * This program is free software: you can redistribute it and/or modify @@ -35,8 +35,9 @@ 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 checkImplementation(interface_, classToCheck) { + static check_implementation(interface_, classToCheck) { const properties = new interface_() const interfaceName = interface_.name const toCheckName = classToCheck.constructor.name @@ -51,7 +52,7 @@ export class Interface { else if((typeof value) === "object") // Test type of object. if(value instanceof Interface) - Interface.checkImplementation(value, classToCheck[property]) + 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}'.`) } @@ -59,13 +60,32 @@ export class Interface { } -export class CanvasInterface extends 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 SettingsInterface { + imageLoaders = OBJECT /** @type {function(string): CanvasRenderingContext2D} */ getContext = FUNCTION /** @type {function(rect)} */ markDirty = FUNCTION - /** @type {function(string): Promise} */ - loadImageAsync = FUNCTION + /** @type {function(string)} */ + loadImage = FUNCTION /** @type {function(string)} */ isImageLoading = FUNCTION /** @type {function(string)} */ @@ -77,28 +97,30 @@ export class CanvasInterface extends Interface { export class RootInterface extends Interface { width = NUMBER height = NUMBER + updateObjectsLists = FUNCTION } 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 { - 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) */ - 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 + render = FUNCTION /** * @param {string} markup - LaTeX markup to render * @param {number} fontSize - Font size (in pt) to render @@ -117,13 +139,37 @@ 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 {string|number|boolean} Value of the setting + * @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 {string|number|boolean} value + * @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 /** @@ -138,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/io.mjs b/common/src/module/io.mjs index 4887954..b6d40f5 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-2025 Ad5001 + * 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 @@ -19,69 +19,36 @@ import { Module } from "./common.mjs" import Objects from "./objects.mjs" import History from "./history.mjs" -import Settings from "./settings.mjs" -import { DialogInterface, RootInterface } from "./interface.mjs" -import { BaseEvent } from "../events.mjs" +import Canvas from "./canvas.mjs" +import { DialogInterface, RootInterface, SettingsInterface } from "./interface.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 + root: RootInterface, + settings: SettingsInterface }) - - // Settings.on("changed", this.__emitModified.bind(this)) - History.on("added undone redone", this.__emitModified.bind(this)) + /** + * Path of the currently opened file. Empty if no file is opened. + * @type {string} + */ + this.saveFileName = "" } - __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 + * @param {SettingsInterface} settings * @param {{show: function(string)}} alert */ - initialize({ root, alert }) { - super.initialize({ root, alert }) - this.#rootElement = root - this.#alert = alert + initialize({ root, settings, alert }) { + super.initialize({ root, settings, alert }) + this.rootElement = root + this.settings = settings + this.alert = alert } /** @@ -93,7 +60,7 @@ class IOAPI extends Module { // Add extension if necessary if(["lpf"].indexOf(filename.split(".")[filename.split(".").length - 1]) === -1) filename += ".lpf" - Settings.set("saveFilename", filename, false) + this.saveFilename = filename let objs = {} for(let objType in Objects.currentObjects) { objs[objType] = [] @@ -102,29 +69,28 @@ class IOAPI extends Module { } } let settings = { - "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, + "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.#saved = true - this.emit(new SavedEvent()) + this.alert.show(qsTranslate("io", "Saved plot to '%1'.").arg(filename.split("/").pop())) + History.history.saved = true } /** @@ -135,32 +101,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 - 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) + 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) - Settings.set("showxgrad", data["showxgrad"], false) + this.settings.showxgrad = data["showxgrad"] if("showygrad" in data) - Settings.set("showygrad", data["showygrad"], false) + this.settings.textsize = data["showygrad"] if("linewidth" in data) - Settings.set("linewidth", data["linewidth"], false) + this.settings.linewidth = data["linewidth"] if("textsize" in data) - Settings.set("textsize", data["textsize"], false) - 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 = {} @@ -191,18 +157,20 @@ class IOAPI extends Module { if("history" in data) 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 load file: ") + error) + this.alert.show(qsTranslate("io", "Could not load file: ") + error) // TODO: Error handling return } - this.#alert.show(qsTranslate("io", "Loaded file '%1'.").arg(basename)) - this.#saved = true - this.emit(new LoadedEvent()) + Canvas.redraw() + 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 27fbdd4..8740160 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-2025 Ad5001 + * 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 @@ -17,12 +17,11 @@ */ 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" -const unicodechars = ["pi", "∞", +const unicodechars = [ "α", "β", "γ", "δ", "ε", "ζ", "η", "π", "θ", "κ", "λ", "μ", "ξ", "ρ", "ς", "σ", "τ", "φ", "χ", "ψ", "ω", @@ -31,9 +30,9 @@ const unicodechars = ["pi", "∞", "ₕ", "ₖ", "ₗ", "ₘ", "ₙ", "ₚ", "ₛ", "ₜ", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃", - "₄", "₅", "₆", "₇", "₈", "₉", "₀" -] -const equivalchars = ["\\pi", "\\infty", + "₄", "₅", "₆", "₇", "₈", "₉", "₀", + "pi", "∞"] +const equivalchars = [ "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta", "\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho", "\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega", @@ -43,29 +42,7 @@ const equivalchars = ["\\pi", "\\infty", "{}_{t}", "{}^{1}", "{}^{2}", "{}^{3}", "{}^{4}", "{}^{5}", "{}^{6}", "{}^{7}", "{}^{8}", "{}^{9}", "{}^{0}", "{}_{1}", "{}_{2}", "{}_{3}", "{}_{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 - } -} + "\\pi", "\\infty"] /** * Class containing the result of a LaTeX render. @@ -83,11 +60,6 @@ class LatexRenderResult { } class LatexAPI extends Module { - static emits = ["async-render-started", "async-render-finished"] - - /** @type {LatexInterface} */ - #latex = null - constructor() { super("Latex", { latex: LatexInterface, @@ -97,7 +69,6 @@ class LatexAPI extends Module { * true if latex has been enabled by the user, false otherwise. */ this.enabled = false - this.promises = new Set() } /** @@ -106,8 +77,9 @@ class LatexAPI extends Module { */ initialize({ latex, helper }) { super.initialize({ latex, helper }) - this.#latex = latex - this.enabled = helper.getSetting("enable_latex") + this.latex = latex + this.helper = helper + this.enabled = helper.getSettingBool("enable_latex") } /** @@ -121,7 +93,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(",")) @@ -138,19 +110,7 @@ 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) { - this.emit(new AsyncRenderStartedEvent(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) - } - const args = render.split(",") + let args = this.latex.render(markup, fontSize, color).split(",") return new LatexRenderResult(...args) } @@ -175,10 +135,9 @@ class LatexAPI extends Module { */ parif(elem, contents) { elem = elem.toString() - const contains = contents.some(x => elem.indexOf(x) > 0) - if(contains && (elem[0] !== "(" || elem.at(-1) !== ")")) + if(elem[0] !== "(" && elem[elem.length - 1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) return this.par(elem) - if(!contains && elem[0] === "(" && elem.at(-1) === ")") + if(elem[0] === "(" && elem[elem.length - 1] === ")") return elem.removeEnclosure() return elem } @@ -196,21 +155,20 @@ 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}(${args[1]})` + return `\\frac{d${args[0]}}{dx}(x)` case "integral": if(args.length === 4) 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` case "sqrt": - const arg = this.parif(args.join(", "), []) - return `\\sqrt{${arg}}` + return `\\sqrt\\left(${args.join(", ")}\\right)` 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)` } @@ -224,17 +182,16 @@ 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 } @@ -302,7 +259,7 @@ class LatexAPI extends Module { throw new EvalError("Unknown operator " + item.value + ".") } break - case Instruction.IOP3: // Ternary operator + case Instruction.IOP3: // Thirdiary operator n3 = nstack.pop() n2 = nstack.pop() n1 = nstack.pop() @@ -329,7 +286,7 @@ class LatexAPI extends Module { nstack.push(this.parif(n1, ["+", "-", "*", "/", "^"]) + "!") break default: - nstack.push(this.functionToLatex(f, [this.parif(n1, ["+", "-", "*", "/", "^"])])) + nstack.push(f + this.parif(n1, ["+", "-", "*", "/", "^"])) break } break @@ -364,6 +321,9 @@ class LatexAPI extends Module { throw new EvalError("invalid Expression") } } + if(nstack.length > 1) { + nstack = [nstack.join(";")] + } return String(nstack[0]) } } diff --git a/common/src/module/objects.mjs b/common/src/module/objects.mjs index e98a15f..a95dc89 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-2025 Ad5001 + * 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 @@ -17,17 +17,13 @@ */ import { Module } from "./common.mjs" -import { textsub } from "../utils/index.mjs" +import { textsub } from "../utils.mjs" class ObjectsAPI extends Module { constructor() { super("Objects") - /** - * List of object constructors. - * @type {Object.} - */ this.types = {} /** * List of objects for each type of object. @@ -69,7 +65,7 @@ class ObjectsAPI extends Module { * @param {string} newName - Name to rename the object to. */ renameObject(oldName, newName) { - const obj = this.currentObjectsByName[oldName] + let obj = this.currentObjectsByName[oldName] delete this.currentObjectsByName[oldName] this.currentObjectsByName[newName] = obj obj.name = newName @@ -80,7 +76,7 @@ class ObjectsAPI extends Module { * @param {string} objName - Current name of the object. */ deleteObject(objName) { - const obj = this.currentObjectsByName[objName] + let 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/preferences.mjs b/common/src/module/preferences.mjs index 5d20f92..afb795e 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-2025 Ad5001 + * 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 @@ -20,9 +20,6 @@ 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") diff --git a/common/src/module/settings.mjs b/common/src/module/settings.mjs deleted file mode 100644 index c740383..0000000 --- a/common/src/module/settings.mjs +++ /dev/null @@ -1,186 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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" -import { HelperInterface } from "./interface.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"] - - #nonConfigurable = ["saveFilename"] - - /** @type {Map} */ - #properties = new Map([ - ["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() { - super("Settings", { - helper: HelperInterface - }) - } - - /** - * - * @param {HelperInterface} helper - */ - initialize({ helper }) { - super.initialize({ helper }) - // Initialize default values. - for(const key of this.#properties.keys()) - if(!this.#nonConfigurable.includes(key)) - this.set(key, helper.getSetting("default_graph."+key), false) - } - - /** - * Sets a setting to a given value - * - * @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)) - throw new Error(`Property ${property} is not a setting.`) - const oldValue = this.#properties.get(property) - 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) - const evt = new ChangedEvent(property, oldValue, value, byUser === true) - this.emit(evt) - } - - /** - * 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} - */ - 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") } -} - -Modules.Settings = Modules.Settings || new SettingsAPI() -export default Modules.Settings - diff --git a/common/src/objs/autoload.mjs b/common/src/objs/autoload.mjs index 7ecac04..26a6003 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/bodemagnitude.mjs b/common/src/objs/bodemagnitude.mjs index 4dbcd28..82d9728 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/bodemagnitudesum.mjs b/common/src/objs/bodemagnitudesum.mjs index 701a4b9..eb81663 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/bodephase.mjs b/common/src/objs/bodephase.mjs index 75776b1..9c93bba 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-2025 Ad5001 + * 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 @@ -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.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/common/src/objs/bodephasesum.mjs b/common/src/objs/bodephasesum.mjs index 55b3b6c..90864d7 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/common.mjs b/common/src/objs/common.mjs index 602856a..891fdd5 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-2025 Ad5001 + * 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 @@ -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 @@ -224,7 +224,7 @@ export class DrawableObject { currentObjectsByName[objName].requiredBy.push(this) } } - if(this[property].canBeCached && this[property].requiredObjects().length > 0) + if(this[property].cached && this[property].requiredObjects().length > 0) // Recalculate this[property].recache() diff --git a/common/src/objs/distribution.mjs b/common/src/objs/distribution.mjs index b63717c..16aa4d4 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/function.mjs b/common/src/objs/function.mjs index fec90ac..1e345cb 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-2025 Ad5001 + * 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 @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { textsub } from "../utils/index.mjs" +import { textsub } from "../utils.mjs" import Objects from "../module/objects.mjs" import { ExecutableObject } from "./common.mjs" import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs" @@ -122,9 +122,7 @@ export default class Function extends ExecutableObject { */ static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { let pxprecision = 10 - const startDrawFrom = canvas.x2px(1)%pxprecision-pxprecision - let previousX = canvas.px2x(startDrawFrom) - // console.log("Starting draw from", previousX, startDrawFrom, canvas.x2px(1)) + let previousX = canvas.px2x(0) let previousY = null if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) { // Point based functions. @@ -162,7 +160,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-pxprecision < canvas.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. @@ -171,7 +169,7 @@ export default class Function extends ExecutableObject { do { tmpPx++ previousX = canvas.px2x(tmpPx) - } while(!definitionDomain.includes(previousX) && currentX > previousX) + } while(!definitionDomain.includes(previousX)) // Recaclulate previousY previousY = expr.execute(previousX) } else if(!definitionDomain.includes(currentX)) { @@ -181,7 +179,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)) diff --git a/common/src/objs/point.mjs b/common/src/objs/point.mjs index 841308e..d179481 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/sequence.mjs b/common/src/objs/sequence.mjs index b424ac0..0328041 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/text.mjs b/common/src/objs/text.mjs index f4dd993..af79824 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-2025 Ad5001 + * 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 diff --git a/common/src/objs/xcursor.mjs b/common/src/objs/xcursor.mjs index 63fd182..11f6a5a 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-2025 Ad5001 + * 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 @@ -78,7 +78,7 @@ export default class XCursor extends DrawableObject { if(this.approximate) { approx = (this.targetElement.execute(this.x.execute())) let intLength = Math.round(approx).toString().length - let rounding = Math.max(0, Math.min(this.rounding, approx.toString().length - intLength - 1)) + let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1) approx = approx.toPrecision(rounding + intLength) } return approx diff --git a/common/src/parameters.mjs b/common/src/parameters.mjs index 755d4aa..1078518 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-2025 Ad5001 + * 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 @@ -377,4 +377,4 @@ export function serializesByPropertyType(propertyType, value) { } else throw new TypeError(`Exportation error: Unknown property type ${propertyType}.`) return result -} +} \ No newline at end of file diff --git a/common/src/parsing/common.mjs b/common/src/parsing/common.mjs index 998f038..72a9a4b 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-2025 Ad5001 + * 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 diff --git a/common/src/parsing/index.mjs b/common/src/parsing/index.mjs index f0fde37..6d0de80 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-2025 Ad5001 + * 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 diff --git a/common/src/parsing/reference.mjs b/common/src/parsing/reference.mjs index 80365aa..36d4c8c 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-2025 Ad5001 + * 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 diff --git a/common/src/parsing/tokenizer.mjs b/common/src/parsing/tokenizer.mjs index 8725bf3..a8552fc 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-2025 Ad5001 + * 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 diff --git a/common/src/preferences/common.mjs b/common/src/preferences/common.mjs index 4e3ecc8..e456dc2 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-2025 Ad5001 + * 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 @@ -53,11 +53,11 @@ export class BoolSetting extends Setting { } value() { - return Helper.getSetting(this.nameInConfig) + return Helper.getSettingBool(this.nameInConfig) } set(value) { - Helper.setSetting(this.nameInConfig, value === true) + Helper.setSettingBool(this.nameInConfig, value) } } @@ -69,11 +69,11 @@ export class NumberSetting extends Setting { } value() { - return Helper.getSetting(this.nameInConfig) + return Helper.getSettingInt(this.nameInConfig) } set(value) { - Helper.setSetting(this.nameInConfig, +value) + Helper.setSettingInt(this.nameInConfig, value) } } @@ -84,11 +84,11 @@ export class EnumIntSetting extends Setting { } value() { - return Helper.getSetting(this.nameInConfig) + return Helper.getSettingInt(this.nameInConfig) } set(value) { - Helper.setSetting(this.nameInConfig, +value) + Helper.setSettingInt(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 c6864d1..0fa9531 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-2025 Ad5001 + * 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 @@ -28,7 +28,7 @@ const XZOOM = new NumberSetting( const YZOOM = new NumberSetting( qsTranslate("Settings", "Y Zoom"), - "default_graph.yzoom", + "default_graph.xzoom", "yzoom", 0.1 ) @@ -37,7 +37,7 @@ const XMIN = new NumberSetting( qsTranslate("Settings", "Min X"), "default_graph.xmin", "xmin", - () => Helper.getSetting("default_graph.logscalex") ? 1e-100 : -Infinity + () => Helper.getSettingBool("default_graph.logscalex") ? 1e-100 : -Infinity ) const YMAX = new NumberSetting( diff --git a/common/src/preferences/expression.mjs b/common/src/preferences/expression.mjs index bda6899..85e1fbe 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-2025 Ad5001 + * 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 diff --git a/common/src/preferences/general.mjs b/common/src/preferences/general.mjs index 093afaf..81c5e3d 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-2025 Ad5001 + * 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 @@ -46,15 +46,8 @@ class EnableLatex extends BoolSetting { } } -const ENABLE_LATEX_ASYNC = new BoolSetting( - qsTranslate("general", "Enable threaded LaTeX renderer (experimental)"), - "enable_latex_threaded", - "new" -) - export default [ CHECK_FOR_UPDATES, RESET_REDO_STACK, - new EnableLatex(), - ENABLE_LATEX_ASYNC + new EnableLatex() ] diff --git a/common/src/utils.mjs b/common/src/utils.mjs new file mode 100644 index 0000000..4f6b0c5 --- /dev/null +++ b/common/src/utils.mjs @@ -0,0 +1,414 @@ +/** + * 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 = 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 = { + "-": "⁻", + "+": "⁺", + "=": "⁼", + " ": " ", + "(": "⁽", + ")": "⁾", + "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 exponentReg = 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 +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] + } + } + return ret +} + +// Put a text in sub position +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] + } + } + return ret +} + +/** + * 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, + // "$1$2 $3 $4 $6 $2 $3 $7$9" + // ], + // [ // Decomposition way 2 + // /(^|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)($| [+-]|\))/g, + // "$1$2 $7 $8 $4 $5 $7 $8$9" + // ], + [ // Factorisation of π elements. + /(([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*) ([+-]) (([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*)?/g, + function(match, m1, n1, pi1, m2, ope2, n2, opeM, m3, n3, pi2, m4, ope4, n4) { + // g1, g2, g3 , g4, g5, g6, g7, g8, g9, g10, g11,g12 , g13 + // We don't care about mx & pix, ope2 & ope4 are either / or * for n2 & n4. + // 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) + + return `${coefficient} * π` + } + ], + [ // Removing parenthesis when content is only added from both sides. + /(^|[+-] |\()\(([^)(]+)\)($| [+-]|\))/g, + 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}`} + ], + [ // Removing parenthesis when content is only multiplied. + /(^|[*\/+-] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, + 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 === '+') { + total = parseFloat(n1) + parseFloat(n2) + } else { + total = parseFloat(n1) - parseFloat(n2) + } + return `${b4}${total} ${op1} ${middle}${after}` + } + ], + [// Simplification multiplications/divisions. + /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, + function(match, n1, op1, middle, op2, n2) { + 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 === '*') { + return `${parseFloat(n1) * parseFloat(n2)} ${op1} ${middle}` + } else { + return `${parseFloat(n1) / parseFloat(n2)} ${op1} ${middle}` + } + } + } + ], + [// Starting & ending parenthesis if not needed. + /^\s*\((.*)\)\s*$/g, + function(match, middle) { + let str = middle + // Replace all groups + while(/\([^)(]+\)/g.test(str)) + 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('(')) { + return middle + } else { + return `(${middle})` + } + + } + ], + // Simple simplifications + // [/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'], + // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], + // [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], + // [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], + // [/(\s|^|\()1(\.0+)? [\*\/] /g, '$1'], + // [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], + // [/ [\*\/] 1(\.0+)?(\s|$|\))/g, '$3'], + // [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], + // [/(^| |\() /g, '$1'], + // [/ ($|\))/g, '$1'], + ] + + // Replacements + let found + do { + found = false + for(let replacement of replacements) + while(replacement[0].test(str)) { + found = true + str = str.replace(replacement[0], replacement[1]) + } + } while(found) + return str +} + + +/** + * 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, '∞'], + // 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'], + [/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) { + return `d(${body.replace(new RegExp(by, 'g'), 'x')})/dx` + }] + ] + + // str = simplifyExpression(str) + // Replacements + for(let replacement of replacements) + while(replacement[0].test(str)) + str = str.replace(replacement[0], replacement[1]) + return str +} + +/** + * 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'], + [/([^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) + str = str.replace(replacement[0], replacement[1]) + return str +} + +/** + * 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") +} + +/** + * 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(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join('')) +} diff --git a/common/src/utils/expression.mjs b/common/src/utils/expression.mjs deleted file mode 100644 index 2caf5ea..0000000 --- a/common/src/utils/expression.mjs +++ /dev/null @@ -1,258 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 { textsub, textsup } from "./subsup.mjs" - -/** - * Simplifies (mathematically) a mathematical expression. - * @deprecated - * @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, - // "$1$2 $3 $4 $6 $2 $3 $7$9" - // ], - // [ // Decomposition way 2 - // /(^|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)($| [+-]|\))/g, - // "$1$2 $7 $8 $4 $5 $7 $8$9" - // ], - [ // Factorisation of π elements. - /(([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*) ([+-]) (([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*)?/g, - function(match, m1, n1, pi1, m2, ope2, n2, opeM, m3, n3, pi2, m4, ope4, n4) { - // g1, g2, g3 , g4, g5, g6, g7, g8, g9, g10, g11,g12 , g13 - // We don't care about mx & pix, ope2 & ope4 are either / or * for n2 & n4. - // 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) - - return `${coefficient} * π` - } - ], - [ // Removing parenthesis when content is only added from both sides. - /(^|[+-] |\()\(([^)(]+)\)($| [+-]|\))/g, - 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}` - } - ], - [ // Removing parenthesis when content is only multiplied. - /(^|[*\/+-] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, - 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 === "+") { - total = parseFloat(n1) + parseFloat(n2) - } else { - total = parseFloat(n1) - parseFloat(n2) - } - return `${b4}${total} ${op1} ${middle}${after}` - } - ], - [// Simplification multiplications/divisions. - /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, - function(match, n1, op1, middle, op2, n2) { - 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 === "*") { - return `${parseFloat(n1) * parseFloat(n2)} ${op1} ${middle}` - } else { - return `${parseFloat(n1) / parseFloat(n2)} ${op1} ${middle}` - } - } - } - ], - [// Starting & ending parenthesis if not needed. - /^\s*\((.*)\)\s*$/g, - function(match, middle) { - let str = middle - // Replace all groups - while(/\([^)(]+\)/g.test(str)) - 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("(")) { - return middle - } else { - return `(${middle})` - } - - } - ] - // Simple simplifications - // [/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'], - // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], - // [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - // [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - // [/(\s|^|\()1(\.0+)? [\*\/] /g, '$1'], - // [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], - // [/ [\*\/] 1(\.0+)?(\s|$|\))/g, '$3'], - // [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], - // [/(^| |\() /g, '$1'], - // [/ ($|\))/g, '$1'], - ] - - // Replacements - let found - do { - found = false - for(let replacement of replacements) - while(replacement[0].test(str)) { - found = true - str = str.replace(replacement[0], replacement[1]) - } - } while(found) - return 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, "∞"], - // 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"], - [/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) { - return `d(${body.replace(new RegExp(by, "g"), "x")})/dx` - }] - ] - - // str = simplifyExpression(str) - // Replacements - for(let replacement of replacements) - while(replacement[0].test(str)) - str = str.replace(replacement[0], replacement[1]) - 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. - * - * @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) { - for(const replacement of replacements) - str = str.replace(replacement[0], replacement[1]) - if(removeUnallowed) - str = str.replace(/[xnπℝℕ\\∪∩\]\[ ()^/÷*×+=\d¹²³⁴⁵⁶⁷⁸⁹⁰-]/g, "") - - return str -} diff --git a/common/src/utils/index.mjs b/common/src/utils/index.mjs deleted file mode 100644 index 2c11c1b..0000000 --- a/common/src/utils/index.mjs +++ /dev/null @@ -1,22 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 deleted file mode 100644 index 50f84f4..0000000 --- a/common/src/utils/other.mjs +++ /dev/null @@ -1,41 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 deleted file mode 100644 index b0fd27f..0000000 --- a/common/src/utils/prototype.mjs +++ /dev/null @@ -1,51 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 deleted file mode 100644 index 6eb4280..0000000 --- a/common/src/utils/subsup.mjs +++ /dev/null @@ -1,140 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/events.mjs b/common/test/basics/events.mjs deleted file mode 100644 index 7dac6e2..0000000 --- a/common/test/basics/events.mjs +++ /dev/null @@ -1,118 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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" - -const { spy } = chaiPlugins - -import { BaseEventEmitter, BaseEvent } from "../../src/events.mjs" - -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 - } -} - -describe("Lib/EventsEmitters", function() { - 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() { - 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("forwards 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.first.called.with.exactly(mockEvent1) - expect(listener).to.have.been.second.called.with.exactly(mockEvent2) - }) - - it("is able to have listeners removed", 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("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() - 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.also.have.been.called.with.exactly(mockEvent2) - }) - - 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) - expect(() => emitter.off("inexistant", listener)).to.throw(Error) - expect(() => emitter.emit(new BaseEvent("inexistant"))).to.throw(Error) - }) - - it("isn't 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/basics/interface.mjs b/common/test/basics/interface.mjs deleted file mode 100644 index 48af62e..0000000 --- a/common/test/basics/interface.mjs +++ /dev/null @@ -1,58 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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("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("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()) - 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/basics/polyfill.mjs b/common/test/basics/polyfill.mjs deleted file mode 100644 index 1fc9599..0000000 --- a/common/test/basics/polyfill.mjs +++ /dev/null @@ -1,232 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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("#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("subtracts two numbers", function() { - expect(Polyfill.sub(2, 1)).to.equal(1) - expect(Polyfill.sub("2", "1")).to.equal(1) - }) - }) - - describe("#mul", 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("divides two numbers", function() { - expect(Polyfill.div(10, 2)).to.equal(5) - expect(Polyfill.div("10", "2")).to.equal(5) - }) - }) - - describe("#mod", 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("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("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 - expect(Polyfill.equal("abc", "abc")).to.be.true - }) - }) - - describe("#notEqual", 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 - expect(Polyfill.notEqual("abc", "abc")).to.be.false - }) - }) - - describe("#greaterThan", 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 - }) - }) - - describe("#lessThan", 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 - }) - }) - - describe("#greaterThanEqual", 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 - }) - }) - - describe("#lessThanEqual", 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 - }) - }) - - describe("#andOperator", 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 - 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("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 - 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("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 - 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("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("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) - 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("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) { - 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/basics/utils.mjs b/common/test/basics/utils.mjs deleted file mode 100644 index 66ecd92..0000000 --- a/common/test/basics/utils.mjs +++ /dev/null @@ -1,183 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/index.mjs" - - -import { describe, it } from "mocha" -import { expect } from "chai" - -describe("Lib/PrototypeExtensions", function() { - describe("#String.toLatinUppercase", 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("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("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") - }) - }) - - describe("#Number.toDecimalPrecision", 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) - 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("Lib/Utils", function() { - describe("#textsup", 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("does not transform characters without a sup equivalent", function() { - expect(textsup("ABCDEFGHIJKLMNOPQRSTUVWXYZq")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZq") - }) - - 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("transforms characters which have a sub unicode equivalent", function() { - expect(textsub("-+=()")).to.equal("₋₊₌₍₎") - expect(textsub("0123456789")).to.equal("₀₁₂₃₄₅₆₇₈₉") - expect(textsub("aehijklmnoprstuvx")).to.equal("ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ") - }) - - it("does not transform characters without a sub equivalent", function() { - expect(textsub("ABCDEFGHIJKLMNOPQRSTUVWXYZ")).to.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ") - expect(textsub("bcdfgqyz")).to.equal("bcdfgqyz") - }) - - 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("parses 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("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("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("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("provides 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("escapes ampersands", function() { - expect(escapeHTML("&")).to.equal("&") - expect(escapeHTML("High & Mighty")).to.equal("High & Mighty") - }) - - 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("transforms exponents to power expression", function() { - expect(exponentsToExpression("x¹²³⁴⁵⁶⁷⁸⁹⁰")).to.equal("x^1234567890") - expect(exponentsToExpression("x¹²+y³⁴")).to.equal("x^12+y^34") - }) - }) -}) diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs index 39a25d7..e48525e 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-2025 Ad5001 + * 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 @@ -15,22 +15,16 @@ * 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 { use } from "chai" -import spies from "chai-spies" -import promised from "chai-as-promised" +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() { - use(promised) - const { spy } = use(spies) - globalThis.Helper = new MockHelper() globalThis.Latex = new MockLatex() - globalThis.chaiPlugins = { spy } + Modules.Latex.initialize({ latex: Latex, helper: Helper }) } setup() diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs index b9161c8..c00384f 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-2025 Ad5001 + * 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 @@ -19,23 +19,10 @@ import { describe, it } from "mocha" import { expect } from "chai" -import { Domain, EmptySet, parseDomainSimple } from "../../src/math/domain.mjs" +import { Domain, 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 @@ -72,37 +59,6 @@ describe("math.domain", function() { 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 - }) + it("") }) }) diff --git a/common/test/math/expression.mjs b/common/test/math/expression.mjs deleted file mode 100644 index 588480c..0000000 --- a/common/test/math/expression.mjs +++ /dev/null @@ -1,181 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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.") - }) - }) -}) diff --git a/common/test/mock/canvas.mjs b/common/test/mock/canvas.mjs deleted file mode 100644 index 82bcbff..0000000 --- a/common/test/mock/canvas.mjs +++ /dev/null @@ -1,59 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 deleted file mode 100644 index ec8628d..0000000 --- a/common/test/mock/dialog.mjs +++ /dev/null @@ -1,23 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/fs.mjs b/common/test/mock/fs.mjs index 7cb00dd..bccb71f 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-2025 Ad5001 + * 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 diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs index 9186947..9f74b64 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-2025 Ad5001 + * 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 @@ -22,8 +22,7 @@ const DEFAULT_SETTINGS = { "check_for_updates": true, "reset_redo_stack": true, "last_install_greet": "0", - "enable_latex": true, - "enable_latex_threaded": true, + "enable_latex": false, "expression_editor": { "autoclose": true, "colorize": true, @@ -54,13 +53,7 @@ export class MockHelper { this.__settings = { ...DEFAULT_SETTINGS } } - - /** - * 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) { + __getSetting(settingName) { const namespace = settingName.split(".") let data = this.__settings for(const name of namespace) @@ -71,12 +64,7 @@ export class MockHelper { return data } - /** - * 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) { + __setSetting(settingName, value) { const namespace = settingName.split(".") const finalName = namespace.pop() let data = this.__settings @@ -88,6 +76,60 @@ 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 @@ -113,4 +155,4 @@ export class MockHelper { throw new Error(`File not found.`) } -} +} \ No newline at end of file diff --git a/common/test/mock/latex.mjs b/common/test/mock/latex.mjs index 54d427d..ab56999 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-2025 Ad5001 + * 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 @@ -22,7 +22,6 @@ const PIXEL = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAA export class MockLatex { constructor() { - this.supportsAsyncRender = true } /** @@ -56,23 +55,13 @@ 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) */ - renderSync(markup, fontSize, color) { + render(markup, fontSize, color) { const file = this.__getFileName(markup, fontSize, color) writeFileSync(file, PIXEL, "base64") return `${file},1,1` @@ -98,4 +87,4 @@ export class MockLatex { checkLatexInstallation() { return true // We're not *actually* doing any latex. } -} +} \ No newline at end of file diff --git a/common/test/mock/qt.mjs b/common/test/mock/qt.mjs index 46f5b3d..50ec349 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-2025 Ad5001 + * 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 @@ -40,17 +40,6 @@ 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 @@ -58,6 +47,8 @@ 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/mock/root.mjs b/common/test/mock/root.mjs deleted file mode 100644 index 0539342..0000000 --- a/common/test/mock/root.mjs +++ /dev/null @@ -1,61 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/common/test/module/base.mjs b/common/test/module/base.mjs deleted file mode 100644 index 0cc73ea..0000000 --- a/common/test/module/base.mjs +++ /dev/null @@ -1,89 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/events.mjs" -import "../basics/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" - -class MockModule extends Module { - constructor() { - super("mock", { - number: NUMBER, - bool: BOOLEAN, - str: STRING, - func: FUNCTION, - dialog: DialogInterface - }) - } -} - -describe("Module/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/module/expreval.mjs b/common/test/module/expreval.mjs deleted file mode 100644 index c04290e..0000000 --- a/common/test/module/expreval.mjs +++ /dev/null @@ -1,389 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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.evaluate", function() { - const evaluate = (expr, vals = {}) => ExprEval.parse(expr).evaluate(vals) - it("parses simple mathematical expressions", function() { - 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) - }) - - it("parses equality and test statements", function() { - 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) - // 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 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) - // 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) - }) - - - 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 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) - 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/module/latex.mjs b/common/test/module/latex.mjs deleted file mode 100644 index 6581850..0000000 --- a/common/test/module/latex.mjs +++ /dev/null @@ -1,231 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 "./base.mjs" -import "./expreval.mjs" - -import { describe, it } from "mocha" -import { expect } from "chai" -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() { - 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("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") - expect(data.source).to.satisfy(existsSync) - expect(data.height).to.be.a("number") - expect(data.width).to.be.a("number") - }) - - it("calls 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("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 - expect(found.source).to.equal(data.source) - expect(found.width).to.equal(data.width) - }) - - 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 - expect(LatexAPI.findPrerendered("\\frac{x}{3}", 13, "#3300AA")).to.be.null - }) - }) - - describe("#par", 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("()") - expect(LatexAPI.par("(example)")).to.equal("((example))") - }) - }) - - describe("#parif", 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("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)") - expect(LatexAPI.parif("(string+assert)", ["+", "-"])).to.equal("(string+assert)") - expect(LatexAPI.parif("(string-assert)", ["+", "-"])).to.equal("(string-assert)") - }) - - 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("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") - expect(LatexAPI.parif("(string/assert))", ["+", "-"])).to.equal("string/assert)") - }) - }) - - 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("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("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("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("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("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("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("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"]) - 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("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)") - expect(f2).to.equal("\\mathrm{h_1}\\left(10\\right)") - }) - }) - - describe("#expression", 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) - }) - }) -}) \ No newline at end of file diff --git a/common/test/module/objects.mjs b/common/test/module/objects.mjs deleted file mode 100644 index 73b9e25..0000000 --- a/common/test/module/objects.mjs +++ /dev/null @@ -1,31 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 "../basics/utils.mjs" - -import { describe, it } from "mocha" -import { expect } from "chai" - -// import Objects from "../../src/module/objects.mjs" -// -// describe("Module/Objects", function() { -// describe("#getNewName", function() { -// }) -// }) \ No newline at end of file diff --git a/common/test/module/settings.mjs b/common/test/module/settings.mjs deleted file mode 100644 index b266bb2..0000000 --- a/common/test/module/settings.mjs +++ /dev/null @@ -1,101 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 "../basics/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/run.py b/run.py index 058ca94..783e23b 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-2025 Ad5001 + * 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 diff --git a/runtime-pyside6/LogarithmPlotter/__init__.py b/runtime-pyside6/LogarithmPlotter/__init__.py index 08914d3..2bd4967 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-2025 Ad5001 + * 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 @@ -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 LogarithmPlotter directory. + cwd = realpath(join(dirname(__file__), '..')) # Root AccountFree directory. if exists(join(cwd, '.git')): date_str = check_output(cmd, cwd=cwd).decode('utf-8').split(' ')[0] try: diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py index 562231a..3264097 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-2025 Ad5001 + * 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 @@ -17,14 +17,13 @@ """ from os import getcwd, chdir, environ, path -from platform import system as os_name, release as OS_RELEASE +from platform import release as os_release from sys import path as sys_path -from sys import argv, exit +from sys import platform, argv, exit from tempfile import TemporaryDirectory -from math import ceil from time import time -from PySide6.QtCore import QTranslator, QLocale, QThreadPool, QThread +from PySide6.QtCore import QTranslator, QLocale from PySide6.QtGui import QIcon from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtQuickControls2 import QQuickStyle @@ -50,18 +49,6 @@ 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", @@ -95,17 +82,18 @@ def get_linux_theme() -> str: def get_platform_qt_style(os) -> str: return { - "Linux": get_linux_theme(), - "Windows": "Universal" if OS_RELEASE() in ["10", "11", "12", "13", "14"] else "Windows", - "Darwin": "macOS", - "Android": "Material" + "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] 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"], ["properties"]] + 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) @@ -159,15 +147,11 @@ def run(): config.init() if not 'QT_QUICK_CONTROLS_STYLE' in environ: - QQuickStyle.setStyle(get_platform_qt_style(OS_NAME)) + QQuickStyle.setStyle(get_platform_qt_style(platform)) 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) @@ -175,12 +159,12 @@ def run(): # Installing macOS file handler. macos_file_open_handler = None - if OS_NAME == "Darwin": + if platform == "darwin": macos_file_open_handler = native.MacOSFileOpenHandler() app.installEventFilter(macos_file_open_handler) helper = Helper(pwd, tmpfile) - latex = Latex(CACHE_PATH) + latex = Latex(tempdir) engine, js_globals = create_engine(helper, latex, dep_time) if len(engine.rootObjects()) == 0: # No root objects loaded @@ -193,7 +177,7 @@ def run(): js_globals.Modules.IO.loadDiagram(argv[-1]) chdir(path.dirname(path.realpath(__file__))) - if OS_NAME == "Darwin": + if platform == "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/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index d271cb6..f26fd5b 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-2025 Ad5001 + * 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 @@ -20,7 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import eu.ad5001.LogarithmPlotter.Common +import "js/index.mjs" as JS /*! @@ -41,7 +41,6 @@ MenuBar { shortcut: StandardKey.Open onTriggered: settings.load() icon.name: 'document-open' - icon.color: sysPalette.windowText } Action { @@ -49,14 +48,13 @@ 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.color: sysPalette.windowText - icon.name: 'document-save-as' + icon.name: 'document-save-as' + } MenuSeparator { } Action { @@ -70,7 +68,6 @@ MenuBar { } icon.name: 'application-exit' - icon.color: sysPalette.windowText } } @@ -79,23 +76,24 @@ MenuBar { Action { text: qsTr("&Undo") shortcut: StandardKey.Undo - onTriggered: Modules.History.undo() + onTriggered: 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: Modules.History.redo() + onTriggered: history.redo() icon.name: 'edit-redo' icon.color: enabled ? sysPalette.windowText : sysPaletteIn.windowText + enabled: history.redoCount > 0 } Action { text: qsTr("&Copy plot") shortcut: StandardKey.Copy onTriggered: root.copyDiagramToClipboard() icon.name: 'edit-copy' - icon.color: sysPalette.windowText } MenuSeparator { } Action { @@ -103,7 +101,6 @@ MenuBar { shortcut: StandardKey.Copy onTriggered: preferences.open() icon.name: 'settings' - icon.color: sysPalette.windowText } } @@ -122,7 +119,7 @@ MenuBar { icon.color: sysPalette.buttonText onTriggered: { var newObj = Modules.Objects.createNewRegisteredObject(modelData) - Modules.History.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) + history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } } @@ -134,45 +131,38 @@ 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: 'translate' - icon.color: sysPalette.windowText + icon.name: 'translator' onTriggered: Qt.openUrlExternally("https://hosted.weblate.org/engage/logarithmplotter/") } MenuSeparator { } Action { text: qsTr("&Thanks") - icon.name: 'help-about' - icon.color: sysPalette.windowText + icon.name: 'about' onTriggered: thanksTo.open() } Action { text: qsTr("&About") shortcut: StandardKey.HelpContents - icon.name: 'help-about' - icon.color: sysPalette.windowText + icon.name: 'about' onTriggered: about.open() } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir deleted file mode 100644 index af9eb16..0000000 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Common/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module eu.ad5001.LogarithmPlotter.Common - -JS 1.0 index.mjs diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml new file mode 100644 index 0000000..47db5f3 --- /dev/null +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -0,0 +1,222 @@ +/** + * 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() { + undoCount = 0 + redoCount = 0 + undoStack = [] + redoStack = [] + } + + + /*! + \qmlmethod var History::serialize() + 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] + } + + /*! + \qmlmethod void History::unserialize(var undoSt, var redoSt) + 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() + } + + /*! + \qmlmethod void History::addToHistory(var action) + 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 + } + } + + /*! + \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) { + if(undoStack.length > 0) { + var action = undoStack.pop() + action.undo() + if(updateObjectList) + objectLists.update() + redoStack.push(action) + undoCount--; + redoCount++; + saved = false + } + } + + /*! + \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) { + 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 + }) + } +} diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml similarity index 66% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 09b6feb..926b42a 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/Browser.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2025 Ad5001 + * 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 @@ -16,15 +16,13 @@ * along with this program. If not, see . */ -pragma ComponentBehavior: Bound - import QtQuick.Controls import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! - \qmltype Browser + \qmltype HistoryBrowser \inqmlmodule eu.ad5001.LogarithmPlotter.History \brief Tab of the drawer that allows to navigate through the undo and redo history. @@ -48,18 +46,6 @@ 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 @@ -90,22 +76,19 @@ Item { id: redoColumn anchors.right: parent.right anchors.top: parent.top - width: historyBrowser.actionWidth + width: actionWidth Repeater { - model: historyBrowser.redoCount + model: history.redoCount - SingleItem { + HistoryItem { id: redoButton - width: historyBrowser.actionWidth + width: 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() - } } } } @@ -118,14 +101,14 @@ Item { transform: Rotation { origin.x: 30; origin.y: 30; angle: 270} height: 70 width: 20 - visible: historyBrowser.redoCount > 0 + visible: history.redoCount > 0 } Rectangle { id: nowRect anchors.right: parent.right anchors.top: redoColumn.bottom - width: historyBrowser.actionWidth + width: actionWidth height: 40 color: sysPalette.highlight Text { @@ -141,24 +124,20 @@ Item { id: undoColumn anchors.right: parent.right anchors.top: nowRect.bottom - width: historyBrowser.actionWidth + width: actionWidth Repeater { - model: historyBrowser.undoCount + model: history.undoCount - SingleItem { + HistoryItem { id: undoButton - width: historyBrowser.actionWidth + width: actionWidth //height: actionHeight isRedo: false + idx: index darkTheme: historyBrowser.darkTheme hidden: !(filterInput.value == "" || content.includes(filterInput.value)) - - onClicked: { - undoTimer.toUndoCount = +index+1 - undoTimer.start() - } } } } @@ -171,39 +150,7 @@ Item { transform: Rotation { origin.x: 30; origin.y: 30; angle: 270} height: 60 width: 20 - 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; + visible: history.undoCount > 0 } } } @@ -216,18 +163,6 @@ 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("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/SingleItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml similarity index 87% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index fac19e3..f1e20a0 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/SingleItem.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2025 Ad5001 + * 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 @@ -16,13 +16,14 @@ * along with this program. If not, see . */ -import QtQuick import QtQuick.Controls +import QtQuick +import Qt5Compat.GraphicalEffects import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! - \qmltype SingleItem + \qmltype HistoryItem \inqmlmodule eu.ad5001.LogarithmPlotter.History \brief Item representing an history action. @@ -40,17 +41,17 @@ Button { \qmlproperty bool HistoryItem::isRedo true if the action is in the redo stack, false othewise. */ - required property bool isRedo + property bool isRedo /*! - \qmlproperty int HistoryItem::index + \qmlproperty int HistoryItem::idx Index of the item within the HistoryBrowser list. */ - required property int index + property int idx /*! \qmlproperty bool HistoryItem::darkTheme true when the system is running with a dark theme, false otherwise. */ - required property bool darkTheme + property bool darkTheme /*! \qmlproperty bool HistoryItem::hidden true when the item is filtered out, false otherwise. @@ -60,7 +61,7 @@ Button { \qmlproperty int HistoryItem::historyAction Associated history action. */ - readonly property var historyAction: isRedo ? Modules.History.redoStack.at(index) : Modules.History.undoStack.at(-index-1) + readonly property var historyAction: isRedo ? history.redoStack[idx] : history.undoStack[history.undoCount-idx-1] /*! \qmlproperty int HistoryItem::actionHeight @@ -81,11 +82,12 @@ Button { height: hidden ? 8 : Math.max(actionHeight, label.height + 15) - Rectangle { + LinearGradient { 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 } } @@ -145,6 +147,13 @@ Button { ToolTip.visible: hovered ToolTip.delay: 200 ToolTip.text: content + + onClicked: { + if(isRedo) + history.redoMultipleDefered(history.redoCount-idx) + else + history.undoMultipleDefered(+idx+1) + } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir index 66c4408..4f011a5 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir @@ -1,4 +1,5 @@ module eu.ad5001.LogarithmPlotter.History -Browser 1.0 Browser.qml -SingleItem 1.0 SingleItem.qml +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/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 30bf6ca..38d05be 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-2025 Ad5001 + * 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 @@ -30,15 +30,104 @@ import Qt.labs.platform as Native */ Canvas { id: canvas - anchors.top: parent.top + anchors.top: separator.bottom 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} containing data for deferred image loading. + 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 = {} @@ -66,21 +155,9 @@ Canvas { Object.keys(imageLoaders).forEach((key) => { if(isImageLoaded(key)) { // Calling callback - imageLoaders[key]() + imageLoaders[key][0](canvas, ctx, imageLoaders[key][1]) 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 ddbd2bd..8545153 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-2025 Ad5001 + * 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 @@ -17,17 +17,16 @@ */ import QtQml -import QtQuick import QtQuick.Controls -import QtQuick.Layouts 1.12 import eu.ad5001.MixedMenu 1.1 +import QtQuick.Layouts 1.12 +import QtQuick // Auto loading all modules. -import eu.ad5001.LogarithmPlotter.Common +import "js/index.mjs" as JS -import eu.ad5001.LogarithmPlotter.History 1.0 as History +import eu.ad5001.LogarithmPlotter.History 1.0 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 /*! @@ -43,7 +42,7 @@ ApplicationWindow { width: 1000 height: 500 color: sysPalette.window - title: qsTr("untitled") + title: "LogarithmPlotter " + (settings.saveFilename != "" ? " - " + settings.saveFilename.split('/').pop() : "") + (history.saved ? "" : "*") SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } @@ -51,7 +50,9 @@ ApplicationWindow { menuBar: appMenu.trueItem AppMenuBar {id: appMenu} - + + History { id: history } + Popup.GreetScreen {} Popup.Preferences {id: preferences} @@ -121,16 +122,16 @@ ApplicationWindow { ObjectLists { id: objectLists - onChanged: Modules.Canvas.requestPaint() + onChanged: drawCanvas.requestPaint() } Settings { id: settings canvas: drawCanvas - onChanged: Modules.Canvas.requestPaint() + onChanged: drawCanvas.requestPaint() } - History.Browser { + HistoryBrowser { id: historyBrowser } } @@ -144,6 +145,20 @@ 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) { @@ -155,21 +170,19 @@ ApplicationWindow { } } - Overlay.ViewPositionChange { + ViewPositionChangeOverlay { id: viewPositionChanger anchors.fill: parent + canvas: parent + settingsInstance: settings } - Overlay.PickLocation { + PickLocationOverlay { id: positionPicker anchors.fill: parent + canvas: parent } } - - Overlay.Loading { - id: loadingOverlay - anchors.fill: parent - } Timer { id: delayRefreshTimer @@ -186,7 +199,7 @@ ApplicationWindow { } onClosing: function(close) { - if(!Modules.IO.saved) { + if(!history.saved) { close.accepted = false appMenu.openSaveUnsavedChangesDialog() } @@ -251,22 +264,5 @@ 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 - } - }) - Modules.IO.on("saved loaded", (evt) => { - // Refreshing sidebar - updateObjectsLists() - if(title.endsWith("*")) - title = title.substring(0, title.length-1) - }) - Modules.IO.on("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 113b8bd..57ea4ae 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-2025 Ad5001 + * 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 @@ -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 eu.ad5001.LogarithmPlotter.Common +import "../../js/index.mjs" as JS /*! \qmltype CustomPropertyList @@ -41,12 +41,6 @@ Repeater { Object whose properties to list and edit. */ property var obj - - /*! - \qmlproperty var CustomPropertyList::objPropertyTypes - Record containing the properties types of the object mapped by their name. - */ - property var objPropertyTypes /*! \qmlproperty var CustomPropertyList::positionPicker Reference to the global PositionPicker QML object. @@ -80,13 +74,13 @@ Repeater { Setting.ExpressionEditor { height: 30 label: propertyLabel - icon: `properties/${propertyIcon}.svg` + icon: `settings/custom/${propertyIcon}.svg` defValue: JS.Utils.simplifyExpression(obj[propertyName].toEditableString()) self: obj.name variables: propertyType.variables onChanged: function(newExpr) { if(obj[propertyName].toString() != newExpr.toString()) { - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newExpr )) @@ -105,7 +99,7 @@ Repeater { Setting.TextSetting { height: 30 label: propertyLabel - icon: `properties/${propertyIcon}.svg` + icon: `settings/custom/${propertyIcon}.svg` min: propertyType == "int" ? 0 : -Infinity isInt: propertyType == "int" isDouble: propertyType == "number" @@ -129,7 +123,7 @@ Repeater { // Ensuring old and new values are different to prevent useless adding to history. if(obj[propertyName] != newValueParsed) { - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], newValueParsed )) @@ -165,7 +159,7 @@ Repeater { CheckBox { height: 20 text: propertyLabel - //icon: `properties/${propertyIcon}.svg` + //icon: `settings/custom/${propertyIcon}.svg` checked: { //if(obj[propertyName] == null) { @@ -174,7 +168,7 @@ Repeater { return obj[propertyName] } onClicked: { - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], this.checked )) @@ -191,7 +185,7 @@ Repeater { Setting.ComboBoxSetting { height: 30 label: propertyLabel - icon: `properties/${propertyIcon}.svg` + icon: `settings/custom/${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") @@ -215,9 +209,7 @@ Repeater { if(selectedObj == null) { // Creating new object. selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType) - Modules.History.addToHistory( - new JS.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())] : []) @@ -227,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) - Modules.History.addToHistory(new JS.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. - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], baseModel[newIndex] )) @@ -252,7 +244,7 @@ Repeater { Setting.ListSetting { label: propertyLabel - //icon: `properties/${propertyIcon}.svg` + //icon: `settings/custom/${propertyIcon}.svg` dictionaryMode: paramTypeIn(propertyType, ['Dict']) keyType: dictionaryMode ? propertyType.keyType : 'string' valueType: propertyType.valueType @@ -264,7 +256,7 @@ Repeater { onChanged: { var exported = exportModel() - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( obj.name, objType, propertyName, obj[propertyName], exported )) @@ -286,15 +278,15 @@ Repeater { Loader { id: propertyEditor width: dlgProperties.width - pointerButton.width - property string propertyName: modelData - property var propertyType: objPropertyTypes[modelData] + property string propertyName: modelData[0] + property var propertyType: modelData[1] property string propertyLabel: qsTranslate('prop',propertyName) - property string propertyIcon: propertyName + property string propertyIcon: JS.Utils.camelCase2readable(propertyName) sourceComponent: { if(propertyName.startsWith('comment')) return commentComponent - else if(propertyType === 'boolean') + else if(propertyType == 'boolean') return checkboxComponent else if(paramTypeIn(propertyType, ['Expression'])) return expressionEditorComponent 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 a5352d4..e2b149b 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-2025 Ad5001 + * 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 @@ -18,10 +18,11 @@ 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 eu.ad5001.LogarithmPlotter.Common +import "../../js/index.mjs" as JS /*! \qmltype Dialog @@ -111,7 +112,7 @@ Popup.BaseDialog { if(newName in Modules.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { - Modules.History.addToHistory(new JS.HistoryLib.NameChanged( + history.addToHistory(new JS.HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) Modules.Objects.renameObject(obj.name, newName) @@ -126,17 +127,13 @@ Popup.BaseDialog { id: labelContentProperty height: 30 width: dlgProperties.width - label: qsTranslate("prop", "labelContent") + label: qsTr("Label content") 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() @@ -164,9 +161,8 @@ Popup.BaseDialog { */ function open() { dlgCustomProperties.model = [] // Reset - const objProps = Modules.Objects.types[objEditor.objType].properties() - dlgCustomProperties.objPropertyTypes = objProps - dlgCustomProperties.model = Object.keys(objProps) + 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/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 21559a9..7aa9574 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-2025 Ad5001 + * 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 @@ -19,7 +19,7 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import eu.ad5001.LogarithmPlotter.Common +import "../js/index.mjs" as JS /*! @@ -104,9 +104,7 @@ Column { onClicked: { let newObj = Modules.Objects.createNewRegisteredObject(modelData) - Modules.History.addToHistory(new JS.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/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 8047573..d92c36b 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-2025 Ad5001 + * 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 @@ -56,7 +56,7 @@ ScrollView { property var editingRows: [] model: Modules.Objects.currentObjects[objType] width: objectsListView.width - height: contentItem.childrenRect.height + (visible ? 10 : 0) + implicitHeight: contentItem.childrenRect.height visible: model != undefined && model.length > 0 interactive: false @@ -71,8 +71,8 @@ ScrollView { id: typeVisibilityCheckBox checked: Modules.Objects.currentObjects[objType] != undefined ? Modules.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(const obj of Modules.Objects.currentObjects[objType]) obj.visible = this.checked - for(const obj of objTypeList.editingRows) obj.objVisible = 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() } @@ -140,7 +140,7 @@ ScrollView { */ function paramTypeIn(parameter, types = []) { if(types.includes(parameter.toString())) return true - if(typeof parameter === 'object' && 'type' in parameter) + if(typeof parameter == 'object' && 'type' in parameter) return types.includes(parameter.type) return false } 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 0f7003f..9118d09 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-2025 Ad5001 + * 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 @@ -21,7 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import eu.ad5001.LogarithmPlotter.Common +import "../js/index.mjs" as JS /*! @@ -72,7 +72,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 5 onClicked: { - Modules.History.addToHistory(new JS.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: { - Modules.History.addToHistory(new JS.HistoryLib.ColorChanged( + history.addToHistory(new JS.HistoryLib.ColorChanged( obj.name, obj.type, obj.color, selectedColor.toString() )) obj.color = selectedColor.toString() @@ -227,11 +227,11 @@ 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 = [] - Modules.History.addToHistory(new JS.HistoryLib.DeleteObject( + 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/Overlay/Loading.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml deleted file mode 100644 index 10f3665..0000000 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/Loading.qml +++ /dev/null @@ -1,130 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 - - -/*! - \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/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir deleted file mode 100644 index 0288c9e..0000000 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/qmldir +++ /dev/null @@ -1,5 +0,0 @@ -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/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml similarity index 95% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 6ba8bb6..2fb45d4 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/PickLocation.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2025 Ad5001 + * 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 @@ -18,12 +18,12 @@ import QtQuick import QtQuick.Controls -import eu.ad5001.LogarithmPlotter.Setting as Setting -import eu.ad5001.LogarithmPlotter.Common +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "js/index.mjs" as JS /*! - \qmltype PickLocation - \inqmlmodule eu.ad5001.LogarithmPlotter.Overlay + \qmltype PickLocationOverlay + \inqmlmodule eu.ad5001.LogarithmPlotter \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 @@ -36,7 +36,7 @@ Item { id: pickerRoot visible: false clip: true - + /*! \qmlsignal PickLocationOverlay::picked(var obj) @@ -97,9 +97,9 @@ Item { readonly property bool userPickY: pickY && pickYCheckbox.checked Rectangle { - anchors.fill: parent color: sysPalette.window opacity: 0.35 + anchors.fill: parent } MouseArea { @@ -115,7 +115,7 @@ Item { let obj = Modules.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { - Modules.History.addToHistory(new JS.HistoryLib.EditedPosition( + 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) { - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + 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) { - Modules.History.addToHistory(new JS.HistoryLib.EditedProperty( + history.addToHistory(new JS.HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValueY )) obj[propertyY] = newValueY @@ -285,7 +285,7 @@ Item { const axisX = Modules.Canvas.axesSteps.x.value const xpos = Modules.Canvas.px2x(picker.mouseX) if(snapToGridCheckbox.checked) { - if(Modules.Settings.logscalex) { + if(canvas.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/Popup/About.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml index e82f39c..d74c101 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-2025 Ad5001 + * 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 @@ -102,7 +102,7 @@ BaseDialog { wrapMode: Text.WordWrap textFormat: Text.RichText font.pixelSize: 13 - text: "Copyright © 2021-2025 Ad5001 <mail@ad5001.eu>
+ text: "Copyright © 2021-2024 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 98e37d4..0220956 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-2025 Ad5001 + * 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 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 a9c73a6..10fe87e 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-2025 Ad5001 + * 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 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 1797b9d..844e22a 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-2025 Ad5001 + * 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 @@ -45,17 +45,17 @@ Popup { property bool changelogNeedsFetching: true onAboutToShow: if(changelogNeedsFetching) { - Helper.fetchChangelog().then((fetchedText) => { - changelogNeedsFetching = false - changelog.text = fetchedText + Helper.fetchChangelog() + } + + Connections { + target: Helper + function onChangelogFetched(chl) { + changelogNeedsFetching = false; + changelog.text = chl changelogView.contentItem.implicitHeight = changelog.height - }, (error) => { - const e = qsTranslate("changelog", "Could not fetch update: {}.").replace('{}', error) - console.error(e) - changelogNeedsFetching = false - changelog.text = e - changelogView.contentItem.implicitHeight = changelog.height - }) + // console.log(changelog.height, changelogView.contentItem.implicitHeight) + } } ScrollView { 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 00dbdae..4b7ff8a 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-2025 Ad5001 + * 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 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 a083d64..09e16e5 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-2025 Ad5001 + * 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 @@ -141,7 +141,7 @@ Popup { horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 text: modelData.name - wrapMode: Text.Wrap + wrapMode: Text.WordWrap clip: true } } 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 8111f85..7002539 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-2025 Ad5001 + * 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 @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -import QtQuick import QtQuick.Controls -import QtQml.Models +import QtQuick /*! \qmltype InsertCharacter @@ -43,18 +42,15 @@ Popup { */ property string category: 'all' - width: insertGrid.width + 10 - height: insertGrid.height + 10 + width: 280 + height: Math.ceil(insertGrid.insertChars.length/insertGrid.columns)*(width/insertGrid.columns)+5 modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - GridView { + Grid { id: insertGrid - width: 280 - height: Math.ceil(model.count/columns)*cellHeight - property int columns: 7 - cellWidth: width/columns - cellHeight: cellWidth + width: parent.width + columns: 7 property var insertCharsExpression: [ "∞","π","¹","²","³","⁴","⁵", @@ -90,34 +86,21 @@ Popup { }[insertPopup.category] } - 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() + 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) + } } } - - Component.onCompleted: function() { - for(const chr of insertChars) { - model.append({ 'chr': chr }) - } - } - - Keys.onEscapePressed: parent.close() } - - function setFocus() { - insertGrid.currentIndex = 0 - insertGrid.forceActiveFocus() - } - } 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 9ed40c8..a76410f 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-2025 Ad5001 + * 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 @@ -20,7 +20,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import eu.ad5001.LogarithmPlotter.Common +import "../js/index.mjs" as JS /*! \qmltype Preferences 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 85e4a64..107eac5 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-2025 Ad5001 + * 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 @@ -232,11 +232,6 @@ BaseDialog { authorLine: 'gallegonovato', website: '', websiteName: '' - }, - TamilNeram: { - authorLine: 'தமிழ் நேரம்', - website: 'https://github.com/TamilNeram', - websiteName: qsTr('Github') } } @@ -270,11 +265,6 @@ 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] - }) } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index 3cf03fa..8c0859f 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -1,11 +1,11 @@ module eu.ad5001.LogarithmPlotter.Popup -Alert 1.0 Alert.qml -About 1.0 About.qml BaseDialog 1.0 BaseDialog.qml -Changelog 1.0 Changelog.qml +About 1.0 About.qml +Alert 1.0 Alert.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/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index 897af70..304b704 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-2025 Ad5001 + * 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 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 a4dc93b..d29ab7c 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-2025 Ad5001 + * 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 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 35bba0a..afa3e09 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-2025 Ad5001 + * 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 @@ -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 eu.ad5001.LogarithmPlotter.Common +import "../js/index.mjs" as JS /*! @@ -175,17 +175,17 @@ Item { Icon { id: iconLabel anchors.top: parent.top - anchors.topMargin: parent.icon == "" ? 0 : 3 - source: control.visible && parent.icon != "" ? "../icons/" + control.icon : "" + anchors.topMargin: icon == "" ? 0 : 3 + source: control.visible && icon != "" ? "../icons/" + control.icon : "" width: height - height: parent.icon == "" || !visible ? 0 : 24 + height: icon == "" || !visible ? 0 : 24 color: sysPalette.windowText } Label { id: labelItem anchors.left: iconLabel.right - anchors.leftMargin: parent.icon == "" ? 0 : 5 + anchors.leftMargin: icon == "" ? 0 : 5 anchors.top: parent.top height: parent.height width: Math.max(85, implicitWidth) @@ -221,9 +221,9 @@ Item { focus: true selectByMouse: true - property bool autocompleteEnabled: Helper.getSetting("autocompletion.enabled") - property bool syntaxHighlightingEnabled: Helper.getSetting("expression_editor.colorize") - property bool autoClosing: Helper.getSetting("expression_editor.autoclose") + property bool autocompleteEnabled: Helper.getSettingBool("autocompletion.enabled") + property bool syntaxHighlightingEnabled: Helper.getSettingBool("expression_editor.colorize") + property bool autoClosing: Helper.getSettingBool("expression_editor.autoclose") property var tokens: autocompleteEnabled || syntaxHighlightingEnabled ? parent.tokens(text) : [] Keys.priority: Keys.BeforeItem // Required for knowing which key the user presses. @@ -231,8 +231,8 @@ Item { onEditingFinished: { if(insertButton.focus || insertPopup.focus) return let value = text - if(value != "" && value.toString() != parent.defValue) { - let expr = parent.parse(value) + if(value != "" && value.toString() != defValue) { + let expr = parse(value) if(expr != null) { control.changed(expr) defValue = expr.toEditableString() @@ -280,10 +280,10 @@ Item { acPopupContent.itemSelected = 0 - if(event.text in parent.openAndCloseMatches && autoClosing) { + if(event.text in openAndCloseMatches && autoClosing) { let start = selectionStart insert(selectionStart, event.text) - insert(selectionEnd, parent.openAndCloseMatches[event.text]) + insert(selectionEnd, openAndCloseMatches[event.text]) cursorPosition = start+1 event.accepted = true } @@ -500,41 +500,29 @@ 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.setFocus() + insertPopup.focus = true } } P.InsertCharacter { id: insertPopup - x: parent.width - width - y: parent.height + x: Math.round((parent.width - width) / 2) + y: Math.round((parent.height - height) / 2) category: "expression" onSelected: function(c) { editor.insert(editor.cursorPosition, c) - } - - onClosed: function() { + insertPopup.close() focus = false editor.focus = true } @@ -612,7 +600,7 @@ Item { */ function colorize(tokenList) { let parsedText = "" - let scheme = colorSchemes[Helper.getSetting("expression_editor.color_scheme")] + let scheme = colorSchemes[Helper.getSettingInt("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/Setting/Icon.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 6ba76aa..aeffe53 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-2025 Ad5001 + * 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 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 daad433..221b3a3 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-2025 Ad5001 + * 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 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 bc105aa..b0a054a 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-2025 Ad5001 + * 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 @@ -37,7 +37,7 @@ Item { Emitted when the value of the text has been changed. The corresponding handler is \c onChanged. */ - signal changed(var newValue) + signal changed(string newValue) /*! \qmlproperty bool TextSetting::isInt @@ -144,40 +144,28 @@ 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.setFocus() + insertPopup.focus = true } } Popup.InsertCharacter { id: insertPopup - x: parent.width - width - y: parent.height + x: Math.round((parent.width - width) / 2) + y: Math.round((parent.height - height) / 2) onSelected: function(c) { input.insert(input.cursorPosition, c) - } - - onClosed: function() { + insertPopup.close() focus = false input.focus = true } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir index bb78bbe..8106e26 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir +++ b/runtime-pyside6/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/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 64e9f61..534556f 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-2025 Ad5001 + * 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 @@ -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 eu.ad5001.LogarithmPlotter.Common +import "js/index.mjs" as JS /*! \qmltype Settings @@ -44,25 +44,25 @@ ScrollView { Zoom on the x axis of the diagram, provided from settings. \sa Settings */ - property double xzoom: Helper.getSetting('default_graph.xzoom') + 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: Helper.getSetting('default_graph.yzoom') + 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: Helper.getSetting('default_graph.xmin') + 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: Helper.getSetting('default_graph.ymax') + property double ymax: Helper.getSettingInt('default_graph.ymax') /*! \qmlproperty string Settings::xaxisstep Step of the x axis graduation, provided from settings. @@ -93,34 +93,39 @@ ScrollView { Width of lines that will be drawn into the canvas, provided from settings. \sa Settings */ - property double linewidth: Helper.getSetting('default_graph.linewidth') + 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: Helper.getSetting('default_graph.textsize') + 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: Helper.getSetting('default_graph.logscalex') + 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: Helper.getSetting('default_graph.showxgrad') + 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: Helper.getSetting('default_graph.showygrad') + 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 @@ -130,21 +135,16 @@ ScrollView { Popup.FileDialog { id: fdiag onAccepted: { - let filePath = fdiag.currentFile.toString().substr(7) - if(filePath.at(2) === ":") // Windows path, remove the leading slash. - filePath = filePath.substr(1) - Modules.Settings.set("saveFilename", filePath) + var filePath = fdiag.currentFile.toString().substr(7) + settings.saveFilename = filePath if(exportMode) { Modules.IO.saveDiagram(filePath) } else { Modules.IO.loadDiagram(filePath) - // 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 + 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 } } } @@ -158,16 +158,11 @@ ScrollView { min: 0.1 icon: "settings/xzoom.svg" width: settings.settingWidth - + value: settings.xzoom.toFixed(2) onChanged: function(newValue) { - Modules.Settings.set("xzoom", newValue, true) + settings.xzoom = newValue settings.changed() } - - function update(newValue) { - value = Modules.Settings.xzoom.toFixed(2) - maxX.update() - } } Setting.TextSetting { @@ -178,16 +173,11 @@ ScrollView { label: qsTr("Y Zoom") icon: "settings/yzoom.svg" width: settings.settingWidth - + value: settings.yzoom.toFixed(2) onChanged: function(newValue) { - Modules.Settings.set("yzoom", newValue, true) + settings.yzoom = newValue settings.changed() } - - function update(newValue) { - value = Modules.Settings.yzoom.toFixed(2) - minY.update() - } } // Positioning the graph @@ -199,18 +189,14 @@ ScrollView { label: qsTr("Min X") icon: "settings/xmin.svg" width: settings.settingWidth - + defValue: settings.xmin onChanged: function(newValue) { - 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() + if(parseFloat(maxX.value) > newValue) { + settings.xmin = newValue + settings.changed() + } else { + alert.show("Minimum x value must be inferior to maximum.") + } } } @@ -222,16 +208,11 @@ ScrollView { label: qsTr("Max Y") icon: "settings/ymax.svg" width: settings.settingWidth - + defValue: settings.ymax onChanged: function(newValue) { - Modules.Settings.set("ymax", newValue, true) + settings.ymax = newValue settings.changed() } - - function update() { - value = Modules.Settings.ymax - minY.update() - } } Setting.TextSetting { @@ -242,24 +223,15 @@ 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 > 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() + if(xvaluemax > settings.xmin) { + 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.") } } - - function update() { - let newVal = Modules.Canvas.px2x(canvas.width) - if(newVal > 1e-5) - newVal = newVal.toDecimalPrecision(8) - value = newVal - } } Setting.TextSetting { @@ -270,21 +242,15 @@ 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) { - 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.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.") } } - - function update() { - value = Modules.Canvas.px2y(canvas.height).toDecimalPrecision(8) - } } Setting.TextSetting { @@ -294,16 +260,12 @@ ScrollView { label: qsTr("X Axis Step") icon: "settings/xaxisstep.svg" width: settings.settingWidth - + defValue: settings.xaxisstep + visible: !settings.logscalex onChanged: function(newValue) { - Modules.Settings.set("xaxisstep", newValue, true) + settings.xaxisstep = newValue settings.changed() } - - function update() { - value = Modules.Settings.xaxisstep - visible = !Modules.Settings.logscalex - } } Setting.TextSetting { @@ -313,13 +275,11 @@ ScrollView { label: qsTr("Y Axis Step") icon: "settings/yaxisstep.svg" width: settings.settingWidth - + defValue: settings.yaxisstep onChanged: function(newValue) { - Modules.Settings.set("yaxisstep", newValue, true) + settings.yaxisstep = newValue settings.changed() } - - function update() { value = Modules.Settings.yaxisstep } } Setting.TextSetting { @@ -330,13 +290,11 @@ ScrollView { min: 1 icon: "settings/linewidth.svg" width: settings.settingWidth - + defValue: settings.linewidth onChanged: function(newValue) { - Modules.Settings.set("linewidth", newValue, true) + settings.linewidth = newValue settings.changed() } - - function update() { value = Modules.Settings.linewidth } } Setting.TextSetting { @@ -347,13 +305,11 @@ ScrollView { min: 1 icon: "settings/textsize.svg" width: settings.settingWidth - + defValue: settings.textsize onChanged: function(newValue) { - Modules.Settings.set("textsize", newValue, true) + settings.textsize = newValue settings.changed() } - - function update() { value = Modules.Settings.textsize } } Setting.ComboBoxSetting { @@ -362,31 +318,24 @@ 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}) - currentIndex = find(editText) - Modules.Settings.set("xlabel", editText, true) + if (find(editText) === -1) model.append({text: editText}) + settings.xlabel = editText settings.changed() } - onActivated: function(selectedId) { - Modules.Settings.set("xlabel", model.get(selectedId).text, true) + settings.xlabel = model.get(selectedId).text settings.changed() } - - function update() { - editText = Modules.Settings.xlabel - if(find(editText) === -1) model.append({text: editText}) - currentIndex = find(editText) - } + Component.onCompleted: editText = settings.xlabel } Setting.ComboBoxSetting { @@ -395,7 +344,6 @@ ScrollView { width: settings.settingWidth label: qsTr('Y Label') icon: "settings/ylabel.svg" - editable: true model: ListModel { ListElement { text: "" } ListElement { text: "y" } @@ -404,52 +352,39 @@ 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}) - currentIndex = find(editText) - Modules.Settings.set("ylabel", editText, true) + if (find(editText) === -1) model.append({text: editText, yaxisstep: root.yaxisstep}) + settings.ylabel = editText settings.changed() } - onActivated: function(selectedId) { - Modules.Settings.set("ylabel", model.get(selectedId).text, true) + settings.ylabel = model.get(selectedId).text settings.changed() } - - function update() { - editText = Modules.Settings.ylabel - if(find(editText) === -1) model.append({text: editText}) - currentIndex = find(editText) - } + Component.onCompleted: editText = settings.ylabel } CheckBox { id: logScaleX + checked: settings.logscalex text: qsTr('X Log scale') onClicked: { - Modules.Settings.set("logscalex", checked, true) - if(Modules.Settings.xmin <= 0) // Reset xmin to prevent crash. - Modules.Settings.set("xmin", .5) + settings.logscalex = checked settings.changed() } - - function update() { - checked = Modules.Settings.logscalex - xAxisStep.update() - } } CheckBox { id: showXGrad + checked: settings.showxgrad text: qsTr('Show X graduation') onClicked: { - Modules.Settings.set("showxgrad", checked, true) + settings.showxgrad = checked settings.changed() } - - function update() { checked = Modules.Settings.showxgrad } } CheckBox { @@ -457,10 +392,9 @@ ScrollView { checked: settings.showygrad text: qsTr('Show Y graduation') onClicked: { - Modules.Settings.set("showygrad", checked, true) + settings.showygrad = checked settings.changed() } - function update() { checked = Modules.Settings.showygrad } } Button { @@ -506,10 +440,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(Modules.Settings.saveFilename == "") { + if(settings.saveFilename == "") { saveAs() } else { - Modules.IO.saveDiagram(Modules.Settings.saveFilename) + Modules.IO.saveDiagram(settings.saveFilename) } } @@ -530,30 +464,4 @@ 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 }) - } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml similarity index 70% rename from runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 78329a7..e8514d4 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Overlay/ViewPositionChange.qml +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2025 Ad5001 + * 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 @@ -17,9 +17,11 @@ */ import QtQuick +import QtQuick.Controls +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! - \qmltype ViewPositionChange.Overlay + \qmltype ViewPositionChangeOverlay \inqmlmodule eu.ad5001.LogarithmPlotter \brief Overlay used allow the user to drag the canvas' position and change the zoom level. @@ -57,6 +59,16 @@ 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. @@ -69,7 +81,7 @@ Item { property int prevY /*! \qmlproperty double ViewPositionChangeOverlay::baseZoomMultiplier - How much should the zoom be multiplied/scrolled by for one scroll step (120° on the mouse wheel). + How much should the zoom be mutliplied/scrolled by for one scroll step (120° on the mouse wheel). */ property double baseZoomMultiplier: 0.1 @@ -79,15 +91,15 @@ Item { cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor property int positionChangeTimer: 0 - function updatePosition(deltaX, deltaY, isEnd) { + function updatePosition(deltaX, deltaY) { const unauthorized = [NaN, Infinity, -Infinity] - const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(Modules.Settings.xmin)-deltaX)) - const ymax = Modules.Settings.ymax + deltaY/Modules.Settings.yzoom + const xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) + const ymax = settingsInstance.ymax + deltaY/canvas.yzoom if(!unauthorized.includes(xmin)) - Modules.Settings.set("xmin", xmin, isEnd) + settingsInstance.xmin = xmin if(!unauthorized.includes(ymax)) - Modules.Settings.set("ymax", ymax.toDecimalPrecision(6), isEnd) - Modules.Canvas.requestPaint() + settingsInstance.ymax = ymax.toFixed(4) + settingsInstance.changed() parent.positionChanged(deltaX, deltaY) } @@ -101,9 +113,9 @@ Item { onPositionChanged: function(mouse) { positionChangeTimer++ if(positionChangeTimer == 3) { - let deltaX = mouse.x - parent.prevX - let deltaY = mouse.y - parent.prevY - updatePosition(deltaX, deltaY, false) + let deltaX = mouse.x - prevX + let deltaY = mouse.y - prevY + updatePosition(deltaX, deltaY) prevX = mouse.x prevY = mouse.y positionChangeTimer = 0 @@ -111,35 +123,35 @@ Item { } onReleased: function(mouse) { - let deltaX = mouse.x - parent.prevX - let deltaY = mouse.y - parent.prevY - updatePosition(deltaX, deltaY, true) + 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) - let zoomMultiplier = Math.pow(1+parent.baseZoomMultiplier, Math.abs(scrollSteps)) + let zoomMultiplier = Math.pow(1+baseZoomMultiplier, Math.abs(scrollSteps)) // Avoid floating-point rounding errors by removing the zoom *after* - let xZoomDelta = (Modules.Settings.xzoom*zoomMultiplier - Modules.Settings.xzoom) - let yZoomDelta = (Modules.Settings.yzoom*zoomMultiplier - Modules.Settings.yzoom) + let xZoomDelta = (settingsInstance.xzoom*zoomMultiplier - settingsInstance.xzoom) + let yZoomDelta = (settingsInstance.yzoom*zoomMultiplier - settingsInstance.yzoom) if(scrollSteps < 0) { // Negative scroll xZoomDelta *= -1 yZoomDelta *= -1 } - let newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(0) - let newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(0) + let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) + let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) // Check if we need to have more precision if(newXZoom < 10) - newXZoom = (Modules.Settings.xzoom+xZoomDelta).toDecimalPrecision(4) + newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) if(newYZoom < 10) - newYZoom = (Modules.Settings.yzoom+yZoomDelta).toDecimalPrecision(4) + newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) if(newXZoom > 0.5) - Modules.Settings.set("xzoom", newXZoom) + settingsInstance.xzoom = newXZoom if(newYZoom > 0.5) - Modules.Settings.set("yzoom", newYZoom) - Modules.Canvas.requestPaint() + settingsInstance.yzoom = newYZoom + settingsInstance.changed() } } } diff --git a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir index c80cae5..ac68e47 100644 --- a/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir +++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir @@ -1,5 +1,4 @@ module eu.ad5001.LogarithmPlotter -AppMenuBar 1.0 AppMenuBar.qml -LogGraphCanvas 1.0 LogGraphCanvas.qml Settings 1.0 Settings.qml +Alert 1.0 Alert.qml diff --git a/runtime-pyside6/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py index 2cce4dc..a5ee23c 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-2025 Ad5001 + * 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 @@ -19,16 +19,13 @@ 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": which("latex") is not None and which("dvipng") is not None, - "enable_latex_threaded": False, + "enable_latex": False, "expression_editor": { "autoclose": True, "colorize": True, diff --git a/runtime-pyside6/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py index c977253..8b57687 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-2025 Ad5001 + * 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 @@ -19,12 +19,10 @@ 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/Common/index.mjs.map") +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\/Common\/index.mjs:(\d+)") class LOG_COLORS: @@ -79,7 +77,6 @@ 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/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py index 8adb81e..d2fe631 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-2025 Ad5001 + * 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 @@ -15,10 +15,12 @@ * 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, __version__ as PySide6_version -from PySide6.QtQml import QJSValue +from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication +from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtGui import QImage +from PySide6 import __version__ as PySide6_version from os import chdir, path from json import loads @@ -28,50 +30,48 @@ 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 """ if SHOW_GUI_MESSAGES: - QMessageBox.warning(None, "LogarithmPlotter", msg) + QMessageBox.warning(None, "LogarithmPlotter", msg, QMessageBox.OK) else: 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 read_changelog(): - f = open(CHANGELOG_CACHE_PATH, 'r', -1) - data = f.read().strip() - f.close() - return data + 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) class Helper(QObject): + changelogFetched = Signal(str) + def __init__(self, cwd: str, tmpfile: str): QObject.__init__(self) self.cwd = cwd @@ -135,13 +135,29 @@ class Helper(QObject): def getVersion(self): return __VERSION__ - @Slot(str, result=QJSValue) - def getSetting(self, namespace: str) -> QJSValue: - return QJSValue(config.getSetting(namespace)) + @Slot(str, result=str) + def getSetting(self, namespace): + return str(config.getSetting(namespace)) - @Slot(str, QJSValue) - def setSetting(self, namespace: str, value: QJSValue): - return config.setSetting(namespace, value.toPrimitive().toVariant()) + @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(result=str) def getDebugInfos(self): @@ -151,14 +167,15 @@ 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(result=PyPromise) + @Slot() def fetchChangelog(self): - """ - Fetches the changelog and returns a Promise. - """ - if path.exists(CHANGELOG_CACHE_PATH): + changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") + if path.exists(changelog_cache_path): # We have a cached version of the changelog, for env that don't have access to the internet. - return PyPromise(read_changelog) + f = open(changelog_cache_path); + self.changelogFetched.emit("".join(f.readlines()).strip()) + f.close() else: # Fetch it from the internet. - return PyPromise(fetch_changelog) + runnable = ChangelogFetcher(self) + QThreadPool.globalInstance().start(runnable) diff --git a/runtime-pyside6/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py index 380ab97..dbe60bc 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-2025 Ad5001 + * 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 @@ -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: @@ -75,11 +75,10 @@ class PyJSValue: return value def type(self) -> any: - ret = None matcher = [ (lambda: self.qjs_value.isArray(), list), (lambda: self.qjs_value.isBool(), bool), - (lambda: self.qjs_value.isCallable(), Callable), + (lambda: self.qjs_value.isCallable(), Function), (lambda: self.qjs_value.isDate(), QDateTime), (lambda: self.qjs_value.isError(), Exception), (lambda: self.qjs_value.isNull(), None), @@ -94,9 +93,8 @@ class PyJSValue: ] for (test, value) in matcher: if test(): - ret = value - break - return ret + return value + return None def primitive(self): """ @@ -105,6 +103,4 @@ class PyJSValue: """ if self.type() not in [bool, float, str, None]: raise NotAPrimitiveException() - return self.qjs_value.toPrimitive().toVariant() - - + return self.qjs_value.toPrimitive().toVariant() \ No newline at end of file diff --git a/runtime-pyside6/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py index 5b127dc..2c650ce 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-2025 Ad5001 + * 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 @@ -15,22 +15,18 @@ * 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.QtCore import QObject, Slot, Property, QCoreApplication from PySide6.QtGui import QImage, QColor from PySide6.QtWidgets import QMessageBox -from os import path, remove, makedirs +from os import path, remove from string import Template +from tempfile import TemporaryDirectory from subprocess import Popen, TimeoutExpired, PIPE -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. @@ -79,20 +75,14 @@ class Latex(QObject): dvipng to be installed on the system. """ - def __init__(self, cache_path): + def __init__(self, tempdir: TemporaryDirectory): QObject.__init__(self) - self.tempdir = path.join(cache_path, "latex") - self.render_pipeline_locks = {} - makedirs(self.tempdir, exist_ok=True) + self.tempdir = tempdir @Property(bool) 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_threaded") - @Slot(result=bool) def checkLatexInstallation(self) -> bool: """ @@ -113,76 +103,21 @@ class Latex(QObject): valid_install = False else: try: - self.renderSync("", 14, QColor(0, 0, 0, 255)) + self.render("", 14, QColor(0, 0, 0, 255)) 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. - """ - 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(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: + 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_hash, export_path = self.create_export_path(latex_markup, font_size, color) + 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 - latex_path = path.join(self.tempdir, str(markup_hash)) + 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) @@ -195,30 +130,27 @@ class Latex(QObject): # 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'file:///{export_path}.png,{img.width()},{img.height()}' + 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: """ Finds a prerendered image and returns its data if possible, and an empty string if not. """ - markup_hash, render_hash, export_path = self.create_export_path(latex_markup, font_size, color) + 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'file:///{export_path}.png,{img.width()},{img.height()}' + 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 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()) - 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 + 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): """ @@ -261,7 +193,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) + 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: diff --git a/runtime-pyside6/LogarithmPlotter/util/native.py b/runtime-pyside6/LogarithmPlotter/util/native.py index 3adf153..7e32119 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-2025 Ad5001 + * 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 @@ -49,7 +49,3 @@ class MacOSFileOpenHandler(QObject): else: # standard event processing return QObject.eventFilter(self, obj, event) - - - - diff --git a/runtime-pyside6/LogarithmPlotter/util/promise.py b/runtime-pyside6/LogarithmPlotter/util/promise.py deleted file mode 100644 index 8e17651..0000000 --- a/runtime-pyside6/LogarithmPlotter/util/promise.py +++ /dev/null @@ -1,175 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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, Property, QObject, Slot, QThreadPool -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: - """ - 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 callable(function): - return function - return None - -class InvalidReturnValue(Exception): pass - - -class PyPromiseRunner(QRunnable): - """ - QRunnable for running Promises in different threads. - """ - def __init__(self, runner, promise, args): - QRunnable.__init__(self) - self.runner = runner - self.promise = promise - self.args = args - - def run(self): - try: - data = self.runner(*self.args) - if type(data) in [int, str, float, bool]: - 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 JS Value, or None.") - self.promise.fulfilled.emit(data) - except Exception as e: - try: - 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. - pass - - -class PyPromise(QObject): - """ - 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) - rejected = Signal(str) - - 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) - 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. - print("Starting", self._runner.args) - QThreadPool.globalInstance().start(self._runner) - self._started = True - - @Property(str) - def state(self): - return self._state - - @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. - """ - on_fulfill = check_callable(on_fulfill) - on_reject = check_callable(on_reject) - self._fulfills.append(on_fulfill) - 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) - def _fulfill(self, data): - self._state = "fulfilled" - 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. - except Exception as e: - self._reject(repr(e), start_at=i) - break - - @Slot(QJSValue) - @Slot(str) - def _reject(self, error, start_at=0): - self._state = "rejected" - 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/LogarithmPlotter/util/update.py b/runtime-pyside6/LogarithmPlotter/util/update.py index e18b93e..1d2ecec 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-2025 Ad5001 + * 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 diff --git a/runtime-pyside6/poetry.lock b/runtime-pyside6/poetry.lock index 9a66e3e..a4727e1 100644 --- a/runtime-pyside6/poetry.lock +++ b/runtime-pyside6/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "altgraph" @@ -24,74 +24,83 @@ files = [ [[package]] name = "coverage" -version = "7.8.0" +version = "7.6.1" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "coverage-7.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2931f66991175369859b5fd58529cd4b73582461877ecfd859b6549869287ffe"}, - {file = "coverage-7.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52a523153c568d2c0ef8826f6cc23031dc86cffb8c6aeab92c4ff776e7951b28"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c8a5c139aae4c35cbd7cadca1df02ea8cf28a911534fc1b0456acb0b14234f3"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a26c0c795c3e0b63ec7da6efded5f0bc856d7c0b24b2ac84b4d1d7bc578d676"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821f7bcbaa84318287115d54becb1915eece6918136c6f91045bb84e2f88739d"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a321c61477ff8ee705b8a5fed370b5710c56b3a52d17b983d9215861e37b642a"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ed2144b8a78f9d94d9515963ed273d620e07846acd5d4b0a642d4849e8d91a0c"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:042e7841a26498fff7a37d6fda770d17519982f5b7d8bf5278d140b67b61095f"}, - {file = "coverage-7.8.0-cp310-cp310-win32.whl", hash = "sha256:f9983d01d7705b2d1f7a95e10bbe4091fabc03a46881a256c2787637b087003f"}, - {file = "coverage-7.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a570cd9bd20b85d1a0d7b009aaf6c110b52b5755c17be6962f8ccd65d1dbd23"}, - {file = "coverage-7.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27"}, - {file = "coverage-7.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9"}, - {file = "coverage-7.8.0-cp311-cp311-win32.whl", hash = "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c"}, - {file = "coverage-7.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe"}, - {file = "coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545"}, - {file = "coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b"}, - {file = "coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd"}, - {file = "coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3"}, - {file = "coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d"}, - {file = "coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487"}, - {file = "coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25"}, - {file = "coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883"}, - {file = "coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada"}, - {file = "coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257"}, - {file = "coverage-7.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa260de59dfb143af06dcf30c2be0b200bed2a73737a8a59248fcb9fa601ef0f"}, - {file = "coverage-7.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96121edfa4c2dfdda409877ea8608dd01de816a4dc4a0523356067b305e4e17a"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8af63b9afa1031c0ef05b217faa598f3069148eeee6bb24b79da9012423b82"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b1f4af0d4afe495cd4787a68e00f30f1d15939f550e869de90a86efa7e0814"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ec0be97723ae72d63d3aa41961a0b9a6f5a53ff599813c324548d18e3b9e8c"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a1d96e780bdb2d0cbb297325711701f7c0b6f89199a57f2049e90064c29f6bd"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f1d8a2a57b47142b10374902777e798784abf400a004b14f1b0b9eaf1e528ba4"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cf60dd2696b457b710dd40bf17ad269d5f5457b96442f7f85722bdb16fa6c899"}, - {file = "coverage-7.8.0-cp39-cp39-win32.whl", hash = "sha256:be945402e03de47ba1872cd5236395e0f4ad635526185a930735f66710e1bd3f"}, - {file = "coverage-7.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:90e7fbc6216ecaffa5a880cdc9c77b7418c1dcb166166b78dbc630d07f278cc3"}, - {file = "coverage-7.8.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd"}, - {file = "coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7"}, - {file = "coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501"}, + {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] @@ -116,13 +125,13 @@ test = ["pytest (>=6)"] [[package]] name = "importlib-metadata" -version = "8.6.1" +version = "8.5.0" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, - {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, + {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] @@ -134,18 +143,18 @@ 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)"] +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.1.0" +version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] @@ -164,24 +173,24 @@ altgraph = ">=0.17" [[package]] name = "packaging" -version = "25.0" +version = "24.1" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] name = "pefile" -version = "2023.2.7" +version = "2024.8.26" description = "Python PE parsing module" optional = false python-versions = ">=3.6.0" files = [ - {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"}, - {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"}, + {file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"}, + {file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"}, ] [[package]] @@ -201,32 +210,32 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyinstaller" -version = "6.13.0" +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.13.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:aa404f0b02cd57948098055e76ee190b8e65ccf7a2a3f048e5000f668317069f"}, - {file = "pyinstaller-6.13.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:92efcf2f09e78f07b568c5cb7ed48c9940f5dad627af4b49bede6320fab2a06e"}, - {file = "pyinstaller-6.13.0-py3-none-manylinux2014_i686.whl", hash = "sha256:9f82f113c463f012faa0e323d952ca30a6f922685d9636e754bd3a256c7ed200"}, - {file = "pyinstaller-6.13.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:db0e7945ebe276f604eb7c36e536479556ab32853412095e19172a5ec8fca1c5"}, - {file = "pyinstaller-6.13.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:92fe7337c5aa08d42b38d7a79614492cb571489f2cb0a8f91dc9ef9ccbe01ed3"}, - {file = "pyinstaller-6.13.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:bc09795f5954135dd4486c1535650958c8218acb954f43860e4b05fb515a21c0"}, - {file = "pyinstaller-6.13.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:589937548d34978c568cfdc39f31cf386f45202bc27fdb8facb989c79dfb4c02"}, - {file = "pyinstaller-6.13.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b7260832f7501ba1d2ce1834d4cddc0f2b94315282bc89c59333433715015447"}, - {file = "pyinstaller-6.13.0-py3-none-win32.whl", hash = "sha256:80c568848529635aa7ca46d8d525f68486d53e03f68b7bb5eba2c88d742e302c"}, - {file = "pyinstaller-6.13.0-py3-none-win_amd64.whl", hash = "sha256:8d4296236b85aae570379488c2da833b28828b17c57c2cc21fccd7e3811fe372"}, - {file = "pyinstaller-6.13.0-py3-none-win_arm64.whl", hash = "sha256:d9f21d56ca2443aa6a1e255e7ad285c76453893a454105abe1b4d45e92bb9a20"}, - {file = "pyinstaller-6.13.0.tar.gz", hash = "sha256:38911feec2c5e215e5159a7e66fdb12400168bd116143b54a8a7a37f08733456"}, + {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\""} +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,<2024.8.26 || >2024.8.26", markers = "sys_platform == \"win32\""} -pyinstaller-hooks-contrib = ">=2025.2" +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" @@ -236,64 +245,62 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2025.3" +version = "2024.8" description = "Community maintained hooks for PyInstaller" optional = false python-versions = ">=3.8" files = [ - {file = "pyinstaller_hooks_contrib-2025.3-py3-none-any.whl", hash = "sha256:70cba46b1a6b82ae9104f074c25926e31f3dde50ff217434d1d660355b949683"}, - {file = "pyinstaller_hooks_contrib-2025.3.tar.gz", hash = "sha256:af129da5cd6219669fbda360e295cc822abac55b7647d03fec63a8fcf0a608cf"}, + {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\""} +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} packaging = ">=22.0" setuptools = ">=42.0.0" [[package]] name = "pyside6-addons" -version = "6.9.0" +version = "6.7.3" description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" optional = false -python-versions = "<3.14,>=3.9" +python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Addons-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:98f9ad4b65820736e12d49c18db2e570eac63727407fbb59a62ac753e89dc201"}, - {file = "PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:fc9dcd63a0ce7565f238cb11c44494435a50eb6cb72b8dbce3b709618989c3dc"}, - {file = "PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:d8a650644e0b9d1e7a092f6bcd11f25a63706d12f77d442b6ace75d346ab5d30"}, - {file = "PySide6_Addons-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:8cf54065b3d1b4698448fad825378a25c10ef52017d9dff48cead03200636d8d"}, - {file = "PySide6_Addons-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:260a56da59539f476c1635a3ff13591e10f1b04d92155c0617129bc53ca8b5f8"}, + {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.9.0" -shiboken6 = "6.9.0" +PySide6-Essentials = "6.7.3" +shiboken6 = "6.7.3" [[package]] name = "pyside6-essentials" -version = "6.9.0" +version = "6.7.3" description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" optional = false -python-versions = "<3.14,>=3.9" +python-versions = "<3.13,>=3.9" files = [ - {file = "PySide6_Essentials-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:b18e3e01b507e8a57481fe19792eb373d5f10a23a50702ce540da1435e722f39"}, - {file = "PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:45eaf7f17688d1991f39680dbfd3c41674f3cbb78f278aa10fe0b5f2f31c1989"}, - {file = "PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:69aedfad77119c5bec0005ca31d5620e9bac8ba5ae66c7389160530cfd698ed8"}, - {file = "PySide6_Essentials-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:94a0096d6bb1d3e5cef29ca4a5366d0f229d42480fbb17aa25ad85d72b1b7947"}, - {file = "PySide6_Essentials-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:d2dc45536f2269ad111991042e81257124f1cd1c9ed5ea778d7224fd65dc9e2b"}, + {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.9.0" +shiboken6 = "6.7.3" [[package]] name = "pytest" -version = "8.3.5" +version = "8.3.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, - {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, ] [package.dependencies] @@ -357,36 +364,35 @@ files = [ [[package]] name = "setuptools" -version = "75.9.1" +version = "75.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "setuptools-75.9.1-py3-none-any.whl", hash = "sha256:0a6f876d62f4d978ca1a11ab4daf728d1357731f978543ff18ecdbf9fd071f73"}, - {file = "setuptools-75.9.1.tar.gz", hash = "sha256:b6eca2c3070cdc82f71b4cb4bb2946bc0760a210d11362278cf1ff394e6ea32c"}, + {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.8.0)"] -core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +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.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.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.14.*)", "pytest-mypy"] +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.9.0" +version = "6.7.3" description = "Python/C++ bindings helper module" optional = false -python-versions = "<3.14,>=3.9" +python-versions = "<3.13,>=3.9" files = [ - {file = "shiboken6-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:c4d8e3a5907154ac4789e52c77957db95bcf584238c244d7743cb39e9b66dd26"}, - {file = "shiboken6-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3f585caae5b814a7e23308db0a077355a7dc20c34d58ca4c339ff7625e9a1936"}, - {file = "shiboken6-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:b61579b90bf9c53ecc174085a69429166dfe57a0b8b894f933d1281af9df6568"}, - {file = "shiboken6-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:121ea290ed1afa5ad6abf690b377612693436292b69c61b0f8e10b1f0850f935"}, - {file = "shiboken6-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:24f53857458881b54798d7e35704611d07f6b6885bcdf80f13a4c8bb485b8df2"}, + {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]] @@ -412,54 +418,24 @@ files = [ [[package]] name = "tomli" -version = "2.2.1" +version = "2.0.1" description = "A lil' TOML parser" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, + {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.21.0" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, - {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, ] [package.extras] @@ -473,4 +449,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "b0920ba14495c199b201802e11473e624a133c5b7b97d2e96ba5744b8bc0e4c4" +content-hash = "5636605737f21954e102a0110972e6bd3df07f2d5929f41fe541c7347c3ecf08" diff --git a/runtime-pyside6/pyproject.toml b/runtime-pyside6/pyproject.toml index ef68cb8..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.9" -PySide6-Addons = "^6.9" +PySide6-Essentials = "^6.7" +PySide6-Addons = "^6.7" [tool.poetry.group.packaging.dependencies] pyinstaller = "^6.10.0" diff --git a/runtime-pyside6/setup.py b/runtime-pyside6/setup.py index 4100042..e2bbd57 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-2025 Ad5001 + * 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 @@ -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 diff --git a/runtime-pyside6/tests/__init__.py b/runtime-pyside6/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/runtime-pyside6/tests/globals.py b/runtime-pyside6/tests/globals.py index 67a1356..def1415 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-2025 Ad5001 + * 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 diff --git a/runtime-pyside6/tests/plugins/__init__.py b/runtime-pyside6/tests/plugins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/runtime-pyside6/tests/plugins/natural/__init__.py b/runtime-pyside6/tests/plugins/natural/__init__.py deleted file mode 100644 index 180969f..0000000 --- a/runtime-pyside6/tests/plugins/natural/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 -from .interfaces.base import Assertion - diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/__init__.py b/runtime-pyside6/tests/plugins/natural/interfaces/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py b/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py deleted file mode 100644 index b81d0e5..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/assertion.py +++ /dev/null @@ -1,39 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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, 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.invert and not self.assertion: - raise self - 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 deleted file mode 100644 index c96c146..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/base.py +++ /dev/null @@ -1,171 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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, Callable, Any - -from .assertion import Assertion -from .utils import repr_ - - -class AssertionInterface: - """ - Most basic assertion interface. - You probably want to use BaseAssertionInterface - """ - - def __init__(self, value, parent: Self = None): - self._value = value - self._parent = parent - if parent is None: - self.__not = False - - @property - 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 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 - 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 - - -class EqualAssertionInterface(AssertionInterface): - """ - Interface created for when its value should be checked for equality - """ - - 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 different from {repr(value)}.", - self._not - ) - - @property - def to(self) -> Self: - return self - - -class BaseAssertionInterface(AssertionInterface): - - @property - def equals(self) -> EqualAssertionInterface: - """ - Checks if the current value is equal to the provided value - """ - return EqualAssertionInterface(self._value, self) - - @property - def equal(self) -> EqualAssertionInterface: - """ - Checks if the current value is equal to the provided value - """ - return self.equals diff --git a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py b/runtime-pyside6/tests/plugins/natural/interfaces/basic.py deleted file mode 100644 index 85720da..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/basic.py +++ /dev/null @@ -1,83 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 .assertion import Assertion -from .base import BaseAssertionInterface -from .int import NumberInterface -from .utils import repr_ - - -class FixedIteratorInterface(BaseAssertionInterface): - @property - def length(self) -> NumberInterface: - return NumberInterface(len(self._value), self) - - def elements(self, *elements) -> Assertion: - 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 {', '.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)}.", - self._not - ) - - def contains(self, *elements) -> Assertion: - """ - 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 true(self): - return Assertion( - self._value == True, - f"The value ({repr_(self._value)}) is not True.", - self._not - ) - - @property - def false(self): - return Assertion( - self._value == False, - f"The value ({repr_(self._value)}) is not False.", - self._not - ) - - -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 deleted file mode 100644 index b282e4d..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/int.py +++ /dev/null @@ -1,320 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 math import log10, floor -from typing import Self - -from .assertion import Assertion -from .base import AssertionInterface -from .utils import repr_ - - -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__}.") - - def __bool__(self) -> bool: - return bool(self._compare()) - - def __call__(self, compare_to: int) -> Self: - 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 AND(self) -> Self: - return self - - """ - Number shorthands - """ - - @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 minus(self) -> Self: - return self(-1) - - @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 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) - - @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(80) - - @property - def ninety(self) -> Self: - return self(90) - - @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(NumberComparisonAssertionInterface): - def _compare(self) -> Assertion: - compare = self._generate_compare_to() - return Assertion( - self._value < compare, - f"The value ({repr_(self._value)}) is not less than to {repr_(compare)}.", - self._not - ) - - -class MoreThanComparisonInterface(NumberComparisonAssertionInterface): - def _compare(self) -> Assertion: - compare = self._generate_compare_to() - return Assertion( - self._value > compare, - f"The value ({repr_(self._value)}) is not more than to {repr_(compare)}.", - self._not - ) - - -class AtLeastComparisonInterface(NumberComparisonAssertionInterface): - def _compare(self) -> Assertion: - compare = self._generate_compare_to() - return Assertion( - self._value >= compare, - f"The value ({repr_(self._value)}) is not at least to {repr_(compare)}.", - self._not - ) - - -class AtMostComparisonInterface(NumberComparisonAssertionInterface): - def _compare(self) -> Assertion: - compare = self._generate_compare_to() - return Assertion( - self._value <= compare, - f"The value ({repr_(self._value)}) is not at least to {repr_(compare)}.", - self._not - ) - - -class EqualComparisonInterface(NumberComparisonAssertionInterface): - def _compare(self) -> Assertion: - compare = self._generate_compare_to() - return Assertion( - self._value == compare, - f"The value ({repr_(self._value)}) is not equal to {repr_(compare)}.", - self._not - ) - - @property - def to(self) -> Self: - return self - - -class NumberInterface(AssertionInterface): - def __call__(self, value): - return EqualComparisonInterface(self._value, self)(value) - - @property - def equals(self) -> EqualComparisonInterface: - return EqualComparisonInterface(self._value, self) - - @property - def equal(self) -> EqualComparisonInterface: - return EqualComparisonInterface(self._value, self) - - @property - def exactly(self) -> EqualComparisonInterface: - 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 deleted file mode 100644 index ce0b8ff..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/spy.py +++ /dev/null @@ -1,218 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 = (" " * 3) - - -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/interfaces/utils.py b/runtime-pyside6/tests/plugins/natural/interfaces/utils.py deleted file mode 100644 index 5200975..0000000 --- a/runtime-pyside6/tests/plugins/natural/interfaces/utils.py +++ /dev/null @@ -1,27 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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/plugins/natural/spy.py b/runtime-pyside6/tests/plugins/natural/spy.py deleted file mode 100644 index 4026b20..0000000 --- a/runtime-pyside6/tests/plugins/natural/spy.py +++ /dev/null @@ -1,33 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 - - -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: - return self.function(*args, **kwargs) diff --git a/runtime-pyside6/tests/plugins/natural/that.py b/runtime-pyside6/tests/plugins/natural/that.py deleted file mode 100644 index 60ad4b6..0000000 --- a/runtime-pyside6/tests/plugins/natural/that.py +++ /dev/null @@ -1,68 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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 . import Spy -from .interfaces.base import AssertionInterface, BaseAssertionInterface -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), - (bool, BoolInterface), - (int, NumberInterface), - (float, NumberInterface), - (list, ListInterface), - (Spy, SpyAssertionInterface) -] - - -@overload -def that(value: str) -> StringInterface: ... - - -@overload -def that(value: bool) -> BoolInterface: ... - - -@overload -def that(value: int) -> NumberInterface: ... - - -@overload -def that(value: float) -> NumberInterface: ... - -@overload -def that(value: Spy) -> SpyAssertionInterface: ... - - -@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/plugins/tests/__init__.py b/runtime-pyside6/tests/plugins/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/runtime-pyside6/tests/plugins/tests/test_natural.py b/runtime-pyside6/tests/plugins/tests/test_natural.py deleted file mode 100644 index 31f85c0..0000000 --- a/runtime-pyside6/tests/plugins/tests/test_natural.py +++ /dev/null @@ -1,217 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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(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 - assert spy(30, arg="string") == 10 - 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() - 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 diff --git a/runtime-pyside6/tests/test_config.py b/runtime-pyside6/tests/test_config.py index a95a9d9..c919c6f 100644 --- a/runtime-pyside6/tests/test_config.py +++ b/runtime-pyside6/tests/test_config.py @@ -1,21 +1,3 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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_debug.py b/runtime-pyside6/tests/test_debug.py index 467e5b8..4799024 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-2025 Ad5001 + * 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 diff --git a/runtime-pyside6/tests/test_helper.py b/runtime-pyside6/tests/test_helper.py index f2f6d70..412eac3 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-2025 Ad5001 + * 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 @@ -17,7 +17,7 @@ """ import pytest -from os import getcwd, remove, path +from os import getcwd, remove from os.path import join from tempfile import TemporaryDirectory from json import loads @@ -25,12 +25,11 @@ 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 Helper, fetch_changelog, read_changelog, InvalidFileException +from LogarithmPlotter.util.helper import ChangelogFetcher, Helper, InvalidFileException pwd = getcwd() helper.SHOW_GUI_MESSAGES = False @@ -44,51 +43,41 @@ def temporary(): directory.cleanup() -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) +class MockHelperSignals(QObject): + changelogFetched = Signal(str) -CHANGELOG_BASE_PATH = path.realpath(path.join(path.dirname(path.realpath(__file__)), "..", "CHANGELOG.md")) + 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_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) - 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) - with qtbot.waitSignal(promise.fulfilled, timeout=10000): - pass - # 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) - 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. tmpfile, directory = temporary @@ -169,13 +158,25 @@ class TestHelper: obj = Helper(pwd, tmpfile) assert obj.getVersion() == version assert type(obj.getDebugInfos()) == str - 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] + 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.setSetting("check_for_updates", obj.getSetting("check_for_updates")) - obj.setSetting("default_graph.xzoom", obj.getSetting("default_graph.xzoom")) + 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/runtime-pyside6/tests/test_latex.py b/runtime-pyside6/tests/test_latex.py index e410995..f02832e 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-2025 Ad5001 + * 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 @@ -22,7 +22,6 @@ 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 @@ -32,32 +31,17 @@ latex.SHOW_GUI_MESSAGES = False @pytest.fixture() def latex_obj(): directory = TemporaryDirectory() - obj = latex.Latex(directory.name) + 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() -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 path.startswith("file:///") - assert exists(path[len("file:///"):]) - 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 @@ -70,54 +54,33 @@ class TestLatex: # Reset [latex.DVIPNG_PATH, latex.LATEX_PATH] = bkp - def test_render_sync(self, latex_obj: latex.Latex) -> None: - result = latex_obj.renderSync("\\frac{d \\sqrt{\\mathrm{f}(x \\times 2.3)}}{dx}", 14, BLACK) + 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 - check_render_results(result) + 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.renderSync("\\nonexistant", 14, BLACK) + 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.renderSync("\\mathrm{f}(x)", 14, BLACK) - # Replace latex bin with one goes indefinitely - # latex.LATEX_PATH = which("import") # TODO: Find one such executable - # with pytest.raises(latex.RenderError): - # latex_obj.renderSync("\\mathrm{f}(x)", 14, BLACK) + 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 = ["\\frac{d \\sqrt{\\mathrm{f}(x \\times 2.3)}}{dx}", 14, BLACK] - latex_obj.renderSync(*args) + 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 - check_render_results(prerendered) + [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 == "" - 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_main.py b/runtime-pyside6/tests/test_main.py index 1595236..d8a56b6 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-2025 Ad5001 + * 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 @@ -22,13 +22,12 @@ 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", @@ -40,10 +39,11 @@ THEMES = [ ] OS_PLATFORMS = [ - "Linux", - "Windows", - "Darwin", - "Android" + "linux", + "freebsd", + "win32", + "cygwin", + "darwin" ] @pytest.fixture() @@ -91,7 +91,7 @@ class TestMain: # Engine tmpfile, tempdir = temporary helper = Helper(".", tmpfile) - latex = Latex(tempdir.name) + 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 diff --git a/runtime-pyside6/tests/test_native.py b/runtime-pyside6/tests/test_native.py index d60b907..6fc2d65 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-2025 Ad5001 + * 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 @@ -17,6 +17,7 @@ """ 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 deleted file mode 100644 index ef71a55..0000000 --- a/runtime-pyside6/tests/test_promise.py +++ /dev/null @@ -1,177 +0,0 @@ -""" - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * 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 - * 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.QtQml import QJSValue - -from .plugins.natural import that, 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_invalid_function(self): - with pytest.raises(ValueError): - promise = PyPromise("not a function") - - 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): - 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): - fulfilled = Spy() - rejected = Spy() - promise = PyPromise(create_async_func(3)) - then_res = promise.then(fulfilled, rejected) - # Check if the return value is the same promise (so we can chain then) - assert that(then_res).does.equal(promise) - # Check on our spy. - with qtbot.waitSignal(promise.fulfilled, timeout=10000): - pass - 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): - fulfilled = Spy() - rejected = Spy() - promise = PyPromise(async_throw) - then_res = promise.then(fulfilled, rejected) - # Check if the return value is the same promise (so we can chain then) - assert that(then_res).does.equal(promise) - # Check on our spies. - with qtbot.waitSignal(promise.rejected, timeout=10000): - pass - 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 9177b4e..5742cfc 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-2025 Ad5001 + * 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 @@ -21,6 +21,7 @@ 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/runtime-pyside6/tests/test_update.py b/runtime-pyside6/tests/test_update.py index 16b562e..9f65597 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-2025 Ad5001 + * 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 @@ -49,20 +49,19 @@ 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) - with qtbot.waitSignal(update_info_newer.got_update_info, timeout=10000): - runnable.run() + runnable.run() + qtbot.waitSignal(update_info_newer.got_update_info, timeout=10000) runnable = UpdateCheckerRunnable('0.1.0', update_info_older) - with qtbot.waitSignal(update_info_older.got_update_info, timeout=10000): - runnable.run() + runnable.run() + qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) runnable = UpdateCheckerRunnable('0.5.0+dev0+git20240101', update_info_older) - with qtbot.waitSignal(update_info_older.got_update_info, timeout=10000): - runnable.run() + runnable.run() + qtbot.waitSignal(update_info_older.got_update_info, timeout=10000) def test_update_checker(qtbot): update_info = check_for_updates('0.6.0', MockWindow()) - assert QThreadPool.globalInstance().activeThreadCount() >= 1 - with qtbot.waitSignal(update_info.got_update_info, timeout=10000): - pass + 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()) assert QThreadPool.globalInstance().activeThreadCount() < 2 # No new update checks where added diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 8f3f38d..2ccd626 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" \ diff --git a/scripts/build.sh b/scripts/build.sh index 8d170bf..be25274 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-2025 Ad5001 +# 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 @@ -22,10 +22,6 @@ 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"))─┐" @@ -34,23 +30,20 @@ box() { } rm -rf build -mkdir -p "$BUILD_DIR" +mkdir -p build/runtime-pyside6 # Copy python box "Copying pyside6 python runtime..." -cp -r runtime-pyside6/{setup.py,LogarithmPlotter} "$BUILD_DIR" +cp -r runtime-pyside6/{setup.py,LogarithmPlotter} build/runtime-pyside6 box "Building ecmascript modules..." -mkdir -p "$BUILD_QML_DIR/js" -cd common && \ - (npm run build || exit) && \ - cd .. +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_DIR/LogarithmPlotter/i18n" && cp assets/i18n/*.qm "$BUILD_DIR/LogarithmPlotter/i18n/" +mkdir -p build/runtime-pyside6/LogarithmPlotter/i18n && cp assets/i18n/*.qm build/runtime-pyside6/LogarithmPlotter/i18n/ box "Building icons..." -cp -r assets/icons "$BUILD_QML_DIR" -cp assets/logarithmplotter.svg "$BUILD_QML_DIR/icons/" -cp assets/logarithmplotter.svg "$BUILD_DIR/LogarithmPlotter/" +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 index e01c370..8ed03ee 100755 --- a/scripts/package-deb.sh +++ b/scripts/package-deb.sh @@ -26,18 +26,7 @@ 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.wheels)" --section science \ - --debian-version +wheels-1 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 \ - --debian-version +packaged-1 bdist_deb - -mv deb_dist deb_dist.oracular + --suite noble --depends3 "$(cat assets/native/linux/debian/depends)" --section science \ + bdist_deb diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index 3f73e37..1410244 100644 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -1,20 +1,8 @@ #!/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 . || exit 1 -cd ../../../ - while [ $# -gt 0 ]; do case "$1" in --no-rebuild) @@ -35,16 +23,13 @@ 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 -box "Testing runtime-pyside6..." -PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . || exit 1 +PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing . cd ../../ # Run js tests cd common || exit 1 -box "Testing common..." -npm test || exit 1 +npm test diff --git a/scripts/sign-deb.sh b/scripts/sign-deb.sh index 05bee26..f8e0a9a 100755 --- a/scripts/sign-deb.sh +++ b/scripts/sign-deb.sh @@ -1,26 +1,23 @@ #!/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/" || exit 1 +cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/deb_dist" || exit 1 PPA_ARCHIVE="ppa:ad5001/logarithmplotter" -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 * +# create a temporary folder +mkdir tmp -p +cd tmp +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" -done +# upload package to my PPA +dput $PPA_ARCHIVE "../${source_package_name}_source.changes"