diff --git a/components/clp-package-utils/clp_package_utils/general.py b/components/clp-package-utils/clp_package_utils/general.py index e254d4f844..4a927576cb 100644 --- a/components/clp-package-utils/clp_package_utils/general.py +++ b/components/clp-package-utils/clp_package_utils/general.py @@ -15,7 +15,6 @@ CLP_DEFAULT_CREDENTIALS_FILE_PATH, CLPConfig, DB_COMPONENT_NAME, - LOG_VIEWER_WEBUI_COMPONENT_NAME, QUEUE_COMPONENT_NAME, REDIS_COMPONENT_NAME, REDUCER_COMPONENT_NAME, @@ -514,34 +513,17 @@ def validate_worker_config(clp_config: CLPConfig): def validate_webui_config( - clp_config: CLPConfig, logs_dir: pathlib.Path, settings_json_path: pathlib.Path + clp_config: CLPConfig, + client_settings_json_path: pathlib.Path, + server_settings_json_path: pathlib.Path, ): - if not settings_json_path.exists(): - raise ValueError( - f"{WEBUI_COMPONENT_NAME} {settings_json_path} is not a valid path to Meteor settings.json" - ) - - try: - validate_path_could_be_dir(logs_dir) - except ValueError as ex: - raise ValueError(f"{WEBUI_COMPONENT_NAME} logs directory is invalid: {ex}") + for path in [client_settings_json_path, server_settings_json_path]: + if not path.exists(): + raise ValueError(f"{WEBUI_COMPONENT_NAME} {path} is not a valid path to settings.json") validate_port(f"{WEBUI_COMPONENT_NAME}.port", clp_config.webui.host, clp_config.webui.port) -def validate_log_viewer_webui_config(clp_config: CLPConfig, settings_json_path: pathlib.Path): - if not settings_json_path.exists(): - raise ValueError( - f"{WEBUI_COMPONENT_NAME} {settings_json_path} is not a valid path to settings.json" - ) - - validate_port( - f"{LOG_VIEWER_WEBUI_COMPONENT_NAME}.port", - clp_config.log_viewer_webui.host, - clp_config.log_viewer_webui.port, - ) - - def validate_path_for_container_mount(path: pathlib.Path) -> None: RESTRICTED_PREFIXES: List[pathlib.Path] = [ CONTAINER_AWS_CONFIG_DIRECTORY, diff --git a/components/clp-package-utils/clp_package_utils/scripts/start_clp.py b/components/clp-package-utils/clp_package_utils/scripts/start_clp.py index 4a4e0239b8..1bb6741a4c 100755 --- a/components/clp-package-utils/clp_package_utils/scripts/start_clp.py +++ b/components/clp-package-utils/clp_package_utils/scripts/start_clp.py @@ -24,7 +24,6 @@ CONTROLLER_TARGET_NAME, DB_COMPONENT_NAME, FILES_TABLE_SUFFIX, - LOG_VIEWER_WEBUI_COMPONENT_NAME, QUERY_JOBS_TABLE_NAME, QUERY_SCHEDULER_COMPONENT_NAME, QUERY_WORKER_COMPONENT_NAME, @@ -57,7 +56,6 @@ validate_and_load_queue_credentials_file, validate_and_load_redis_credentials_file, validate_db_config, - validate_log_viewer_webui_config, validate_queue_config, validate_redis_config, validate_reducer_config, @@ -843,7 +841,12 @@ def read_and_update_settings_json(settings_file_path: pathlib.Path, updates: Dic return settings_object -def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts): +def start_webui( + instance_id: str, + clp_config: CLPConfig, + container_clp_config: CLPConfig, + mounts: CLPDockerMounts, +): component_name = WEBUI_COMPONENT_NAME logger.info(f"Starting {component_name}...") @@ -851,112 +854,36 @@ def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts if container_exists(container_name): return - webui_logs_dir = clp_config.logs_directory / component_name container_webui_dir = CONTAINER_CLP_HOME / "var" / "www" / "webui" - node_path = str(container_webui_dir / "programs" / "server" / "npm" / "node_modules") - settings_json_path = get_clp_home() / "var" / "www" / "webui" / "settings.json" - - validate_webui_config(clp_config, webui_logs_dir, settings_json_path) - - # Create directories - webui_logs_dir.mkdir(exist_ok=True, parents=True) + node_path = str(container_webui_dir / "server" / "node_modules") + client_settings_json_path = ( + get_clp_home() / "var" / "www" / "webui" / "client" / "settings.json" + ) + server_settings_json_path = ( + get_clp_home() / "var" / "www" / "webui" / "server" / "dist" / "server" / "settings.json" + ) - container_webui_logs_dir = pathlib.Path("/") / "var" / "log" / component_name + validate_webui_config(clp_config, client_settings_json_path, server_settings_json_path) - # Read and update settings.json + # Read, update, and write back client's and server's settings.json clp_db_connection_params = clp_config.database.get_clp_connection_params_and_type(True) table_prefix = clp_db_connection_params["table_prefix"] if StorageEngine.CLP_S == clp_config.package.storage_engine: table_prefix = f"{table_prefix}{CLP_DEFAULT_DATASET_NAME}_" - meteor_settings_updates = { - "private": { - "SqlDbHost": clp_config.database.host, - "SqlDbPort": clp_config.database.port, - "SqlDbName": clp_config.database.name, - "SqlDbClpArchivesTableName": f"{table_prefix}{ARCHIVES_TABLE_SUFFIX}", - "SqlDbClpFilesTableName": f"{table_prefix}{FILES_TABLE_SUFFIX}", - "SqlDbCompressionJobsTableName": COMPRESSION_JOBS_TABLE_NAME, - "SqlDbQueryJobsTableName": QUERY_JOBS_TABLE_NAME, - }, - "public": { - "ClpStorageEngine": clp_config.package.storage_engine, - "LogViewerWebuiUrl": ( - f"http://{clp_config.log_viewer_webui.host}:{clp_config.log_viewer_webui.port}", - ), - }, + client_settings_json_updates = { + "ClpStorageEngine": clp_config.package.storage_engine, + "MongoDbSearchResultsMetadataCollectionName": clp_config.webui.results_metadata_collection_name, + "SqlDbClpArchivesTableName": f"{table_prefix}{ARCHIVES_TABLE_SUFFIX}", + "SqlDbClpFilesTableName": f"{table_prefix}{FILES_TABLE_SUFFIX}", + "SqlDbCompressionJobsTableName": COMPRESSION_JOBS_TABLE_NAME, } - meteor_settings = read_and_update_settings_json(settings_json_path, meteor_settings_updates) - - # Start container - # fmt: off - container_cmd = [ - "docker", "run", - "-d", - "--network", "host", - "--name", container_name, - "--log-driver", "local", - "-u", f"{os.getuid()}:{os.getgid()}", - ] - # fmt: on - env_vars = [ - f"NODE_PATH={node_path}", - f"MONGO_URL={clp_config.results_cache.get_uri()}", - f"PORT={clp_config.webui.port}", - f"ROOT_URL=http://{clp_config.webui.host}", - f"METEOR_SETTINGS={json.dumps(meteor_settings)}", - f"CLP_DB_USER={clp_config.database.username}", - f"CLP_DB_PASS={clp_config.database.password}", - f"WEBUI_LOGS_DIR={container_webui_logs_dir}", - f"WEBUI_LOGGING_LEVEL={clp_config.webui.logging_level}", - ] - necessary_mounts = [ - mounts.clp_home, - DockerMount(DockerMountType.BIND, webui_logs_dir, container_webui_logs_dir), - ] - append_docker_options(container_cmd, necessary_mounts, env_vars) - container_cmd.append(clp_config.execution_container) - - node_cmd = [ - str(CONTAINER_CLP_HOME / "bin" / "node-14"), - str(container_webui_dir / "launcher.js"), - str(container_webui_dir / "main.js"), - ] - cmd = container_cmd + node_cmd - subprocess.run(cmd, stdout=subprocess.DEVNULL, check=True) - - logger.info(f"Started {component_name}.") - - -def start_log_viewer_webui( - instance_id: str, - clp_config: CLPConfig, - container_clp_config: CLPConfig, - mounts: CLPDockerMounts, -): - component_name = LOG_VIEWER_WEBUI_COMPONENT_NAME - logger.info(f"Starting {component_name}...") - - container_name = f"clp-{component_name}-{instance_id}" - if container_exists(container_name): - return - - container_log_viewer_webui_dir = CONTAINER_CLP_HOME / "var" / "www" / "log-viewer-webui" - node_path = str(container_log_viewer_webui_dir / "server" / "node_modules") - settings_json_path = ( - get_clp_home() - / "var" - / "www" - / "log-viewer-webui" - / "server" - / "dist" - / "server" - / "settings.json" + client_settings_json = read_and_update_settings_json( + client_settings_json_path, client_settings_json_updates ) + with open(client_settings_json_path, "w") as client_settings_json_file: + client_settings_json_file.write(json.dumps(client_settings_json)) - validate_log_viewer_webui_config(clp_config, settings_json_path) - - # Read, update, and write back settings.json - settings_json_updates = { + server_settings_json_updates = { "SqlDbHost": clp_config.database.host, "SqlDbPort": clp_config.database.port, "SqlDbName": clp_config.database.name, @@ -964,11 +891,12 @@ def start_log_viewer_webui( "MongoDbHost": clp_config.results_cache.host, "MongoDbPort": clp_config.results_cache.port, "MongoDbName": clp_config.results_cache.db_name, + "MongoDbSearchResultsMetadataCollectionName": clp_config.webui.results_metadata_collection_name, "MongoDbStreamFilesCollectionName": clp_config.results_cache.stream_collection_name, - "ClientDir": str(container_log_viewer_webui_dir / "client"), + "ClientDir": str(container_webui_dir / "client"), + "LogViewerDir": str(container_webui_dir / "yscope-log-viewer"), "StreamFilesDir": str(container_clp_config.stream_output.get_directory()), "StreamTargetUncompressedSize": container_clp_config.stream_output.target_uncompressed_size, - "LogViewerDir": str(container_log_viewer_webui_dir / "yscope-log-viewer"), } container_cmd_extra_opts = [] @@ -977,23 +905,25 @@ def start_log_viewer_webui( if StorageType.S3 == stream_storage.type: s3_config = stream_storage.s3_config - settings_json_updates["StreamFilesS3Region"] = s3_config.region_code - settings_json_updates["StreamFilesS3PathPrefix"] = ( + server_settings_json_updates["StreamFilesS3Region"] = s3_config.region_code + server_settings_json_updates["StreamFilesS3PathPrefix"] = ( f"{s3_config.bucket}/{s3_config.key_prefix}" ) auth = s3_config.aws_authentication if AwsAuthType.profile == auth.type: - settings_json_updates["StreamFilesS3Profile"] = auth.profile + server_settings_json_updates["StreamFilesS3Profile"] = auth.profile else: - settings_json_updates["StreamFilesS3Profile"] = None + server_settings_json_updates["StreamFilesS3Profile"] = None elif StorageType.FS == stream_storage.type: - settings_json_updates["StreamFilesS3Region"] = None - settings_json_updates["StreamFilesS3PathPrefix"] = None - settings_json_updates["StreamFilesS3Profile"] = None + server_settings_json_updates["StreamFilesS3Region"] = None + server_settings_json_updates["StreamFilesS3PathPrefix"] = None + server_settings_json_updates["StreamFilesS3Profile"] = None - settings_json = read_and_update_settings_json(settings_json_path, settings_json_updates) - with open(settings_json_path, "w") as settings_json_file: - settings_json_file.write(json.dumps(settings_json)) + server_settings_json = read_and_update_settings_json( + server_settings_json_path, server_settings_json_updates + ) + with open(server_settings_json_path, "w") as settings_json_file: + settings_json_file.write(json.dumps(server_settings_json)) # fmt: off container_cmd = [ @@ -1009,8 +939,8 @@ def start_log_viewer_webui( necessary_env_vars = [ f"NODE_PATH={node_path}", - f"HOST={clp_config.log_viewer_webui.host}", - f"PORT={clp_config.log_viewer_webui.port}", + f"HOST={clp_config.webui.host}", + f"PORT={clp_config.webui.port}", f"CLP_DB_USER={clp_config.database.username}", f"CLP_DB_PASS={clp_config.database.password}", f"NODE_ENV=production", @@ -1027,7 +957,7 @@ def start_log_viewer_webui( necessary_env_vars.append(f"AWS_SECRET_ACCESS_KEY={credentials.secret_access_key}") else: aws_mount, aws_env_vars = generate_container_auth_options( - clp_config, LOG_VIEWER_WEBUI_COMPONENT_NAME + clp_config, WEBUI_COMPONENT_NAME ) if aws_mount: necessary_mounts.append(mounts.aws_config_dir) @@ -1038,7 +968,7 @@ def start_log_viewer_webui( node_cmd = [ str(CONTAINER_CLP_HOME / "bin" / "node-22"), - str(container_log_viewer_webui_dir / "server" / "dist" / "server" / "src" / "main.js"), + str(container_webui_dir / "server" / "dist" / "server" / "src" / "main.js"), ] cmd = container_cmd + node_cmd subprocess.run(cmd, stdout=subprocess.DEVNULL, check=True) @@ -1147,7 +1077,6 @@ def main(argv): reducer_server_parser = component_args_parser.add_parser(REDUCER_COMPONENT_NAME) add_num_workers_argument(reducer_server_parser) component_args_parser.add_parser(WEBUI_COMPONENT_NAME) - component_args_parser.add_parser(LOG_VIEWER_WEBUI_COMPONENT_NAME) parsed_args = args_parser.parse_args(argv[1:]) @@ -1175,7 +1104,6 @@ def main(argv): COMPRESSION_SCHEDULER_COMPONENT_NAME, QUERY_SCHEDULER_COMPONENT_NAME, WEBUI_COMPONENT_NAME, - LOG_VIEWER_WEBUI_COMPONENT_NAME, ): validate_and_load_db_credentials_file(clp_config, clp_home, True) if target in ( @@ -1271,9 +1199,7 @@ def main(argv): if target in (ALL_TARGET_NAME, REDUCER_COMPONENT_NAME): start_reducer(instance_id, clp_config, container_clp_config, num_workers, mounts) if target in (ALL_TARGET_NAME, WEBUI_COMPONENT_NAME): - start_webui(instance_id, clp_config, mounts) - if target in (ALL_TARGET_NAME, LOG_VIEWER_WEBUI_COMPONENT_NAME): - start_log_viewer_webui(instance_id, clp_config, container_clp_config, mounts) + start_webui(instance_id, clp_config, container_clp_config, mounts) except Exception as ex: if type(ex) == ValueError: diff --git a/components/clp-package-utils/clp_package_utils/scripts/stop_clp.py b/components/clp-package-utils/clp_package_utils/scripts/stop_clp.py index a55d7a7951..307eadaa75 100755 --- a/components/clp-package-utils/clp_package_utils/scripts/stop_clp.py +++ b/components/clp-package-utils/clp_package_utils/scripts/stop_clp.py @@ -11,7 +11,6 @@ COMPRESSION_WORKER_COMPONENT_NAME, CONTROLLER_TARGET_NAME, DB_COMPONENT_NAME, - LOG_VIEWER_WEBUI_COMPONENT_NAME, QUERY_SCHEDULER_COMPONENT_NAME, QUERY_WORKER_COMPONENT_NAME, QUEUE_COMPONENT_NAME, @@ -85,7 +84,6 @@ def main(argv): component_args_parser.add_parser(COMPRESSION_WORKER_COMPONENT_NAME) component_args_parser.add_parser(QUERY_WORKER_COMPONENT_NAME) component_args_parser.add_parser(WEBUI_COMPONENT_NAME) - component_args_parser.add_parser(LOG_VIEWER_WEBUI_COMPONENT_NAME) parsed_args = args_parser.parse_args(argv[1:]) @@ -104,7 +102,6 @@ def main(argv): ALL_TARGET_NAME, CONTROLLER_TARGET_NAME, DB_COMPONENT_NAME, - LOG_VIEWER_WEBUI_COMPONENT_NAME, ): validate_and_load_db_credentials_file(clp_config, clp_home, False) if target in ( @@ -133,9 +130,6 @@ def main(argv): already_exited_containers = [] force = parsed_args.force - if target in (ALL_TARGET_NAME, LOG_VIEWER_WEBUI_COMPONENT_NAME): - container_name = f"clp-{LOG_VIEWER_WEBUI_COMPONENT_NAME}-{instance_id}" - stop_running_container(container_name, already_exited_containers, force) if target in (ALL_TARGET_NAME, WEBUI_COMPONENT_NAME): container_name = f"clp-{WEBUI_COMPONENT_NAME}-{instance_id}" stop_running_container(container_name, already_exited_containers, force) diff --git a/components/clp-py-utils/clp_py_utils/clp_config.py b/components/clp-py-utils/clp_py_utils/clp_config.py index 4c3199501d..0e4477dd82 100644 --- a/components/clp-py-utils/clp_py_utils/clp_config.py +++ b/components/clp-py-utils/clp_py_utils/clp_config.py @@ -26,7 +26,6 @@ COMPRESSION_WORKER_COMPONENT_NAME = "compression_worker" QUERY_WORKER_COMPONENT_NAME = "query_worker" WEBUI_COMPONENT_NAME = "webui" -LOG_VIEWER_WEBUI_COMPONENT_NAME = "log_viewer_webui" # Target names ALL_TARGET_NAME = "" @@ -572,7 +571,7 @@ def dump_to_primitive_dict(self): class WebUi(BaseModel): host: str = "localhost" port: int = 4000 - logging_level: str = "INFO" + results_metadata_collection_name: str = "results-metadata" @validator("host") def validate_host(cls, field): @@ -584,24 +583,12 @@ def validate_port(cls, field): _validate_port(cls, field) return field - @validator("logging_level") - def validate_logging_level(cls, field): - _validate_logging_level(cls, field) - return field - - -class LogViewerWebUi(BaseModel): - host: str = "localhost" - port: int = 3000 - - @validator("host") - def validate_host(cls, field): - _validate_host(cls, field) - return field - - @validator("port") - def validate_port(cls, field): - _validate_port(cls, field) + @validator("results_metadata_collection_name") + def validate_results_metadata_collection_name(cls, field): + if "" == field: + raise ValueError( + f"{WEBUI_COMPONENT_NAME}.results_metadata_collection_name cannot be empty." + ) return field @@ -621,7 +608,6 @@ class CLPConfig(BaseModel): compression_worker: CompressionWorker = CompressionWorker() query_worker: QueryWorker = QueryWorker() webui: WebUi = WebUi() - log_viewer_webui: LogViewerWebUi = LogViewerWebUi() credentials_file_path: pathlib.Path = CLP_DEFAULT_CREDENTIALS_FILE_PATH archive_output: ArchiveOutput = ArchiveOutput() diff --git a/components/clp-py-utils/clp_py_utils/s3_utils.py b/components/clp-py-utils/clp_py_utils/s3_utils.py index 3a41a89616..dbc7d0981b 100644 --- a/components/clp-py-utils/clp_py_utils/s3_utils.py +++ b/components/clp-py-utils/clp_py_utils/s3_utils.py @@ -14,13 +14,13 @@ COMPRESSION_SCHEDULER_COMPONENT_NAME, COMPRESSION_WORKER_COMPONENT_NAME, FsStorage, - LOG_VIEWER_WEBUI_COMPONENT_NAME, QUERY_SCHEDULER_COMPONENT_NAME, QUERY_WORKER_COMPONENT_NAME, S3Config, S3Credentials, S3Storage, StorageType, + WEBUI_COMPONENT_NAME, ) from clp_py_utils.compression import FileMetadata @@ -115,7 +115,7 @@ def generate_container_auth_options( ): output_storages_by_component_type = [clp_config.archive_output.storage] input_storage_needed = True - elif component_type in (LOG_VIEWER_WEBUI_COMPONENT_NAME,): + elif component_type in (WEBUI_COMPONENT_NAME,): output_storages_by_component_type = [clp_config.stream_output.storage] elif component_type in ( QUERY_SCHEDULER_COMPONENT_NAME, diff --git a/components/log-viewer-webui/.gitignore b/components/log-viewer-webui/.gitignore deleted file mode 100644 index b6448e2f62..0000000000 --- a/components/log-viewer-webui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Dependencies -node_modules diff --git a/components/log-viewer-webui/README.md b/components/log-viewer-webui/README.md deleted file mode 100644 index e052ec9d93..0000000000 --- a/components/log-viewer-webui/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Log Viewer WebUI - -A webapp that allows us to serve the [log-viewer] and integrate it with CLP's [webui]. - -See the [docs] for more details. - -[docs]: https://docs.yscope.com/clp/main/dev-guide/components-log-viewer-webui -[log-viewer]: https://github.com/y-scope/yscope-log-viewer -[webui]: ../webui diff --git a/components/log-viewer-webui/client/README.md b/components/log-viewer-webui/client/README.md deleted file mode 100644 index e425639b98..0000000000 --- a/components/log-viewer-webui/client/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Log Viewer WebUI Client - -### Start a Dev Server -Run: -```bash -npm run start -``` - -### Start a Dev Server for the New WebUI (Under Development) -Run: -```bash -npm run antd -``` diff --git a/components/log-viewer-webui/client/public/settings.json b/components/log-viewer-webui/client/public/settings.json deleted file mode 100644 index 5bbc0333c3..0000000000 --- a/components/log-viewer-webui/client/public/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "MongoDbSearchResultsMetadataCollectionName": "results-metadata", - "ClpStorageEngine": "clp" -} diff --git a/components/log-viewer-webui/client/src/App.tsx b/components/log-viewer-webui/client/src/App.tsx deleted file mode 100644 index b54609e539..0000000000 --- a/components/log-viewer-webui/client/src/App.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import {CssVarsProvider} from "@mui/joy"; - -import {LOCAL_STORAGE_KEY} from "./typings/config"; -import QueryStatus from "./ui/QueryStatus"; - - -/** - * Renders the main application. - * - * @return - */ -const App = () => { - return ( - - - - ); -}; - -export default App; diff --git a/components/log-viewer-webui/package-lock.json b/components/log-viewer-webui/package-lock.json deleted file mode 100644 index 4ca32e8ff9..0000000000 --- a/components/log-viewer-webui/package-lock.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "name": "log-viewer-webui", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "log-viewer-webui", - "version": "0.1.0", - "license": "Apache-2.0", - "devDependencies": { - "concurrently": "^8.2.2" - } - }, - "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concurrently": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", - "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "date-fns": "^2.30.0", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": "^14.13.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/spawn-command": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", - "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", - "dev": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - } - } -} diff --git a/components/log-viewer-webui/package.json b/components/log-viewer-webui/package.json deleted file mode 100644 index dff17d93da..0000000000 --- a/components/log-viewer-webui/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "log-viewer-webui", - "version": "0.1.0", - "description": "", - "scripts": { - "client:lint:check": "cd client && npm run lint:check", - "client:lint:fix": "cd client && npm run lint:fix", - "client:start": "cd client && npm start", - "init": "npm clean-install && (cd client && npm clean-install) && (cd server && npm clean-install)", - "lint:check": "npm run client:lint:check && npm run server:lint:check", - "lint:fix": "npm run client:lint:fix && npm run server:lint:fix", - "server:lint:check": "cd server && npm run lint:check", - "server:lint:fix": "cd server && npm run lint:fix", - "server:start": "cd server && npm start", - "start": "concurrently \"npm run client:start\" \"npm run server:start\"" - }, - "author": "YScope Inc. ", - "license": "Apache-2.0", - "devDependencies": { - "concurrently": "^8.2.2" - } -} diff --git a/components/package-template/src/etc/clp-config.yml b/components/package-template/src/etc/clp-config.yml index 24e012a29f..423741325a 100644 --- a/components/package-template/src/etc/clp-config.yml +++ b/components/package-template/src/etc/clp-config.yml @@ -61,11 +61,7 @@ #webui: # host: "localhost" # port: 4000 -# logging_level: "INFO" -# -#log_viewer_webui: -# host: "localhost" -# port: 3000 +# results_metadata_collection_name: "results-metadata" # ## Where archives should be output to #archive_output: diff --git a/components/webui/.gitignore b/components/webui/.gitignore index c40aa38d0e..2e86728fc3 100644 --- a/components/webui/.gitignore +++ b/components/webui/.gitignore @@ -1,2 +1,3 @@ -docs/ +# Dependencies node_modules/ +yscope-log-viewer/ diff --git a/components/webui/.meteor/.finished-upgraders b/components/webui/.meteor/.finished-upgraders deleted file mode 100644 index c07b6ff75a..0000000000 --- a/components/webui/.meteor/.finished-upgraders +++ /dev/null @@ -1,19 +0,0 @@ -# This file contains information which helps Meteor properly upgrade your -# app when you run 'meteor update'. You should check it into version control -# with your project. - -notices-for-0.9.0 -notices-for-0.9.1 -0.9.4-platform-file -notices-for-facebook-graph-api-2 -1.2.0-standard-minifiers-package -1.2.0-meteor-platform-split -1.2.0-cordova-changes -1.2.0-breaking-changes -1.3.0-split-minifiers-package -1.4.0-remove-old-dev-bundle-link -1.4.1-add-shell-server-package -1.4.3-split-account-service-packages -1.5-add-dynamic-import-package -1.7-split-underscore-from-meteor-base -1.8.3-split-jquery-from-blaze diff --git a/components/webui/.meteor/.gitignore b/components/webui/.meteor/.gitignore deleted file mode 100644 index 4083037423..0000000000 --- a/components/webui/.meteor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -local diff --git a/components/webui/.meteor/.id b/components/webui/.meteor/.id deleted file mode 100644 index 0428be3da9..0000000000 --- a/components/webui/.meteor/.id +++ /dev/null @@ -1,7 +0,0 @@ -# This file contains a token that is unique to your project. -# Check it into your repository along with the rest of this directory. -# It can be used for purposes such as: -# - ensuring you don't accidentally deploy one app on top of another -# - providing package authors with aggregated statistics - -w2i4drbtdntc.kdbz5fehx6g diff --git a/components/webui/.meteor/packages b/components/webui/.meteor/packages deleted file mode 100644 index 88d4b182ac..0000000000 --- a/components/webui/.meteor/packages +++ /dev/null @@ -1,19 +0,0 @@ -# Meteor packages used by this project, one per line. -# Check this file (and the other files in this directory) into your repository. -# -# 'meteor add' and 'meteor remove' will edit this file for you, -# but you can also edit it by hand. - -meteor-base@1.5.1 # Packages every Meteor app needs to have -mongo@1.16.10 # The database Meteor supports right now -reactive-var@1.0.12 # Reactive variable for tracker - -standard-minifier-css@1.9.2 # CSS minifier run for production mode -standard-minifier-js@2.8.1 # JS minifier run for production mode -ecmascript@0.16.8 # Enable ECMAScript2015+ syntax in app code -hot-module-replacement@0.5.3 # Update client in development without reloading the page - -static-html@1.3.2 # Define static page content in .html files -react-meteor-data@2.7.2 # React higher-order component for reactively tracking Meteor data -fourseven:scss@4.16.0 # Compile Sass files with node-sass -meteortesting:mocha@2.1.0 # Testing framework diff --git a/components/webui/.meteor/platforms b/components/webui/.meteor/platforms deleted file mode 100644 index efeba1b50c..0000000000 --- a/components/webui/.meteor/platforms +++ /dev/null @@ -1,2 +0,0 @@ -server -browser diff --git a/components/webui/.meteor/release b/components/webui/.meteor/release deleted file mode 100644 index 5152abe9d5..0000000000 --- a/components/webui/.meteor/release +++ /dev/null @@ -1 +0,0 @@ -METEOR@2.16 diff --git a/components/webui/.meteor/versions b/components/webui/.meteor/versions deleted file mode 100644 index d568e975cb..0000000000 --- a/components/webui/.meteor/versions +++ /dev/null @@ -1,73 +0,0 @@ -allow-deny@1.1.1 -autoupdate@1.8.0 -babel-compiler@7.10.5 -babel-runtime@1.5.1 -base64@1.0.12 -binary-heap@1.0.11 -blaze-tools@1.1.3 -boilerplate-generator@1.7.2 -caching-compiler@1.2.2 -caching-html-compiler@1.2.1 -callback-hook@1.5.1 -check@1.4.1 -ddp@1.4.1 -ddp-client@2.6.2 -ddp-common@1.4.1 -ddp-server@2.7.1 -diff-sequence@1.1.2 -dynamic-import@0.7.3 -ecmascript@0.16.8 -ecmascript-runtime@0.8.1 -ecmascript-runtime-client@0.12.1 -ecmascript-runtime-server@0.11.0 -ejson@1.1.3 -es5-shim@4.8.0 -fetch@0.1.4 -fourseven:scss@4.16.0 -geojson-utils@1.0.11 -hot-code-push@1.0.4 -hot-module-replacement@0.5.3 -html-tools@1.1.3 -htmljs@1.1.1 -http@1.0.10 -id-map@1.1.1 -inter-process-messaging@0.1.1 -logging@1.3.4 -meteor@1.11.5 -meteor-base@1.5.1 -meteortesting:browser-tests@1.4.2 -meteortesting:mocha@2.1.0 -meteortesting:mocha-core@8.0.1 -minifier-css@1.6.4 -minifier-js@2.8.0 -minimongo@1.9.4 -modern-browsers@0.1.10 -modules@0.20.0 -modules-runtime@0.13.1 -modules-runtime-hot@0.14.2 -mongo@1.16.10 -mongo-decimal@0.1.3 -mongo-dev-server@1.1.0 -mongo-id@1.0.8 -npm-mongo@4.17.2 -ordered-dict@1.1.0 -promise@0.12.2 -random@1.2.1 -react-fast-refresh@0.2.8 -react-meteor-data@2.7.2 -reactive-var@1.0.12 -reload@1.3.1 -retry@1.1.0 -routepolicy@1.1.1 -socket-stream-client@0.5.2 -spacebars-compiler@1.3.1 -standard-minifier-css@1.9.2 -standard-minifier-js@2.8.1 -static-html@1.3.2 -templating-tools@1.2.2 -tracker@1.3.3 -typescript@4.9.5 -underscore@1.6.2 -url@1.3.2 -webapp@1.13.8 -webapp-hashing@1.1.1 diff --git a/components/webui/.meteorignore b/components/webui/.meteorignore deleted file mode 100644 index 48357e9f1f..0000000000 --- a/components/webui/.meteorignore +++ /dev/null @@ -1 +0,0 @@ -linter diff --git a/components/webui/README.md b/components/webui/README.md index 61c95fe645..299000819d 100644 --- a/components/webui/README.md +++ b/components/webui/README.md @@ -1,4 +1,4 @@ -# CLP WebUI +# WebUI The web interface for the CLP package. diff --git a/components/log-viewer-webui/client/.gitignore b/components/webui/client/.gitignore similarity index 100% rename from components/log-viewer-webui/client/.gitignore rename to components/webui/client/.gitignore diff --git a/components/log-viewer-webui/client/eslint.config.mjs b/components/webui/client/eslint.config.mjs similarity index 100% rename from components/log-viewer-webui/client/eslint.config.mjs rename to components/webui/client/eslint.config.mjs diff --git a/components/log-viewer-webui/client/index.html b/components/webui/client/index.html similarity index 90% rename from components/log-viewer-webui/client/index.html rename to components/webui/client/index.html index 962213f7f9..26b1691c70 100644 --- a/components/log-viewer-webui/client/index.html +++ b/components/webui/client/index.html @@ -4,7 +4,7 @@ Log Viewer Web UI - + diff --git a/components/webui/client/main.css b/components/webui/client/main.css deleted file mode 100644 index 22090692cd..0000000000 --- a/components/webui/client/main.css +++ /dev/null @@ -1,4 +0,0 @@ -#root { - display: flex; - height: 100%; -} diff --git a/components/webui/client/main.html b/components/webui/client/main.html deleted file mode 100644 index 17c3d873b4..0000000000 --- a/components/webui/client/main.html +++ /dev/null @@ -1,15 +0,0 @@ - - YScope CLP - - - - - - - - -
- diff --git a/components/webui/client/main.jsx b/components/webui/client/main.jsx deleted file mode 100644 index 082c37091e..0000000000 --- a/components/webui/client/main.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import {Meteor} from "meteor/meteor"; -import {StrictMode} from "react"; -import ReactDOM from "react-dom/client"; -import {Router} from "react-router"; - -import {createBrowserHistory} from "history"; - -import {App} from "/imports/ui/App"; - - -Meteor.startup(() => { - const root = ReactDOM.createRoot(document.getElementById("root")); - - root.render( - - - - - - ); -}); diff --git a/components/log-viewer-webui/client/package-lock.json b/components/webui/client/package-lock.json similarity index 99% rename from components/log-viewer-webui/client/package-lock.json rename to components/webui/client/package-lock.json index 9e797c367d..620a05d725 100644 --- a/components/log-viewer-webui/client/package-lock.json +++ b/components/webui/client/package-lock.json @@ -1,11 +1,11 @@ { - "name": "log-viewer-webui-client", + "name": "webui-client", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "log-viewer-webui-client", + "name": "webui-client", "version": "0.1.0", "license": "Apache-2.0", "dependencies": { diff --git a/components/log-viewer-webui/client/package.json b/components/webui/client/package.json similarity index 91% rename from components/log-viewer-webui/client/package.json rename to components/webui/client/package.json index 18b28a262a..0a77318e2b 100644 --- a/components/log-viewer-webui/client/package.json +++ b/components/webui/client/package.json @@ -1,5 +1,5 @@ { - "name": "log-viewer-webui-client", + "name": "webui-client", "version": "0.1.0", "description": "", "main": "src/main.tsx", @@ -7,8 +7,7 @@ "build": "tsc -b && vite build", "lint:check": "eslint", "lint:fix": "eslint --fix", - "start": "vite", - "antd": "VITE_USE_ANTD_APP=true npm run start" + "start": "vite" }, "author": "YScope Inc. ", "license": "Apache-2.0", diff --git a/components/log-viewer-webui/client/public/clp-logo.png b/components/webui/client/public/clp-logo.png similarity index 100% rename from components/log-viewer-webui/client/public/clp-logo.png rename to components/webui/client/public/clp-logo.png diff --git a/components/log-viewer-webui/client/public/favicon.svg b/components/webui/client/public/favicon.svg similarity index 100% rename from components/log-viewer-webui/client/public/favicon.svg rename to components/webui/client/public/favicon.svg diff --git a/components/webui/client/public/settings.json b/components/webui/client/public/settings.json new file mode 100644 index 0000000000..ef9b741d3c --- /dev/null +++ b/components/webui/client/public/settings.json @@ -0,0 +1,7 @@ +{ + "ClpStorageEngine": "clp", + "MongoDbSearchResultsMetadataCollectionName": "results-metadata", + "SqlDbClpArchivesTableName": "clp_archives", + "SqlDbClpFilesTableName": "clp_files", + "SqlDbCompressionJobsTableName": "compression_jobs" +} diff --git a/components/log-viewer-webui/client/src/AntdApp.tsx b/components/webui/client/src/App.tsx similarity index 89% rename from components/log-viewer-webui/client/src/AntdApp.tsx rename to components/webui/client/src/App.tsx index 4a70cb5f74..a2044d95db 100644 --- a/components/log-viewer-webui/client/src/AntdApp.tsx +++ b/components/webui/client/src/App.tsx @@ -13,7 +13,7 @@ import "@ant-design/v5-patch-for-react-19"; * * @return */ -const AntApp = () => { +const App = () => { return ( { ); }; -export default AntApp; +export default App; diff --git a/components/log-viewer-webui/client/src/api/query.ts b/components/webui/client/src/api/query.ts similarity index 100% rename from components/log-viewer-webui/client/src/api/query.ts rename to components/webui/client/src/api/query.ts diff --git a/components/log-viewer-webui/client/src/api/search.ts b/components/webui/client/src/api/search.ts similarity index 100% rename from components/log-viewer-webui/client/src/api/search.ts rename to components/webui/client/src/api/search.ts diff --git a/components/log-viewer-webui/client/src/api/socket/MongoSocketCollection.ts b/components/webui/client/src/api/socket/MongoSocketCollection.ts similarity index 100% rename from components/log-viewer-webui/client/src/api/socket/MongoSocketCollection.ts rename to components/webui/client/src/api/socket/MongoSocketCollection.ts diff --git a/components/log-viewer-webui/client/src/api/socket/MongoSocketCursor.ts b/components/webui/client/src/api/socket/MongoSocketCursor.ts similarity index 100% rename from components/log-viewer-webui/client/src/api/socket/MongoSocketCursor.ts rename to components/webui/client/src/api/socket/MongoSocketCursor.ts diff --git a/components/log-viewer-webui/client/src/api/socket/SocketSingleton.ts b/components/webui/client/src/api/socket/SocketSingleton.ts similarity index 100% rename from components/log-viewer-webui/client/src/api/socket/SocketSingleton.ts rename to components/webui/client/src/api/socket/SocketSingleton.ts diff --git a/components/log-viewer-webui/client/src/api/socket/useCursor.tsx b/components/webui/client/src/api/socket/useCursor.tsx similarity index 100% rename from components/log-viewer-webui/client/src/api/socket/useCursor.tsx rename to components/webui/client/src/api/socket/useCursor.tsx diff --git a/components/log-viewer-webui/client/src/components/DashboardCard/index.module.css b/components/webui/client/src/components/DashboardCard/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/components/DashboardCard/index.module.css rename to components/webui/client/src/components/DashboardCard/index.module.css diff --git a/components/log-viewer-webui/client/src/components/DashboardCard/index.tsx b/components/webui/client/src/components/DashboardCard/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/DashboardCard/index.tsx rename to components/webui/client/src/components/DashboardCard/index.tsx diff --git a/components/log-viewer-webui/client/src/components/Layout/MainLayout.module.css b/components/webui/client/src/components/Layout/MainLayout.module.css similarity index 100% rename from components/log-viewer-webui/client/src/components/Layout/MainLayout.module.css rename to components/webui/client/src/components/Layout/MainLayout.module.css diff --git a/components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx b/components/webui/client/src/components/Layout/MainLayout.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx rename to components/webui/client/src/components/Layout/MainLayout.tsx diff --git a/components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx b/components/webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx rename to components/webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx diff --git a/components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/index.tsx b/components/webui/client/src/components/QueryBox/InputWithCaseSensitive/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/index.tsx rename to components/webui/client/src/components/QueryBox/InputWithCaseSensitive/index.tsx diff --git a/components/log-viewer-webui/client/src/components/QueryBox/index.module.css b/components/webui/client/src/components/QueryBox/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/components/QueryBox/index.module.css rename to components/webui/client/src/components/QueryBox/index.module.css diff --git a/components/log-viewer-webui/client/src/components/QueryBox/index.tsx b/components/webui/client/src/components/QueryBox/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/QueryBox/index.tsx rename to components/webui/client/src/components/QueryBox/index.tsx diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/index.ts b/components/webui/client/src/components/ResultsTimeline/datetime/index.ts similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/index.ts rename to components/webui/client/src/components/ResultsTimeline/datetime/index.ts diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/typings.ts b/components/webui/client/src/components/ResultsTimeline/datetime/typings.ts similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/datetime/typings.ts rename to components/webui/client/src/components/ResultsTimeline/datetime/typings.ts diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/index.module.css b/components/webui/client/src/components/ResultsTimeline/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/index.module.css rename to components/webui/client/src/components/ResultsTimeline/index.module.css diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx b/components/webui/client/src/components/ResultsTimeline/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/index.tsx rename to components/webui/client/src/components/ResultsTimeline/index.tsx diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts b/components/webui/client/src/components/ResultsTimeline/typings.ts similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/typings.ts rename to components/webui/client/src/components/ResultsTimeline/typings.ts diff --git a/components/log-viewer-webui/client/src/components/ResultsTimeline/utils.ts b/components/webui/client/src/components/ResultsTimeline/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/components/ResultsTimeline/utils.ts rename to components/webui/client/src/components/ResultsTimeline/utils.ts diff --git a/components/log-viewer-webui/client/src/components/StatCard/index.module.css b/components/webui/client/src/components/StatCard/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/components/StatCard/index.module.css rename to components/webui/client/src/components/StatCard/index.module.css diff --git a/components/log-viewer-webui/client/src/components/StatCard/index.tsx b/components/webui/client/src/components/StatCard/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/StatCard/index.tsx rename to components/webui/client/src/components/StatCard/index.tsx diff --git a/components/log-viewer-webui/client/src/components/VirtualTable/index.tsx b/components/webui/client/src/components/VirtualTable/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/VirtualTable/index.tsx rename to components/webui/client/src/components/VirtualTable/index.tsx diff --git a/components/log-viewer-webui/client/src/components/VirtualTable/typings.tsx b/components/webui/client/src/components/VirtualTable/typings.tsx similarity index 100% rename from components/log-viewer-webui/client/src/components/VirtualTable/typings.tsx rename to components/webui/client/src/components/VirtualTable/typings.tsx diff --git a/components/log-viewer-webui/client/src/config/index.ts b/components/webui/client/src/config/index.ts similarity index 100% rename from components/log-viewer-webui/client/src/config/index.ts rename to components/webui/client/src/config/index.ts diff --git a/components/log-viewer-webui/client/src/index.css b/components/webui/client/src/index.css similarity index 100% rename from components/log-viewer-webui/client/src/index.css rename to components/webui/client/src/index.css diff --git a/components/log-viewer-webui/client/src/main.tsx b/components/webui/client/src/main.tsx similarity index 53% rename from components/log-viewer-webui/client/src/main.tsx rename to components/webui/client/src/main.tsx index 8e45e59ef8..b049316a14 100644 --- a/components/log-viewer-webui/client/src/main.tsx +++ b/components/webui/client/src/main.tsx @@ -1,7 +1,6 @@ import {StrictMode} from "react"; import {createRoot} from "react-dom/client"; -import AntdApp from "./AntdApp"; import App from "./App"; import "./index.css"; @@ -12,16 +11,10 @@ if (null === rootElement) { throw new Error("Root element not found"); } -/* eslint-disable-next-line no-warning-comments */ -// TODO: Remove flag and related logic when the new UI is fully implemented. -const {VITE_USE_ANTD_APP} = import.meta.env; -const AppComponent = ("true" === VITE_USE_ANTD_APP) ? - AntdApp : - App; const root = createRoot(rootElement); root.render( - + ); diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/DetailsCard.tsx b/components/webui/client/src/pages/IngestPage/Details/DetailsCard.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/DetailsCard.tsx rename to components/webui/client/src/pages/IngestPage/Details/DetailsCard.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx b/components/webui/client/src/pages/IngestPage/Details/Files.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/Files.tsx rename to components/webui/client/src/pages/IngestPage/Details/Files.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx b/components/webui/client/src/pages/IngestPage/Details/Messages.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/Messages.tsx rename to components/webui/client/src/pages/IngestPage/Details/Messages.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx b/components/webui/client/src/pages/IngestPage/Details/TimeRange.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/TimeRange.tsx rename to components/webui/client/src/pages/IngestPage/Details/TimeRange.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css b/components/webui/client/src/pages/IngestPage/Details/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/index.module.css rename to components/webui/client/src/pages/IngestPage/Details/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsx b/components/webui/client/src/pages/IngestPage/Details/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/index.tsx rename to components/webui/client/src/pages/IngestPage/Details/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Details/sql.ts b/components/webui/client/src/pages/IngestPage/Details/sql.ts similarity index 89% rename from components/log-viewer-webui/client/src/pages/IngestPage/Details/sql.ts rename to components/webui/client/src/pages/IngestPage/Details/sql.ts index 790c33700f..67970d0ce9 100644 --- a/components/log-viewer-webui/client/src/pages/IngestPage/Details/sql.ts +++ b/components/webui/client/src/pages/IngestPage/Details/sql.ts @@ -1,9 +1,9 @@ import {Nullable} from "src/typings/common"; +import {settings} from "../../../settings"; import { CLP_ARCHIVES_TABLE_COLUMN_NAMES, CLP_FILES_TABLE_COLUMN_NAMES, - SQL_CONFIG, } from "../sqlConfig"; @@ -23,7 +23,7 @@ FROM SELECT MIN(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.BEGIN_TIMESTAMP}) AS begin_timestamp, MAX(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.END_TIMESTAMP}) AS end_timestamp - FROM ${SQL_CONFIG.SqlDbClpArchivesTableName} + FROM ${settings.SqlDbClpArchivesTableName} ) a, ( SELECT @@ -34,7 +34,7 @@ FROM 0 ) AS INTEGER ) AS num_messages - FROM ${SQL_CONFIG.SqlDbClpFilesTableName} + FROM ${settings.SqlDbClpFilesTableName} ) b; `; diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/index.module.css b/components/webui/client/src/pages/IngestPage/Jobs/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/index.module.css rename to components/webui/client/src/pages/IngestPage/Jobs/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/index.tsx b/components/webui/client/src/pages/IngestPage/Jobs/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/index.tsx rename to components/webui/client/src/pages/IngestPage/Jobs/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/sql.ts b/components/webui/client/src/pages/IngestPage/Jobs/sql.ts similarity index 88% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/sql.ts rename to components/webui/client/src/pages/IngestPage/Jobs/sql.ts index e0256667c1..d66f41238f 100644 --- a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/sql.ts +++ b/components/webui/client/src/pages/IngestPage/Jobs/sql.ts @@ -1,9 +1,7 @@ import {Nullable} from "src/typings/common"; -import { - COMPRESSION_JOBS_TABLE_COLUMN_NAMES, - SQL_CONFIG, -} from "../sqlConfig"; +import {settings} from "../../../settings"; +import {COMPRESSION_JOBS_TABLE_COLUMN_NAMES} from "../sqlConfig"; /** @@ -23,7 +21,7 @@ SELECT ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.DURATION}, ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.UNCOMPRESSED_SIZE}, ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.COMPRESSED_SIZE} -FROM ${SQL_CONFIG.SqlDbCompressionJobsTableName} +FROM ${settings.SqlDbCompressionJobsTableName} WHERE ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.UPDATE_TIME} >= FROM_UNIXTIME(${lastUpdateTimestampSeconds}) - 1 ORDER BY _id DESC;`; diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/typings.tsx b/components/webui/client/src/pages/IngestPage/Jobs/typings.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/typings.tsx rename to components/webui/client/src/pages/IngestPage/Jobs/typings.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/units.ts b/components/webui/client/src/pages/IngestPage/Jobs/units.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/units.ts rename to components/webui/client/src/pages/IngestPage/Jobs/units.ts diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/Jobs/utils.ts b/components/webui/client/src/pages/IngestPage/Jobs/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/Jobs/utils.ts rename to components/webui/client/src/pages/IngestPage/Jobs/utils.ts diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/CompressedSize.tsx b/components/webui/client/src/pages/IngestPage/SpaceSavings/CompressedSize.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/CompressedSize.tsx rename to components/webui/client/src/pages/IngestPage/SpaceSavings/CompressedSize.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/UncompressedSize.tsx b/components/webui/client/src/pages/IngestPage/SpaceSavings/UncompressedSize.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/UncompressedSize.tsx rename to components/webui/client/src/pages/IngestPage/SpaceSavings/UncompressedSize.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.module.css b/components/webui/client/src/pages/IngestPage/SpaceSavings/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.module.css rename to components/webui/client/src/pages/IngestPage/SpaceSavings/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx b/components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/index.tsx rename to components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/sql.ts b/components/webui/client/src/pages/IngestPage/SpaceSavings/sql.ts similarity index 81% rename from components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/sql.ts rename to components/webui/client/src/pages/IngestPage/SpaceSavings/sql.ts index fbd61a657b..e3639071b8 100644 --- a/components/log-viewer-webui/client/src/pages/IngestPage/SpaceSavings/sql.ts +++ b/components/webui/client/src/pages/IngestPage/SpaceSavings/sql.ts @@ -1,7 +1,5 @@ -import { - CLP_ARCHIVES_TABLE_COLUMN_NAMES, - SQL_CONFIG, -} from "../sqlConfig"; +import {settings} from "../../../settings"; +import {CLP_ARCHIVES_TABLE_COLUMN_NAMES} from "../sqlConfig"; /** @@ -23,7 +21,7 @@ SELECT 0 ) AS UNSIGNED ) AS total_compressed_size -FROM ${SQL_CONFIG.SqlDbClpArchivesTableName} +FROM ${settings.SqlDbClpArchivesTableName} `; interface SpaceSavingsItem { diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/index.module.css b/components/webui/client/src/pages/IngestPage/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/index.module.css rename to components/webui/client/src/pages/IngestPage/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/index.tsx b/components/webui/client/src/pages/IngestPage/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/index.tsx rename to components/webui/client/src/pages/IngestPage/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/ingestStatsStore.ts b/components/webui/client/src/pages/IngestPage/ingestStatsStore.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/IngestPage/ingestStatsStore.ts rename to components/webui/client/src/pages/IngestPage/ingestStatsStore.ts diff --git a/components/log-viewer-webui/client/src/pages/IngestPage/sqlConfig.ts b/components/webui/client/src/pages/IngestPage/sqlConfig.ts similarity index 88% rename from components/log-viewer-webui/client/src/pages/IngestPage/sqlConfig.ts rename to components/webui/client/src/pages/IngestPage/sqlConfig.ts index 1c8edbfdae..5b11a66c2e 100644 --- a/components/log-viewer-webui/client/src/pages/IngestPage/sqlConfig.ts +++ b/components/webui/client/src/pages/IngestPage/sqlConfig.ts @@ -1,12 +1,6 @@ import axios from "axios"; -enum SQL_CONFIG { - SqlDbClpArchivesTableName = "clp_archives", - SqlDbClpFilesTableName = "clp_files", - SqlDbCompressionJobsTableName = "compression_jobs", -} - /** * Column names for the `clp_archives` table. */ @@ -60,5 +54,4 @@ export { CLP_FILES_TABLE_COLUMN_NAMES, COMPRESSION_JOBS_TABLE_COLUMN_NAMES, querySql, - SQL_CONFIG, }; diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/QueryInput/index.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/QueryInput/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/QueryInput/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/QueryInput/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/QueryInput/typings.ts b/components/webui/client/src/pages/SearchPage/SearchControls/QueryInput/typings.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/QueryInput/typings.ts rename to components/webui/client/src/pages/SearchPage/SearchControls/QueryInput/typings.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/CancelButton.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/CancelButton.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/CancelButton.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/CancelButton.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SearchButton.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SearchButton.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SearchButton.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SearchButton.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/index.module.css b/components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/SearchButton/index.module.css rename to components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css b/components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css rename to components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/TimeRangeInput/utils.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/index.module.css b/components/webui/client/src/pages/SearchPage/SearchControls/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/index.module.css rename to components/webui/client/src/pages/SearchPage/SearchControls/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/index.tsx b/components/webui/client/src/pages/SearchPage/SearchControls/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchControls/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/search-requests.ts b/components/webui/client/src/pages/SearchPage/SearchControls/search-requests.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/search-requests.ts rename to components/webui/client/src/pages/SearchPage/SearchControls/search-requests.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/utils.ts b/components/webui/client/src/pages/SearchPage/SearchControls/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchControls/utils.ts rename to components/webui/client/src/pages/SearchPage/SearchControls/utils.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx rename to components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/index.module.css b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/index.module.css rename to components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.module.css b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.module.css rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.tsx b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/utils.ts b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/utils.ts rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/utils.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/index.tsx b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/typings.tsx b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/typings.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/typings.tsx rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/typings.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/useSearchResults.ts b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/useSearchResults.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/useSearchResults.ts rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/useSearchResults.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/utils.ts b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/utils.ts rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/utils.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/useAggregationResults.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts b/components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts rename to components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/utils.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx b/components/webui/client/src/pages/SearchPage/SearchState/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchState/index.tsx rename to components/webui/client/src/pages/SearchPage/SearchState/index.tsx diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchState/typings.ts b/components/webui/client/src/pages/SearchPage/SearchState/typings.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchState/typings.ts rename to components/webui/client/src/pages/SearchPage/SearchState/typings.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchState/useResultsMetadata.ts b/components/webui/client/src/pages/SearchPage/SearchState/useResultsMetadata.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchState/useResultsMetadata.ts rename to components/webui/client/src/pages/SearchPage/SearchState/useResultsMetadata.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts b/components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts rename to components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/index.module.css b/components/webui/client/src/pages/SearchPage/index.module.css similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/index.module.css rename to components/webui/client/src/pages/SearchPage/index.module.css diff --git a/components/log-viewer-webui/client/src/pages/SearchPage/index.tsx b/components/webui/client/src/pages/SearchPage/index.tsx similarity index 100% rename from components/log-viewer-webui/client/src/pages/SearchPage/index.tsx rename to components/webui/client/src/pages/SearchPage/index.tsx diff --git a/components/log-viewer-webui/client/src/router.tsx b/components/webui/client/src/router.tsx similarity index 100% rename from components/log-viewer-webui/client/src/router.tsx rename to components/webui/client/src/router.tsx diff --git a/components/log-viewer-webui/client/src/settings.ts b/components/webui/client/src/settings.ts similarity index 86% rename from components/log-viewer-webui/client/src/settings.ts rename to components/webui/client/src/settings.ts index 9dd14bf155..041fe0ac15 100644 --- a/components/log-viewer-webui/client/src/settings.ts +++ b/components/webui/client/src/settings.ts @@ -2,8 +2,11 @@ import axios from "axios"; type Settings = { - MongoDbSearchResultsMetadataCollectionName: string; ClpStorageEngine: string; + MongoDbSearchResultsMetadataCollectionName: string; + SqlDbClpArchivesTableName: string; + SqlDbClpFilesTableName: string; + SqlDbCompressionJobsTableName: string; }; /** diff --git a/components/log-viewer-webui/client/src/theme.tsx b/components/webui/client/src/theme.tsx similarity index 100% rename from components/log-viewer-webui/client/src/theme.tsx rename to components/webui/client/src/theme.tsx diff --git a/components/log-viewer-webui/client/src/typings/common.ts b/components/webui/client/src/typings/common.ts similarity index 100% rename from components/log-viewer-webui/client/src/typings/common.ts rename to components/webui/client/src/typings/common.ts diff --git a/components/log-viewer-webui/client/src/typings/config.ts b/components/webui/client/src/typings/config.ts similarity index 100% rename from components/log-viewer-webui/client/src/typings/config.ts rename to components/webui/client/src/typings/config.ts diff --git a/components/log-viewer-webui/client/src/typings/datetime.ts b/components/webui/client/src/typings/datetime.ts similarity index 100% rename from components/log-viewer-webui/client/src/typings/datetime.ts rename to components/webui/client/src/typings/datetime.ts diff --git a/components/log-viewer-webui/client/src/typings/query.ts b/components/webui/client/src/typings/query.ts similarity index 100% rename from components/log-viewer-webui/client/src/typings/query.ts rename to components/webui/client/src/typings/query.ts diff --git a/components/log-viewer-webui/client/src/ui/Loading.css b/components/webui/client/src/ui/Loading.css similarity index 100% rename from components/log-viewer-webui/client/src/ui/Loading.css rename to components/webui/client/src/ui/Loading.css diff --git a/components/log-viewer-webui/client/src/ui/Loading.tsx b/components/webui/client/src/ui/Loading.tsx similarity index 100% rename from components/log-viewer-webui/client/src/ui/Loading.tsx rename to components/webui/client/src/ui/Loading.tsx diff --git a/components/log-viewer-webui/client/src/ui/QueryStatus.tsx b/components/webui/client/src/ui/QueryStatus.tsx similarity index 100% rename from components/log-viewer-webui/client/src/ui/QueryStatus.tsx rename to components/webui/client/src/ui/QueryStatus.tsx diff --git a/components/log-viewer-webui/client/src/vite-env.d.ts b/components/webui/client/src/vite-env.d.ts similarity index 100% rename from components/log-viewer-webui/client/src/vite-env.d.ts rename to components/webui/client/src/vite-env.d.ts diff --git a/components/log-viewer-webui/client/tsconfig.json b/components/webui/client/tsconfig.json similarity index 100% rename from components/log-viewer-webui/client/tsconfig.json rename to components/webui/client/tsconfig.json diff --git a/components/log-viewer-webui/client/tsconfig/tsconfig.app.json b/components/webui/client/tsconfig/tsconfig.app.json similarity index 100% rename from components/log-viewer-webui/client/tsconfig/tsconfig.app.json rename to components/webui/client/tsconfig/tsconfig.app.json diff --git a/components/log-viewer-webui/client/tsconfig/tsconfig.base.json b/components/webui/client/tsconfig/tsconfig.base.json similarity index 100% rename from components/log-viewer-webui/client/tsconfig/tsconfig.base.json rename to components/webui/client/tsconfig/tsconfig.base.json diff --git a/components/log-viewer-webui/client/tsconfig/tsconfig.node.json b/components/webui/client/tsconfig/tsconfig.node.json similarity index 100% rename from components/log-viewer-webui/client/tsconfig/tsconfig.node.json rename to components/webui/client/tsconfig/tsconfig.node.json diff --git a/components/log-viewer-webui/client/vite.config.ts b/components/webui/client/vite.config.ts similarity index 92% rename from components/log-viewer-webui/client/vite.config.ts rename to components/webui/client/vite.config.ts index aa3b84042e..36b11bfb92 100644 --- a/components/log-viewer-webui/client/vite.config.ts +++ b/components/webui/client/vite.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ proxy: { "/query/": { // Below target should match the server's configuration in - // `components/log-viewer-webui/server/.env` (or `.env.local` if overridden) + // `components/webui/server/.env` (or `.env.local` if overridden) target: "http://localhost:3000/", changeOrigin: true, }, diff --git a/components/log-viewer-webui/common/index.ts b/components/webui/common/index.ts similarity index 100% rename from components/log-viewer-webui/common/index.ts rename to components/webui/common/index.ts diff --git a/components/log-viewer-webui/common/package.json b/components/webui/common/package.json similarity index 100% rename from components/log-viewer-webui/common/package.json rename to components/webui/common/package.json diff --git a/components/webui/imports/api/constants.js b/components/webui/imports/api/constants.js deleted file mode 100644 index 8877e9d0c8..0000000000 --- a/components/webui/imports/api/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Enum of the CLP package's possible storage engines. These must match the values in - * clp_py_utils.clp_config.StorageEngine. - * - * @enum {string} - */ -const CLP_STORAGE_ENGINES = Object.freeze({ - CLP: "clp", - CLP_S: "clp-s", -}); - -export {CLP_STORAGE_ENGINES}; diff --git a/components/webui/imports/api/ingestion/collections.js b/components/webui/imports/api/ingestion/collections.js deleted file mode 100644 index 9938317901..0000000000 --- a/components/webui/imports/api/ingestion/collections.js +++ /dev/null @@ -1,23 +0,0 @@ -import {Mongo} from "meteor/mongo"; - - -const CompressionJobsCollection = new Mongo.Collection( - Meteor.settings.public.CompressionJobsCollectionName -); - -/** - * Enum representing the statistics collection IDs. - * - * @enum {string} - */ -const STATS_COLLECTION_ID = Object.freeze({ - COMPRESSION: "compression", -}); - -const StatsCollection = new Mongo.Collection(Meteor.settings.public.StatsCollectionName); - -export { - CompressionJobsCollection, - STATS_COLLECTION_ID, - StatsCollection, -}; diff --git a/components/webui/imports/api/ingestion/constants.js b/components/webui/imports/api/ingestion/constants.js deleted file mode 100644 index cab5cbb7ed..0000000000 --- a/components/webui/imports/api/ingestion/constants.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable sort-keys */ -/** - * Enum of the column names for the `compression_jobs` table. - * - * @enum {string} - */ -const COMPRESSION_JOBS_TABLE_COLUMN_NAMES = Object.freeze({ - ID: "id", - STATUS: "status", - STATUS_MSG: "status_msg", - CREATION_TIME: "creation_time", - START_TIME: "start_time", - UPDATE_TIME: "update_time", - DURATION: "duration", - ORIGINAL_SIZE: "original_size", - UNCOMPRESSED_SIZE: "uncompressed_size", - COMPRESSED_SIZE: "compressed_size", - NUM_TASKS: "num_tasks", - NUM_TASKS_COMPLETED: "num_tasks_completed", - CLP_BINARY_VERSION: "clp_binary_version", - CLP_CONFIG: "clp_config", -}); -/* eslint-enable sort-keys */ - -/** - * @typedef {number} CompressionJobStatus - */ -let enumCompressionJobStatus; -/** - * Enum of compression job statuses, matching the `CompressionJobStatus` class in - * `job_orchestration.scheduler.constants`. - * - * @enum {CompressionJobStatus} - */ -const COMPRESSION_JOB_STATUS = Object.freeze({ - PENDING: (enumCompressionJobStatus = 0), - RUNNING: ++enumCompressionJobStatus, - SUCCEEDED: ++enumCompressionJobStatus, - FAILED: ++enumCompressionJobStatus, -}); - -/** - * List of waiting states for a compression job. - * - * @see COMPRESSION_JOB_STATUS - */ -const COMPRESSION_JOB_WAITING_STATES = Object.freeze([ - COMPRESSION_JOB_STATUS.PENDING, - COMPRESSION_JOB_STATUS.RUNNING, -]); - -/** - * Names for the compression job statuses. - * - * @type {ReadonlyArray} - */ -const COMPRESSION_JOB_STATUS_NAMES = Object.freeze(Object.keys(COMPRESSION_JOB_STATUS)); - -export { - COMPRESSION_JOB_STATUS, - COMPRESSION_JOB_STATUS_NAMES, - COMPRESSION_JOB_WAITING_STATES, - COMPRESSION_JOBS_TABLE_COLUMN_NAMES, -}; diff --git a/components/webui/imports/api/ingestion/server/CompressionDbManager.js b/components/webui/imports/api/ingestion/server/CompressionDbManager.js deleted file mode 100644 index 03a1dda4dd..0000000000 --- a/components/webui/imports/api/ingestion/server/CompressionDbManager.js +++ /dev/null @@ -1,52 +0,0 @@ -import {COMPRESSION_JOBS_TABLE_COLUMN_NAMES} from "../constants"; - - -/** - * Class for retrieving compression jobs from the database. - */ -class CompressionDbManager { - #sqlDbConnPool; - - #compressionJobsTableName; - - /** - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.compressionJobsTableName - */ - constructor (sqlDbConnPool, {compressionJobsTableName}) { - this.#sqlDbConnPool = sqlDbConnPool; - this.#compressionJobsTableName = compressionJobsTableName; - } - - /** - * Retrieves compression jobs that are updated on or after a specific time. - * - * @param {number} lastUpdateTimestampSeconds - * @return {Promise} Job objects with fields with the names in - * `COMPRESSION_JOBS_TABLE_COLUMN_NAMES` - */ - async getCompressionJobs (lastUpdateTimestampSeconds) { - const queryString = ` - SELECT - UNIX_TIMESTAMP() as retrieval_time, - id as _id, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.STATUS}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.STATUS_MSG}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.START_TIME}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.UPDATE_TIME}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.DURATION}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.UNCOMPRESSED_SIZE}, - ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.COMPRESSED_SIZE} - FROM ${this.#compressionJobsTableName} - WHERE ${COMPRESSION_JOBS_TABLE_COLUMN_NAMES.UPDATE_TIME} >= - FROM_UNIXTIME(${lastUpdateTimestampSeconds}) - 1 - ORDER BY _id DESC;`; - - const [results] = await this.#sqlDbConnPool.query(queryString); - - return results; - } -} - -export default CompressionDbManager; diff --git a/components/webui/imports/api/ingestion/server/StatsDbManager.js b/components/webui/imports/api/ingestion/server/StatsDbManager.js deleted file mode 100644 index 2198d21339..0000000000 --- a/components/webui/imports/api/ingestion/server/StatsDbManager.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Enum of the column names for the `clp_archives` table. - * - * @enum {string} - */ -const CLP_ARCHIVES_TABLE_COLUMN_NAMES = Object.freeze({ - BEGIN_TIMESTAMP: "begin_timestamp", - END_TIMESTAMP: "end_timestamp", - UNCOMPRESSED_SIZE: "uncompressed_size", - SIZE: "size", -}); - -/** - * Enum of the column names for the `clp_files` table. - * - * @enum {string} - */ -const CLP_FILES_TABLE_COLUMN_NAMES = Object.freeze({ - ORIG_FILE_ID: "orig_file_id", - NUM_MESSAGES: "num_messages", -}); - -/** - * Class for retrieving compression stats from the database. - */ -class StatsDbManager { - #sqlDbConnPool; - - #clpArchivesTableName; - - #clpFilesTableName; - - /** - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.clpArchivesTableName - * @param {string} tableNames.clpFilesTableName - */ - constructor (sqlDbConnPool, { - clpArchivesTableName, - clpFilesTableName, - }) { - this.#sqlDbConnPool = sqlDbConnPool; - - this.#clpArchivesTableName = clpArchivesTableName; - this.#clpFilesTableName = clpFilesTableName; - } - - /** - * Queries compression stats. - * - * @return {Promise} - * @throws {Error} on error. - */ - async getCompressionStats () { - /* eslint-disable @stylistic/js/max-len */ - const [queryStats] = await this.#sqlDbConnPool.query(` - SELECT - a.begin_timestamp AS begin_timestamp, - a.end_timestamp AS end_timestamp, - a.total_uncompressed_size AS total_uncompressed_size, - a.total_compressed_size AS total_compressed_size, - b.num_files AS num_files, - b.num_messages AS num_messages - FROM - ( - SELECT - MIN(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.BEGIN_TIMESTAMP}) AS begin_timestamp, - MAX(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.END_TIMESTAMP}) AS end_timestamp, - SUM(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.UNCOMPRESSED_SIZE}) AS total_uncompressed_size, - SUM(${CLP_ARCHIVES_TABLE_COLUMN_NAMES.SIZE}) AS total_compressed_size - FROM ${this.#clpArchivesTableName} - ) a, - ( - SELECT - NULLIF(COUNT(DISTINCT ${CLP_FILES_TABLE_COLUMN_NAMES.ORIG_FILE_ID}), 0) AS num_files, - SUM(${CLP_FILES_TABLE_COLUMN_NAMES.NUM_MESSAGES}) AS num_messages - FROM ${this.#clpFilesTableName} - ) b; - `); - /* eslint-enable @stylistic/js/max-len */ - - return queryStats[0]; - } -} - -export default StatsDbManager; diff --git a/components/webui/imports/api/ingestion/server/publications.js b/components/webui/imports/api/ingestion/server/publications.js deleted file mode 100644 index 8febca51f4..0000000000 --- a/components/webui/imports/api/ingestion/server/publications.js +++ /dev/null @@ -1,232 +0,0 @@ -import {Meteor} from "meteor/meteor"; - -import {logger} from "/imports/utils/logger"; -import {MONGO_SORT_BY_ID} from "/imports/utils/mongo"; - -import { - CompressionJobsCollection, - STATS_COLLECTION_ID, - StatsCollection, -} from "../collections"; -import CompressionDbManager from "./CompressionDbManager"; -import StatsDbManager from "./StatsDbManager"; - - -const COMPRESSION_JOBS_REFRESH_INTERVAL_MILLIS = 1000; - -const STATS_REFRESH_INTERVAL_MILLIS = 5000; - -/** - * @type {CompressionDbManager|null} - */ -let compressionDbManager = null; - -/** - * @type {StatsDbManager|null} - */ -let statsDbManager = null; - -/** - * @type {number|null} - */ -let compressionJobsRefreshTimeout = null; - -/** - * @type {number|null} - */ -let statsRefreshInterval = null; - -/** - * @type {number} - */ -let lastUpdateTimestampSeconds = 0; - -/** - * Updates the compression statistics in the StatsCollection. - * - * @return {Promise} - */ -const refreshCompressionStats = async () => { - if (0 === Meteor.server.stream_server.all_sockets().length) { - return; - } - - const stats = await statsDbManager.getCompressionStats(); - const filter = { - _id: STATS_COLLECTION_ID.COMPRESSION, - }; - const modifier = { - $set: stats, - }; - const options = { - upsert: true, - }; - - await StatsCollection.updateAsync(filter, modifier, options); -}; - -/** - * Updates the compression jobs in the CompressionJobsCollection. - * - * @return {Promise} - */ -const refreshCompressionJobs = async () => { - if (null !== compressionJobsRefreshTimeout) { - // Clear the timeout in case this method is not called due to the timeout expiring. - Meteor.clearTimeout(compressionJobsRefreshTimeout); - compressionJobsRefreshTimeout = null; - } - if (0 === Meteor.server.stream_server.all_sockets().length) { - compressionJobsRefreshTimeout = Meteor.setTimeout( - refreshCompressionJobs, - COMPRESSION_JOBS_REFRESH_INTERVAL_MILLIS - ); - - return; - } - - const jobs = await compressionDbManager.getCompressionJobs( - lastUpdateTimestampSeconds - ); - - if (0 !== jobs.length) { - // `refreshCompressionJobs()` shall not be run concurrently - // and therefore incurs no race condition. - // eslint-disable-next-line require-atomic-updates - lastUpdateTimestampSeconds = jobs[0].retrieval_time; - } - - const operations = jobs.map((doc) => ({ - updateOne: { - filter: {_id: doc._id}, - update: {$set: doc}, - upsert: true, - }, - })); - - if (0 !== operations.length) { - await CompressionJobsCollection.rawCollection().bulkWrite(operations); - } - - // `refreshCompressionJobs()` shall not be run concurrently and therefore incurs no race - // condition. - // eslint-disable-next-line require-atomic-updates - compressionJobsRefreshTimeout = Meteor.setTimeout( - refreshCompressionJobs, - COMPRESSION_JOBS_REFRESH_INTERVAL_MILLIS - ); -}; - -/** - * Initializes the CompressionDbManager and starts a timeout timer (`compressionJobsRefreshTimeout`) - * for compression job updates. - * - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.compressionJobsTableName - * @throws {Error} on error. - */ -const initCompressionDbManager = (sqlDbConnPool, { - compressionJobsTableName, -}) => { - compressionDbManager = new CompressionDbManager(sqlDbConnPool, { - compressionJobsTableName, - }); - - compressionJobsRefreshTimeout = Meteor.setTimeout( - refreshCompressionJobs, - COMPRESSION_JOBS_REFRESH_INTERVAL_MILLIS - ); -}; - -/** - * De-initializes the CompressionDbManager by clearing the timeout timer for compression job - * updates (`refreshCompressionJobs`). - */ -const deinitCompressionDbManager = () => { - if (null !== compressionJobsRefreshTimeout) { - Meteor.clearTimeout(compressionJobsRefreshTimeout); - compressionJobsRefreshTimeout = null; - } -}; - -/** - * Initializes the StatsDbManager and starts an interval timer (`refreshMeteorInterval`) for - * compression stats updates. - * - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.clpArchivesTableName - * @param {string} tableNames.clpFilesTableName - * @throws {Error} on error. - */ -const initStatsDbManager = (sqlDbConnPool, { - clpArchivesTableName, - clpFilesTableName, -}) => { - statsDbManager = new StatsDbManager(sqlDbConnPool, { - clpArchivesTableName, - clpFilesTableName, - }); - - statsRefreshInterval = Meteor.setInterval( - refreshCompressionStats, - STATS_REFRESH_INTERVAL_MILLIS - ); -}; - -/** - * De-initializes the StatsDbManager by clearing the interval timer for compression stats updates - * (`refreshMeteorInterval`). - */ -const deinitStatsDbManager = () => { - if (null !== statsRefreshInterval) { - Meteor.clearInterval(statsRefreshInterval); - statsRefreshInterval = null; - } -}; - -/** - * Updates and publishes compression job statuses. - * - * @param {string} publicationName - * @return {Mongo.Cursor} - */ -Meteor.publish(Meteor.settings.public.CompressionJobsCollectionName, async () => { - logger.debug(`Subscription '${Meteor.settings.public.CompressionJobsCollectionName}'`); - - await refreshCompressionJobs(); - - const findOptions = { - disableOplog: true, - pollingIntervalMs: COMPRESSION_JOBS_REFRESH_INTERVAL_MILLIS, - sort: [MONGO_SORT_BY_ID], - }; - - return CompressionJobsCollection.find({}, findOptions); -}); - -/** - * Updates and publishes compression statistics. - * - * @param {string} publicationName - * @return {Mongo.Cursor} - */ -Meteor.publish(Meteor.settings.public.StatsCollectionName, async () => { - logger.debug(`Subscription '${Meteor.settings.public.StatsCollectionName}'`); - - await refreshCompressionStats(); - - const filter = { - _id: STATS_COLLECTION_ID.COMPRESSION, - }; - - return StatsCollection.find(filter); -}); - -export { - deinitCompressionDbManager, - deinitStatsDbManager, - initCompressionDbManager, - initStatsDbManager, -}; diff --git a/components/webui/imports/api/ingestion/types.js b/components/webui/imports/api/ingestion/types.js deleted file mode 100644 index e505f9f274..0000000000 --- a/components/webui/imports/api/ingestion/types.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @typedef {object} CompressionJob - * @property {number} _id - * @property {number} status - * @property {string} status_msg - * @property {Date} start_time - * @property {number} duration - * @property {string} uncompressed_size - * @property {string} compressed_size - */ - -/** - * @typedef {object} CompressionStats - * @property {number|null} begin_timestamp - * @property {number|null} end_timestamp - * @property {number|null} total_uncompressed_size - * @property {number|null} total_compressed_size - * @property {number|null} num_files - * @property {number|null} num_messages - */ diff --git a/components/webui/imports/api/search/SearchJobCollectionsManager.js b/components/webui/imports/api/search/SearchJobCollectionsManager.js deleted file mode 100644 index 721d295a6d..0000000000 --- a/components/webui/imports/api/search/SearchJobCollectionsManager.js +++ /dev/null @@ -1,51 +0,0 @@ -const ERROR_NAME_COLLECTION_DROPPED = "collection-dropped"; - -/** - * Class to keep track of MongoDB collections created for search jobs, ensuring all collections have - * unique names. - */ -class SearchJobCollectionsManager { - #collections; - - constructor () { - this.#collections = new Map(); - } - - /** - * Gets, or if it doesn't exist, creates a MongoDB collection named with the given job ID. - * - * @param {number} jobId - * @return {Mongo.Collection} - * @throws {Meteor.Error} with ERROR_NAME_COLLECTION_DROPPED if the collection was already - * dropped. - */ - getOrCreateCollection (jobId) { - const name = jobId.toString(); - if ("undefined" === typeof this.#collections.get(name)) { - this.#collections.set(name, new Mongo.Collection(name)); - } else if (null === this.#collections.get(name)) { - throw new Meteor.Error( - ERROR_NAME_COLLECTION_DROPPED, - `Collection ${name} has been dropped.` - ); - } - - return this.#collections.get(name); - } - - /** - * Drops the MongoDB collection with the given job ID. - * - * @param {number} jobId - */ - async dropCollection (jobId) { - const name = jobId.toString(); - const collection = this.#collections.get(name); - - await collection.dropCollectionAsync(); - this.#collections.set(name, null); - } -} - -export default SearchJobCollectionsManager; -export {ERROR_NAME_COLLECTION_DROPPED}; diff --git a/components/webui/imports/api/search/collections.js b/components/webui/imports/api/search/collections.js deleted file mode 100644 index 1642b0c9c6..0000000000 --- a/components/webui/imports/api/search/collections.js +++ /dev/null @@ -1,19 +0,0 @@ -import {Mongo} from "meteor/mongo"; - - -/** - * @typedef {object} SearchResultsMetadata - * @property {string} _id - * @property {string|null} errorMsg - * @property {SearchSignal} lastSignal - * @property {number} numTotalResults - */ - -/** - * A MongoDB collection for storing metadata about search results. - */ -const SearchResultsMetadataCollection = new Mongo.Collection( - Meteor.settings.public.SearchResultsMetadataCollectionName -); - -export {SearchResultsMetadataCollection}; diff --git a/components/webui/imports/api/search/constants.js b/components/webui/imports/api/search/constants.js deleted file mode 100644 index baedddb859..0000000000 --- a/components/webui/imports/api/search/constants.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @typedef {string} SearchSignal - */ - -/** - * Enum of search-related signals. - * - * This includes request and response signals for various search operations and their respective - * states. - * - * @enum {SearchSignal} - */ -const SEARCH_SIGNAL = Object.freeze({ - NONE: "none", - - REQ_CANCELLING: "req-cancelling", - REQ_CLEARING: "req-clearing", - REQ_QUERYING: "req-querying", - - RESP_DONE: "resp-done", - RESP_QUERYING: "resp-querying", -}); - -/** - * Checks if the given search signal is a search signal request. - * - * @param {SearchSignal} s - * @return {boolean} - */ -const isSearchSignalReq = (s) => s.startsWith("req-"); - -/** - * Checks if the given search signal is a search signal response. - * - * @param {SearchSignal} s - * @return {boolean} - */ -const isSearchSignalResp = (s) => s.startsWith("resp-"); - -/** - * Checks if the given search signal is a querying request / response. - * - * @param {SearchSignal} s - * @return {boolean} - */ -const isSearchSignalQuerying = (s) => s.endsWith("-querying"); - -/** - * Checks if the given search signal is an operation in progress, which can be used as a - * condition to disable UI elements. - * - * @param {SearchSignal} s - * @return {boolean} - */ -const isOperationInProgress = (s) => ( - (true === isSearchSignalReq(s)) || - (true === isSearchSignalQuerying(s)) -); - -/* eslint-disable sort-keys */ -let enumQueryJobStatus; -/** - * Enum of job statuses, matching the `QueryJobStatus` class in - * `job_orchestration.query_scheduler.constants`. - * - * @enum {number} - */ -const QUERY_JOB_STATUS = Object.freeze({ - PENDING: (enumQueryJobStatus = 0), - RUNNING: ++enumQueryJobStatus, - SUCCEEDED: ++enumQueryJobStatus, - FAILED: ++enumQueryJobStatus, - CANCELLING: ++enumQueryJobStatus, - CANCELLED: ++enumQueryJobStatus, -}); -/* eslint-enable sort-keys */ - -const QUERY_JOB_STATUS_WAITING_STATES = [ - QUERY_JOB_STATUS.PENDING, - QUERY_JOB_STATUS.RUNNING, - QUERY_JOB_STATUS.CANCELLING, -]; - -/* eslint-disable sort-keys */ -let enumQueryType; -/** - * Enum of job type, matching the `QueryJobType` class in - * `job_orchestration.query_scheduler.constants`. - * - * @enum {number} - */ -const QUERY_JOB_TYPE = Object.freeze({ - SEARCH_OR_AGGREGATION: (enumQueryType = 0), - EXTRACT_IR: ++enumQueryType, -}); -/* eslint-enable sort-keys */ - -/** - * Enum of Mongo Collection sort orders. - * - * @enum {string} - */ -const MONGO_SORT_ORDER = Object.freeze({ - ASCENDING: "asc", - DESCENDING: "desc", -}); - -/** - * Enum of search results cache fields. - * - * @enum {string} - */ -const SEARCH_RESULTS_FIELDS = Object.freeze({ - ID: "_id", - TIMESTAMP: "timestamp", -}); - -/** - * The maximum number of results to retrieve for a search. - */ -const SEARCH_MAX_NUM_RESULTS = 1000; - -export { - isOperationInProgress, - isSearchSignalQuerying, - isSearchSignalReq, - isSearchSignalResp, - MONGO_SORT_ORDER, - QUERY_JOB_STATUS, - QUERY_JOB_STATUS_WAITING_STATES, - QUERY_JOB_TYPE, - SEARCH_MAX_NUM_RESULTS, - SEARCH_RESULTS_FIELDS, - SEARCH_SIGNAL, -}; diff --git a/components/webui/imports/api/search/server/QueryJobsDbManager.js b/components/webui/imports/api/search/server/QueryJobsDbManager.js deleted file mode 100644 index 9efc4771cc..0000000000 --- a/components/webui/imports/api/search/server/QueryJobsDbManager.js +++ /dev/null @@ -1,149 +0,0 @@ -import {encode} from "@msgpack/msgpack"; - -import {sleep} from "/imports/utils/misc"; - -import { - QUERY_JOB_STATUS, - QUERY_JOB_STATUS_WAITING_STATES, - QUERY_JOB_TYPE, -} from "../constants"; - - -/** - * Interval in milliseconds for polling the completion status of a job. - */ -const JOB_COMPLETION_STATUS_POLL_INTERVAL_MILLIS = 0.5; - -/** - * Enum of the `query_jobs` table's column names. - * - * @enum {string} - */ -const QUERY_JOBS_TABLE_COLUMN_NAMES = Object.freeze({ - ID: "id", - STATUS: "status", - TYPE: "type", - JOB_CONFIG: "job_config", -}); - -/** - * Class for submitting and monitoring query jobs in the database. - */ -class QueryJobsDbManager { - #sqlDbConnPool; - - #queryJobsTableName; - - /** - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.queryJobsTableName - */ - constructor (sqlDbConnPool, {queryJobsTableName}) { - this.#sqlDbConnPool = sqlDbConnPool; - this.#queryJobsTableName = queryJobsTableName; - } - - /** - * Submits a search job to the database. - * - * @param {object} searchConfig The arguments for the query. - * @return {Promise} The job's ID. - * @throws {Error} on error. - */ - async submitSearchJob (searchConfig) { - const [queryInsertResults] = await this.#sqlDbConnPool.query( - `INSERT INTO ${this.#queryJobsTableName} - (${QUERY_JOBS_TABLE_COLUMN_NAMES.JOB_CONFIG}, - ${QUERY_JOBS_TABLE_COLUMN_NAMES.TYPE}) - VALUES (?, ?)`, - [Buffer.from(encode(searchConfig)), - QUERY_JOB_TYPE.SEARCH_OR_AGGREGATION], - ); - - return queryInsertResults.insertId; - } - - /** - * Submits an aggregation job to the database. - * - * @param {object} searchConfig The arguments for the query. - * @param {number} timeRangeBucketSizeMillis - * @return {Promise} The aggregation job's ID. - * @throws {Error} on error. - */ - async submitAggregationJob (searchConfig, timeRangeBucketSizeMillis) { - const searchAggregationConfig = { - ...searchConfig, - aggregation_config: { - count_by_time_bucket_size: timeRangeBucketSizeMillis, - }, - }; - - return await this.submitSearchJob(searchAggregationConfig); - } - - /** - * Submits a query cancellation request to the database. - * - * @param {number} jobId ID of the job to cancel. - * @return {Promise} - * @throws {Error} on error. - */ - async submitQueryCancellation (jobId) { - await this.#sqlDbConnPool.query( - `UPDATE ${this.#queryJobsTableName} - SET ${QUERY_JOBS_TABLE_COLUMN_NAMES.STATUS} = ${QUERY_JOB_STATUS.CANCELLING} - WHERE ${QUERY_JOBS_TABLE_COLUMN_NAMES.ID} = ? - AND ${QUERY_JOBS_TABLE_COLUMN_NAMES.STATUS} - IN (${QUERY_JOB_STATUS.PENDING}, ${QUERY_JOB_STATUS.RUNNING})`, - jobId, - ); - } - - /** - * Waits for the job to complete. - * - * @param {number} jobId - * @return {Promise} - * @throws {Error} on MySQL error, if the job wasn't found in the database, if the job was - * cancelled, or if the job completed in an unexpected state. - */ - async awaitJobCompletion (jobId) { - while (true) { - let rows; - try { - const [queryRows] = await this.#sqlDbConnPool.query( - ` - SELECT ${QUERY_JOBS_TABLE_COLUMN_NAMES.STATUS} - FROM ${this.#queryJobsTableName} - WHERE ${QUERY_JOBS_TABLE_COLUMN_NAMES.ID} = ? - `, - jobId, - ); - - rows = queryRows; - } catch (e) { - throw new Error(`Failed to query status for job ${jobId} - ${e}`); - } - if (0 === rows.length) { - throw new Error(`Job ${jobId} not found in database.`); - } - const status = rows[0][QUERY_JOBS_TABLE_COLUMN_NAMES.STATUS]; - - if (false === QUERY_JOB_STATUS_WAITING_STATES.includes(status)) { - if (QUERY_JOB_STATUS.CANCELLED === status) { - throw new Error(`Job ${jobId} was cancelled.`); - } else if (QUERY_JOB_STATUS.SUCCEEDED !== status) { - throw new Error(`Job ${jobId} exited with unexpected status=${status}: ` + - `${Object.keys(QUERY_JOB_STATUS)[status]}.`); - } - break; - } - - await sleep(JOB_COMPLETION_STATUS_POLL_INTERVAL_MILLIS); - } - } -} - -export default QueryJobsDbManager; diff --git a/components/webui/imports/api/search/server/collections.js b/components/webui/imports/api/search/server/collections.js deleted file mode 100644 index 58e5db06c3..0000000000 --- a/components/webui/imports/api/search/server/collections.js +++ /dev/null @@ -1,6 +0,0 @@ -import SearchJobCollectionsManager from "../SearchJobCollectionsManager"; - - -const searchJobCollectionsManager = new SearchJobCollectionsManager(); - -export {searchJobCollectionsManager}; diff --git a/components/webui/imports/api/search/server/methods.js b/components/webui/imports/api/search/server/methods.js deleted file mode 100644 index 695b6b4a65..0000000000 --- a/components/webui/imports/api/search/server/methods.js +++ /dev/null @@ -1,263 +0,0 @@ -import {Meteor} from "meteor/meteor"; - -import {logger} from "/imports/utils/logger"; - -import {SearchResultsMetadataCollection} from "../collections"; -import { - SEARCH_MAX_NUM_RESULTS, - SEARCH_SIGNAL, -} from "../constants"; -import {ERROR_NAME_COLLECTION_DROPPED} from "../SearchJobCollectionsManager"; -import {searchJobCollectionsManager} from "./collections"; -import QueryJobsDbManager from "./QueryJobsDbManager"; - - -/** - * @type {QueryJobsDbManager|null} - */ -let queryJobsDbManager = null; - -/** - * Initializes the QueryJobsDbManager. - * - * @param {import("mysql2/promise").Pool} sqlDbConnPool - * @param {object} tableNames - * @param {string} tableNames.queryJobsTableName - * @throws {Error} on error. - */ -const initQueryJobsDbManager = (sqlDbConnPool, {queryJobsTableName}) => { - queryJobsDbManager = new QueryJobsDbManager(sqlDbConnPool, {queryJobsTableName}); -}; - -/** - * Modifies the search results metadata for a given job ID. - * - * @param {object} filter - * @param {number} filter.jobId - * @param {string} filter.lastSignal - * @param {SearchResultsMetadata} fields The fields to be updated in the search results metadata. - */ -const updateSearchResultsMeta = ({ - jobId, - lastSignal, -}, fields) => { - const filter = { - _id: jobId.toString(), - lastSignal: lastSignal, - }; - - const modifier = { - $set: fields, - }; - - logger.debug("SearchResultsMetadataCollection modifier = ", modifier); - SearchResultsMetadataCollection.update(filter, modifier); -}; - -/** - * Updates the search signal when the specified job finishes. - * - * @param {object} props - * @param {number} props.searchJobId of the job to monitor - * @param {number} props.aggregationJobId of the job to monitor - */ -const updateSearchSignalWhenJobsFinish = async ({ - searchJobId, - aggregationJobId, -}) => { - let errorMsg; - try { - await queryJobsDbManager.awaitJobCompletion(searchJobId); - await queryJobsDbManager.awaitJobCompletion(aggregationJobId); - } catch (e) { - errorMsg = e.message; - } - - let numResultsInCollection = -1; - try { - numResultsInCollection = await searchJobCollectionsManager - .getOrCreateCollection(searchJobId) - .countDocuments(); - } catch (e) { - if (ERROR_NAME_COLLECTION_DROPPED === e.error) { - logger.warn(`Collection ${searchJobId} has been dropped.`); - - return; - } - throw e; - } - - updateSearchResultsMeta({ - jobId: searchJobId, - lastSignal: SEARCH_SIGNAL.RESP_QUERYING, - }, { - lastSignal: SEARCH_SIGNAL.RESP_DONE, - errorMsg: errorMsg, - numTotalResults: Math.min( - numResultsInCollection, - SEARCH_MAX_NUM_RESULTS - ), - }); -}; - -/** - * Creates MongoDB indexes for a specific job's collection. - * - * @param {number} searchJobId used to identify the Mongo Collection to add indexes - */ -const createMongoIndexes = async (searchJobId) => { - const timestampAscendingIndex = { - key: { - timestamp: 1, - _id: 1, - }, - name: "timestamp-ascending", - }; - const timestampDescendingIndex = { - key: { - timestamp: -1, - _id: -1, - }, - name: "timestamp-descending", - }; - - const queryJobCollection = searchJobCollectionsManager.getOrCreateCollection(searchJobId); - const queryJobRawCollection = queryJobCollection.rawCollection(); - await queryJobRawCollection.createIndexes([ - timestampAscendingIndex, - timestampDescendingIndex, - ]); -}; - -Meteor.methods({ - /** - * @typedef {object} SubmitQueryResp - * @property {number} searchJobId - * @property {number} aggregationJobId - */ - /** - * Submits a search query and initiates the search process. - * - * @param {object} props - * @param {string} props.queryString - * @param {number} props.timestampBegin - * @param {number} props.timestampEnd - * @param {boolean} props.ignoreCase - * @param {number} props.timeRangeBucketSizeMillis - * @return {SubmitQueryResp} - */ - async "search.submitQuery" ({ - queryString, - timestampBegin, - timestampEnd, - ignoreCase, - timeRangeBucketSizeMillis, - }) { - this.unblock(); - - const args = { - query_string: queryString, - - begin_timestamp: timestampBegin, - end_timestamp: timestampEnd, - ignore_case: ignoreCase, - max_num_results: SEARCH_MAX_NUM_RESULTS, - }; - - logger.info("search.submitQuery args =", args); - - let searchJobId; - let aggregationJobId; - try { - searchJobId = await queryJobsDbManager.submitSearchJob(args); - aggregationJobId = - await queryJobsDbManager.submitAggregationJob(args, timeRangeBucketSizeMillis); - } catch (e) { - const errorMsg = "Unable to submit search/aggregation job to the SQL database."; - logger.error(errorMsg, e.toString()); - throw new Meteor.Error("query-submit-error", errorMsg); - } - - SearchResultsMetadataCollection.insert({ - _id: searchJobId.toString(), - lastSignal: SEARCH_SIGNAL.RESP_QUERYING, - errorMsg: null, - }); - - Meteor.defer(async () => { - await updateSearchSignalWhenJobsFinish({ - searchJobId, - aggregationJobId, - }); - }); - - await createMongoIndexes(searchJobId); - - return {searchJobId, aggregationJobId}; - }, - - /** - * Clears the results of a search operation identified by jobId. - * - * @param {object} props - * @param {number} props.searchJobId of the search results to clear - * @param {number} props.aggregationJobId of the search results to clear - */ - async "search.clearResults" ({ - searchJobId, - aggregationJobId, - }) { - this.unblock(); - - logger.info(`search.clearResults searchJobId=${searchJobId}, ` + - `aggregationJobId=${aggregationJobId}`); - - try { - await searchJobCollectionsManager.dropCollection(searchJobId); - await searchJobCollectionsManager.dropCollection(aggregationJobId); - } catch (e) { - const errorMsg = `Failed to clear search results for searchJobId=${searchJobId}, ` + - `aggregationJobId=${aggregationJobId}`; - - logger.error(errorMsg, e.toString()); - throw new Meteor.Error("clear-results-error", errorMsg); - } - }, - - /** - * Cancels an ongoing search operation identified by jobId. - * - * @param {object} props - * @param {number} props.searchJobId - * @param {number} props.aggregationJobId - */ - async "search.cancelOperation" ({ - searchJobId, - aggregationJobId, - }) { - this.unblock(); - - logger.info(`search.cancelOperation searchJobId=${searchJobId}, ` + - `aggregationJobId=${aggregationJobId}`); - - try { - await queryJobsDbManager.submitQueryCancellation(searchJobId); - await queryJobsDbManager.submitQueryCancellation(aggregationJobId); - updateSearchResultsMeta({ - jobId: searchJobId, - lastSignal: SEARCH_SIGNAL.RESP_QUERYING, - }, { - lastSignal: SEARCH_SIGNAL.RESP_DONE, - errorMsg: "Query cancelled before it could be completed.", - }); - } catch (e) { - const errorMsg = `Failed to submit cancel request for searchJobId=${searchJobId},` + - `aggregationJobId=${aggregationJobId}.`; - - logger.error(errorMsg, e.toString()); - throw new Meteor.Error("query-cancel-error", errorMsg); - } - }, -}); - -export {initQueryJobsDbManager}; diff --git a/components/webui/imports/api/search/server/publications.js b/components/webui/imports/api/search/server/publications.js deleted file mode 100644 index 79650ca788..0000000000 --- a/components/webui/imports/api/search/server/publications.js +++ /dev/null @@ -1,117 +0,0 @@ -import {Meteor} from "meteor/meteor"; - -import {logger} from "/imports/utils/logger"; -import { - MONGO_SORT_BY_ID, - MONGO_SORT_ORDER, -} from "/imports/utils/mongo"; - -import {SearchResultsMetadataCollection} from "../collections"; -import { - SEARCH_MAX_NUM_RESULTS, - SEARCH_RESULTS_FIELDS, -} from "../constants"; -import {searchJobCollectionsManager} from "./collections"; - - -/** - * The interval, in milliseconds, at which the Meteor Mongo collection is polled. - */ -const COLLECTION_POLL_INTERVAL_MILLIS = 250; - -/** - * The maximum value (2^31 - 1) that can be used as a polling interval in JavaScript. - * Reference: https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value - */ -// eslint-disable-next-line no-magic-numbers -const JS_MAX_DELAY_VALUE = (2 ** 31) - 1; - -/** - * Publishes search results metadata for a specific job. - * - * @param {string} publicationName - * @param {object} props - * @param {string} props.searchJobId of the search operation - * @return {Mongo.Cursor} cursor that provides access to the search results metadata. - */ -Meteor.publish(Meteor.settings.public.SearchResultsMetadataCollectionName, ({searchJobId}) => { - logger.debug( - `Subscription '${Meteor.settings.public.SearchResultsMetadataCollectionName}'`, - `searchJobId=${searchJobId}` - ); - - const filter = { - _id: searchJobId.toString(), - }; - - return SearchResultsMetadataCollection.find(filter); -}); - -/** - * Publishes search results for a specific search job. - * - * @param {string} publicationName - * @param {object} props - * @param {string} props.searchJobId - * @param {boolean} props.isExpectingUpdates Whether the subscriber - * expects that the collection will be updated. - * @return {Mongo.Cursor} cursor that provides access to the search results. - */ -Meteor.publish(Meteor.settings.public.SearchResultsCollectionName, ({ - searchJobId, - isExpectingUpdates, -}) => { - logger.debug( - `Subscription '${Meteor.settings.public.SearchResultsCollectionName}'`, - `searchJobId=${searchJobId}`, - `isExpectingUpdates=${isExpectingUpdates}` - ); - - const collection = searchJobCollectionsManager.getOrCreateCollection(searchJobId); - const findOptions = { - sort: [ - /* eslint-disable @stylistic/js/array-element-newline */ - [SEARCH_RESULTS_FIELDS.TIMESTAMP, MONGO_SORT_ORDER.DESCENDING], - MONGO_SORT_BY_ID, - /* eslint-enable @stylistic/js/array-element-newline */ - ], - limit: SEARCH_MAX_NUM_RESULTS, - disableOplog: true, - pollingIntervalMs: isExpectingUpdates ? - COLLECTION_POLL_INTERVAL_MILLIS : - JS_MAX_DELAY_VALUE, - }; - - return collection.find({}, findOptions); -}); - -/** - * Publishes search aggregation results for a specific aggregation job. - * - * @param {string} publicationName - * @param {object} props - * @param {string} props.aggregationJobId - * @param {boolean} props.isExpectingUpdates Whether the subscriber - * expects that the collection will be updated. - * @return {Mongo.Cursor} cursor that provides access to the aggregation results. - */ -Meteor.publish(Meteor.settings.public.AggregationResultsCollectionName, ({ - aggregationJobId, - isExpectingUpdates, -}) => { - logger.debug( - `Subscription '${Meteor.settings.public.AggregationResultsCollectionName}'`, - `aggregationJobId=${aggregationJobId}`, - `isExpectingUpdates=${isExpectingUpdates}` - ); - - const collection = searchJobCollectionsManager.getOrCreateCollection(aggregationJobId); - const findOptions = { - disableOplog: true, - pollingIntervalMs: isExpectingUpdates ? - COLLECTION_POLL_INTERVAL_MILLIS : - JS_MAX_DELAY_VALUE, - }; - - return collection.find({}, findOptions); -}); diff --git a/components/webui/imports/api/search/types.js b/components/webui/imports/api/search/types.js deleted file mode 100644 index bb0d00ad4f..0000000000 --- a/components/webui/imports/api/search/types.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @typedef {object} TimeRange - * @property {import("dayjs").Dayjs} begin - * @property {import("dayjs").Dayjs} end - */ - -/** - * @typedef {object} TimelineConfig - * @property {import("dayjs/plugin/duration").Duration} bucketDuration - * @property {TimeRange} range - */ - -/** - * @typedef {object} TimelineBucket - * @property {number} timestamp Timestamp as milliseconds since the Unix epoch. - * @property {number} count - */ - -/** - * @typedef {object} ChartJsDatasetItem - * @property {number} x - * @property {number} y - */ diff --git a/components/webui/imports/ui/App.jsx b/components/webui/imports/ui/App.jsx deleted file mode 100644 index dd8e9766c7..0000000000 --- a/components/webui/imports/ui/App.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import { - useEffect, - useState, -} from "react"; -import { - Redirect, - Route, - Switch, -} from "react-router"; - -import { - faFileUpload, - faSearch, -} from "@fortawesome/free-solid-svg-icons"; - -import {LOCAL_STORAGE_KEYS} from "./constants"; -import IngestView from "./IngestView/IngestView"; -import SearchView from "./SearchView/SearchView"; -import Sidebar from "./Sidebar/Sidebar"; - -import "./App.scss"; - - -const ROUTES = [ - { - path: "/ingest", - label: "Ingest", - icon: faFileUpload, - component: IngestView, - }, - { - path: "/search", - label: "Search", - icon: faSearch, - component: SearchView, - }, -]; - -/** - * Represents the top-level application component. - * - * @return {React.ReactElement} The rendered App component. - */ -const App = () => { - const [isSidebarCollapsed, setIsSidebarCollapsed] = useState( - "true" === localStorage.getItem(LOCAL_STORAGE_KEYS.IS_SIDEBAR_COLLAPSED), - ); - - useEffect(() => { - localStorage.setItem( - LOCAL_STORAGE_KEYS.IS_SIDEBAR_COLLAPSED, - isSidebarCollapsed.toString() - ); - }, [isSidebarCollapsed]); - - const handleSidebarToggle = () => { - setIsSidebarCollapsed(false === isSidebarCollapsed); - }; - - return ( - <> - -
- - - - - - - - - - - -
- - ); -}; - -export {App}; diff --git a/components/webui/imports/ui/App.scss b/components/webui/imports/ui/App.scss deleted file mode 100644 index 759d18f686..0000000000 --- a/components/webui/imports/ui/App.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import "./bootstrap-customized"; - -html { - font-size: 14px; - height: 100%; -} - -body { - background-image: linear-gradient(165deg, white 80%, rgba(122, 194, 204, 0.1) 80%), - linear-gradient(115deg, white 90%, rgba(122, 194, 204, 0.2) 90%); - font-family: 'Source Sans 3', sans-serif; - height: 100%; -} - -#page-container { - flex-grow: 1; - - overflow-y: auto; -} diff --git a/components/webui/imports/ui/IngestView/IngestView.jsx b/components/webui/imports/ui/IngestView/IngestView.jsx deleted file mode 100644 index d3b2163f91..0000000000 --- a/components/webui/imports/ui/IngestView/IngestView.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import {useTracker} from "meteor/react-meteor-data"; -import Col from "react-bootstrap/Col"; -import Container from "react-bootstrap/Container"; -import Row from "react-bootstrap/Row"; - -import {StatsCollection} from "/imports/api/ingestion/collections"; - -import Details from "./panels/Details"; -import IngestionJobs from "./panels/IngestionJobs"; -import SpaceSavings from "./panels/SpaceSavings"; - -import "./IngestView.scss"; - - -/** - * Presents compression statistics. - * - * @return {React.ReactElement} - */ -const IngestView = () => { - const stats = useTracker(() => { - Meteor.subscribe(Meteor.settings.public.StatsCollectionName); - - return StatsCollection.findOne(); - }, []); - - return ( - - - - {stats && - - -
- } - - - - - - - ); -}; - -export default IngestView; diff --git a/components/webui/imports/ui/IngestView/IngestView.scss b/components/webui/imports/ui/IngestView/IngestView.scss deleted file mode 100644 index 63402d6a97..0000000000 --- a/components/webui/imports/ui/IngestView/IngestView.scss +++ /dev/null @@ -1,75 +0,0 @@ -@import "../bootstrap-customized"; - -.ingest-container { - // Background highlight - background: linear-gradient(to bottom, #004850, #004850 160px, transparent 160px); - padding: 30px; -} - -.panel { - background-color: white; - border: 1px solid #ddd; - border-radius: 3px; - box-shadow: 0 1px 11px 0 rgba(0, 0, 0, 0.1); - padding: 15px; - margin: 10px 0; -} - -.panel-h1 { - font-size: 1.5rem; - line-height: 1.5rem; - margin: 0 0 15px 0; -} - -.panel-icon { - color: #004850; - font-size: 1.5rem; - line-height: 1.5rem; -} - -.ingest { - &-stats { - &-details { - &-icon-container { - width: 40px; - - flex: 0 0 auto; - margin-right: 10px; - - color: #ad1869; - font-size: 40px; - line-height: 40px; - text-align: center; - } - - &-text-container { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - &-row { - border-top: 1px solid #eee; - display: flex; - flex-wrap: wrap; - padding: 15px 0; - } - } - - &-detail { - display: block; - font-family: "Roboto Mono", monospace; - font-weight: 600; - font-size: 1.5rem; - line-height: 1; - } - } -} - -.ingest-stat-bar { - height: 4px !important; -} - -.ingest-stat-bar > .progress-bar { - background-color: $info; -} diff --git a/components/webui/imports/ui/IngestView/Panel.jsx b/components/webui/imports/ui/IngestView/Panel.jsx deleted file mode 100644 index 559187df47..0000000000 --- a/components/webui/imports/ui/IngestView/Panel.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import Col from "react-bootstrap/Col"; -import Row from "react-bootstrap/Row"; - -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - - -/** - * Represents a Panel component. - * - * @param {object} props - * @param {React.ReactNode} props.children The content of the Panel. - * @param {import("@fortawesome/react-fontawesome").IconProp} props.faIcon The FontAwesomeIcon to - * display in the Panel. - * @param {string} props.title - * @param {object} props.rootColProps - * @return {React.ReactElement} - */ -const Panel = ({ - children, - faIcon, - title, - ...rootColProps -}) => ( - -
- - -

- {title} -

- - - - - - - {children} - - -
-
- -); - -export default Panel; diff --git a/components/webui/imports/ui/IngestView/panels/Details/DetailsRow.jsx b/components/webui/imports/ui/IngestView/panels/Details/DetailsRow.jsx deleted file mode 100644 index 144c5d7bcb..0000000000 --- a/components/webui/imports/ui/IngestView/panels/Details/DetailsRow.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - - -/** - * Represents a compression stats details row. - * - * @param {object} props - * @param {React.ReactNode} props.children The content in the Detail row. - * @param {import("@fortawesome/react-fontawesome").IconProp} props.faIcon The FontAwesomeIcon to - * display in the Detail row. - * @param {string} props.title - * @return {React.ReactElement} - */ -const DetailsRow = ({ - faIcon, - children, - title, -}) => ( -
-
- -
-
-
- {children} -
- - {title} - -
-
-); - -export default DetailsRow; diff --git a/components/webui/imports/ui/IngestView/panels/Details/index.jsx b/components/webui/imports/ui/IngestView/panels/Details/index.jsx deleted file mode 100644 index b1cc86ee76..0000000000 --- a/components/webui/imports/ui/IngestView/panels/Details/index.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import dayjs from "dayjs"; - -import { - faChartBar, - faClock, - faEnvelope, - faFileAlt, -} from "@fortawesome/free-solid-svg-icons"; - -import {DATETIME_FORMAT_TEMPLATE} from "/imports/utils/datetime"; - -import Panel from "../../Panel"; -import DetailsRow from "./DetailsRow"; - - -/** - * Presents details from the given statistics. - * - * @param {object} props - * @param {CompressionStats} props.stats - * @return {React.ReactElement} - */ -const Details = ({stats}) => { - const { - begin_timestamp: beginTimestamp, - end_timestamp: endTimestamp, - num_files: numFiles, - num_messages: numMessages, - } = stats; - - let timeRangeRow = null; - if (null !== endTimestamp) { - timeRangeRow = ( - -
- {dayjs.utc(Number(beginTimestamp)).format(DATETIME_FORMAT_TEMPLATE)} - {" to"} -
-
- {dayjs.utc(Number(endTimestamp)).format(DATETIME_FORMAT_TEMPLATE)} -
-
- ); - } - - let numFilesRow = null; - if (null !== numFiles) { - numFilesRow = ( - - {Number(numFiles).toLocaleString()} - - ); - } - - let numMessagesRow = null; - if (null !== numMessages) { - numMessagesRow = ( - - {Number(numMessages).toLocaleString()} - - ); - } - - if (!(timeRangeRow || numFilesRow || numMessagesRow)) { - // No details to display - return <>; - } - - return ( - - {timeRangeRow} - {numFilesRow} - {numMessagesRow} - - ); -}; - -export default Details; diff --git a/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobRow.jsx b/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobRow.jsx deleted file mode 100644 index de23ec02be..0000000000 --- a/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobRow.jsx +++ /dev/null @@ -1,113 +0,0 @@ -import OverlayTrigger from "react-bootstrap/OverlayTrigger"; -import Spinner from "react-bootstrap/Spinner"; -import Tooltip from "react-bootstrap/Tooltip"; - -import dayjs from "dayjs"; - -import { - faCheck, - faClock, - faExclamation, -} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import { - COMPRESSION_JOB_STATUS, - COMPRESSION_JOB_STATUS_NAMES, -} from "/imports/api/ingestion/constants"; -import {computeHumanSize} from "/imports/utils/misc"; - -import PlaceholderText from "./PlaceholderText"; - - -/** - * Icons corresponding to different compression job statuses. - * - * @type {{[key: CompressionJobStatus]: import("@fortawesome/react-fontawesome").IconProp}} - */ -const COMPRESSION_JOB_STATUS_ICONS = Object.freeze({ - [COMPRESSION_JOB_STATUS.PENDING]: faClock, - [COMPRESSION_JOB_STATUS.SUCCEEDED]: faCheck, - [COMPRESSION_JOB_STATUS.FAILED]: faExclamation, -}); - -/** - * Renders an ingestion job. - * - * @param {import("/imports/api/ingestion/types").CompressionJob} job The job object containing - * information about the compression job. - * @return {React.ReactElement} - */ -const IngestionJobRow = ({job}) => { - let uncompressedSizeText = ""; - let compressedSizeText = ""; - let speedText = ""; - - if (null === job.duration && null !== job.start_time) { - job.duration = dayjs.duration( - dayjs() - dayjs(job.start_time) - ).asSeconds(); - } - - const uncompressedSize = Number(job.uncompressed_size); - if (false === isNaN(uncompressedSize) && 0 !== uncompressedSize) { - uncompressedSizeText = computeHumanSize(uncompressedSize); - } - - const compressedSize = Number(job.compressed_size); - if (false === isNaN(compressedSize) && 0 !== compressedSize) { - compressedSizeText = computeHumanSize(compressedSize); - } - - if ( - false === isNaN(uncompressedSize) && - 0 !== uncompressedSize && - 0 < job.duration - ) { - speedText = `${computeHumanSize(job.uncompressed_size / job.duration)}/s`; - } - - const isPlaceholderVisible = job.status !== COMPRESSION_JOB_STATUS.FAILED; - - return ( - - - - {COMPRESSION_JOB_STATUS_NAMES[job.status]} - {job.status_msg && (` - ${job.status_msg}`)} - - } - > - {COMPRESSION_JOB_STATUS.RUNNING === job.status ? - : - } - - - - {job._id} - - - - - - - - - - - - ); -}; - -export default IngestionJobRow; diff --git a/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobs.scss b/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobs.scss deleted file mode 100644 index 0212c12ca2..0000000000 --- a/components/webui/imports/ui/IngestView/panels/IngestionJobs/IngestionJobs.scss +++ /dev/null @@ -1,3 +0,0 @@ -.ingestion-jobs-table { - table-layout: fixed; -} diff --git a/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.jsx b/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.jsx deleted file mode 100644 index ac0f07f83c..0000000000 --- a/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import Placeholder from "react-bootstrap/Placeholder"; - -import "./PlaceholderText.scss"; - - -/** - * Renders an animated text placeholder when the text is an empty string. - * - * @param {object} props - * @param {string} props.text - * @param {boolean} props.isAlwaysVisible - * @return {React.ReactElement} - */ -const PlaceholderText = ({ - text, - isAlwaysVisible = true, -}) => ( - - {(0 !== text.length) ? - text : - ( - (isAlwaysVisible) && - - )} - -); - -export default PlaceholderText; diff --git a/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.scss b/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.scss deleted file mode 100644 index af0a489df5..0000000000 --- a/components/webui/imports/ui/IngestView/panels/IngestionJobs/PlaceholderText.scss +++ /dev/null @@ -1,3 +0,0 @@ -.placeholder-element { - border-radius: 3px; -} diff --git a/components/webui/imports/ui/IngestView/panels/IngestionJobs/index.jsx b/components/webui/imports/ui/IngestView/panels/IngestionJobs/index.jsx deleted file mode 100644 index 9591d5e008..0000000000 --- a/components/webui/imports/ui/IngestView/panels/IngestionJobs/index.jsx +++ /dev/null @@ -1,64 +0,0 @@ -import {useTracker} from "meteor/react-meteor-data"; -import Table from "react-bootstrap/Table"; - -import {faBarsProgress} from "@fortawesome/free-solid-svg-icons"; - -import {CompressionJobsCollection} from "/imports/api/ingestion/collections"; -import {MONGO_SORT_BY_ID} from "/imports/utils/mongo"; - -import Panel from "../../Panel"; -import IngestionJobRow from "./IngestionJobRow"; - -import "./IngestionJobs.scss"; - - -/** - * Displays a table of ingestion jobs. - * - * @return {React.ReactElement} - */ -const IngestionJobs = () => { - const compressionJobs = useTracker(() => { - Meteor.subscribe(Meteor.settings.public.CompressionJobsCollectionName); - - const findOptions = { - sort: [MONGO_SORT_BY_ID], - }; - - return CompressionJobsCollection.find({}, findOptions).fetch(); - }, []); - - if (0 === compressionJobs.length) { - return <>; - } - - return ( - - - - - - - - - - - - - {compressionJobs.map((job, i) => ( - - ))} - -
StatusJob IDSpeedData IngestedCompressed Size
-
- ); -}; - -export default IngestionJobs; diff --git a/components/webui/imports/ui/IngestView/panels/SpaceSavings.jsx b/components/webui/imports/ui/IngestView/panels/SpaceSavings.jsx deleted file mode 100644 index d30a4ca216..0000000000 --- a/components/webui/imports/ui/IngestView/panels/SpaceSavings.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import Col from "react-bootstrap/Col"; -import ProgressBar from "react-bootstrap/ProgressBar"; -import Row from "react-bootstrap/Row"; - -import {faHdd} from "@fortawesome/free-solid-svg-icons"; - -import {computeHumanSize} from "/imports/utils/misc"; - -import Panel from "../Panel"; - - -/** - * Presents space savings from the given statistics. - * - * @param {object} props - * @param {CompressionStats} props.stats - * @return {React.ReactElement} - */ -const SpaceSavings = ({stats}) => { - const logsUncompressedSize = parseInt(stats.total_uncompressed_size, 10) || 0; - const logsCompressedSize = parseInt(stats.total_compressed_size, 10) || 0; - const spaceSavings = 0 < logsUncompressedSize ? - 100 * (1 - (logsCompressedSize / logsUncompressedSize)) : - 0; - - return ( - - - - - - {`${spaceSavings.toFixed(2)}%`} - - - - - - -
- {computeHumanSize(logsUncompressedSize)} - {" "} - before compression - -
- -
- - -
- {computeHumanSize(logsCompressedSize)} - {" "} - after compression - -
- -
-
- ); -}; - -export default SpaceSavings; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/SearchControlsCaseSensitivityCheck.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/SearchControlsCaseSensitivityCheck.jsx deleted file mode 100644 index cd735598da..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/SearchControlsCaseSensitivityCheck.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import Form from "react-bootstrap/Form"; - - -/** - * Renders a case sensitivity checkbox. - * - * @param {object} props - * @param {string} props.label - * @param {object} props.rest - * @return {React.ReactElement} - */ -const SearchControlsCaseSensitivityCheck = ({ - label, - ...rest -}) => ( - -); - -export default SearchControlsCaseSensitivityCheck; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/index.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/index.jsx deleted file mode 100644 index 3460d10e3b..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsCaseSensitivity/index.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import Col from "react-bootstrap/Col"; -import Form from "react-bootstrap/Form"; -import Row from "react-bootstrap/Row"; - -import SearchControlsFilterLabel from "../SearchControlsFilterLabel"; -import SearchControlsCaseSensitivityCheck from "./SearchControlsCaseSensitivityCheck"; - - -/** - * Represents a component for selecting case sensitivity. - * - * @param {object} props - * @param {boolean} props.ignoreCase - * @param {Function} props.setIgnoreCase - * @return {React.ReactElement} - */ -const SearchControlsCaseSensitivity = ({ - ignoreCase, - setIgnoreCase, -}) => { - /** - * Handles case sensitivity change. - * - * @param {InputEvent} event - */ - const handleCaseSensitivityChange = (event) => { - setIgnoreCase("true" === event.target.value); - }; - - return ( - - - Case sensitivity - - - - - - - ); -}; - -export default SearchControlsCaseSensitivity; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterDrawer.scss b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterDrawer.scss deleted file mode 100644 index 4679e2392f..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterDrawer.scss +++ /dev/null @@ -1,11 +0,0 @@ -.search-filter { - &-controls-drawer { - background-color: #efefef; - } - - &-control-label { - color: #666; - - min-width: 9rem; - } -} diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterLabel.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterLabel.jsx deleted file mode 100644 index 870e2dbf83..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsFilterLabel.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import Form from "react-bootstrap/Form"; - - -/** - * Renders a label for a search filter control. - * - * @param {object} props - * @return {React.ReactElement} - */ -const SearchControlsFilterLabel = (props) => ( - -); - -export default SearchControlsFilterLabel; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsDatePicker.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsDatePicker.jsx deleted file mode 100644 index 9243d76418..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsDatePicker.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import DatePicker from "react-datepicker"; - -import "react-datepicker/dist/react-datepicker.css"; -import "./SearchControlsTimeRangeInput.scss"; - - -/** - * Renders a date picker control for selecting date and time. - * - * @param {object} props - * @return {React.ReactElement} - */ -const SearchControlsDatePicker = (props) => ( - -); - -export default SearchControlsDatePicker; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsTimeRangeInput.scss b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsTimeRangeInput.scss deleted file mode 100644 index c16645f3b0..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/SearchControlsTimeRangeInput.scss +++ /dev/null @@ -1,10 +0,0 @@ -.timestamp-picker { - border: 1px solid rgb(206, 212, 218); - border-radius: 0; - - font-size: 0.875rem; - line-height: 1.5; - - height: calc(1.5em + 0.5rem + 2px); - padding: 0.25rem 0.5rem; -} diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/index.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/index.jsx deleted file mode 100644 index 382212ad65..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/SearchControlsTimeRangeInput/index.jsx +++ /dev/null @@ -1,139 +0,0 @@ -import Col from "react-bootstrap/Col"; -import Dropdown from "react-bootstrap/Dropdown"; -import DropdownButton from "react-bootstrap/DropdownButton"; -import Form from "react-bootstrap/Form"; -import InputGroup from "react-bootstrap/InputGroup"; -import Row from "react-bootstrap/Row"; - -import { - computeTimeRange, - convertLocalDateToSameUtcDatetime, - convertUtcDatetimeToSameLocalDate, - TIME_RANGE_PRESET_LABEL, - TIME_UNIT, -} from "/imports/utils/datetime"; - -import SearchControlsFilterLabel from "../SearchControlsFilterLabel"; -import SearchControlsDatePicker from "./SearchControlsDatePicker"; - - -/** - * Represents a component for selecting a time range. - * - * @param {object} props - * @param {object} props.timeRange - * @param {Function} props.setTimeRange - * @return {React.ReactElement} - */ -const SearchControlsTimeRangeInput = ({ - timeRange, - setTimeRange, -}) => { - /** - * Updates the `begin` timestamp of the time range. - * - * @param {Date} localDateBegin The local date to be used for updating the beginning timestamp. - */ - const handleBeginDateChange = (localDateBegin) => { - const utcDatetime = convertLocalDateToSameUtcDatetime(localDateBegin); - - if (utcDatetime > timeRange.end) { - setTimeRange({ - begin: utcDatetime, - end: utcDatetime, - }); - } else { - setTimeRange((v) => ({ - ...v, - begin: utcDatetime, - })); - } - }; - - /** - * Updates the `end` timestamp of the time range. - * - * @param {Date} localDateEnd The local date to be used for updating the ending timestamp. - */ - const handleEndDateChange = (localDateEnd) => { - const utcDatetime = convertLocalDateToSameUtcDatetime(localDateEnd); - - setTimeRange( - (v) => ({ - ...v, - end: utcDatetime, - }), - ); - }; - - const handleTimeRangePresetSelection = (event) => { - event.preventDefault(); - - const presetToken = event.target.getAttribute("data-preset"); - const newTimeRange = computeTimeRange(presetToken); - - setTimeRange(newTimeRange); - }; - - // Compute range of end timestamp so that it's after the beginning timestamp - let datepickerEndMin = null; - let datepickerEndMax = null; - if (timeRange.begin.isSame(timeRange.end, TIME_UNIT.DAY)) { - datepickerEndMin = timeRange.begin; - datepickerEndMax = timeRange.end.endOf(TIME_UNIT.DAY); - } - - const timeRangePresetItems = Object.entries(TIME_RANGE_PRESET_LABEL).map(([token, label]) => ( - - {label} - - )); - - return ( - - - Time range - - - - - {timeRangePresetItems} - - - - to - - - - - - ); -}; - -export default SearchControlsTimeRangeInput; diff --git a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/index.jsx b/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/index.jsx deleted file mode 100644 index 61a1848f70..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/SearchControlsFilterDrawer/index.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import Container from "react-bootstrap/Container"; - -import SearchControlsCaseSensitivity from "./SearchControlsCaseSensitivity"; -import SearchControlsTimeRangeInput from "./SearchControlsTimeRangeInput"; - -import "./SearchControlsFilterDrawer.scss"; - - -/** - * Renders the controls for filtering search results by time range, including a date picker and - * preset time range options. - * - * @param {object} props - * @param {boolean} props.ignoreCase - * @param {Function} props.setIgnoreCase - * @param {Function} props.setTimeRange - * @param {TimeRange} props.timeRange - * @return {React.ReactElement} - */ -const SearchControlsFilterDrawer = ({ - ignoreCase, - setIgnoreCase, - setTimeRange, - timeRange, -}) => { - return ( - - - - - ); -}; - -export default SearchControlsFilterDrawer; diff --git a/components/webui/imports/ui/SearchView/SearchControls/index.jsx b/components/webui/imports/ui/SearchView/SearchControls/index.jsx deleted file mode 100644 index 81751f46c8..0000000000 --- a/components/webui/imports/ui/SearchView/SearchControls/index.jsx +++ /dev/null @@ -1,163 +0,0 @@ -import { - useEffect, - useRef, - useState, -} from "react"; -import Button from "react-bootstrap/Button"; -import Form from "react-bootstrap/Form"; -import InputGroup from "react-bootstrap/InputGroup"; - -import { - faBars, - faSearch, - faTimes, - faTrash, -} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import {CLP_STORAGE_ENGINES} from "/imports/api/constants"; -import { - isOperationInProgress, - isSearchSignalReq, - SEARCH_SIGNAL, -} from "/imports/api/search/constants"; - -import {LOCAL_STORAGE_KEYS} from "../../constants"; -import SearchControlsFilterDrawer from "./SearchControlsFilterDrawer"; - - -/** - * Renders the search controls including query input, filter drawer toggle, and operation buttons - * like submit, clear, and cancel. It also manages the state of the drawer. - * - * @param {object} props - * @param {boolean} props.ignoreCase - * @param {Function} props.onCancelOperation - * @param {Function} props.onClearResults - * @param {Function} props.onSubmitQuery - * @param {string} props.queryString - * @param {SearchResultsMetadata} props.resultsMetadata - * @param {Function} props.setIgnoreCase - * @param {Function} props.setQueryString - * @param {Function} props.setTimeRange - * @param {TimeRange} props.timeRange - * @return {React.ReactElement} - */ -const SearchControls = ({ - ignoreCase, - onCancelOperation, - onClearResults, - onSubmitQuery, - queryString, - resultsMetadata, - setIgnoreCase, - setQueryString, - setTimeRange, - timeRange, -}) => { - const [drawerOpen, setDrawerOpen] = useState( - "true" === localStorage.getItem(LOCAL_STORAGE_KEYS.SEARCH_CONTROLS_VISIBLE) - ); - const inputRef = useRef(null); - - const isInputDisabled = isOperationInProgress(resultsMetadata.lastSignal); - - useEffect(() => { - if (false === isInputDisabled) { - inputRef.current?.focus(); - } - }, [isInputDisabled]); - - useEffect(() => { - localStorage.setItem(LOCAL_STORAGE_KEYS.SEARCH_CONTROLS_VISIBLE, drawerOpen.toString()); - }, [drawerOpen]); - - const queryChangeHandler = (e) => { - setQueryString(e.target.value); - }; - - const handleDrawerToggleClick = () => { - setDrawerOpen(!drawerOpen); - }; - - const handleQuerySubmission = (e) => { - e.preventDefault(); - - onSubmitQuery(); - }; - - const queryPlaceholderText = - CLP_STORAGE_ENGINES.CLP === Meteor.settings.public.ClpStorageEngine ? - "Enter a wildcard query..." : - "Enter a KQL query..."; - - return ( - <> -
- - - - - {(SEARCH_SIGNAL.RESP_DONE === resultsMetadata.lastSignal) && - } - {(SEARCH_SIGNAL.RESP_QUERYING === resultsMetadata.lastSignal) ? - : - } - - -
- - {drawerOpen && } - - ); -}; - -export default SearchControls; diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/SearchResultsHeader.scss b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/SearchResultsHeader.scss deleted file mode 100644 index 54093c9f54..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/SearchResultsHeader.scss +++ /dev/null @@ -1,11 +0,0 @@ -.search-results-title-bar { - background-color: #fff; -} - -.search-results-count { - padding: 0.375rem 0; - - color: #999; - font-size: 1rem; - line-height: 1.5; -} diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/index.jsx b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/index.jsx deleted file mode 100644 index 548f4e4f2a..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsHeader/index.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import Button from "react-bootstrap/Button"; -import Col from "react-bootstrap/Col"; -import Container from "react-bootstrap/Container"; -import Form from "react-bootstrap/Form"; -import InputGroup from "react-bootstrap/InputGroup"; -import OverlayTrigger from "react-bootstrap/OverlayTrigger"; -import Popover from "react-bootstrap/Popover"; -import Row from "react-bootstrap/Row"; - -import {faCog} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import "./SearchResultsHeader.scss"; - - -/** - * Renders the header for the search results, which includes the search job ID, the number of - * results found, and a control for setting the maximum number of lines per search result. - * - * @param {object} props - * @param {number} props.maxLinesPerResult - * @param {number} props.numResultsInTotal - * @param {number} props.searchJobId - * @param {Function} props.setMaxLinesPerResult - * @return {React.ReactElement} - */ -const SearchResultsHeader = ({ - maxLinesPerResult, - numResultsInTotal, - searchJobId, - setMaxLinesPerResult, -}) => { - const handleMaxLinesPerResultSubmission = (e) => { - e.preventDefault(); - const value = parseInt(e.target.elements.maxLinesPerResult.value, 10); - if (0 < value) { - setMaxLinesPerResult(value); - } - }; - - return ( - <> - - - - - Job ID - {" "} - {searchJobId} - {" "} - | Results count: - {" "} - {numResultsInTotal} - - - - -
- - Max lines per result - - -
- - } - > - -
- -
-
- - ); -}; - -export default SearchResultsHeader; diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.jsx b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.jsx deleted file mode 100644 index b7f62e1d82..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import { - useEffect, - useRef, -} from "react"; -import Spinner from "react-bootstrap/Spinner"; - -import {faCircleInfo} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import {SEARCH_MAX_NUM_RESULTS} from "/imports/api/search/constants"; - -import "./SearchResultsLoadSensor.scss"; - - -/** - * The interval, in milliseconds, at which the search results load sensor should poll for updates. - */ -const SEARCH_RESULTS_LOAD_SENSOR_POLL_INTERVAL_MILLIS = 200; - -/** - * Senses if the user has requested to load more results by scrolling until - * this element becomes partially visible. - * - * @param {object} props - * @param {boolean} props.hasMoreResultsInCache - * @param {boolean} props.hasMoreResultsInTotal - * @param {Function} props.onLoadMoreResults - * @return {React.ReactElement} - */ -const SearchResultsLoadSensor = ({ - hasMoreResultsInCache, - hasMoreResultsInTotal, - onLoadMoreResults, -}) => { - const loadingBlockRef = useRef(null); - const loadIntervalRef = useRef(null); - - useEffect(() => { - if (false === hasMoreResultsInCache) { - return () => null; - } - - const observer = new IntersectionObserver((entries) => { - if (entries[0].isIntersecting) { - onLoadMoreResults(); - loadIntervalRef.current = setInterval( - onLoadMoreResults, - SEARCH_RESULTS_LOAD_SENSOR_POLL_INTERVAL_MILLIS, - ); - } else if (null !== loadIntervalRef.current) { - clearInterval(loadIntervalRef.current); - loadIntervalRef.current = null; - } - }); - - observer.observe(loadingBlockRef.current); - - return () => { - if (null !== loadIntervalRef.current) { - clearInterval(loadIntervalRef.current); - loadIntervalRef.current = null; - } - observer.disconnect(); - }; - }, [ - hasMoreResultsInCache, - onLoadMoreResults, - ]); - - return ( -
- {(hasMoreResultsInCache) && -
- - Loading... -
} - {(false === hasMoreResultsInCache && hasMoreResultsInTotal) && -
- - - Showing the top - {" "} - {SEARCH_MAX_NUM_RESULTS} - {" "} - results by time. To view any other results, please refine your search. - -
} -
- ); -}; - -export default SearchResultsLoadSensor; diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.scss b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.scss deleted file mode 100644 index c9881458b3..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsLoadSensor.scss +++ /dev/null @@ -1,9 +0,0 @@ -.search-results-load-sensor-content { - display: flex; - align-items: center; - gap: 10px; - padding-inline: 10px; - padding-bottom: 12px; - - font-size: 1.3rem; -} diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsTable.scss b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsTable.scss deleted file mode 100644 index 063900dfb3..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/SearchResultsTable.scss +++ /dev/null @@ -1,61 +0,0 @@ -.search-results-container { - overflow-y: auto; - background: white; -} - -// NOTE: We use a hierarchical selector to override Bootstrap's hierarchical selector (classes can't override hierarchical selectors without !important) -.search-results thead th { - border: none; - padding: 0; -} - -.search-results-th { - position: sticky; - top: 0; - - &-sortable { - cursor: pointer; - user-select: none; - } -} - -.search-results-table-header { - background-color: #fff; - border-bottom: 1px solid #ccc; - border-top: 1px solid #dee2e6; - padding: 10px; -} - -.search-results-content { - overflow: auto; - - font-size: 0.875rem; - line-height: var(--search-results-message-line-height); -} - -.search-results-timestamp { - color: #69707D !important; - font-family: "Roboto", sans-serif; - font-weight: 500; - white-space: nowrap; -} - -.search-results-message { - margin: 0; - max-height: var(--search-results-message-max-height); - - font-family: "Roboto Mono", monospace; - font-weight: 400; - white-space: pre-wrap; - word-break: break-word; -} - -.search-results-file-link { - margin-top: 0.25rem; - - color: grey; - font-family: 'Roboto', sans-serif; - font-size: 0.875rem; - font-weight: 400; - line-height: 1.5; -} diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/index.jsx b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/index.jsx deleted file mode 100644 index c7fa62a25a..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTable/index.jsx +++ /dev/null @@ -1,188 +0,0 @@ -import {Meteor} from "meteor/meteor"; -import {useEffect} from "react"; -import Table from "react-bootstrap/Table"; - -import dayjs from "dayjs"; - -import { - faFileLines, - faSort, - faSortDown, - faSortUp, -} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import { - MONGO_SORT_ORDER, - SEARCH_RESULTS_FIELDS, -} from "/imports/api/search/constants"; -import {DATETIME_FORMAT_TEMPLATE} from "/imports/utils/datetime"; - -import SearchResultsLoadSensor from "./SearchResultsLoadSensor"; - -import "./SearchResultsTable.scss"; - - -/** - * For calculating max message height from `maxLinesPerResult`. - */ -const SEARCH_RESULT_MESSAGE_LINE_HEIGHT = 1.5; - -const IS_IR_STREAM = ("clp" === Meteor.settings.public.ClpStorageEngine); -const STREAM_TYPE = IS_IR_STREAM ? - "ir" : - "json"; - - -/** - * Gets the stream id for an extraction job from the search result. - * - * @param {object} searchResult - * @return {string} stream_id - */ -const getStreamId = (searchResult) => { - return IS_IR_STREAM ? - searchResult.orig_file_id : - searchResult.archive_id; -}; - - -/** - * Represents a table component to display search results. - * - * @param {object} props - * @param {object} props.fieldToSortBy - * @param {boolean} props.hasMoreResultsInCache - * @param {boolean} props.hasMoreResultsInTotal - * @param {number} props.maxLinesPerResult - * @param {Function} props.onLoadMoreResults - * @param {object[]} props.searchResults - * @param {Function} props.setFieldToSortBy - * @return {React.ReactElement} - */ -const SearchResultsTable = ({ - fieldToSortBy, - hasMoreResultsInCache, - hasMoreResultsInTotal, - maxLinesPerResult, - onLoadMoreResults, - searchResults, - setFieldToSortBy, -}) => { - const getSortIcon = (fieldName) => { - if (fieldName === fieldToSortBy.name) { - return (MONGO_SORT_ORDER.ASCENDING === fieldToSortBy.direction) ? - faSortUp : - faSortDown; - } - - return faSort; - }; - - const toggleSortDirection = (event) => { - const {columnName} = event.currentTarget.dataset; - if (fieldToSortBy.name !== columnName) { - setFieldToSortBy({ - name: columnName, - direction: (SEARCH_RESULTS_FIELDS.TIMESTAMP === columnName) ? - MONGO_SORT_ORDER.DESCENDING : - MONGO_SORT_ORDER.ASCENDING, - }); - } else { - setFieldToSortBy({ - name: columnName, - direction: (MONGO_SORT_ORDER.ASCENDING === fieldToSortBy.direction) ? - MONGO_SORT_ORDER.DESCENDING : - MONGO_SORT_ORDER.ASCENDING, - }); - } - }; - - useEffect(() => { - document.documentElement.style.setProperty( - "--search-results-message-line-height", - `${SEARCH_RESULT_MESSAGE_LINE_HEIGHT}rem` - ); - }, []); - - useEffect(() => { - document.documentElement.style.setProperty( - "--search-results-message-max-height", - `${(SEARCH_RESULT_MESSAGE_LINE_HEIGHT * maxLinesPerResult)}rem` - ); - }, [maxLinesPerResult]); - - return ( -
- - - - - - - - - {searchResults.map((result) => ( - - - - - ))} - -
-
- - Timestamp -
-
-
- Log message -
-
- {result.timestamp ? - dayjs.utc(result.timestamp).format(DATETIME_FORMAT_TEMPLATE) : - "N/A"} - -
-                                    {result.message}
-                                
- -
- -
- ); -}; - -export default SearchResultsTable; diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/SearchResultsTimeline.scss b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/SearchResultsTimeline.scss deleted file mode 100644 index 06f2d04a47..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/SearchResultsTimeline.scss +++ /dev/null @@ -1,5 +0,0 @@ -.timeline-chart { - cursor: var(--timeline-chart-cursor, crosshair); - height: 100px; - max-height: 100px; -} diff --git a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/index.jsx b/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/index.jsx deleted file mode 100644 index b0c41bbd04..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/SearchResultsTimeline/index.jsx +++ /dev/null @@ -1,276 +0,0 @@ -import {useEffect} from "react"; -import {Bar} from "react-chartjs-2"; - -import { - BarElement, - Chart as ChartJs, - LinearScale, - TimeScale, - Tooltip, -} from "chart.js"; -import zoomPlugin from "chartjs-plugin-zoom"; -import dayjs from "dayjs"; - -import {isOperationInProgress} from "/imports/api/search/constants"; -import { - convertLocalDateToSameUtcDatetime, - convertUtcDatetimeToSameLocalDate, - DATETIME_FORMAT_TEMPLATE, - expandTimeRangeToDurationMultiple, - TIME_UNIT, -} from "/imports/utils/datetime"; -import {deselectAll} from "/imports/utils/misc"; - -import "chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm"; -import "./SearchResultsTimeline.scss"; - - -ChartJs.register( - TimeScale, - LinearScale, - BarElement, - Tooltip, - zoomPlugin -); - -const MAX_DATA_POINTS_PER_TIMELINE = 40; - -/** - * Converts an array of timeline buckets into an array of objects compatible with Chart.js. - * - * @param {TimelineBucket[]} timelineBuckets - * @return {ChartJsDatasetItem[]} - */ -const adaptTimelineBucketsForChartJs = (timelineBuckets) => ( - timelineBuckets.map( - ({ - timestamp, - count, - }) => ({ - x: timestamp, - y: count, - }) - ) -); - -/** - * Converts the timestamp from Chart.js' zoom plugin to a UTC Dayjs object. - * NOTE: The Chart.js timescale operates in the local timezone, but we want to the timeline to - * appear as if it's in UTC, so we apply the negative offset of the local timezone to all timestamps - * before passing them to Chart.js. However, the zoom plugin thinks that Chart.js is displaying - * timestamps in the local timezone, so it also applies the negative offset of the local timezone - * before passing them to onZoom. So to get the original UTC timestamp, this method needs to apply - * the local timezone offset twice. - * - * @param {number} timestampUnixMillis - * @return {dayjs.Dayjs} The corresponding Dayjs object - */ -const convertZoomTimestampToUtcDatetime = (timestampUnixMillis) => { - // Create a Date object with given timestamp, which contains local timezone information. - const initialDate = new Date(timestampUnixMillis); - - // Reverse local timezone offset. - const intermediateDateTime = convertLocalDateToSameUtcDatetime(initialDate); - - // Reverse local timezone offset again. - return convertLocalDateToSameUtcDatetime(intermediateDateTime.toDate()); -}; - -/** - * Computes the timestamp range and bucket duration necessary to render the bars in the timeline - * chart. - * - * @param {dayjs.Dayjs} timestampBeginUnixMillis - * @param {dayjs.Dayjs} timestampEndUnixMillis - * @return {TimelineConfig} - */ -const computeTimelineConfig = (timestampBeginUnixMillis, timestampEndUnixMillis) => { - const timeRangeMillis = timestampEndUnixMillis - timestampBeginUnixMillis; - const exactTimelineBucketMillis = timeRangeMillis / MAX_DATA_POINTS_PER_TIMELINE; - - // A list of predefined bucket durations, ordered from least to greatest so that the - // `durationSelections.find()` below can find the smallest bucket containing - // `exactTimelineBucketMillis`. - const durationSelections = [ - /* eslint-disable @stylistic/js/array-element-newline, no-magic-numbers */ - {unit: "second", values: [1, 2, 5, 10, 15, 30]}, - {unit: "minute", values: [1, 2, 5, 10, 15, 20, 30]}, - {unit: "hour", values: [1, 2, 3, 4, 8, 12]}, - {unit: "day", values: [1, 2, 5, 15]}, - {unit: "month", values: [1, 2, 3, 4, 6]}, - {unit: "year", values: [1]}, - /* eslint-enable @stylistic/js/array-element-newline, no-magic-numbers */ - ].flatMap( - ({ - unit, - values, - }) => values.map( - (value) => dayjs.duration(value, unit), - ), - ); - - const bucketDuration = - durationSelections.find( - (duration) => (exactTimelineBucketMillis <= duration.asMilliseconds()), - ) || - dayjs.duration( - Math.ceil(exactTimelineBucketMillis / - dayjs.duration(1, TIME_UNIT.YEAR).asMilliseconds()), - TIME_UNIT.YEAR, - ); - - return { - range: expandTimeRangeToDurationMultiple(bucketDuration, { - begin: dayjs.utc(timestampBeginUnixMillis), - end: dayjs.utc(timestampEndUnixMillis), - }), - bucketDuration: bucketDuration, - }; -}; - -/** - * Displays a timeline of search results. - * - * @param {object} props - * @param {Function} props.onTimelineZoom - * @param {object} props.resultsMetadata - * @param {TimelineBucket[]} props.timelineBuckets - * @param {TimelineConfig} props.timelineConfig - * @return {React.ReactElement} - */ -const SearchResultsTimeline = ({ - onTimelineZoom, - resultsMetadata, - timelineBuckets, - timelineConfig, -}) => { - const isInputDisabled = isOperationInProgress(resultsMetadata.lastSignal); - useEffect(() => { - document.documentElement.style.setProperty( - "--timeline-chart-cursor", - isInputDisabled ? - "wait" : - "crosshair" - ); - }, [isInputDisabled]); - - if (null === timelineBuckets) { - return <>; - } - - const data = { - datasets: [ - { - backgroundColor: "#4096a0", - barPercentage: 1.2, - borderColor: "#007380", - borderWidth: 2, - minBarLength: 5, - - data: adaptTimelineBucketsForChartJs(timelineBuckets), - }, - ], - }; - - const options = { - animation: { - duration: 100, - }, - maintainAspectRatio: false, - responsive: true, - - scales: { - x: { - type: "time", - - max: timelineConfig.range.end.valueOf(), - min: timelineConfig.range.begin.valueOf(), - offset: false, - - grid: { - drawOnChartArea: false, - color: "black", - drawTicks: true, - offset: true, - }, - ticks: { - maxRotation: 0, - autoSkipPadding: 30, - major: {enabled: true}, - }, - time: { - displayFormats: { - millisecond: "HH:mm:ss.SSS", - second: "HH:mm:ss", - minute: "HH:mm", - hour: "HH:mm", - }, - parser: (date) => convertUtcDatetimeToSameLocalDate( - dayjs.utc(date) - ), - }, - }, - y: { - ticks: { - autoSkip: true, - autoSkipPadding: 10, - }, - }, - }, - - plugins: { - tooltip: { - callbacks: { - title: (tooltipItems) => { - const [{raw: {x}}] = tooltipItems; - const bucketBeginTime = dayjs.utc(x); - const bucketEndTime = bucketBeginTime - .add(timelineConfig.bucketDuration); - - return `${bucketBeginTime.format(DATETIME_FORMAT_TEMPLATE)} to\n` + - `${bucketEndTime.format(DATETIME_FORMAT_TEMPLATE)}`; - }, - }, - caretSize: 0, - intersect: false, - mode: "x", - xAlign: "left", - yAlign: "bottom", - }, - zoom: { - zoom: { - drag: { - enabled: false === isInputDisabled, - backgroundColor: "rgba(64,150,160,0.3)", - }, - mode: "x", - onZoom: ({chart}) => { - const xAxis = chart.scales.x; - const {min, max} = xAxis; - const newTimeRange = { - begin: convertZoomTimestampToUtcDatetime(parseInt(min, 10)), - end: convertZoomTimestampToUtcDatetime(parseInt(max, 10)), - }; - - onTimelineZoom(newTimeRange); - }, - }, - }, - }, - }; - - return ( - - ); -}; - -export default SearchResultsTimeline; -export {computeTimelineConfig}; diff --git a/components/webui/imports/ui/SearchView/SearchResults/index.jsx b/components/webui/imports/ui/SearchView/SearchResults/index.jsx deleted file mode 100644 index 4b2375f036..0000000000 --- a/components/webui/imports/ui/SearchView/SearchResults/index.jsx +++ /dev/null @@ -1,130 +0,0 @@ -import {useCallback} from "react"; -import Container from "react-bootstrap/Container"; -import Row from "react-bootstrap/Row"; - -import SearchResultsHeader from "./SearchResultsHeader"; -import SearchResultsTable from "./SearchResultsTable"; -import SearchResultsTimeline from "./SearchResultsTimeline"; - - -/** - * The initial visible results limit. - * - * @type {number} - * @constant - */ -const VISIBLE_RESULTS_LIMIT_INITIAL = 10; - -/** - * The increment value for the visible results limit. - * - * @type {number} - * @constant - */ -const VISIBLE_RESULTS_LIMIT_INCREMENT = 10; - -/** - * Renders the search results, which includes the search results header and the search results - * table. - * - * @param {object} props - * @param {number} props.estimatedNumResults - * @param {object} props.fieldToSortBy - * @param {number} props.maxLinesPerResult - * @param {Function} props.onTimelineZoom - * @param {SearchResultsMetadata} props.resultsMetadata - * @param {number} props.searchJobId - * @param {object[]} props.searchResults - * @param {Function} props.setFieldToSortBy - * @param {Function} props.setMaxLinesPerResult - * @param {Function} props.setVisibleSearchResultsLimit - * @param {TimelineBucket[]} props.timelineBuckets - * @param {TimelineConfig} props.timelineConfig - * @param {number} props.visibleSearchResultsLimit - * @return {React.ReactElement} - */ -const SearchResults = ({ - estimatedNumResults, - fieldToSortBy, - maxLinesPerResult, - onTimelineZoom, - resultsMetadata, - searchJobId, - searchResults, - setFieldToSortBy, - setMaxLinesPerResult, - setVisibleSearchResultsLimit, - timelineBuckets, - timelineConfig, - visibleSearchResultsLimit, -}) => { - let aggregatedCount = null; - if (null !== timelineBuckets && 0 !== timelineBuckets.length) { - aggregatedCount = timelineBuckets.reduce( - (accumulator, currentValue) => (accumulator + currentValue.count), - 0, - ); - } - - // The number of result in the results cache is available in different variables at different - // times: - // - when the search job ends, it will be in resultsMetadata.numTotalResults. - // - while the query is in progress, it will be in estimatedNumResults. - // - when the query starts, the other two variables will be null, so searchResults.length is the - // best estimate. - const numResultsInCache = - resultsMetadata.numTotalResults || - estimatedNumResults || - searchResults.length; - - const numResultsInTotal = aggregatedCount || numResultsInCache; - - const hasMoreResultsInCache = visibleSearchResultsLimit < numResultsInCache; - const hasMoreResultsInTotal = visibleSearchResultsLimit < numResultsInTotal; - - const handleLoadMoreResults = useCallback(() => { - if (hasMoreResultsInCache) { - setVisibleSearchResultsLimit((v) => v + VISIBLE_RESULTS_LIMIT_INCREMENT); - } - }, [ - hasMoreResultsInCache, - setVisibleSearchResultsLimit, - ]); - - return ( - <> - - - - - - - - - {0 < searchResults.length && - } - - ); -}; - -export default SearchResults; -export {VISIBLE_RESULTS_LIMIT_INITIAL}; diff --git a/components/webui/imports/ui/SearchView/SearchStatus.jsx b/components/webui/imports/ui/SearchView/SearchStatus.jsx deleted file mode 100644 index 8c63f41f22..0000000000 --- a/components/webui/imports/ui/SearchView/SearchStatus.jsx +++ /dev/null @@ -1,94 +0,0 @@ -import { - useEffect, - useRef, - useState, -} from "react"; -import ProgressBar from "react-bootstrap/ProgressBar"; - -import {faExclamationCircle} from "@fortawesome/free-solid-svg-icons"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - -import { - isSearchSignalQuerying, - SEARCH_SIGNAL, -} from "/imports/api/search/constants"; - -import "./SearchStatus.scss"; - - -// for pseudo progress bar -const PROGRESS_INCREMENT = 5; -const PROGRESS_INTERVAL_MILLIS = 100; - -/** - * Displays the status of a search operation, which shows error messages if any, and otherwise - * displays the current status of the search. - * - * @param {object} props - * @param {SearchResultsMetadata} props.resultsMetadata including the last search signal - * @param {string} props.errorMsg if there is an error - * @return {React.ReactElement} - */ -const SearchStatus = ({ - resultsMetadata, - errorMsg, -}) => { - const [progress, setProgress] = useState(0); - const timerIntervalRef = useRef(null); - - useEffect(() => { - if (true === isSearchSignalQuerying(resultsMetadata.lastSignal)) { - timerIntervalRef.current ??= setInterval(() => { - setProgress((v) => (v + PROGRESS_INCREMENT)); - }, PROGRESS_INTERVAL_MILLIS); - } else { - if (null !== timerIntervalRef.current) { - clearInterval(timerIntervalRef.current); - timerIntervalRef.current = null; - } - setProgress(0); - } - }, [resultsMetadata.lastSignal]); - - if ("" !== errorMsg && null !== errorMsg && "undefined" !== typeof errorMsg) { - return ( -
- - {errorMsg} -
- ); - } - let statusMessage = null; - switch (resultsMetadata.lastSignal) { - case SEARCH_SIGNAL.NONE: - statusMessage = "Ready"; - break; - case SEARCH_SIGNAL.REQ_CLEARING: - statusMessage = "Clearing..."; - break; - default: - break; - } - - return ( - <> - - {(null !== statusMessage) && -
- {statusMessage} -
} - - ); -}; - -export default SearchStatus; diff --git a/components/webui/imports/ui/SearchView/SearchStatus.scss b/components/webui/imports/ui/SearchView/SearchStatus.scss deleted file mode 100644 index 7d9e93ae4c..0000000000 --- a/components/webui/imports/ui/SearchView/SearchStatus.scss +++ /dev/null @@ -1,26 +0,0 @@ -.search-status-message { - color: #ccc; - font-size: 5rem; - line-height: 1em; - - padding: 1rem 2rem; - user-select: none; -} - -.search-error { - padding: 0.5rem; - - background-color: #ffc0c0; - color: #8e0000; - border-top: 1px solid #ca9b9b; - border-bottom: 1px solid #ecb4b4; -} - -.search-error-icon { - margin-right: 0.5rem; - vertical-align: middle; -} - -.search-progress-bar { - height: 4px !important; -} diff --git a/components/webui/imports/ui/SearchView/SearchView.jsx b/components/webui/imports/ui/SearchView/SearchView.jsx deleted file mode 100644 index e9d161fd63..0000000000 --- a/components/webui/imports/ui/SearchView/SearchView.jsx +++ /dev/null @@ -1,351 +0,0 @@ -/* eslint-disable max-lines, max-lines-per-function, max-statements */ -import {Meteor} from "meteor/meteor"; -import {useTracker} from "meteor/react-meteor-data"; -import { - useEffect, - useMemo, - useRef, - useState, -} from "react"; - -import {CLP_STORAGE_ENGINES} from "/imports/api/constants"; -import {SearchResultsMetadataCollection} from "/imports/api/search/collections"; -import { - SEARCH_RESULTS_FIELDS, - SEARCH_SIGNAL, -} from "/imports/api/search/constants"; -import SearchJobCollectionsManager from "/imports/api/search/SearchJobCollectionsManager"; -import { - DEFAULT_TIME_RANGE, - expandTimeRangeToDurationMultiple, -} from "/imports/utils/datetime"; -import {unquoteString} from "/imports/utils/misc"; -import { - MONGO_SORT_BY_ID, - MONGO_SORT_ORDER, -} from "/imports/utils/mongo"; - -import {LOCAL_STORAGE_KEYS} from "../constants"; -import SearchControls from "./SearchControls"; -import SearchResults, {VISIBLE_RESULTS_LIMIT_INITIAL} from "./SearchResults"; -import {computeTimelineConfig} from "./SearchResults/SearchResultsTimeline"; -import SearchStatus from "./SearchStatus"; - - -const DEFAULT_IGNORE_CASE_SETTING = true; - -/** - * Provides a search interface that allows users to query archives and visualize search results. - * - * @return {React.ReactElement} - */ -const SearchView = () => { - // Query states - const [searchJobId, setSearchJobId] = useState(null); - const [aggregationJobId, setAggregationJobId] = useState(null); - const [operationErrorMsg, setOperationErrorMsg] = useState(""); - const [localLastSearchSignal, setLocalLastSearchSignal] = useState(SEARCH_SIGNAL.NONE); - const [estimatedNumResults, setEstimatedNumResults] = useState(null); - const dbRef = useRef(new SearchJobCollectionsManager()); - - // gets updated as soon as localLastSearchSignal is updated - // to avoid reading old localLastSearchSignal value from Closures - const localLastSearchSignalRef = useRef(localLastSearchSignal); - - // Query options - const [queryString, setQueryString] = useState(""); - const [timeRange, setTimeRange] = useState(DEFAULT_TIME_RANGE); - const [timelineConfig, setTimelineConfig] = useState(null); - const [ignoreCase, setIgnoreCase] = useState(DEFAULT_IGNORE_CASE_SETTING); - const [visibleSearchResultsLimit, setVisibleSearchResultsLimit] = useState( - VISIBLE_RESULTS_LIMIT_INITIAL - ); - const [fieldToSortBy, setFieldToSortBy] = useState({ - name: SEARCH_RESULTS_FIELDS.TIMESTAMP, - direction: MONGO_SORT_ORDER.DESCENDING, - }); - - // Visuals - const [maxLinesPerResult, setMaxLinesPerResult] = useState( - Number(localStorage.getItem(LOCAL_STORAGE_KEYS.MAX_LINES_PER_RESULT) || 2) - ); - - // Subscriptions - /** - * @type {SearchResultsMetadata} - */ - const resultsMetadata = useTracker(() => { - let result = {lastSignal: localLastSearchSignal}; - - if (null !== searchJobId) { - const args = {searchJobId}; - const subscription = Meteor.subscribe( - Meteor.settings.public.SearchResultsMetadataCollectionName, - args - ); - const doc = SearchResultsMetadataCollection.findOne(); - - const isReady = subscription.ready(); - if (true === isReady) { - result = doc; - } - } - - return result; - }, [ - searchJobId, - localLastSearchSignal, - ]); - - const isExpectingUpdates = useMemo(() => (null !== searchJobId) && [ - SEARCH_SIGNAL.REQ_QUERYING, - SEARCH_SIGNAL.RESP_QUERYING, - ].includes(resultsMetadata.lastSignal), [ - searchJobId, - resultsMetadata.lastSignal, - ]); - - const searchResults = useTracker(() => { - if (null === searchJobId) { - return []; - } - - Meteor.subscribe(Meteor.settings.public.SearchResultsCollectionName, { - searchJobId: searchJobId, - isExpectingUpdates: isExpectingUpdates, - }); - - // NOTE: Although we publish and subscribe using the name - // `Meteor.settings.public.SearchResultsCollectionName`, the rows are still returned in the - // job-specific collection (e.g., "1"); this is because on the server, we're returning a - // cursor from the job-specific collection and Meteor creates a collection with the same - // name on the client rather than returning the rows in a collection with the published - // name. - const resultsCollection = dbRef.current.getOrCreateCollection(searchJobId); - const findOptions = { - limit: visibleSearchResultsLimit, - sort: [ - [ - fieldToSortBy.name, - fieldToSortBy.direction, - ], - MONGO_SORT_BY_ID, - ], - }; - - if (SEARCH_SIGNAL.RESP_DONE !== resultsMetadata.lastSignal) { - // Only refresh estimatedNumResults if the job isn't DONE; - // otherwise the count would already be available in - // `resultsMetadata.numTotalResults` - resultsCollection.estimatedDocumentCount() - .then(setEstimatedNumResults) - .catch((e) => { - console.log( - "Error occurred in " + - `resultsCollection<${searchJobId}>.estimatedDocumentCount()`, - e, - ); - }); - } - - return resultsCollection.find({}, findOptions).fetch(); - }, [ - fieldToSortBy, - isExpectingUpdates, - searchJobId, - visibleSearchResultsLimit, - ]); - - /** - * @type {TimelineBucket[]} - */ - const timelineBuckets = useTracker(() => { - if (null === aggregationJobId) { - return null; - } - - Meteor.subscribe(Meteor.settings.public.AggregationResultsCollectionName, { - aggregationJobId: aggregationJobId, - isExpectingUpdates: isExpectingUpdates, - }); - const collection = dbRef.current.getOrCreateCollection(aggregationJobId); - - return collection.find().fetch(); - }, [ - aggregationJobId, - isExpectingUpdates, - ]); - - // State transitions - useEffect(() => { - localStorage.setItem(LOCAL_STORAGE_KEYS.MAX_LINES_PER_RESULT, maxLinesPerResult.toString()); - }, [maxLinesPerResult]); - - useEffect(() => { - localLastSearchSignalRef.current = localLastSearchSignal; - }, [localLastSearchSignal]); - - // Handlers - const handleClearResults = () => { - setSearchJobId(null); - setAggregationJobId(null); - setOperationErrorMsg(""); - setLocalLastSearchSignal(SEARCH_SIGNAL.REQ_CLEARING); - setEstimatedNumResults(null); - setVisibleSearchResultsLimit(VISIBLE_RESULTS_LIMIT_INITIAL); - - const args = { - searchJobId, - aggregationJobId, - }; - - Meteor.call("search.clearResults", args, (error) => { - if (error) { - setOperationErrorMsg(error.reason); - - return; - } - - if (SEARCH_SIGNAL.REQ_CLEARING === localLastSearchSignalRef.current) { - // The check prevents clearing `localLastSearchSignal = SEARCH_SIGNAL.REQ_QUERYING` - // when `handleClearResults` is called by handleQuerySubmit. - setLocalLastSearchSignal(SEARCH_SIGNAL.NONE); - } - }); - }; - - const handleQuerySubmit = (newArgs) => { - if (null !== searchJobId) { - // Clear result caches before starting a new query - handleClearResults(); - } - - let processedQueryString = queryString; - if (CLP_STORAGE_ENGINES.CLP === Meteor.settings.public.ClpStorageEngine) { - try { - processedQueryString = unquoteString(queryString, '"', "\\"); - if ("" === processedQueryString) { - throw new Error("Cannot be empty."); - } - } catch (e) { - setOperationErrorMsg(`Invalid query: ${e.message}`); - - return; - } - } - - setOperationErrorMsg(""); - setLocalLastSearchSignal(SEARCH_SIGNAL.REQ_QUERYING); - setVisibleSearchResultsLimit(VISIBLE_RESULTS_LIMIT_INITIAL); - - const queryTimeRange = { - begin: timeRange.begin, - end: timeRange.end, - }; - - if ("undefined" !== typeof newArgs) { - queryTimeRange.begin = newArgs.begin; - queryTimeRange.end = newArgs.end; - setTimeRange(queryTimeRange); - } - - const timestampBeginUnixMillis = queryTimeRange.begin; - const timestampEndUnixMillis = queryTimeRange.end; - const newTimelineConfig = computeTimelineConfig( - timestampBeginUnixMillis, - timestampEndUnixMillis - ); - - setTimelineConfig(newTimelineConfig); - - const args = { - ignoreCase: ignoreCase, - queryString: processedQueryString, - timeRangeBucketSizeMillis: newTimelineConfig.bucketDuration.asMilliseconds(), - timestampBegin: timestampBeginUnixMillis.valueOf(), - timestampEnd: timestampEndUnixMillis.valueOf(), - }; - - Meteor.call("search.submitQuery", args, (error, result) => { - if (error) { - setOperationErrorMsg(error.reason); - - return; - } - - setSearchJobId(result.searchJobId); - setAggregationJobId(result.aggregationJobId); - }); - }; - - const handleCancelOperation = () => { - setOperationErrorMsg(""); - setLocalLastSearchSignal(SEARCH_SIGNAL.REQ_CANCELLING); - - const args = { - searchJobId, - aggregationJobId, - }; - - Meteor.call("search.cancelOperation", args, (error) => { - if (error) { - setOperationErrorMsg(error.reason); - } - }); - }; - - const handleTimelineZoom = (newTimeRange) => { - // Expand the time range to the granularity of buckets so if the user - // pans across at least one bar in the graph, we will zoom into a region - // that still contains log events. - const expandedTimeRange = expandTimeRangeToDurationMultiple( - timelineConfig.bucketDuration, - newTimeRange - ); - - handleQuerySubmit(expandedTimeRange); - }; - - return ( -
-
- - - -
- - {(null !== searchJobId) && } -
- ); -}; - -export default SearchView; - -/* eslint-enable max-lines, max-lines-per-function, max-statements */ diff --git a/components/webui/imports/ui/Sidebar/Sidebar.jsx b/components/webui/imports/ui/Sidebar/Sidebar.jsx deleted file mode 100644 index 78d0f00d53..0000000000 --- a/components/webui/imports/ui/Sidebar/Sidebar.jsx +++ /dev/null @@ -1,70 +0,0 @@ -import { - faAngleDoubleLeft, - faAngleDoubleRight, - faCircleInfo, - faMessage, -} from "@fortawesome/free-solid-svg-icons"; - -import SidebarButton from "./SidebarButton"; - -import "./Sidebar.scss"; - - -/** - * Renders a sidebar navigation component, which includes navigation links and a toggle for - * collapsing or expanding the sidebar. - * - * @param {object} props - * @param {boolean} props.isSidebarCollapsed indicates whether the sidebar is collapsed - * @param {object[]} props.routes objects for navigation links - * @param {Function} props.onSidebarToggle callback to toggle the sidebar's collapsed state - * @return {React.ReactElement} - */ -const Sidebar = ({ - isSidebarCollapsed, - routes, - onSidebarToggle, -}) => ( -
-
- {!isSidebarCollapsed && YScope} - {isSidebarCollapsed ? - CLP : - "CLP"} -
- -
- {routes.map((route, i) => (false === (route.hide ?? false)) && ( - - ))} -
- -
- - - -
-
-); - -export default Sidebar; diff --git a/components/webui/imports/ui/Sidebar/Sidebar.scss b/components/webui/imports/ui/Sidebar/Sidebar.scss deleted file mode 100644 index 2c75ea68f0..0000000000 --- a/components/webui/imports/ui/Sidebar/Sidebar.scss +++ /dev/null @@ -1,91 +0,0 @@ -#sidebar { - height: 100%; - min-width: 190px; - width: 190px; - - display: flex; - flex-direction: column; - - background: #080808; - color: #dedede; - - transition: min-width 0.5s, width 0.5s; -} - -#sidebar.collapsed { - min-width: 3rem; - width: 3rem; -} - -#sidebar .brand { - align-items: center; /* center element vertically */ - display: flex; - flex: 0 0 3rem; /* cannot grow, cannot shrink, 44px height */ - justify-content: center; /* center element horizontally */ - - border-left: 1px solid #111; - - font-size: 1.25rem; - white-space: nowrap; /* proper animation */ - overflow: hidden; /* proper animation */ -} - -.sidebar-menu { - flex: 1 1 auto; /* can shrink, can grow, auto height */ - display: flex; - flex-direction: column; - overflow-y: auto; - user-select: none; -} - -.sidebar-item-icon { - display: inline-block; - margin-left: -1px; - - width: 3rem; - - text-align: center; -} - -.sidebar-item-text { - opacity: inherit; - transition: opacity 0.5s; -} - -#sidebar.collapsed .sidebar-item-text { - opacity: 0; -} - -.sidebar-menu a { - border-left: 1px solid #333; - color: #aaa; - text-decoration: none; - - height: 3rem; - width: 100%; - - display: block; - margin-top: 2px; - overflow: hidden; - - line-height: 3rem; - white-space: nowrap; - - transition: width 0.5s; - - cursor: pointer; -} - -.sidebar-menu a:hover, .sidebar-menu .active { - border-left: 1px solid #dedede; - color: #dedede; - text-decoration: none; -} - -.sidebar-menu a:hover { - background-color: #0d5259; -} - -.sidebar-menu .active { - background-color: #004952; -} diff --git a/components/webui/imports/ui/Sidebar/SidebarButton.jsx b/components/webui/imports/ui/Sidebar/SidebarButton.jsx deleted file mode 100644 index c6b14728d5..0000000000 --- a/components/webui/imports/ui/Sidebar/SidebarButton.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import {NavLink} from "react-router-dom"; - -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; - - -/** - * Component for rendering a sidebar link. - * - * @param {object} props - * @param {import("@fortawesome/react-fontawesome").IconProp} props.icon - * @param {string} props.label - * @param {string} [props.link] - * @param {Function} [props.onClick] - * @return {React.ReactElement} - */ -const SidebarButton = ({ - icon, - label, - link, - onClick, -}) => { - const children = ( - <> -
- -
- - {label} - - - ); - - const isNavLink = ("undefined" !== typeof link) && link.startsWith("/"); - if (isNavLink) { - return ( - - {children} - - ); - } - - return ( - - {children} - - ); -}; - -export default SidebarButton; diff --git a/components/webui/imports/ui/bootstrap-customized.scss b/components/webui/imports/ui/bootstrap-customized.scss deleted file mode 100644 index e66685621a..0000000000 --- a/components/webui/imports/ui/bootstrap-customized.scss +++ /dev/null @@ -1,5 +0,0 @@ -$primary: #007380; -$secondary: #e9ecef; -$info: #a60058; - -@import "~bootstrap/scss/bootstrap"; diff --git a/components/webui/imports/ui/constants.js b/components/webui/imports/ui/constants.js deleted file mode 100644 index e5c7aeac87..0000000000 --- a/components/webui/imports/ui/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Dictionary for local storage items used in the application. - * - * @enum {string} - */ -const LOCAL_STORAGE_KEYS = Object.freeze({ - IS_SIDEBAR_COLLAPSED: "isSidebarCollapsed", - MAX_LINES_PER_RESULT: "maxLinesPerResult", - SEARCH_CONTROLS_VISIBLE: "searchFilterControlsVisible", -}); - -export {LOCAL_STORAGE_KEYS}; diff --git a/components/webui/imports/utils/DbManager.js b/components/webui/imports/utils/DbManager.js deleted file mode 100644 index 6607e9c72d..0000000000 --- a/components/webui/imports/utils/DbManager.js +++ /dev/null @@ -1,108 +0,0 @@ -import mysql from "mysql2/promise"; - -import { - deinitCompressionDbManager, - deinitStatsDbManager, - initCompressionDbManager, - initStatsDbManager, -} from "/imports/api/ingestion/server/publications"; -import {initQueryJobsDbManager} from "/imports/api/search/server/methods"; -import {logger} from "/imports/utils/logger"; - - -const DB_CONNECTION_LIMIT = 2; -const DB_MAX_IDLE = DB_CONNECTION_LIMIT; -const DB_IDLE_TIMEOUT_MILLIS = 10000; - -/** - * @type {import("mysql2/promise").Pool|null} - */ -let dbConnPool = null; - -/** - * Creates a new database connection and initializes DB managers with it. - * - * @param {object} dbConfig - * @param {string} dbConfig.dbHost - * @param {number} dbConfig.dbPort - * @param {string} dbConfig.dbName - * @param {string} dbConfig.dbPassword - * @param {string} dbConfig.dbUser - * @param {object} tableNames - * @param {string} tableNames.clpArchivesTableName - * @param {string} tableNames.clpFilesTableName - * @param {string} tableNames.compressionJobsTableName - * @param {string} tableNames.queryJobsTableName - * @return {Promise} - * @throws {Error} on error. - */ -const initDbManagers = async ({ - dbHost, - dbPort, - dbName, - dbPassword, - dbUser, -}, { - clpArchivesTableName, - clpFilesTableName, - compressionJobsTableName, - queryJobsTableName, -}) => { - if (null !== dbConnPool) { - throw Error("This method should not be called twice."); - } - - try { - // This method shall not be called twice and therefore incurs no race condition. - // eslint-disable-next-line require-atomic-updates - dbConnPool = await mysql.createPool({ - host: dbHost, - port: dbPort, - - database: dbName, - password: dbPassword, - user: dbUser, - - bigNumberStrings: true, - supportBigNumbers: true, - timezone: "Z", - - connectionLimit: DB_CONNECTION_LIMIT, - enableKeepAlive: true, - idleTimeout: DB_IDLE_TIMEOUT_MILLIS, - maxIdle: DB_MAX_IDLE, - }); - - initCompressionDbManager(dbConnPool, { - compressionJobsTableName, - }); - initQueryJobsDbManager(dbConnPool, { - queryJobsTableName, - }); - initStatsDbManager(dbConnPool, { - clpArchivesTableName, - clpFilesTableName, - }); - } catch (e) { - logger.error("Unable to create MySQL / mariadb connection pool.", e.toString()); - throw e; - } -}; - -/** - * De-initializes database managers. - * - * @return {Promise} - * @throws {Error} on error. - */ -const deinitDbManagers = async () => { - deinitCompressionDbManager(); - deinitStatsDbManager(); - - await dbConnPool.end(); -}; - -export { - deinitDbManagers, - initDbManagers, -}; diff --git a/components/webui/imports/utils/datetime.js b/components/webui/imports/utils/datetime.js deleted file mode 100644 index bff3aa4d2a..0000000000 --- a/components/webui/imports/utils/datetime.js +++ /dev/null @@ -1,172 +0,0 @@ -import dayjs from "dayjs"; -import Duration from "dayjs/plugin/duration"; -import Timezone from "dayjs/plugin/timezone"; -import Utc from "dayjs/plugin/utc"; - - -dayjs.extend(Utc); -dayjs.extend(Timezone); -dayjs.extend(Duration); - -const DATETIME_FORMAT_TEMPLATE = "YYYY-MMM-DD HH:mm:ss"; - -/* eslint-disable sort-keys */ -/** - * Enum of time units. - * - * @enum {string} - */ -const TIME_UNIT = Object.freeze({ - ALL: "all", - MINUTE: "minute", - HOUR: "hour", - DAY: "day", - WEEK: "week", - MONTH: "month", - YEAR: "year", -}); -/* eslint-enable sort-keys */ - -/* eslint-disable sort-keys */ -/** - * Enum of time range modifiers. - * - * @enum {string} - */ -const TIME_RANGE_MODIFIER = Object.freeze({ - NONE: "none", - TODAY: "today", - LAST: "last", - PREV: "prev", - TO_DATE: "to-date", -}); -/* eslint-enable sort-keys */ - -/** - * Time range presets. - * - * @type {{[key: string]: string}} - */ -const TIME_RANGE_PRESET_LABEL = Object.freeze({ - [`${TIME_UNIT.MINUTE}_${TIME_RANGE_MODIFIER.LAST}_15`]: "Last 15 Minutes", - [`${TIME_UNIT.MINUTE}_${TIME_RANGE_MODIFIER.LAST}_60`]: "Last 60 Minutes", - [`${TIME_UNIT.HOUR}_${TIME_RANGE_MODIFIER.LAST}_4`]: "Last 4 Hours", - [`${TIME_UNIT.HOUR}_${TIME_RANGE_MODIFIER.LAST}_24`]: "Last 24 Hours", - [`${TIME_UNIT.DAY}_${TIME_RANGE_MODIFIER.PREV}_1`]: "Previous Day", - [`${TIME_UNIT.WEEK}_${TIME_RANGE_MODIFIER.PREV}_1`]: "Previous Week", - [`${TIME_UNIT.MONTH}_${TIME_RANGE_MODIFIER.PREV}_1`]: "Previous Month", - [`${TIME_UNIT.YEAR}_${TIME_RANGE_MODIFIER.PREV}_1`]: "Previous Year", - [`${TIME_UNIT.DAY}_${TIME_RANGE_MODIFIER.TODAY}_0`]: "Today", - [`${TIME_UNIT.WEEK}_${TIME_RANGE_MODIFIER.TO_DATE}_0`]: "Week to Date", - [`${TIME_UNIT.MONTH}_${TIME_RANGE_MODIFIER.TO_DATE}_0`]: "Month to Date", - [`${TIME_UNIT.YEAR}_${TIME_RANGE_MODIFIER.TO_DATE}_0`]: "Year to Date", - [`${TIME_UNIT.ALL}_${TIME_RANGE_MODIFIER.NONE}_0`]: "All Time", -}); - -/** - * Computes a time range based on a token. - * - * @param {string} token representing the time range to compute; format: `unit_modifier_amount` - * @return {TimeRange} The computed time range - */ -const computeTimeRange = (token) => { - const [ - unit, - modifier, - amount, - ] = token.split("_"); - let end; - let begin; - - if (TIME_UNIT.ALL === unit) { - end = dayjs.utc().add(1, TIME_UNIT.YEAR); - begin = dayjs.utc(0); - } else { - const isEndingNow = [ - TIME_RANGE_MODIFIER.LAST, - TIME_RANGE_MODIFIER.TODAY, - TIME_RANGE_MODIFIER.TO_DATE, - ].includes(modifier); - const isBeginStartOfUnit = [ - TIME_RANGE_MODIFIER.PREV, - TIME_RANGE_MODIFIER.TODAY, - TIME_RANGE_MODIFIER.TO_DATE, - ].includes(modifier); - - end = (true === isEndingNow) ? - dayjs.utc() : - dayjs.utc() - .subtract(amount, unit) - .endOf(unit); - begin = (true === isBeginStartOfUnit) ? - end.startOf(unit) : - end.subtract(amount, unit); - } - - return { - begin, - end, - }; -}; - -const DEFAULT_TIME_RANGE = computeTimeRange( - `${TIME_UNIT.ALL}_${TIME_RANGE_MODIFIER.NONE}_0`, -); - -// eslint-disable-next-line no-warning-comments -// TODO: Switch date pickers so we don't have to do this hack -/** - * Converts a UTC Dayjs object to a local-timezone JavaScript Date object that represents the same - * date and time. In other words, the original year, month, day, hour, minute, second, and - * millisecond appear unchanged. - * - * @param {dayjs.Dayjs} utcDatetime - * @return {Date} The corresponding Date object - */ -const convertUtcDatetimeToSameLocalDate = (utcDatetime) => { - const localTz = dayjs.tz.guess(); - return utcDatetime.tz(localTz, true).toDate(); -}; - -/** - * Converts a local-timezone JavaScript Date object to a UTC Dayjs object that represents the same - * date and time. In other words, the original year, month, day, hour, minute, second, and - * millisecond appear unchanged. - * - * @param {Date} localDate - * @return {dayjs.Dayjs} The corresponding Dayjs object - */ -const convertLocalDateToSameUtcDatetime = (localDate) => { - return dayjs(localDate).utc(true); -}; - -/** - * Expands the time range so that both extremes are multiples of the given duration. - * - * @param {dayjs.Duration} duration - * @param {TimeRange} timeRange The time range to be expanded. - * @return {TimeRange} The expanded time range. - */ -const expandTimeRangeToDurationMultiple = (duration, { - begin, - end, -}) => { - const adjustedBegin = begin - (begin % duration.asMilliseconds()); - const adjustedEnd = - Math.floor( - (end + duration.asMilliseconds() - 1) / duration.asMilliseconds() - ) * duration.asMilliseconds(); - - return {begin: dayjs.utc(adjustedBegin), end: dayjs.utc(adjustedEnd)}; -}; - -export { - computeTimeRange, - convertLocalDateToSameUtcDatetime, - convertUtcDatetimeToSameLocalDate, - DATETIME_FORMAT_TEMPLATE, - DEFAULT_TIME_RANGE, - expandTimeRangeToDurationMultiple, - TIME_RANGE_PRESET_LABEL, - TIME_UNIT, -}; diff --git a/components/webui/imports/utils/logger.js b/components/webui/imports/utils/logger.js deleted file mode 100644 index eca756129f..0000000000 --- a/components/webui/imports/utils/logger.js +++ /dev/null @@ -1,147 +0,0 @@ -import JSON5 from "json5"; -import winston from "winston"; - -import "winston-daily-rotate-file"; - - -const MAX_LOGS_FILE_SIZE = "100m"; -const MAX_LOGS_RETENTION_DAYS = "30d"; - -let winstonLogger = null; -let isTraceEnabled = false; - -/* eslint-disable sort-keys */ -// attribute names should match clp_py_utils.clp_logging.LOGGING_LEVEL_MAPPING -const webuiLoggingLevelToWinstonMap = { - DEBUG: "debug", - INFO: "info", - WARN: "warn", - WARNING: "warn", - ERROR: "error", - CRITICAL: "error", -}; -/* eslint-enable sort-keys */ - -/* eslint-disable prefer-destructuring, no-magic-numbers */ -/** - * Retrieves information about the calling function's stack trace. - * - * @return {object | null} an object containing method, filePath, and line information, - * or null if the information couldn't be extracted - */ -const getStackInfo = () => { - let info; - - const stackList = (new Error()).stack.split("\n"); - const stackInfo = stackList[4]; - const stackRegex = /at\s+(.*)\s+\((.*):(\d+):(\d+)\)/i; - const stackMatch = stackRegex.exec(stackInfo); - - if (null !== stackMatch && 5 === stackMatch.length) { - info = { - method: stackMatch[1], - filePath: stackMatch[2], - line: stackMatch[3], - }; - } else { - const stackRegex2 = /at\s+(.*):(\d*):(\d*)/i; - const stackMatch2 = stackRegex2.exec(stackInfo); - info = { - method: "", - filePath: stackMatch2[1], - line: stackMatch2[2], - }; - } - - return info; -}; -/* eslint-enable prefer-destructuring, no-magic-numbers */ - -/** - * Logs a message with the specified log level, including optional trace information. - * - * @param {string} level of the log message - * @param {...any} args message or data to be logged - */ -const fileLineFuncLog = (level, ...args) => { - let logMessage = `${args.map((a) => (("string" === typeof a) ? - a : - JSON5.stringify(a))).join(" ")}`; - let logLabel = ""; - - if (true === isTraceEnabled) { - const stackInfo = getStackInfo(); - - if (null !== stackInfo) { - logMessage = `[${stackInfo.filePath}:${stackInfo.line}] ${logMessage}`; - logLabel = stackInfo.method; - } - } - - winstonLogger.log({ - level: level, - message: logMessage, - label: logLabel, - }); -}; - -/* eslint-disable sort-keys */ -/** - * Logger interface object that provides logging with different levels. - */ -const logger = Object.freeze({ - error: (...args) => (fileLineFuncLog("error", ...args)), - warn: (...args) => (fileLineFuncLog("warn", ...args)), - help: (...args) => (fileLineFuncLog("help", ...args)), - data: (...args) => (fileLineFuncLog("data", ...args)), - info: (...args) => (fileLineFuncLog("info", ...args)), - debug: (...args) => (fileLineFuncLog("debug", ...args)), - prompt: (...args) => (fileLineFuncLog("prompt", ...args)), - verbose: (...args) => (fileLineFuncLog("verbose", ...args)), - input: (...args) => (fileLineFuncLog("input", ...args)), - silly: (...args) => (fileLineFuncLog("silly", ...args)), -}); -/* eslint-enable sort-keys */ - -/** - * Initializes winston logger with the specified configuration. - * - * @param {string} logsDir where log files will be stored. - * @param {string} webuiLoggingLevel messages higher than this level will be logged - * @param {boolean} [_isTraceEnabled] whether to log function & file names and line numbers - */ -const initLogger = (logsDir, webuiLoggingLevel, _isTraceEnabled = false) => { - isTraceEnabled = _isTraceEnabled; - - winstonLogger = winston.createLogger({ - level: webuiLoggingLevelToWinstonMap[webuiLoggingLevel], - format: winston.format.combine( - winston.format.timestamp(), - winston.format.printf((info) => { - return JSON.stringify({ - timestamp: info.timestamp, - level: info.level, - label: info.label, - message: info.message, - }); - }), - ), - transports: [ - new winston.transports.Console(), - new winston.transports.DailyRotateFile({ - datePattern: "YYYY-MM-DD-HH", - dirname: logsDir, - filename: "webui-%DATE%.log", - maxFiles: MAX_LOGS_RETENTION_DAYS, - maxSize: MAX_LOGS_FILE_SIZE, - }), - ], - }); - - logger.info("logger has been initialized"); -}; - -export { - initLogger, - logger, -}; diff --git a/components/webui/imports/utils/misc.js b/components/webui/imports/utils/misc.js deleted file mode 100644 index 943a417fca..0000000000 --- a/components/webui/imports/utils/misc.js +++ /dev/null @@ -1,120 +0,0 @@ -const MILLIS_PER_SECOND = 1000; -const BYTES_PER_KIBIBYTE = 1024; - -/** - * Creates a promise that resolves after a specified number of seconds. - * - * @param {number} seconds to wait before resolving the promise - * @return {Promise} that resolves after the specified delay - */ -const sleep = (seconds) => new Promise((resolve) => { - setTimeout(resolve, seconds * MILLIS_PER_SECOND); -}); - -/** - * Computes a human-readable representation of a size in bytes. - * - * @param {number} num - * @return {string} - */ -const computeHumanSize = (num) => { - // eslint-disable-next-line @stylistic/js/array-element-newline - const siPrefixes = ["", "K", "M", "G", "T", "P", "E", "Z"]; - for (let i = 0; i < siPrefixes.length; ++i) { - if (BYTES_PER_KIBIBYTE > Math.abs(num)) { - return `${Math.round(num)} ${siPrefixes[i]}B`; - } - num /= BYTES_PER_KIBIBYTE; - } - - return `${Math.round(num)} B`; -}; - -/** - * Deselects all selections within the browser viewport. - */ -const deselectAll = () => { - window.getSelection().removeAllRanges(); -}; - - -/** - * Removes wrapping quotes from the given string, if it's quoted, and unescapes quotes from within - * the quoted string. - * NOTE: This method does *not* unescape non-quote characters, unlike most methods which handle - * unescaping quotes. - * - * @param {string} str - * @param {string} quoteChar - * @param {string} escapeChar - * @return {string} The processed string - * @throws Error if the quoted string has a quote within it (rather than at its ends) or it's - * missing one of it's begin/end quotes. - */ -// eslint-disable-next-line max-statements -const unquoteString = ( - str, - quoteChar, - escapeChar, -) => { - if (0 === str.length) { - return str; - } - - // Determine the position of every character that we should remove from the processed string - const positionOfCharsToRemove = []; - const chars = Array.from(str); - let isEscaped = false; - for (let i = 0; i < chars.length; ++i) { - const c = chars[i]; - if (isEscaped) { - isEscaped = false; - if (c === quoteChar) { - // We only remove the escape characters that escape quotes - positionOfCharsToRemove.push(i - 1); - } - } else if (c === escapeChar) { - isEscaped = true; - } else if (c === quoteChar) { - positionOfCharsToRemove.push(i); - } - } - - if (0 === positionOfCharsToRemove.length) { - return str; - } - - // Ensure any unescaped quotes are only at the beginning and end of the string - let foundBeginQuote = false; - let foundEndQuote = false; - positionOfCharsToRemove.forEach((pos) => { - const char = chars[pos]; - if (quoteChar === char) { - if (0 === pos) { - foundBeginQuote = true; - } else if (chars.length - 1 === pos) { - foundEndQuote = true; - } else { - throw new Error(`Found unescaped quote character (${quoteChar}) within.`); - } - } - }); - if (foundBeginQuote ^ foundEndQuote) { - throw new Error("Begin/end quote is missing."); - } - - const processedChars = chars.filter( - (c, i) => ( - false === positionOfCharsToRemove.includes(i) - ) - ); - - return processedChars.join(""); -}; - -export { - computeHumanSize, - deselectAll, - sleep, - unquoteString, -}; diff --git a/components/webui/imports/utils/mongo.js b/components/webui/imports/utils/mongo.js deleted file mode 100644 index 8719f3d529..0000000000 --- a/components/webui/imports/utils/mongo.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Enum of Mongo Collection sort orders. - * - * @enum {string} - */ -const MONGO_SORT_ORDER = Object.freeze({ - ASCENDING: "asc", - DESCENDING: "desc", -}); - -/** - * The sort order for MongoDB queries using the "_id" field. - * - * @type {string[]} - */ -const MONGO_SORT_BY_ID = Object.freeze([ - "_id", - MONGO_SORT_ORDER.DESCENDING, -]); - -export { - MONGO_SORT_BY_ID, - MONGO_SORT_ORDER, -}; diff --git a/components/webui/launcher.js b/components/webui/launcher.js deleted file mode 100644 index 5d1f6f14ec..0000000000 --- a/components/webui/launcher.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Production launcher for CLP WebUI, which redirects Meteor server stderr to rotated error logs - * files in a specified directory for error monitoring. - * - * To avoid duplicated installations of dependencies, use the same `node_modules` for the server - * by setting envvar NODE_PATH="./programs/server/npm/node_modules", assuming this script is - * placed under the same directory where the bundled `main.js` is located. - * - * This is not intended for development use. For development, please refer to README.md in the - * component root for launching a development server with Meteor-specific error messages print - * to the console. - * - * ENVIRONMENT VARIABLES: - * - NODE_PATH: path to node_modules including "winston" and "winston-daily-rotate-file" - * - WEBUI_LOGS_DIR: path to error logs directory - * SCRIPT USAGE: - * - usage: node /path/to/launcher.js /path/to/main.js - */ - -const {spawn} = require("child_process"); -const winston = require("winston"); -require("winston-daily-rotate-file"); - - -const DEFAULT_LOGS_DIR = "."; - -const MAX_LOGS_FILE_SIZE = "100m"; -const MAX_LOGS_RETENTION_DAYS = "30d"; - -/** - * Creates a logger using winston module. - * - * @param {string} logsDir directory where the log files will be saved. - * @return {object} the logger object - */ -const getLogger = (logsDir) => { - return winston.createLogger({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.printf((info) => { - return JSON.stringify({ - timestamp: info.timestamp, - level: info.level, - label: info.label, - message: info.message, - }); - }), - ), - transports: [ - new winston.transports.DailyRotateFile({ - datePattern: "YYYY-MM-DD-HH", - dirname: logsDir, - filename: "webui_error-%DATE%.log", - maxFiles: MAX_LOGS_RETENTION_DAYS, - maxSize: MAX_LOGS_FILE_SIZE, - }), - ], - }); -}; - - -/** - * Runs a script with logging support. - * - * @param {string} logsDir path where the logs will be stored - * @param {string} scriptPath path of the script to be executed - */ -const runScript = (logsDir, scriptPath) => { - const logger = getLogger(logsDir); - const script = spawn(process.argv0, [scriptPath]); - - script.stderr.on("data", (data) => { - logger.error(data.toString()); - }); - - script.on("close", (code) => { - console.log(`Child process exited with code ${code}`); - }); -}; - -/** - * Parses the command line arguments and retrieves the values for the - * WEBUI_LOGS_DIR and scriptPath variables. - * - * @return {object} containing the values for WEBUI_LOGS_DIR and scriptPath - */ -const parseArgs = () => { - const WEBUI_LOGS_DIR = process.env.WEBUI_LOGS_DIR || DEFAULT_LOGS_DIR; - // eslint-disable-next-line prefer-destructuring - const scriptPath = process.argv[2]; - - return { - WEBUI_LOGS_DIR, - scriptPath, - }; -}; - -/** - * The main function of the program. - * - * This function is the entry point of the program. - * - * @return {void} - */ -const main = () => { - const args = parseArgs(); - - runScript(args.WEBUI_LOGS_DIR, args.scriptPath); -}; - -main(); diff --git a/components/webui/linter/package-lock.json b/components/webui/linter/package-lock.json deleted file mode 100644 index eab4f59f02..0000000000 --- a/components/webui/linter/package-lock.json +++ /dev/null @@ -1,4494 +0,0 @@ -{ - "name": "linter", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "devDependencies": { - "eslint-config-yscope": "0.0.32" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.46.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", - "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "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_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", - "peer": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "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", - "peer": true - }, - "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", - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "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", - "peer": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", - "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "acorn": "^8.11.3", - "escape-string-regexp": "^4.0.0", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", - "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "^1.8.1", - "@types/eslint": "^8.56.10", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", - "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^6.21.0" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "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", - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "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", - "peer": true - }, - "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", - "peer": true - }, - "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", - "peer": true - }, - "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", - "peer": true - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", - "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "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", - "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "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", - "peer": true, - "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" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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", - "peer": true, - "engines": { - "node": ">=14" - } - }, - "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", - "peer": 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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "license": "MIT", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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": "MIT", - "peer": true, - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "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", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "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", - "peer": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "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", - "peer": true - }, - "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", - "peer": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "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", - "peer": true, - "dependencies": { - "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/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", - "peer": true, - "dependencies": { - "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/inspect-js" - } - }, - "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", - "peer": true, - "dependencies": { - "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/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", - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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", - "peer": true - }, - "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", - "peer": true, - "dependencies": { - "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/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", - "peer": true, - "dependencies": { - "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/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", - "peer": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "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", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "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": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "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": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "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", - "peer": true, - "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" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-yscope": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/eslint-config-yscope/-/eslint-config-yscope-0.0.32.tgz", - "integrity": "sha512-eLeOT8AFkjSqy/oxJTxJ/e7d9+qMDZTxqL926asp4VS0LxngxqOQRrUkTKrWXZiE6AQBJuK1udHQI1pgZBxehw==", - "dev": true, - "peerDependencies": { - "@stylistic/eslint-plugin-js": "^1.6.2", - "@stylistic/eslint-plugin-jsx": "^1.6.2", - "@stylistic/eslint-plugin-plus": "^1.6.2", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-import-newlines": "^1.4.0", - "eslint-plugin-jsdoc": "^48.2.3", - "eslint-plugin-no-autofix": "^1.2.3", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-simple-import-sort": "^12.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import-newlines": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-newlines/-/eslint-plugin-import-newlines-1.4.0.tgz", - "integrity": "sha512-+Cz1x2xBLtI9gJbmuYEpvY7F8K75wskBmJ7rk4VRObIJo+jklUJaejFJgtnWeL0dCFWabGEkhausrikXaNbtoQ==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "import-linter": "lib/index.js" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-import/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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "48.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.11.0.tgz", - "integrity": "sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.46.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.5", - "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.6.0", - "parse-imports": "^2.1.1", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-jsdoc/node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-no-autofix": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-autofix/-/eslint-plugin-no-autofix-1.2.3.tgz", - "integrity": "sha512-JFSYe82Da2A8Krh+Gfq7+3X2pchTScKgmrlMKIA4HmV6t5xGBF/kgjiFL3YTWRQXQ0NB9eOqpcxh6SuLtQUFjQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0", - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "eslint": ">= 5.12.1" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.37.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", - "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.3", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.2.1", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.8", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.1", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.12", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", - "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", - "dev": true, - "license": "MIT", - "peer": true, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fastq": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", - "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "function-bind": "^1.1.2", - "get-proto": "^1.0.0", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/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", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/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": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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", - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", - "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", - "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", - "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", - "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-imports": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", - "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", - "dev": true, - "license": "Apache-2.0 AND MIT", - "peer": true, - "dependencies": { - "es-module-lexer": "^1.5.3", - "slashes": "^3.0.12" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peer": true - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slashes": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", - "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0", - "peer": true - }, - "node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", - "dev": true, - "license": "CC0-1.0", - "peer": true - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dev": true, - "license": "MIT", - "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-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "peer": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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 OR CC0-1.0)", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/components/webui/linter/package.json b/components/webui/linter/package.json deleted file mode 100644 index 491012675c..0000000000 --- a/components/webui/linter/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "scripts": { - "lint:check": "npx eslint --no-eslintrc --config package.json ../client ../imports ../server ../tests ../launcher.js", - "lint:fix": "npm run lint:check -- --fix" - }, - "devDependencies": { - "eslint-config-yscope": "0.0.32" - }, - "eslintConfig": { - "extends": [ - "yscope/meteor" - ] - } -} diff --git a/components/webui/package-lock.json b/components/webui/package-lock.json index c7644cc78e..50f7f6c8c8 100644 --- a/components/webui/package-lock.json +++ b/components/webui/package-lock.json @@ -1,2238 +1,351 @@ { "name": "webui", + "version": "0.1.0", + "lockfileVersion": 3, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", - "requires": { - "@babel/highlight": "^7.25.7", - "picocolors": "^1.0.0" - } - }, - "@babel/compat-data": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", - "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==" - }, - "@babel/core": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", - "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/helper-compilation-targets": "^7.25.7", - "@babel/helper-module-transforms": "^7.25.7", - "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.8", - "@babel/template": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.8", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - } - }, - "@babel/generator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", - "requires": { - "@babel/types": "^7.25.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz", - "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==", - "requires": { - "@babel/types": "^7.25.7" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", - "requires": { - "@babel/compat-data": "^7.25.7", - "@babel/helper-validator-option": "^7.25.7", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - } - }, - "@babel/helper-module-imports": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", - "requires": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", - "requires": { - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-simple-access": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "@babel/traverse": "^7.25.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", - "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==" - }, - "@babel/helper-simple-access": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", - "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", - "requires": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/helper-string-parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==" - }, - "@babel/helper-validator-identifier": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==" - }, - "@babel/helper-validator-option": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==" - }, - "@babel/helpers": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", - "requires": { - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", - "requires": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - } - }, - "@babel/parser": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", - "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", - "requires": { - "@babel/types": "^7.25.8" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz", - "integrity": "sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.25.7" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.7.tgz", - "integrity": "sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.25.7", - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-jsx": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", - "requires": { + "packages": { + "": { + "name": "webui", + "version": "0.1.0", + "license": "Apache-2.0", + "devDependencies": { + "concurrently": "^8.2.2" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dev": true, + "dependencies": { "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", - "requires": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/traverse": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", - "requires": { - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", - "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", - "requires": { - "@babel/helper-string-parser": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "to-fast-properties": "^2.0.0" - } - }, - "@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" - }, - "@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@fortawesome/fontawesome-common-types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", - "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", - "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.6.0" - } - }, - "@fortawesome/free-solid-svg-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz", - "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.6.0" - } - }, - "@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", - "requires": { - "prop-types": "^15.8.1" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@jsdoc/salty": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", - "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "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, - "requires": { - "lodash": "^4.17.21" - } - }, - "@kurkle/color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", - "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" - }, - "@msgpack/msgpack": { - "version": "3.0.0-beta2", - "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.0.0-beta2.tgz", - "integrity": "sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==" - }, - "@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" - }, - "@react-aria/ssr": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.6.tgz", - "integrity": "sha512-iLo82l82ilMiVGy342SELjshuWottlb5+VefO3jOQqQRNYnJBFpUSadswDPbRimSgJUZuFwIEYs6AabkP038fA==", - "requires": { - "@swc/helpers": "^0.5.0" - } - }, - "@restart/hooks": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", - "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", - "requires": { - "dequal": "^2.0.3" + "engines": { + "node": ">=8" } }, - "@restart/ui": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.8.0.tgz", - "integrity": "sha512-xJEOXUOTmT4FngTmhdjKFRrVVF0hwCLNPdatLCHkyS4dkiSK12cEu1Y0fjxktjJrdst9jJIc5J6ihMJCoWEN/g==", - "requires": { - "@babel/runtime": "^7.21.0", - "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.4.9", - "@types/warning": "^3.0.0", - "dequal": "^2.0.3", - "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.1", - "warning": "^4.0.3" - }, + "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, "dependencies": { - "uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==" - } - } - }, - "@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", - "requires": { - "tslib": "^2.4.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "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, - "requires": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" - }, - "@types/react": { - "version": "18.3.11", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", - "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", - "requires": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-transition-group": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", - "requires": { - "@types/react": "*" - } - }, - "@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "@types/warning": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", - "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "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 - }, - "async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" - }, - "aws-ssl-profiles": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", - "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bootstrap": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", - "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==" - }, - "browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "requires": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "caniuse-lite": { - "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==" - }, - "catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "chart.js": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.5.tgz", - "integrity": "sha512-CVVjg1RYTJV9OCC8WeJPMx8gsV8K6WIyIEQUE3ui4AR9Hfgls9URri6Ja3hyMVBbTF8Q2KFa19PE815gWcWhng==", - "requires": { - "@kurkle/color": "^0.3.0" + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "chartjs-adapter-dayjs-4": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chartjs-adapter-dayjs-4/-/chartjs-adapter-dayjs-4-1.0.4.tgz", - "integrity": "sha512-yy9BAYW4aNzPVrCWZetbILegTRb7HokhgospPoC3b5iZ5qdlqNmXts2KdSp6AqnjkPAp/YWyHDxLvIvwt5x81w==" - }, - "chartjs-plugin-zoom": { + "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.0.1.tgz", - "integrity": "sha512-ogOmLu6e+Q7E1XWOCOz9YwybMslz9qNfGV2a+qjfmqJYpsw5ZMoRHZBUyW+NGhkpQ5PwwPA/+rikHpBZb7PZuA==", - "requires": { - "hammerjs": "^2.0.8" - } - }, - "classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "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==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "colorspace": { + "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "requires": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "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==" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "node_modules/concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } }, - "date-fns": { + "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "requires": { + "dev": true, + "dependencies": { "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, - "dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" - }, - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" - }, - "dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "electron-to-chromium": { - "version": "1.5.41", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz", - "integrity": "sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==" - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true - }, - "escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "file-stream-rotator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", - "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", - "requires": { - "moment": "^2.29.1" - } - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, - "requires": { - "xmlcreate": "^2.0.4" + "engines": { + "node": ">=6" } }, - "jsdoc": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", - "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "requires": { - "@babel/parser": "^7.20.15", - "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^14.1.1", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^14.1.0", - "markdown-it-anchor": "^8.6.7", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "underscore": "~1.13.2" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "graceful-fs": "^4.1.9" + "engines": { + "node": ">=8" } }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "requires": { - "uc.micro": "^2.0.0" + "engines": { + "node": ">=8" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "logform": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", - "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", - "requires": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - }, - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" } }, - "lru.min": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.1.tgz", - "integrity": "sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==" - }, - "markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "dev": true - }, - "marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true - }, - "mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, - "meteor-node-stubs": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-1.2.10.tgz", - "integrity": "sha512-zP1AVg8sOATz15yfy11R2VTx+IZFfAOXi8GuZa8tOfeVT1tKaqDooAbFylnIXwpStSu6HRBUhQqHtR06Qr9aEA==", - "requires": { - "@meteorjs/crypto-browserify": "^3.12.1", - "assert": "^2.1.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.7.1", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "domain-browser": "^4.23.0", - "elliptic": "^6.5.7", - "events": "^3.3.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^1.4.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.2", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "0.0.1", - "url": "^0.11.4", - "util": "^0.12.5", - "vm-browserify": "^1.1.2" - }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { - "@meteorjs/crypto-browserify": { - "version": "3.12.1", - "bundled": true, - "requires": { - "browserify-cipher": "^1.0.1", - "browserify-sign": "^4.2.3", - "create-ecdh": "^4.0.4", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "diffie-hellman": "^5.0.3", - "hash-base": "~3.0.4", - "inherits": "^2.0.4", - "pbkdf2": "^3.1.2", - "public-encrypt": "^4.0.3", - "randombytes": "^2.1.0", - "randomfill": "^1.0.4" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "asn1.js": { - "version": "4.10.1", - "bundled": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "assert": { - "version": "2.1.0", - "bundled": true, - "requires": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "bundled": true - }, - "base64-js": { - "version": "1.5.1", - "bundled": true - }, - "bn.js": { - "version": "5.2.0", - "bundled": true - }, - "brorand": { - "version": "1.1.0", - "bundled": true - }, - "browserify-aes": { - "version": "1.2.0", - "bundled": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "bundled": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "bundled": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "bundled": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.3", - "bundled": true, - "requires": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "bundled": true - }, - "hash-base": { - "version": "3.0.4", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "readable-stream": { - "version": "2.3.8", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "bundled": true - } - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "bundled": true - } - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "bundled": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.7.1", - "bundled": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-xor": { - "version": "1.0.3", - "bundled": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "bundled": true - }, - "call-bind": { - "version": "1.0.7", - "bundled": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "cipher-base": { - "version": "1.0.4", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "console-browserify": { - "version": "1.2.0", - "bundled": true - }, - "constants-browserify": { - "version": "1.0.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.3", - "bundled": true - }, - "create-ecdh": { - "version": "4.0.4", - "bundled": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "bundled": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "bundled": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "define-data-property": { - "version": "1.1.4", - "bundled": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-properties": { - "version": "1.2.1", - "bundled": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "des.js": { - "version": "1.0.1", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "bundled": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "domain-browser": { - "version": "4.23.0", - "bundled": true - }, - "elliptic": { - "version": "6.5.7", - "bundled": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "es-define-property": { - "version": "1.0.0", - "bundled": true, - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "bundled": true - }, - "events": { - "version": "3.3.0", - "bundled": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "bundled": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "for-each": { - "version": "0.3.3", - "bundled": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "function-bind": { - "version": "1.1.2", - "bundled": true - }, - "get-intrinsic": { - "version": "1.2.4", - "bundled": true, - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "bundled": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has-property-descriptors": { - "version": "1.0.2", - "bundled": true, - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.1", - "bundled": true - }, - "has-symbols": { - "version": "1.0.3", - "bundled": true - }, - "has-tostringtag": { - "version": "1.0.0", - "bundled": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "bundled": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasown": { - "version": "2.0.0", - "bundled": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "bundled": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "https-browserify": { - "version": "1.0.0", - "bundled": true - }, - "ieee754": { - "version": "1.2.1", - "bundled": true - }, - "inherits": { - "version": "2.0.4", - "bundled": true - }, - "is-arguments": { - "version": "1.1.1", - "bundled": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "bundled": true - }, - "is-generator-function": { - "version": "1.0.10", - "bundled": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-nan": { - "version": "1.3.2", - "bundled": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-typed-array": { - "version": "1.1.12", - "bundled": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "md5.js": { - "version": "1.3.5", - "bundled": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "bundled": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "bundled": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "bundled": true - }, - "object-inspect": { - "version": "1.13.2", - "bundled": true - }, - "object-is": { - "version": "1.1.5", - "bundled": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "bundled": true - }, - "object.assign": { - "version": "4.1.4", - "bundled": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "os-browserify": { - "version": "0.3.0", - "bundled": true - }, - "pako": { - "version": "1.0.11", - "bundled": true - }, - "parse-asn1": { - "version": "5.1.7", - "bundled": true, - "requires": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "path-browserify": { - "version": "1.0.1", - "bundled": true - }, - "pbkdf2": { - "version": "3.1.2", - "bundled": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "process": { - "version": "0.11.10", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true - }, - "public-encrypt": { - "version": "4.0.3", - "bundled": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "bundled": true - } - } - }, - "punycode": { - "version": "1.4.1", - "bundled": true - }, - "qs": { - "version": "6.13.0", - "bundled": true, - "requires": { - "side-channel": "^1.0.6" - } - }, - "querystring-es3": { - "version": "0.2.1", - "bundled": true - }, - "randombytes": { - "version": "2.1.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "bundled": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "ripemd160": { - "version": "2.0.2", - "bundled": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true - }, - "set-function-length": { - "version": "1.2.2", - "bundled": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "setimmediate": { - "version": "1.0.5", - "bundled": true - }, - "sha.js": { - "version": "2.4.11", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "side-channel": { - "version": "1.0.6", - "bundled": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "stream-browserify": { - "version": "3.0.0", - "bundled": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "bundled": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "timers-browserify": { - "version": "2.0.12", - "bundled": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tty-browserify": { - "version": "0.0.1", - "bundled": true - }, - "url": { - "version": "0.11.4", - "bundled": true, - "requires": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - } - }, - "util": { - "version": "0.12.5", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "vm-browserify": { - "version": "1.1.2", - "bundled": true - }, - "which-typed-array": { - "version": "1.1.13", - "bundled": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "xtend": { - "version": "4.0.2", - "bundled": true - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "mysql2": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.3.tgz", - "integrity": "sha512-Qpu2ADfbKzyLdwC/5d4W7+5Yz7yBzCU05YWt5npWzACST37wJsB23wgOSo00qi043urkiRwXtEvJc9UnuLX/MQ==", - "requires": { - "aws-ssl-profiles": "^1.1.1", - "denque": "^2.1.0", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^5.2.1", - "lru.min": "^1.0.0", - "named-placeholders": "^1.1.3", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - } - }, - "named-placeholders": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", - "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", - "requires": { - "lru-cache": "^7.14.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - } - } - }, - "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" + "engines": { + "node": ">=8" } }, - "path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "requires": { - "isarray": "0.0.1" - } - }, - "picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "prop-types-extra": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "requires": { - "react-is": "^16.3.2", - "warning": "^4.0.0" - } - }, - "punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true - }, - "react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-bootstrap": { - "version": "2.10.5", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.5.tgz", - "integrity": "sha512-XueAOEn64RRkZ0s6yzUTdpFtdUXs5L5491QU//8ZcODKJNDLt/r01tNyriZccjgRImH1REynUc9pqjiRMpDLWQ==", - "requires": { - "@babel/runtime": "^7.24.7", - "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.6.9", - "@types/react-transition-group": "^4.4.6", - "classnames": "^2.3.2", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.8.1", - "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.5", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - } - }, - "react-chartjs-2": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", - "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==" - }, - "react-datepicker": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.25.0.tgz", - "integrity": "sha512-zB7CSi44SJ0sqo8hUQ3BF1saE/knn7u25qEMTO1CQGofY1VAKahO8k9drZtp0cfW1DMfoYLR3uSY1/uMvbEzbg==", - "requires": { - "@popperjs/core": "^2.11.8", - "classnames": "^2.2.6", - "date-fns": "^2.30.0", - "prop-types": "^15.7.2", - "react-onclickoutside": "^6.13.0", - "react-popper": "^2.3.0" - } - }, - "react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - } - }, - "react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "react-onclickoutside": { - "version": "6.13.1", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.1.tgz", - "integrity": "sha512-LdrrxK/Yh9zbBQdFbMTXPp3dTSN9B+9YJQucdDu3JNKRrbdU+H+/TVONJoWtOwy4II8Sqf1y/DTI6w/vGPYW0w==" - }, - "react-popper": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", - "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", - "requires": { - "react-fast-compare": "^3.0.1", - "warning": "^4.0.2" - } - }, - "react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - }, - "seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" - }, - "tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" - }, - "uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true - }, - "uncontrollable": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "requires": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" } }, - "underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, - "update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "requires": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "winston": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", - "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", - "requires": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.6.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "winston-daily-rotate-file": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", - "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", - "requires": { - "file-stream-rotator": "^0.6.1", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" } }, - "winston-transport": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", - "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", - "requires": { - "logform": "^2.6.1", - "readable-stream": "^4.5.2", - "triple-beam": "^1.3.0" - }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "dependencies": { - "readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - } - } + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } } } } diff --git a/components/webui/package.json b/components/webui/package.json index 8ba99fc11c..d424326369 100644 --- a/components/webui/package.json +++ b/components/webui/package.json @@ -1,66 +1,22 @@ { "name": "webui", - "private": true, + "version": "0.1.0", + "description": "", "scripts": { - "start": "meteor run", - "build-docs": "jsdoc -r client imports server tests launcher.js -d docs", - "lint": "npm run lint:check", - "lint:check": "npm --prefix linter/ run lint:check", - "lint:fix": "npm --prefix linter/ run lint:fix", - "test": "meteor test --once --driver-package meteortesting:mocha", - "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha", - "visualize": "meteor --production --extra-packages bundle-visualizer" - }, - "dependencies": { - "@babel/core": "^7.24.4", - "@babel/plugin-transform-react-jsx": "^7.23.4", - "@babel/runtime": "^7.24.4", - "@fortawesome/fontawesome-svg-core": "^6.5.1", - "@fortawesome/free-solid-svg-icons": "^6.5.1", - "@fortawesome/react-fontawesome": "^0.2.0", - "@msgpack/msgpack": "^3.0.0-beta2", - "bootstrap": "^5.3.2", - "chart.js": "^4.4.2", - "chartjs-adapter-dayjs-4": "^1.0.4", - "chartjs-plugin-zoom": "^2.0.1", - "dayjs": "^1.11.10", - "json5": "^2.2.3", - "meteor-node-stubs": "^1.2.10", - "mysql2": "^3.10.0", - "react": "^18.2.0", - "react-bootstrap": "^2.10.2", - "react-chartjs-2": "^5.2.0", - "react-datepicker": "^4.25.0", - "react-dom": "^18.2.0", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4", - "uuid": "^9.0.1", - "winston": "^3.11.0", - "winston-daily-rotate-file": "^4.7.1" + "client:lint:check": "cd client && npm run lint:check", + "client:lint:fix": "cd client && npm run lint:fix", + "client:start": "cd client && npm start", + "init": "npm clean-install && (cd client && npm clean-install) && (cd server && npm clean-install)", + "lint:check": "npm run client:lint:check && npm run server:lint:check", + "lint:fix": "npm run client:lint:fix && npm run server:lint:fix", + "server:lint:check": "cd server && npm run lint:check", + "server:lint:fix": "cd server && npm run lint:fix", + "server:start": "cd server && npm start", + "start": "concurrently \"npm run client:start\" \"npm run server:start\"" }, + "author": "YScope Inc. ", + "license": "Apache-2.0", "devDependencies": { - "jsdoc": "^4.0.2" - }, - "eslintConfig": { - "extends": [ - "yscope/meteor" - ] - }, - "meteor": { - "mainModule": { - "client": "client/main.jsx", - "server": "server/main.js" - }, - "testModule": "tests/main.js" - }, - "babel": { - "plugins": [ - [ - "@babel/plugin-transform-react-jsx", - { - "runtime": "automatic" - } - ] - ] + "concurrently": "^8.2.2" } } diff --git a/components/log-viewer-webui/server/.env b/components/webui/server/.env similarity index 100% rename from components/log-viewer-webui/server/.env rename to components/webui/server/.env diff --git a/components/log-viewer-webui/server/.gitignore b/components/webui/server/.gitignore similarity index 100% rename from components/log-viewer-webui/server/.gitignore rename to components/webui/server/.gitignore diff --git a/components/log-viewer-webui/server/eslint.config.mjs b/components/webui/server/eslint.config.mjs similarity index 100% rename from components/log-viewer-webui/server/eslint.config.mjs rename to components/webui/server/eslint.config.mjs diff --git a/components/webui/server/main.js b/components/webui/server/main.js deleted file mode 100644 index 2660e16c13..0000000000 --- a/components/webui/server/main.js +++ /dev/null @@ -1,77 +0,0 @@ -import {Meteor} from "meteor/meteor"; - -import { - deinitDbManagers, - initDbManagers, -} from "/imports/utils/DbManager"; -import {initLogger} from "/imports/utils/logger"; - -import "/imports/api/ingestion/collections"; -import "/imports/api/ingestion/server/publications"; -import "/imports/api/search/server/collections"; -import "/imports/api/search/server/methods"; -import "/imports/api/search/server/publications"; - - -const DEFAULT_LOGS_DIR = "."; -const DEFAULT_LOGGING_LEVEL = Meteor.isDevelopment ? - "DEBUG" : - "INFO"; - -/** - * Parses environment variables into config values for the application. - * - * @return {object} containing config values including the SQL database credentials, - * logs directory, and logging level. - * @throws {Error} if the required environment variables are undefined, it exits the process with an - * error. - */ -const parseEnvVars = () => { - const { - CLP_DB_USER, - CLP_DB_PASS, - } = process.env; - - if ([ - typeof CLP_DB_USER, - typeof CLP_DB_PASS, - ].includes("undefined")) { - console.error("Environment variables CLP_DB_USER and CLP_DB_PASS must be defined"); - process.exit(1); - } - - const WEBUI_LOGS_DIR = process.env.WEBUI_LOGS_DIR || DEFAULT_LOGS_DIR; - const WEBUI_LOGGING_LEVEL = process.env.WEBUI_LOGGING_LEVEL || DEFAULT_LOGGING_LEVEL; - - return { - CLP_DB_USER, - CLP_DB_PASS, - WEBUI_LOGS_DIR, - WEBUI_LOGGING_LEVEL, - }; -}; - -Meteor.startup(async () => { - const envVars = parseEnvVars(); - - initLogger(envVars.WEBUI_LOGS_DIR, envVars.WEBUI_LOGGING_LEVEL, Meteor.isDevelopment); - - await initDbManagers({ - dbHost: Meteor.settings.private.SqlDbHost, - dbPort: Meteor.settings.private.SqlDbPort, - - dbName: Meteor.settings.private.SqlDbName, - dbPassword: envVars.CLP_DB_PASS, - dbUser: envVars.CLP_DB_USER, - }, { - clpArchivesTableName: Meteor.settings.private.SqlDbClpArchivesTableName, - clpFilesTableName: Meteor.settings.private.SqlDbClpFilesTableName, - compressionJobsTableName: Meteor.settings.private.SqlDbCompressionJobsTableName, - queryJobsTableName: Meteor.settings.private.SqlDbQueryJobsTableName, - }); -}); - -process.on("exit", async (code) => { - console.log(`Node.js is about to exit with code: ${code}`); - await deinitDbManagers(); -}); diff --git a/components/log-viewer-webui/server/package-lock.json b/components/webui/server/package-lock.json similarity index 99% rename from components/log-viewer-webui/server/package-lock.json rename to components/webui/server/package-lock.json index 5543eaaf21..9461a27621 100644 --- a/components/log-viewer-webui/server/package-lock.json +++ b/components/webui/server/package-lock.json @@ -1,11 +1,11 @@ { - "name": "log-viewer-webui-server", + "name": "webui-server", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "log-viewer-webui-server", + "name": "webui-server", "version": "0.1.0", "license": "Apache-2.0", "dependencies": { diff --git a/components/log-viewer-webui/server/package.json b/components/webui/server/package.json similarity index 97% rename from components/log-viewer-webui/server/package.json rename to components/webui/server/package.json index a7c26f1e55..a4ac87fac9 100644 --- a/components/log-viewer-webui/server/package.json +++ b/components/webui/server/package.json @@ -1,5 +1,5 @@ { - "name": "log-viewer-webui-server", + "name": "webui-server", "version": "0.1.0", "description": "", "main": "src/main.ts", diff --git a/components/log-viewer-webui/server/settings.json b/components/webui/server/settings.json similarity index 100% rename from components/log-viewer-webui/server/settings.json rename to components/webui/server/settings.json index 4e615a3cf2..5f7f789364 100644 --- a/components/log-viewer-webui/server/settings.json +++ b/components/webui/server/settings.json @@ -7,8 +7,8 @@ "MongoDbHost": "localhost", "MongoDbPort": 27017, "MongoDbName": "clp-query-results", - "MongoDbStreamFilesCollectionName": "stream-files", "MongoDbSearchResultsMetadataCollectionName": "results-metadata", + "MongoDbStreamFilesCollectionName": "stream-files", "ClientDir": "../client/dist", "LogViewerDir": "../yscope-log-viewer/dist", diff --git a/components/log-viewer-webui/server/src/app.ts b/components/webui/server/src/app.ts similarity index 100% rename from components/log-viewer-webui/server/src/app.ts rename to components/webui/server/src/app.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/app.ts b/components/webui/server/src/fastify-v2/app.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/app.ts rename to components/webui/server/src/fastify-v2/app.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/index.ts b/components/webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/index.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/index.ts rename to components/webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/index.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/typings.ts b/components/webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/typings.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/typings.ts rename to components/webui/server/src/fastify-v2/plugins/app/search/QueryJobsDbManager/typings.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/external/env.ts b/components/webui/server/src/fastify-v2/plugins/external/env.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/external/env.ts rename to components/webui/server/src/fastify-v2/plugins/external/env.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/external/mongo.ts b/components/webui/server/src/fastify-v2/plugins/external/mongo.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/external/mongo.ts rename to components/webui/server/src/fastify-v2/plugins/external/mongo.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/external/mysql.ts b/components/webui/server/src/fastify-v2/plugins/external/mysql.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/external/mysql.ts rename to components/webui/server/src/fastify-v2/plugins/external/mysql.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/external/rateLimit.ts b/components/webui/server/src/fastify-v2/plugins/external/rateLimit.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/external/rateLimit.ts rename to components/webui/server/src/fastify-v2/plugins/external/rateLimit.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/plugins/external/sensible.ts b/components/webui/server/src/fastify-v2/plugins/external/sensible.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/plugins/external/sensible.ts rename to components/webui/server/src/fastify-v2/plugins/external/sensible.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/routes/api/search/index.ts b/components/webui/server/src/fastify-v2/routes/api/search/index.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/routes/api/search/index.ts rename to components/webui/server/src/fastify-v2/routes/api/search/index.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/routes/api/search/typings.ts b/components/webui/server/src/fastify-v2/routes/api/search/typings.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/routes/api/search/typings.ts rename to components/webui/server/src/fastify-v2/routes/api/search/typings.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/routes/api/search/utils.ts b/components/webui/server/src/fastify-v2/routes/api/search/utils.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/routes/api/search/utils.ts rename to components/webui/server/src/fastify-v2/routes/api/search/utils.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/schemas/common.ts b/components/webui/server/src/fastify-v2/schemas/common.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/schemas/common.ts rename to components/webui/server/src/fastify-v2/schemas/common.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/schemas/error.ts b/components/webui/server/src/fastify-v2/schemas/error.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/schemas/error.ts rename to components/webui/server/src/fastify-v2/schemas/error.ts diff --git a/components/log-viewer-webui/server/src/fastify-v2/schemas/search.ts b/components/webui/server/src/fastify-v2/schemas/search.ts similarity index 100% rename from components/log-viewer-webui/server/src/fastify-v2/schemas/search.ts rename to components/webui/server/src/fastify-v2/schemas/search.ts diff --git a/components/log-viewer-webui/server/src/main.ts b/components/webui/server/src/main.ts similarity index 100% rename from components/log-viewer-webui/server/src/main.ts rename to components/webui/server/src/main.ts diff --git a/components/log-viewer-webui/server/src/plugins/DbManager.ts b/components/webui/server/src/plugins/DbManager.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/DbManager.ts rename to components/webui/server/src/plugins/DbManager.ts diff --git a/components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/MongoWatcherCollection.ts b/components/webui/server/src/plugins/MongoSocketIoServer/MongoWatcherCollection.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/MongoWatcherCollection.ts rename to components/webui/server/src/plugins/MongoSocketIoServer/MongoWatcherCollection.ts diff --git a/components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/index.ts b/components/webui/server/src/plugins/MongoSocketIoServer/index.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/index.ts rename to components/webui/server/src/plugins/MongoSocketIoServer/index.ts diff --git a/components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/typings.ts b/components/webui/server/src/plugins/MongoSocketIoServer/typings.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/typings.ts rename to components/webui/server/src/plugins/MongoSocketIoServer/typings.ts diff --git a/components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/utils.ts b/components/webui/server/src/plugins/MongoSocketIoServer/utils.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/MongoSocketIoServer/utils.ts rename to components/webui/server/src/plugins/MongoSocketIoServer/utils.ts diff --git a/components/log-viewer-webui/server/src/plugins/S3Manager.ts b/components/webui/server/src/plugins/S3Manager.ts similarity index 100% rename from components/log-viewer-webui/server/src/plugins/S3Manager.ts rename to components/webui/server/src/plugins/S3Manager.ts diff --git a/components/log-viewer-webui/server/src/routes/example.ts b/components/webui/server/src/routes/example.ts similarity index 100% rename from components/log-viewer-webui/server/src/routes/example.ts rename to components/webui/server/src/routes/example.ts diff --git a/components/log-viewer-webui/server/src/routes/query.ts b/components/webui/server/src/routes/query.ts similarity index 100% rename from components/log-viewer-webui/server/src/routes/query.ts rename to components/webui/server/src/routes/query.ts diff --git a/components/log-viewer-webui/server/src/routes/static.ts b/components/webui/server/src/routes/static.ts similarity index 100% rename from components/log-viewer-webui/server/src/routes/static.ts rename to components/webui/server/src/routes/static.ts diff --git a/components/log-viewer-webui/server/src/test/app.test.ts b/components/webui/server/src/test/app.test.ts similarity index 100% rename from components/log-viewer-webui/server/src/test/app.test.ts rename to components/webui/server/src/test/app.test.ts diff --git a/components/log-viewer-webui/server/src/test/tap.ts b/components/webui/server/src/test/tap.ts similarity index 100% rename from components/log-viewer-webui/server/src/test/tap.ts rename to components/webui/server/src/test/tap.ts diff --git a/components/log-viewer-webui/server/src/typings/DbManager.ts b/components/webui/server/src/typings/DbManager.ts similarity index 100% rename from components/log-viewer-webui/server/src/typings/DbManager.ts rename to components/webui/server/src/typings/DbManager.ts diff --git a/components/log-viewer-webui/server/src/typings/common.ts b/components/webui/server/src/typings/common.ts similarity index 100% rename from components/log-viewer-webui/server/src/typings/common.ts rename to components/webui/server/src/typings/common.ts diff --git a/components/log-viewer-webui/server/src/typings/query.ts b/components/webui/server/src/typings/query.ts similarity index 100% rename from components/log-viewer-webui/server/src/typings/query.ts rename to components/webui/server/src/typings/query.ts diff --git a/components/log-viewer-webui/server/src/utils/time.ts b/components/webui/server/src/utils/time.ts similarity index 100% rename from components/log-viewer-webui/server/src/utils/time.ts rename to components/webui/server/src/utils/time.ts diff --git a/components/log-viewer-webui/server/tsconfig.json b/components/webui/server/tsconfig.json similarity index 100% rename from components/log-viewer-webui/server/tsconfig.json rename to components/webui/server/tsconfig.json diff --git a/components/webui/settings.json b/components/webui/settings.json deleted file mode 100644 index f959dac8e9..0000000000 --- a/components/webui/settings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "private": { - "SqlDbHost": "localhost", - "SqlDbPort": 3306, - "SqlDbName": "clp-db", - - "SqlDbClpArchivesTableName": "clp_archives", - "SqlDbClpFilesTableName": "clp_files", - "SqlDbCompressionJobsTableName": "compression_jobs", - "SqlDbQueryJobsTableName": "query_jobs" - }, - "public": { - "AggregationResultsCollectionName": "aggregation-results", - "ClpStorageEngine": "clp", - "CompressionJobsCollectionName": "compression-jobs", - "LogViewerWebuiUrl": "http://localhost:8080", - "SearchResultsCollectionName": "search-results", - "SearchResultsMetadataCollectionName": "results-metadata", - "StatsCollectionName": "stats", - "SupportUrl": "https://github.com/y-scope/clp/issues/new/choose" - } -} diff --git a/components/webui/tests/main.js b/components/webui/tests/main.js deleted file mode 100644 index 9820a417b5..0000000000 --- a/components/webui/tests/main.js +++ /dev/null @@ -1,23 +0,0 @@ -import assert from "assert"; - -import "./misc.js"; - - -describe("webui", () => { - it("package.json has correct name", async () => { - const {name} = await import("../package.json"); - assert.strictEqual(name, "webui"); - }); - - if (Meteor.isClient) { - it("client is not server", () => { - assert.strictEqual(Meteor.isServer, false); - }); - } - - if (Meteor.isServer) { - it("server is not client", () => { - assert.strictEqual(Meteor.isClient, false); - }); - } -}); diff --git a/components/webui/tests/misc.js b/components/webui/tests/misc.js deleted file mode 100644 index 04a1abe8b2..0000000000 --- a/components/webui/tests/misc.js +++ /dev/null @@ -1,42 +0,0 @@ -import assert from "assert"; - -import {unquoteString} from "/imports/utils/misc"; - - -describe("misc", () => { - it("unquoteString", () => { - // Empty string - assert.strictEqual(unquoteString("", '"', "\\"), ""); - - // Unquoted string - assert.strictEqual(unquoteString("abc", '"', "\\"), "abc"); - - // Double-quoted string - assert.strictEqual(unquoteString("\"abc\"", '"', "\\"), "abc"); - - // Single-quoted string - assert.strictEqual(unquoteString("'abc'", "'", "\\"), "abc"); - - // With escaped characters - assert.strictEqual(unquoteString("a\\\\b\\\"c\\*\\?", '"', "\\"), "a\\\\b\"c\\*\\?"); - - // Double-quoted with escaped characters - assert.strictEqual(unquoteString("\"a\\\\b\\\"c\\*\\?\"", '"', "\\"), "a\\\\b\"c\\*\\?"); - - // With one of the quotes missing - assert.throws(() => { - unquoteString("\"abc", '"', "\\"); - }, Error); - assert.throws(() => { - unquoteString("abc\"", '"', "\\"); - }, Error); - - // With an unescaped quote in the middle - assert.throws(() => { - unquoteString("ab\"c", '"', "\\"); - }, Error); - assert.throws(() => { - unquoteString("\"ab\"c\"", '"', "\\"); - }, Error); - }); -}); diff --git a/docs/src/dev-guide/components-log-viewer-webui.md b/docs/src/dev-guide/components-log-viewer-webui.md deleted file mode 100644 index 5496a46120..0000000000 --- a/docs/src/dev-guide/components-log-viewer-webui.md +++ /dev/null @@ -1,98 +0,0 @@ -# Log Viewer WebUI - -A webapp that allows us to serve the [log-viewer] and integrate it with CLP's [webui]. The webapp -currently consists of a [React] client and a [Fastify] server. - -## Requirements - -* Node.js v20 or higher - -## Setup - -Download the log-viewer's source code: - -```bash -task deps:log-viewer -``` - -Install the app's dependencies: - -```shell -cd components/log-viewer-webui -(cd client && npm i) -(cd server && npm i) -``` - -## Running - -To run the client during development: - -```shell -npm run start -``` - -To run the server during development: - -```shell -npm run dev -``` - -To run the server in production: - -```shell -npm run start -``` - -To run the server as a standalone Node.js process: - -```shell -npm run standalone -``` - -If you want to customize what host and port the server binds to, you can use the -environment variables in `components/log-viewer-webui/server/.env`. - -## Testing - -To run the server's unit tests: - -```shell -npm test -``` - -## Linting - -You can lint this component either as part of the entire project or as a standalone component. - -### Lint as part of the project - -To check for linting errors: - -```shell -task lint:check-js -``` - -To also fix linting errors (if applicable): - -```shell -task lint:fix-js -``` - -### Lint the component alone - -To check for linting errors: - -```shell -npm run lint:check -``` - -To also fix linting errors (if applicable): - -```shell -npm run lint:fix -``` - -[Fastify]: https://www.fastify.io/ -[log-viewer]: https://github.com/y-scope/yscope-log-viewer -[React]: https://reactjs.org/ -[webui]: components-webui.md diff --git a/docs/src/dev-guide/components-webui.md b/docs/src/dev-guide/components-webui.md index 9c880b4a1c..a34842b224 100644 --- a/docs/src/dev-guide/components-webui.md +++ b/docs/src/dev-guide/components-webui.md @@ -1,101 +1,67 @@ # WebUI -The web interface for the CLP package. +The web interface for the CLP package, which currently consists of a [React] client and a [Fastify] +server. It also serves the [log-viewer]. ## Requirements -* Node.js v14 for building and running the webui - * Meteor.js only [supports](https://docs.meteor.com/install#prereqs-node) Node.js versions >= v10 - and <= v14. -* Node.js v18 or higher for linting the webui +* Node.js v22 or higher * (Optional) [nvm (Node Version Manager)][nvm] to manage different versions of Node.js -* [Meteor.js](https://docs.meteor.com/install.html#installation) -## Install the dependencies +## Setup -```shell -meteor npm install -``` - -If you ever add a package manually to `package.json` or `package.json` changes -for some other reason, you should rerun this command. - -## Running in development - -The full functionality of the webui depends on other components in the CLP -package: - -1. Build the [CLP package](building-package) -2. Start the package: `/sbin/start-clp.sh` -3. Stop the webui instance started by the package: `/sbin/stop-clp.sh webui` -4. Start the webui using meteor (refer to `/etc/clp-config.yml` for the config values): - ```shell - MONGO_URL="mongodb://:/" \ - ROOT_URL="http://:" \ - CLP_DB_USER="" \ - CLP_DB_PASS="" \ - meteor --port --settings settings.json - ``` - - Here is an example based on the default `clp-config.yml`: - ```shell - # Please update `` accordingly. - - MONGO_URL="mongodb://localhost:27017/clp-query-results" \ - ROOT_URL="http://localhost:4000" \ - CLP_DB_USER="clp-user" \ - CLP_DB_PASS="" \ - meteor --port 4000 --settings settings.json - ``` -5. The Web UI should now be available at `http://:` - (e.g., http://localhost:4000). - -## Linting +1. Download the log-viewer's source code: -We enforce code quality and consistency across our project using [ESLint][eslint]. Due to specific -dependencies, linting this project requires Node.js v18 or higher. We offer two methods for -performing linting; you may choose either one according to your preference. + ```shell + task deps:log-viewer + ``` -### Method 1: Run `Taskfile` tasks +2. Install the app's dependencies: -`Taskfile` tasks are available to automatically manage dependency setup and linting operations. + ```shell + cd components/webui + (cd client && npm i) + (cd server && npm i) + ``` -#### Checking for linting errors + If you add a package manually to `package.json` or `package.json` changes for some other reason, + you should rerun the commands above. -```shell -task lint:check-js -``` +## Running -This will run ESLint on the entire project's source code and report any linting errors. +1. To run the client during development: -#### Automatically fixing linting errors + ```shell + cd components/webui/client + npm run start + ``` -```shell -task lint:fix-js -``` +2. To run the server during development: -This command attempts to automatically fix any linting issues found in the project. + ```shell + cd components/webui/server + npm run dev + ``` -### Method 2: IDE Integration + If you want to customize what host and port the server binds to, you can copy `.env` to + `.env.local` and modify the values there. The `.env.local` file will override settings in + `.env`. -To integrate ESLint into IDEs like WebStorm and VSCode, follow these steps: +## Linting -1. Switch to Node.js v18 or higher - ```shell - # Install the latest node if not already installed - nvm install node +To check for linting errors: - # Switch to the latest node - nvm use node - ``` +```shell +task lint:check-js +``` -2. Install the latest ESLint shared config package. - * We use `--package-lock=false` and `--no-save` to avoid adding the package to - `package-lock.json` and `package.json`. +To also fix linting errors (if applicable): - ```shell - npm --package-lock=false install --no-save eslint-config-yscope@latest - ``` +```shell +task lint:fix-js +``` -[eslint]: https://eslint.org/ +[Fastify]: https://www.fastify.io/ +[log-viewer]: https://github.com/y-scope/yscope-log-viewer [nvm]: https://github.com/nvm-sh/nvm +[React]: https://reactjs.org/ diff --git a/docs/src/dev-guide/index.md b/docs/src/dev-guide/index.md index 841a7cf4b4..ae892e5707 100644 --- a/docs/src/dev-guide/index.md +++ b/docs/src/dev-guide/index.md @@ -63,7 +63,6 @@ contributing-linting :hidden: components-core/index -components-log-viewer-webui components-webui ::: diff --git a/taskfile.yaml b/taskfile.yaml index b7012bfdb9..82d04f456f 100644 --- a/taskfile.yaml +++ b/taskfile.yaml @@ -14,15 +14,11 @@ vars: G_COMPONENTS_DIR: "{{.ROOT_DIR}}/components" G_CORE_COMPONENT_DIR: "{{.G_COMPONENTS_DIR}}/core" G_CORE_COMPONENT_SUBMODULES_DIR: "{{.G_CORE_COMPONENT_DIR}}/submodules" - G_LOG_VIEWER_WEBUI_SRC_DIR: "{{.G_COMPONENTS_DIR}}/log-viewer-webui" + G_WEBUI_SRC_DIR: "{{.G_COMPONENTS_DIR}}/webui" # Build paths G_BUILD_DIR: "{{.ROOT_DIR}}/build" G_CORE_COMPONENT_BUILD_DIR: "{{.G_BUILD_DIR}}/core" - G_LOG_VIEWER_WEBUI_BUILD_DIR: "{{.G_BUILD_DIR}}/log-viewer-webui" - G_METEOR_BUILD_DIR: "{{.G_BUILD_DIR}}/meteor" - G_NODEJS_14_BUILD_DIR: "{{.G_BUILD_DIR}}/nodejs-14" - G_NODEJS_14_BIN_DIR: "{{.G_NODEJS_14_BUILD_DIR}}/bin" G_NODEJS_22_BUILD_DIR: "{{.G_BUILD_DIR}}/nodejs-22" G_NODEJS_22_BIN_DIR: "{{.G_NODEJS_22_BUILD_DIR}}/bin" G_PACKAGE_BUILD_DIR: "{{.G_BUILD_DIR}}/clp-package" @@ -40,6 +36,13 @@ vars: G_CORE_MAX_PARALLELISM_PER_BUILD_TASK: >- {{default "" (env "CLP_CORE_MAX_PARALLELISM_PER_BUILD_TASK")}} + # Checksum files + G_WEBUI_CLIENT_NODE_MODULES_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/webui-client-node-modules.md5" + G_WEBUI_LOG_VIEWER_NODE_MODULES_CHECKSUM_FILE: + "{{.G_BUILD_DIR}}/webui-log-viewer-node-modules.md5" + G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/webui-package-node-modules.md5" + G_WEBUI_SERVER_NODE_MODULES_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/webui-server-node-modules.md5" + tasks: default: deps: ["package"] @@ -47,7 +50,6 @@ tasks: clean: cmds: - "rm -rf '{{.G_BUILD_DIR}}'" - - task: "clean-log-viewer-webui" - task: "clean-python-component" vars: COMPONENT: "clp-package-utils" @@ -65,18 +67,6 @@ tasks: vars: BUILD_DIR: "{{.G_CORE_COMPONENT_BUILD_DIR}}" - clean-log-viewer-webui: - cmds: - - "rm -rf 'components/log-viewer-webui/client/node_modules'" - - "rm -rf 'components/log-viewer-webui/node_modules'" - - "rm -rf 'components/log-viewer-webui/server/node_modules'" - - "rm -rf 'components/log-viewer-webui/yscope-log-viewer/node_modules'" - - clean-webui: - cmds: - - "rm -rf 'components/webui/.meteor/local'" - - "rm -rf 'components/webui/node_modules'" - clp-json-pkg-tar: cmds: - task: "package-tar" @@ -91,6 +81,13 @@ tasks: FLAVOUR: "text" STORAGE_ENGINE: "clp" + clean-webui: + cmds: + - "rm -rf '{{.G_WEBUI_SRC_DIR}}/client/node_modules'" + - "rm -rf '{{.G_WEBUI_SRC_DIR}}/node_modules'" + - "rm -rf '{{.G_WEBUI_SRC_DIR}}/server/node_modules'" + - "rm -rf '{{.G_WEBUI_SRC_DIR}}/yscope-log-viewer/node_modules'" + package: env: NODE_ENV: "production" @@ -98,10 +95,8 @@ tasks: CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" OUTPUT_DIR: "{{.G_PACKAGE_BUILD_DIR}}" sources: - - "{{.G_BUILD_DIR}}/log-viewer-webui.md5" - "{{.G_BUILD_DIR}}/package-venv.md5" - "{{.G_BUILD_DIR}}/webui.md5" - - "{{.G_BUILD_DIR}}/webui-nodejs.md5" - "{{.G_CORE_COMPONENT_BUILD_DIR}}/clg" - "{{.G_CORE_COMPONENT_BUILD_DIR}}/clo" - "{{.G_CORE_COMPONENT_BUILD_DIR}}/clp" @@ -121,8 +116,6 @@ tasks: - "clp-py-utils" - "init" - "job-orchestration" - - "log-viewer-webui" - - "nodejs-14" - "package-venv" - task: "utils:checksum:validate" vars: @@ -151,10 +144,6 @@ tasks: "{{.G_CORE_COMPONENT_BUILD_DIR}}/indexer" "{{.G_CORE_COMPONENT_BUILD_DIR}}/reducer-server" "{{.OUTPUT_DIR}}/bin/" - - >- - rsync -a - "{{.G_NODEJS_14_BIN_DIR}}/node" - "{{.OUTPUT_DIR}}/bin/node-14" - >- rsync -a "{{.G_NODEJS_22_BIN_DIR}}/node" @@ -163,18 +152,9 @@ tasks: - >- rsync -a "{{.G_WEBUI_BUILD_DIR}}/" - "{{.OUTPUT_DIR}}/var/www/webui/" - # Avoid using `npm clean-install` because Meteor does not generate a `package-lock.json` file, - # which `clean-install` depends on. - - |- - cd "{{.OUTPUT_DIR}}/var/www/webui/programs/server" - PATH="{{.G_NODEJS_14_BIN_DIR}}":$PATH npm install - - >- - rsync -a - "{{.G_LOG_VIEWER_WEBUI_BUILD_DIR}}/" - "{{.OUTPUT_DIR}}/var/www/log-viewer-webui" + "{{.OUTPUT_DIR}}/var/www/webui" - |- - cd "{{.OUTPUT_DIR}}/var/www/log-viewer-webui/server" + cd "{{.OUTPUT_DIR}}/var/www/webui/server" PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm clean-install # This command must be last - task: "utils:checksum:compute" @@ -278,41 +258,28 @@ tasks: vars: COMPONENT: "{{.TASK}}" - log-viewer-webui: + webui: vars: CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - OUTPUT_DIR: "{{.G_LOG_VIEWER_WEBUI_BUILD_DIR}}" + OUTPUT_DIR: "{{.G_WEBUI_BUILD_DIR}}" sources: - - "{{.G_BUILD_DIR}}/log-viewer-webui-node-modules.md5" + - "{{.G_WEBUI_CLIENT_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_LOG_VIEWER_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_SERVER_NODE_MODULES_CHECKSUM_FILE}}" - "{{.TASKFILE}}" - - "client/index.html" - - "client/tsconfig/**/*" - - "client/tsconfig.json" - - "client/package.json" - - "client/package-lock.json" - - "client/src/**/*.css" - - "client/src/**/*.ts" - - "client/src/**/*.tsx" - - "server/package.json" - - "server/package-lock.json" - - "server/settings.json" - - "server/src/**/*.ts" - - "server/tsconfig.json" - - "yscope-log-viewer/package.json" - - "yscope-log-viewer/public/**/*" - - "yscope-log-viewer/src/**/*" - - "yscope-log-viewer/tsconfig.json" - - "yscope-log-viewer/webpack.common.js" - - "yscope-log-viewer/webpack.prod.js" - dir: "components/log-viewer-webui" + - "**/*" + - exclude: "**/dist/**/*" + - exclude: "**/node_modules/**/*" + dir: "{{.G_WEBUI_SRC_DIR}}" generates: ["{{.CHECKSUM_FILE}}"] deps: - "init" - - "log-viewer-webui-node-modules" - task: "utils:checksum:validate" vars: CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] + - "webui-node-modules" cmds: - "rm -rf '{{.OUTPUT_DIR}}'" - "mkdir -p '{{.OUTPUT_DIR}}'" @@ -335,50 +302,6 @@ tasks: CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - webui: - vars: - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - OUTPUT_DIR: "{{.G_WEBUI_BUILD_DIR}}" - sources: - - "{{.G_BUILD_DIR}}/meteor.md5" - - "{{.G_BUILD_DIR}}/webui-node-modules.md5" - - "{{.TASKFILE}}" - - "*" - - ".meteor/*" - - "client/**/*" - - "imports/**/*" - - "server/**/*" - - "tests/**/*" - dir: "components/webui" - platforms: ["386", "amd64"] - generates: ["{{.CHECKSUM_FILE}}"] - deps: - - "init" - - "meteor" - - task: "utils:checksum:validate" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - - "webui-node-modules" - cmds: - - "rm -rf '{{.OUTPUT_DIR}}'" - - "mkdir -p '{{.OUTPUT_DIR}}'" - - "PATH='{{.G_METEOR_BUILD_DIR}}':$PATH meteor build --directory '{{.OUTPUT_DIR}}'" - - >- - rsync -a - "{{.OUTPUT_DIR}}/bundle/" - launcher.js - settings.json - "{{.OUTPUT_DIR}}/" - - "rm -rf '{{.OUTPUT_DIR}}/bundle/'" - # Remove temp files generated by `meteor build` before checksum - - "find node_modules -type f -name '.meteor-portable-2.json' -exec rm {} +" - # This command must be last - - task: "utils:checksum:compute" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - nodejs-22: internal: true vars: @@ -392,18 +315,6 @@ tasks: NODEJS_VERSION: "v22.4.0" OUTPUT_DIR: "{{.OUTPUT_DIR}}" - nodejs-14: - internal: true - vars: - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - OUTPUT_DIR: "{{.G_NODEJS_14_BUILD_DIR}}" - cmds: - - task: "nodejs" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - NODEJS_VERSION: "v14.21.3" - OUTPUT_DIR: "{{.OUTPUT_DIR}}" - download-and-extract-tar: internal: true label: "{{.TASK}}-{{.TAR_NAME}}" @@ -437,25 +348,16 @@ tasks: CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - # NOTE: The log-viewer-webui has four different node_modules directories: + # NOTE: The webui has four different node_modules directories, and we generate a checksum file for + # each one. The directories are: # * client # * server # * log-viewer submodule # * the top-level one we call "package" - # This means we have to create four different checksums. To allow tasks which depend on this task - # to only have to check one checksum file, we concatenate the four checksum files into one. - log-viewer-webui-node-modules: + webui-node-modules: internal: true vars: - # Checksum files - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - CLIENT_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/log-viewer-webui-client-node-modules.md5" - LOG_VIEWER_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/log-viewer-webui-log-viewer-node-modules.md5" - PACKAGE_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/log-viewer-webui-package-node-modules.md5" - SERVER_CHECKSUM_FILE: "{{.G_BUILD_DIR}}/log-viewer-webui-server-node-modules.md5" - - # Directories - SRC_DIR: "{{.TASKFILE_DIR}}/components/log-viewer-webui" + SRC_DIR: "{{.TASKFILE_DIR}}/components/webui" CLIENT_OUTPUT_DIR: "{{.SRC_DIR}}/client/node_modules" LOG_VIEWER_OUTPUT_DIR: "{{.SRC_DIR}}/yscope-log-viewer/node_modules" PACKAGE_OUTPUT_DIR: "{{.SRC_DIR}}/node_modules" @@ -474,82 +376,56 @@ tasks: - "yscope-log-viewer/package-lock.json" dir: "{{.SRC_DIR}}" generates: - - "{{.CHECKSUM_FILE}}" - - "{{.CLIENT_CHECKSUM_FILE}}" - - "{{.LOG_VIEWER_CHECKSUM_FILE}}" - - "{{.PACKAGE_CHECKSUM_FILE}}" - - "{{.SERVER_CHECKSUM_FILE}}" + - "{{.G_WEBUI_CLIENT_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_LOG_VIEWER_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE}}" + - "{{.G_WEBUI_SERVER_NODE_MODULES_CHECKSUM_FILE}}" deps: - "deps:log-viewer" - "nodejs-22" - task: "utils:checksum:validate" vars: - CHECKSUM_FILE: "{{.CLIENT_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_CLIENT_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.CLIENT_OUTPUT_DIR}}"] + EXCLUDE_PATTERNS: &webui_node_modules_checksum_exclude_patterns + - ".tmp" + - ".vite-temp" - task: "utils:checksum:validate" vars: - CHECKSUM_FILE: "{{.SERVER_CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.SERVER_OUTPUT_DIR}}"] + CHECKSUM_FILE: "{{.G_WEBUI_LOG_VIEWER_NODE_MODULES_CHECKSUM_FILE}}" + INCLUDE_PATTERNS: ["{{.LOG_VIEWER_OUTPUT_DIR}}"] - task: "utils:checksum:validate" vars: - CHECKSUM_FILE: "{{.PACKAGE_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.PACKAGE_OUTPUT_DIR}}"] - task: "utils:checksum:validate" vars: - CHECKSUM_FILE: "{{.LOG_VIEWER_CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.LOG_VIEWER_OUTPUT_DIR}}"] + CHECKSUM_FILE: "{{.G_WEBUI_SERVER_NODE_MODULES_CHECKSUM_FILE}}" + INCLUDE_PATTERNS: ["{{.SERVER_OUTPUT_DIR}}"] cmds: - - "rm -f {{.CHECKSUM_FILE}}" - - task: "clean-log-viewer-webui" + - task: "clean-webui" - "PATH='{{.G_NODEJS_22_BIN_DIR}}':$PATH npm run init" - |- cd yscope-log-viewer - PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm install + PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm clean-install # These commands must be last - task: "utils:checksum:compute" vars: - CHECKSUM_FILE: "{{.CLIENT_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_CLIENT_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.CLIENT_OUTPUT_DIR}}"] + EXCLUDE_PATTERNS: *webui_node_modules_checksum_exclude_patterns - task: "utils:checksum:compute" vars: - CHECKSUM_FILE: "{{.LOG_VIEWER_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_LOG_VIEWER_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.LOG_VIEWER_OUTPUT_DIR}}"] - task: "utils:checksum:compute" vars: - CHECKSUM_FILE: "{{.PACKAGE_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.PACKAGE_OUTPUT_DIR}}"] - task: "utils:checksum:compute" vars: - CHECKSUM_FILE: "{{.SERVER_CHECKSUM_FILE}}" + CHECKSUM_FILE: "{{.G_WEBUI_SERVER_NODE_MODULES_CHECKSUM_FILE}}" INCLUDE_PATTERNS: ["{{.SERVER_OUTPUT_DIR}}"] - # This command must be last - - >- - cat - "{{.CLIENT_CHECKSUM_FILE}}" - "{{.LOG_VIEWER_CHECKSUM_FILE}}" - "{{.PACKAGE_CHECKSUM_FILE}}" - "{{.SERVER_CHECKSUM_FILE}}" - > "{{.CHECKSUM_FILE}}" - - meteor: - vars: - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - METEOR_ARCH: "{{ if eq ARCH \"arm64\" }}arm64{{ else }}x86_64{{ end }}" - METEOR_PLATFORM: "{{ if eq OS \"darwin\" }}osx{{ else }}linux{{ end }}" - METEOR_RELEASE: "2.16" - run: "once" - preconditions: - - sh: >- - (test "$(uname -m)" != "aarch64") || (test "$(uname -s)" != "Linux") - msg: "Meteor 2.x does not support aarch64 on Linux" - cmds: - - task: "download-and-extract-tar" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - EXTRACTED_DIR_NAME: ".meteor" - OUTPUT_DIR: "{{.G_METEOR_BUILD_DIR}}" - TAR_NAME: "meteor-bootstrap-os.{{.METEOR_PLATFORM}}.{{.METEOR_ARCH}}.tar.gz" - URL_PREFIX: "https://static.meteor.com/packages-bootstrap/{{.METEOR_RELEASE}}" nodejs: internal: true @@ -673,35 +549,6 @@ tasks: . "{{.VENV_DIR}}/bin/activate" poetry build --format wheel - webui-node-modules: - internal: true - vars: - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5" - WEBUI_SRC_DIR: "{{.ROOT_DIR}}/components/webui" - OUTPUT_DIR: "{{.WEBUI_SRC_DIR}}/node_modules" - sources: - - "{{.G_BUILD_DIR}}/meteor.md5" - - "{{.TASKFILE}}" - - ".meteor/packages" - - "package.json" - dir: "{{.WEBUI_SRC_DIR}}" - generates: ["{{.CHECKSUM_FILE}}"] - deps: - - "init" - - "meteor" - - task: "utils:checksum:validate" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - cmds: - - "rm -rf '{{.OUTPUT_DIR}}'" - - "PATH='{{.G_METEOR_BUILD_DIR}}':$PATH meteor npm install --production" - # This command must be last - - task: "utils:checksum:compute" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - component-venv: internal: true label: "{{.COMPONENT}}-venv" diff --git a/taskfiles/deps/main.yaml b/taskfiles/deps/main.yaml index 16f999df94..fa36ea1566 100644 --- a/taskfiles/deps/main.yaml +++ b/taskfiles/deps/main.yaml @@ -51,7 +51,7 @@ tasks: vars: CHECKSUM_FILE: "{{.G_DEPS_LOG_VIEWER_CHECKSUM_FILE}}" FILE_SHA256: "de0600b505545f1bceb7ff5725941035f7c1dc875d08249d9b6d679e3ba77f26" - OUTPUT_DIR: "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/yscope-log-viewer" + OUTPUT_DIR: "{{.G_WEBUI_SRC_DIR}}/yscope-log-viewer" TAR_FILE: "{{.G_BUILD_DIR}}/yscope-log-viewer.tar.gz" URL: "https://github.com/y-scope/yscope-log-viewer/archive/969ff35.tar.gz" diff --git a/taskfiles/lint.yaml b/taskfiles/lint.yaml index b07c4cad31..149a1ba5f8 100644 --- a/taskfiles/lint.yaml +++ b/taskfiles/lint.yaml @@ -6,7 +6,6 @@ vars: {\"name\":\"cpp11_zone.hpp\",\"lines\":[[197,197]]} G_LINT_CLANG_TIDY_DIR: "{{.G_BUILD_DIR}}/lint-clang-tidy" G_LINT_VENV_DIR: "{{.G_BUILD_DIR}}/lint-venv" - G_WEBUI_SRC_DIR: "{{.ROOT_DIR}}/components/webui" tasks: check: @@ -57,26 +56,9 @@ tasks: check-js: sources: &js_source_files - - "{{.G_BUILD_DIR}}/lint#linter-node-modules.md5" - - "{{.G_BUILD_DIR}}/log-viewer-webui-node-modules.md5" - "{{.G_BUILD_DIR}}/webui-node-modules.md5" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/client/package.json" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/client/src/**/*.css" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/client/src/**/*.jsx" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/client/src/webpack.config.js" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/package.json" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/settings.json" - - "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/src/**/*.js" - - "{{.G_WEBUI_SRC_DIR}}/client/**/*.js" - - "{{.G_WEBUI_SRC_DIR}}/client/**/*.jsx" - - "{{.G_WEBUI_SRC_DIR}}/imports/**/*.js" - - "{{.G_WEBUI_SRC_DIR}}/imports/**/*.jsx" - - "{{.G_WEBUI_SRC_DIR}}/launcher.js" - - "{{.G_WEBUI_SRC_DIR}}/package.json" - - "{{.G_WEBUI_SRC_DIR}}/server/**/*.js" - - "{{.G_WEBUI_SRC_DIR}}/server/**/*.jsx" - - "{{.G_WEBUI_SRC_DIR}}/tests/**/*.js" - - "{{.G_WEBUI_SRC_DIR}}/tests/**/*.jsx" + - "{{.G_WEBUI_SRC_DIR}}/**/*" + - exclude: "{{.G_WEBUI_SRC_DIR}}/**/dist/*" - "{{.ROOT_DIR}}/taskfile.yaml" - "{{.TASKFILE}}" cmds: @@ -775,14 +757,11 @@ tasks: internal: true requires: vars: ["LINT_CMD"] - deps: [":log-viewer-webui-node-modules", "linter-node-modules"] + deps: [":webui-node-modules"] cmds: - - for: - - "components/log-viewer-webui" - - "components/webui" - cmd: |- - cd "{{.ITEM}}" - PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm run "lint:{{.LINT_CMD}}" + - |- + cd "{{.G_WEBUI_SRC_DIR}}" + PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm run "lint:{{.LINT_CMD}}" py: internal: true @@ -803,38 +782,6 @@ tasks: black --color --line-length 100 {{.BLACK_FLAGS}} . ruff check {{.RUFF_FLAGS}} . - linter-node-modules: - internal: true - vars: - WEBUI_LINTER_DIR: "{{.ROOT_DIR}}/components/webui/linter" - OUTPUT_DIR: "{{.WEBUI_LINTER_DIR}}/node_modules" - CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK | replace \":\" \"#\"}}.md5" - sources: - - "{{.G_BUILD_DIR}}/nodejs-22.md5" - - "{{.G_BUILD_DIR}}/webui-node-modules.md5" - - "{{.ROOT_DIR}}/taskfile.yaml" - - "{{.TASKFILE}}" - - "package.json" - - "package-lock.json" - dir: "{{.WEBUI_LINTER_DIR}}" - generates: ["{{.CHECKSUM_FILE}}"] - deps: - - ":init" - - ":webui-node-modules" - - task: ":utils:checksum:validate" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - - ":nodejs-22" - cmds: - - "rm -rf '{{.OUTPUT_DIR}}'" - - "PATH='{{.G_NODEJS_22_BIN_DIR}}':$PATH npm clean-install" - # This command must be last - - task: ":utils:checksum:compute" - vars: - CHECKSUM_FILE: "{{.CHECKSUM_FILE}}" - INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"] - venv: internal: true vars: