diff --git a/MySQLShellPluginDevelopment.code-workspace b/MySQLShellPluginDevelopment.code-workspace index 80e5219f6..fa7bbf2e3 100644 --- a/MySQLShellPluginDevelopment.code-workspace +++ b/MySQLShellPluginDevelopment.code-workspace @@ -40,6 +40,10 @@ { "name": "Shell Plugin Tools", "path": "gui/tools" + }, + { + "name": "Shell Utility Plugin Additions", + "path": "util_plugin" } ], "settings": { diff --git a/VERSION b/VERSION index 5dd06304a..2d3fe0e93 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION=1.19.12 +VERSION=1.19.13 diff --git a/gui/backend/gui_plugin/core/GuiBackendDbManager.py b/gui/backend/gui_plugin/core/GuiBackendDbManager.py index ca8fc32e2..2616b2767 100644 --- a/gui/backend/gui_plugin/core/GuiBackendDbManager.py +++ b/gui/backend/gui_plugin/core/GuiBackendDbManager.py @@ -38,7 +38,7 @@ from gui_plugin.core.lib.Version import Version # Refers to the schema version supported by this version of the code -CURRENT_DB_VERSION = Version((0, 0, 22)) +CURRENT_DB_VERSION = Version((0, 0, 23)) # Do not change it, it was dropped in 0.0.16 and that is valid value DROPPED_VERSION_IN_NAME_DB_VERSION = Version((0, 0, 16)) OLDEST_SUPPORTED_DB_VERSION = Version((0, 0, 11)) diff --git a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mwb b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mwb index 4fd714d02..5d42c50b1 100644 Binary files a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mwb and b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mwb differ diff --git a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mysql.sql b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mysql.sql index 1b09d94ce..6ad4b53c4 100644 --- a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mysql.sql +++ b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.mysql.sql @@ -562,6 +562,7 @@ CREATE TABLE IF NOT EXISTS `folder_path` ( `parent_folder_id` INT NULL, `caption` VARCHAR(256) NOT NULL, `index` INT NULL, + `settings` TEXT NULL, PRIMARY KEY (`id`), INDEX `fk_folder_path_folder_path1_idx` (`parent_folder_id` ASC) VISIBLE, INDEX `index_idx` (`index` ASC) VISIBLE, @@ -577,7 +578,7 @@ ENGINE = InnoDB -- View `schema_version` -- ----------------------------------------------------- DROP VIEW IF EXISTS `schema_version` ; -CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 22; +CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 23; -- ----------------------------------------------------- -- Data for table `data_category` diff --git a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.sqlite.sql b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.sqlite.sql index abb24b168..e2c4f0d77 100644 --- a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.sqlite.sql +++ b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend.sqlite.sql @@ -562,6 +562,7 @@ CREATE TABLE IF NOT EXISTS `folder_path` ( `parent_folder_id` INTEGER NULL, `caption` VARCHAR(256) NOT NULL, `index` INTEGER NULL, + `settings` TEXT NULL, PRIMARY KEY (`id`), CONSTRAINT `fk_folder_path_folder_path1` FOREIGN KEY (`parent_folder_id`) @@ -631,7 +632,7 @@ CREATE TABLE IF NOT EXISTS `logs`.`message` ( -- View `schema_version` -- ----------------------------------------------------- DROP VIEW IF EXISTS `schema_version` ; -CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 22; +CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 23; -- ----------------------------------------------------- -- Data for table `data_category` diff --git a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.mysql.sql b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.mysql.sql new file mode 100644 index 000000000..b04fa1d8b --- /dev/null +++ b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.mysql.sql @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * 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, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Add settings for folder_path +-- ----------------------------------------------------- +BEGIN TRANSACTION; +ALTER TABLE `folder_path` +ADD COLUMN `settings` TEXT NULL; + +COMMIT; + +-- ----------------------------------------------------- +-- View `schema_version` +-- ----------------------------------------------------- +DROP VIEW IF EXISTS `schema_version` ; +CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 23; + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.sqlite.sql b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.sqlite.sql new file mode 100644 index 000000000..cc4a75f8b --- /dev/null +++ b/gui/backend/gui_plugin/core/db_schema/mysqlsh_gui_backend_0.0.22_to_0.0.23.sqlite.sql @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * + * 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, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +PRAGMA foreign_keys = OFF; + +-- ----------------------------------------------------- +-- Add settings for folder_path +-- ----------------------------------------------------- +BEGIN TRANSACTION; +ALTER TABLE `folder_path` +ADD COLUMN `settings` TEXT NULL; + +COMMIT; + +-- ----------------------------------------------------- +-- View `schema_version` +-- ----------------------------------------------------- +DROP VIEW IF EXISTS `schema_version`; +CREATE VIEW schema_version (major, minor, patch) AS SELECT 0, 0, 23; + +PRAGMA foreign_keys = ON; \ No newline at end of file diff --git a/gui/backend/gui_plugin/core/dbms/DbMySQLSession.py b/gui/backend/gui_plugin/core/dbms/DbMySQLSession.py index 954808743..83a70f1e0 100644 --- a/gui/backend/gui_plugin/core/dbms/DbMySQLSession.py +++ b/gui/backend/gui_plugin/core/dbms/DbMySQLSession.py @@ -43,7 +43,7 @@ MySQLColumnsListTask, MySQLRoutinesListTask) from gui_plugin.core.dbms.DbSession import (DbSession, DbSessionFactory, - ReconnectionMode) + ReconnectionMode, lock_usage) from gui_plugin.core.dbms.DbSessionTasks import (DbExecuteTask, check_supported_type) from gui_plugin.core.Error import MSGException @@ -131,6 +131,12 @@ def is_connection_error(self, error): return False def run_sql(self, sql, args=None): + """ + Executes an sql statement, returns a result object. + + WARNING: Use LOCKED state to call this function anc consume it's result, + otherwise may lead to race conditions and shell crashes (see lock_usage) + """ return self.session.run_sql(sql, args) def on_shell_prompt(self, text, options): @@ -373,8 +379,9 @@ def start_transaction(self): self.execute("START TRANSACTION") def kill_query(self, user_session): - user_session._killed = True - self.session.run_sql(f"KILL QUERY {user_session.connection_id}") + with lock_usage(self._mutex, 5): + user_session._killed = True + self.run_sql(f"KILL QUERY {user_session.connection_id}") def get_default_schema(self): return self._connection_options['schema'] if 'schema' in self._connection_options else '' @@ -753,11 +760,11 @@ def get_columns_metadata(self, names): f"The columns {column_names} do not exist.") return {"columns": result} - def get_routines_metadata(self, schema_name): params = (schema_name,) - has_external_language = self._column_exists("ROUTINES", "EXTERNAL_LANGUAGE") + has_external_language = self._column_exists( + "ROUTINES", "EXTERNAL_LANGUAGE") if has_external_language: sql = """SELECT ROUTINE_NAME as 'name', ROUTINE_TYPE as 'type', EXTERNAL_LANGUAGE as 'language' FROM information_schema.ROUTINES @@ -783,10 +790,9 @@ def get_routines_metadata(self, schema_name): result = [] if not result: raise MSGException(Error.DB_OBJECT_DOES_NOT_EXISTS, - f"The '{schema_name}' does not exist.") + f"The '{schema_name}' does not exist.") return {"routines": result} - def _column_exists(self, table_name, column_name): """Check if a column exists in INFORMATION_SCHEMA table.""" @@ -796,9 +802,10 @@ def _column_exists(self, table_name, column_name): AND TABLE_NAME = ? AND COLUMN_NAME = ?""" - cursor = self.cursor = self.run_sql(sql, (table_name, column_name)) + with lock_usage(self._mutex, 5): + cursor = self.cursor = self.run_sql(sql, (table_name, column_name)) - if cursor: - result = cursor.fetch_one() - return result and result.get_field("count") > 0 - return False \ No newline at end of file + if cursor: + result = cursor.fetch_one() + return result and result.get_field("count") > 0 + return False diff --git a/gui/backend/gui_plugin/db_connections/DbConnections.py b/gui/backend/gui_plugin/db_connections/DbConnections.py index e17cfb6a9..2123ac552 100644 --- a/gui/backend/gui_plugin/db_connections/DbConnections.py +++ b/gui/backend/gui_plugin/db_connections/DbConnections.py @@ -391,15 +391,19 @@ def move_connection(profile_id, folder_id, connection_id_to_move, connection_id_ @plugin_function('gui.dbConnections.addFolderPath', cli=True, shell=True, web=True) -def add_folder_path(profile_id, caption, parent_folder_id=None, be_session=None): +def add_folder_path(profile_id, caption, settings=None, parent_folder_id=None, be_session=None): """Add a new folder path Args: profile_id (int): The id of the profile caption (str): The caption of the folder + settings (dict): Additional settings for the folder, optional parent_folder_id (int): The id of the parent folder, optional be_session (object): A session to the GUI backend database where the operation will be performed. + Allowed options for settings: + color (str): The color of the tile + Returns: int: The folder path ID """ @@ -411,9 +415,9 @@ def add_folder_path(profile_id, caption, parent_folder_id=None, be_session=None) if folder_path_id is None: index = db_connections.get_next_connection_index( db, profile_id, parent_folder_id) - db.execute('''INSERT INTO folder_path (parent_folder_id, caption, `index`) - VALUES (?, ?, ?)''', - (parent_folder_id, caption, index)) + db.execute('''INSERT INTO folder_path (parent_folder_id, caption, `index`, settings) + VALUES (?, ?, ?, ?)''', + (parent_folder_id, caption, index, json.dumps(settings or {}))) folder_path_id = db.get_last_row_id() return db.select('''SELECT * FROM folder_path WHERE id=?''', (folder_path_id,))[0] @@ -548,10 +552,47 @@ def list_all(profile_id, folder_id=None, be_session=None): LEFT JOIN db_connection dc ON p_dc.db_connection_id = dc.id WHERE p_dc.profile_id = ? AND p_dc.folder_path_id = ? UNION ALL - SELECT fp.id, fp.caption, NULL AS description, NULL AS db_type, NULL AS options, NULL AS settings, fp.`index`, 'folder' AS type + SELECT fp.id, fp.caption, NULL AS description, NULL AS db_type, NULL AS options, fp.settings, fp.`index`, 'folder' AS type FROM folder_path fp WHERE fp.parent_folder_id = ? ORDER BY `index` ASC ''', (profile_id, folder_id if folder_id is not None else 1, folder_id if folder_id is not None else 1)) return combined_list + + +@plugin_function('gui.dbConnections.updateFolderSettings', cli=True, shell=True, web=True) +def update_folder_settings(folder_path_id, new_settings, be_session=None): + """Rename a folder path + + Args: + folder_path_id (int): The id of the folder path to rename + new_settings (dict): The new settings for the folder path + be_session (object): A session to the GUI backend database where the operation will be performed. + + Allowed options for new_settings: + color (str): The color of the tile + + Returns: + None + """ + with BackendDatabase(be_session) as db: + db.execute('''UPDATE folder_path SET settings=? WHERE id=?''', + (new_settings, folder_path_id)) + + +@plugin_function('gui.dbConnections.getFolder', cli=True, shell=True, web=True) +def get_folder(folder_path_id, be_session=None): + """Get folder + + Args: + folder_path_id (int): The id of the folder + be_session (object): A session to the GUI backend database + where the operation will be performed. + + Returns: + dict: The folder + """ + with BackendDatabase(be_session) as db: + return db.select('SELECT * FROM folder_path WHERE id = ?', + (folder_path_id,))[0] diff --git a/gui/backend/gui_plugin/general.py b/gui/backend/gui_plugin/general.py index faf27e50d..2965fb1c7 100644 --- a/gui/backend/gui_plugin/general.py +++ b/gui/backend/gui_plugin/general.py @@ -24,7 +24,7 @@ from mysqlsh.plugin_manager import plugin_function # Define plugin version -VERSION = "1.19.12" +VERSION = "1.19.13" @plugin_function('gui.info', shell=True, cli=True, web=True) def info(): diff --git a/gui/backend/tests/shell/test_integration.py b/gui/backend/tests/shell/test_integration.py index ad5ba279f..76fc4e2a3 100644 --- a/gui/backend/tests/shell/test_integration.py +++ b/gui/backend/tests/shell/test_integration.py @@ -166,7 +166,7 @@ def test_gui_db_connections(): add_db_connection(profile_id, connection[, folder_path_id][, be_session]) Add a new db_connection and associate the connection with a profile - add_folder_path(profile_id, caption[, parent_folder_id][, be_session]) + add_folder_path(profile_id, caption[, settings][, parent_folder_id][, be_session]) Add a new folder path delete_credential(url) @@ -178,6 +178,9 @@ def test_gui_db_connections(): get_db_types() Get the list of db_types + get_folder(folder_path_id[, be_session]) + Get folder + help([member]) Provides help about this object and it's members @@ -220,7 +223,10 @@ def test_gui_db_connections(): Opens test connection update_db_connection(profile_id, connection_id[, connection][, folder_path_id][, be_session]) - Update the data for a database connection''' + Update the data for a database connection + + update_folder_settings(folder_path_id, new_settings[, be_session]) + Rename a folder path''' assert help_text == mysqlsh.globals.gui.db_connections.help() # pylint: disable=no-member diff --git a/gui/backend/tests/websocket/single_user/as_admin/dbconnections/folder_paths.py b/gui/backend/tests/websocket/single_user/as_admin/dbconnections/folder_paths.py index c220e8956..ac6d136a1 100644 --- a/gui/backend/tests/websocket/single_user/as_admin/dbconnections/folder_paths.py +++ b/gui/backend/tests/websocket/single_user/as_admin/dbconnections/folder_paths.py @@ -100,7 +100,8 @@ "id": ws.tokens['develop_folder_path_id'], "parent_folder_id": 1, "caption": "develop", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -197,13 +198,15 @@ "id": ws.tokens['develop_folder_path_id'], "parent_folder_id": 1, "caption": "develop", - "index": ws.ignore + "index": ws.ignore, + "settings": {} }, { "id": ws.tokens['test_folder_path_id'], "parent_folder_id": 1, "caption": "test", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -237,7 +240,8 @@ "id": ws.tokens['sub_develop_folder_path_id'], "parent_folder_id": ws.tokens['develop_folder_path_id'], "caption": "sub_develop", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -367,19 +371,22 @@ "id": ws.tokens['subfolder1_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder1", - "index": ws.ignore + "index": ws.ignore, + "settings": {} }, { "id": ws.tokens['subfolder2_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder2", - "index": ws.ignore + "index": ws.ignore, + "settings": {} }, { "id": ws.tokens['subfolder3_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder3", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -458,8 +465,20 @@ 'msg': '' }, 'result': [ - {"id": ws.tokens['develop_folder_path_id'], "parent_folder_id": 1, "caption": "development", "index": ws.ignore}, - {"id": ws.tokens['test_folder_path_id'], "parent_folder_id": 1, "caption": "test", "index": ws.ignore} + { + "id": ws.tokens['develop_folder_path_id'], + "parent_folder_id": 1, + "caption": "development", + "index": ws.ignore, + "settings": {} + }, + { + "id": ws.tokens['test_folder_path_id'], + "parent_folder_id": 1, + "caption": "test", + "index": ws.ignore, + "settings": {} + } ], 'request_id': ws.lastGeneratedRequestId, }, @@ -485,9 +504,27 @@ 'msg': '' }, 'result': [ - {"id": ws.tokens['subfolder1_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder_one", "index": ws.ignore}, - {"id": ws.tokens['subfolder2_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder_two", "index": ws.ignore}, - {"id": ws.tokens['subfolder3_id'], "parent_folder_id": ws.tokens['test_folder_path_id'], "caption": "subfolder3", "index": ws.ignore} + { + "id": ws.tokens['subfolder1_id'], + "parent_folder_id": ws.tokens['test_folder_path_id'], + "caption": "subfolder_one", + "index": ws.ignore, + "settings": {} + }, + { + "id": ws.tokens['subfolder2_id'], + "parent_folder_id": ws.tokens['test_folder_path_id'], + "caption": "subfolder_two", + "index": ws.ignore, + "settings": {} + }, + { + "id": ws.tokens['subfolder3_id'], + "parent_folder_id": ws.tokens['test_folder_path_id'], + "caption": "subfolder3", + "index": ws.ignore, + "settings": {} + } ], 'request_id': ws.lastGeneratedRequestId, }, @@ -698,7 +735,8 @@ "id": ws.tokens['sub_recursive1_id'], "parent_folder_id": ws.tokens['recursive_folder_id'], "caption": "sub_recursive1", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -733,13 +771,15 @@ "id": ws.tokens['sub_recursive1_id'], "parent_folder_id": ws.tokens['recursive_folder_id'], "caption": "sub_recursive1", - "index": ws.ignore + "index": ws.ignore, + "settings": {} }, { "id": ws.tokens['subsub_recursive1_id'], "parent_folder_id": ws.tokens['sub_recursive1_id'], "caption": "subsub_recursive1", - "index": ws.ignore + "index": ws.ignore, + "settings": {} } ], 'request_id': ws.lastGeneratedRequestId, @@ -815,7 +855,7 @@ "description": null, "db_type": null, "options": null, - "settings": null, + "settings": {}, "index": ws.ignore, "type": "folder" }, diff --git a/gui/extension/CHANGELOG.md b/gui/extension/CHANGELOG.md index cfc371374..8d9d23f37 100644 --- a/gui/extension/CHANGELOG.md +++ b/gui/extension/CHANGELOG.md @@ -1,5 +1,18 @@ # MySQL Shell for VS Code Change Log +## Changes in 1.19.13+9.3.1 + +### Additions + +- Error highlighting for Javascript stored programs +- Usability and functionality improvements in the Connection Overview + +### Fixes + +- BUG#38037847 Type-check errors in generated Python SDK file with Async Procedure +- BUG#38005572 Python SDK: cannot call procedure which has no parameters +- + ## Changes in 1.19.12+9.3.1 ### Additions diff --git a/gui/extension/README.md b/gui/extension/README.md index eff1ac091..d349c3938 100644 --- a/gui/extension/README.md +++ b/gui/extension/README.md @@ -1,4 +1,4 @@ -# MySQL Shell for VS Code 1.19.12+9.3.1 +# MySQL Shell for VS Code 1.19.13+9.3.1 The MySQL Shell for VS Code extension integrates the powerful feature set of MySQL Shell - an advanced MySQL client for developers and DBAs - directly into VS Code. diff --git a/gui/extension/images/dark/openConnection.svg b/gui/extension/images/dark/openConnection.svg deleted file mode 100644 index c4037ba3d..000000000 --- a/gui/extension/images/dark/openConnection.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/gui/extension/images/light/openConnection.svg b/gui/extension/images/light/openConnection.svg deleted file mode 100644 index 6d52f480e..000000000 --- a/gui/extension/images/light/openConnection.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/gui/extension/package.json b/gui/extension/package.json index d90caf2de..f6d4d56e4 100644 --- a/gui/extension/package.json +++ b/gui/extension/package.json @@ -7,7 +7,7 @@ "color": "#2789e1", "theme": "dark" }, - "version": "1.19.12", + "version": "1.19.13", "publisher": "Oracle", "license": "SEE LICENSE IN LICENSE.txt", "repository": { @@ -227,6 +227,11 @@ "default": true, "description": "If set, a message section is shown with some useful links." }, + "msg.dbEditor.connectionBrowser.sortFoldersFirst": { + "type": "boolean", + "default": false, + "description": "If set, folders are sorted before connections in the connection overview." + }, "msg.sql.limitRowCount": { "type": "number", "default": 1000, @@ -463,6 +468,10 @@ "command": "msg.fileBugReport", "title": "File Bug Report" }, + { + "command": "msg.importWorkbenchConnections", + "title": "Import MySQL Workbench Connections" + }, { "command": "msg.restartShell", "title": "Restart the Internal MySQL Shell Process" @@ -761,10 +770,6 @@ "command": "msg.mrs.editSchema", "title": "Edit REST Schema..." }, - { - "command": "msg.mrs.dumpCreateSchemaSql", - "title": "Dump REST Schema SQL..." - }, { "command": "msg.mrs.editAuthApp", "title": "Edit Authentication App" @@ -841,10 +846,6 @@ "command": "msg.mrs.exportServiceSdk", "title": "Dump REST Client SDK Files ..." }, - { - "command": "msg.mrs.exportServiceSdk", - "title": "Dump REST Client SDK Files ..." - }, { "command": "msg.mrs.dumpCreateServiceSql", "title": "Dump REST SERVICE SQL Script..." @@ -1100,6 +1101,18 @@ { "command": "msg.msm.generateDeploymentScript", "title": "Generate Deployment Script" + }, + { + "command": "msg.addSubFolder", + "title": "Add Sub Folder" + }, + { + "command": "msg.editFolder", + "title": "Edit Folder" + }, + { + "command": "msg.removeFolder", + "title": "Delete Folder" } ], "submenus": [ @@ -1418,8 +1431,13 @@ "when": "view == msg.connections" }, { - "command": "msg.fileBugReport", + "command": "msg.importWorkbenchConnections", "group": "3_msg@1", + "when": "view == msg.connections && false" + }, + { + "command": "msg.fileBugReport", + "group": "4_msg@1", "when": "view == msg.connections" }, { @@ -1436,23 +1454,23 @@ "view/item/context": [ { "command": "msg.refreshConnection", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "inline" }, { "command": "msg.openConnectionNotebook", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "inline" }, { "command": "msg.openConnectionSqlScript", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "inline" }, { "command": "msg.openConnection", "alt": "msg.openConnectionNewTab", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "1_msg@1" }, { @@ -1462,17 +1480,17 @@ }, { "command": "msg.editConnection", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "3_msg@1" }, { "command": "msg.duplicateConnection", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "3_msg@2" }, { "command": "msg.removeConnection", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "3_msg@3" }, { @@ -1483,7 +1501,7 @@ }, { "command": "msg.loadScriptFromDisk", - "when": "view == msg.connections && viewItem =~ /^connection.*/", + "when": "view == msg.connections && viewItem == connectionMySQL || viewItem == connectionSqlite", "group": "5_msg@1" }, { @@ -1639,27 +1657,27 @@ { "command": "msg.newScriptSqlite", "group": "inline@2", - "when": "view == msg.openEditors && viewItem == connectionSQLite" + "when": "view == msg.openEditors && viewItem == connectionSqlite" }, { "command": "msg.newScriptSqlite", "group": "scripts@2", - "when": "view == msg.openEditors && viewItem == connectionSQLite" + "when": "view == msg.openEditors && viewItem == connectionSqlite" }, { "command": "msg.newScriptJs", "group": "scripts@3", - "when": "view == msg.openEditors && viewItem =~ /^connection.*/" + "when": "view == msg.openEditors && viewItem == connectionMySQL || viewItem == connectionSqlite" }, { "command": "msg.newScriptTs", "group": "scripts@4", - "when": "view == msg.openEditors && viewItem =~ /^connection.*/" + "when": "view == msg.openEditors && viewItem == connectionMySQL || viewItem == connectionSqlite" }, { "command": "msg.loadScriptFromDisk", "group": "scripts2@1", - "when": "view == msg.openEditors && viewItem =~ /^connection.*/" + "when": "view == msg.openEditors && viewItem == connectionMySQL || viewItem == connectionSqlite" }, { "command": "msg.newSessionUsingConnection", @@ -1988,6 +2006,21 @@ "command": "msg.mds.getLoadBalancer", "when": "view == msg.oci && viewItem == mdsLoadBalancer", "group": "1_msg@1" + }, + { + "command": "msg.addSubFolder", + "when": "view == msg.connections && viewItem == connectionGroup", + "group": "1_msg@1" + }, + { + "command": "msg.editFolder", + "when": "view == msg.connections && viewItem == connectionGroup", + "group": "2_msg@1" + }, + { + "command": "msg.removeFolder", + "when": "view == msg.connections && viewItem == connectionGroup", + "group": "3_msg@1" } ] }, diff --git a/gui/extension/scripts/package_extension.ps1 b/gui/extension/scripts/package_extension.ps1 index 44456047a..cdedd1fe6 100644 --- a/gui/extension/scripts/package_extension.ps1 +++ b/gui/extension/scripts/package_extension.ps1 @@ -107,6 +107,7 @@ $mrs_plugin_path = Join-Path $extensionFolder "shell" "lib" "mysqlsh" "plugins" $mds_plugin_path = Join-Path $extensionFolder "shell" "lib" "mysqlsh" "plugins" "mds_plugin" $msm_plugin_path = Join-Path $extensionFolder "shell" "lib" "mysqlsh" "plugins" "msm_plugin" $gui_plugin_path = Join-Path $extensionFolder "shell" "lib" "mysqlsh" "plugins" "gui_plugin" +$util_plugin_path = Join-Path $extensionFolder "shell" "lib" "mysqlsh" "plugins" "util_plugin" Write-host "Adding MRS plugin..." -NoNewLine Remove-Item -Path $mrs_plugin_path -Recurse -Force -ErrorAction SilentlyContinue @@ -123,6 +124,11 @@ Remove-Item -Path $msm_plugin_path -Recurse -Force -ErrorAction SilentlyContinue Copy-Item -Path $(Join-Path $shellPluginsFolder "msm_plugin") -Destination $msm_plugin_path -Recurse Write-host "DONE" +Write-host "Adding utilities..." -NoNewLine +Remove-Item -Path $util_plugin_path -Recurse -Force -ErrorAction SilentlyContinue +Copy-Item -Path $(Join-Path $shellPluginsFolder "util_plugin") -Destination $util_plugin_path -Recurse +Write-host "DONE" + Write-host "Adding GUI plugin backend ..." -NoNewLine Remove-Item -Path $gui_plugin_path -Recurse -Force -ErrorAction SilentlyContinue Copy-Item -Path $guiPluginBackend -Destination $gui_plugin_path -Recurse diff --git a/gui/extension/scripts/package_extension.sh b/gui/extension/scripts/package_extension.sh index 1597595fa..f35fd2fdb 100755 --- a/gui/extension/scripts/package_extension.sh +++ b/gui/extension/scripts/package_extension.sh @@ -148,14 +148,18 @@ if [ ! -d "$SHELL_PLUGINS_LOCATION/mds_plugin" ]; then echo "ERROR: The mds_plugin is missing from $SHELL_PLUGINS_LOCATION" exit 1 fi -if [ ! -d "$SHELL_PLUGINS_LOCATION" ]; then +if [ ! -d "$SHELL_PLUGINS_LOCATION/mrs_plugin" ]; then echo "ERROR: The mrs_plugin is missing from $SHELL_PLUGINS_LOCATION" exit 1 fi -if [ ! -d "$SHELL_PLUGINS_LOCATION" ]; then +if [ ! -d "$SHELL_PLUGINS_LOCATION/msm_plugin" ]; then echo "ERROR: The msm_plugin is missing from $SHELL_PLUGINS_LOCATION" exit 1 fi +if [ ! -d "$SHELL_PLUGINS_LOCATION/util_plugin" ]; then + echo "ERROR: The util_plugin is missing from ~/.mysqlsh/plugins/" + exit 1 +fi if [ -z "${SHELL_VERSION}" ] && [ ! -d "packaging" ]; then echo "Setting up the packaging resources..." @@ -241,13 +245,14 @@ for d in packaging/mysql-shell/*; do rm -Rf shell/lib/mysqlsh/plugins/mds_plugin rm -Rf shell/lib/mysqlsh/plugins/mrs_plugin rm -Rf shell/lib/mysqlsh/plugins/msm_plugin + rm -Rf shell/lib/mysqlsh/plugins/util_plugin echo "Copy plugins" - cp -RL $SHELL_PLUGINS_LOCATION/gui_plugin shell/lib/mysqlsh/plugins/. cp -RL $SHELL_PLUGINS_LOCATION/mds_plugin shell/lib/mysqlsh/plugins/. cp -RL $SHELL_PLUGINS_LOCATION/mrs_plugin shell/lib/mysqlsh/plugins/. cp -RL $SHELL_PLUGINS_LOCATION/msm_plugin shell/lib/mysqlsh/plugins/. + cp -RL $SHELL_PLUGINS_LOCATION/util_plugin shell/lib/mysqlsh/plugins/. # Clean *.py[co] files and __pycache__ directories find shell/lib/mysqlsh/plugins -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete diff --git a/gui/extension/src/DocumentCommandHandler.ts b/gui/extension/src/DocumentCommandHandler.ts index 35b20ce83..562a19a9d 100644 --- a/gui/extension/src/DocumentCommandHandler.ts +++ b/gui/extension/src/DocumentCommandHandler.ts @@ -30,8 +30,7 @@ import { commands, ConfigurationTarget, TextEditor, Uri, window, workspace } fro import { requisitions } from "../../frontend/src/supplement/Requisitions.js"; import { - ICodeBlockExecutionOptions, IRequestListEntry, IRequestTypeMap, IWebviewProvider, - type IDocumentOpenData, + ICodeBlockExecutionOptions, IRequestListEntry, IRequestTypeMap, IWebviewProvider, type IDocumentOpenData, type InitialEditor, } from "../../frontend/src/supplement/RequisitionTypes.js"; @@ -41,21 +40,23 @@ import { DBConnectionViewProvider } from "./WebviewProviders/DBConnectionViewPro import { ui } from "../../frontend/src/app-logic/UILayer.js"; import { IMrsDbObjectData } from "../../frontend/src/communication/ProtocolMrs.js"; import { - cdbDbEntityTypeName, - CdmEntityType, ConnectionDataModelEntry, ICdmConnectionEntry, ICdmEventEntry, ICdmRestDbObjectEntry, - type ICdmAdminPageEntry, type ICdmRoutineEntry, type ICdmSchemaEntry, type ICdmSchemaGroupEntry, - type ICdmTableEntry, type ICdmTriggerEntry, type ICdmViewEntry, + cdbDbEntityTypeName, CdmEntityType, ConnectionDataModelEntry, ICdmConnectionEntry, ICdmEventEntry, + ICdmRestDbObjectEntry, type ConnectionDataModelNoGroupEntry, type ICdmAdminPageEntry, type ICdmConnectionGroupEntry, + type ICdmRoutineEntry, type ICdmSchemaEntry, type ICdmSchemaGroupEntry, type ICdmTableEntry, type ICdmTriggerEntry, + type ICdmViewEntry, } from "../../frontend/src/data-models/ConnectionDataModel.js"; import { OdmEntityType, OpenDocumentDataModel, type IOdmConnectionPageEntry, type IOdmNotebookEntry, type IOdmScriptEntry, - type IOdmShellSessionEntry, - type OpenDocumentDataModelEntry, + type IOdmShellSessionEntry, type OpenDocumentDataModelEntry, } from "../../frontend/src/data-models/OpenDocumentDataModel.js"; +import { ConnectionProcessor } from "../../frontend/src/modules/common/ConnectionProcessor.js"; import { MrsDbObjectType } from "../../frontend/src/modules/mrs/types.js"; import { DBType, type IShellSessionDetails } from "../../frontend/src/supplement/ShellInterface/index.js"; +import { ShellInterface } from "../../frontend/src/supplement/ShellInterface/ShellInterface.js"; import { ShellInterfaceSqlEditor } from "../../frontend/src/supplement/ShellInterface/ShellInterfaceSqlEditor.js"; +import { webSession } from "../../frontend/src/supplement/WebSession.js"; import { uuid } from "../../frontend/src/utilities/helpers.js"; -import { convertSnakeToCamelCase } from "../../frontend/src/utilities/string-helpers.js"; +import { convertSnakeToCamelCase, formatWithNumber } from "../../frontend/src/utilities/string-helpers.js"; import { CodeBlocks } from "./CodeBlocks.js"; import { ExtensionHost } from "./ExtensionHost.js"; import { @@ -81,37 +82,37 @@ export class DocumentCommandHandler { private latestPagesByConnection: Map = new Map(); - #isConnected = false; - #host: ExtensionHost; + private isConnected = false; + private host: ExtensionHost; - #codeBlocks = new CodeBlocks(); + private codeBlocks = new CodeBlocks(); // For each open editor a list of open scripts is held (via a mapping of script IDs and their target URI). - #openScripts = new Map>(); + private openScripts = new Map>(); - #openEditorsTreeDataProvider: OpenEditorsTreeDataProvider; - #connectionsProvider: ConnectionsTreeDataProvider; + private openEditorsTreeDataProvider: OpenEditorsTreeDataProvider; + private connectionsProvider: ConnectionsTreeDataProvider; - #initialDisplayOfOpenEditorsView = true; - #displayDbConnectionOverviewWhenConnected = false; + private initialDisplayOfOpenEditorsView = true; + private displayDbConnectionOverviewWhenConnected = false; - #openDocumentsModel = new OpenDocumentDataModel(false); + private openDocumentsModel = new OpenDocumentDataModel(false); // Set when the handler triggers a document selection, which causes the a bounce back from the web app // in which a document was selected. This flag is used to prevent the re-selection of the last selected item. - #selectionInProgress = false; + private selectionInProgress = false; public constructor(connectionsProvider: ConnectionsTreeDataProvider) { - this.#connectionsProvider = connectionsProvider; + this.connectionsProvider = connectionsProvider; } public setup(host: ExtensionHost): void { - this.#host = host; + this.host = host; const context = host.context; - this.#codeBlocks.setup(context); + this.codeBlocks.setup(context); const dbConnectionsTreeView = window.createTreeView("msg.connections", { - treeDataProvider: this.#connectionsProvider, + treeDataProvider: this.connectionsProvider, showCollapseAll: true, canSelectMany: false, }); @@ -119,27 +120,27 @@ export class DocumentCommandHandler { // Register expand/collapse handlers dbConnectionsTreeView.onDidExpandElement((event) => { - this.#connectionsProvider.didExpandElement(event.element); + this.connectionsProvider.didExpandElement(event.element); }); dbConnectionsTreeView.onDidCollapseElement((event) => { - this.#connectionsProvider.didCollapseElement(event.element); + this.connectionsProvider.didCollapseElement(event.element); }); - this.#openEditorsTreeDataProvider = new OpenEditorsTreeDataProvider(this.#openDocumentsModel); + this.openEditorsTreeDataProvider = new OpenEditorsTreeDataProvider(this.openDocumentsModel); const openEditorsTreeView = window.createTreeView( "msg.openEditors", { - treeDataProvider: this.#openEditorsTreeDataProvider, + treeDataProvider: this.openEditorsTreeDataProvider, showCollapseAll: true, canSelectMany: false, }); context.subscriptions.push(openEditorsTreeView); - this.#openEditorsTreeDataProvider.onSelect = (item: OpenDocumentDataModelEntry): void => { - if (!this.#selectionInProgress) { + this.openEditorsTreeDataProvider.onSelect = (item: OpenDocumentDataModelEntry): void => { + if (!this.selectionInProgress) { void openEditorsTreeView.reveal(item, { select: true, focus: false, expand: 3 }); } else { - this.#selectionInProgress = false; + this.selectionInProgress = false; } }; @@ -149,16 +150,16 @@ export class DocumentCommandHandler { const showDbConnectionsTab = workspace.getConfiguration(`msg.startup`) .get("showDbConnectionsTab", true); - if (e.visible && this.#initialDisplayOfOpenEditorsView && showDbConnectionsTab) { - this.#initialDisplayOfOpenEditorsView = false; + if (e.visible && this.initialDisplayOfOpenEditorsView && showDbConnectionsTab) { + this.initialDisplayOfOpenEditorsView = false; // If the extension is already connected to the MySQL Shell websocket, // open the DB Connection Overview right away - if (this.#isConnected) { + if (this.isConnected) { void commands.executeCommand("msg.openDBBrowser"); } else { // Otherwise open the DB Connection Overview when connected - this.#displayDbConnectionOverviewWhenConnected = true; + this.displayDbConnectionOverviewWhenConnected = true; } } }); @@ -175,16 +176,41 @@ export class DocumentCommandHandler { if (entry) { // "Open connection" acts differently, depending on whether the same connection is already open or not. let provider; - if (this.#openDocumentsModel.isOpen(entry.details)) { - provider = this.#host.newProvider; + if (this.openDocumentsModel.isOpen(entry.details)) { + provider = this.host.newProvider; } else { - provider = this.#host.currentProvider; + provider = this.host.currentProvider; } void provider?.show(entry.details.id, editor); } }; + context.subscriptions.push(commands.registerCommand("msg.importWorkbenchConnections", () => { + void window.showOpenDialog({ + title: "Select the connection.xml file to import", + openLabel: "Import Connections File", + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: false, + filters: { + // eslint-disable-next-line @typescript-eslint/naming-convention + XML: ["xml"], + }, + }).then((value) => { + if (value && value.length === 1) { + const uri = value[0]; + void workspace.fs.readFile(uri).then((value) => { + const content = value.toString(); + void ConnectionProcessor.importMySQLWorkbenchConnections(content, + this.connectionsProvider.dataModel); + + void requisitions.execute("refreshConnection", undefined); + }); + } + }); + })); + context.subscriptions.push(commands.registerCommand("msg.openConnection", (entry?: ICdmConnectionEntry) => { openConnection(entry); })); @@ -202,7 +228,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.openConnectionNewTab", (entry?: ICdmConnectionEntry) => { if (entry) { - const provider = this.#host.newProvider; + const provider = this.host.newProvider; void provider?.show(entry.details.id); } })); @@ -212,7 +238,6 @@ export class DocumentCommandHandler { return; } - const connection = await host.determineConnection(DBType.MySQL, true); if (connection) { const stat = await workspace.fs.stat(uri); @@ -222,7 +247,7 @@ export class DocumentCommandHandler { `is too large to edit it in a web view. Instead use the VS Code built-in editor.`, {}); } else { const content = (await workspace.fs.readFile(uri)).toString(); - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { // We load only sql and mysql scripts here. @@ -236,17 +261,15 @@ export class DocumentCommandHandler { language, }; - let scripts = this.#openScripts.get(provider); + let scripts = this.openScripts.get(provider); if (!scripts) { scripts = new Map(); - this.#openScripts.set(provider, scripts); + this.openScripts.set(provider, scripts); } scripts.set(request.id, uri); const details = connection.details; void provider.editScript(details.id, request); - - } } } @@ -254,7 +277,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.showTableData", (entry?: ICdmTableEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; const configuration = workspace.getConfiguration(`msg.dbEditor`); const uppercaseKeywords = configuration.get("upperCaseKeywords", true); @@ -277,7 +300,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.selectTableRows", (entry?: ICdmTableEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; const configuration = workspace.getConfiguration(`msg.dbEditor`); const uppercaseKeywords = configuration.get("upperCaseKeywords", true); @@ -294,12 +317,12 @@ export class DocumentCommandHandler { })); const showAdminPage = (provider: IWebviewProvider | undefined, _caption: string, page: ICdmAdminPageEntry) => { - provider ??= this.#host.currentProvider; + provider ??= this.host.currentProvider; if (provider instanceof DBConnectionViewProvider) { const connectionId = page.connection.details.id; const latestPageId = this.latestPagesByConnection.get(connectionId); - const documents = this.#openEditorsTreeDataProvider.findAdminDocument(provider, + const documents = this.openEditorsTreeDataProvider.findAdminDocument(provider, connectionId, latestPageId); // Check the list of open admin pages for the type we want to open. @@ -328,7 +351,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.showLakehouseNavigator", showAdminPage)); context.subscriptions.push(commands.registerCommand("msg.addConnection", () => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.addConnection(); })); @@ -338,14 +361,14 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.removeConnection", (entry?: ICdmConnectionEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.removeConnection(entry.details.id); } })); context.subscriptions.push(commands.registerCommand("msg.editConnection", (entry?: ICdmConnectionEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.editConnection(entry?.details.id); } })); @@ -353,7 +376,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.duplicateConnection", (entry?: ICdmConnectionEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.duplicateConnection(entry.details.id); } })); @@ -381,11 +404,11 @@ export class DocumentCommandHandler { })); context.subscriptions.push(commands.registerCommand("msg.openDBBrowser", (provider?: IWebviewProvider) => { - provider ??= this.#host.currentProvider; + provider ??= this.host.currentProvider; if (provider instanceof DBConnectionViewProvider) { void provider.show(); } else { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { void provider.show(); } @@ -394,14 +417,13 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.makeCurrentSchema", (entry?: ICdmSchemaEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { - void provider?.makeCurrentSchema(entry.connection.details.id, entry.caption) - .then((success) => { - if (success) { - this.#connectionsProvider.makeCurrentSchema(entry); - } - }); + void provider?.makeCurrentSchema(entry.connection.details.id, entry.caption).then((success) => { + if (success) { + this.connectionsProvider.makeCurrentSchema(entry); + } + }); } } })); @@ -441,7 +463,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.editRoutine", async (entry?: ICdmRoutineEntry) => { if (entry) { const entryType = entry.type === CdmEntityType.StoredFunction ? "function" : "procedure"; - const sql = await this.#connectionsProvider.getCreateSqlScript(entry, entryType, true, true); + const sql = await this.connectionsProvider.getCreateSqlScript(entry, entryType, true, true, true); void this.addNewSqlScript(entry.connection.details.id, "msg.editRoutine", entry.parent.caption, "Edit Routine", sql); @@ -450,37 +472,37 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.dropSchema", (entry?: ICdmSchemaEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); context.subscriptions.push(commands.registerCommand("msg.dropTable", (entry?: ICdmTableEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); context.subscriptions.push(commands.registerCommand("msg.dropView", (entry?: ICdmViewEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); context.subscriptions.push(commands.registerCommand("msg.dropRoutine", (entry?: ICdmRoutineEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); context.subscriptions.push(commands.registerCommand("msg.dropTrigger", (entry?: ICdmTriggerEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); context.subscriptions.push(commands.registerCommand("msg.dropEvent", (entry?: ICdmEventEntry) => { if (entry) { - this.#connectionsProvider.dropItem(entry); + this.connectionsProvider.dropItem(entry); } })); @@ -499,31 +521,31 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.copyNameToClipboard", (entry?: ConnectionDataModelEntry) => { if (entry) { - this.#connectionsProvider.copyNameToClipboard(entry); + this.connectionsProvider.copyNameToClipboard(entry); } })); context.subscriptions.push(commands.registerCommand("msg.copyCreateScriptToClipboard", - (entry?: ConnectionDataModelEntry) => { + (entry?: ConnectionDataModelNoGroupEntry) => { if (entry) { const typeName = cdbDbEntityTypeName.get(entry.type)!; - void this.#connectionsProvider.copyCreateScriptToClipboard(entry, typeName); + void this.connectionsProvider.copyCreateScriptToClipboard(entry, typeName); } })); context.subscriptions.push(commands.registerCommand("msg.copyCreateScriptWithDelimitersToClipboard", - (entry?: ConnectionDataModelEntry) => { + (entry?: ConnectionDataModelNoGroupEntry) => { if (entry) { const typeName = cdbDbEntityTypeName.get(entry.type)!; - void this.#connectionsProvider.copyCreateScriptToClipboard(entry, typeName, true); + void this.connectionsProvider.copyCreateScriptToClipboard(entry, typeName, true); } })); context.subscriptions.push(commands.registerCommand("msg.copyDropCreateScriptWithDelimitersToClipboard", - (entry?: ConnectionDataModelEntry) => { + (entry?: ConnectionDataModelNoGroupEntry) => { if (entry) { const typeName = cdbDbEntityTypeName.get(entry.type)!; - void this.#connectionsProvider.copyCreateScriptToClipboard(entry, typeName, true, true); + void this.connectionsProvider.copyCreateScriptToClipboard(entry, typeName, true, true); } })); @@ -542,7 +564,7 @@ export class DocumentCommandHandler { if (connection) { await workspace.fs.readFile(uri).then((value) => { const content = value.toString(); - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { const name = basename(uri.fsPath); @@ -553,10 +575,10 @@ export class DocumentCommandHandler { content, }; - let scripts = this.#openScripts.get(provider); + let scripts = this.openScripts.get(provider); if (!scripts) { scripts = new Map(); - this.#openScripts.set(provider, scripts); + this.openScripts.set(provider, scripts); } scripts.set(details.id, uri); @@ -593,7 +615,7 @@ export class DocumentCommandHandler { } else { await workspace.fs.readFile(uri).then((value) => { const content = value.toString(); - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { let language: EditorLanguage = "mysql"; @@ -628,10 +650,10 @@ export class DocumentCommandHandler { content, }; - let scripts = this.#openScripts.get(provider); + let scripts = this.openScripts.get(provider); if (!scripts) { scripts = new Map(); - this.#openScripts.set(provider, scripts); + this.openScripts.set(provider, scripts); } scripts.set(details.id, uri); @@ -644,6 +666,105 @@ export class DocumentCommandHandler { } })); + context.subscriptions.push(commands.registerCommand("msg.addSubFolder", + async (entry: ICdmConnectionGroupEntry) => { + let name = await window.showInputBox({ + title: `Add subfolder in Folder \`${entry.caption}\``, + placeHolder: "Sub folder", + prompt: "Enter the name of the new folder:", + value: "", + }); + + if (name === undefined) { + return; + } + + if (name === "") { + name = "Sub folder"; + } + + await ShellInterface.dbConnections.addFolderPath(webSession.currentProfileId, name, + entry.folderPath.id); + await entry.refresh?.(); + void requisitions.executeRemote("refreshConnectionGroup", entry.folderPath.id); + })); + + context.subscriptions.push(commands.registerCommand("msg.editFolder", + async (entry: ICdmConnectionGroupEntry) => { + const name = await window.showInputBox({ + title: `Edit Folder`, + prompt: "Enter the new name of the folder:", + value: entry.caption, + }); + + if (!name) { + return; + } + + await ShellInterface.dbConnections.renameFolderPath(entry.folderPath.id, name); + + // TODO: for now we have to update the parent folder, to get the new name. A new API should be created + // to get the new name of the folder directly. + await entry.parent?.refresh?.(); + void requisitions.executeRemote("refreshConnectionGroup", entry.parent?.folderPath.id); + })); + + context.subscriptions.push(commands.registerCommand("msg.removeFolder", + async (entry: ICdmConnectionGroupEntry) => { + // Count how many connections and subfolders are in the folder. The group entry is returned + // in the list too. + await entry?.refresh?.(); + const flatList = await this.connectionsProvider.dataModel.flattenGroupList(entry); + + let description: string[] = []; + let prompt = `Are you sure you want to remove the folder "${entry?.caption}", including all its ` + + `contents? This operation cannot be reverted!`; + if (flatList.connections.length === 0 && + flatList.groups.length === 1) { // Only the group entry is in the list. + prompt = `The folder "${entry?.caption}" is empty. Do you want to remove it?`; + } else { + let groupString = ""; + if (flatList.groups.length > 1) { + groupString = formatWithNumber("subfolder", flatList.groups.length - 1); + } + + let connectionString = ""; + if (flatList.connections.length > 0) { + connectionString = formatWithNumber("connection", flatList.connections.length); + } + + if (groupString && connectionString) { + description = [`The folder contains ${groupString} and ` + + `${connectionString}.`]; + } else if (groupString) { + description = [`The folder contains ${groupString}.`]; + } else { + description = [`The folder contains ${connectionString}.`]; + } + } + + description.unshift(""); + description.unshift(prompt); + const answer = await ui.confirm(description.join("\n"), "Delete Folder"); + if (answer === "Delete Folder") { + for (const connection of flatList.connections.reverse()) { + await this.connectionsProvider.dataModel.dropItem(connection); + await this.connectionsProvider.dataModel.removeEntry(connection); + } + + for (const group of flatList.groups.reverse()) { + await this.connectionsProvider.dataModel.dropItem(group); + await this.connectionsProvider.dataModel.removeEntry(group); + } + + void ui.showInformationMessage(`The connection group ` + + `"${entry?.caption}" has been deleted.`, {}); + + await entry.parent?.refresh?.(); + void requisitions.executeRemote("refreshConnectionGroup", entry.parent?.folderPath.id); + } + })); + context.subscriptions.push(commands.registerCommand("msg.selectDocument", (item?: DocumentTreeBaseItem) => { if (item) { @@ -672,7 +793,7 @@ export class DocumentCommandHandler { } case OdmEntityType.Overview: { - provider = this.#host.currentProvider; + provider = this.host.currentProvider; break; } @@ -702,7 +823,7 @@ export class DocumentCommandHandler { } if (provider) { - this.#selectionInProgress = true; + this.selectionInProgress = true; void provider.selectDocument(dataModelEntry.id, connectionId, pageId); } } @@ -711,7 +832,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.mds.createConnectionViaBastionService", (item?: OciDbSystemTreeItem) => { if (item) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.addConnection(item.dbSystem, item.profile.profile); } })); @@ -721,7 +842,7 @@ export class DocumentCommandHandler { if (editor) { void host.determineConnection().then((connection) => { if (connection) { - this.#codeBlocks.executeSqlFromEditor(editor, connection.details.caption, + this.codeBlocks.executeSqlFromEditor(editor, connection.details.caption, connection.details.id); } }); @@ -733,7 +854,7 @@ export class DocumentCommandHandler { if (editor) { void host.determineConnection().then((connection) => { if (connection) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { const sql = this.getSql(editor); @@ -795,7 +916,7 @@ export class DocumentCommandHandler { || entry.type === CdmEntityType.StoredFunction || entry.type === CdmEntityType.StoredProcedure) { // First, create a new temporary dbObject, then call the DbObject dialog this.createNewDbObject(connection.backend, entry).then((dbObject) => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.editMrsDbObject(connection.details.id, { dbObject, createObject: true }); }).catch((reason) => { @@ -810,7 +931,7 @@ export class DocumentCommandHandler { context.subscriptions.push(commands.registerCommand("msg.mrs.editDbObject", (entry?: ICdmRestDbObjectEntry) => { if (entry) { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; const connection = entry.parent.parent.parent.parent; void provider?.editMrsDbObject(connection.details.id, { dbObject: entry.details, createObject: false }); @@ -818,18 +939,18 @@ export class DocumentCommandHandler { })); context.subscriptions.push(commands.registerCommand("msg.newSession", () => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.openSession({ sessionId: uuid() }); })); context.subscriptions.push(commands.registerCommand("msg.openSession", (details: IShellSessionDetails) => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; void provider?.openSession(details); })); context.subscriptions.push(commands.registerCommand("msg.newSessionUsingConnection", (entry: ICdmConnectionEntry | IOdmConnectionPageEntry) => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; const caption = entry.type === CdmEntityType.Connection ? entry.details.caption : entry.caption; const dbConnectionId = entry.details.id; @@ -848,6 +969,7 @@ export class DocumentCommandHandler { void provider.removeSession(entry.details); } })); + } public async addNewSqlScript(connectionId: number, command: string, schemaName: string, @@ -867,6 +989,7 @@ export class DocumentCommandHandler { if (name === undefined) { return; } + if (name === "") { name = placeHolder; } @@ -935,7 +1058,7 @@ export class DocumentCommandHandler { default: } - const provider = this.#host.currentProvider ?? this.#host.newProvider; + const provider = this.host.currentProvider ?? this.host.newProvider; if (provider) { this.createNewScriptEditor( provider, scriptName, sql, "mysql", connectionId, @@ -947,12 +1070,12 @@ export class DocumentCommandHandler { * Triggered on authentication, which means existing connections are no longer valid. */ public async refreshConnectionTree(): Promise { - await this.#connectionsProvider.closeAllConnections(); - this.#connectionsProvider.refresh(); + await this.connectionsProvider.closeAllConnections(); + this.connectionsProvider.refresh(); } public clear(): void { - this.#openEditorsTreeDataProvider.clear(); + this.openEditorsTreeDataProvider.clear(); } /** @@ -962,17 +1085,17 @@ export class DocumentCommandHandler { */ public providerOpened(provider: DBConnectionViewProvider): void { // Register the new provider with our data model. - this.#openDocumentsModel.openProvider(provider); - this.#openEditorsTreeDataProvider.refresh(); + this.openDocumentsModel.openProvider(provider); + this.openEditorsTreeDataProvider.refresh(); } public providerClosed(provider: DBConnectionViewProvider): void { - this.#openDocumentsModel.closeProvider(provider); - this.#openScripts.delete(provider); - this.#openEditorsTreeDataProvider.refresh(); - if (this.#openEditorsTreeDataProvider.clear(provider)) { + this.openDocumentsModel.closeProvider(provider); + this.openScripts.delete(provider); + this.openEditorsTreeDataProvider.refresh(); + if (this.openEditorsTreeDataProvider.clear(provider)) { // No provider remained open. Reset the current schemas. - this.#connectionsProvider.resetCurrentSchemas(); + this.connectionsProvider.resetCurrentSchemas(); } } @@ -982,11 +1105,11 @@ export class DocumentCommandHandler { * @returns The new caption. */ public generateNewProviderCaption(): string { - return this.#openDocumentsModel.createUniqueCaption(); + return this.openDocumentsModel.createUniqueCaption(); } public providerStateChanged(provider: DBConnectionViewProvider, active: boolean): void { - this.#connectionsProvider.providerStateChanged(provider, active); + this.connectionsProvider.providerStateChanged(provider, active); } private createNewDbObject = async (backend: ShellInterfaceSqlEditor, @@ -1075,10 +1198,10 @@ export class DocumentCommandHandler { }; private connectedToUrl = (url?: URL): Promise => { - this.#isConnected = url !== undefined; + this.isConnected = url !== undefined; - if (this.#displayDbConnectionOverviewWhenConnected) { - this.#displayDbConnectionOverviewWhenConnected = false; + if (this.displayDbConnectionOverviewWhenConnected) { + this.displayDbConnectionOverviewWhenConnected = false; void commands.executeCommand("msg.openDBBrowser"); } @@ -1093,7 +1216,7 @@ export class DocumentCommandHandler { * @returns A promise returning a flag whether the task was successfully executed or not. */ private executeCodeBlock = (details: ICodeBlockExecutionOptions): Promise => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { return provider.runCode(details.connectionId, { linkId: details.linkId, @@ -1142,9 +1265,9 @@ export class DocumentCommandHandler { }).then((list: Uri[]) => { if (list.length > 0) { void workspace.fs.readFile(list[0]).then((content) => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { - const scripts = this.#openScripts.get(provider); + const scripts = this.openScripts.get(provider); if (scripts) { scripts.set(details.id, list[0]); const newName = basename(list[0].fsPath); @@ -1159,7 +1282,7 @@ export class DocumentCommandHandler { } details.content = content.toString(); - const connectionId = this.#openEditorsTreeDataProvider.currentConnectionId(provider) ?? -1; + const connectionId = this.openEditorsTreeDataProvider.currentConnectionId(provider) ?? -1; void provider.loadScript(connectionId, details); } @@ -1172,9 +1295,9 @@ export class DocumentCommandHandler { }; private editorSaveScript = (details: IScriptRequest): Promise => { - const provider = this.#host.currentProvider; + const provider = this.host.currentProvider; if (provider) { - const scripts = this.#openScripts.get(provider); + const scripts = this.openScripts.get(provider); if (scripts) { const uri = scripts.get(details.id); if (uri) { @@ -1249,10 +1372,10 @@ export class DocumentCommandHandler { pageId, }; - let scripts = this.#openScripts.get(dbProvider); + let scripts = this.openScripts.get(dbProvider); if (!scripts) { scripts = new Map(); - this.#openScripts.set(dbProvider, scripts); + this.openScripts.set(dbProvider, scripts); } if (uri) { scripts.set(request.id, uri); @@ -1277,9 +1400,9 @@ export class DocumentCommandHandler { provider = params.entry.parent.provider; pageId = params.entry.id; } else if (!connectionId) { - provider = this.#host.currentProvider; + provider = this.host.currentProvider; if (provider) { - connectionId = this.#openEditorsTreeDataProvider.currentConnectionId(provider) ?? -1; + connectionId = this.openEditorsTreeDataProvider.currentConnectionId(provider) ?? -1; } } diff --git a/gui/extension/src/ExtensionHost.ts b/gui/extension/src/ExtensionHost.ts index d3afc6a26..78878a6f8 100644 --- a/gui/extension/src/ExtensionHost.ts +++ b/gui/extension/src/ExtensionHost.ts @@ -40,6 +40,7 @@ import { ShellTasksTreeDataProvider } from "./tree-providers/ShellTreeProvider/S import { ui } from "../../frontend/src/app-logic/UILayer.js"; import type { IShellModuleDataCategoriesEntry, IShellProfile } from "../../frontend/src/communication/ProtocolGui.js"; import { + CdmEntityType, ConnectionDataModel, type ICdmConnectionEntry, type ICdmSchemaEntry, } from "../../frontend/src/data-models/ConnectionDataModel.js"; import type { @@ -96,6 +97,9 @@ export class ExtensionHost { #connectionsDataModel: ConnectionDataModel; public constructor(public context: ExtensionContext) { + // Access the node specific message scheduler once to create the correct version of it. + void NodeMessageScheduler.get; + this.#connectionsDataModel = new ConnectionDataModel(false); void this.#connectionsDataModel.initialize(); // Async init, but don't wait. @@ -174,15 +178,13 @@ export class ExtensionHost { */ public determineConnection = async (dbType?: DBType, forcePicker?: boolean, showErrorMessages = true): Promise => { - let connections = this.#connectionsDataModel.connections; + let connections: ICdmConnectionEntry[] = []; let title = "Select a connection for SQL execution"; if (!forcePicker) { const connectionName = workspace.getConfiguration("msg.editor").get("defaultDbConnection"); if (connectionName) { - const connection = connections.find((candidate) => { - return candidate.details.caption === connectionName; - }); + const connection = this.#connectionsDataModel.findConnectionEntryByCaption(connectionName); if (!connection) { if (showErrorMessages) { @@ -205,8 +207,8 @@ export class ExtensionHost { // If a specific dbType was specified, filter connections by that DBType if (dbType) { - connections = connections.filter((conn) => { - return conn.details.dbType === dbType; + connections = this.#connectionsDataModel.connectionList.filter((entry) => { + return entry.type === CdmEntityType.Connection && entry.details.dbType === dbType; }); } @@ -310,9 +312,6 @@ export class ExtensionHost { * Prepares all VS Code providers for first use. */ private setupEnvironment(): void { - // Access the node specific message scheduler once to create the correct version of it. - void NodeMessageScheduler.get; - // Register the extension host as target for broadcasts. requisitions.setRemoteTarget(this); diff --git a/gui/extension/src/MDSCommandHandler.ts b/gui/extension/src/MDSCommandHandler.ts index 4cdedb206..1ef2838fd 100644 --- a/gui/extension/src/MDSCommandHandler.ts +++ b/gui/extension/src/MDSCommandHandler.ts @@ -48,7 +48,7 @@ import { MySQLConnCompression, MySQLConnectionScheme } from "../../frontend/src/ import { IMdsProfileData } from "../../frontend/src/communication/ProtocolMds.js"; import type { ICdmSchemaEntry } from "../../frontend/src/data-models/ConnectionDataModel.js"; import { requisitions } from "../../frontend/src/supplement/Requisitions.js"; -import { DBType } from "../../frontend/src/supplement/ShellInterface/index.js"; +import { DBType, type IConnectionDetails } from "../../frontend/src/supplement/ShellInterface/index.js"; import { ShellInterface } from "../../frontend/src/supplement/ShellInterface/ShellInterface.js"; import { ShellInterfaceShellSession } from "../../frontend/src/supplement/ShellInterface/ShellInterfaceShellSession.js"; import { webSession } from "../../frontend/src/supplement/WebSession.js"; @@ -822,13 +822,14 @@ export class MDSCommandHandler { await commands.executeCommand("msg.mds.refreshOciProfiles"); if (createDbConnection) { - const details = { + const details: IConnectionDetails = { id: 0, // Will be replaced with the ID returned from the BE call. + index: 0, dbType: DBType.MySQL, caption: instanceName, description: "MySQL Router Connection", useSSH: false, - useMDS: false, + useMHS: false, options: { /* eslint-disable @typescript-eslint/naming-convention */ "scheme": MySQLConnectionScheme.MySQL, diff --git a/gui/extension/src/MRSCommandHandler.ts b/gui/extension/src/MRSCommandHandler.ts index 22a7820b5..3992d4086 100644 --- a/gui/extension/src/MRSCommandHandler.ts +++ b/gui/extension/src/MRSCommandHandler.ts @@ -471,6 +471,98 @@ export class MRSCommandHandler { } }; + const createStatementContentSetSql = async (entry?: ICdmRestContentSetEntry, + toFile?: boolean) => { + if (!entry) { + void ui.showErrorMessage(`Error creating the SQL for this REST Content Set`, {}); + + return; + } + + try { + if (toFile) { + const convertedUrl = convertPathToCamelCase(entry.details.requestPath) + "." + + convertPathToCamelCase(entry.details.hostCtx); + const overwrite = true; + + const value = await window.showSaveDialog({ + title: "Export REST Content Set SQL to file...", + defaultUri: Uri.file(`${os.homedir()}/${convertedUrl}.mrs.sql`), + saveLabel: "Export SQL File", + }); + + if (value === undefined) { + return; + } + + const result = await entry.connection.backend.mrs.dumpContentSetCreateStatement( + entry.details.id, value.fsPath, overwrite); + + if (result) { + void ui.showInformationMessage(`The REST Content Set SQL was exported`, {}); + } else { + void ui.showErrorMessage(`Error creating the SQL for this REST Content Set`, {}); + } + } else { + const result = await entry.connection.backend.mrs.getContentSetCreateStatement( + entry.details.id); + + void env.clipboard.writeText(result).then(() => { + void ui.showInformationMessage("The CREATE statement was copied to the system clipboard", {}); + }); + } + } catch (reason) { + const message = convertErrorToString(reason); + void ui.showErrorMessage(`Error setting the default REST Content Set: ${message}`, {}); + } + }; + + const createStatementContentFileSql = async (entry?: ICdmRestContentFileEntry, + toFile?: boolean) => { + if (!entry) { + void ui.showErrorMessage(`Error creating the SQL for this REST Content File`, {}); + + return; + } + + try { + if (toFile) { + const convertedUrl = convertPathToCamelCase(entry.details.requestPath) + "." + + convertPathToCamelCase(entry.details.hostCtx); + const overwrite = true; + + const value = await window.showSaveDialog({ + title: "Export REST Content File SQL to file...", + defaultUri: Uri.file(`${os.homedir()}/${convertedUrl}.mrs.sql`), + saveLabel: "Export SQL File", + }); + + if (value === undefined) { + return; + } + + const result = await entry.connection.backend.mrs.dumpContentFileCreateStatement( + entry.details.id, value.fsPath, overwrite); + + if (result) { + void ui.showInformationMessage(`The REST Content File SQL was exported`, {}); + } else { + void ui.showErrorMessage(`Error creating the SQL for this REST Content File`, {}); + } + } else { + const result = await entry.connection.backend.mrs.getContentFileCreateStatement( + entry.details.id); + + void env.clipboard.writeText(result).then(() => { + void ui.showInformationMessage("The CREATE statement was copied to the system clipboard", {}); + }); + } + } catch (reason) { + const message = convertErrorToString(reason); + void ui.showErrorMessage(`Error setting the default REST Content File: ${message}`, {}); + } + }; + context.subscriptions.push(commands.registerCommand("msg.mrs.dumpCreateServiceSql", async (entry?: ICdmRestServiceEntry) => { if (!entry) { @@ -576,6 +668,16 @@ export class MRSCommandHandler { await createStatementDbObjectSql(entry, true); })); + context.subscriptions.push(commands.registerCommand("msg.mrs.exportCreateContentSetSql", + async (entry?: ICdmRestContentSetEntry) => { + await createStatementContentSetSql(entry, true); + })); + + context.subscriptions.push(commands.registerCommand("msg.mrs.exportCreateContentFileSql", + async (entry?: ICdmRestContentFileEntry) => { + await createStatementContentFileSql(entry, true); + })); + context.subscriptions.push(commands.registerCommand("msg.mrs.copyCreateServiceSql", async (entry?: ICdmRestServiceEntry) => { await createStatementServiceSql(entry, false); @@ -624,23 +726,12 @@ export class MRSCommandHandler { host.context.subscriptions.push(commands.registerCommand("msg.mrs.copyCreateContentSetSql", async (entry?: ICdmRestContentSetEntry) => { - if (!entry) { - void ui.showErrorMessage(`Error creating the SQL for this REST Content Set`, {}); - - return; - } - - try { - const result = await entry.connection.backend.mrs.getContentSetCreateStatement( - entry.details.id); - - void env.clipboard.writeText(result).then(() => { - void ui.showInformationMessage("The CREATE statement was copied to the system clipboard", {}); - }); + await createStatementContentSetSql(entry, false); + })); - } catch (reason) { - void ui.showErrorMessage(`Error getting the SQL for this REST Content Set`, {}); - } + host.context.subscriptions.push(commands.registerCommand("msg.mrs.copyCreateContentFileSql", + async (entry?: ICdmRestContentFileEntry) => { + await createStatementContentFileSql(entry, false); })); diff --git a/gui/extension/src/WebviewProviders/DBConnectionViewProvider.ts b/gui/extension/src/WebviewProviders/DBConnectionViewProvider.ts index ae1c06cd5..0be0aabc1 100644 --- a/gui/extension/src/WebviewProviders/DBConnectionViewProvider.ts +++ b/gui/extension/src/WebviewProviders/DBConnectionViewProvider.ts @@ -339,7 +339,7 @@ export class DBConnectionViewProvider extends WebviewProvider { // callback. ["refreshConnection", "connectionAdded", "connectionUpdated", "connectionRemoved", "refreshOciTree", "codeBlocksUpdate", "editorLoadScript", "editorSaveScript", "createNewEditor", "documentOpened", - "documentClosed", "selectDocument", "sessionAdded", "sessionRemoved"] + "documentClosed", "selectDocument", "sessionAdded", "sessionRemoved", "refreshConnectionGroup"] .forEach((requestType: keyof IRequestTypeMap) => { this.requisitions!.register(requestType, this.forwardRequest.bind(this, requestType)); }); diff --git a/gui/extension/src/extension.ts b/gui/extension/src/extension.ts index ea5150eb1..8b040fef4 100644 --- a/gui/extension/src/extension.ts +++ b/gui/extension/src/extension.ts @@ -169,14 +169,17 @@ const extensionUILayer: IUILayer = { } }, - confirm: async (message: string, yes: string, no: string, extra?: string): Promise => { - if (extra === undefined) { - const result = await ui.showInformationMessage(message, { modal: true }, yes, no); + confirm: async (message: string, yes: string, no?: string, extra?: string): Promise => { + const items: string[] = [yes]; + if (no !== undefined) { + items.push(no); + } - return Promise.resolve(result); + if (extra !== undefined) { + items.push(extra); } - const result = await ui.showInformationMessage(message, { modal: true }, yes, no, extra); + const result = await ui.showInformationMessage(message, { modal: true }, ...items); return Promise.resolve(result); }, diff --git a/gui/frontend/src/components/ui/SessionTile/SessionTile.css b/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionGroupTreeItem.ts similarity index 69% rename from gui/frontend/src/components/ui/SessionTile/SessionTile.css rename to gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionGroupTreeItem.ts index 6d003a81c..ad67cd009 100644 --- a/gui/frontend/src/components/ui/SessionTile/SessionTile.css +++ b/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionGroupTreeItem.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -23,7 +23,14 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -msg.sessionTile > #actions > .icon:not(.codicon) { - flex: 0 0 24px; - margin: 0; +import { type ICdmConnectionGroupEntry } from "../../../../frontend/src/data-models/ConnectionDataModel.js"; +import { ConnectionBaseTreeItem } from "./ConnectionBaseTreeItem.js"; + +export class ConnectionGroupTreeItem extends ConnectionBaseTreeItem { + + public override contextValue = `connectionGroup`; + + public constructor(dataModelEntry: ICdmConnectionGroupEntry) { + super(dataModelEntry, "folder.svg", true); + } } diff --git a/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionsTreeProvider.ts b/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionsTreeProvider.ts index 9457f5250..fc6130a00 100644 --- a/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionsTreeProvider.ts +++ b/gui/extension/src/tree-providers/ConnectionsTreeProvider/ConnectionsTreeProvider.ts @@ -31,9 +31,8 @@ import type { import { requisitions } from "../../../../frontend/src/supplement/Requisitions.js"; import { - CdmEntityType, ConnectionDataModelEntry, ICdmRestRootEntry, - ICdmSchemaEntry, cdbDbEntityTypeName, cdmDbEntityTypes, - type ConnectionDataModel, type ICdmConnectionEntry, + CdmEntityType, ConnectionDataModelEntry, ICdmRestRootEntry, ICdmSchemaEntry, cdbDbEntityTypeName, cdmDbEntityTypes, + type ConnectionDataModel, type ConnectionDataModelNoGroupEntry, type ICdmConnectionEntry, } from "../../../../frontend/src/data-models/ConnectionDataModel.js"; import { ui } from "../../../../frontend/src/app-logic/UILayer.js"; @@ -47,6 +46,7 @@ import { convertErrorToString } from "../../../../frontend/src/utilities/helpers import { DBConnectionViewProvider } from "../../WebviewProviders/DBConnectionViewProvider.js"; import { AdminSectionTreeItem } from "./AdminSectionTreeItem.js"; import { AdminTreeItem } from "./AdminTreeItem.js"; +import { ConnectionGroupTreeItem } from "./ConnectionGroupTreeItem.js"; import { ConnectionMySQLTreeItem } from "./ConnectionMySQLTreeItem.js"; import { ConnectionSqliteTreeItem } from "./ConnectionSqliteTreeItem.js"; import { MrsAuthAppGroupTreeItem } from "./MrsAuthAppGroupTreeItem.js"; @@ -80,7 +80,7 @@ import { SchemaViewSqliteTreeItem } from "./SchemaViewSqliteTreeItem.js"; /** A class to provide the entire tree structure for DB editor connections and the DB objects from them. */ export class ConnectionsTreeDataProvider implements TreeDataProvider { - static #adminPageTypeToIcon = new Map([ + private static adminPageTypeToIcon = new Map([ ["serverStatus", "adminServerStatus.svg"], ["clientConnections", "clientConnections.svg"], ["performanceDashboard", "adminPerformanceDashboard.svg"], @@ -98,6 +98,9 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider(); public get onDidChangeTreeData(): Event { @@ -117,8 +120,8 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { - connection.currentSchema = ""; + this.dataModel.roots.forEach((connection) => { + if (connection.type === CdmEntityType.Connection) { + connection.currentSchema = ""; + } }); this.changeEvent.fire(undefined); } @@ -186,6 +191,10 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { if (result instanceof Error) { @@ -364,6 +375,8 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { + public async getCreateSqlScript(entry: ConnectionDataModelNoGroupEntry, entryType: string, withDelimiter = false, + withDrop = false, editRoutine = false): Promise { let sql = ""; const configuration = workspace.getConfiguration(`msg.dbEditor`); @@ -467,7 +482,7 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { + public async copyCreateScriptToClipboard(entry: ConnectionDataModelNoGroupEntry, dbType: string, + withDelimiter = false, withDrop = false): Promise { try { const sql = await this.getCreateSqlScript(entry, dbType, withDelimiter, withDrop); @@ -568,6 +583,17 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { - this.changeEvent.fire(entry); - }); + void entry.mrsEntry?.refresh?.(); // Tree item refresh happens in the data model change handler. + + return Promise.resolve(true); } - return Promise.resolve(true); + break; } default: @@ -645,15 +671,25 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider>>): void => { + if (this.updating) { + return; + } + list.forEach((action) => { switch (action.action) { case "add": { - this.changeEvent.fire(action.entry); + this.changeEvent.fire(action.entry?.parent); break; } case "remove": { - this.changeEvent.fire(action.entry); + const parent = action.entry?.parent; + if (parent?.type === CdmEntityType.ConnectionGroup && parent?.folderPath.id === 1) { + // A top level entry was removed, so refresh the entire tree. + this.changeEvent.fire(undefined); + } else { + this.changeEvent.fire(action.entry?.parent); + } break; } @@ -690,4 +726,33 @@ export class ConnectionsTreeDataProvider implements TreeDataProvider { + const aIsGroup = a.type === CdmEntityType.ConnectionGroup; + const bIsGroup = b.type === CdmEntityType.ConnectionGroup; + + if (aIsGroup && !bIsGroup) { + return -1; + } else if (!aIsGroup && bIsGroup) { + return 1; + } + + return 0; + }); + } + + return children; + } + } diff --git a/gui/extension/tests/e2e/lib/E2ETests.ts b/gui/extension/tests/e2e/lib/E2ETests.ts index 9663151a1..b70a4f2e0 100644 --- a/gui/extension/tests/e2e/lib/E2ETests.ts +++ b/gui/extension/tests/e2e/lib/E2ETests.ts @@ -46,13 +46,16 @@ export class E2ETests { public static testSuites: IE2ETestSuite[] = []; /** The MySQL port used by the deployed sandbox. Defaults to 3308 */ - public static mysqlPort = "3307"; + public static mysqlPort = "1107"; /** The MySQL port used by the deployed sandbox for REST tests*/ - public static mysqlPortRest = "3308"; + public static mysqlPortRest = "1108"; /** The MySQL port used by the deployed sandbox for ROUTER tests*/ - public static mysqlPortRouter = "3309"; + public static mysqlPortRouter = "1109"; + + /** The MySQL port used by the deployed sandbox for REST CONFIG tests*/ + public static mysqlPortRestConfig = "1110"; /** The MySQL deployed sandbox directory */ public static mysqlSandboxDir = process.cwd(); @@ -255,10 +258,13 @@ export class E2ETests { */ public static removeLogs = async (testSuite: IE2ETestSuite): Promise => { const logsFolderPath = join(testSuite.testResources, "settings", "logs"); - const folderItems = await fs.readdir(logsFolderPath); - for (const item of folderItems) { - await fs.rm(join(logsFolderPath, item), { recursive: true }); + if (existsSync(logsFolderPath)) { + const folderItems = await fs.readdir(logsFolderPath); + + for (const item of folderItems) { + await fs.rm(join(logsFolderPath, item), { recursive: true }); + } } }; @@ -271,7 +277,7 @@ export class E2ETests { this.checkMySql(); this.setShellBinary(); - for (const port of [this.mysqlPort, this.mysqlPortRest, this.mysqlPortRouter]) { + for (const port of [this.mysqlPort, this.mysqlPortRest, this.mysqlPortRouter, this.mysqlPortRestConfig]) { this.runShellCommand([ "--", @@ -303,12 +309,13 @@ export class E2ETests { this.runShellCommand([connUri, "--sql", "-e", `INSTALL COMPONENT "file://component_mle";`]); E2ELogger.success(`Installed MLE component`); - // CONFIGURE REST - this.runShellCommand([ - `root:${process.env.DBROOTPASSWORD}@localhost:${this.mysqlPortRouter}`, - "--py", "-e", "mrs.configure()", - ]); - E2ELogger.success(`MRS was configured successfully on MySQL instance ${this.mysqlPortRouter}`); + for (const port of [this.mysqlPortRest, this.mysqlPortRouter]) { + this.runShellCommand([ + `root:${process.env.DBROOTPASSWORD}@localhost:${port}`, + "--py", "-e", "mrs.configure()", + ]); + E2ELogger.success(`MRS was configured successfully on MySQL instance ${port}`); + } // CREATE THE OCI CONFIG FILE const ociConfigFile = ` @@ -351,6 +358,7 @@ key_file=${process.env.OCI_HW_KEY_FILE_PATH} process.env.MYSQL_PORT = this.mysqlPort; process.env.MYSQL_REST_PORT = this.mysqlPortRest; process.env.MYSQL_ROUTER_PORT = this.mysqlPortRouter; + process.env.MYSQL_REST_CONFIG_PORT = this.mysqlPortRestConfig; process.env.DBUSERNAME1 = "clientqa"; process.env.DBPASSWORD1 = "dummy"; process.env.DBUSERNAME2 = "shell"; @@ -644,7 +652,12 @@ key_file=${process.env.OCI_HW_KEY_FILE_PATH} E2ETests.setTestSuite("DB"); E2ETests.setShellBinary(); - const mysqlPorts = [E2ETests.mysqlPort, E2ETests.mysqlPortRest, E2ETests.mysqlPortRouter]; + const mysqlPorts = [ + E2ETests.mysqlPort, + E2ETests.mysqlPortRest, + E2ETests.mysqlPortRouter, + E2ETests.mysqlPortRestConfig, + ]; for (const mysqlPort of mysqlPorts) { diff --git a/gui/extension/tests/e2e/lib/Misc.ts b/gui/extension/tests/e2e/lib/Misc.ts index 7ec81a57d..285e4966d 100644 --- a/gui/extension/tests/e2e/lib/Misc.ts +++ b/gui/extension/tests/e2e/lib/Misc.ts @@ -277,13 +277,20 @@ export class Misc { public static removeDatabaseConnections = (): void => { const sqliteFile = join(process.env.MYSQLSH_GUI_CUSTOM_CONFIG_DIR, "plugin_data", "gui_plugin", "mysqlsh_gui_backend.sqlite3"); - const query1 = "DELETE FROM main.profile_has_db_connection"; - const query2 = "DELETE FROM main.db_connection"; + + const queries = [ + "DELETE FROM main.profile_has_db_connection", + "DELETE FROM main.db_connection", + "DELETE FROM main.folder_path WHERE caption <> '/'", + "DELETE FROM main.session", + ]; if (existsSync(sqliteFile)) { const sqlite = new Database(sqliteFile); - sqlite.run(query1); - sqlite.run(query2); + + for (const query of queries) { + sqlite.run(query); + } sqlite.close(); } else { throw new Error(`Could not find the sqlite file. Expected location: ${sqliteFile}`); diff --git a/gui/extension/tests/e2e/lib/SideBar/E2EAccordionSection.ts b/gui/extension/tests/e2e/lib/SideBar/E2EAccordionSection.ts index 5bc44f1d2..b62bb655f 100644 --- a/gui/extension/tests/e2e/lib/SideBar/E2EAccordionSection.ts +++ b/gui/extension/tests/e2e/lib/SideBar/E2EAccordionSection.ts @@ -579,18 +579,31 @@ export class E2EAccordionSection { }); }; + /** + * Verifies if the tree item has children + * @param element The element + * @returns A condition resolving to true if the tree item has children, false otherwise + */ + public untilTreeItemHasChildren = (element: string): Condition => { + return new Condition(`for ${element} to have a red mark`, async () => { + const treeItem = await this.getTreeItem(element); + + return treeItem.hasChildren(); + }); + }; + /** * Gets an action button from a tree element * @param element The tree item name * @param actionButton The action button d * @returns A promise resolving with the button */ - public getTreeItemActionButton = async (element: string, actionButton: string): Promise => { + public clickTreeItemActionButton = async (element: string, actionButton: string): Promise => { if ((await Misc.insideIframe())) { await Misc.switchBackToTopFrame(); } - return driver.wait(async () => { + await driver.wait(async () => { try { const treeItem = await this.getTreeItem(element); const btn = await treeItem.findElement(locator.section.itemAction(actionButton)); @@ -602,8 +615,9 @@ export class E2EAccordionSection { }).perform(); await driver.wait(until.elementIsVisible(btn), constants.wait1second * 5, `'${actionButton}' button was not visible`); + await btn.click(); - return btn; + return true; } catch (e) { if (!(errors.isStaleError(e as Error))) { throw e; diff --git a/gui/extension/tests/e2e/lib/WebViews/DatabaseConnectionOverview.ts b/gui/extension/tests/e2e/lib/WebViews/DatabaseConnectionOverview.ts index 7cd32d81b..9aa011672 100644 --- a/gui/extension/tests/e2e/lib/WebViews/DatabaseConnectionOverview.ts +++ b/gui/extension/tests/e2e/lib/WebViews/DatabaseConnectionOverview.ts @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -import { WebElement, until, Condition, Key } from "vscode-extension-tester"; +import { WebElement, until, Condition, Key, error } from "vscode-extension-tester"; import { driver, Misc } from "../Misc"; import * as constants from "../constants"; import * as locator from "../locators"; @@ -30,6 +30,8 @@ import { E2EToolbar } from "./E2EToolbar"; import * as errors from "../errors"; import { Os } from "../Os"; import { E2EShellConsole } from "./E2EShellConsole"; +import { IDBConnection } from "../interfaces"; +import { DatabaseConnectionDialog } from "./Dialogs/DatabaseConnectionDialog"; /** * This class represents the database connection overview page, and all its related functions @@ -39,6 +41,20 @@ export class DatabaseConnectionOverview { /** The toolbar*/ public toolbar = new E2EToolbar(); + /** + * Adds a new connection + * @param connection The DB Connection + */ + public addNewConnection = async (connection: IDBConnection): Promise => { + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await DatabaseConnectionDialog.setConnection(connection); + + }; + /** * Gets a Database connection from the DB Connection Overview * @param name The database connection caption @@ -76,6 +92,10 @@ export class DatabaseConnectionOverview { * @returns A promise resolving with the connection details */ public moreActions = async (dbConnection: string, option: string): Promise => { + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + const connection = await this.getConnection(dbConnection); const moreActions = await connection.findElement(locator.dbConnectionOverview.dbConnection.moreActions); await driver.actions().move({ origin: moreActions }).perform(); @@ -103,6 +123,7 @@ export class DatabaseConnectionOverview { */ public existsConnection = async (dbConnection: string): Promise => { let found = false; + if (!(await Misc.insideIframe())) { await Misc.switchToFrame(); } @@ -169,4 +190,157 @@ export class DatabaseConnectionOverview { "Shell Console was not loaded"); }; + /** + * Gets the breadcrumb item links + * @returns A promise resolving with the breadcrumb items as an array of WebElements + */ + public getBreadCrumbLinks = async (): Promise => { + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + + const breadCrumb = await driver.findElement(locator.dbConnectionOverview.breadCrumb.exists); + + return breadCrumb.findElements(locator.dbConnectionOverview.breadCrumb.item); + }; + + /** + * Gets the breadcrumb items as full path + * @returns A promise resolving with the breadcrumb items as an array of WebElements + */ + public getBreadCrumb = async (): Promise => { + let breadcrumb: string[]; + + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + + await driver.wait(async () => { + try { + const breadCrumb = await driver.findElement(locator.dbConnectionOverview.breadCrumb.exists); + const items = await breadCrumb.findElements(locator.dbConnectionOverview.breadCrumb.item); + + breadcrumb = await Promise.all(items.map(async (item: WebElement) => { + return (await item.getText()).replace(/\s/g, ""); + })); + + return true; + } catch (e) { + if (!(e instanceof error.StaleElementReferenceError)) { + throw e; + } + } + }, constants.wait1second * 3, "Could not get the breadcrumb items"); + + return breadcrumb.join(""); + }; + + /** + * Verifies if a group exists on the DB Connection Overview + * @param name The group name + * @returns A promise resolving to true if the group exists, false otherwise + */ + public existsGroup = async (name: string): Promise => { + let found = false; + + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + + await driver.wait(async () => { + try { + const hosts = await driver.findElements(locator.dbConnectionOverview.group.tile); + for (const host of hosts) { + const hostCation = await host.findElement(locator.dbConnectionOverview.group.caption); + const textCaption = await hostCation.getText(); + if (textCaption.match(new RegExp(name)) !== null) { + found = true; + + break; + } + } + + return true; + } catch (e) { + if (!(e instanceof error.StaleElementReferenceError)) { + throw e; + } + } + }, constants.wait1second * 5, "The groups were always stale"); + + return found; + }; + + /** + * Clicks on a group and waits until the breadcrumb has the group name, ensuring the user is inside the group + * @param name The group caption + * @returns A promise resolving with the group + */ + public joinGroup = async (name: string): Promise => { + await driver.wait(async () => { + const breadCrump = await this.getBreadCrumb(); + + if (!breadCrump.includes(name)) { + const group = await this.getGroup(name); + await group.click(); + } else { + return true; + } + + }); + }; + + /** + * Verifies if a group exists on the DB Connection Overview + * @param name The group name + * @returns A condition resolving to true if the group exists, false otherwise + */ + public untilGroupExists = (name: string): Condition => { + return new Condition(`for group ${name} to exist`, async () => { + return this.existsGroup(name); + }); + }; + + /** + * Gets a group from the DB Connection Overview + * @param name The group caption + * @returns A promise resolving with the group + */ + public getGroup = async (name: string): Promise => { + if (!(await Misc.insideIframe())) { + await Misc.switchToFrame(); + } + + const group = await driver.wait(async () => { + const groups = await driver.findElements(locator.dbConnectionOverview.group.tile); + + for (const grp of groups) { + try { + const el = await (await grp + .findElement(locator.dbConnectionOverview.group.caption)).getText(); + if (el.match(new RegExp(name)) !== null) { + return grp; + } + } catch (e) { + return undefined; + } + } + + return undefined; + }, constants.wait1second * 5, `The connection ${name} was not found on the Connection Browser`); + + return group; + }; + + /** + * Verifies if the breadcrumb is equal to a value + * @param value The breadcrumb value + * @returns A condition resolving to true when the breadcrumb is equal to the value + */ + public untilBreadCrumbIs = (value: string): Condition => { + return new Condition(`for breadcrumb to be '${value}'`, async () => { + return (await this.getBreadCrumb()) === value; + }); + }; + } diff --git a/gui/extension/tests/e2e/lib/WebViews/Dialogs/DatabaseConnectionDialog.ts b/gui/extension/tests/e2e/lib/WebViews/Dialogs/DatabaseConnectionDialog.ts index 5ae499592..87df11a06 100644 --- a/gui/extension/tests/e2e/lib/WebViews/Dialogs/DatabaseConnectionDialog.ts +++ b/gui/extension/tests/e2e/lib/WebViews/Dialogs/DatabaseConnectionDialog.ts @@ -28,6 +28,7 @@ import * as constants from "../../constants"; import * as interfaces from "../../interfaces"; import * as locator from "../../locators"; import { DialogHelper } from "./DialogHelper"; +import { FolderDialog } from "./FolderDialog"; /** * This class aggregates the functions to interact with the database connection dialog @@ -46,12 +47,23 @@ export class DatabaseConnectionDialog { const dialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), constants.wait1second * 25, "Connection dialog was not displayed"); + if (dbConfig.dbType) { - const inDBType = await dialog.findElement(locator.dbConnectionDialog.databaseType); - await inDBType.click(); - const popup = await driver.wait(until.elementLocated(locator.dbConnectionDialog.databaseTypeList), - constants.wait1second * 5, "Database type popup was not found"); - await popup.findElement(By.id(dbConfig.dbType)).click(); + + await driver.wait(async () => { + const inDBType = await dialog.findElement(locator.dbConnectionDialog.databaseType); + await inDBType.click(); + + try { + const popup = await driver.wait(until.elementLocated(locator.dbConnectionDialog.databaseTypeList), + constants.wait1second * 2, "Database type popup was not found"); + await popup.findElement(By.id(dbConfig.dbType)).click(); + + return true; + } catch (e) { + // repeat + } + }, constants.wait1second * 5, "Database type popup was not opened"); } if (dbConfig.caption) { await DialogHelper.setFieldText(dialog, locator.dbConnectionDialog.caption, dbConfig.caption); @@ -59,6 +71,22 @@ export class DatabaseConnectionDialog { if (dbConfig.description) { await DialogHelper.setFieldText(dialog, locator.dbConnectionDialog.description, dbConfig.description); } + if (dbConfig.folderPath) { + await dialog.findElement(locator.dbConnectionDialog.folderPath.exists).click(); + const selectList = await driver.wait(until + .elementLocated(locator.dbConnectionDialog.folderPath.selectList.exists), + + constants.wait1second * 3, "Could not find the Folder Path select list"); + + if (dbConfig.folderPath.new === true) { + await selectList.findElement(locator.dbConnectionDialog.folderPath.selectList.addNewFolder).click(); + await FolderDialog.setFolderValue(dbConfig.folderPath.value); + await FolderDialog.ok(); + } else { + await selectList.findElement(locator.dbConnectionDialog.folderPath.selectList + .item(dbConfig.folderPath.value)).click(); + } + } if (dbConfig.dbType) { if (dbConfig.dbType === "MySQL") { if (interfaces.isMySQLConnection(dbConfig.basic)) { @@ -271,6 +299,11 @@ export class DatabaseConnectionDialog { caption: await DialogHelper.getFieldValue(dialog, locator.dbConnectionDialog.caption), description: await DialogHelper.getFieldValue(dialog, locator.dbConnectionDialog.description), }; + + dbConnection.folderPath = { + value: await (await dialog.findElement(locator.dbConnectionDialog.folderPath.label)).getText(), + }; + if (dbConnection.dbType === "MySQL") { const basic: interfaces.IConnBasicMySQL = { hostname: await DialogHelper.getFieldValue(dialog, locator.dbConnectionDialog.mysql.basic.hostname), diff --git a/gui/extension/tests/e2e/lib/WebViews/Dialogs/FolderDialog.ts b/gui/extension/tests/e2e/lib/WebViews/Dialogs/FolderDialog.ts new file mode 100644 index 000000000..513fd9e32 --- /dev/null +++ b/gui/extension/tests/e2e/lib/WebViews/Dialogs/FolderDialog.ts @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have included with + * the program or referenced in the documentation. + * + * 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, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +import { until } from "vscode-extension-tester"; +import { driver } from "../../Misc"; +import * as locator from "../../locators.js"; +import * as constants from "../../constants.js"; + +/** + * This class aggregates the functions that perform folder dialog related operations + */ +export class FolderDialog { + + /** + * Sets the folder dialog value + * @param value The value to set + */ + public static setFolderValue = async (value: string): Promise => { + const folderPathDialog = await driver.wait(until.elementLocated(locator.createNewFolderDialog.exists), + constants.wait1second * 3, "Could not find the Create Folder dialog"); + const path = await folderPathDialog + .findElement(locator.createNewFolderDialog.name); + await path.clear(); + await path.sendKeys(value); + }; + + /** + * Clicks on the ok button of the dialog + */ + public static ok = async (): Promise => { + const folderPathDialog = await driver.wait(until.elementLocated(locator.createNewFolderDialog.exists), + constants.wait1second * 3, "Could not find the Create Folder dialog"); + await folderPathDialog.findElement(locator.createNewFolderDialog.ok).click(); + }; + + /** + * Clicks on the cancel button of the dialog + */ + public static cancel = async (): Promise => { + const folderPathDialog = await driver.wait(until.elementLocated(locator.createNewFolderDialog.exists), + constants.wait1second * 3, "Could not find the Create Folder dialog"); + await folderPathDialog.findElement(locator.createNewFolderDialog.cancel).click(); + }; + +} diff --git a/gui/extension/tests/e2e/lib/WebViews/Dialogs/RestUserDialog.ts b/gui/extension/tests/e2e/lib/WebViews/Dialogs/RestUserDialog.ts index 7c1965069..f185e252d 100644 --- a/gui/extension/tests/e2e/lib/WebViews/Dialogs/RestUserDialog.ts +++ b/gui/extension/tests/e2e/lib/WebViews/Dialogs/RestUserDialog.ts @@ -135,7 +135,7 @@ export class RestUserDialog { restUser.permitLogin = await DialogHelper.getCheckBoxValue("loginPermitted"); await driver.wait(async () => { - await dialog.findElement(locator.mrsUserDialog.ok).click(); + await dialog.findElement(locator.mrsUserDialog.cancel).click(); return (await DialogHelper.existsDialog()) === false; }, constants.wait1second * 10, "The MRS User dialog was not closed"); diff --git a/gui/extension/tests/e2e/lib/constants.ts b/gui/extension/tests/e2e/lib/constants.ts index b1fc3a22b..78821b593 100644 --- a/gui/extension/tests/e2e/lib/constants.ts +++ b/gui/extension/tests/e2e/lib/constants.ts @@ -320,6 +320,7 @@ export const addRESTUser = "Add User"; export const editRESTUser = "Edit User"; export const deleteRESTUser = "Delete User"; export const vendorOCIOAuth2 = "OCI OAuth2"; +export const mrs = "MRS"; export const checkNewTabAndWebView = "Check New Tab and WebView"; export const checkNewTab = "Check New Tab"; @@ -584,7 +585,18 @@ export const dbTreeSectionMoreActionsCtxMenu = new Map([ [resetExtension, 4], ]); +export const addSubfolder = "Add Sub Folder"; +export const editFolder = "Edit Folder"; +export const removeFolder = "Delete Folder"; + +export const groupsCtxMenu = new Map([ + [addSubfolder, 1], + [editFolder, 2], + [removeFolder, 3], +]); + export const restServiceMetadataSchema = "mysql_rest_service_metadata"; export const ociFailure = "OCI Failure"; export const mysqlRouters = "MySQL Routers"; export const reloadDataBaseInformation = "Reload Database Information"; + diff --git a/gui/extension/tests/e2e/lib/interfaces.ts b/gui/extension/tests/e2e/lib/interfaces.ts index 3dde9f2e1..d8452b0bf 100644 --- a/gui/extension/tests/e2e/lib/interfaces.ts +++ b/gui/extension/tests/e2e/lib/interfaces.ts @@ -111,6 +111,10 @@ export interface IDBConnection { dbType?: string; caption?: string; description?: string; + folderPath?: { + new?: boolean; + value?: string; + }; basic?: IConnBasicMySQL | IConnBasicSqlite; ssl?: IConnSSL; advanced?: IConnAdvancedMySQL | IConnAdvancedSqlite; diff --git a/gui/extension/tests/e2e/lib/locators.ts b/gui/extension/tests/e2e/lib/locators.ts index b4dcbce16..3e4ad3c5a 100644 --- a/gui/extension/tests/e2e/lib/locators.ts +++ b/gui/extension/tests/e2e/lib/locators.ts @@ -32,6 +32,17 @@ export const dbConnectionDialog = { databaseTypeList: By.id("databaseTypePopup"), databaseTypeMysql: By.id("MySQL"), databaseTypeSqlite: By.id("Sqlite"), + folderPath: { + exists: By.id("folderPath"), + label: By.css("#folderPath label"), + selectList: { + exists: By.css("#folderPathPopup .popup.visible"), + addNewFolder: By.id(""), + item: (itemName: string): By => { + return By.id(itemName); + }, + }, + }, mysql: { basic: { hostname: By.id("hostName"), @@ -646,6 +657,7 @@ export const dbConnectionOverview = { newConsoleButton: By.id("newConsoleMenuButton"), browser: By.className("connectionBrowser"), newDBConnection: By.id("-1"), + back: By.id("-2"), dbConnection: { tile: By.css("#tilesHost .connectionTile"), caption: By.className("tileCaption"), @@ -658,6 +670,15 @@ export const dbConnectionOverview = { newScript: By.id("tileNewScriptAction"), contextMenu: By.css(".noArrow.menu"), }, + group: { + tile: By.css("#tilesHost .group"), + caption: By.className("tileCaption"), + description: By.css(".tileDescription"), + }, + breadCrumb: { + exists: By.css(".breadcrumb"), + item: By.css(".breadcrumbItem"), + }, closeHeader: By.id("closeButton"), }; @@ -995,4 +1016,9 @@ export const notification = { export const sideBarItems = By.css(".composite-bar .actions-container > li"); export const togglePrimarySideBar = By.xpath("//a[contains(@aria-label, 'Toggle Primary Side Bar')]"); - +export const createNewFolderDialog = { + exists: By.id("connectionFolderPath"), + name: By.id("input"), + ok: By.id("ok"), + cancel: By.id("cancel"), +}; diff --git a/gui/extension/tests/e2e/setup/settings.json b/gui/extension/tests/e2e/setup/settings.json index edd878cbd..2b2031b94 100644 --- a/gui/extension/tests/e2e/setup/settings.json +++ b/gui/extension/tests/e2e/setup/settings.json @@ -2,7 +2,7 @@ "terminal.integrated.copyOnSelection": true, "terminal.integrated.sendKeybindingsToShell": true, "window.dialogStyle": "custom", - "msg.debugLog.level": "DEBUG2", + "msg.debugLog.level": "DEBUG3", "terminal.integrated.gpuAcceleration": "off", "workbench.colorTheme": "Dark Modern", "disable-hardware-acceleration": true, diff --git a/gui/extension/tests/e2e/tests/ui-db.ts b/gui/extension/tests/e2e/tests/ui-db.ts index 01a988c63..fc1fdf35d 100644 --- a/gui/extension/tests/e2e/tests/ui-db.ts +++ b/gui/extension/tests/e2e/tests/ui-db.ts @@ -28,7 +28,7 @@ import fs from "fs/promises"; import { BottomBarPanel, Condition, TreeItem, until, WebElement, Workbench as extWorkbench, ActivityBar, CustomTreeItem, - SideBarView, CustomTreeSection, + SideBarView, CustomTreeSection, error, } from "vscode-extension-tester"; import { expect } from "chai"; import clipboard from "clipboardy"; @@ -105,7 +105,40 @@ describe("DATABASE CONNECTIONS", () => { }); - describe("Toolbar", () => { + describe("Tree context menu items", () => { + + let treeGlobalSchema: TreeItem; + let treeGlobalSchemaTables: TreeItem; + let treeGlobalSchemaViews: TreeItem; + let treeGlobalConn: TreeItem; + const dumpFolder = join(constants.workspace, "dump"); + const dumpSchemaToDisk = `dump_schema_to_disk`; + const schemaForMySQLDbService = "schema_for_mysql_db_service"; + const schemaToDrop = "schema_to_drop"; + const tableToDrop = `table_to_drop`; + const testView = `test_view`; + const viewToDrop = "view_to_drop"; + const testRoutine = "test_function"; + const testEvent = "test_event"; + const dup = "duplicatedConnection"; + const tasksTreeSection = new E2EAccordionSection(constants.tasksTreeSection); + let existsInQueue = false; + + before(async function () { + await Os.appendToExtensionLog("beforeAll Tree context menu items"); + try { + await Os.deleteCredentials(); + await dbTreeSection.focus(); + treeGlobalConn = await dbTreeSection.getTreeItem(globalConn.caption); + await treeGlobalConn.collapse(); + await Workbench.closeAllEditors(); + await dbTreeSection.clickToolbarButton(constants.collapseAll); + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); beforeEach(async function () { await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); @@ -115,667 +148,548 @@ describe("DATABASE CONNECTIONS", () => { if (this.currentTest.state === "failed") { await Misc.processFailure(this); } + + if (existsInQueue) { + await TestQueue.pop(this.currentTest.title); + existsInQueue = false; + } }); - it("Reload the connection list", async () => { + after(async () => { - await driver.wait(dbTreeSection.untilTreeItemExists(globalConn.caption), constants.waitForTreeItem); + await fs.rm(dumpFolder, { force: true, recursive: true }); }); - it("Collapse All", async () => { + it("Set this DB Connection as Default", async () => { - await dbTreeSection.focus(); - await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); - const treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) - .schema); + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.setDBConnDefault); + await driver.wait(Workbench + .untilNotificationExists(`"${globalConn.caption}" has been set as default DB Connection`), + constants.wait1second * 10); - await treeGlobalSchema.expand(); - const treeGlobalSchemaTables = await dbTreeSection.getTreeItem("Tables"); - await treeGlobalSchemaTables.expand(); - const treeGlobalSchemaViews = await dbTreeSection.getTreeItem("Views"); - await treeGlobalSchemaViews.expand(); - const treeDBSection: CustomTreeSection = await new SideBarView().getContent() - .getSection(constants.dbTreeSection); - await dbTreeSection.clickToolbarButton(constants.collapseAll); + }); + + it("Open Database Connection", async () => { - let visibleItems: CustomTreeItem[]; await driver.wait(async () => { - visibleItems = await treeDBSection.getVisibleItems(); - if (visibleItems.length > 0) { - for (const item of visibleItems) { - if (await item.getAttribute("aria-level") !== "1") { - return false; - } - } + try { + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.openNewConnection); + await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.wait1second * 6); return true; + } catch (e) { + if (!(e instanceof error.TimeoutError)) { + throw e; + } } - }, constants.wait1second * 5, "The tree is not fully collapsed"); - }); + }, constants.wait1second * 20, "Could not open the database connection"); - it("Restart internal MySQL Shell process", async () => { + }); - await fs.truncate(Os.getMysqlshLog()); - await dbTreeSection.selectMoreActionsItem(constants.restartInternalShell); - const notification = await Workbench.getNotification("This will close all MySQL Shell tabs", false); - await Workbench.clickOnNotificationButton(notification, "Restart MySQL Shell"); - await driver.wait(async () => { - return Os.findOnMySQLShLog(/Info/); - }, constants.wait1second * 5 * 3, "Shell server did not start"); + it("Open MySQL Shell Console for this connection", async () => { - try { - await driver.wait(async () => { - const text = await fs.readFile(Os.getMysqlshLog()); - if (text.includes("Registering session...")) { - return true; - } - }, constants.wait1second * 20, "Restarting the internal MySQL Shell server went wrong"); - } finally { - E2ELogger.info("<<<>>>"); - await Os.writeMySQLshLogs(); - } + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.openShellConnection); + await driver.wait(new E2EShellConsole().untilIsOpened(globalConn), constants.waitShellOpen); + const treeOpenEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + await treeOpenEditorsSection.expand(); + await treeOpenEditorsSection.focus(); + const treeOEShellConsoles = await treeOpenEditorsSection.getTreeItem(constants.mysqlShellConsoles); + expect(await treeOEShellConsoles.findChildItem(`Session to ${String(globalConn.caption)}`), + errors.doesNotExistOnTree(`Session to ${String(globalConn.caption)}`)).to.exist; }); - it("Relaunch Welcome Wizard", async () => { + it("Edit MySQL connection", async () => { - await dbTreeSection.selectMoreActionsItem(constants.relaunchWelcomeWizard); - await driver.wait(Workbench.untilTabIsOpened(constants.welcomeTab), constants.wait1second * 5); - const active = await Workbench.getActiveTab(); - let error = `The active tab should be ${constants.welcomeTab}`; - error += `, but found ${await active.getTitle()}`; - expect(await active.getTitle(), error).equals(constants.welcomeTab); - await driver.wait(until.ableToSwitchToFrame(0), constants.wait1second * 5, "Not able to switch to frame 0"); - await driver.wait(until.ableToSwitchToFrame( - locator.iframe.isActive), constants.wait1second * 5, "Not able to switch to frame 2"); - const text = await driver.findElement(locator.welcomeWizard.title).getText(); - expect(text, `The Welcome wizard title should be ${constants.welcome}, but found ${text}`) - .equals(constants.welcome); - expect(await driver.findElement(locator.welcomeWizard.nextButton), - `Next button does not exist on the welcome wizard`).to.exist; + await dbTreeSection.focus(); + await dbTreeSection.clickToolbarButton(constants.collapseAll); + const localConn = Object.assign({}, globalConn); + localConn.caption = `e2eConnectionToEdit`; + await dbTreeSection.createDatabaseConnection(localConn); + await new DatabaseConnectionOverview().getConnection(localConn.caption); + await dbTreeSection.openContextMenuAndSelect(localConn.caption, constants.editDBConnection); + await DatabaseConnectionDialog.setConnection(localConn); + await driver.wait(dbTreeSection.untilTreeItemExists(localConn.caption), constants.waitForTreeItem); }); - it("Reset MySQL Shell for VS Code Extension", async () => { + it("Duplicate this MySQL connection", async () => { - await Workbench.closeAllEditors(); - await dbTreeSection.selectMoreActionsItem(constants.resetExtension); - let notification = "This will completely reset the MySQL Shell for VS Code extension by "; - notification += "deleting the web certificate and optionally deleting the user settings directory."; - const ntf = await Workbench.getNotification(notification, false); - await Workbench.clickOnNotificationButton(ntf, constants.cancel); + const dupConn = Object.assign({}, globalConn); + dupConn.caption = dup; + await dbTreeSection.focus(); + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.duplicateConnection); + await DatabaseConnectionDialog.setConnection(dupConn); + await driver.wait(dbTreeSection.untilTreeItemExists(dup), constants.waitForTreeItem); }); - }); - describe("DB Connection Overview", () => { - - const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); - const dbConnectionOverview = new DatabaseConnectionOverview(); - let existsInQueue = false; + it("Delete DB connection", async () => { - const duplicateConnection: interfaces.IDBConnection = { - dbType: "MySQL", - caption: "e2eDuplicateFromGlobal", - basic: { - hostname: "localhost", - username: String(process.env.DBUSERNAME1), - port: parseInt(process.env.MYSQL_PORT, 10), - schema: "sakila", - password: String(process.env.DBPASSWORD1), - }, - }; + await dbTreeSection.focus(); - before(async function () { - await Os.appendToExtensionLog("beforeAll DB Connection Overview"); - try { - await new BottomBarPanel().toggle(false); - await Os.deleteCredentials(); - await openEditorsSection.focus(); - await (await openEditorsSection.getTreeItem(constants.dbConnectionsLabel)).click(); + for (const connection of [dup, "e2eConnectionToEdit"]) { + await dbTreeSection.openContextMenuAndSelect(connection, constants.deleteDBConnection); await Misc.switchToFrame(); - await driver.wait(until.elementLocated(locator.dbConnectionOverview.exists), - constants.wait1second * 10, "DB Connection Overview page was not displayed"); - const closeHeaderButton = await driver.findElements(locator.dbConnectionOverview.closeHeader); - if (closeHeaderButton.length > 0) { - await closeHeaderButton[0].click(); - } - } catch (e) { - await Misc.processFailure(this); - throw e; + const dialog = await driver.wait(until.elementLocated( + locator.confirmDialog.exists), constants.wait1second * 15, "confirm dialog was not found"); + await dialog.findElement(locator.confirmDialog.accept).click(); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(connection)); + }, constants.wait1second * 5, `Waiting for ${connection} to not exist on the tree`); } }); - let sslConn: interfaces.IDBConnection; + it("Load SQL Script from Disk", async () => { - beforeEach(async function () { - await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); - try { - await dbConnectionOverview.toolbar.editorSelector - .selectEditor(new RegExp(constants.dbConnectionsLabel)); - } catch (e) { - await Misc.processFailure(this); - throw e; - } + const e2eScript = new E2EScript(); + const script = "2_sakila_cst.sql"; + const destFile = join(constants.workspace, "gui", "frontend", "src", "tests", "e2e", "sql", script); + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.loadScriptFromDisk); + await Workbench.setInputPath(destFile); + await driver.wait(e2eScript.untilIsOpened(globalConn), constants.wait1second * 15); + await driver.wait(async () => { + return ((await e2eScript.toolbar.editorSelector.getCurrentEditor()).label) === script; + }, constants.wait1second * 5, `Current editor is not ${script}`); + let error = `The current editor type should be 'Mysql',`; + error += ` but found ${(await e2eScript.toolbar.editorSelector.getCurrentEditor()).icon}`; + expect((await e2eScript.toolbar.editorSelector.getCurrentEditor()).icon, error) + .to.include(constants.mysqlScriptIcon); + const scriptLines = await driver.findElements(locator.notebook.codeEditor.editor.line); + expect(scriptLines.length, "The script was not loaded. No lines found on the editor").to.be.greaterThan(0); + await e2eScript.toolbar.editorSelector.selectEditor(new RegExp(constants.openEditorsDBNotebook), + globalConn.caption); }); - afterEach(async function () { + it("Set as Current Database Schema", async () => { - if (this.currentTest.state === "failed") { - await Misc.processFailure(this); - } + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL).schema, + constants.setCurrentDBSchema, undefined); + await driver.wait(dbTreeSection.untilTreeItemIsDefault("sakila"), constants.wait1second * 5); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.openNewConnectionUsingNotebook); + await Workbench.openEditor(globalConn.caption); - if (existsInQueue) { - await TestQueue.pop(this.currentTest.title); - existsInQueue = false; - } + const notebook = new E2ENotebook(); + await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); - }); + let result = await notebook.codeEditor.execute("SELECT DATABASE();") as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + expect(await result.resultContext.getAttribute("innerHTML")) + .to.match(new RegExp((globalConn.basic as interfaces.IConnBasicMySQL).schema)); - after(async () => { + await dbTreeSection.openContextMenuAndSelect("world_x_cst", constants.setCurrentDBSchema, undefined); + await driver.wait(dbTreeSection.untilTreeItemIsDefault("world_x_cst"), constants.wait1second * 5); - await Workbench.openMySQLShellForVSCode(); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemIsDefault("sakila")); + }, constants.wait1second * 3, `sakila should not be the default schema on the tree`); - }); + await Workbench.openEditor(globalConn.caption); + await notebook.codeEditor.clean(); + result = await notebook.codeEditor.execute("SELECT DATABASE();") as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + expect(await result.resultContext.getAttribute("innerHTML")).to.match(/world_x_cst/); + await Workbench.closeAllEditors(); - it("MySQL Database connection - Verify mandatory fields", async () => { + await driver.wait(async () => { + return !(await dbTreeSection.treeItemIsDefault("world_x_cst")); + }, constants.wait1second * 5, "world_x_cst should not be the default"); - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), - constants.wait1second * 5, "Connection dialog was not displayed"); + expect(await dbTreeSection.treeItemIsDefault("sakila"), errors.isDefault("sakila")).to.be.false; + }); - const caption = await conDialog.findElement(locator.dbConnectionDialog.caption); - const hostname = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.hostname); + it("Dump Schema to Disk", async () => { - await DialogHelper.clearInputField(caption); - await DialogHelper.clearInputField(hostname); + treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) + .schema); + await fs.rm(dumpFolder, { force: true, recursive: true }); + await fs.mkdir(dumpFolder); + await dbTreeSection.openContextMenuAndSelect(dumpSchemaToDisk, + [constants.dumpToDisk, constants.databaseSchemaDump], constants.schemaCtxMenu); + await Workbench.setInputPath(dumpFolder); + await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); + await Workbench.waitForOutputText(`Task 'Dump Schema ${dumpSchemaToDisk} to Disk' completed successfully`, + constants.wait1second * 10); + const files = await fs.readdir(dumpFolder); + expect(files.length, `The dump did not exported any files to ${dumpFolder}`).to.be.greaterThan(0); + await tasksTreeSection.focus(); + await driver.wait(tasksTreeSection.untilTreeItemExists(`Dump Schema ${dumpSchemaToDisk} to Disk (done)`), + constants.waitForTreeItem); + await dbTreeSection.focus(); + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); - await conDialog.findElement(locator.dbConnectionDialog.ok).click(); - await driver.wait(async () => { - return (await conDialog.findElements(locator.dbConnectionDialog.errorMessage)).length > 0; - }, constants.wait1second * 5, "The DB Connection dialog should have errors"); + await dbTreeSection.openContextMenuAndSelect(dumpSchemaToDisk, constants.dropSchema); + await Workbench.pushDialogButton(`Drop ${dumpSchemaToDisk}`); + await Workbench.getNotification(`The object ${dumpSchemaToDisk} has been dropped successfully.`); - const dialogErrors = await conDialog.findElements(locator.dbConnectionDialog.errorMessage); - const errorMsgs = await Promise.all( - dialogErrors.map((item: WebElement) => { - return item.getText(); - })); - expect(errorMsgs, `Could not find the error message 'The user name must not be empty' on the dialog`) - .to.include("The user name must not be empty"); - expect(await caption.getAttribute("value"), errors.captionError("New Connection", - await caption.getAttribute("value"))).to.include("New Connection"); - let error = `The hostname should be 'localhost'`; - error += ` but found ${await hostname.getAttribute("value")}`; - expect(await hostname.getAttribute("value"), error).to.equals("localhost"); - await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(dumpSchemaToDisk)); + }, constants.waitForTreeItem, `${dumpSchemaToDisk} should not exist on the tree`); }); - it("SQLite Database connection - Verify mandatory fields", async () => { + it("Load Dump from Disk", async function () { - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), - constants.wait1second * 5, "Connection dialog was not displayed"); + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); - await conDialog.findElement(locator.dbConnectionDialog.databaseType).click(); - const popup = await driver.wait(until.elementLocated(locator.dbConnectionDialog.databaseTypeList), - constants.wait1second * 5, "Database type popup was not found"); - await popup.findElement(locator.dbConnectionDialog.databaseTypeSqlite).click(); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.loadDumpFromDisk); + await Workbench.setInputPath(dumpFolder); + await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); + await Workbench.waitForOutputText(/Task 'Loading Dump .* from Disk' completed successfully/, + constants.wait1second * 10); + await driver.wait(dbTreeSection.untilTreeItemExists(dumpSchemaToDisk), constants.waitForTreeItem); - const caption = await conDialog.findElement(locator.dbConnectionDialog.caption); - await DialogHelper.clearInputField(caption); + }); - await conDialog.findElement(locator.dbConnectionDialog.ok).click(); - await driver.wait(async () => { - return (await conDialog.findElements(locator.dbConnectionDialog.errorMessage)).length > 0; - }, constants.wait1second * 5, "The DB Connection dialog should have errors"); + it("Dump Schema to Disk for MySQL Database Service", async function () { - const dialogErrors = await conDialog.findElements(locator.dbConnectionDialog.errorMessage); - const errorMsgs = await Promise.all( - dialogErrors.map((item: WebElement) => { - return item.getText(); - })); - expect(await caption.getAttribute("value"), errors.captionError("New Connection", - await caption.getAttribute("value"))).to.include("New Connection"); - expect(errorMsgs, "'Specify the path to an existing Sqlite DB file' error was not found on the dialog") - .to.include("Specify the path to an existing Sqlite DB file"); - await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + await fs.rm(dumpFolder, { force: true, recursive: true }); + await fs.mkdir(dumpFolder); + await dbTreeSection.openContextMenuAndSelect(schemaForMySQLDbService, + [constants.dumpToDisk, constants.databaseSchemaDumpRest], constants.schemaCtxMenu); + await Workbench.setInputPath(dumpFolder); + await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); + await Workbench + .waitForOutputText(`Task 'Dump Schema ${schemaForMySQLDbService} to Disk' completed successfully`, + constants.wait1second * 10); + const files = await fs.readdir(dumpFolder); + expect(files.length, `The dump did not exported any files to ${dumpFolder}`).to.be.greaterThan(0); }); - it("Connect to SQLite database", async () => { - - const sqliteConn = Object.assign({}, globalConn); - sqliteConn.dbType = "Sqlite"; - sqliteConn.caption = `e2eSqliteConnection`; + it("Load Data to HeatWave Cluster", async () => { - if (Os.isLinux()) { - process.env.USERPROFILE = process.env.HOME; - } + await dbTreeSection.focus(); + await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL).schema, + constants.loadDataToHW); + await DatabaseConnectionDialog.setDataToHeatWave(); + await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); + await Workbench.getNotification("The data load to the HeatWave cluster operation has finished"); + await new BottomBarPanel().toggle(false); - sqliteConn.basic = { - dbPath: join(process.cwd(), "e2e_test.sqlite3"), - dbName: "SQLite", - }; - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await DatabaseConnectionDialog.setConnection(sqliteConn); - const sqliteWebConn = dbConnectionOverview.getConnection(sqliteConn.caption); + }); - await driver.executeScript( - "arguments[0].click();", - sqliteWebConn, - ); + it("Drop Schema", async () => { - const notebook = new E2ENotebook(); - await driver.wait(notebook.untilIsOpened(sqliteConn), constants.waitConnectionOpen); await dbTreeSection.focus(); - await dbTreeSection.clickToolbarButton(constants.reloadConnections); - await driver.wait(new Condition("", async () => { - const item = await dbTreeSection.getTreeItem(sqliteConn.caption); - await item.expand(); + await dbTreeSection.openContextMenuAndSelect(schemaToDrop, constants.dropSchema); + const ntfs = await new extWorkbench().getNotifications(); - return item.isExpanded(); - }), constants.wait1second * 10, `${sqliteConn.caption} was not expanded`); + if (ntfs.length > 0) { + await Workbench.clickOnNotificationButton(ntfs[ntfs.length - 1], `Drop ${schemaToDrop}')]`); + } else { + await Workbench.pushDialogButton(`Drop ${schemaToDrop}`); + } - await driver.wait(new Condition("", async () => { - const item = await dbTreeSection.getTreeItem("main"); - await item.expand(); + await Workbench.getNotification(`The object ${schemaToDrop} has been dropped successfully.`); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(schemaToDrop)); + }, constants.wait1second * 5, `${schemaToDrop} should not exist on the tree`); + }); - return item.isExpanded(); - }), constants.wait1second * 10, `main was not expanded`); + it("Schema - Copy name and create statement to clipboard", async function () { - await driver.wait(new Condition("", async () => { - const item = await dbTreeSection.getTreeItem("Tables"); - await item.expand(); + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); - return item.isExpanded(); - }), constants.wait1second * 10, `Tables was not expanded`); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL) + .schema, [constants.copyToClipboard, + constants.copyToClipboardName], constants.schemaCtxMenu); + await Workbench.getNotification("The name was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - await dbTreeSection.openContextMenuAndSelect("db_connection", constants.selectRowsInNotebook); - await driver.wait(notebook.untilIsOpened(sqliteConn), constants.waitConnectionOpen); - const result = await notebook.executeWithButton("SELECT * FROM main.db_connection;", - constants.execFullBlockSql) as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - }); + return clipboard.readSync() === (globalConn.basic as interfaces.IConnBasicMySQL).schema; + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The schema name was not copied to the clipboard"); - it("Connect to MySQL database using SSL", async () => { + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL) + .schema, [constants.copyToClipboard, + constants.copyToClipboardStat], constants.schemaCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - sslConn = Object.assign({}, globalConn); - sslConn.caption = `e2eSSLConnection`; + return clipboard.readSync().includes("CREATE DATABASE"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The schema create statement was not copied to the clipboard"); - sslConn.ssl = { - mode: "Require and Verify CA", - caPath: join(process.env.SSL_CERTIFICATES_PATH, "ca.pem"), - clientCertPath: join(process.env.SSL_CERTIFICATES_PATH, "client-cert.pem"), - clientKeyPath: join(process.env.SSL_CERTIFICATES_PATH, "client-key.pem"), - }; + }); - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await DatabaseConnectionDialog.setConnection(sslConn); - const dbConn = dbConnectionOverview.getConnection(sslConn.caption); + it("Table - Select Rows in DB Notebook", async () => { - await driver.executeScript("arguments[0].click();", dbConn); + treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) + .schema); + await treeGlobalSchema.expand(); + treeGlobalSchemaTables = await dbTreeSection.getTreeItem("Tables"); + await treeGlobalSchemaTables.expand(); + await dbTreeSection.openContextMenuAndSelect("actor", constants.selectRowsInNotebook); const notebook = new E2ENotebook(); - await driver.wait(notebook.untilIsOpened(sslConn), constants.waitConnectionOpen); - const query = - `select * from performance_schema.session_status where variable_name in - ("ssl_cipher") and variable_value like "%TLS%";`; + await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); + const result = await notebook.codeEditor.getLastExistingCommandResult(true) as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); - const result = await notebook.codeEditor.execute(query) as E2ECommandResultGrid; - expect(result.status).to.match(/1 record retrieved/); }); - it("Copy paste and cut paste into the DB Connection dialog", async function () { + it("Table - Copy name and create statement to clipboard", async function () { await TestQueue.push(this.test.title); existsInQueue = true; await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), - constants.wait1second * 5, "Connection dialog was not displayed"); - const hostNameInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.hostname); - const valueToCopy = await hostNameInput.getAttribute("value"); - await driver.wait(async () => { - await Os.keyboardSelectAll(hostNameInput); - await Os.keyboardCopy(hostNameInput); - const usernameInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.username); - await Os.keyboardPaste(usernameInput); + await dbTreeSection.focus(); - return (await usernameInput.getAttribute("value")).includes(valueToCopy); - }, constants.wait1second * 15, `Could not copy paste ${valueToCopy} to user name field`); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect("actor", [constants.copyToClipboard, + constants.copyToClipboardName], constants.dbObjectCtxMenu); + await Workbench.getNotification("The name was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - expect(await hostNameInput.getAttribute("value"), - "Hostname value should stay the same after copying it to the clipboard").to.equal(valueToCopy); - const descriptionInput = await conDialog.findElement(locator.dbConnectionDialog.description); - await DialogHelper.clearInputField(descriptionInput); - await descriptionInput.sendKeys("testing"); - const valueToCut = await descriptionInput.getAttribute("value"); - await Os.keyboardSelectAll(descriptionInput); - await Os.keyboardCut(descriptionInput); - expect(await descriptionInput.getAttribute("value"), "Description value was not cut").to.equals(""); - const schemaInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.defaultSchema); - await Os.keyboardPaste(schemaInput); - expect(await schemaInput.getAttribute("value"), - "Hostname value was not pasted to the description field").to.include(valueToCut); - await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + return clipboard.readSync() === "actor"; + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The table name was not copied to the clipboard"); - }); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect("actor", [constants.copyToClipboard, + constants.copyToClipboardStat], constants.dbObjectCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - it("Edit a MySQL connection", async () => { + return clipboard.readSync().includes("idx_actor_last_name"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The table create statement was not copied to the clipboard"); - const editConn: interfaces.IDBConnection = { - dbType: "MySQL", - caption: `e2eConnectionToEdit`, - description: "Local connection", - basic: { - hostname: "localhost", - username: String(process.env.DBUSERNAME1), - port: 3308, - schema: "sakila", - password: String(process.env.DBPASSWORD1), - }, - }; + }); - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await DatabaseConnectionDialog.setConnection(editConn); - await dbConnectionOverview.moreActions(editConn.caption, constants.editConnection); - editConn.caption = "e2eEditedCaption"; - editConn.description = "edited description"; - if (interfaces.isMySQLConnection(editConn.basic)) { - editConn.basic.hostname = "hostname edited"; - editConn.basic.username = "username edited"; - editConn.basic.schema = "edited schema"; - editConn.basic.protocol = "mysqlx"; - editConn.basic.port = 3305; - editConn.basic.sshTunnel = true; - editConn.basic.ociBastion = true; - editConn.ssl = { - mode: "Require", - ciphers: "ciphers, edited", - caPath: "ca edited", - clientCertPath: "cert edited", - clientKeyPath: "key edited", - }; - editConn.ssh = { - uri: "edited uri", - privateKey: "edited private key", - customPath: "edited custom path", - }; - editConn.advanced = { - // bug : https://mybug.mysql.oraclecorp.com/orabugs/site/bug.php?id=36482559 - /*mode: { - ansi: true, - traditional: true, - allowInvalidDates: true, - ansiQuotes: true, - errorForDivisionByZero: true, - highNotPrecedence: true, - ignoreSpace: true, - noAutoValueOnZero: true, - noUnsignedSubtraction: true, - noZeroDate: true, - noZeroInDate: true, - onlyFullGroupBy: true, - padCharToFullLength: true, - pipesAsConcat: true, - realAsFloat: true, - strictAllTables: true, - strictTransTables: true, - timeTruncateFractional: true, - }, - timeout: "5",*/ - mode: { - ansi: false, - traditional: false, - allowInvalidDates: false, - ansiQuotes: false, - errorForDivisionByZero: false, - highNotPrecedence: false, - ignoreSpace: false, - noAutoValueOnZero: false, - noUnsignedSubtraction: false, - noZeroDate: false, - noZeroInDate: false, - onlyFullGroupBy: false, - padCharToFullLength: false, - pipesAsConcat: false, - realAsFloat: false, - strictAllTables: false, - strictTransTables: false, - timeTruncateFractional: false, - }, - timeout: "5", - compression: "Required", - compressionLevel: "5", - disableHeatWave: true, - }; - editConn.mds = { - profile: "E2ETESTS", - sshPrivateKey: "edited private key", - sshPublicKey: "edited public key", - // eslint-disable-next-line max-len - dbSystemOCID: "ocid1.mysqldbsystem.oc1.iad.aaaaaaaakj7775hxfupaggyci4x2nze45gaqyhcufae23fm5fl2bynwy4tpq", - bastionOCID: "ocid1.bastion.oc1.iad.amaaaaaaumfjfyaaectz7jrnfnuses2qc6qvg6ksseu6i2xfow2cnqpbn44q", - }; - } - delete (editConn.basic as interfaces.IConnBasicMySQL).password; - const dbConnectionDialog = DatabaseConnectionDialog; - await dbConnectionDialog.setConnection(editConn); - await dbConnectionOverview.moreActions(editConn.caption, constants.editConnection); - const verifyConn = await dbConnectionDialog.getConnectionDetails(); - expect(verifyConn).to.deep.equal(editConn); + it("Drop Table", async () => { + + await dbTreeSection.focus(); + await dbTreeSection.openContextMenuAndSelect(tableToDrop, constants.dropTable); + await Workbench.pushDialogButton(`Drop ${tableToDrop}`); + await Workbench.getNotification(`The object ${tableToDrop} has been dropped successfully.`); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(tableToDrop)); + }, constants.wait1second * 3, `${tableToDrop} should not exist on the tree`); }); - it("Edit an Sqlite connection", async () => { + it("View - Select Rows in DB Notebook", async () => { - const editSqliteConn: interfaces.IDBConnection = { - dbType: "Sqlite", - caption: `e2eSqliteConnectionToEdit`, - description: "Local connection", - basic: { - dbPath: join(process.env.TEST_RESOURCES_PATH, - `mysqlsh-${String(process.env.TEST_SUITE)}`, - "plugin_data", "gui_plugin", "mysqlsh_gui_backend.sqlite3"), - dbName: "SQLite", - }, - advanced: { - params: "one parameter", - }, - }; + const openEditorsTreeSection = new E2EAccordionSection(constants.openEditorsTreeSection); + await openEditorsTreeSection.collapse(); + treeGlobalSchemaViews = await dbTreeSection.getTreeItem("Views"); + await treeGlobalSchemaViews.expand(); - const dbConnectionDialog = DatabaseConnectionDialog; - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await dbConnectionDialog.setConnection(editSqliteConn); - await dbConnectionOverview.moreActions(editSqliteConn.caption, constants.editConnection); - editSqliteConn.caption = "e2eEditedSqliteCaption"; - editSqliteConn.description = "edited sqlite description"; - if (interfaces.isSQLiteConnection(editSqliteConn.basic)) { - editSqliteConn.basic.dbPath = "edited path"; - // https://mybug.mysql.oraclecorp.com/orabugs/site/bug.php?id=36492230 - // editConn.basic.dbName = "edited name"; - } - if (interfaces.isAdvancedSqlite(editSqliteConn.advanced)) { - editSqliteConn.advanced.params = "another param"; - } + await dbTreeSection.openContextMenuAndSelect(testView, constants.selectRowsInNotebook); + const notebook = new E2ENotebook(); + await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); + const result = await notebook.codeEditor.getLastExistingCommandResult(true) as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + expect(result.status).to.match(/OK, (\d+) records/); + }); - await dbConnectionDialog.setConnection(editSqliteConn); - await dbConnectionOverview.moreActions(editSqliteConn.caption, constants.editConnection); - const verifyConn = await dbConnectionDialog.getConnectionDetails(); - delete (verifyConn.basic as interfaces.IConnBasicSqlite).dbName; - delete (editSqliteConn.basic as interfaces.IConnBasicSqlite).dbName; - expect(verifyConn).to.deep.equal(editSqliteConn); + it("View - Copy name and create statement to clipboard", async function () { - }); + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); - it("Duplicate a MySQL Connection", async () => { + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testView, [constants.copyToClipboard, + constants.copyToClipboardName], constants.dbObjectCtxMenu); + await Workbench.getNotification("The name was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - await dbConnectionOverview.moreActions(globalConn.caption, constants.dupConnection); - await DatabaseConnectionDialog.setConnection(duplicateConnection); - await driver.wait(dbConnectionOverview.untilConnectionExists(duplicateConnection.caption), - constants.wait1second * 5); + return clipboard.readSync() === testView; + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The view name was not copied to the clipboard"); - }); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testView, [constants.copyToClipboard, + constants.copyToClipboardStat], constants.dbObjectCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); + E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); - it("Duplicate a Sqlite Connection", async () => { + return clipboard.readSync().includes("DEFINER VIEW"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 25, "The view create statement was not copied to the clipboard"); - const sqliteConn: interfaces.IDBConnection = { - dbType: "Sqlite", - caption: `e2eSqliteConnectionToDuplicate`, - description: "Local connection", - basic: { - dbPath: join(process.env.TEST_RESOURCES_PATH, - `mysqlsh-${String(process.env.TEST_SUITE)}`, - "plugin_data", "gui_plugin", "mysqlsh_gui_backend.sqlite3"), - dbName: "SQLite", - }, - advanced: { - params: "one parameter", - }, - }; + }); - const dbConnectionDialog = DatabaseConnectionDialog; - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await dbConnectionDialog.setConnection(sqliteConn); - await dbConnectionOverview.moreActions(sqliteConn.caption, constants.dupConnection); - const duplicateSqlite: interfaces.IDBConnection = { - dbType: "Sqlite", - caption: "e2eDuplicateSqliteFromGlobal", - }; - await dbConnectionDialog.setConnection(duplicateSqlite); - await driver.wait(dbConnectionOverview.untilConnectionExists(duplicateSqlite.caption), - constants.wait1second * 5); + it("Drop View", async () => { + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + await treeGlobalSchema.expand(); + await treeGlobalSchemaViews.expand(); + await dbTreeSection.openContextMenuAndSelect(viewToDrop, constants.dropView); + await Workbench.pushDialogButton(`Drop ${viewToDrop}`); + await Workbench.getNotification(`The object ${viewToDrop} has been dropped successfully.`); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(viewToDrop)); + }, constants.wait1second * 3, `${viewToDrop} should not exist on the tree`); }); - it("Remove a MySQL connection", async () => { + it("Table - Show Data", async () => { - const connectionToRemove: interfaces.IDBConnection = { - dbType: "MySQL", - caption: `e2eConnectionToRemove`, - description: "Local connection", - basic: { - hostname: "localhost", - username: String(process.env.DBUSERNAME1), - }, - }; - - await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); - await DatabaseConnectionDialog.setConnection(connectionToRemove); - await dbConnectionOverview.moreActions(connectionToRemove.caption, constants.removeConnection); - const dialog = await driver.wait(until.elementLocated(locator.confirmDialog.exists), - constants.wait1second * 5, "confirm dialog was not found"); - - await dialog.findElement(locator.confirmDialog.accept).click(); - expect(await dbConnectionOverview.existsConnection(connectionToRemove.caption)).to.be.false; + await dbTreeSection.openContextMenuAndSelect("actor", constants.showData); + const result = await new E2EScript().getResult() as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + await driver.wait(result.untilIsMaximized(), constants.wait1second * 5); }); - it("Remove a Sqlite connection", async () => { + it("View - Show Data", async () => { - const sqliteConnectionToRemove = "e2eSqliteConnectionToDuplicate"; - await dbConnectionOverview.moreActions(sqliteConnectionToRemove, constants.removeConnection); - const dialog = await driver.wait(until.elementLocated(locator.confirmDialog.exists), - constants.wait1second * 5, "confirm dialog was not found"); - await dialog.findElement(locator.confirmDialog.accept).click(); await dbTreeSection.focus(); - await driver.wait(dbTreeSection.untilIsNotLoading(), constants.waitSectionNoProgressBar); - expect(await dbConnectionOverview.existsConnection(sqliteConnectionToRemove)).to.be.false; - + await dbTreeSection.openContextMenuAndSelect(testView, constants.showData); + const script = new E2EScript(); + await driver.wait(script.untilIsOpened(globalConn), constants.wait1second * 15); + const result = await script.getResult() as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + await driver.wait(result.untilIsMaximized(), constants.wait1second * 5); }); - it("Create new notebook", async () => { + it("Functions - Clipboard", async function () { - const connection = await dbConnectionOverview.getConnection(globalConn.caption); - const newNotebook = await connection.findElement(locator.dbConnectionOverview.dbConnection.newNotebook); - await driver.actions().move({ origin: newNotebook }).perform(); - await driver.wait(until.elementIsVisible(newNotebook), constants.wait1second * 5, - "New notebook button was not visible"); - await newNotebook.click(); - await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.waitConnectionOpen); - const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); - const dbNotebook = await openEditorsSection.getTreeItem(constants.openEditorsDBNotebook); - expect(dbNotebook).to.exist; + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); - }); + await dbTreeSection.focus(); + await (await dbTreeSection.getTreeItem("performance_schema")).collapse(); - it("Create new script", async () => { + await (await dbTreeSection.getTreeItem("Tables")).collapse(); + const treeRoutines = await dbTreeSection.getTreeItem("Functions"); + await treeRoutines.expand(); + await driver.wait(dbTreeSection.untilTreeItemExists(testRoutine), constants.waitForTreeItem); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, + constants.copyToClipboardName], constants.routinesCtxMenu); + await Workbench.getNotification("The name was copied to the system clipboard"); - const connection = await dbConnectionOverview.getConnection("e2eDuplicateFromGlobal"); - const newScript = await connection.findElement(locator.dbConnectionOverview.dbConnection.newScript); - await driver.actions().move({ origin: newScript }).perform(); - await driver.wait(until.elementIsVisible(newScript), constants.wait1second * 5, - "New script button was not visible"); - await driver.executeScript("arguments[0].click()", newScript); - await driver.wait(new E2EScript().untilIsOpened(duplicateConnection), constants.wait1second * 5); - const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); - await openEditorsSection.focus(); - const script = await openEditorsSection.getTreeItem("Script"); - expect(script).to.exist; + return clipboard.readSync() === testRoutine; + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } - }); + }), constants.wait1second * 15, "The routine name was not copied to the clipboard"); - it("Open new shell console", async () => { + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, + constants.copyToClipboardStat], constants.routinesCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); - await driver.wait(until.elementLocated(locator.dbConnectionOverview.newConsoleButton), - constants.wait1second * 10).click(); - await driver.wait(new E2EShellConsole().untilIsOpened(globalConn), - constants.waitShellOpen, "Shell Console was not loaded"); + return clipboard.readSync().includes("CREATE DEFINER"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 15, "The routine create statement was not copied to the clipboard"); - }); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, + constants.copyToClipboardStatDel], constants.routinesCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); - it("Open 3 notebooks for the same database connection", async () => { - const dbConnectionOverview = new DatabaseConnectionOverview(); - const connection = await dbConnectionOverview.getConnection(globalConn.caption); - await connection.click(); - const notebook = new E2ENotebook(); - await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); - await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); + return clipboard.readSync().includes("DELIMITER"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } + } + }), constants.wait1second * 15, + "The routine create statement with delimiters was not copied to the clipboard"); - await driver.wait(async () => { - if (await PasswordDialog.exists()) { - await PasswordDialog.setCredentials(globalConn); + await driver.wait(new Condition("", async () => { + try { + await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, + constants.copyToClipboardDropStatDel], constants.routinesCtxMenu); + await Workbench.getNotification("The create script was copied to the system clipboard"); - return true; + return clipboard.readSync().includes("DROP") && clipboard.readSync().includes("DELIMITER"); + } catch (e) { + if (!(errors.isStaleError(e as Error))) { + throw e; + } } - }, constants.wait1second * 5, "Could not find the Password Dialog for second connection"); - + }), constants.wait1second * 15, + "The routine drop & create statement with delimiters was not copied to the clipboard"); - await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); - await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); - await driver.wait(async () => { - if (await PasswordDialog.exists()) { - await PasswordDialog.setCredentials(globalConn); + }); - return true; - } - }, constants.wait1second * 5, "Could not find the Password Dialog for third connection"); + it("Functions - Drop Function", async () => { - await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); - await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); + await dbTreeSection.openContextMenuAndSelect(testRoutine, constants.dropStoredRoutine); + await Workbench.pushDialogButton(`Drop ${testRoutine}`); + await Workbench.getNotification(`The object ${testRoutine} has been dropped successfully.`); await driver.wait(async () => { - if (await PasswordDialog.exists()) { - await PasswordDialog.setCredentials(globalConn); + return !(await dbTreeSection.treeItemExists(testRoutine)); + }, constants.wait1second * 3, `${testRoutine} should not exist on the tree`); - return true; - } - }, constants.wait1second * 5, "Could not find the Password Dialog for forth connection"); + }); - const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); - await openEditorsSection.focus(); + it("Drop Event", async () => { - expect(await openEditorsSection.treeItemExists(`${globalConn.caption}`)).to.equals(true); - expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (2)`)).to.equals(true); - expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (3)`)).to.equals(true); + const treeRoutines = await dbTreeSection.getTreeItem("Functions"); + await treeRoutines.collapse(); + const treeEvents = await dbTreeSection.getTreeItem("Events"); + await treeEvents.expand(); + await driver.wait(dbTreeSection.untilTreeItemExists(testEvent), constants.waitForTreeItem); + await dbTreeSection.openContextMenuAndSelect(testEvent, constants.dropEvent); + await Workbench.pushDialogButton(`Drop ${testEvent}`); + await Workbench.getNotification(`The object ${testEvent} has been dropped successfully.`); + await driver.wait(async () => { + return !(await dbTreeSection.treeItemExists(testEvent)); + }, constants.wait1second * 3, `${testEvent} should not exist on the tree`); - await Workbench.closeAllEditors(); - expect(await openEditorsSection.treeItemExists(`${globalConn.caption}`)).to.equals(false); - expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (2)`)).to.equals(false); - expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (3)`)).to.equals(false); }); }); @@ -865,9 +779,9 @@ describe("DATABASE CONNECTIONS", () => { expect(typeof mysqlAdministration.serverStatus.auditLog).to.equals("boolean"); expect(mysqlAdministration.serverStatus.firewall).to.not.equals(""); expect(mysqlAdministration.serverStatus.firewallTrace).to.not.equals(""); - expect(mysqlAdministration.serverStatus.sslCa).to.match(/.pem/); - expect(mysqlAdministration.serverStatus.sslCert).to.match(/.pem/); - expect(mysqlAdministration.serverStatus.sslKey).to.match(/.pem/); + expect(mysqlAdministration.serverStatus.sslCa).to.match(/.+pem$/); + expect(mysqlAdministration.serverStatus.sslCert).to.match(/.+pem$/); + expect(mysqlAdministration.serverStatus.sslKey).to.match(/.+pem$/); expect(mysqlAdministration.serverStatus.privateKey).to.equals("private_key.pem"); expect(mysqlAdministration.serverStatus.publicKey).to.equals("public_key.pem"); @@ -915,11 +829,12 @@ describe("DATABASE CONNECTIONS", () => { await Workbench.closeAllEditors(); await dbTreeSection.createDatabaseConnection(mleDisabledConn); await driver.wait(dbTreeSection.untilTreeItemExists(mleDisabledConn.caption), constants.waitForTreeItem); - await (await dbTreeSection.getTreeItemActionButton(mleDisabledConn.caption, - constants.openNewConnectionUsingNotebook)).click(); + await dbTreeSection.clickTreeItemActionButton(mleDisabledConn.caption, + constants.openNewConnectionUsingNotebook); await driver.wait(new E2ENotebook().untilIsOpened(mleDisabledConn), constants.waitConnectionOpen); await dbTreeSection.expandTreeItem(mleDisabledConn.caption, mleDisabledConn); const treeMySQLAdmin = await dbTreeSection.getTreeItem(constants.mysqlAdmin); + await dbTreeSection.focus(); await treeMySQLAdmin.expand(); await (await dbTreeSection.getTreeItem(constants.perfDash)).click(); await driver.wait(mysqlAdministration.untilPageIsOpened(globalConn, constants.perfDash), @@ -1027,8 +942,8 @@ describe("DATABASE CONNECTIONS", () => { expect(mysqlAdministration.performanceDashboard.mlePerformance.mleHeapUtilizationGraph).to.exist; expect(mysqlAdministration.performanceDashboard.mlePerformance.currentHeapUsage).to.equals("0%"); - await (await dbTreeSection.getTreeItemActionButton(globalConn.caption, - constants.openNewConnectionUsingNotebook)).click(); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.openNewConnectionUsingNotebook); const notebook = new E2ENotebook(); await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); @@ -1092,11 +1007,13 @@ describe("DATABASE CONNECTIONS", () => { await dbTreeSection.expandTreeItem(heatWaveConn.caption, heatWaveConn); const treeMySQLAdmin = await dbTreeSection.getTreeItem(constants.mysqlAdmin); await treeMySQLAdmin.expand(); + await dbTreeSection.focus(); await (await dbTreeSection.getTreeItem(constants.lakehouseNavigator)).click(); await driver.wait(mysqlAdministration.untilPageIsOpened(heatWaveConn, constants.lakehouseNavigator), constants.wait1second * 15); expect(await Workbench.getOpenEditorTitles(), errors.tabIsNotOpened(constants.lakehouseNavigator)) .to.include(`${constants.lakehouseNavigator} (${heatWaveConn.caption})`); + await dbTreeSection.focus(); await (await dbTreeSection.getTreeItem((heatWaveConn.basic as interfaces.IConnBasicMySQL) .schema)).expand(); await (await dbTreeSection.getTreeItem("Tables")).expand(); @@ -1128,8 +1045,8 @@ describe("DATABASE CONNECTIONS", () => { await (await dbTreeSection.getTreeItem((heatWaveConn.basic as interfaces.IConnBasicMySQL) .schema)).expand(); await (await dbTreeSection.getTreeItem("Tables")).expand(); - await (await dbTreeSection.getTreeItemActionButton(heatWaveConn.caption, - constants.reloadDataBaseInformation)).click(); + await dbTreeSection.clickTreeItemActionButton(heatWaveConn.caption, + constants.reloadDataBaseInformation); await driver.wait(dbTreeSection.untilTreeItemExists(newTask.name), constants.waitForTreeItem); await dbTreeSection.openContextMenuAndSelect(newTask.name, constants.dropTable); @@ -1250,583 +1167,1052 @@ describe("DATABASE CONNECTIONS", () => { }); - }); + }); + + describe("DB Connection Overview", () => { + + const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + const dbConnectionOverview = new DatabaseConnectionOverview(); + let existsInQueue = false; + + const duplicateConnection: interfaces.IDBConnection = { + dbType: "MySQL", + caption: "e2eDuplicateFromGlobal", + basic: { + hostname: "localhost", + username: String(process.env.DBUSERNAME1), + port: parseInt(process.env.MYSQL_PORT, 10), + schema: "sakila", + password: String(process.env.DBPASSWORD1), + }, + }; + + before(async function () { + await Os.appendToExtensionLog("beforeAll DB Connection Overview"); + try { + await Workbench.openMySQLShellForVSCode(); + await new BottomBarPanel().toggle(false); + await Os.deleteCredentials(); + await openEditorsSection.focus(); + await (await openEditorsSection.getTreeItem(constants.dbConnectionsLabel)).click(); + await Misc.switchToFrame(); + await driver.wait(until.elementLocated(locator.dbConnectionOverview.exists), + constants.wait1second * 10, "DB Connection Overview page was not displayed"); + const closeHeaderButton = await driver.findElements(locator.dbConnectionOverview.closeHeader); + + if (closeHeaderButton.length > 0) { + await closeHeaderButton[0].click(); + } + + await dbTreeSection.focus(); + await dbTreeSection.clickToolbarButton(constants.collapseAll); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + + }); + + let sslConn: interfaces.IDBConnection; + + beforeEach(async function () { + await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); + try { + await dbConnectionOverview.toolbar.editorSelector + .selectEditor(new RegExp(constants.dbConnectionsLabel)); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + + }); + + afterEach(async function () { + + if (this.currentTest.state === "failed") { + await Misc.processFailure(this); + } + + if (existsInQueue) { + await TestQueue.pop(this.currentTest.title); + existsInQueue = false; + } + + }); + + after(async () => { + + await Workbench.openMySQLShellForVSCode(); + + }); + + it("MySQL Database connection - Verify mandatory fields", async () => { + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), + constants.wait1second * 5, "Connection dialog was not displayed"); + + const caption = await conDialog.findElement(locator.dbConnectionDialog.caption); + const hostname = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.hostname); + + await DialogHelper.clearInputField(caption); + await DialogHelper.clearInputField(hostname); + + await conDialog.findElement(locator.dbConnectionDialog.ok).click(); + await driver.wait(async () => { + return (await conDialog.findElements(locator.dbConnectionDialog.errorMessage)).length > 0; + }, constants.wait1second * 5, "The DB Connection dialog should have errors"); + + const dialogErrors = await conDialog.findElements(locator.dbConnectionDialog.errorMessage); + const errorMsgs = await Promise.all( + dialogErrors.map((item: WebElement) => { + return item.getText(); + })); + expect(errorMsgs, `Could not find the error message 'The user name must not be empty' on the dialog`) + .to.include("The user name must not be empty"); + expect(await caption.getAttribute("value"), errors.captionError("New Connection", + await caption.getAttribute("value"))).to.include("New Connection"); + let error = `The hostname should be 'localhost'`; + error += ` but found ${await hostname.getAttribute("value")}`; + expect(await hostname.getAttribute("value"), error).to.equals("localhost"); + await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + + }); + + it("SQLite Database connection - Verify mandatory fields", async () => { + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), + constants.wait1second * 5, "Connection dialog was not displayed"); + + await conDialog.findElement(locator.dbConnectionDialog.databaseType).click(); + const popup = await driver.wait(until.elementLocated(locator.dbConnectionDialog.databaseTypeList), + constants.wait1second * 5, "Database type popup was not found"); + await popup.findElement(locator.dbConnectionDialog.databaseTypeSqlite).click(); + + const caption = await conDialog.findElement(locator.dbConnectionDialog.caption); + await DialogHelper.clearInputField(caption); + + await conDialog.findElement(locator.dbConnectionDialog.ok).click(); + await driver.wait(async () => { + return (await conDialog.findElements(locator.dbConnectionDialog.errorMessage)).length > 0; + }, constants.wait1second * 5, "The DB Connection dialog should have errors"); + + const dialogErrors = await conDialog.findElements(locator.dbConnectionDialog.errorMessage); + const errorMsgs = await Promise.all( + dialogErrors.map((item: WebElement) => { + return item.getText(); + })); + expect(await caption.getAttribute("value"), errors.captionError("New Connection", + await caption.getAttribute("value"))).to.include("New Connection"); + expect(errorMsgs, "'Specify the path to an existing Sqlite DB file' error was not found on the dialog") + .to.include("Specify the path to an existing Sqlite DB file"); + await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + + }); + + it("Connect to SQLite database", async () => { + + const sqliteConn = Object.assign({}, globalConn); + sqliteConn.dbType = "Sqlite"; + sqliteConn.caption = `e2eSqliteConnection`; + + if (Os.isLinux()) { + process.env.USERPROFILE = process.env.HOME; + } + + sqliteConn.basic = { + dbPath: join(process.cwd(), "e2e_test.sqlite3"), + dbName: "SQLite", + }; + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await DatabaseConnectionDialog.setConnection(sqliteConn); + const sqliteWebConn = dbConnectionOverview.getConnection(sqliteConn.caption); + + await driver.executeScript( + "arguments[0].click();", + sqliteWebConn, + ); + + const notebook = new E2ENotebook(); + await driver.wait(notebook.untilIsOpened(sqliteConn), constants.waitConnectionOpen); + await dbTreeSection.focus(); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await driver.wait(new Condition("", async () => { + const item = await dbTreeSection.getTreeItem(sqliteConn.caption); + await item.expand(); + + return item.isExpanded(); + }), constants.wait1second * 10, `${sqliteConn.caption} was not expanded`); + + await driver.wait(new Condition("", async () => { + const item = await dbTreeSection.getTreeItem("main"); + await item.expand(); + + return item.isExpanded(); + }), constants.wait1second * 10, `main was not expanded`); + + await driver.wait(new Condition("", async () => { + const item = await dbTreeSection.getTreeItem("Tables"); + await item.expand(); + + return item.isExpanded(); + }), constants.wait1second * 10, `Tables was not expanded`); + + await dbTreeSection.openContextMenuAndSelect("db_connection", constants.selectRowsInNotebook); + await driver.wait(notebook.untilIsOpened(sqliteConn), constants.waitConnectionOpen); + const result = await notebook.executeWithButton("SELECT * FROM main.db_connection;", + constants.execFullBlockSql) as E2ECommandResultGrid; + expect(result.status).to.match(/OK/); + }); + + it("Connect to MySQL database using SSL", async () => { + + sslConn = Object.assign({}, globalConn); + sslConn.caption = `e2eSSLConnection`; + + sslConn.ssl = { + mode: "Require and Verify CA", + caPath: join(process.env.SSL_CERTIFICATES_PATH, "ca.pem"), + clientCertPath: join(process.env.SSL_CERTIFICATES_PATH, "client-cert.pem"), + clientKeyPath: join(process.env.SSL_CERTIFICATES_PATH, "client-key.pem"), + }; + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await DatabaseConnectionDialog.setConnection(sslConn); + const dbConn = dbConnectionOverview.getConnection(sslConn.caption); + + await driver.executeScript("arguments[0].click();", dbConn); + const notebook = new E2ENotebook(); + await driver.wait(notebook.untilIsOpened(sslConn), constants.waitConnectionOpen); + const query = + `select * from performance_schema.session_status where variable_name in + ("ssl_cipher") and variable_value like "%TLS%";`; + + const result = await notebook.codeEditor.execute(query) as E2ECommandResultGrid; + expect(result.status).to.match(/1 record retrieved/); + }); + + it("Copy paste and cut paste into the DB Connection dialog", async function () { + + await TestQueue.push(this.test.title); + existsInQueue = true; + await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + const conDialog = await driver.wait(until.elementLocated(locator.dbConnectionDialog.exists), + constants.wait1second * 5, "Connection dialog was not displayed"); + const hostNameInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.hostname); + const valueToCopy = await hostNameInput.getAttribute("value"); + await driver.wait(async () => { + await Os.keyboardSelectAll(hostNameInput); + await Os.keyboardCopy(hostNameInput); + const usernameInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.username); + await Os.keyboardPaste(usernameInput); + + return (await usernameInput.getAttribute("value")).includes(valueToCopy); + }, constants.wait1second * 15, `Could not copy paste ${valueToCopy} to user name field`); + + expect(await hostNameInput.getAttribute("value"), + "Hostname value should stay the same after copying it to the clipboard").to.equal(valueToCopy); + const descriptionInput = await conDialog.findElement(locator.dbConnectionDialog.description); + await DialogHelper.clearInputField(descriptionInput); + await descriptionInput.sendKeys("testing"); + const valueToCut = await descriptionInput.getAttribute("value"); + await Os.keyboardSelectAll(descriptionInput); + await Os.keyboardCut(descriptionInput); + expect(await descriptionInput.getAttribute("value"), "Description value was not cut").to.equals(""); + const schemaInput = await conDialog.findElement(locator.dbConnectionDialog.mysql.basic.defaultSchema); + await Os.keyboardPaste(schemaInput); + expect(await schemaInput.getAttribute("value"), + "Hostname value was not pasted to the description field").to.include(valueToCut); + await conDialog.findElement(locator.dbConnectionDialog.cancel).click(); + + }); + + it("Edit a MySQL connection", async () => { + + const editConn: interfaces.IDBConnection = { + dbType: "MySQL", + caption: `e2eConnectionToEdit`, + description: "Local connection", + basic: { + hostname: "localhost", + username: String(process.env.DBUSERNAME1), + port: 3308, + schema: "sakila", + password: String(process.env.DBPASSWORD1), + }, + folderPath: { + value: "/", + }, + }; + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await DatabaseConnectionDialog.setConnection(editConn); + await dbConnectionOverview.moreActions(editConn.caption, constants.editConnection); + editConn.caption = "e2eEditedCaption"; + editConn.description = "edited description"; + + if (interfaces.isMySQLConnection(editConn.basic)) { + editConn.basic.hostname = "hostname edited"; + editConn.basic.username = "username edited"; + editConn.basic.schema = "edited schema"; + editConn.basic.protocol = "mysqlx"; + editConn.basic.port = 3305; + editConn.basic.sshTunnel = true; + editConn.basic.ociBastion = true; + editConn.ssl = { + mode: "Require", + ciphers: "ciphers, edited", + caPath: "ca edited", + clientCertPath: "cert edited", + clientKeyPath: "key edited", + }; + editConn.ssh = { + uri: "edited uri", + privateKey: "edited private key", + customPath: "edited custom path", + }; + editConn.advanced = { + // bug : https://mybug.mysql.oraclecorp.com/orabugs/site/bug.php?id=36482559 + /*mode: { + ansi: true, + traditional: true, + allowInvalidDates: true, + ansiQuotes: true, + errorForDivisionByZero: true, + highNotPrecedence: true, + ignoreSpace: true, + noAutoValueOnZero: true, + noUnsignedSubtraction: true, + noZeroDate: true, + noZeroInDate: true, + onlyFullGroupBy: true, + padCharToFullLength: true, + pipesAsConcat: true, + realAsFloat: true, + strictAllTables: true, + strictTransTables: true, + timeTruncateFractional: true, + }, + timeout: "5",*/ + mode: { + ansi: false, + traditional: false, + allowInvalidDates: false, + ansiQuotes: false, + errorForDivisionByZero: false, + highNotPrecedence: false, + ignoreSpace: false, + noAutoValueOnZero: false, + noUnsignedSubtraction: false, + noZeroDate: false, + noZeroInDate: false, + onlyFullGroupBy: false, + padCharToFullLength: false, + pipesAsConcat: false, + realAsFloat: false, + strictAllTables: false, + strictTransTables: false, + timeTruncateFractional: false, + }, + timeout: "5", + compression: "Required", + compressionLevel: "5", + disableHeatWave: true, + }; + editConn.mds = { + profile: "E2ETESTS", + sshPrivateKey: "edited private key", + sshPublicKey: "edited public key", + // eslint-disable-next-line max-len + dbSystemOCID: "ocid1.mysqldbsystem.oc1.iad.aaaaaaaakj7775hxfupaggyci4x2nze45gaqyhcufae23fm5fl2bynwy4tpq", + bastionOCID: "ocid1.bastion.oc1.iad.amaaaaaaumfjfyaaectz7jrnfnuses2qc6qvg6ksseu6i2xfow2cnqpbn44q", + }; + } + delete (editConn.basic as interfaces.IConnBasicMySQL).password; + const dbConnectionDialog = DatabaseConnectionDialog; + await dbConnectionDialog.setConnection(editConn); + await dbConnectionOverview.moreActions(editConn.caption, constants.editConnection); + const verifyConn = await dbConnectionDialog.getConnectionDetails(); + expect(verifyConn).to.deep.equal(editConn); + + }); + + it("Edit an Sqlite connection", async () => { - describe("Tree context menu items", () => { + const editSqliteConn: interfaces.IDBConnection = { + dbType: "Sqlite", + caption: `e2eSqliteConnectionToEdit`, + description: "Local connection", + basic: { + dbPath: join(process.env.TEST_RESOURCES_PATH, + `mysqlsh-${String(process.env.TEST_SUITE)}`, + "plugin_data", "gui_plugin", "mysqlsh_gui_backend.sqlite3"), + dbName: "SQLite", + }, + advanced: { + params: "one parameter", + }, + folderPath: { + value: "/", + }, + }; - let treeGlobalSchema: TreeItem; - let treeGlobalSchemaTables: TreeItem; - let treeGlobalSchemaViews: TreeItem; - let treeGlobalConn: TreeItem; - const dumpFolder = join(constants.workspace, "dump"); - const dumpSchemaToDisk = `dump_schema_to_disk`; - const schemaForMySQLDbService = "schema_for_mysql_db_service"; - const schemaToDrop = "schema_to_drop"; - const tableToDrop = `table_to_drop`; - const testView = `test_view`; - const viewToDrop = "view_to_drop"; - const testRoutine = "test_function"; - const testEvent = "test_event"; - const dup = "duplicatedConnection"; - const tasksTreeSection = new E2EAccordionSection(constants.tasksTreeSection); - let existsInQueue = false; + const dbConnectionDialog = DatabaseConnectionDialog; + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await dbConnectionDialog.setConnection(editSqliteConn); + await dbConnectionOverview.moreActions(editSqliteConn.caption, constants.editConnection); + editSqliteConn.caption = "e2eEditedSqliteCaption"; + editSqliteConn.description = "edited sqlite description"; - before(async function () { - await Os.appendToExtensionLog("beforeAll Tree context menu items"); - try { - await Os.deleteCredentials(); - await dbTreeSection.focus(); - treeGlobalConn = await dbTreeSection.getTreeItem(globalConn.caption); - await treeGlobalConn.collapse(); - await Workbench.closeAllEditors(); - await dbTreeSection.clickToolbarButton(constants.collapseAll); - await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); - } catch (e) { - await Misc.processFailure(this); - throw e; + if (interfaces.isSQLiteConnection(editSqliteConn.basic)) { + editSqliteConn.basic.dbPath = "edited path"; + // https://mybug.mysql.oraclecorp.com/orabugs/site/bug.php?id=36492230 + // editConn.basic.dbName = "edited name"; } - }); - beforeEach(async function () { - await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); + if (interfaces.isAdvancedSqlite(editSqliteConn.advanced)) { + editSqliteConn.advanced.params = "another param"; + } + + await dbConnectionDialog.setConnection(editSqliteConn); + await dbConnectionOverview.moreActions(editSqliteConn.caption, constants.editConnection); + const verifyConn = await dbConnectionDialog.getConnectionDetails(); + delete (verifyConn.basic as interfaces.IConnBasicSqlite).dbName; + delete (editSqliteConn.basic as interfaces.IConnBasicSqlite).dbName; + expect(verifyConn).to.deep.equal(editSqliteConn); + }); - afterEach(async function () { - if (this.currentTest.state === "failed") { - await Misc.processFailure(this); - } + it("Duplicate a MySQL Connection", async () => { + + await dbConnectionOverview.moreActions(globalConn.caption, constants.dupConnection); + await DatabaseConnectionDialog.setConnection(duplicateConnection); + await driver.wait(dbConnectionOverview.untilConnectionExists(duplicateConnection.caption), + constants.wait1second * 5); - if (existsInQueue) { - await TestQueue.pop(this.currentTest.title); - existsInQueue = false; - } }); - after(async () => { + it("Duplicate a Sqlite Connection", async () => { - await fs.rm(dumpFolder, { force: true, recursive: true }); + const sqliteConn: interfaces.IDBConnection = { + dbType: "Sqlite", + caption: `e2eSqliteConnectionToDuplicate`, + description: "Local connection", + basic: { + dbPath: join(process.env.TEST_RESOURCES_PATH, + `mysqlsh-${String(process.env.TEST_SUITE)}`, + "plugin_data", "gui_plugin", "mysqlsh_gui_backend.sqlite3"), + dbName: "SQLite", + }, + advanced: { + params: "one parameter", + }, + }; + + const dbConnectionDialog = DatabaseConnectionDialog; + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await dbConnectionDialog.setConnection(sqliteConn); + await dbConnectionOverview.moreActions(sqliteConn.caption, constants.dupConnection); + const duplicateSqlite: interfaces.IDBConnection = { + dbType: "Sqlite", + caption: "e2eDuplicateSqliteFromGlobal", + }; + await dbConnectionDialog.setConnection(duplicateSqlite); + await driver.wait(dbConnectionOverview.untilConnectionExists(duplicateSqlite.caption), + constants.wait1second * 5); }); - it("Set this DB Connection as Default", async () => { + it("Remove a MySQL connection", async () => { - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.setDBConnDefault); - await driver.wait(Workbench - .untilNotificationExists(`"${globalConn.caption}" has been set as default DB Connection`), - constants.wait1second * 10); + const connectionToRemove: interfaces.IDBConnection = { + dbType: "MySQL", + caption: `e2eConnectionToRemove`, + description: "Local connection", + basic: { + hostname: "localhost", + username: String(process.env.DBUSERNAME1), + }, + }; + + await driver.findElement(locator.dbConnectionOverview.newDBConnection).click(); + await DatabaseConnectionDialog.setConnection(connectionToRemove); + await dbConnectionOverview.moreActions(connectionToRemove.caption, constants.removeConnection); + const dialog = await driver.wait(until.elementLocated(locator.confirmDialog.exists), + constants.wait1second * 5, "confirm dialog was not found"); + + await dialog.findElement(locator.confirmDialog.accept).click(); + expect(await dbConnectionOverview.existsConnection(connectionToRemove.caption)).to.be.false; }); - it("Open Database Connection", async () => { + it("Remove a Sqlite connection", async () => { - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.openNewConnection); - await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.waitConnectionOpen); - await driver.wait(dbTreeSection.untilTreeItemExists(globalConn.caption), constants.waitForTreeItem); + const sqliteConnectionToRemove = "e2eSqliteConnectionToDuplicate"; + await dbConnectionOverview.moreActions(sqliteConnectionToRemove, constants.removeConnection); + const dialog = await driver.wait(until.elementLocated(locator.confirmDialog.exists), + constants.wait1second * 5, "confirm dialog was not found"); + await dialog.findElement(locator.confirmDialog.accept).click(); + await dbTreeSection.focus(); + await driver.wait(dbTreeSection.untilIsNotLoading(), constants.waitSectionNoProgressBar); + expect(await dbConnectionOverview.existsConnection(sqliteConnectionToRemove)).to.be.false; }); - it("Open MySQL Shell Console for this connection", async () => { + it("Create new notebook", async () => { - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.openShellConnection); - await driver.wait(new E2EShellConsole().untilIsOpened(globalConn), constants.waitShellOpen); - const treeOpenEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); - await treeOpenEditorsSection.expand(); - await treeOpenEditorsSection.focus(); - const treeOEShellConsoles = await treeOpenEditorsSection.getTreeItem(constants.mysqlShellConsoles); - expect(await treeOEShellConsoles.findChildItem(`Session to ${String(globalConn.caption)}`), - errors.doesNotExistOnTree(`Session to ${String(globalConn.caption)}`)).to.exist; + const connection = await dbConnectionOverview.getConnection(globalConn.caption); + const newNotebook = await connection.findElement(locator.dbConnectionOverview.dbConnection.newNotebook); + await driver.actions().move({ origin: newNotebook }).perform(); + await driver.wait(until.elementIsVisible(newNotebook), constants.wait1second * 5, + "New notebook button was not visible"); + await newNotebook.click(); + await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.waitConnectionOpen); + const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + const dbNotebook = await openEditorsSection.getTreeItem(constants.openEditorsDBNotebook); + expect(dbNotebook).to.exist; }); - it("Edit MySQL connection", async () => { + it("Create new script", async () => { - await dbTreeSection.focus(); - await dbTreeSection.clickToolbarButton(constants.collapseAll); - const localConn = Object.assign({}, globalConn); - localConn.caption = `e2eConnectionToEdit`; - await dbTreeSection.createDatabaseConnection(localConn); - await new DatabaseConnectionOverview().getConnection(localConn.caption); - await dbTreeSection.openContextMenuAndSelect(localConn.caption, constants.editDBConnection); - await DatabaseConnectionDialog.setConnection(localConn); - await driver.wait(dbTreeSection.untilTreeItemExists(localConn.caption), constants.waitForTreeItem); + const connection = await dbConnectionOverview.getConnection("e2eDuplicateFromGlobal"); + const newScript = await connection.findElement(locator.dbConnectionOverview.dbConnection.newScript); + await driver.actions().move({ origin: newScript }).perform(); + await driver.wait(until.elementIsVisible(newScript), constants.wait1second * 5, + "New script button was not visible"); + await driver.executeScript("arguments[0].click()", newScript); + await driver.wait(new E2EScript().untilIsOpened(duplicateConnection), constants.wait1second * 5); + const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + await openEditorsSection.focus(); + const script = await openEditorsSection.getTreeItem("Script"); + expect(script).to.exist; }); - it("Duplicate this MySQL connection", async () => { + it("Open new shell console", async () => { - const dupConn = Object.assign({}, globalConn); - dupConn.caption = dup; - await dbTreeSection.focus(); - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.duplicateConnection); - await DatabaseConnectionDialog.setConnection(dupConn); - await driver.wait(dbTreeSection.untilTreeItemExists(dup), constants.waitForTreeItem); + await driver.wait(until.elementLocated(locator.dbConnectionOverview.newConsoleButton), + constants.wait1second * 10).click(); + await driver.wait(new E2EShellConsole().untilIsOpened(globalConn), + constants.waitShellOpen, "Shell Console was not loaded"); }); - it("Delete DB connection", async () => { + it("Open 3 notebooks for the same database connection", async () => { + const dbConnectionOverview = new DatabaseConnectionOverview(); + const connection = await dbConnectionOverview.getConnection(globalConn.caption); + await connection.click(); + const notebook = new E2ENotebook(); + await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); + await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); - await dbTreeSection.focus(); - await dbTreeSection.openContextMenuAndSelect(dup, constants.deleteDBConnection); - await Misc.switchToFrame(); - const dialog = await driver.wait(until.elementLocated( - locator.confirmDialog.exists), constants.wait1second * 15, "confirm dialog was not found"); - await dialog.findElement(locator.confirmDialog.accept).click(); await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(dup)); - }, constants.wait1second * 5, `Waiting for ${dup} to not exist on the tree`); + if (await PasswordDialog.exists()) { + await PasswordDialog.setCredentials(globalConn); - }); + return true; + } + }, constants.wait1second * 5, "Could not find the Password Dialog for second connection"); - it("Load SQL Script from Disk", async () => { - const e2eScript = new E2EScript(); - const script = "2_sakila_cst.sql"; - const destFile = join(constants.workspace, "gui", "frontend", "src", "tests", "e2e", "sql", script); - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.loadScriptFromDisk); - await Workbench.setInputPath(destFile); - await driver.wait(e2eScript.untilIsOpened(globalConn), constants.wait1second * 15); + await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); + await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); await driver.wait(async () => { - return ((await e2eScript.toolbar.editorSelector.getCurrentEditor()).label) === script; - }, constants.wait1second * 5, `Current editor is not ${script}`); - let error = `The current editor type should be 'Mysql',`; - error += ` but found ${(await e2eScript.toolbar.editorSelector.getCurrentEditor()).icon}`; - expect((await e2eScript.toolbar.editorSelector.getCurrentEditor()).icon, error) - .to.include(constants.mysqlScriptIcon); - const scriptLines = await driver.findElements(locator.notebook.codeEditor.editor.line); - expect(scriptLines.length, "The script was not loaded. No lines found on the editor").to.be.greaterThan(0); - await e2eScript.toolbar.editorSelector.selectEditor(new RegExp(constants.openEditorsDBNotebook), - globalConn.caption); + if (await PasswordDialog.exists()) { + await PasswordDialog.setCredentials(globalConn); + + return true; + } + }, constants.wait1second * 5, "Could not find the Password Dialog for third connection"); - }); + await notebook.toolbar.editorSelector.selectEditor(new RegExp(constants.dbConnectionsLabel)); + await dbConnectionOverview.openNotebookUsingKeyboard(globalConn.caption); + await driver.wait(async () => { + if (await PasswordDialog.exists()) { + await PasswordDialog.setCredentials(globalConn); - it("Set as Current Database Schema", async () => { + return true; + } + }, constants.wait1second * 5, "Could not find the Password Dialog for forth connection"); - await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); - await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL).schema, - constants.setCurrentDBSchema, undefined); - await driver.wait(dbTreeSection.untilTreeItemIsDefault("sakila"), constants.wait1second * 5); - await (await dbTreeSection.getTreeItemActionButton(globalConn.caption, - constants.openNewConnectionUsingNotebook)).click(); - await Workbench.openEditor(globalConn.caption); + const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + await openEditorsSection.focus(); - const notebook = new E2ENotebook(); - await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption}`)).to.equals(true); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (2)`)).to.equals(true); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (3)`)).to.equals(true); - await notebook.codeEditor.clean(); - let result = await notebook.codeEditor.execute("SELECT DATABASE();") as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - expect(await result.resultContext.getAttribute("innerHTML")) - .to.match(new RegExp((globalConn.basic as interfaces.IConnBasicMySQL).schema)); + await Workbench.closeAllEditors(); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption}`)).to.equals(false); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (2)`)).to.equals(false); + expect(await openEditorsSection.treeItemExists(`${globalConn.caption} (3)`)).to.equals(false); + }); - await dbTreeSection.openContextMenuAndSelect("world_x_cst", constants.setCurrentDBSchema, undefined); - await driver.wait(dbTreeSection.untilTreeItemIsDefault("world_x_cst"), constants.wait1second * 5); + describe("DB Connection Groups", () => { - await driver.wait(async () => { - return !(await dbTreeSection.treeItemIsDefault("sakila")); - }, constants.wait1second * 3, `sakila should not be the default schema on the tree`); + const dbConnection1: interfaces.IDBConnection = { + caption: `E2E - CONNECTION 1`, + dbType: "MySQL", + folderPath: { + new: true, + value: "group1", + }, + basic: { + hostname: "localhost", + username: "test", + }, + }; - await Workbench.openEditor(globalConn.caption); - await notebook.codeEditor.clean(); - result = await notebook.codeEditor.execute("SELECT DATABASE();") as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - expect(await result.resultContext.getAttribute("innerHTML")).to.match(/world_x_cst/); - await Workbench.closeAllEditors(); + const dbConnection2: interfaces.IDBConnection = { + caption: `E2E - CONNECTION 2`, + dbType: "MySQL", + folderPath: { + new: true, + value: "/group1/group2", + }, + basic: { + hostname: "localhost", + username: "test", + }, + }; - await driver.wait(async () => { - return !(await dbTreeSection.treeItemIsDefault("world_x_cst")); - }, constants.wait1second * 5, "world_x_cst should not be the default"); + const connectionOverview = new DatabaseConnectionOverview(); + let testFailed = false; - expect(await dbTreeSection.treeItemIsDefault("sakila"), errors.isDefault("sakila")).to.be.false; - }); + before(async () => { + try { + const openEditorsSection = new E2EAccordionSection(constants.openEditorsTreeSection); + await (await openEditorsSection.getTreeItem(constants.dbConnectionsLabel)).click(); + await dbTreeSection.focus(); + await dbTreeSection.clickToolbarButton(constants.collapseAll); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); - it("Dump Schema to Disk", async () => { + beforeEach(async () => { + try { + await dbTreeSection.focus(); + await (await connectionOverview.getBreadCrumbLinks())[0].click(); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); - treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) - .schema); - await fs.rm(dumpFolder, { force: true, recursive: true }); - await fs.mkdir(dumpFolder); - await dbTreeSection.openContextMenuAndSelect(dumpSchemaToDisk, - [constants.dumpToDisk, constants.databaseSchemaDump], constants.schemaCtxMenu); - await Workbench.setInputPath(dumpFolder); - await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); - await Workbench.waitForOutputText(`Task 'Dump Schema ${dumpSchemaToDisk} to Disk' completed successfully`, - constants.wait1second * 10); - const files = await fs.readdir(dumpFolder); - expect(files.length, `The dump did not exported any files to ${dumpFolder}`).to.be.greaterThan(0); - await tasksTreeSection.focus(); - await driver.wait(tasksTreeSection.untilTreeItemExists(`Dump Schema ${dumpSchemaToDisk} to Disk (done)`), - constants.waitForTreeItem); - await dbTreeSection.focus(); - await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + afterEach(async () => { + if (testFailed) { + testFailed = false; + await Misc.processFailure(this); + } + }); - await dbTreeSection.openContextMenuAndSelect(dumpSchemaToDisk, constants.dropSchema); - await Workbench.pushDialogButton(`Drop ${dumpSchemaToDisk}`); - await Workbench.getNotification(`The object ${dumpSchemaToDisk} has been dropped successfully.`); + it("Add MySQL connection to new folder", async () => { - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(dumpSchemaToDisk)); - }, constants.waitForTreeItem, `${dumpSchemaToDisk} should not exist on the tree`); + await dbTreeSection.focus(); + await connectionOverview.addNewConnection(dbConnection1); + await driver.wait(connectionOverview.untilGroupExists(dbConnection1.folderPath.value), + constants.wait1second * 5); + await connectionOverview.joinGroup(dbConnection1.folderPath.value); + await driver.wait(connectionOverview.untilConnectionExists(dbConnection1.caption), + constants.wait1second * 3); - }); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/${dbConnection1.folderPath.value}/`); + expect(await dbTreeSection.treeItemExists(dbConnection1.folderPath.value)).to.equals(true); - it("Load Dump from Disk", async function () { + await driver.wait(dbTreeSection.untilTreeItemHasChildren(dbConnection1.folderPath.value), + constants.wait1second * 5); + const folder = await dbTreeSection.getTreeItem(dbConnection1.folderPath.value); + expect(await (await folder.getChildren())[0].getLabel()).to.equals(dbConnection1.caption); - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + }); - await dbTreeSection.clickToolbarButton(constants.reloadConnections); - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.loadDumpFromDisk); - await Workbench.setInputPath(dumpFolder); - await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); - await Workbench.waitForOutputText(/Task 'Loading Dump .* from Disk' completed successfully/, - constants.wait1second * 10); - await driver.wait(dbTreeSection.untilTreeItemExists(dumpSchemaToDisk), constants.waitForTreeItem); + it("Add MySQL connection to subfolder", async () => { - }); + await connectionOverview.addNewConnection(dbConnection2); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await dbTreeSection.expandTree(dbConnection2.folderPath.value.split("/").filter((item) => { + return item !== ""; + })); - it("Dump Schema to Disk for MySQL Database Service", async function () { + const group1 = dbConnection2.folderPath.value.split("/")[1]; + const group2 = dbConnection2.folderPath.value.split("/")[2]; - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + await connectionOverview.joinGroup(group1); + expect(await connectionOverview.existsGroup(group2)).to.be.true; + await connectionOverview.joinGroup(group2); + expect(await connectionOverview.existsConnection(dbConnection2.caption)).to.be.true; + expect(await dbTreeSection.treeItemExists(group2)).to.be.true; - await fs.rm(dumpFolder, { force: true, recursive: true }); - await fs.mkdir(dumpFolder); - await dbTreeSection.openContextMenuAndSelect(schemaForMySQLDbService, - [constants.dumpToDisk, constants.databaseSchemaDumpRest], constants.schemaCtxMenu); - await Workbench.setInputPath(dumpFolder); - await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); - await Workbench - .waitForOutputText(`Task 'Dump Schema ${schemaForMySQLDbService} to Disk' completed successfully`, - constants.wait1second * 10); - const files = await fs.readdir(dumpFolder); - expect(files.length, `The dump did not exported any files to ${dumpFolder}`).to.be.greaterThan(0); - }); + const group2TreeItem = await dbTreeSection.getTreeItem(group2); + expect(await (await group2TreeItem.getChildren())[0].getLabel()).to.equals(dbConnection2.caption); - it("Load Data to HeatWave Cluster", async () => { + }); - await dbTreeSection.focus(); - await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL).schema, - constants.loadDataToHW); - await DatabaseConnectionDialog.setDataToHeatWave(); - await Workbench.setInputPassword((globalConn.basic as interfaces.IConnBasicMySQL).password); - await Workbench.getNotification("The data load to the HeatWave cluster operation has finished"); - await new BottomBarPanel().toggle(false); + it("Add Sqlite connection to new folder", async () => { - }); + const dbConnection: interfaces.IDBConnection = { + caption: `E2E - SQLITE CONNECTION 1`, + dbType: "Sqlite", + folderPath: { + new: true, + value: "sqliteGroup1", + }, + basic: { + dbPath: "test", + }, + }; - it("Drop Schema", async () => { + await connectionOverview.addNewConnection(dbConnection); + await driver.wait(connectionOverview.untilGroupExists(dbConnection.folderPath.value), + constants.wait1second * 5); + await connectionOverview.joinGroup(dbConnection.folderPath.value); + await driver.wait(connectionOverview.untilConnectionExists(dbConnection.caption), + constants.wait1second * 3); - await dbTreeSection.openContextMenuAndSelect(schemaToDrop, constants.dropSchema); - const ntfs = await new extWorkbench().getNotifications(); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/${dbConnection.folderPath.value}/`); + expect(await dbTreeSection.treeItemExists(dbConnection.folderPath.value)).to.be.true; - if (ntfs.length > 0) { - await Workbench.clickOnNotificationButton(ntfs[ntfs.length - 1], `Drop ${schemaToDrop}')]`); - } else { - await Workbench.pushDialogButton(`Drop ${schemaToDrop}`); - } + await driver.wait(dbTreeSection.untilTreeItemHasChildren(dbConnection.folderPath.value), + constants.wait1second * 5); - await Workbench.getNotification(`The object ${schemaToDrop} has been dropped successfully.`); - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(schemaToDrop)); - }, constants.wait1second * 5, `${schemaToDrop} should not exist on the tree`); - }); + const folder = await dbTreeSection.getTreeItem(dbConnection.folderPath.value); + expect(await (await folder.getChildren())[0].getLabel()).to.equals(dbConnection.caption); - it("Schema - Copy name and create statement to clipboard", async function () { + }); - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + it("Add Sqlite connection to subfolder", async () => { - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL) - .schema, [constants.copyToClipboard, - constants.copyToClipboardName], constants.schemaCtxMenu); - await Workbench.getNotification("The name was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + const dbConnection: interfaces.IDBConnection = { + caption: `E2E - SQLITE CONNECTION 2`, + dbType: "Sqlite", + folderPath: { + new: true, + value: "/sqliteGroup1/sqliteGroup2", + }, + basic: { + dbPath: "test", + }, + }; - return clipboard.readSync() === (globalConn.basic as interfaces.IConnBasicMySQL).schema; - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 25, "The schema name was not copied to the clipboard"); + await connectionOverview.addNewConnection(dbConnection); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await dbTreeSection.expandTree(dbConnection.folderPath.value.split("/").filter((item) => { + return item !== ""; + })); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect((globalConn.basic as interfaces.IConnBasicMySQL) - .schema, [constants.copyToClipboard, - constants.copyToClipboardStat], constants.schemaCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + const sqliteGroup1 = dbConnection.folderPath.value.split("/")[1]; + const sqliteGroup2 = dbConnection.folderPath.value.split("/")[2]; - return clipboard.readSync().includes("CREATE DATABASE"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 25, "The schema create statement was not copied to the clipboard"); + await connectionOverview.joinGroup(sqliteGroup1); + expect(await connectionOverview.existsGroup(sqliteGroup2)).to.be.true; + await connectionOverview.joinGroup(sqliteGroup2); + expect(await connectionOverview.existsConnection(dbConnection.caption)).to.be.true; + expect(await dbTreeSection.treeItemExists(sqliteGroup2)).to.be.true; - }); + await driver.wait(dbTreeSection.untilTreeItemHasChildren(sqliteGroup2), + constants.wait1second * 5); - it("Table - Select Rows in DB Notebook", async () => { + const folder = await dbTreeSection.getTreeItem(sqliteGroup2); + expect(await (await folder.getChildren())[0].getLabel()).to.equals(dbConnection.caption); - treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) - .schema); - await treeGlobalSchema.expand(); - treeGlobalSchemaTables = await dbTreeSection.getTreeItem("Tables"); - await treeGlobalSchemaTables.expand(); - await dbTreeSection.openContextMenuAndSelect("actor", constants.selectRowsInNotebook); - const notebook = new E2ENotebook(); - await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); - const result = await notebook.codeEditor.getLastExistingCommandResult(true) as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); + }); - }); + it("Add Subfolder", async () => { - it("Table - Copy name and create statement to clipboard", async function () { + const dbConnection: interfaces.IDBConnection = { + caption: `E2E - CONN 1`, + dbType: "MySQL", + folderPath: { + new: true, + value: "1group", + }, + basic: { + hostname: "localhost", + username: "test", + }, + }; - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + const subFolder = "2group"; - await dbTreeSection.focus(); + await connectionOverview.addNewConnection(dbConnection); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await dbTreeSection.openContextMenuAndSelect(dbConnection.folderPath.value, + constants.addSubfolder); + await Workbench.setInputPath(subFolder); + await dbTreeSection.expandTreeItem(dbConnection.folderPath.value); + expect(await dbTreeSection.treeItemExists(subFolder)).to.be.true; - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect("actor", [constants.copyToClipboard, - constants.copyToClipboardName], constants.dbObjectCtxMenu); - await Workbench.getNotification("The name was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + }); - return clipboard.readSync() === "actor"; - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 25, "The table name was not copied to the clipboard"); + it("Navigate through folders and subfolders", async () => { - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect("actor", [constants.copyToClipboard, - constants.copyToClipboardStat], constants.dbObjectCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + await dbTreeSection.openContextMenuAndSelect("2group", constants.addSubfolder); + await Workbench.setInputPath("3group"); + await dbTreeSection.expandTreeItem("2group"); + expect(await dbTreeSection.treeItemExists("3group")).to.equals(true); - return clipboard.readSync().includes("idx_actor_last_name"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 25, "The table create statement was not copied to the clipboard"); + await dbTreeSection.openContextMenuAndSelect("3group", constants.addSubfolder); + await Workbench.setInputPath("4group"); + await dbTreeSection.expandTreeItem("3group"); + expect(await dbTreeSection.treeItemExists("4group")).to.equals(true); + + await (await connectionOverview.getBreadCrumbLinks())[0].click(); + await connectionOverview.joinGroup("1group"); + await connectionOverview.joinGroup("2group"); + await connectionOverview.joinGroup("3group"); + await connectionOverview.joinGroup("4group"); + + // USING BACK BUTTON + await driver.wait(connectionOverview.untilBreadCrumbIs(`/1group/2group/3group/4group/`), + constants.wait1second * 3); + await driver.findElement(locator.dbConnectionOverview.back).click(); + await driver.wait(connectionOverview.untilBreadCrumbIs(`/1group/2group/3group/`), + constants.wait1second * 3); + await driver.findElement(locator.dbConnectionOverview.back).click(); + await driver.wait(connectionOverview.untilBreadCrumbIs(`/1group/2group/`), + constants.wait1second * 3); + await driver.findElement(locator.dbConnectionOverview.back).click(); + await driver.wait(connectionOverview.untilBreadCrumbIs(`/1group/`), + constants.wait1second * 3); + await driver.findElement(locator.dbConnectionOverview.back).click(); + await driver.wait(connectionOverview.untilBreadCrumbIs(`/`), + constants.wait1second * 3); - }); + await connectionOverview.joinGroup("1group"); + await connectionOverview.joinGroup("2group"); + await connectionOverview.joinGroup("3group"); + await connectionOverview.joinGroup("4group"); - it("Drop Table", async () => { + // USING BREADCRUMB LINKS + let breadCrumbLinks = await connectionOverview.getBreadCrumbLinks(); + await breadCrumbLinks[breadCrumbLinks.length - 2].click(); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/1group/2group/3group/`); - await dbTreeSection.focus(); - await dbTreeSection.openContextMenuAndSelect(tableToDrop, constants.dropTable); - await Workbench.pushDialogButton(`Drop ${tableToDrop}`); - await Workbench.getNotification(`The object ${tableToDrop} has been dropped successfully.`); + breadCrumbLinks = await connectionOverview.getBreadCrumbLinks(); + await breadCrumbLinks[breadCrumbLinks.length - 2].click(); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/1group/2group/`); - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(tableToDrop)); - }, constants.wait1second * 3, `${tableToDrop} should not exist on the tree`); - }); + breadCrumbLinks = await connectionOverview.getBreadCrumbLinks(); + await breadCrumbLinks[breadCrumbLinks.length - 2].click(); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/1group/`); - it("View - Select Rows in DB Notebook", async () => { + breadCrumbLinks = await connectionOverview.getBreadCrumbLinks(); + await breadCrumbLinks[0].click(); + expect(await connectionOverview.getBreadCrumb()).to.equals(`/`); - const openEditorsTreeSection = new E2EAccordionSection(constants.openEditorsTreeSection); - await openEditorsTreeSection.collapse(); - treeGlobalSchemaViews = await dbTreeSection.getTreeItem("Views"); - await treeGlobalSchemaViews.expand(); + }); - await dbTreeSection.openContextMenuAndSelect(testView, constants.selectRowsInNotebook); - const notebook = new E2ENotebook(); - await driver.wait(notebook.untilIsOpened(globalConn), constants.waitConnectionOpen); - const result = await notebook.codeEditor.getLastExistingCommandResult(true) as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - expect(result.status).to.match(/OK, (\d+) records/); - }); + it("Move MySQL connection to folder", async () => { - it("View - Copy name and create statement to clipboard", async function () { + const dbConnection = { + dbType: "MySQL", + folderPath: { + new: false, + value: `/${dbConnection1.folderPath.value}`, + }, + basic: { + hostname: "localhost", + username: "test", + }, + }; - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + await dbTreeSection.expandTree(dbConnection2.folderPath.value.split("/").filter((item) => { + return item !== ""; + })); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testView, [constants.copyToClipboard, - constants.copyToClipboardName], constants.dbObjectCtxMenu); - await Workbench.getNotification("The name was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + await dbTreeSection.openContextMenuAndSelect(dbConnection2.caption, constants.editDBConnection); + await DatabaseConnectionDialog.setConnection(dbConnection); - return clipboard.readSync() === testView; - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 25, "The view name was not copied to the clipboard"); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + const treeFolder = await dbTreeSection.getTreeItem(dbConnection1.folderPath.value); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testView, [constants.copyToClipboard, - constants.copyToClipboardStat], constants.dbObjectCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); - E2ELogger.debug(`clipboard content: ${clipboard.readSync()}`); + const children = await treeFolder.getChildren(); + const childrenNames: string[] = []; - return clipboard.readSync().includes("DEFINER VIEW"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } + for (const child of children) { + childrenNames.push(await child.getLabel()); } - }), constants.wait1second * 25, "The view create statement was not copied to the clipboard"); - }); + expect(childrenNames).to.include(dbConnection2.caption); + await (await connectionOverview.getGroup(dbConnection.folderPath.value.slice(1))).click(); + expect(await connectionOverview.existsConnection(dbConnection1.caption)).to.be.true; - it("Drop View", async () => { + }); - await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); - await treeGlobalSchema.expand(); - await treeGlobalSchemaViews.expand(); - await dbTreeSection.openContextMenuAndSelect(viewToDrop, constants.dropView); - await Workbench.pushDialogButton(`Drop ${viewToDrop}`); - await Workbench.getNotification(`The object ${viewToDrop} has been dropped successfully.`); - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(viewToDrop)); - }, constants.wait1second * 3, `${viewToDrop} should not exist on the tree`); - }); + it("Edit a folder", async () => { - it("Table - Show Data", async () => { - await dbTreeSection.openContextMenuAndSelect("actor", constants.showData); - const result = await new E2EScript().getResult() as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - await driver.wait(result.untilIsMaximized(), constants.wait1second * 5); + const dbConnection: interfaces.IDBConnection = { + caption: `E2E - DB CONNECTION`, + dbType: "MySQL", + folderPath: { + new: true, + value: "groupToEdit", + }, + basic: { + hostname: "localhost", + username: "test", + }, + }; - }); + const editedGroup = "Edited group"; + await connectionOverview.addNewConnection(dbConnection); + await dbTreeSection.openContextMenuAndSelect(dbConnection.folderPath.value, constants.editFolder); + await Workbench.setInputPath("Edited group"); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await driver.wait(dbTreeSection.untilTreeItemExists(editedGroup), constants.waitForTreeItem); + expect(await connectionOverview.existsGroup(editedGroup)).to.be.true; - it("View - Show Data", async () => { + }); + + it("Edit subfolder", async () => { + + const editedFolderName = "Edited subfolder"; + await dbTreeSection.openContextMenuAndSelect(dbConnection2.folderPath.value.split("/")[2], + constants.editFolder); + await Workbench.setInputPath(editedFolderName); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + expect(await dbTreeSection.treeItemExists(editedFolderName)).to.be.true; + await connectionOverview.joinGroup(dbConnection1.folderPath.value); + expect(await connectionOverview.existsGroup(editedFolderName)).to.be.true; + + }); + + it("Remove empty folder", async () => { + + await dbTreeSection.openContextMenuAndSelect("4group", constants.removeFolder); + await Workbench.pushDialogButton("Delete Folder"); + await driver.wait(Workbench + // eslint-disable-next-line max-len + .untilNotificationExists(`The connection group "4group" has been deleted.`, + true, true), constants.wait1second * 5); + expect(await dbTreeSection.treeItemExists("4group")).to.be.false; + }); + + it("Remove folder with connections", async () => { + + await dbTreeSection.openContextMenuAndSelect(dbConnection1.folderPath.value, + constants.removeFolder); + await Workbench.pushDialogButton("Delete Folder"); + await driver.wait(Workbench + // eslint-disable-next-line max-len + .untilNotificationExists(`The connection group "${dbConnection1.folderPath.value}" has been deleted.`, + true, true), constants.wait1second * 5); + expect(await dbTreeSection.treeItemExists(dbConnection1.folderPath.value)).to.be.false; + }); - await dbTreeSection.focus(); - await dbTreeSection.openContextMenuAndSelect(testView, constants.showData); - const script = new E2EScript(); - await driver.wait(script.untilIsOpened(globalConn), constants.wait1second * 15); - const result = await script.getResult() as E2ECommandResultGrid; - expect(result.status).to.match(/OK/); - await driver.wait(result.untilIsMaximized(), constants.wait1second * 5); }); - it("Functions - Clipboard", async function () { + }); - await TestQueue.push(this.test.title); - existsInQueue = true; - await driver.wait(TestQueue.poll(this.test.title), constants.queuePollTimeout); + describe("Toolbar", () => { - await dbTreeSection.focus(); - await (await dbTreeSection.getTreeItem("performance_schema")).collapse(); + beforeEach(async function () { + await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); + }); - await (await dbTreeSection.getTreeItem("Tables")).collapse(); - const treeRoutines = await dbTreeSection.getTreeItem("Functions"); - await treeRoutines.expand(); - await driver.wait(dbTreeSection.untilTreeItemExists(testRoutine), constants.waitForTreeItem); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, - constants.copyToClipboardName], constants.routinesCtxMenu); - await Workbench.getNotification("The name was copied to the system clipboard"); + afterEach(async function () { + if (this.currentTest.state === "failed") { + await Misc.processFailure(this); + } + }); - return clipboard.readSync() === testRoutine; - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } + it("Reload the connection list", async () => { - }), constants.wait1second * 15, "The routine name was not copied to the clipboard"); + await driver.wait(dbTreeSection.untilTreeItemExists(globalConn.caption), constants.waitForTreeItem); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, - constants.copyToClipboardStat], constants.routinesCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); + }); - return clipboard.readSync().includes("CREATE DEFINER"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; - } - } - }), constants.wait1second * 15, "The routine create statement was not copied to the clipboard"); + it("Collapse All", async () => { - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, - constants.copyToClipboardStatDel], constants.routinesCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); + await dbTreeSection.focus(); + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + const treeGlobalSchema = await dbTreeSection.getTreeItem((globalConn.basic as interfaces.IConnBasicMySQL) + .schema); - return clipboard.readSync().includes("DELIMITER"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; + await treeGlobalSchema.expand(); + const treeGlobalSchemaTables = await dbTreeSection.getTreeItem("Tables"); + await treeGlobalSchemaTables.expand(); + const treeGlobalSchemaViews = await dbTreeSection.getTreeItem("Views"); + await treeGlobalSchemaViews.expand(); + const treeDBSection: CustomTreeSection = await new SideBarView().getContent() + .getSection(constants.dbTreeSection); + await dbTreeSection.clickToolbarButton(constants.collapseAll); + + let visibleItems: CustomTreeItem[]; + await driver.wait(async () => { + visibleItems = await treeDBSection.getVisibleItems(); + if (visibleItems.length > 0) { + for (const item of visibleItems) { + if (await item.getAttribute("aria-level") !== "1") { + return false; + } } + + return true; } - }), constants.wait1second * 15, - "The routine create statement with delimiters was not copied to the clipboard"); + }, constants.wait1second * 5, "The tree is not fully collapsed"); + }); - await driver.wait(new Condition("", async () => { - try { - await dbTreeSection.openContextMenuAndSelect(testRoutine, [constants.copyToClipboard, - constants.copyToClipboardDropStatDel], constants.routinesCtxMenu); - await Workbench.getNotification("The create script was copied to the system clipboard"); + it("Restart internal MySQL Shell process", async () => { - return clipboard.readSync().includes("DROP") && clipboard.readSync().includes("DELIMITER"); - } catch (e) { - if (!(errors.isStaleError(e as Error))) { - throw e; + await fs.truncate(Os.getMysqlshLog()); + await dbTreeSection.selectMoreActionsItem(constants.restartInternalShell); + const notification = await Workbench.getNotification("This will close all MySQL Shell tabs", false); + await Workbench.clickOnNotificationButton(notification, "Restart MySQL Shell"); + await driver.wait(async () => { + return Os.findOnMySQLShLog(/Info/); + }, constants.wait1second * 5 * 3, "Shell server did not start"); + + try { + await driver.wait(async () => { + const text = await fs.readFile(Os.getMysqlshLog()); + if (text.includes("Registering session...")) { + return true; } - } - }), constants.wait1second * 15, - "The routine drop & create statement with delimiters was not copied to the clipboard"); + }, constants.wait1second * 20, "Restarting the internal MySQL Shell server went wrong"); + } finally { + E2ELogger.info("<<<>>>"); + await Os.writeMySQLshLogs(); + } }); - it("Functions - Drop Function", async () => { + it("Relaunch Welcome Wizard", async () => { - await dbTreeSection.openContextMenuAndSelect(testRoutine, constants.dropStoredRoutine); - await Workbench.pushDialogButton(`Drop ${testRoutine}`); - await Workbench.getNotification(`The object ${testRoutine} has been dropped successfully.`); - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(testRoutine)); - }, constants.wait1second * 3, `${testRoutine} should not exist on the tree`); + await dbTreeSection.selectMoreActionsItem(constants.relaunchWelcomeWizard); + await driver.wait(Workbench.untilTabIsOpened(constants.welcomeTab), constants.wait1second * 5); + const active = await Workbench.getActiveTab(); + let error = `The active tab should be ${constants.welcomeTab}`; + error += `, but found ${await active.getTitle()}`; + expect(await active.getTitle(), error).equals(constants.welcomeTab); + await driver.wait(until.ableToSwitchToFrame(0), constants.wait1second * 5, "Not able to switch to frame 0"); + await driver.wait(until.ableToSwitchToFrame( + locator.iframe.isActive), constants.wait1second * 5, "Not able to switch to frame 2"); + const text = await driver.findElement(locator.welcomeWizard.title).getText(); + expect(text, `The Welcome wizard title should be ${constants.welcome}, but found ${text}`) + .equals(constants.welcome); + expect(await driver.findElement(locator.welcomeWizard.nextButton), + `Next button does not exist on the welcome wizard`).to.exist; }); - it("Drop Event", async () => { + it("Reset MySQL Shell for VS Code Extension", async () => { - const treeRoutines = await dbTreeSection.getTreeItem("Functions"); - await treeRoutines.collapse(); - const treeEvents = await dbTreeSection.getTreeItem("Events"); - await treeEvents.expand(); - await driver.wait(dbTreeSection.untilTreeItemExists(testEvent), constants.waitForTreeItem); - await dbTreeSection.openContextMenuAndSelect(testEvent, constants.dropEvent); - await Workbench.pushDialogButton(`Drop ${testEvent}`); - await Workbench.getNotification(`The object ${testEvent} has been dropped successfully.`); - await driver.wait(async () => { - return !(await dbTreeSection.treeItemExists(testEvent)); - }, constants.wait1second * 3, `${testEvent} should not exist on the tree`); + await Workbench.closeAllEditors(); + await dbTreeSection.selectMoreActionsItem(constants.resetExtension); + let notification = "This will completely reset the MySQL Shell for VS Code extension by "; + notification += "deleting the web certificate and optionally deleting the user settings directory."; + const ntf = await Workbench.getNotification(notification, false); + await Workbench.clickOnNotificationButton(ntf, constants.cancel); }); - }); }); diff --git a/gui/extension/tests/e2e/tests/ui-open-editors.ts b/gui/extension/tests/e2e/tests/ui-open-editors.ts index f85dafb3b..8792c50f4 100644 --- a/gui/extension/tests/e2e/tests/ui-open-editors.ts +++ b/gui/extension/tests/e2e/tests/ui-open-editors.ts @@ -111,35 +111,34 @@ describe("OPEN EDITORS", () => { it("Icon - New MySQL Script", async () => { await dbTreeSection.focus(); - await (await dbTreeSection.getTreeItemActionButton(globalConn.caption, - constants.openNewConnectionUsingNotebook)).click(); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.openNewConnectionUsingNotebook); await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.wait1second * 15); - const newMySQLScript = await openEditorsTreeSection.getTreeItemActionButton(globalConn.caption, + await openEditorsTreeSection.clickTreeItemActionButton(globalConn.caption, constants.newMySQLScript); - await driver.executeScript("arguments[0].click()", newMySQLScript); await driver.wait(Workbench.untilCurrentEditorIs(/Untitled-(\d+)/), constants.wait1second * 5); expect((await new E2EScript().toolbar.editorSelector.getCurrentEditor()).icon, `The current editor icon should be 'Mysql'`) .to.include(constants.mysqlScriptIcon); const treeItem = await openEditorsTreeSection.getTreeItem(/Untitled-/, constants.mysqlType); - await (await openEditorsTreeSection.getTreeItemActionButton(await treeItem.getLabel(), - constants.closeEditor)).click(); + await openEditorsTreeSection.clickTreeItemActionButton(await treeItem.getLabel(), + constants.closeEditor); }); it("Icon - Load SQL Script from Disk", async () => { const sqlScript = "setup.sql"; - const loadScriptFromDisk = await openEditorsTreeSection.getTreeItemActionButton(globalConn.caption, + await openEditorsTreeSection.clickTreeItemActionButton(globalConn.caption, constants.loadScriptFromDisk); - await driver.executeScript("arguments[0].click()", loadScriptFromDisk); + await Workbench.setInputPath(join(process.cwd(), "sql", sqlScript)); await driver.wait(Workbench.untilCurrentEditorIs(new RegExp(sqlScript)), constants.wait1second * 5); await driver.wait(openEditorsTreeSection.untilTreeItemExists(sqlScript), constants.waitForTreeItem); expect((await new E2EScript().codeEditor.existsText("GEOMETRYCOLLECTION"))).to.be.true; const treeItem = await openEditorsTreeSection.getTreeItem(new RegExp(sqlScript), constants.mysqlType); - await (await openEditorsTreeSection.getTreeItemActionButton(await treeItem.getLabel(), - constants.closeEditor)).click(); + await openEditorsTreeSection.clickTreeItemActionButton(await treeItem.getLabel(), + constants.closeEditor); }); @@ -152,9 +151,8 @@ describe("OPEN EDITORS", () => { `The current editor icon should be 'Mysql'`) .to.include(constants.mysqlScriptIcon); const treeItem = await openEditorsTreeSection.getTreeItem(/Untitled-/, constants.mysqlType); - await (await openEditorsTreeSection.getTreeItemActionButton(await treeItem.getLabel(), - constants.closeEditor)).click(); - + await openEditorsTreeSection.clickTreeItemActionButton(await treeItem.getLabel(), + constants.closeEditor); }); it("Context menu - New JavaScript Script", async () => { @@ -165,9 +163,8 @@ describe("OPEN EDITORS", () => { `The current editor icon should be 'scriptJs'`) .to.include(constants.jsScriptIcon); const treeItem = await openEditorsTreeSection.getTreeItem(/Untitled-/, constants.jsType); - await (await openEditorsTreeSection.getTreeItemActionButton(await treeItem.getLabel(), - constants.closeEditor)).click(); - + await openEditorsTreeSection.clickTreeItemActionButton(await treeItem.getLabel(), + constants.closeEditor); }); it("Context menu - New TypeScript Script", async () => { @@ -177,8 +174,8 @@ describe("OPEN EDITORS", () => { expect((await new E2EScript().toolbar.editorSelector.getCurrentEditor()).icon, `The current editor icon should be 'scriptTs'`).to.include(constants.tsScriptIcon); const treeItem = await openEditorsTreeSection.getTreeItem(/Untitled-/, constants.tsType); - await (await openEditorsTreeSection.getTreeItemActionButton(await treeItem.getLabel(), - constants.closeEditor)).click(); + await openEditorsTreeSection.clickTreeItemActionButton(await treeItem.getLabel(), + constants.closeEditor); }); diff --git a/gui/extension/tests/e2e/tests/ui-rest-config.ts b/gui/extension/tests/e2e/tests/ui-rest-config.ts new file mode 100644 index 000000000..bcbcc43d4 --- /dev/null +++ b/gui/extension/tests/e2e/tests/ui-rest-config.ts @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have included with + * the program or referenced in the documentation. + * + * 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, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +import { expect } from "chai"; +import { driver, Misc } from "../lib/Misc"; +import { E2EAccordionSection } from "../lib/SideBar/E2EAccordionSection"; +import { Os } from "../lib/Os"; +import { Workbench } from "../lib/Workbench"; +import { DatabaseConnectionOverview } from "../lib/WebViews/DatabaseConnectionOverview"; +import * as constants from "../lib/constants"; +import * as interfaces from "../lib/interfaces"; +import { E2ENotebook } from "../lib/WebViews/E2ENotebook"; +import { TestQueue } from "../lib/TestQueue"; +import { ConfigRestServiceDialog } from "../lib/WebViews/Dialogs/ConfigRestServiceDialog"; +import { E2ECommandResultData } from "../lib/WebViews/CommandResults/E2ECommandResultData"; + +describe("MySQL REST Service Configuration", () => { + let existsInQueue = false; + const globalConn: interfaces.IDBConnection = { + dbType: "MySQL", + caption: "e2eGlobalConnection", + description: "Local connection", + basic: { + hostname: "localhost", + username: String(process.env.DBUSERNAME1), + port: parseInt(process.env.MYSQL_REST_CONFIG_PORT, 10), + schema: "sakila", + password: String(process.env.DBPASSWORD1), + }, + }; + + const dbTreeSection = new E2EAccordionSection(constants.dbTreeSection); + + before(async function () { + await Misc.loadDriver(); + try { + await driver.wait(Workbench.untilExtensionIsReady(), constants.waitForExtensionReady); + await Os.appendToExtensionLog("beforeAll Rest Config"); + await Workbench.toggleBottomBar(false); + Misc.removeDatabaseConnections(); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + await dbTreeSection.createDatabaseConnection(globalConn); + await driver.wait(dbTreeSection.untilTreeItemExists(globalConn.caption), constants.waitForTreeItem); + await (await new DatabaseConnectionOverview().getConnection(globalConn.caption)).click(); + await driver.wait(new E2ENotebook().untilIsOpened(globalConn), constants.wait1second * 10); + await driver.wait(dbTreeSection.untilTreeItemExists(globalConn.caption), constants.waitForTreeItem); + await Os.deleteCredentials(); + await dbTreeSection.focus(); + await dbTreeSection.expandTreeItem(globalConn.caption, globalConn); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); + + beforeEach(async function () { + await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); + try { + await driver.wait(dbTreeSection.untilIsNotLoading(), constants.waitSectionNoProgressBar, + `${constants.dbTreeSection} is still loading`); + await Workbench.dismissNotifications(); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); + + afterEach(async function () { + if (this.currentTest.state === "failed") { + await Misc.processFailure(this); + } + if (existsInQueue) { + await TestQueue.pop(this.currentTest.title); + existsInQueue = false; + } + await Workbench.dismissNotifications(); + const result = await new E2ENotebook().codeEditor + .execute("DROP SCHEMA IF EXISTS mysql_rest_service_metadata;") as E2ECommandResultData; + expect(result.text).to.match(/OK/); + await dbTreeSection.clickToolbarButton(constants.reloadConnections); + }); + + after(async function () { + try { + Misc.removeDatabaseConnections(); + } catch (e) { + await Misc.processFailure(this); + throw e; + } + }); + + it("Add new Configuration with Authentication App", async () => { + const mrsConfig: interfaces.IRestServiceConfig = { + status: "disabled", + authentication: { + createDefaultApp: true, + username: "newApp", + password: "Guidev!1", + }, + }; + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); + await ConfigRestServiceDialog.set(mrsConfig); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 25); + await driver.wait(dbTreeSection.untilTreeItemExists(constants.mysqlRestService), constants.waitForTreeItem); + await dbTreeSection.expandTreeItem(constants.mysqlRestService); + await dbTreeSection.expandTreeItem(constants.restAuthenticationApps); + await driver.wait(dbTreeSection.untilTreeItemExists("MRS"), constants.wait1second * 5); + expect(await dbTreeSection.treeItemExists("MySQL")).to.be.true; + }); + + it("Add new Configuration without Authentication app", async () => { + const mrsConfig: interfaces.IRestServiceConfig = { + status: "enabled", + authentication: { + createDefaultApp: false, + }, + }; + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); + await ConfigRestServiceDialog.set(mrsConfig); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 25); + await driver.wait(dbTreeSection.untilTreeItemExists(constants.mysqlRestService), constants.waitForTreeItem); + await dbTreeSection.expandTreeItem(constants.mysqlRestService); + await dbTreeSection.expandTreeItem(constants.restAuthenticationApps); + expect(await dbTreeSection.treeItemExists("MRS")).to.be.false; + expect(await dbTreeSection.treeItemExists("MySQL")).to.be.true; + }); + + it("Edit existing configuration", async () => { + const config: interfaces.IRestServiceConfig = { + status: "enabled", + authentication: { + createDefaultApp: false, + }, + }; + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); + await ConfigRestServiceDialog.set(config); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 10); + await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.configureRestService); + const mrsConfig: interfaces.IRestServiceConfig = { + status: "Disabled", + authenticationThrottling: { + preAccountThrottling: { + minTimeBetweenRequests: "800", + maxAttemptsPerMinute: "250", + }, + perHostThrottling: { + minTimeBetweenRequests: "210", + maxAttemptsPerMinute: "303", + }, + throttlingGeneral: { + blockTimeout: "155", + }, + }, + caches: { + endPointResponseCache: "3M", + staticFileCache: "5M", + gtidCache: true, + refreshRate: "15", + refreshWhenIncreased: "110", + }, + redirectsStaticContent: { + endPointResponseCacheOptions: [{ + name: "ack1", + value: "test", + }, + { + name: "ack2", + value: "test", + }], + defaultRedirects: [{ + name: "ack1", + value: "test", + }, + { + name: "ack2", + value: "test", + }], + }, + options: `{"key11":"value12"}`, + }; + await ConfigRestServiceDialog.set(mrsConfig); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 10); + await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.configureRestService); + const newConfig = await ConfigRestServiceDialog.get(); + expect(mrsConfig.status).to.equals(newConfig.status); + expect(mrsConfig.authenticationThrottling.preAccountThrottling) + .to.deep.equals(newConfig.authenticationThrottling.preAccountThrottling); + expect(mrsConfig.authenticationThrottling.perHostThrottling) + .to.deep.equals(newConfig.authenticationThrottling.perHostThrottling); + expect(mrsConfig.authenticationThrottling.throttlingGeneral) + .to.deep.equals(newConfig.authenticationThrottling.throttlingGeneral); + expect(mrsConfig.caches).to.deep.equals(newConfig.caches); + for (const option of mrsConfig.redirectsStaticContent.endPointResponseCacheOptions) { + expect(newConfig.redirectsStaticContent.endPointResponseCacheOptions).to.deep.include(option); + } + for (const option of mrsConfig.redirectsStaticContent.defaultRedirects) { + expect(newConfig.redirectsStaticContent.defaultRedirects).to.deep.include(option); + } + expect(mrsConfig.options).to.equals(newConfig.options); + }); + + it("Upgrade MRS version", async () => { + await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); + const msrVersions = (await ConfigRestServiceDialog.getMRSVersions()).reverse(); + let mrsConfig: interfaces.IRestServiceConfig = { + currentVersion: msrVersions[0], + authentication: { + createDefaultApp: false, + }, + }; + await ConfigRestServiceDialog.set(mrsConfig); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 10); + for (const mrsVersion of msrVersions.slice(1)) { + mrsConfig = { + updateToVersion: mrsVersion, + }; + await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, + constants.configureRestService); + await ConfigRestServiceDialog.set(mrsConfig); + await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), + constants.wait1second * 10); + } + }); +}); diff --git a/gui/extension/tests/e2e/tests/ui-rest.ts b/gui/extension/tests/e2e/tests/ui-rest.ts index 5b493b2e3..dbaeaf5cd 100644 --- a/gui/extension/tests/e2e/tests/ui-rest.ts +++ b/gui/extension/tests/e2e/tests/ui-rest.ts @@ -45,7 +45,6 @@ import { RestObjectDialog } from "../lib/WebViews/Dialogs/RestObjectDialog"; import { AuthenticationAppDialog } from "../lib/WebViews/Dialogs/AuthenticationAppDialog"; import { RestUserDialog } from "../lib/WebViews/Dialogs/RestUserDialog"; import { E2ELogger } from "../lib/E2ELogger"; -import { ConfigRestServiceDialog } from "../lib/WebViews/Dialogs/ConfigRestServiceDialog"; import { E2ECommandResultData } from "../lib/WebViews/CommandResults/E2ECommandResultData"; const sakilaRestSchema: interfaces.IRestSchema = { @@ -107,200 +106,6 @@ describe("MySQL REST Service", () => { } }); - describe("Rest Service Configuration", () => { - - let existsInQueue = false; - - beforeEach(async function () { - await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); - try { - await driver.wait(dbTreeSection.untilIsNotLoading(), constants.waitSectionNoProgressBar, - `${constants.dbTreeSection} is still loading`); - await Workbench.dismissNotifications(); - } catch (e) { - await Misc.processFailure(this); - throw e; - } - }); - - afterEach(async function () { - if (this.currentTest.state === "failed") { - await Misc.processFailure(this); - } - - if (existsInQueue) { - await TestQueue.pop(this.currentTest.title); - existsInQueue = false; - } - - await Workbench.dismissNotifications(); - const result = await new E2ENotebook().codeEditor - .execute("DROP SCHEMA IF EXISTS mysql_rest_service_metadata;") as E2ECommandResultData; - expect(result.text).to.match(/OK/); - await dbTreeSection.clickToolbarButton(constants.reloadConnections); - }); - - it("Add new Configuration with Authentication App", async () => { - - const mrsConfig: interfaces.IRestServiceConfig = { - status: "disabled", - authentication: { - createDefaultApp: true, - username: "newApp", - password: "Guidev!1", - }, - }; - - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); - await ConfigRestServiceDialog.set(mrsConfig); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 25); - await driver.wait(dbTreeSection.untilTreeItemExists(constants.mysqlRestService), constants.waitForTreeItem); - await dbTreeSection.expandTreeItem(constants.mysqlRestService); - await dbTreeSection.expandTreeItem(constants.restAuthenticationApps); - expect(await dbTreeSection.treeItemExists("MRS")).to.be.true; - expect(await dbTreeSection.treeItemExists("MySQL")).to.be.true; - - }); - - it("Add new Configuration without Authentication app", async () => { - - const mrsConfig: interfaces.IRestServiceConfig = { - status: "enabled", - authentication: { - createDefaultApp: false, - }, - }; - - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); - await ConfigRestServiceDialog.set(mrsConfig); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 25); - await driver.wait(dbTreeSection.untilTreeItemExists(constants.mysqlRestService), constants.waitForTreeItem); - await dbTreeSection.expandTreeItem(constants.mysqlRestService); - await dbTreeSection.expandTreeItem(constants.restAuthenticationApps); - expect(await dbTreeSection.treeItemExists("MRS")).to.be.false; - expect(await dbTreeSection.treeItemExists("MySQL")).to.be.true; - - }); - - it("Edit existing configuration", async () => { - - const config: interfaces.IRestServiceConfig = { - status: "enabled", - authentication: { - createDefaultApp: false, - }, - }; - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); - await ConfigRestServiceDialog.set(config); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 10); - - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.configureRestService); - - const mrsConfig: interfaces.IRestServiceConfig = { - status: "Disabled", - authenticationThrottling: { - preAccountThrottling: { - minTimeBetweenRequests: "800", - maxAttemptsPerMinute: "250", - }, - perHostThrottling: { - minTimeBetweenRequests: "210", - maxAttemptsPerMinute: "303", - }, - throttlingGeneral: { - blockTimeout: "155", - }, - }, - caches: { - endPointResponseCache: "3M", - staticFileCache: "5M", - gtidCache: true, - refreshRate: "15", - refreshWhenIncreased: "110", - }, - redirectsStaticContent: { - endPointResponseCacheOptions: [{ - name: "ack1", - value: "test", - }, - { - name: "ack2", - value: "test", - }], - defaultRedirects: [{ - name: "ack1", - value: "test", - }, - { - name: "ack2", - value: "test", - }], - }, - options: `{"key11":"value12"}`, - }; - - await ConfigRestServiceDialog.set(mrsConfig); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 10); - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.configureRestService); - const newConfig = await ConfigRestServiceDialog.get(); - expect(mrsConfig.status).to.equals(newConfig.status); - expect(mrsConfig.authenticationThrottling.preAccountThrottling) - .to.deep.equals(newConfig.authenticationThrottling.preAccountThrottling); - expect(mrsConfig.authenticationThrottling.perHostThrottling) - .to.deep.equals(newConfig.authenticationThrottling.perHostThrottling); - expect(mrsConfig.authenticationThrottling.throttlingGeneral) - .to.deep.equals(newConfig.authenticationThrottling.throttlingGeneral); - expect(mrsConfig.caches).to.deep.equals(newConfig.caches); - - for (const option of mrsConfig.redirectsStaticContent.endPointResponseCacheOptions) { - expect(newConfig.redirectsStaticContent.endPointResponseCacheOptions).to.deep.include(option); - } - - for (const option of mrsConfig.redirectsStaticContent.defaultRedirects) { - expect(newConfig.redirectsStaticContent.defaultRedirects).to.deep.include(option); - } - - expect(mrsConfig.options).to.equals(newConfig.options); - - - }); - - it("Upgrade MRS version", async () => { - - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, constants.configureInstanceForRestService); - - const msrVersions = (await ConfigRestServiceDialog.getMRSVersions()).reverse(); - let mrsConfig: interfaces.IRestServiceConfig = { - currentVersion: msrVersions[0], - authentication: { - createDefaultApp: false, - }, - }; - - await ConfigRestServiceDialog.set(mrsConfig); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 10); - - for (const mrsVersion of msrVersions.slice(1)) { - mrsConfig = { - updateToVersion: mrsVersion, - }; - - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, - constants.configureRestService); - await ConfigRestServiceDialog.set(mrsConfig); - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 10); - } - - }); - - }); - describe("Rest Services", () => { let service1: interfaces.IRestService = { @@ -320,25 +125,6 @@ describe("MySQL REST Service", () => { let existsInQueue = false; const destDumpSdk = join(process.cwd(), "dump.sdk"); - before(async function () { - try { - await dbTreeSection.openContextMenuAndSelect(globalConn.caption, - constants.configureInstanceForRestService); - - await ConfigRestServiceDialog.set({ - authentication: { - createDefaultApp: false, - }, - }); - - await driver.wait(Workbench.untilNotificationExists("MySQL REST Service configured successfully."), - constants.wait1second * 5); - } catch (e) { - await Misc.processFailure(this); - throw e; - } - }); - beforeEach(async function () { await Os.appendToExtensionLog(String(this.currentTest.title) ?? process.env.TEST_SUITE); try { @@ -589,11 +375,12 @@ describe("MySQL REST Service", () => { } await (await dbTreeSection.getTreeItem("sakila")).collapse(); - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.addRESTService); - await RestServiceDialog.set(service2); - await driver.wait(Workbench.untilNotificationExists("The MRS service has been created"), - constants.wait1second * 20); - await driver.wait(dbTreeSection.untilTreeItemExists(service2.servicePath), constants.waitForTreeItem); + const notebook = new E2ENotebook(); + const result = await notebook.codeEditor + .execute(`CREATE REST SERVICE ${service2.servicePath}`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.reloadDataBaseInformation); } catch (e) { await Misc.processFailure(this); throw e; @@ -658,8 +445,8 @@ describe("MySQL REST Service", () => { await dbTreeSection.expandTreeItem(service2.servicePath); const schemaTreeName = `${service2.restSchemas[i].restSchemaPath} (${service2.restSchemas[i] .settings.schemaName})`; - await (await dbTreeSection.getTreeItemActionButton(globalConn.caption, - constants.reloadDataBaseInformation)).click(); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.reloadDataBaseInformation); await driver.wait(dbTreeSection.untilTreeItemExists(schemaTreeName), constants.waitForTreeItem); } @@ -896,24 +683,18 @@ describe("MySQL REST Service", () => { await (await dbTreeSection.getTreeItem("sakila")).collapse(); - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.addRESTService); - await RestServiceDialog.set(service3); - await driver.wait(Workbench.untilNotificationExists("The MRS service has been created"), - constants.wait1second * 20); - await driver.wait(dbTreeSection.untilTreeItemExists(service3.servicePath), constants.waitForTreeItem); - await dbTreeSection.setCurrentRestService(service3.servicePath); - - await dbTreeSection.openContextMenuAndSelect(service3.restSchemas[0].settings.schemaName, - constants.addSchemaToREST); - - service3.restSchemas[0] = await RestSchemaDialog.set(service3.restSchemas[0]); - await driver.wait(Workbench.untilNotificationExists("The MRS schema has been added successfully."), - constants.wait1second * 10); - + const notebook = new E2ENotebook(); + let result = await notebook.codeEditor + .execute(`CREATE REST SERVICE ${service3.servicePath};`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + result = await notebook.codeEditor + .execute(`CREATE REST SCHEMA ${service3.restSchemas[0].restSchemaPath} + ON SERVICE ${service3.servicePath} + FROM \`${service3.restSchemas[0].settings.schemaName}\`;`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.reloadDataBaseInformation); await dbTreeSection.expandTreeItem(service3.servicePath); - const schemaTreeName = `${service3.restSchemas[0].restSchemaPath} (${service3.restSchemas[0] - .settings.schemaName})`; - await driver.wait(dbTreeSection.untilTreeItemExists(schemaTreeName), constants.waitForTreeItem); } catch (e) { await Misc.processFailure(this); throw e; @@ -1284,11 +1065,12 @@ describe("MySQL REST Service", () => { await (await dbTreeSection.getTreeItem("sakila")).collapse(); - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.addRESTService); - await RestServiceDialog.set(service4); - await driver.wait(Workbench.untilNotificationExists("The MRS service has been created"), - constants.wait1second * 20); - await driver.wait(dbTreeSection.untilTreeItemExists(service4.servicePath), constants.waitForTreeItem); + const notebook = new E2ENotebook(); + const result = await notebook.codeEditor + .execute(`CREATE REST SERVICE ${service4.servicePath};`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.reloadDataBaseInformation); await dbTreeSection.setCurrentRestService(service4.servicePath); } catch (e) { await Misc.processFailure(this); @@ -1531,24 +1313,19 @@ describe("MySQL REST Service", () => { servicePath: `/service5`, authenticationApps: [ { - vendor: constants.vendorOCIOAuth2, - name: "Auth App", + vendor: constants.mrs, + name: "MRS", enabled: true, limitToRegisteredUsers: true, settings: { description: "this is an authentication app", defaultRole: "Full Access", }, - oauth2settings: { - appId: "1234", - appSecret: "1234test", - customURL: "http://localhost/", - customURLforAccessToken: "http://localhost/1234", - }, options: `{ "name": "test options" }`, user: [{ username: "gui", - authenticationApp: "new app", + password: "MySQLR0cks!", + authenticationApp: "MRS", email: "user@oracle.com", assignedRoles: undefined, userOptions: "", @@ -1576,21 +1353,17 @@ describe("MySQL REST Service", () => { await (await dbTreeSection.getTreeItem("sakila")).collapse(); - await dbTreeSection.openContextMenuAndSelect(constants.mysqlRestService, constants.addRESTService); - await RestServiceDialog.set(service5); - await driver.wait(Workbench.untilNotificationExists("The MRS service has been created"), - constants.wait1second * 20); - await driver.wait(dbTreeSection.untilTreeItemExists(service5.servicePath), constants.waitForTreeItem); - await dbTreeSection.setCurrentRestService(service5.servicePath); - - await dbTreeSection.openContextMenuAndSelect(constants.restAuthenticationApps, - constants.addNewAuthenticationApp); - service5.authenticationApps = [await AuthenticationAppDialog.set(service5.authenticationApps[0])]; - await driver.wait(Workbench.untilNotificationExists("The MRS Authentication App has been added"), - constants.wait1second * 5); + const notebook = new E2ENotebook(); + let result = await notebook.codeEditor + .execute(`CREATE REST SERVICE ${service5.servicePath};`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + result = await notebook.codeEditor + .execute(`CREATE OR REPLACE REST AUTHENTICATION APP "${service5.authenticationApps[0].name}" + VENDOR ${service5.authenticationApps[0].vendor};`) as E2ECommandResultData; + expect(result.text).to.match(/OK/); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, + constants.reloadDataBaseInformation); await dbTreeSection.expandTreeItem(constants.restAuthenticationApps); - await driver.wait(dbTreeSection.untilTreeItemExists(service5.authenticationApps[0].name), - constants.waitForTreeItem); } catch (e) { await Misc.processFailure(this); throw e; @@ -1642,6 +1415,7 @@ describe("MySQL REST Service", () => { const editedUser: interfaces.IRestUser = { username: "testUser", + password: "MySQLR0cks!", authenticationApp: service5.authenticationApps[0].name, email: "testuser@oracle.com", assignedRoles: "Full Access", diff --git a/gui/extension/tests/e2e/tests/ui-result-grids.ts b/gui/extension/tests/e2e/tests/ui-result-grids.ts index dddfbcb24..22bdd7782 100644 --- a/gui/extension/tests/e2e/tests/ui-result-grids.ts +++ b/gui/extension/tests/e2e/tests/ui-result-grids.ts @@ -1438,8 +1438,8 @@ describe("RESULT GRIDS", () => { await openEditorsSection.expand(); await Workbench.dismissNotifications(); - await (await openEditorsSection.getTreeItemActionButton(globalConn.caption, - constants.newMySQLScript)).click(); + await openEditorsSection.clickTreeItemActionButton(globalConn.caption, + constants.newMySQLScript); await dbTreeSection.openContextMenuAndSelect(anotherConn.caption, constants.openNewConnection); const anotherConnNotebook = new E2ENotebook(); diff --git a/gui/extension/tests/e2e/tests/ui-router.ts b/gui/extension/tests/e2e/tests/ui-router.ts index 1c28dd754..3930893a2 100644 --- a/gui/extension/tests/e2e/tests/ui-router.ts +++ b/gui/extension/tests/e2e/tests/ui-router.ts @@ -152,8 +152,7 @@ describe("Router", () => { await Workbench.waitForTerminalText("Once the MySQL Router is started", constants.wait1second * 10); expect(await Workbench.terminalHasErrors(), "Terminal has errors").to.be.false; await dbTreeSection.expandTreeItem(constants.mysqlRouters); - await (await dbTreeSection.getTreeItemActionButton(globalConn.caption, constants.reloadDataBaseInformation)) - .click(); + await dbTreeSection.clickTreeItemActionButton(globalConn.caption, constants.reloadDataBaseInformation); await driver.wait(dbTreeSection.untilTreeItemExists(new RegExp(hostname())), constants.waitForTreeItem); await Os.setRouterConfigFile({ sinks: "filelog", diff --git a/gui/frontend/e2e.jest.config.ts b/gui/frontend/e2e.jest.config.ts index f2f9c1503..75b84b3a2 100644 --- a/gui/frontend/e2e.jest.config.ts +++ b/gui/frontend/e2e.jest.config.ts @@ -214,7 +214,7 @@ const config: Config = { // The glob patterns Jest uses to detect test files testMatch: [ - "**/tests/e2e/**/ui-*.[jt]s?(x)" + "**/tests/e2e/**/ui-misc.[jt]s?(x)" ], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped diff --git a/gui/frontend/package-lock.json b/gui/frontend/package-lock.json index 1f4c34f2f..650f00a3c 100644 --- a/gui/frontend/package-lock.json +++ b/gui/frontend/package-lock.json @@ -131,22 +131,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", + "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -162,9 +162,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.8.tgz", - "integrity": "sha512-3tBctaHRW6xSub26z7n8uyOTwwUsCdvIug/oxBH9n6yCO5hMj2vwDJAo7RbBMKrM7P+W2j61zLKviJQFGOYKMg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.10.tgz", + "integrity": "sha512-QsfQZr4AiLpKqn7fz+j7SN+f43z2DZCgGyYbNJ2vJOqKfG4E6MZer1+jqGZqKJaxq/gdO2DC/nUu45+pOL5p2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -191,14 +191,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", + "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/parser": "^7.26.10", + "@babel/types": "^7.26.10", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -310,27 +310,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/types": "^7.26.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" @@ -615,9 +615,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", - "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dev": true, "license": "MIT", "dependencies": { @@ -643,17 +643,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz", + "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", + "@babel/generator": "^7.26.10", + "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/types": "^7.26.10", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -662,9 +662,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -794,3579 +794,3508 @@ "esbuild": "*" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz", - "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "cpu": [ - "arm" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "android" + "aix" ], "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", - "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "cpu": [ - "loong64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "peer": true, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@glen/jest-raw-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@glen/jest-raw-loader/-/jest-raw-loader-2.0.0.tgz", - "integrity": "sha512-758pv2NtgFOJvVIdh6JRy4LoxLsAz8qtXwxLp/u/GHXz6wCWrbw581QF0ORJ2E8zEdhM4xjDLlsFSjeISmX0KQ==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "peerDependencies": { - "jest": ">=28" + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=10.10.0" + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, + "optional": true, + "os": [ + "sunos" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "node_modules/@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, + "optional": true, + "os": [ + "win32" + ], + "peer": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" } }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.0.tgz", + "integrity": "sha512-RoV8Xs9eNwiDvhv7M+xcL4PWyRyIXRY/FLp3buU4h1EYfdF7unWUy3dOjPqb3C7rMUewIcqwW850PgS8h1o1yg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "funding": { + "url": "https://opencollective.com/eslint" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/create-cache-key-function": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", - "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" + "type-fest": "^0.20.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "*" } }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "node_modules/@glen/jest-raw-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@glen/jest-raw-loader/-/jest-raw-loader-2.0.0.tgz", + "integrity": "sha512-758pv2NtgFOJvVIdh6JRy4LoxLsAz8qtXwxLp/u/GHXz6wCWrbw581QF0ORJ2E8zEdhM4xjDLlsFSjeISmX0KQ==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "peerDependencies": { + "jest": ">=28" } }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=10.10.0" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "*" } }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "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==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=6.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "engines": { + "node": ">=8" } }, - "node_modules/@mdn/browser-compat-data": { - "version": "5.6.43", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.6.43.tgz", - "integrity": "sha512-qLuxKpjwFhjvFkdqNb37AJpJo9J22Qdcml+92/yWdlREte3JFdayz7SqmjXLlCuizSjz9uVH+aW7dQ7KJEKg1g==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "CC0-1.0" + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "license": "MIT", "dependencies": { - "eslint-scope": "5.1.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", "dev": true, "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3" + }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@preact/preset-vite": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.8.2.tgz", - "integrity": "sha512-m3tl+M8IO8jgiHnk+7LSTFl8axdPXloewi7iGVLdmCwf34XOzEUur0bZVewW4DUbUipFjTS2CXu27+5f/oexBA==", + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@prefresh/vite": "^2.4.1", - "@rollup/pluginutils": "^4.1.1", - "babel-plugin-transform-hook-names": "^1.0.2", - "debug": "^4.3.4", - "kolorist": "^1.8.0", - "magic-string": "0.30.5", - "node-html-parser": "^6.1.10", - "resolve": "^1.22.8", - "source-map": "^0.7.4", - "stack-trace": "^1.0.0-pre2" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, - "peerDependencies": { - "@babel/core": "7.x", - "vite": "2.x || 3.x || 4.x || 5.x" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@prefresh/babel-plugin": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@prefresh/babel-plugin/-/babel-plugin-0.5.1.tgz", - "integrity": "sha512-uG3jGEAysxWoyG3XkYfjYHgaySFrSsaEb4GagLzYaxlydbuREtaX+FTxuIidp241RaLl85XoHg9Ej6E4+V1pcg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@prefresh/core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@prefresh/core/-/core-1.5.3.tgz", - "integrity": "sha512-nDzxj0tA1/M6APNAWqaxkZ+3sTdPHESa+gol4+Bw7rMc2btWdkLoNH7j9rGhUb8SThC0Vz0VoXtq+U+9azGLHg==", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "license": "MIT", - "peerDependencies": { - "preact": "^10.0.0" + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@prefresh/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@prefresh/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ==", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@prefresh/vite": { - "version": "2.4.7", - "resolved": "https://registry.npmjs.org/@prefresh/vite/-/vite-2.4.7.tgz", - "integrity": "sha512-zmCEDWSFHl5A7PciXa/fe+OUjoGi4iiCQclpWfpIg7LjxwWrtlUT4DfxDBcQwHfTyipS/XDm8x7WYrkiTW0q+w==", + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.22.1", - "@prefresh/babel-plugin": "0.5.1", - "@prefresh/core": "^1.5.1", - "@prefresh/utils": "^1.2.0", - "@rollup/pluginutils": "^4.2.1" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, - "peerDependencies": { - "preact": "^10.4.0", - "vite": ">=2.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/plugin-inject": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", - "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.3" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">=14.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "rollup": { + "node-notifier": { "optional": true } } }, - "node_modules/@rollup/plugin-inject/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==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/plugin-inject/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "license": "MIT", "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", - "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", - "cpu": [ - "arm" - ], + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", - "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", - "cpu": [ - "arm64" - ], + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", - "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", - "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", - "cpu": [ - "x64" - ], + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", - "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", - "cpu": [ - "arm64" - ], + "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==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", - "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", - "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", - "cpu": [ - "arm" - ], + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", - "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", - "cpu": [ - "arm" - ], + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", - "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", - "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", - "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", - "cpu": [ - "loong64" - ], + "node_modules/@mdn/browser-compat-data": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.7.2.tgz", + "integrity": "sha512-ZmBrBR3PH+N7z5yLi4xz4wFzgsXyK0yghIH0t/zdo6taPYLk44OlycvVD5ZZlcz1py9J8yW/4D70CLz72KoLUg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "CC0-1.0" }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", - "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", - "cpu": [ - "ppc64" - ], + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "eslint-scope": "5.1.1" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", - "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", - "cpu": [ - "riscv64" - ], + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", - "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", - "cpu": [ - "s390x" - ], + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", - "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", - "cpu": [ - "x64" - ], + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", - "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", - "cpu": [ - "x64" - ], + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">= 8" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", - "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", - "cpu": [ - "arm64" - ], + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", - "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", - "cpu": [ - "ia32" - ], + "node_modules/@preact/preset-vite": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.8.2.tgz", + "integrity": "sha512-m3tl+M8IO8jgiHnk+7LSTFl8axdPXloewi7iGVLdmCwf34XOzEUur0bZVewW4DUbUipFjTS2CXu27+5f/oexBA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@prefresh/vite": "^2.4.1", + "@rollup/pluginutils": "^4.1.1", + "babel-plugin-transform-hook-names": "^1.0.2", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "magic-string": "0.30.5", + "node-html-parser": "^6.1.10", + "resolve": "^1.22.8", + "source-map": "^0.7.4", + "stack-trace": "^1.0.0-pre2" + }, + "peerDependencies": { + "@babel/core": "7.x", + "vite": "2.x || 3.x || 4.x || 5.x" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", - "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", - "cpu": [ - "x64" - ], + "node_modules/@prefresh/babel-plugin": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@prefresh/babel-plugin/-/babel-plugin-0.5.1.tgz", + "integrity": "sha512-uG3jGEAysxWoyG3XkYfjYHgaySFrSsaEb4GagLzYaxlydbuREtaX+FTxuIidp241RaLl85XoHg9Ej6E4+V1pcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prefresh/core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@prefresh/core/-/core-1.5.3.tgz", + "integrity": "sha512-nDzxj0tA1/M6APNAWqaxkZ+3sTdPHESa+gol4+Bw7rMc2btWdkLoNH7j9rGhUb8SThC0Vz0VoXtq+U+9azGLHg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "peerDependencies": { + "preact": "^10.0.0" + } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "node_modules/@prefresh/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@prefresh/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ==", "dev": true, "license": "MIT" }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/@prefresh/vite": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/@prefresh/vite/-/vite-2.4.7.tgz", + "integrity": "sha512-zmCEDWSFHl5A7PciXa/fe+OUjoGi4iiCQclpWfpIg7LjxwWrtlUT4DfxDBcQwHfTyipS/XDm8x7WYrkiTW0q+w==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "type-detect": "4.0.8" + "@babel/core": "^7.22.1", + "@prefresh/babel-plugin": "0.5.1", + "@prefresh/core": "^1.5.1", + "@prefresh/utils": "^1.2.0", + "@rollup/pluginutils": "^4.2.1" + }, + "peerDependencies": { + "preact": "^10.4.0", + "vite": ">=2.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@swc/core": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", - "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", + "node_modules/@rollup/plugin-inject/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==", "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@swc/counter": "^0.1.2", - "@swc/types": "0.1.7" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.5.7", - "@swc/core-darwin-x64": "1.5.7", - "@swc/core-linux-arm-gnueabihf": "1.5.7", - "@swc/core-linux-arm64-gnu": "1.5.7", - "@swc/core-linux-arm64-musl": "1.5.7", - "@swc/core-linux-x64-gnu": "1.5.7", - "@swc/core-linux-x64-musl": "1.5.7", - "@swc/core-win32-arm64-msvc": "1.5.7", - "@swc/core-win32-ia32-msvc": "1.5.7", - "@swc/core-win32-x64-msvc": "1.5.7" + "node": ">=14.0.0" }, "peerDependencies": { - "@swc/helpers": "^0.5.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { - "@swc/helpers": { + "rollup": { "optional": true } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", - "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", - "cpu": [ - "arm64" - ], + "node_modules/@rollup/plugin-inject/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", - "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", - "cpu": [ - "x64" - ], + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, "engines": { - "node": ">=10" + "node": ">= 8.0.0" } }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", - "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", + "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", "cpu": [ "arm" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "android" + ] }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", - "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", + "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "android" + ] }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", - "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", + "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "darwin" + ] }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", - "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", + "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "darwin" + ] }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", - "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", + "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", + "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", + "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", + "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", + "cpu": [ + "arm" ], - "engines": { - "node": ">=10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", - "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", + "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", + "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">=10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", - "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", + "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", "cpu": [ - "ia32" + "loong64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", + "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", + "cpu": [ + "ppc64" ], - "engines": { - "node": ">=10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", - "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", + "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", "cpu": [ - "x64" + "riscv64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", + "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", + "cpu": [ + "s390x" ], - "engines": { - "node": ">=10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", + "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/jest": { - "version": "0.2.36", - "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.36.tgz", - "integrity": "sha512-8X80dp81ugxs4a11z1ka43FPhP+/e+mJNXJSxiNYk8gIX/jPBtY4gQTrKu/KIoco8bzKuPI5lUxjfLiGsfvnlw==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", + "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jest/create-cache-key-function": "^29.7.0", - "@swc/counter": "^0.1.3", - "jsonc-parser": "^3.2.0" - }, - "engines": { - "npm": ">= 7.0.0" - }, - "peerDependencies": { - "@swc/core": "*" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/types": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", - "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", + "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", + "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", + "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "deep-equal": "^2.0.5" + "type-detect": "4.0.8" } }, - "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } }, - "node_modules/@testing-library/jest-dom": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", - "integrity": "sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==", + "node_modules/@swc/core": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", + "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", "dev": true, - "license": "MIT", + "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@adobe/css-tools": "^4.3.2", - "@babel/runtime": "^7.9.2", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.21", - "redent": "^3.0.0" - }, + "@swc/counter": "^0.1.2", + "@swc/types": "0.1.7" + }, "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.5.7", + "@swc/core-darwin-x64": "1.5.7", + "@swc/core-linux-arm-gnueabihf": "1.5.7", + "@swc/core-linux-arm64-gnu": "1.5.7", + "@swc/core-linux-arm64-musl": "1.5.7", + "@swc/core-linux-x64-gnu": "1.5.7", + "@swc/core-linux-x64-musl": "1.5.7", + "@swc/core-win32-arm64-msvc": "1.5.7", + "@swc/core-win32-ia32-msvc": "1.5.7", + "@swc/core-win32-x64-msvc": "1.5.7" }, "peerDependencies": { - "@jest/globals": ">= 28", - "@types/bun": "latest", - "@types/jest": ">= 28", - "jest": ">= 28", - "vitest": ">= 0.32" + "@swc/helpers": "^0.5.0" }, "peerDependenciesMeta": { - "@jest/globals": { - "optional": true - }, - "@types/bun": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "jest": { - "optional": true - }, - "vitest": { + "@swc/helpers": { "optional": true } } }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/@swc/core-darwin-arm64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", + "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/@testing-library/preact": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@testing-library/preact/-/preact-3.2.3.tgz", - "integrity": "sha512-y6Kklp1XK3f1X2fWCbujmJyzkf+1BgLYXNgAx21j9+D4CoqMTz5qC4SQufb1L6q/jxLGACzrQ90ewVOTBvHOfg==", + "node_modules/@swc/core-darwin-x64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", + "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@testing-library/dom": "^8.11.1" - }, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "preact": ">=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0" + "node": ">=10" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", + "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/cheerio": { - "version": "0.22.35", - "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.35.tgz", - "integrity": "sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/color": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz", - "integrity": "sha512-NMiNcZFRUAiUUCCf7zkAelY8eV3aKqfbzyFQlXpPIEeoNDbsEHGpb854V3gzTsGKYj830I5zPuOwU/TP5/cW6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/color-convert": "*" - } - }, - "node_modules/@types/color-convert": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.4.tgz", - "integrity": "sha512-Ub1MmDdyZ7mX//g25uBAoH/mWGd9swVbt8BseymnaE18SU4po/PjmCrHxqIIRjBo3hV/vh1KGr0eMxUhp+t+dQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/color-name": "^1.1.0" - } - }, - "node_modules/@types/color-name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.5.tgz", - "integrity": "sha512-j2K5UJqGTxeesj6oQuGpMgifpT5k9HprgQd8D1Y0lOFqKHl3PJu5GMeS4Y5EgjS55AE6OQxf8mPED9uaGbf4Cg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" + "node": ">=10" } }, - "node_modules/@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", + "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-array": "*", - "@types/geojson": "*" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-dispatch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", + "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", + "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-dsv": "*" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", + "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/geojson": "*" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", + "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", + "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", + "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0" }, - "node_modules/@types/d3-scale": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", - "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "node_modules/@swc/jest": { + "version": "0.2.36", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.36.tgz", + "integrity": "sha512-8X80dp81ugxs4a11z1ka43FPhP+/e+mJNXJSxiNYk8gIX/jPBtY4gQTrKu/KIoco8bzKuPI5lUxjfLiGsfvnlw==", "dev": true, "license": "MIT", "dependencies": { - "@types/d3-time": "*" + "@jest/create-cache-key-function": "^29.7.0", + "@swc/counter": "^0.1.3", + "jsonc-parser": "^3.2.0" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" } }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "node_modules/@swc/types": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", + "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } }, - "node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", "dev": true, "license": "MIT", "dependencies": { - "@types/d3-path": "*" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/d3-time": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT" }, - "node_modules/@types/d3-transition": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "node_modules/@testing-library/jest-dom": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", + "integrity": "sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==", "dev": true, "license": "MIT", "dependencies": { - "@types/d3-selection": "*" + "@adobe/css-tools": "^4.3.2", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } } }, - "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "license": "MIT", "dependencies": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/enzyme": { - "version": "3.10.18", - "resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.18.tgz", - "integrity": "sha512-RaO/TyyHZvXkpzinbMTZmd/S5biU4zxkvDsn22ujC29t9FMSzq8tnn8f2MxQ2P8GVhFRG5jTAL05DXKyTtpEQQ==", + "node_modules/@testing-library/preact": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@testing-library/preact/-/preact-3.2.3.tgz", + "integrity": "sha512-y6Kklp1XK3f1X2fWCbujmJyzkf+1BgLYXNgAx21j9+D4CoqMTz5qC4SQufb1L6q/jxLGACzrQ90ewVOTBvHOfg==", "dev": true, "license": "MIT", "dependencies": { - "@types/cheerio": "*", - "@types/react": "^16" + "@testing-library/dom": "^8.11.1" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "preact": ">=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0" } }, - "node_modules/@types/eslint": { - "version": "8.56.12", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", - "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "engines": { + "node": ">= 10" } }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true, "license": "MIT" }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true, "license": "MIT" }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/isomorphic-fetch": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz", - "integrity": "sha512-DaZNUvLDCAnCTjgwxgiL1eQdxIKEpNLOlTNtAgnZc50bG2copGhRrFN9/PxPBuJe+tZVLCbQ7ls0xveXVRPkvw==", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true, "license": "MIT" }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, "license": "MIT" }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "license": "MIT", "dependencies": { - "@types/istanbul-lib-report": "*" + "@babel/types": "^7.0.0" } }, - "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/@types/jest/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "dependencies": { + "@babel/types": "^7.20.7" } }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "node_modules/@types/cheerio": { + "version": "0.22.35", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.35.tgz", + "integrity": "sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/node": "*" } }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsdom": { - "version": "21.1.6", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.6.tgz", - "integrity": "sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==", + "node_modules/@types/color": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.6.tgz", + "integrity": "sha512-NMiNcZFRUAiUUCCf7zkAelY8eV3aKqfbzyFQlXpPIEeoNDbsEHGpb854V3gzTsGKYj830I5zPuOwU/TP5/cW6A==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "@types/tough-cookie": "*", - "parse5": "^7.0.0" + "@types/color-convert": "*" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-mM4TkDpA9oixqg1Fv2vVpOFyIVLJjm5x4k0V+K/rEsizfjD7Tk7LKk3GTtbB7KCfP0FEHQtsZqFxYA0+sijNVg==", + "node_modules/@types/color-convert": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.4.tgz", + "integrity": "sha512-Ub1MmDdyZ7mX//g25uBAoH/mWGd9swVbt8BseymnaE18SU4po/PjmCrHxqIIRjBo3hV/vh1KGr0eMxUhp+t+dQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/color-name": "^1.1.0" } }, - "node_modules/@types/jssha": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/jssha/-/jssha-2.0.0.tgz", - "integrity": "sha512-oBnY3csYnXfqZXDRBJwP1nDDJCW/+VMJ88UHT4DCy0deSXpJIQvMCwYlnmdW4M+u7PiSfQc44LmiFcUbJ8hLEw==", + "node_modules/@types/color-name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.5.tgz", + "integrity": "sha512-j2K5UJqGTxeesj6oQuGpMgifpT5k9HprgQd8D1Y0lOFqKHl3PJu5GMeS4Y5EgjS55AE6OQxf8mPED9uaGbf4Cg==", "dev": true, "license": "MIT" }, - "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" } }, - "node_modules/@types/opossum": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@types/opossum/-/opossum-4.1.1.tgz", - "integrity": "sha512-9TMnd8AWRVtnZMqBbbzceQoJdafErgUViogFaQ3eetsbeLtiFFZ695mepNaLtlfJi4uRP3GmHfe3CJ2DZKaxYA==", + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/d3-selection": "*" } }, - "node_modules/@types/prop-types": { - "version": "15.7.14", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", - "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "16.14.62", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.62.tgz", - "integrity": "sha512-BWf7hqninZav6nerxXj+NeZT/mTpDeG6Lk2zREHAy63CrnXoOGPGtNqTFYFN/sqpSaREDP5otVV88axIXmKfGA==", + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", "dev": true, "license": "MIT", "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" + "@types/d3-selection": "*" } }, - "node_modules/@types/resize-observer-browser": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", - "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", "dev": true, "license": "MIT" }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", "dev": true, "license": "MIT" }, - "node_modules/@types/selenium-webdriver": { - "version": "4.1.19", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.1.19.tgz", - "integrity": "sha512-9/vdyC3KeFQ7/vtt0H5RR0fnlrtc4dF9ssRBnh+yerua9O2Sst4nuPL4eHyKlR1/ZVV/5XPMLaJuVgv+7CDCAw==", + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", "dev": true, "license": "MIT", "dependencies": { - "@types/ws": "*" + "@types/d3-array": "*", + "@types/geojson": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", "dev": true, "license": "MIT" }, - "node_modules/@types/set-interval-async": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/set-interval-async/-/set-interval-async-1.0.3.tgz", - "integrity": "sha512-sPwjhIU2p8JeaYJPuzfQclyPni3c4Nz7IK4KhvAkMq5O36TsQXeaZ5g3YwiOtE90ja3E4rg7Aja1DcO+eknZbw==", + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", "dev": true, "license": "MIT" }, - "node_modules/@types/sshpk": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@types/sshpk/-/sshpk-1.10.3.tgz", - "integrity": "sha512-cru1waDhHZnZuB18E6Dgf2UXf8U93mdOEDcKYe5jTri+fpucidSs7DLmGICpLxN+95aYkwtgeyny9fBFzQVdmA==", + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/d3-selection": "*" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tabulator-tables": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-6.2.0.tgz", - "integrity": "sha512-dKEz3X/1SuEBa25RpbPhG4a5mVa+/nL5G4hHDWf+W+Xs6m1HREN9lX2qVhEIoJSeTqfqpvze8Fw5+qbCakH86g==", + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", "dev": true, "license": "MIT" }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", "dev": true, "license": "MIT" }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/d3-dsv": "*" } }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } + "license": "MIT" }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", "dev": true, "license": "MIT" }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", - "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/type-utils": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/geojson": "*" } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", - "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/d3-color": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } + "license": "MIT" }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/d3-time": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" + "@types/d3-path": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" } }, - "node_modules/@typescript-eslint/parser": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", - "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", - "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", + "node_modules/@types/enzyme": { + "version": "3.10.18", + "resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.18.tgz", + "integrity": "sha512-RaO/TyyHZvXkpzinbMTZmd/S5biU4zxkvDsn22ujC29t9FMSzq8tnn8f2MxQ2P8GVhFRG5jTAL05DXKyTtpEQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/cheerio": "*", + "@types/react": "^16" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", - "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", + "node_modules/@types/eslint": { + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/@typescript-eslint/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", - "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "dependencies": { + "@types/node": "*" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", - "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", + "node_modules/@types/isomorphic-fetch": { + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz", + "integrity": "sha512-DaZNUvLDCAnCTjgwxgiL1eQdxIKEpNLOlTNtAgnZc50bG2copGhRrFN9/PxPBuJe+tZVLCbQ7ls0xveXVRPkvw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" } }, - "node_modules/@typescript-eslint/utils": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", - "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/typescript-estree": "7.11.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" + "expect": "^29.0.0", + "pretty-format": "^29.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", - "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.11.0", - "eslint-visitor-keys": "^3.4.3" - }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "BSD-3-Clause" + "license": "MIT" }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "node_modules/@types/jsdom": { + "version": "21.1.6", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.6.tgz", + "integrity": "sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" } }, - "node_modules/acorn-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", - "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-mM4TkDpA9oixqg1Fv2vVpOFyIVLJjm5x4k0V+K/rEsizfjD7Tk7LKk3GTtbB7KCfP0FEHQtsZqFxYA0+sijNVg==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2" + "@types/node": "*" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@types/jssha": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/jssha/-/jssha-2.0.0.tgz", + "integrity": "sha512-oBnY3csYnXfqZXDRBJwP1nDDJCW/+VMJ88UHT4DCy0deSXpJIQvMCwYlnmdW4M+u7PiSfQc44LmiFcUbJ8hLEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "undici-types": "~5.26.4" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "node_modules/@types/opossum": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/opossum/-/opossum-4.1.1.tgz", + "integrity": "sha512-9TMnd8AWRVtnZMqBbbzceQoJdafErgUViogFaQ3eetsbeLtiFFZ695mepNaLtlfJi4uRP3GmHfe3CJ2DZKaxYA==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" + "@types/node": "*" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "16.14.62", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.62.tgz", + "integrity": "sha512-BWf7hqninZav6nerxXj+NeZT/mTpDeG6Lk2zREHAy63CrnXoOGPGtNqTFYFN/sqpSaREDP5otVV88axIXmKfGA==", "dev": true, "license": "MIT", "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" + "@types/prop-types": "*", + "@types/scheduler": "^0.16", + "csstype": "^3.0.2" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/@types/resize-observer-browser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/selenium-webdriver": { + "version": "4.1.19", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.1.19.tgz", + "integrity": "sha512-9/vdyC3KeFQ7/vtt0H5RR0fnlrtc4dF9ssRBnh+yerua9O2Sst4nuPL4eHyKlR1/ZVV/5XPMLaJuVgv+7CDCAw==", "dev": true, "license": "MIT", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@types/ws": "*" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/set-interval-async": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/set-interval-async/-/set-interval-async-1.0.3.tgz", + "integrity": "sha512-sPwjhIU2p8JeaYJPuzfQclyPni3c4Nz7IK4KhvAkMq5O36TsQXeaZ5g3YwiOtE90ja3E4rg7Aja1DcO+eknZbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sshpk": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@types/sshpk/-/sshpk-1.10.3.tgz", + "integrity": "sha512-cru1waDhHZnZuB18E6Dgf2UXf8U93mdOEDcKYe5jTri+fpucidSs7DLmGICpLxN+95aYkwtgeyny9fBFzQVdmA==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@types/node": "*" } }, - "node_modules/anser": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz", - "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==", + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, "license": "MIT" }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@types/tabulator-tables": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-6.2.0.tgz", + "integrity": "sha512-dKEz3X/1SuEBa25RpbPhG4a5mVa+/nL5G4hHDWf+W+Xs6m1HREN9lX2qVhEIoJSeTqfqpvze8Fw5+qbCakH86g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/node": "*" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@types/yargs-parser": "*" } }, - "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==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", + "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/type-utils": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/antlr4-c3": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/antlr4-c3/-/antlr4-c3-3.4.1.tgz", - "integrity": "sha512-YLO/ncwUp8w2GNK/lnsYXtMkd8izHCWjxtk7EaTGIZq07THfvI5aHDuhls/RctX3EYDlM9zeTKdqn54eLYNglQ==", - "license": "MIT", - "dependencies": { - "antlr4ng": "^3.0.1" - } - }, - "node_modules/antlr4ng": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/antlr4ng/-/antlr4ng-3.0.3.tgz", - "integrity": "sha512-LkxS0SADLLZVnSeMIF+ebB5sNAVejpg0LWeEPvI+sGDkmRJdY8MphVEu6/e9J2TNn3nxSP/hr1wERJ0kWC/0Tw==", - "license": "BSD-3-Clause", + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "antlr4ng-cli": "^2.0.0" - } - }, - "node_modules/antlr4ng-cli": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/antlr4ng-cli/-/antlr4ng-cli-2.0.0.tgz", - "integrity": "sha512-oAt5OSSYhRQn1PgahtpAP4Vp3BApCoCqlzX7Q8ZUWWls4hX59ryYuu0t7Hwrnfk796OxP/vgIJaqxdltd/oEvQ==", - "deprecated": "This package is deprecated and will no longer be updated. Please use the new antlr-ng package instead: https://github.com/mike-lischke/antlr-ng", - "license": "BSD-3-Clause", - "bin": { - "antlr4ng": "index.js" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@typescript-eslint/utils": "5.62.0" }, "engines": { - "node": ">= 8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "license": "MIT", "dependencies": { - "default-require-extensions": "^3.0.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=14" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, - "license": "Apache-2.0", + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/array.prototype.filter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz", - "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "node_modules/@typescript-eslint/type-utils": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", + "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "node_modules/@typescript-eslint/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "node_modules/@typescript-eslint/utils": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", + "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, - "node_modules/ast-metadata-inferer": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.1.tgz", - "integrity": "sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "license": "MIT", "dependencies": { - "@mdn/browser-compat-data": "^5.6.19" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", + "@typescript-eslint/types": "7.11.0", + "eslint-visitor-keys": "^3.4.3" + }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, "bin": { - "autoprefixer": "bin/autoprefixer" + "acorn": "bin/acorn" }, "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=0.4.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, - "node_modules/await-semaphore": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/await-semaphore/-/await-semaphore-0.1.3.tgz", - "integrity": "sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, - "license": "MPL-2.0", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, - "node_modules/axobject-query": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.4.tgz", - "integrity": "sha512-aPTElBrbifBU1krmZxGZOlBkslORe7Ll7+BDnI50Wy4LgOt69luMgevkDfTq1O/ZgprooPCtWpjCwKSZw/iZ4A==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "debug": "4" + }, "engines": { - "node": ">= 0.4" + "node": ">= 6.0.0" } }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "@babel/core": "^7.8.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "node_modules/anser": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz", + "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==", + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" + "type-fest": "^0.21.3" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "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": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/babel-plugin-transform-hook-names": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz", - "integrity": "sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==", - "dev": true, + "node_modules/antlr4-c3": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/antlr4-c3/-/antlr4-c3-3.4.1.tgz", + "integrity": "sha512-YLO/ncwUp8w2GNK/lnsYXtMkd8izHCWjxtk7EaTGIZq07THfvI5aHDuhls/RctX3EYDlM9zeTKdqn54eLYNglQ==", "license": "MIT", + "dependencies": { + "antlr4ng": "^3.0.1" + } + }, + "node_modules/antlr4ng": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/antlr4ng/-/antlr4ng-3.0.3.tgz", + "integrity": "sha512-LkxS0SADLLZVnSeMIF+ebB5sNAVejpg0LWeEPvI+sGDkmRJdY8MphVEu6/e9J2TNn3nxSP/hr1wERJ0kWC/0Tw==", + "license": "BSD-3-Clause", "peerDependencies": { - "@babel/core": "^7.12.10" + "antlr4ng-cli": "^2.0.0" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "node_modules/antlr4ng-cli": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/antlr4ng-cli/-/antlr4ng-cli-2.0.0.tgz", + "integrity": "sha512-oAt5OSSYhRQn1PgahtpAP4Vp3BApCoCqlzX7Q8ZUWWls4hX59ryYuu0t7Hwrnfk796OxP/vgIJaqxdltd/oEvQ==", + "deprecated": "This package is deprecated and will no longer be updated. Please use the new antlr-ng package instead: https://github.com/mike-lischke/antlr-ng", + "license": "BSD-3-Clause", + "bin": { + "antlr4ng": "index.js" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@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" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">= 8" } }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "default-require-extensions": "^3.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true, "license": "MIT" }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bignumber.js": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", - "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=14" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true, "license": "MIT" }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "ISC" + "license": "Python-2.0" }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "node_modules/array.prototype.filter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz", + "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-array-method-boxes-properly": "^1.0.0", + "es-object-atoms": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "license": "MIT", "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caching-transform/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caching-transform/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4375,29 +4304,37 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, "license": "MIT", "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, - "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -4406,1418 +4343,1452 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.8" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/ast-metadata-inferer": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.1.tgz", + "integrity": "sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdn/browser-compat-data": "^5.6.19" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.4" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001701", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001701.tgz", - "integrity": "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "funding": [ { "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + "url": "https://tidelift.com/funding/github/npm/autoprefixer" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], - "license": "CC-BY-4.0" + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/await-semaphore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/await-semaphore/-/await-semaphore-0.1.3.tgz", + "integrity": "sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q==", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "license": "MPL-2.0", "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/cheerio": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", - "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "node_modules/axobject-query": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.4.tgz", + "integrity": "sha512-aPTElBrbifBU1krmZxGZOlBkslORe7Ll7+BDnI50Wy4LgOt69luMgevkDfTq1O/ZgprooPCtWpjCwKSZw/iZ4A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", "dependencies": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.1", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/cheerio/node_modules/parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "@types/node": "*" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, "engines": { "node": ">=8" } }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, - "license": "MIT" - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/babel-plugin-transform-hook-names": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz", + "integrity": "sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "peerDependencies": { + "@babel/core": "^7.12.10" } }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/collect-v8-coverage": { + "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" + "tweetnacl": "^0.14.3" } }, - "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==", + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "dev": true, "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": "*" } }, - "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==", + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "balanced-match": "^1.0.0" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "fill-range": "^7.1.1" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, "engines": { - "node": ">= 10" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.0.0" + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" } }, - "node_modules/commondir": { + "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, "license": "MIT" }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "node_modules/caching-transform/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, - "bin": { - "create-jest": "bin/create-jest.js" + "engines": { + "node": ">= 0.4" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" } }, - "node_modules/css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, - "license": "BSD-like", + "license": "MIT", "dependencies": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/cssfontparser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", - "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "node_modules/caniuse-lite": { + "version": "1.0.30001703", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz", + "integrity": "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "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": { - "cssom": "~0.3.6" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=10" + } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "node_modules/cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", "dev": true, - "license": "MIT" - }, - "node_modules/d3": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", - "integrity": "sha512-q2WHStdhiBtD8DMmhDPyJmXUxr6VWRngKyiJ5EfXMxPw+tqT6BhNjhJZ4w3BHsNm3QoVfZLY8Orq/qPFczwKRA==", - "license": "ISC", + "license": "MIT", "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" }, "engines": { - "node": ">=12" + "node": ">= 0.6" } }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "license": "ISC", + "node_modules/cheerio/node_modules/parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "license": "MIT", "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" + "@types/node": "*" } }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "license": "ISC", + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - }, - "engines": { - "node": ">=12" - } + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "license": "ISC", - "dependencies": { - "d3-path": "1 - 3" - }, - "engines": { - "node": ">=12" - } + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "license": "ISC", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "license": "ISC", "dependencies": { - "d3-array": "^3.2.0" - }, - "engines": { - "node": ">=12" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "license": "ISC", - "dependencies": { - "delaunator": "5" - }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "license": "ISC", - "engines": { - "node": ">=12" - } + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "license": "ISC", + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" }, "engines": { - "node": ">=12" + "node": ">=12.5.0" } }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "license": "ISC", + "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": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" + "color-name": "~1.1.4" }, "engines": { - "node": ">=12" + "node": ">=7.0.0" } }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12" - } + "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/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "license": "ISC", + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", "dependencies": { - "d3-dsv": "1 - 3" - }, - "engines": { - "node": ">=12" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "license": "ISC", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "license": "ISC", + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 10" } }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "license": "ISC", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 12.0.0" } }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "license": "ISC", - "engines": { - "node": ">=12" - } + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "license": "ISC", - "engines": { - "node": ">=12" - } + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "license": "ISC", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "license": "ISC", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "license": "ISC", + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "license": "BSD-like", "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" } }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "license": "ISC", + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=12" + "node": "*" } }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">=12" + "node": ">=4" } }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "license": "ISC", + "node_modules/cssfontparser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", + "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-array": "2 - 3" + "cssom": "~0.3.6" }, "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", + "integrity": "sha512-q2WHStdhiBtD8DMmhDPyJmXUxr6VWRngKyiJ5EfXMxPw+tqT6BhNjhJZ4w3BHsNm3QoVfZLY8Orq/qPFczwKRA==", "license": "ISC", "dependencies": { - "d3-time": "1 - 3" + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" }, "engines": { "node": ">=12" } }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, "engines": { "node": ">=12" } }, - "node_modules/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", "license": "ISC", - "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, "engines": { "node": ">=12" - }, - "peerDependencies": { - "d3-selection": "2 - 3" } }, - "node_modules/d3-zoom": { + "node_modules/d3-brush": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" + "d3-selection": "3", + "d3-transition": "3" }, "engines": { "node": ">=12" } }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, - "license": "MIT", + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "d3-path": "1 - 3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" + "node": ">=12" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "d3-array": "^3.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dateformat": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.2.tgz", - "integrity": "sha512-EelsCzH0gMC2YmXuMeaZ3c6md1sUJQxyb1XXc4xaisi/K6qKukqZhKPrEQyRkdNIncgYyLoDTReq0nNyuKerTg==", - "dev": true, - "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, - "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==", - "dev": true, - "license": "MIT", + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", "dependencies": { - "ms": "^2.1.3" + "delaunator": "5" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=12" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } + "engines": { + "node": ">=12" } }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "license": "MIT", + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" }, - "engines": { - "node": ">= 0.4" + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=12" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/default-require-extensions": { + "node_modules/d3-fetch": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", "dependencies": { - "strip-bom": "^4.0.0" + "d3-dsv": "1 - 3" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "license": "ISC", "dependencies": { - "robust-predicates": "^3.0.2" + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "dev": true, - "license": "Apache-2.0", + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, "engines": { - "node": ">=0.10" + "node": ">=12" } }, - "node_modules/detect-newline": { + "node_modules/d3-path": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", "engines": { - "node": ">=0.3.1" + "node": ">=12" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/dir-glob": { + "node_modules/d3-random": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", "dependencies": { - "path-type": "^4.0.0" + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", - "dev": true, - "license": "MIT" + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/doctrine": { + "node_modules/d3-selection": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { - "esutils": "^2.0.2" + "d3-path": "^3.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", - "dev": true, - "license": "MIT" + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dev": true, - "license": "MIT", + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true, - "license": "BSD-2-Clause" + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "deprecated": "Use your platform's native DOMException instead", - "dev": true, - "license": "MIT", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { - "webidl-conversions": "^7.0.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "domelementtype": "1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } + "license": "BSD-2-Clause" }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", "dev": true, "license": "MIT", "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.109", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.109.tgz", - "integrity": "sha512-AidaH9JETVRr9DIPGfp1kAarm/W6hRJTPuCnkF+2MqhF4KaAgRIcBc8nvjk+YMXZhwfISof/7WG29eS4iGxQLQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/enzyme": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", - "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "array.prototype.flat": "^1.2.3", - "cheerio": "^1.0.0-rc.3", - "enzyme-shallow-equal": "^1.0.1", - "function.prototype.name": "^1.1.2", - "has": "^1.0.3", - "html-element-map": "^1.2.0", - "is-boolean-object": "^1.0.1", - "is-callable": "^1.1.5", - "is-number-object": "^1.0.4", - "is-regex": "^1.0.5", - "is-string": "^1.0.5", - "is-subset": "^0.1.1", - "lodash.escape": "^4.0.1", - "lodash.isequal": "^4.5.0", - "object-inspect": "^1.7.0", - "object-is": "^1.0.2", - "object.assign": "^4.1.0", - "object.entries": "^1.1.1", - "object.values": "^1.1.1", - "raf": "^3.4.1", - "rst-selector-parser": "^2.2.3", - "string.prototype.trim": "^1.2.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/enzyme-adapter-preact-pure": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enzyme-adapter-preact-pure/-/enzyme-adapter-preact-pure-4.1.0.tgz", - "integrity": "sha512-SifzvBGf1qUEs0FfCAOiKgDppb1wg/R+rmX8D7jFVpQ/Q2L3/xuyc1V575zoi8QAhIBDUB/8QUWvI4KZc50trw==", + "node_modules/dateformat": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.2.tgz", + "integrity": "sha512-EelsCzH0gMC2YmXuMeaZ3c6md1sUJQxyb1XXc4xaisi/K6qKukqZhKPrEQyRkdNIncgYyLoDTReq0nNyuKerTg==", "dev": true, "license": "MIT", - "peerDependencies": { - "enzyme": "^3.11.0", - "preact": "^10.0.0" + "engines": { + "node": "*" } }, - "node_modules/enzyme-shallow-equal": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz", - "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0", - "object-is": "^1.1.5" + "ms": "^2.1.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/enzyme-to-json": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz", - "integrity": "sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==", + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "license": "MIT", - "dependencies": { - "@types/cheerio": "^0.22.22", - "lodash": "^4.17.21", - "react-is": "^16.12.0" - }, "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "enzyme": "^3.4.0" + "node": ">=0.10.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } } }, - "node_modules/es-abstract": { - "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.0", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-regex": "^1.2.1", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.3", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -5826,553 +5797,639 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, "license": "MIT", + "dependencies": { + "strip-bom": "^4.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-iterator-helpers": { + "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.4", - "safe-array-concat": "^1.1.3" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "node_modules/discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } }, - "node_modules/es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "node_modules/electron-to-chromium": { + "version": "1.5.114", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz", + "integrity": "sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/esbuild": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz", - "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, "engines": { "node": ">=12" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.15.18", - "@esbuild/linux-loong64": "0.15.18", - "esbuild-android-64": "0.15.18", - "esbuild-android-arm64": "0.15.18", - "esbuild-darwin-64": "0.15.18", - "esbuild-darwin-arm64": "0.15.18", - "esbuild-freebsd-64": "0.15.18", - "esbuild-freebsd-arm64": "0.15.18", - "esbuild-linux-32": "0.15.18", - "esbuild-linux-64": "0.15.18", - "esbuild-linux-arm": "0.15.18", - "esbuild-linux-arm64": "0.15.18", - "esbuild-linux-mips64le": "0.15.18", - "esbuild-linux-ppc64le": "0.15.18", - "esbuild-linux-riscv64": "0.15.18", - "esbuild-linux-s390x": "0.15.18", - "esbuild-netbsd-64": "0.15.18", - "esbuild-openbsd-64": "0.15.18", - "esbuild-sunos-64": "0.15.18", - "esbuild-windows-32": "0.15.18", - "esbuild-windows-64": "0.15.18", - "esbuild-windows-arm64": "0.15.18" - } - }, - "node_modules/esbuild-android-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", - "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/esbuild-android-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", - "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", - "cpu": [ - "arm64" - ], + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild-darwin-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", - "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", - "cpu": [ - "x64" - ], + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/enzyme": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", + "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "array.prototype.flat": "^1.2.3", + "cheerio": "^1.0.0-rc.3", + "enzyme-shallow-equal": "^1.0.1", + "function.prototype.name": "^1.1.2", + "has": "^1.0.3", + "html-element-map": "^1.2.0", + "is-boolean-object": "^1.0.1", + "is-callable": "^1.1.5", + "is-number-object": "^1.0.4", + "is-regex": "^1.0.5", + "is-string": "^1.0.5", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.7.0", + "object-is": "^1.0.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1", + "object.values": "^1.1.1", + "raf": "^3.4.1", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.2.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", - "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", - "cpu": [ - "arm64" - ], + "node_modules/enzyme-adapter-preact-pure": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-preact-pure/-/enzyme-adapter-preact-pure-4.1.0.tgz", + "integrity": "sha512-SifzvBGf1qUEs0FfCAOiKgDppb1wg/R+rmX8D7jFVpQ/Q2L3/xuyc1V575zoi8QAhIBDUB/8QUWvI4KZc50trw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" + "peerDependencies": { + "enzyme": "^3.11.0", + "preact": "^10.0.0" } }, - "node_modules/esbuild-freebsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", - "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", - "cpu": [ - "x64" - ], + "node_modules/enzyme-shallow-equal": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz", + "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "hasown": "^2.0.0", + "object-is": "^1.1.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", - "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", - "cpu": [ - "arm64" - ], + "node_modules/enzyme-to-json": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz", + "integrity": "sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, + "dependencies": { + "@types/cheerio": "^0.22.22", + "lodash": "^4.17.21", + "react-is": "^16.12.0" + }, "engines": { - "node": ">=12" + "node": ">=6.0.0" + }, + "peerDependencies": { + "enzyme": "^3.4.0" } }, - "node_modules/esbuild-linux-32": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", - "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", - "cpu": [ - "ia32" - ], + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/esbuild-linux-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", - "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", - "cpu": [ - "x64" - ], + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-linux-arm": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", - "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", - "cpu": [ - "arm" - ], + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild-linux-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", - "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", - "cpu": [ - "arm64" - ], + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", - "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", - "cpu": [ - "mips64el" - ], + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", - "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", - "cpu": [ - "ppc64" - ], + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", - "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", - "cpu": [ - "riscv64" - ], + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-linux-s390x": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", - "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", - "cpu": [ - "s390x" - ], + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "dependencies": { + "es-errors": "^1.3.0" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-netbsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", - "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", - "cpu": [ - "x64" - ], + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-openbsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", - "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", - "cpu": [ - "x64" - ], + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, + "dependencies": { + "hasown": "^2.0.2" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-sunos-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", - "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", - "cpu": [ - "x64" - ], + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "peer": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-windows-32": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", - "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", - "cpu": [ - "ia32" - ], + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild-windows-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", - "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", - "cpu": [ - "x64" - ], + "node_modules/es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild-windows-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", - "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", - "cpu": [ - "arm64" - ], + "node_modules/esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/escalade": { @@ -10938,9 +10995,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz", + "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", "dev": true, "funding": [ { @@ -11245,9 +11302,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", - "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "version": "2.2.18", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", + "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", "dev": true, "license": "MIT" }, @@ -12514,9 +12571,9 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", - "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", + "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "license": "MIT", "dependencies": { @@ -12530,25 +12587,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.9", - "@rollup/rollup-android-arm64": "4.34.9", - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-freebsd-arm64": "4.34.9", - "@rollup/rollup-freebsd-x64": "4.34.9", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", - "@rollup/rollup-linux-arm-musleabihf": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", - "@rollup/rollup-linux-riscv64-gnu": "4.34.9", - "@rollup/rollup-linux-s390x-gnu": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-ia32-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9", + "@rollup/rollup-android-arm-eabi": "4.35.0", + "@rollup/rollup-android-arm64": "4.35.0", + "@rollup/rollup-darwin-arm64": "4.35.0", + "@rollup/rollup-darwin-x64": "4.35.0", + "@rollup/rollup-freebsd-arm64": "4.35.0", + "@rollup/rollup-freebsd-x64": "4.35.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", + "@rollup/rollup-linux-arm-musleabihf": "4.35.0", + "@rollup/rollup-linux-arm64-gnu": "4.35.0", + "@rollup/rollup-linux-arm64-musl": "4.35.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", + "@rollup/rollup-linux-riscv64-gnu": "4.35.0", + "@rollup/rollup-linux-s390x-gnu": "4.35.0", + "@rollup/rollup-linux-x64-gnu": "4.35.0", + "@rollup/rollup-linux-x64-musl": "4.35.0", + "@rollup/rollup-win32-arm64-msvc": "4.35.0", + "@rollup/rollup-win32-ia32-msvc": "4.35.0", + "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" } }, @@ -14689,16 +14746,17 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, diff --git a/gui/frontend/package.json b/gui/frontend/package.json index bfa045c49..77dce2a8e 100644 --- a/gui/frontend/package.json +++ b/gui/frontend/package.json @@ -1,6 +1,6 @@ { "name": "mysql-shell-gui", - "version": "1.19.12", + "version": "1.19.13", "publisher": "Oracle", "type": "module", "scripts": { diff --git a/gui/frontend/src/app-logic/App.tsx b/gui/frontend/src/app-logic/App.tsx index 4215899a1..757b43bfd 100644 --- a/gui/frontend/src/app-logic/App.tsx +++ b/gui/frontend/src/app-logic/App.tsx @@ -25,40 +25,43 @@ import "./App.css"; -import { Component, VNode, createRef } from "preact"; - -import { LoginPage } from "../components/Login/LoginPage.js"; -import { IThemeChangeData } from "../components/Theming/ThemeManager.js"; -import { TooltipProvider } from "../components/ui/Tooltip/Tooltip.js"; -import { requisitions } from "../supplement/Requisitions.js"; -import { appParameters } from "../supplement/AppParameters.js"; -import { ShellInterface } from "../supplement/ShellInterface/ShellInterface.js"; -import { RunMode, webSession } from "../supplement/WebSession.js"; -import { ApplicationHost } from "./ApplicationHost.js"; -import { ErrorBoundary } from "./ErrorBoundary.js"; -import { ProfileSelector } from "./ProfileSelector.js"; +import { Component, createRef, VNode } from "preact"; import type { IDisposable } from "monaco-editor"; import { StandaloneServices } from "monaco-editor/esm/vs/editor/standalone/browser/standaloneServices.js"; import { IStandaloneThemeService } from "monaco-editor/esm/vs/editor/standalone/common/standaloneTheme.js"; + import { MessageScheduler } from "../communication/MessageScheduler.js"; import { IShellProfile } from "../communication/ProtocolGui.js"; import { PasswordDialog } from "../components/Dialogs/PasswordDialog.js"; +import { LoginPage } from "../components/Login/LoginPage.js"; +import { IThemeChangeData, ThemeManager } from "../components/Theming/ThemeManager.js"; +import { CodeEditorSetup } from "../components/ui/CodeEditor/CodeEditorSetup.js"; import { IComponentState } from "../components/ui/Component/ComponentBase.js"; import { NotificationCenter, NotificationType } from "../components/ui/NotificationCenter/NotificationCenter.js"; -import { ProgressIndicator } from "../components/ui/ProgressIndicator/ProgressIndicator.js"; +import { renderStatusBar, StatusBar } from "../components/ui/Statusbar/Statusbar.js"; import type { - IStatusBarItem, IStatusBarItemOptions, StatusBarAlignment, + IStatusBarItem, IStatusBarItemOptions, + StatusBarAlignment, } from "../components/ui/Statusbar/StatusBarItem.js"; -import { StatusBar, renderStatusBar } from "../components/ui/Statusbar/Statusbar.js"; +import { TooltipProvider } from "../components/ui/Tooltip/Tooltip.js"; +import { appParameters } from "../supplement/AppParameters.js"; +import { requisitions } from "../supplement/Requisitions.js"; import { Settings } from "../supplement/Settings/Settings.js"; +import { ShellInterface } from "../supplement/ShellInterface/ShellInterface.js"; +import { RunMode, webSession } from "../supplement/WebSession.js"; import { versionMatchesExpected } from "../utilities/helpers.js"; import { ApplicationDB } from "./ApplicationDB.js"; import { DialogHost } from "./DialogHost.js"; -import { registerUiLayer, ui, type MessageOptions, type Thenable } from "./UILayer.js"; +import { ErrorBoundary } from "./ErrorBoundary.js"; import { - DialogResponseClosure, DialogType, IDialogResponse, minimumShellVersion, type IServicePasswordRequest, + DialogResponseClosure, DialogType, IDialogResponse, minimumShellVersion, type IDialogRequest, + type IServicePasswordRequest, } from "./general-types.js"; +import { LazyAppRouter, LoadingIndicator } from "./LazyAppRouter.js"; +import { registerUiLayer, ui, type MessageOptions, type Thenable } from "./UILayer.js"; + +void CodeEditorSetup.init(); interface IAppState extends IComponentState { explorerIsVisible: boolean; @@ -70,10 +73,10 @@ interface IAppState extends IComponentState { export class App extends Component<{}, IAppState> { - private actionMenuRef = createRef(); private passwordDialogRef = createRef(); private defaultProfile?: IShellProfile; + private themeManager = ThemeManager.get; #notificationCenterRef = createRef(); @@ -88,6 +91,7 @@ export class App extends Component<{}, IAppState> { loginInProgress: true, showOptions: false, }; + requisitions.register("hostThemeChange", this.themeManager.hostThemeChange); // Register early to ensure this handler is called last. requisitions.register("dialogResponse", this.dialogResponse); @@ -185,10 +189,9 @@ export class App extends Component<{}, IAppState> { MessageScheduler.get.disconnect(); void ApplicationDB.cleanUp(); - requisitions.unregister("statusBarButtonClick", this.statusBarButtonClick); requisitions.unregister("themeChanged", this.themeChanged); requisitions.unregister("dialogResponse", this.dialogResponse); - + requisitions.unregister("hostThemeChange", this.themeManager.hostThemeChange); }); // The Monaco Editor includes a font (codicon.ttf). @@ -196,7 +199,6 @@ export class App extends Component<{}, IAppState> { // is dynamically injected into the document by JavaScript via a style.monaco-colors element. // This injection only occurs if an Editor instance is created. // We require the icons to be available on pages even without an editor instance. - // The only reason why it works in standalone is that CommunicationDebugger renders CodeEditor. const themeService = StandaloneServices.get(IStandaloneThemeService); themeService.registerEditorContainer(document.createElement("div")); } @@ -224,7 +226,6 @@ export class App extends Component<{}, IAppState> { `.msg.resultHost .resultView .tabulator { font-size: ${editorFontSize}; }`; document.head.appendChild(style); - requisitions.register("statusBarButtonClick", this.statusBarButtonClick); requisitions.register("themeChanged", this.themeChanged); } @@ -235,16 +236,12 @@ export class App extends Component<{}, IAppState> { if (loginInProgress) { const connectionToken = appParameters.get("token") ?? ""; if (connectionToken.length > 0) { - content = ; + content = LoadingIndicator; } else { content = ; } } else { - content = ; + content = ; } return ( @@ -254,11 +251,11 @@ export class App extends Component<{}, IAppState> { + - {!appParameters.embedded && ( + {!appParameters.hideStatusBar && ( <> {renderStatusBar()} - )} @@ -267,8 +264,8 @@ export class App extends Component<{}, IAppState> { // IUILayer interface implementation - public showInformationMessage = (message: string, _options: MessageOptions, - ..._items: T[]): Thenable => { + public showInformationMessage = (message: string, options: MessageOptions, + ...items: T[]): Thenable => { // Forward info messages to the hosting application. if (appParameters.embedded) { const result = requisitions.executeRemote("showInfo", message); @@ -277,11 +274,31 @@ export class App extends Component<{}, IAppState> { } } - if (this.#notificationCenterRef.current) { - return this.#notificationCenterRef.current.showNotification({ - type: NotificationType.Information, - text: message, - }); + const accept = items.shift(); + const refuse = items.shift(); + const alternative = items.shift(); + if (options?.modal) { + const request: IDialogRequest = { + id: "uiInformationMessage", + type: DialogType.Confirm, + description: options?.detail ? [options.detail] : undefined, + parameters: { + title: options?.title ?? "Information", + prompt: message, + accept, + refuse, + alternative, + }, + }; + + void requisitions.execute("showDialog", request); + } else { + if (this.#notificationCenterRef.current) { + return this.#notificationCenterRef.current.showNotification({ + type: NotificationType.Information, + text: message, + }); + } } return Promise.resolve(undefined); @@ -389,28 +406,12 @@ export class App extends Component<{}, IAppState> { // End of UILayer interface implementation - private statusBarButtonClick = (values: { type: string; event: MouseEvent | KeyboardEvent; }): Promise => { - if (values.type === "openPopupMenu") { - const target = values.event.target as HTMLElement; - this.actionMenuRef.current?.open(target.getBoundingClientRect()); - - return Promise.resolve(true); - } - - return Promise.resolve(false); - }; - private themeChanged = (values: IThemeChangeData): Promise => { requisitions.executeRemote("themeChanged", values); return Promise.resolve(true); }; - private toggleOptions = (): void => { - const { showOptions } = this.state; - this.setState({ showOptions: !showOptions }); - }; - private dialogResponse = (response: IDialogResponse): Promise => { if (appParameters.embedded) { // Forward all dialog responses. diff --git a/gui/frontend/src/app-logic/ApplicationHost.tsx b/gui/frontend/src/app-logic/ApplicationHost.tsx index cc8e27cd5..770edfff6 100644 --- a/gui/frontend/src/app-logic/ApplicationHost.tsx +++ b/gui/frontend/src/app-logic/ApplicationHost.tsx @@ -25,35 +25,38 @@ import { ComponentChild } from "preact"; - -import { requisitions } from "../supplement/Requisitions.js"; -import { appParameters } from "../supplement/AppParameters.js"; -import { RunMode, webSession } from "../supplement/WebSession.js"; +import { lazy, Suspense } from "preact/compat"; import { SettingsEditor } from "../components/SettingsEditor/SettingsEditor.js"; -import { DialogHost } from "./DialogHost.js"; - -import { CommunicationDebugger } from "../components/CommunicationDebugger/CommunicationDebugger.js"; +import { AboutBox } from "../components/ui/AboutBox/AboutBox.js"; import { ComponentBase, type IComponentProperties } from "../components/ui/Component/ComponentBase.js"; import { Container, Orientation } from "../components/ui/Container/Container.js"; -import { SplitContainer, type ISplitterPaneSizeInfo } from "../components/ui/SplitContainer/SplitContainer.js"; +import { ISplitterPane, SplitContainer, + type ISplitterPaneSizeInfo } from "../components/ui/SplitContainer/SplitContainer.js"; import { StatusBarAlignment, type IStatusBarItem } from "../components/ui/Statusbar/StatusBarItem.js"; import { DocumentModule } from "../modules/db-editor/DocumentModule.js"; +import { appParameters } from "../supplement/AppParameters.js"; +import { requisitions } from "../supplement/Requisitions.js"; +import { RunMode, webSession } from "../supplement/WebSession.js"; +import { LoadingIndicator } from "./LazyAppRouter.js"; import { ui } from "./UILayer.js"; -import { AboutBox } from "../components/ui/AboutBox/AboutBox.js"; -interface IApplicationHostProperties extends IComponentProperties { - toggleOptions: () => void; -} +// eslint-disable-next-line @typescript-eslint/naming-convention +const CommunicationDebugger = lazy(async () => { + return import("../components/CommunicationDebugger/CommunicationDebugger.js"); +}); + +interface IApplicationHostProperties extends IComponentProperties {} interface IApplicationHostState { settingsVisible: boolean; aboutVisible: boolean; debuggerVisible: boolean; debuggerMaximized: boolean; + debuggerEnabledInBackground: boolean; } -export class ApplicationHost extends ComponentBase { +export default class ApplicationHost extends ComponentBase { private lastEmbeddedDebuggerSplitPosition = 500; private optionsStatusItem?: IStatusBarItem; @@ -70,6 +73,7 @@ export class ApplicationHost extends ComponentBase + + + ), + minSize: debuggerVisible && !debuggerMaximized ? 200 : 0, + initialSize: !debuggerVisible ? 0 : undefined, + snap: true, + resizable: debuggerVisible && !debuggerMaximized, + stretch: debuggerVisible && debuggerMaximized, + }); + } content = [ , - minSize: debuggerVisible && !debuggerMaximized ? 200 : 0, - initialSize: !debuggerVisible ? 0 : undefined, - snap: true, - resizable: debuggerVisible && !debuggerMaximized, - stretch: debuggerVisible && debuggerMaximized, - }, - ]} + panes={panes} onPaneResized={this.embeddedDebuggerSplitterResize} />]; } @@ -163,7 +173,6 @@ export class ApplicationHost extends ComponentBase {content} - ); } @@ -203,7 +212,12 @@ export class ApplicationHost extends ComponentBase { + data?: IDictionary): Promise => { const type = data?.type as DialogType ?? DialogType.Prompt; const element = this.#focusedElements.pop(); @@ -442,6 +442,8 @@ export class DialogHost extends ComponentBase { if (element instanceof HTMLTextAreaElement || element instanceof HTMLInputElement) { element.focus(); } + + return Promise.resolve(); }; private handleDialogClose = (type: MdsDialogType, closure: DialogResponseClosure, data?: IDictionary): void => { diff --git a/gui/frontend/src/components/ui/SessionTile/SessionTile.tsx b/gui/frontend/src/app-logic/LazyAppRouter.tsx similarity index 50% rename from gui/frontend/src/components/ui/SessionTile/SessionTile.tsx rename to gui/frontend/src/app-logic/LazyAppRouter.tsx index 75f1d2856..e39e8c28f 100644 --- a/gui/frontend/src/components/ui/SessionTile/SessionTile.tsx +++ b/gui/frontend/src/app-logic/LazyAppRouter.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. + * Copyright (c) 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -22,50 +22,39 @@ * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -import "./SessionTile.css"; - -import { ComponentChild } from "preact"; - -import { Assets } from "../../../supplement/Assets.js"; -import { IShellSessionDetails } from "../../../supplement/ShellInterface/index.js"; -import { BrowserTile, IBrowserTileProperties } from "../BrowserTile/BrowserTile.js"; -import { Icon } from "../Icon/Icon.js"; - -export interface ISessionTileProperties extends IBrowserTileProperties { - details: IShellSessionDetails; -} - -export class SessionTile extends BrowserTile { - - public static override defaultProps = { - className: "sessionTile", - }; - - public constructor(props: ISessionTileProperties) { - super(props); - - this.addHandledProperties("details"); +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Component, ComponentChild, ComponentType } from "preact"; +import { lazy, Suspense } from "preact/compat"; + +import { ProgressIndicator } from "../components/ui/ProgressIndicator/ProgressIndicator.js"; +import { appParameters } from "../supplement/AppParameters.js"; + +const ApplicationHost = lazy(async () => { + return import("./ApplicationHost.js"); +}); + +export const LoadingIndicator = ( + +); + +let Root: ComponentType; +switch (appParameters.subApp) { + default: { + Root = ApplicationHost; + break; } +} +export class LazyAppRouter extends Component { public override render(): ComponentChild { - return super.render(); - } - - protected renderTileActionUI = (): ComponentChild => { return ( - + + + ); - }; - - private handleActionClick = (e: MouseEvent | KeyboardEvent): void => { - const { onAction } = this.props; - - e.stopPropagation(); - onAction?.("remove", this.props, {}); - }; - + } } diff --git a/gui/frontend/src/app-logic/ProfileSelector.tsx b/gui/frontend/src/app-logic/ProfileSelector.tsx index e6b4a999e..c0cf112e6 100644 --- a/gui/frontend/src/app-logic/ProfileSelector.tsx +++ b/gui/frontend/src/app-logic/ProfileSelector.tsx @@ -348,7 +348,8 @@ export class ProfileSelector extends ComponentBase<{}, IProfileSelectorState> { return result; }; - private handleProfileChanges = (closure: DialogResponseClosure, values: IDialogValues, payload: unknown): void => { + private handleProfileChanges = (closure: DialogResponseClosure, values: IDialogValues, + payload: unknown): Promise => { if (closure === DialogResponseClosure.Accept) { const details = payload as { saveProfile: boolean; section: string; }; @@ -418,6 +419,8 @@ export class ProfileSelector extends ComponentBase<{}, IProfileSelectorState> { } } } + + return Promise.resolve(); }; private updateProfile = async (profileToEdit: IShellProfile, setDefault: boolean): Promise => { diff --git a/gui/frontend/src/app-logic/UILayer.ts b/gui/frontend/src/app-logic/UILayer.ts index 7ebb8c877..88d5fbd81 100644 --- a/gui/frontend/src/app-logic/UILayer.ts +++ b/gui/frontend/src/app-logic/UILayer.ts @@ -36,7 +36,6 @@ import type { IServicePasswordRequest } from "./general-types.js"; */ // eslint-disable-next-line @typescript-eslint/naming-convention export interface MessageOptions { - /** Indicates that this message should be modal. */ modal?: boolean; @@ -45,6 +44,11 @@ export interface MessageOptions { * is only shown for {@link MessageOptions.modal modal} messages. */ detail?: string; + + /** + * An optional string as title for the message. This is used only for {@link MessageOptions.modal modal} messages. + */ + title?: string; } /** @@ -119,8 +123,10 @@ export interface IUILayer { /** * Asks the user for a yes/no decision. Returns the yes/no string, depending on what the user clicked or * undefined if the user clicked outside/cancelled the dialog (e.g. pressed ). + * Note: in the extension there's always a "cancel" button. Don't specify a "no" button if you want to + * to avoid an additional button. */ - confirm(message: string, yes: string, no: string, extra?: string): Promise; + confirm(message: string, yes: string, no?: string, extra?: string): Promise; /** * Triggers a password request. diff --git a/gui/frontend/src/app-logic/general-types.ts b/gui/frontend/src/app-logic/general-types.ts index c532761d9..6dab2c85d 100644 --- a/gui/frontend/src/app-logic/general-types.ts +++ b/gui/frontend/src/app-logic/general-types.ts @@ -274,6 +274,7 @@ export enum MessageType { Text, Response, Success, + Log, } /** Details for a status message, usually used in result view status bars. */ diff --git a/gui/frontend/src/communication/ProtocolGui.ts b/gui/frontend/src/communication/ProtocolGui.ts index 840069141..85c543e6c 100644 --- a/gui/frontend/src/communication/ProtocolGui.ts +++ b/gui/frontend/src/communication/ProtocolGui.ts @@ -90,6 +90,10 @@ export enum ShellAPIGui { GuiDbConnectionsListFolderPaths = "gui.dbConnections.list_folder_paths", /** Lists all connections and folder paths for the given profile and folder */ GuiDbConnectionsListAll = "gui.dbConnections.list_all", + /** Rename a folder path */ + GuiDbConnectionsUpdateFolderSettings = "gui.dbConnections.update_folder_settings", + /** Get folder */ + GuiDbConnectionsGetFolder = "gui.dbConnections.get_folder", /** Indicates whether this module is a GUI backend module */ GuiMdsIsGuiModuleBackend = "gui.mds.is_gui_module_backend", /** Returns display information about the module */ @@ -321,13 +325,15 @@ export interface IProtocolGuiParameters { [ShellAPIGui.GuiDbConnectionsListCredentials]: {}; [ShellAPIGui.GuiDbConnectionsTestConnection]: { args: { connection: IShellDbConnection | number; password?: string; }; }; [ShellAPIGui.GuiDbConnectionsMoveConnection]: { args: { profileId: number; folderId: number; connectionIdToMove: number; connectionIdOffset: number; before?: boolean; }; }; - [ShellAPIGui.GuiDbConnectionsAddFolderPath]: { args: { profileId: number; caption: string; parentFolderId?: number; }; }; + [ShellAPIGui.GuiDbConnectionsAddFolderPath]: { args: { profileId: number; caption: string; settings: { color: string; }; parentFolderId?: number; }; }; [ShellAPIGui.GuiDbConnectionsRemoveFolderPath]: { args: { folderPathId: number; }; }; [ShellAPIGui.GuiDbConnectionsRemoveEmptyFolders]: {}; [ShellAPIGui.GuiDbConnectionsRenameFolderPath]: { args: { folderPathId: number; newCaption: string; }; }; [ShellAPIGui.GuiDbConnectionsMoveFolder]: { args: { folderPathId: number; newParentFolderId: number; }; }; [ShellAPIGui.GuiDbConnectionsListFolderPaths]: { args: { parentFolderId?: number; recursive?: boolean; }; }; [ShellAPIGui.GuiDbConnectionsListAll]: { args: { profileId: number; folderId?: number; }; }; + [ShellAPIGui.GuiDbConnectionsUpdateFolderSettings]: { args: { folderPathId: number; newSettings: { color: string; }; }; }; + [ShellAPIGui.GuiDbConnectionsGetFolder]: { args: { folderPathId: number; }; }; [ShellAPIGui.GuiMdsIsGuiModuleBackend]: {}; [ShellAPIGui.GuiMdsGetGuiModuleDisplayInfo]: {}; [ShellAPIGui.GuiModelerIsGuiModuleBackend]: {}; @@ -772,6 +778,8 @@ export interface IProtocolGuiResults { [ShellAPIGui.GuiDbConnectionsMoveFolder]: {}; [ShellAPIGui.GuiDbConnectionsListFolderPaths]: { result: IFolderPath[]; }; [ShellAPIGui.GuiDbConnectionsListAll]: { result: Array; }; + [ShellAPIGui.GuiDbConnectionsUpdateFolderSettings]: {}; + [ShellAPIGui.GuiDbConnectionsGetFolder]: { result: IFolderPath; }; [ShellAPIGui.GuiMdsIsGuiModuleBackend]: {}; [ShellAPIGui.GuiMdsGetGuiModuleDisplayInfo]: {}; [ShellAPIGui.GuiModelerIsGuiModuleBackend]: {}; diff --git a/gui/frontend/src/components/CommunicationDebugger/CommunicationDebugger.tsx b/gui/frontend/src/components/CommunicationDebugger/CommunicationDebugger.tsx index 6ab1669bf..962b8ce6c 100644 --- a/gui/frontend/src/components/CommunicationDebugger/CommunicationDebugger.tsx +++ b/gui/frontend/src/components/CommunicationDebugger/CommunicationDebugger.tsx @@ -93,7 +93,7 @@ interface ICommunicationDebuggerState extends IComponentState { scriptTabs: ITabviewPage[]; } -export class CommunicationDebugger +export default class CommunicationDebugger extends ComponentBase { private environment: CommunicationDebuggerEnvironment; diff --git a/gui/frontend/src/components/Dialogs/AwaitableValueEditDialog.tsx b/gui/frontend/src/components/Dialogs/AwaitableValueEditDialog.tsx index 08de6ef60..55405cf70 100644 --- a/gui/frontend/src/components/Dialogs/AwaitableValueEditDialog.tsx +++ b/gui/frontend/src/components/Dialogs/AwaitableValueEditDialog.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -99,7 +99,9 @@ export class AwaitableValueEditDialog extends ComponentBase { return { messages: {} }; }; - private handleCloseDialog = (closure: DialogResponseClosure, values: IDialogValues): void => { + private handleCloseDialog = (closure: DialogResponseClosure, values: IDialogValues): Promise => { this.#signal?.notify({ closure, values }); + + return Promise.resolve(); }; } diff --git a/gui/frontend/src/components/Dialogs/ConfirmDialog.tsx b/gui/frontend/src/components/Dialogs/ConfirmDialog.tsx index d4e75e170..251cd6ebf 100644 --- a/gui/frontend/src/components/Dialogs/ConfirmDialog.tsx +++ b/gui/frontend/src/components/Dialogs/ConfirmDialog.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -36,11 +36,12 @@ import { Icon } from "../ui/Icon/Icon.js"; import { Label } from "../ui/Label/Label.js"; import { Button } from "../ui/Button/Button.js"; -interface IConfirmDialogButtons { - accept?: string; // Default: "Yes". - refuse?: string; // Default: "No". - alternative?: string; // Default: nothing. - default?: string; // Default: nothing. +/** Possible buttons to show. Only fields with a value also show a button. */ +export interface IConfirmDialogButtons { + accept?: string; + refuse?: string; + alternative?: string; + default?: string; } interface IConfirmDialogProperties extends IComponentProperties { diff --git a/gui/frontend/src/components/Dialogs/ValueEditDialog.tsx b/gui/frontend/src/components/Dialogs/ValueEditDialog.tsx index f922117b3..63e387081 100644 --- a/gui/frontend/src/components/Dialogs/ValueEditDialog.tsx +++ b/gui/frontend/src/components/Dialogs/ValueEditDialog.tsx @@ -129,6 +129,8 @@ interface IButtonDialogValue extends IBaseDialogValue { value?: string; + icon?: Codicon | string; + /** Called when the button is clicked. The passed in id is what was used to define the button value entry. */ onClick?: (id: string, values: IDialogValues, dialog: ValueEditDialog) => void; } @@ -430,7 +432,7 @@ interface IValueEditDialogProperties extends IComponentProperties { advancedAction?: (values: IDialogValues, props: IButtonProperties) => void; onValidate?: (closing: boolean, values: IDialogValues, data?: IDictionary) => IDialogValidations; - onClose?: (closure: DialogResponseClosure, values: IDialogValues, data?: IDictionary) => void; + onClose?: (closure: DialogResponseClosure, values: IDialogValues, data?: IDictionary) => Promise | void; onToggleAdvanced?: (checked: boolean) => void; onSelectTab?: (id: string) => void; } @@ -678,17 +680,33 @@ export class ValueEditDialog extends ComponentBase { const entry = section.values[id]; - if (entry && (entry.type === "text" || entry.type === "choice")) { - entry.value = value; - if (entry.type === "text") { + switch (entry?.type) { + case "text": { + entry.value = value; entry.showLoading = false; + + const { onValidate } = this.props; + const validations = onValidate?.(false, values, data) || { messages: {} }; + this.setState({ values, validations }); + + return; } - const { onValidate } = this.props; - const validations = onValidate?.(false, values, data) || { messages: {} }; - this.setState({ values, validations }); + case "choice": { + entry.value = value; + if (!entry.choices.includes(value)) { + // If a new value is entered, add it to the list of choices. + entry.choices.push(value); + } - return; + const { onValidate } = this.props; + const validations = onValidate?.(false, values, data) || { messages: {} }; + this.setState({ values, validations }); + + return; + } + + default: } }); }; @@ -1084,8 +1102,15 @@ export class ValueEditDialog extends ComponentBase); + > + {entry.value.icon && } + ); break; } @@ -1568,7 +1593,7 @@ export class ValueEditDialog extends ComponentBase, result }); }; +const iconHostClassName = "iconHost data"; + export interface IResultViewProperties extends IComponentProperties { /** The result data to show. */ resultSet: IResultSet; @@ -1155,7 +1157,7 @@ export class ResultView extends ComponentBase { // Keep a reference to the selected cell, because it is reset while the file dialog is open. const cell = this.selectedCell; if (cell) { - void selectFile([], false).then((files) => { + void selectFileInBrowser([], false).then((files) => { if (files && files.length > 0) { const reader = new FileReader(); reader.onload = (e) => { @@ -1480,7 +1482,7 @@ export class ResultView extends ComponentBase { if (value == null) { const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; const element = ; render(element, host); @@ -1507,7 +1509,7 @@ export class ResultView extends ComponentBase { const value = cell.getValue(); const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; const element = ; render(element, host); @@ -1528,7 +1530,7 @@ export class ResultView extends ComponentBase { const value = cell.getValue(); if (value === null) { const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; const element = ; render(element, host); @@ -1553,7 +1555,7 @@ export class ResultView extends ComponentBase { const value = cell.getValue(); if (value === null) { const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; element = ; render(element, host); @@ -1582,7 +1584,7 @@ export class ResultView extends ComponentBase { const icon = ; const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; render(icon, host); @@ -1597,7 +1599,7 @@ export class ResultView extends ComponentBase { const icon = ; const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; render(icon, host); @@ -1612,7 +1614,7 @@ export class ResultView extends ComponentBase { const value = cell.getValue(); if (value === null) { const host = document.createElement("div"); - host.className = "iconHost"; + host.className = iconHostClassName; const element = ; render(element, host); @@ -1678,7 +1680,7 @@ export class ResultView extends ComponentBase { let element; if (cell.getValue() === null) { element = ; - host.className = "iconHost"; + host.className = iconHostClassName; render(element, host); return host; diff --git a/gui/frontend/src/components/Theming/ThemeManager.ts b/gui/frontend/src/components/Theming/ThemeManager.ts index 1caf9ceb9..857541768 100644 --- a/gui/frontend/src/components/Theming/ThemeManager.ts +++ b/gui/frontend/src/components/Theming/ThemeManager.ts @@ -178,7 +178,6 @@ export class ThemeManager { } requisitions.register("settingsChanged", this.settingsChanged); - requisitions.register("hostThemeChange", this.hostThemeChange); } public static get get(): ThemeManager { @@ -462,6 +461,28 @@ export class ThemeManager { return this.getThemeCss(theme); } + /** + * Handles theme changes in the host (if the app is embedded). + * + * @param data The new theme data. + * @param data.css A set of CSS variables with individual theme data. + * @param data.themeClass The name of the main theme type. The exact name depends on the host. + * + * @returns A promise that always resolve to true. + */ + public hostThemeChange = (data: IHostThemeData): Promise => { + // From now on we ignore the theme from the profile. + this.#useHostTheme = true; + + this.themeDefinitions.delete(data.themeClass); + + const theme = this.parseHostTheme(data); + this.loadThemeDetails(theme); + this.switchTheme(data.themeClass); + + return Promise.resolve(true); + }; + private setFont(theme: IThemeObject, property: string, value: string): void { if (!theme.font) { theme.font = {}; @@ -580,28 +601,6 @@ export class ThemeManager { return Promise.resolve(false); }; - /** - * Handles theme changes in the host (if the app is embedded). - * - * @param data The new theme data. - * @param data.css A set of CSS variables with individual theme data. - * @param data.themeClass The name of the main theme type. The exact name depends on the host. - * - * @returns A promise that always resolve to true. - */ - private hostThemeChange = (data: IHostThemeData): Promise => { - // From now on we ignore the theme from the profile. - this.#useHostTheme = true; - - this.themeDefinitions.delete(data.themeClass); - - const theme = this.parseHostTheme(data); - this.loadThemeDetails(theme); - this.switchTheme(data.themeClass); - - return Promise.resolve(true); - }; - /** * Triggered only if the auto theme is currently active. * diff --git a/gui/frontend/src/components/Theming/assets/dark-app-colors.json b/gui/frontend/src/components/Theming/assets/dark-app-colors.json index e1843dfa4..6718485d0 100644 --- a/gui/frontend/src/components/Theming/assets/dark-app-colors.json +++ b/gui/frontend/src/components/Theming/assets/dark-app-colors.json @@ -1,19 +1,34 @@ { - "browserTile.activeBackground": "#123E54", - "browserTile.activeBorder": "#2D9BD2", - "browserTile.activeForeground": "#CCCCCC", - "browserTile.background": "#123F54", - "browserTile.border": "#2A93C6", - "browserTile.foreground": "#CCCCCC", - "browserTile.hoverBackground": "#1B5E7F", - "browserTileSecondary.activeBackground": "#2C2C2C", - "browserTileSecondary.activeBorder": "#3D3D3D", - "browserTileSecondary.activeForeground": "#CCCCCC", - "browserTileSecondary.background": "#2E2E2E", - "browserTileSecondary.border": "#444444", - "browserTileSecondary.foreground": "#CCCCCC", + "connectionTile.activeBackground": "#123E54", + "connectionTile.activeBorder": "#2D9BD2", + "connectionTile.activeForeground": "#DDDDDD", + "connectionTile.background": "#123F54", + "connectionTile.border": "#2A93C6", + "connectionTile.foreground": "#DDDDDD", + "connectionTile.hoverBackground": "#1B5E7F", + "connectionTileCreateNew.activeBackground": "#2C2C2C", + "connectionTileCreateNew.activeBorder": "#3D3D3D", + "connectionTileCreateNew.activeForeground": "#DDDDDD", + "connectionTileCreateNew.background": "#2E2E2E", + "connectionTileCreateNew.border": "#444444", + "connectionTileCreateNew.foreground": "#DDDDDD", + "connectionTileCreateNew.hoverBackground": "#444444", + "connectionTileBack.activeBackground": "#2C2C2C", + "connectionTileBack.activeBorder": "#3D3D3D", + "connectionTileBack.activeForeground": "#DDDDDD", + "connectionTileBack.background": "#2E2E2E", + "connectionTileBack.border": "#444444", + "connectionTileBack.foreground": "#DDDDDD", + "connectionTileBack.hoverBackground": "#444444", + "connectionTileGroup.activeBackground": "#2C2C2C", + "connectionTileGroup.activeBorder": "#3D3D3D", + "connectionTileGroup.activeForeground": "#DDDDDD", + "connectionTileGroup.background": "#DE7600", + "connectionTileGroup.border": "#EE9020", + "connectionTileGroup.foreground": "#DDDDDD", + "connectionTileGroup.hoverBackground": "#EE9020", "button.defaultBackground": "#1177BB", "button.defaultForeground": "#FFFFFF", "list.sortIndicatorForeground": "#0D66A2", "text.captionForeground": "#DFDFDF" -} \ No newline at end of file +} diff --git a/gui/frontend/src/components/Theming/assets/light-app-colors.json b/gui/frontend/src/components/Theming/assets/light-app-colors.json index 22af23610..338272708 100644 --- a/gui/frontend/src/components/Theming/assets/light-app-colors.json +++ b/gui/frontend/src/components/Theming/assets/light-app-colors.json @@ -1,17 +1,34 @@ { - "browserTile.activeBackground": "#ABD7ED", - "browserTile.activeBorder": "#42A5D7", - "browserTile.activeForeground": "#575760", - "browserTile.background": "#C0E1F2", - "browserTile.border": "#6CB9E0", - "browserTile.foreground": "#575760", - "browserTile.hoverBackground": "#AAD6ED", - "browserTileSecondary.activeBackground": "#D6D6DB", - "browserTileSecondary.activeBorder": "#B4B4BB", - "browserTileSecondary.activeForeground": "#575760", - "browserTileSecondary.background": "#E4E4E7", - "browserTileSecondary.border": "#B4B4BB", - "browserTileSecondary.foreground": "#575760", + "connectionTile.activeBackground": "#ABD7ED", + "connectionTile.activeBorder": "#42A5D7", + "connectionTile.activeForeground": "#575760", + "connectionTile.background": "#C0E1F2", + "connectionTile.border": "#6CB9E0", + "connectionTile.foreground": "#575760", + "connectionTile.hoverBackground": "#AAD6ED", + "connectionTileCreateNew.activeBackground": "#D6D6DB", + "connectionTileCreateNew.activeBorder": "#B4B4BB", + "connectionTileCreateNew.activeForeground": "#575760", + "connectionTileCreateNew.background": "#E4E4E7", + "connectionTileCreateNew.border": "#B4B4BB", + "connectionTileCreateNew.foreground": "#575760", + "connectionTileCreateNew.hoverBackground": "#CCCCCC", + "connectionTileBack.activeBackground": "#D6D6DB", + "connectionTileBack.activeBorder": "#B4B4BB", + "connectionTileBack.activeForeground": "#575760", + "connectionTileBack.background": "#E4E4E7", + "connectionTileBack.border": "#B4B4BB", + "connectionTileBack.foreground": "#575760", + "connectionTileBack.hoverBackground": "#CCCCCC", + "connectionTileGroup.activeBackground": "#2C2C2C", + "connectionTileGroup.activeBorder": "#3D3D3D", + "connectionTileGroup.activeForeground": "#CCCCCC", + "connectionTileGroup.background": "#FFB866", + "connectionTileGroup.border": "#F1A241", + "connectionTileGroup.foreground": "#444444", + "connectionTileGroup.hoverBackground": "#EE9020", + "button.defaultBackground": "#1177BB", + "button.defaultForeground": "#FFFFFF", "list.sortIndicatorForeground": "#007ACC", "text.captionForeground": "#998F8F" -} \ No newline at end of file +} diff --git a/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.css b/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.css index 5dacdd753..ce5bcc0e0 100644 --- a/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.css +++ b/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.css @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -33,7 +33,7 @@ } .msg.breadcrumb > button { - min-width: 0px; + min-width: 0; padding: 1px 2px; margin: 0; @@ -53,19 +53,21 @@ flex: 0 0 auto; width: 24px; height: 24px; - padding: 0px; - margin: 0px; + padding: 0; + margin: 0; } .msg.breadcrumb > .breadcrumbItem { margin: 0; padding: 2px 4px; - border-radius: 0px; + border-radius: 0; + border: none; + color: inherit; } .msg.breadcrumb > .separator { padding: 2px 4px; - border-radius: 0px; + border-radius: 0; } .msg.breadcrumb > .breadcrumbItem:not(:disabled):hover, diff --git a/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.tsx b/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.tsx index 1c2c76d92..83424e263 100644 --- a/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.tsx +++ b/gui/frontend/src/components/ui/Breadcrumb/Breadcrumb.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, @@ -32,36 +32,39 @@ import { ComponentBase, IComponentProperties } from "../Component/ComponentBase. import { Container, Orientation } from "../Container/Container.js"; import { Label } from "../Label/Label.js"; +export interface IBreadCrumbSegment { + id: string | number; + caption: string; + selected?: boolean; +} + +/** Details for a breadcrum path. */ // TODO: breadcrumb picker popup for a breadcrumb item. export interface IBreadcrumbProperties extends IComponentProperties { - path?: string[]; + path: IBreadCrumbSegment[]; separator?: string | ComponentChild; - selected?: number; + showPicker?: boolean; - onSelect?: (path: string[]) => void; + onSelect?: (path: number[]) => void; } export class Breadcrumb extends ComponentBase { public static override defaultProps = { path: [""], - separator: "❯", + showPicker: false, }; public constructor(props: IBreadcrumbProperties) { super(props); - this.addHandledProperties("path", "separator", "selected", "onSelect"); + this.addHandledProperties("path", "separator", "onSelect"); } public render(): ComponentChild { - const { id, children, path, separator, selected } = this.props; - const className = this.getEffectiveClassNames([ - "breadcrumb", - "verticalCenterContent", - ]); + const { children, path, separator, showPicker } = this.props; + const className = this.getEffectiveClassNames(["breadcrumb"]); - const baseId = id as string || "breadcrumb"; let content; if (children != null) { @@ -70,25 +73,23 @@ export class Breadcrumb extends ComponentBase { const separatorItem = typeof separator === "string" ?