diff --git a/.husky/pre-commit b/.husky/pre-commit index 514e42af..b485d7f4 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,3 +1,4 @@ +npm run generate-doc && git add packages/*/*/generatedDoc.ts npm --prefix packages/diracx-web-components run lint-staged npm --prefix packages/diracx-web run lint-staged npm --prefix packages/extensions run lint-staged diff --git a/.prettierignore b/.prettierignore index a7a8580a..55a0eb66 100644 --- a/.prettierignore +++ b/.prettierignore @@ -19,6 +19,7 @@ packages/*/tsup.config.ts packages/*/.next packages/*/.tsup packages/*/out +packages/*/src/generatedDoc.ts **/release-please-config.json **/.release-please-manifest.json diff --git a/docs/developer/create_application.md b/docs/developer/create_application.md index 52b552b6..2f65f811 100644 --- a/docs/developer/create_application.md +++ b/docs/developer/create_application.md @@ -22,4 +22,6 @@ The code of your app should be in `packages/diracx-web-components/src/components In order to be compatible with the share and import buttons, the application must write its state to the session storage at `_State`. This slot is read from and written to by the corresponding functions. +You can create documentation for your new application. If you create documentation for the users (in `docs/user/`), you should follow the structure: each folder represents an application, and each file explains a section of that application. This folder is used to automatically build the documentation that will be available in the web application. + 💡You can look at `JobMonitor` as an example. \ No newline at end of file diff --git a/docs/developer/index.md b/docs/developer/index.md index c6223efa..633e6f11 100644 --- a/docs/developer/index.md +++ b/docs/developer/index.md @@ -38,14 +38,14 @@ flowchart TD This repository is organized as a monorepo, with the following key packages: -- [**DiracX-Web-Components**](packages/diracx-web-components): A library of reusable React components designed for integration within the `DiracX-Web` package and to facilitate the creation of custom DiracX web extensions. +- [**DiracX-Web-Components**](../../packages/diracx-web-components): A library of reusable React components designed for integration within the `DiracX-Web` package and to facilitate the creation of custom DiracX web extensions. -- [**DiracX-Web**](packages/diracx-web): Vanilla Dirac web interface based on Next.js. Leverages components from `DiracX-Web-Components` to provide core functionalities. +- [**DiracX-Web**](../../packages/diracx-web): Vanilla Dirac web interface based on Next.js. Leverages components from `DiracX-Web-Components` to provide core functionalities. -- [**Extensions**](packages/extensions): An illustrative example of a web extension, also based on Next.js, demonstrating how to extend the functionality of `DiracX-Web` using the components from the `DiracX-Web-Components` package. +- [**Extensions**](../../packages/extensions): An illustrative example of a web extension, also based on Next.js, demonstrating how to extend the functionality of `DiracX-Web` using the components from the `DiracX-Web-Components` package. -The monorepo structure is based on *npm workspaces* to ensure that related packages ([DiracX-Web-Components](packages/diracx-web-components)) are automatically used from their local versions instead of fetching them from the npm registry. +The monorepo structure is based on *npm workspaces* to ensure that related packages ([DiracX-Web-Components](../../packages/diracx-web-components)) are automatically used from their local versions instead of fetching them from the npm registry. ## Ramping up diff --git a/docs/developer/manage_extension.md b/docs/developer/manage_extension.md index be82b526..0546474f 100644 --- a/docs/developer/manage_extension.md +++ b/docs/developer/manage_extension.md @@ -89,4 +89,4 @@ Follow the instructions from the [Gubbins extension README](https://github.com/D ## Creating a new extension -More details available in the [**extensions** README](/packages/extensions/README.md) \ No newline at end of file +More details available in the [**extensions** README](../../packages/extensions/README.md) \ No newline at end of file diff --git a/docs/user/list_and_share_applications.md b/docs/user/Dashboard/list_and_share_applications.md similarity index 76% rename from docs/user/list_and_share_applications.md rename to docs/user/Dashboard/list_and_share_applications.md index 4dd03d8a..8b7af8c9 100644 --- a/docs/user/list_and_share_applications.md +++ b/docs/user/Dashboard/list_and_share_applications.md @@ -25,6 +25,7 @@ By default, a few application instances are displayed (e.g., `My Jobs`, an insta 2. Select **Rename**. - :bulb: The instance name will change to an input field. 3. Enter a new name and press **Enter** to save it. + - :bulb: You can't use the same name for several intances ### Moving an Application Instance @@ -42,13 +43,16 @@ By default, a few application instances are displayed (e.g., `My Jobs`, an insta ### Sharing Your Dashboard -1. Copy the URL from your browser. - - :bulb: The URL encodes the current state of your dashboard. -2. Share it with others. - - :warning: The recipient will see a similar dashboard layout but may not see identical content if: - - They belong to a different VO or group. - - Time-sensitive data has changed since sharing. - - :warning: Encoding too many application instances may create discrepancies as the URL has a theoretical limit of 8000 characters based on [RFC9110](https://www.rfc-editor.org/rfc/rfc9110#section-4.1-5) +1. Click on the **Export** button at the top-right corner of the page. +2. Select the instances you want to share. + - :bulb: You can select a group to select all instances within that group. + - :bulb: For each instance, the shared content will include the name you gave it and the settings you configured. +3. Click on **Export N Selected**. + - :bulb: A menu will appear with a text box containing the exported JSON. +4. Click on the **Copy to Clipboard** button. +5. Send this text to the person you want to share it with. + - :bulb: If you're using **Mattermost**, you can wrap the text with triple backticks (```) to display it nicely. + ## Advanced Features @@ -91,11 +95,4 @@ When managing multiple instances of the same application, grouping can help you 2. Select **Delete**. - :bulb: The group and all its application instances will disappear from the sidebar. - -### Share and import the settings of an application - -1. **Share**: You can export the status of an app by clicking on the share button in the top-right corner of the screen. After clicking, you can select which group and app you want to share and then copy a text corresponding to the states of the selected applications. - -2. **Import**: Next to the export button you can find the import button. You can paste into the window opened by the button the text corresponding to one or multiple shared apps. This will create a new group named *Imported App* with the imported applications and their settings. - **Good to know:** When switching to a new version, the settings you are trying to import may no longer be valid. In this case, a new window will appear, offering to resolve the issue by updating the state copied to your clipboard. This updated version preserves your imported rules as much as possible. diff --git a/docs/user/login_out.md b/docs/user/Dashboard/login_out.md similarity index 100% rename from docs/user/login_out.md rename to docs/user/Dashboard/login_out.md diff --git a/docs/user/Job_Monitor/manage_job.md b/docs/user/Job_Monitor/manage_job.md new file mode 100644 index 00000000..145a4b81 --- /dev/null +++ b/docs/user/Job_Monitor/manage_job.md @@ -0,0 +1,19 @@ +# Manage Your Jobs + +## Status transitions + +You can select one or more jobs by clicking on the checkboxes next to each job. Once jobs are selected, you can perform actions on them using the buttons at the top of the table. The available actions include: + +- **Reschedule**: Reschedules the selected jobs. +- **Kill**: Marks the selected jobs to be killed. +- **Delete**: Marks the selected jobs for deletion. + +**Note**: +- You can only delete jobs that are already killed. +- A job cannot typically be rescheduled more than three times. + +## View a Job's History + +You can right-click on a job to open its **Job History**. +The history shows the different statuses the job has gone through, along with the corresponding dates and the authors of the changes. + diff --git a/docs/user/Job_Monitor/use_searchbar.md b/docs/user/Job_Monitor/use_searchbar.md new file mode 100644 index 00000000..188b44e5 --- /dev/null +++ b/docs/user/Job_Monitor/use_searchbar.md @@ -0,0 +1,19 @@ +# The Search Bar + +The search bar allows you to filter jobs based on various criteria. Filters are represented as equations, where each equation consists of a job attribute, an operator, and a value. The search bar analyzes these equations to evaluate their consistency. A green equation is valid, a yellow equation is incomplete, and a red equation is invalid. + +A search is automatically performed when all equations in the search bar are valid. + +## Create a Filter + +To create a filter, click on the search bar and start typing. Suggestions will appear based on the available job attributes. You can select a suggestion to choose the criterion. After that, you can either type or select an operator and a value to filter by. +The search bar only suggests attributes, operators, and values that are available in your current set of jobs. + +## Edit a Filter + +To edit a filter, click on it in the search bar. You can change the operator or value by clicking on them. You can also use the arrow keys to navigate through the equations and edit them. Press `ESCAPE` to return to the end of the search bar. + +## Remove a Filter + +To remove a filter, press the `Backspace` key to remove the last token, or right-click on the equation to remove the entire equation. +You can also clear the entire search bar by clicking on the trash can button at the end of the search bar. diff --git a/docs/user/Job_Monitor/use_table.md b/docs/user/Job_Monitor/use_table.md new file mode 100644 index 00000000..24284298 --- /dev/null +++ b/docs/user/Job_Monitor/use_table.md @@ -0,0 +1,15 @@ +# The Table + +The table displays the jobs that match the criteria specified in the search bar. Each row represents a job, and the columns show various attributes of the job, such as its ID, status, type, and submission date. + +## Table display settings +You can click on the eye icon to select additional columns to display in the table. Some columns are hidden by default. + +You can sort the table by clicking on the column headers. Clicking once will sort the table in ascending order; clicking again will sort it in descending order. + +You can set the page size by using the `Rows per page` dropdown at the bottom of the table. This allows you to control how many jobs are displayed per page. + +## Select a Job + +You can select one or multiple jobs using the checkboxes on the left side of the table. +Once you have selected at least one job, you can perform actions on it. You can manage the selected jobs or copy their IDs to your clipboard. diff --git a/docs/user/generalUsage.md b/docs/user/generalUsage.md new file mode 100644 index 00000000..55762518 --- /dev/null +++ b/docs/user/generalUsage.md @@ -0,0 +1,24 @@ +# General Usage + +## Navigate Between Applications + +You can click on the `Add application` button to create a new instance of an application. +The list of open instances appears in the sidebar on the left. Clicking on one of these instances will display it in the center of the dashboard. + +## Share Applications + +To share applications, click the `Export` button at the top right of the screen. +Then, select the applications you want to share and copy them to the clipboard. + +## Import Applications + +To import applications, click the `Import` button at the top right of the screen. +Paste the copied applications into the input field and click `Import`. The imported applications will appear in the sidebar. +If the states are outdated, you can copy the updated version of them by clicking the `Copy all updated states` button. + +## Save Your Dashboard + +To save your dashboard, click the `Export` button at the top right of the screen. +Then, select the applications you want to save and click the `Save in the browser` button. The saved applications will be stored in your browser's local storage. +When you want to load the saved applications, click the `Import` button at the top right of the screen and select the `Load from the browser` option. +The saved applications will be loaded into the sidebar. diff --git a/docs/user/monitor_jobs.md b/docs/user/monitor_jobs.md deleted file mode 100644 index 95fc67c4..00000000 --- a/docs/user/monitor_jobs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Job Monitor documentation - -## The search bar - - The search bar allows you to filter jobs based on various criteria. The filters are represented as equations in the search bar, where each equation consists of a job attribute, an operator, and a value. - A resarch is automatically performed when all the equations in the search bar are valid. - - ### Create a filter - To create a filter, click on the search bar and start typing. Suggestions will appear based on the available job attributes. You can select a suggestion to choose the criterion. After that, you can either type or select an operator and a value to filter by. - The search bar only suggests attributes, operators, and values that are available in your current set of jobs. - - ### Edit a filter - To edit a filter, click on the filter in the search bar. You can change the operator or value by clicking on them. You can also use the arrow keys to navigate through the equations and edit them. - - ### Remove a filter - To remove a filter, you can either press the `Backspace` key to remove the last token or right-click on the equation to remove the entire equation. - - -## Use the table -The table displays the jobs that match the criteria specified in the search bar. Each row represents a job, and the columns show various attributes of the job, such as its ID, status, type, and submission date. - -### Actions on the table -You can click on the eye icon to select more columns to display in the table. -You can sort the table by clicking on the column headers. Clicking on a column header will sort the table in ascending order, and clicking again will sort it in descending order. -You can set the page size by clicking on the `Row per page` dropdown at the bottom of the table. This allows you to control how many jobs are displayed per page. - -### Actions on a job -You can do a right-click on a job to open the `Job History`. -You can select one or more jobs by clicking on the checkboxes next to each job. Once you have selected jobs, you can perform actions on them using the buttons at the top of the table. The available actions include: -- **Get IDs**: This button will copy the IDs of the selected jobs to the clipboard. -- **Rechedule**: This button will reschedule the selected jobs. -- **Kill**: This button will kill the selected jobs. -- **Delete**: This button will delete the selected jobs. - diff --git a/package-lock.json b/package-lock.json index 4224a408..f1968b39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,9 @@ "devDependencies": { "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", - "husky": "^9.0.11" + "@types/node": "^24.1.0", + "husky": "^9.0.11", + "ts-node": "^10.9.2" } }, "node_modules/@adobe/css-tools": { @@ -39,6 +41,37 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/install-pkg/node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "license": "MIT", + "optional": true + }, + "node_modules/@antfu/utils": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@atlaskit/atlassian-context": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@atlaskit/atlassian-context/-/atlassian-context-0.2.0.tgz", @@ -2114,6 +2147,57 @@ "dev": true, "license": "MIT" }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", + "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==", + "license": "MIT", + "optional": true + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0", + "optional": true + }, "node_modules/@chromatic-com/storybook": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.6.tgz", @@ -2403,6 +2487,30 @@ "node": ">=v18" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@cypress/request": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.8.tgz", @@ -3324,6 +3432,43 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT", + "optional": true + }, + "node_modules/@iconify/utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", + "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@antfu/install-pkg": "^1.0.0", + "@antfu/utils": "^8.1.0", + "@iconify/types": "^2.0.0", + "debug": "^4.4.0", + "globals": "^15.14.0", + "kolorist": "^1.8.0", + "local-pkg": "^1.0.0", + "mlly": "^1.7.4" + } + }, + "node_modules/@iconify/utils/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", @@ -4577,6 +4722,16 @@ "react": ">=16" } }, + "node_modules/@mermaid-js/parser": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.5.0.tgz", + "integrity": "sha512-AiaN7+VjXC+3BYE+GwNezkpjIcCI2qIMB/K4S2/vMWe0q/XJCBbx5+K7iteuz7VyltX9iAK4FmVTvGc9kjOV4w==", + "license": "MIT", + "optional": true, + "dependencies": { + "langium": "3.3.1" + } + }, "node_modules/@microsoft/api-extractor": { "version": "7.52.5", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.5.tgz", @@ -5994,6 +6149,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -7172,6 +7339,34 @@ "node": ">= 10" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, "node_modules/@tybys/wasm-util": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", @@ -7252,6 +7447,290 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -7298,6 +7777,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT", + "optional": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -7426,13 +7912,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", - "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.8.0" } }, "node_modules/@types/parse-json": { @@ -7441,6 +7927,13 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", + "license": "MIT", + "optional": true + }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", @@ -7517,6 +8010,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -8305,7 +8805,7 @@ "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -8597,6 +9097,13 @@ ], "license": "MIT" }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -9928,7 +10435,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -9965,6 +10471,34 @@ "node": ">= 0.8.0" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -10327,6 +10861,13 @@ "dev": true, "license": "MIT" }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT", + "optional": true + }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", @@ -10435,6 +10976,16 @@ "dev": true, "license": "MIT" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "optional": true, + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", @@ -10595,8 +11146,15 @@ "node": ">=8" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, @@ -10884,6 +11442,557 @@ "node": ">=10" } }, + "node_modules/cytoscape": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz", + "integrity": "sha512-5JHBC9n75kz5851jeklCPmZWcg3hUe6sjqJvyk3+hVqFaKcHwHgxsjeN1yLmggoUc6STbtm9/NQyabQehfjvWQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "optional": true, + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT", + "optional": true + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "optional": true, + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "optional": true, + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "optional": true, + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC", + "optional": true + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "optional": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "license": "MIT", + "optional": true, + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -11110,6 +12219,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "optional": true, + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -11173,6 +12292,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -11327,6 +12456,16 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", + "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optional": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", @@ -11464,6 +12603,12 @@ "dev": true, "license": "MIT" }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -12686,6 +13831,13 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/exsolve": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.6.tgz", + "integrity": "sha512-Q05uIdxhPBVBwK29gcPsl2K220xSBy52TZQPdeYWE0zOs8jM+yJ6y5h7jm6cpAo1p+OOMZRIj/Ftku4EQQBLnQ==", + "license": "MIT", + "optional": true + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -13692,6 +14844,13 @@ "resolved": "packages/extensions", "link": true }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT", + "optional": true + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -14060,7 +15219,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -14269,6 +15428,16 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/is-arguments": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", @@ -16956,6 +18125,33 @@ "node": ">=4.0" } }, + "node_modules/katex": { + "version": "0.16.22", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", + "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -16966,6 +18162,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==", + "optional": true + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -16976,6 +18178,30 @@ "node": ">=6" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT", + "optional": true + }, + "node_modules/langium": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", + "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", + "license": "MIT", + "optional": true, + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -16996,6 +18222,13 @@ "node": ">=0.10" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT", + "optional": true + }, "node_modules/lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -17528,6 +18761,24 @@ "node": ">= 12.13.0" } }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", @@ -17551,6 +18802,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT", + "optional": true + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -17917,6 +19175,32 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdown-to-jsx": { + "version": "7.7.8", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.7.8.tgz", + "integrity": "sha512-e+5bQJ30iIyJUV4tH/3wuBjpE5muLXsuBBi30N9t3B9O+UomC1Ocdqu7uD3X4YqtPrNLz+6QwHJaD7CXURBi+w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "optional": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -18205,6 +19489,56 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.7.0.tgz", + "integrity": "sha512-/1/5R0rt0Z1Ak0CuznAnCF3HtQgayRXUz6SguzOwN4L+DuCobz0UxnQ+ZdTSZ3AugKVVh78tiVmsHpHWV25TCw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@braintree/sanitize-url": "^7.0.4", + "@iconify/utils": "^2.1.33", + "@mermaid-js/parser": "^0.5.0", + "@types/d3": "^7.4.3", + "cytoscape": "^3.29.3", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.13", + "dompurify": "^3.2.5", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^15.0.7", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid/node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT", + "optional": true + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -18934,12 +20268,60 @@ "node": ">=8" } }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "license": "MIT", + "optional": true, + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT", + "optional": true + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mui-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mui-markdown/-/mui-markdown-2.0.1.tgz", + "integrity": "sha512-R++Ju6+a0qRPyMDY3JBXo1zt6RncntuQ1r684ECTxSbED9/fDSu7GT2pNQsxQivs4QRLAw11glrsRBTOspBwoA==", + "license": "MIT", + "optionalDependencies": { + "mermaid": "^11.6.0", + "prism-react-renderer": "^2.0.3" + }, + "peerDependencies": { + "@mui/material": ">=5.0.0", + "markdown-to-jsx": ">=7.0.0", + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -19502,6 +20884,21 @@ "dev": true, "license": "MIT" }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -19966,6 +21363,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", + "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "license": "MIT", + "optional": true + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -20063,6 +21467,13 @@ "dev": true, "license": "MIT" }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT", + "optional": true + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -20142,6 +21553,13 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT", + "optional": true + }, "node_modules/pathval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", @@ -20314,6 +21732,18 @@ "node": ">=8" } }, + "node_modules/pkg-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "license": "MIT", + "optional": true, + "dependencies": { + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -20406,6 +21836,24 @@ "node": ">=6" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT", + "optional": true + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "optional": true, + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/polished": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", @@ -20697,6 +22145,20 @@ "dev": true, "license": "MIT" }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -20841,6 +22303,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT", + "optional": true + }, "node_modules/querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", @@ -21691,6 +23170,13 @@ "inherits": "^2.0.1" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense", + "optional": true + }, "node_modules/rollup": { "version": "4.40.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz", @@ -21731,6 +23217,19 @@ "fsevents": "~2.3.2" } }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -21755,6 +23254,13 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause", + "optional": true + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -21845,7 +23351,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/sass-loader": { @@ -22214,6 +23720,18 @@ "dev": true, "license": "MIT" }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -23373,7 +24891,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.10" @@ -23449,6 +24967,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -23856,6 +25418,13 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT", + "optional": true + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -23876,9 +25445,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", "dev": true, "license": "MIT" }, @@ -23892,6 +25461,15 @@ "node": ">=4" } }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", @@ -24208,6 +25786,13 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -24275,6 +25860,61 @@ "dev": true, "license": "MIT" }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "optional": true, + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "optional": true, + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT", + "optional": true + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT", + "optional": true + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT", + "optional": true + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -24852,6 +26492,16 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -24936,6 +26586,8 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "dayjs": "^1.11.13", + "mui-markdown": "^2.0.1", + "node-emoji": "^2.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-virtuoso": "^4.12.3", diff --git a/package.json b/package.json index de4dc815..4eecb072 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "devDependencies": { "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", - "husky": "^9.0.11" + "@types/node": "^24.1.0", + "husky": "^9.0.11", + "ts-node": "^10.9.2" }, "scripts": { "dev": "npm --prefix packages/diracx-web run dev", @@ -20,6 +22,7 @@ "doc:diracx-web-components": "npm --prefix packages/diracx-web-components run doc", "lint": "npm --prefix packages/diracx-web-components run lint && npm --prefix packages/diracx-web run lint", "ts-lint": "npm --prefix packages/diracx-web-components run ts-lint && npm --prefix packages/diracx-web run ts-lint", - "prepare": "husky" + "prepare": "husky", + "generate-doc": "npm --prefix packages/diracx-web-components run generate-doc && npm --prefix packages/extensions run generate-doc" } } diff --git a/packages/diracx-web-components/.prettierignore b/packages/diracx-web-components/.prettierignore index 523cdf01..6b3078ad 100644 --- a/packages/diracx-web-components/.prettierignore +++ b/packages/diracx-web-components/.prettierignore @@ -7,3 +7,4 @@ jest.config.mjs release-please-config.json .release-please-manifest.json CHANGELOG.md +src/generatedDoc.ts \ No newline at end of file diff --git a/packages/diracx-web-components/package.json b/packages/diracx-web-components/package.json index 1e0750c9..73f6c92b 100644 --- a/packages/diracx-web-components/package.json +++ b/packages/diracx-web-components/package.json @@ -7,7 +7,7 @@ "access": "public" }, "scripts": { - "build": "tsup --minify", + "build": "npm run generate-doc && tsup --minify", "dev": "tsup --watch", "test": "jest --ci", "lint": "eslint ./src", @@ -15,7 +15,8 @@ "ts-lint": "tsc -noEmit -incremental", "prepack": "rm -rf dist && npm run build", "doc": "storybook dev -p 6006", - "build-doc": "storybook build" + "build-doc": "storybook build", + "generate-doc": "node script/generateDoc.js" }, "license": "GPL-3.0", "type": "module", @@ -35,6 +36,8 @@ "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "dayjs": "^1.11.13", + "mui-markdown": "^2.0.1", + "node-emoji": "^2.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-virtuoso": "^4.12.3", diff --git a/packages/diracx-web-components/script/generateDoc.js b/packages/diracx-web-components/script/generateDoc.js new file mode 100644 index 00000000..1a0c3105 --- /dev/null +++ b/packages/diracx-web-components/script/generateDoc.js @@ -0,0 +1,78 @@ +import * as fs from "fs"; +import * as path from "path"; + +const DOCS_PATH = "../../docs/user"; +const OUTPUT_PATH = "./src/generatedDoc.ts"; + +async function readMarkdown(filePath) { + return fs.promises.readFile(filePath, "utf-8"); +} + +async function getTitleAndContent(filePath, fallbackName) { + const content = await readMarkdown(filePath); + const lines = content.split("\n").map((line) => line.trim()); + + let title = fallbackName; + + if (lines.length > 0 && lines[0].startsWith("# ")) { + title = lines[0].substring(2).trim(); + } + + return { title, content }; +} + +async function generate() { + const apps = []; + + const files = await fs.promises.readdir(DOCS_PATH); + + let generalUsage = ""; + + for (const entry of files) { + const fullPath = path.join(DOCS_PATH, entry); + const stat = await fs.promises.stat(fullPath); + + if (entry === "generalUsage.md") { + generalUsage = await readMarkdown(fullPath); + } else if (stat.isDirectory()) { + const sections = []; + const sectionFiles = await fs.promises.readdir(fullPath); + for (const sectionFile of sectionFiles) { + const sectionPath = path.join(fullPath, sectionFile); + const { title, content } = await getTitleAndContent( + sectionPath, + sectionFile.replace(".md", "").replace(/_/g, " "), // Use file name as title + ); + + sections.push({ + title: title, + content, + }); + } + apps.push({ + appName: entry.replace(/_/g, " "), // Convert directory name to app name + sections, + }); + } + } + + const doc = { + generalUsage, + applications: apps, + }; + + const fileContent = `/* eslint-disable */ +/** +*File generated by generateDocs.js from /docs/user. +*Do not edit this file directly. +*/ + +import { UserDocumentation } from './types'; + +export const userDocumentation: UserDocumentation = ${JSON.stringify(doc, null, 2)}; +`; + + await fs.promises.writeFile(OUTPUT_PATH, fileContent, "utf-8"); +} + +generate().catch(console.error); diff --git a/packages/diracx-web-components/src/components/DashboardLayout/DashboardDrawer.tsx b/packages/diracx-web-components/src/components/DashboardLayout/DashboardDrawer.tsx index ebc8ee76..f6ba6d70 100644 --- a/packages/diracx-web-components/src/components/DashboardLayout/DashboardDrawer.tsx +++ b/packages/diracx-web-components/src/components/DashboardLayout/DashboardDrawer.tsx @@ -16,7 +16,7 @@ import { Toolbar, useTheme, } from "@mui/material"; -import { MenuBook, Add } from "@mui/icons-material"; +import { MenuBook, Add, TipsAndUpdates } from "@mui/icons-material"; import React, { useContext, useEffect, useState } from "react"; import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"; import { extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge"; @@ -24,6 +24,7 @@ import { ApplicationsContext } from "../../contexts/ApplicationsProvider"; import { DashboardGroup } from "../../types"; import DrawerItemGroup from "./DrawerItemGroup"; import AppDialog from "./ApplicationDialog"; +import HelpOverlay from "./HelpOverlay"; interface DashboardDrawerProps { /** The variant of the drawer. Usually temporary if on mobile and permanent otherwise. */ @@ -78,6 +79,8 @@ export default function DashboardDrawer({ const [renamingGroupId, setRenamingGroupId] = useState(null); const [renameValue, setRenameValue] = useState(""); + const [helpOpen, setHelpOpen] = useState(false); + // Define the applications that are accessible to users. // Each application has an associated icon and path. const [userDashboard, setUserDashboard, , , setCurrentAppId] = @@ -456,6 +459,15 @@ export default function DashboardDrawer({ + + setHelpOpen(true)} + data-testid="user-guide-button" + > + {} + + + {} @@ -523,6 +535,8 @@ export default function DashboardDrawer({ setAppDialogOpen={setAppDialogOpen} handleCreateApp={handleAppCreation} /> + + setHelpOpen(false)} /> ); } diff --git a/packages/diracx-web-components/src/components/DashboardLayout/HelpOverlay.tsx b/packages/diracx-web-components/src/components/DashboardLayout/HelpOverlay.tsx new file mode 100644 index 00000000..ec95de27 --- /dev/null +++ b/packages/diracx-web-components/src/components/DashboardLayout/HelpOverlay.tsx @@ -0,0 +1,198 @@ +import { useState, useContext } from "react"; +import { MuiMarkdown, defaultOverrides } from "mui-markdown"; +import { emojify } from "node-emoji"; + +import { + Box, + Typography, + ListItemButton, + IconButton, + List, + ListItemText, + Divider, + Modal, + Collapse, + useTheme, +} from "@mui/material"; + +import { grey } from "@mui/material/colors"; + +import CloseIcon from "@mui/icons-material/Close"; + +import ExpandLess from "@mui/icons-material/ExpandLess"; +import ExpandMore from "@mui/icons-material/ExpandMore"; +import { ApplicationsContext } from "../../contexts"; + +/** + * + * @param isOpen Boolean indicating if the help page is open + * @param closeHelp Function to close the help page + * @returns Component to display the help overlay with user documentation + */ +export default function HelpOverlay({ + isOpen, + closeHelp, +}: { + isOpen: boolean; + closeHelp: () => void; +}) { + const [selected, setSelected] = useState("general"); + const [expandedApps, setExpandedApps] = useState>({}); + + const userDocumentation = useContext(ApplicationsContext)[5]; + const theme = useTheme(); + + const backgroundColor = theme.palette.mode === "dark" ? grey[900] : grey[50]; + + const customOverrides = { + ...defaultOverrides, + h1: { + component: Typography, + props: { + variant: "h3", + gutterBottom: true, + sx: { + marginTop: "1.5rem", + marginBottom: "1.5rem", + }, + } as React.HTMLProps, + }, + h2: { + component: Typography, + props: { + variant: "h4", + gutterBottom: true, + sx: { + marginTop: "1rem", + marginBottom: "0.5rem", + }, + } as React.HTMLProps, + }, + h3: { + component: Typography, + props: { + variant: "h5", + gutterBottom: true, + sx: { + marginTop: "1rem", + marginBottom: "0.25rem", + }, + } as React.HTMLProps, + }, + p: { + component: Typography, + props: { + paragraph: true, + } as React.HTMLProps, + }, + }; + // Handle application section toggle + const toggleApp = (appName: string) => { + setExpandedApps((prev) => ({ + ...prev, + [appName]: !prev[appName], + })); + }; + + // Render content based on selected item + const RenderContent = () => { + if (selected === "general") { + return ( + <> + + {emojify(userDocumentation.generalUsage)} + + + ); + } + + const [appName, sectionTitle] = selected.split("::"); + const app = userDocumentation.applications.find( + (a) => a.appName === appName, + ); + const section = app?.sections.find((s) => s.title === sectionTitle); + + return ( + <> + + {emojify(section?.content || "")} + + + ); + }; + + return ( + + + {/* Left vertical menu */} + + + + + + + setSelected("general")} + > + + + + {userDocumentation.applications.map((app, index) => ( + + toggleApp(app.appName)}> + + {expandedApps[app.appName] ? : } + + + + {app.sections.map((section) => ( + + setSelected(`${app.appName}::${section.title}`) + } + > + + + ))} + + + + ))} + + + + {/* Right content pane */} + {RenderContent()} + + + ); +} diff --git a/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx b/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx index c0996263..7e712f1b 100644 --- a/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx +++ b/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx @@ -4,7 +4,9 @@ import React, { createContext, useEffect, useState } from "react"; import { applicationList } from "../components/applicationList"; import { defaultDashboard } from "../components/defaultDashboard"; import { DashboardGroup } from "../types/DashboardGroup"; +import { userDocumentation as userDoc } from "../generatedDoc"; import ApplicationMetadata from "../types/ApplicationMetadata"; +import { UserDocumentation } from "../types"; // Create a context for the UserDashboard state export const ApplicationsContext = createContext< @@ -14,13 +16,15 @@ export const ApplicationsContext = createContext< ApplicationMetadata[], string, // Id of the current application React.Dispatch>, + UserDocumentation, ] ->([[], () => {}, [], "", () => {}]); +>([[], () => {}, [], "", () => {}, userDoc]); interface ApplicationsProviderProps { children: React.ReactNode; appList?: ApplicationMetadata[]; defaultUserDashboard?: DashboardGroup[]; + userDocumentation?: UserDocumentation; } /** @@ -29,12 +33,14 @@ interface ApplicationsProviderProps { * @param children - The child components to be wrapped by the provider. * @param appList - The list of application configurations. * @param defaultUserDashboard - The default user dashboard. + * @param userDocunentation - The user documentation for the applications. * @returns The applications provider. */ export const ApplicationsProvider = ({ children, appList = applicationList, defaultUserDashboard = defaultDashboard, + userDocumentation, }: ApplicationsProviderProps) => { const loadedDashboard = sessionStorage.getItem("savedDashboard"); const parsedDashboard: DashboardGroup[] = loadedDashboard @@ -60,6 +66,16 @@ export const ApplicationsProvider = ({ sessionStorage.setItem("savedDashboard", JSON.stringify(userDashboard)); }, [userDashboard]); + const mergedDocumentation: UserDocumentation = { ...userDoc }; + + if (userDocumentation) { + mergedDocumentation.applications = mergedDocumentation.applications.concat( + userDocumentation.applications, + ); + mergedDocumentation.generalUsage = + userDocumentation.generalUsage || mergedDocumentation.generalUsage; + } + return ( {children} diff --git a/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx b/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx index 856a7e2c..063d1ff2 100644 --- a/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx +++ b/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx @@ -1,6 +1,10 @@ "use client"; -import type { ApplicationMetadata, DashboardGroup } from "../types"; +import type { + ApplicationMetadata, + DashboardGroup, + UserDocumentation, +} from "../types"; import { OIDCSecure } from "../components"; import { @@ -17,6 +21,7 @@ interface DiracXWebProvidersProps { getSearchParams: () => URLSearchParams; appList?: ApplicationMetadata[]; defaultUserDashboard?: DashboardGroup[]; + userDocumentation?: UserDocumentation; } export function DiracXWebProviders({ @@ -26,6 +31,7 @@ export function DiracXWebProviders({ getSearchParams, appList, defaultUserDashboard, + userDocumentation, }: DiracXWebProvidersProps) { return ( @@ -37,6 +43,7 @@ export function DiracXWebProviders({ {children} diff --git a/packages/diracx-web-components/src/generatedDoc.ts b/packages/diracx-web-components/src/generatedDoc.ts new file mode 100644 index 00000000..abaaece6 --- /dev/null +++ b/packages/diracx-web-components/src/generatedDoc.ts @@ -0,0 +1,43 @@ + +/** +*File generated by generateDocs.js from /docs/user. +*Do not edit this file directly. +*/ + +import { UserDocumentation } from './types'; + +export const userDocumentation: UserDocumentation = { + "generalUsage": "# General Usage\n\n## Navigate Between Applications\n\nYou can click on the `Add application` button to create a new instance of an application. \nThe list of open instances appears in the sidebar on the left. Clicking on one of these instances will display it in the center of the dashboard.\n\n## Share Applications\n\nTo share applications, click the `Export` button at the top right of the screen.\nThen, select the applications you want to share and copy them to the clipboard.\n\n## Import Applications\n\nTo import applications, click the `Import` button at the top right of the screen.\nPaste the copied applications into the input field and click `Import`. The imported applications will appear in the sidebar.\nIf the states are outdated, you can copy the updated version of them by clicking the `Copy all updated states` button.\n\n## Save Your Dashboard\n\nTo save your dashboard, click the `Export` button at the top right of the screen. \nThen, select the applications you want to save and click the `Save in the browser` button. The saved applications will be stored in your browser's local storage.\nWhen you want to load the saved applications, click the `Import` button at the top right of the screen and select the `Load from the browser` option. \nThe saved applications will be loaded into the sidebar.\n", + "applications": [ + { + "appName": "Dashboard", + "sections": [ + { + "title": "Managing Application Instances", + "content": "# Managing Application Instances\n\nAn *application instance* is a graphical web interface that allows users to interact with DiracX services. DiracX-Web is essentially a collection of such applications, and users can \"spawn\" instances to interact with them.\n\nBy default, a few application instances are displayed (e.g., `My Jobs`, an instance of `Job Monitor`). This guide will help you manage, organize, and share application instances effectively.\n\n## Basics\n\n### Accessing More Applications\n\n1. Click the **Add Application** button at the bottom of the sidebar.\n - :bulb: On mobile devices, first open the sidebar by clicking the **menu icon** (☰) at the top-left corner.\n2. Select an application from the list in the dialog box.\n - :bulb: The selected application will appear in the sidebar.\n\n### Opening Multiple Instances of the Same Application\n\n- Repeat the steps above to open additional instances of the same application.\n - :bulb: Each instance has its own state, making it ideal for monitoring different job groups with specific criteria for instance.\n\n### Renaming an Application Instance\n\n1. **Right-click** on the instance name in the sidebar.\n - :bulb: A context menu will appear.\n2. Select **Rename**.\n - :bulb: The instance name will change to an input field.\n3. Enter a new name and press **Enter** to save it.\n - :bulb: You can't use the same name for several intances\n\n### Moving an Application Instance\n\n1. Locate the **handle icon** next to the instance name.\n2. Click and hold the handle to select the instance.\n3. Drag it to the desired position within the sidebar.\n4. Release the mouse button to place the instance.\n\n### Deleting an Application Instance\n\n1. **Right-click** on the instance name in the sidebar.\n - :bulb: A context menu will appear.\n2. Select **Delete**.\n - :bulb: The application instance will disappear from the sidebar.\n\n### Sharing Your Dashboard\n\n1. Click on the **Export** button at the top-right corner of the page.\n2. Select the instances you want to share.\n - :bulb: You can select a group to select all instances within that group.\n - :bulb: For each instance, the shared content will include the name you gave it and the settings you configured.\n3. Click on **Export N Selected**.\n - :bulb: A menu will appear with a text box containing the exported JSON.\n4. Click on the **Copy to Clipboard** button.\n5. Send this text to the person you want to share it with.\n - :bulb: If you're using **Mattermost**, you can wrap the text with triple backticks (```) to display it nicely.\n\n\n## Advanced Features\n\nWhen managing multiple instances of the same application, grouping can help you organize your dashboard efficiently.\n\n### Creating a New Group\n\n1. **Right-click** anywhere in the sidebar.\n - :bulb: A context menu will appear.\n2. Select **New Group**.\n - :bulb: A new group with a default name will appear in the sidebar.\n3. Add new application instances to the group using the **Add Application** button.\n - :bulb: By default, new instances will be placed in the most recently created group.\n\n### Renaming a Group\n\n1. **Right-click** on the group name in the sidebar.\n - :bulb: A context menu will appear.\n2. Select **Rename**.\n - :bulb: The group name will change to an input field.\n3. Enter a new name and press **Enter** to save it.\n\n### Moving a Group\n\n1. Locate the **handle icon** next to the group name.\n2. Click and hold the handle to select the group.\n3. Drag the group to the desired position within the sidebar.\n - :bulb: All application instances within the group will move together.\n4. Release the mouse button to place the group.\n\n### Moving Instances Between Groups\n\n1. Drag an application instance from one group.\n2. Drop it into another group using the same drag-and-drop process as moving instances within a group.\n\n### Deleting a Group\n\n1. **Right-click** on the group name in the sidebar.\n - :bulb: A context menu will appear.\n2. Select **Delete**.\n - :bulb: The group and all its application instances will disappear from the sidebar.\n\n**Good to know:** When switching to a new version, the settings you are trying to import may no longer be valid. In this case, a new window will appear, offering to resolve the issue by updating the state copied to your clipboard. This updated version preserves your imported rules as much as possible. \n" + }, + { + "title": "Logging in & out", + "content": "# Logging in & out\n\n## Basics\n### Logging in\n\n1. Go to the DiracX-Web instance homepage. \n - 💡 You should end up on an authentication page.\n2. Authenticate you as a user of a given VO/group:\n - If your instance supports multiple VOs, select your VO in the list box.\n - Select your Group in the list box below.\n3. Click the **Login** button. \n - 💡 You should be redirected to the VO login page.\n4. Enter your credentials (e.g., Username/Password, X509 certificates). \n - 💡 You should see a page asking for permission to access your profile.\n5. Accept the permissions to access your DiracX dashboard. \n - 💡 You should be redirected to the DiracX-Web instance as a logged-in user, and the dashboard should appear.\n\n### Logging out\n\n1. Click on your profile icon in the top-right corner of the dashboard.\n - :bulb: A dropdown menu should appear\n2. Select **Logout** from the dropdown menu.\n \n## Advanced\n### Logging in with specific properties\n\nTODO\n" + } + ] + }, + { + "appName": "Job Monitor", + "sections": [ + { + "title": "Manage Your Jobs", + "content": "# Manage Your Jobs\n\n## Status transitions\n\nYou can select one or more jobs by clicking on the checkboxes next to each job. Once jobs are selected, you can perform actions on them using the buttons at the top of the table. The available actions include:\n\n- **Reschedule**: Reschedules the selected jobs.\n- **Kill**: Marks the selected jobs to be killed.\n- **Delete**: Marks the selected jobs for deletion.\n\n**Note**: \n- You can only delete jobs that are already killed. \n- A job cannot typically be rescheduled more than three times.\n\n## View a Job's History\n\nYou can right-click on a job to open its **Job History**. \nThe history shows the different statuses the job has gone through, along with the corresponding dates and the authors of the changes.\n\n" + }, + { + "title": "The Search Bar", + "content": "# The Search Bar\n\nThe search bar allows you to filter jobs based on various criteria. Filters are represented as equations, where each equation consists of a job attribute, an operator, and a value. The search bar analyzes these equations to evaluate their consistency. A green equation is valid, a yellow equation is incomplete, and a red equation is invalid.\n\nA search is automatically performed when all equations in the search bar are valid.\n\n## Create a Filter\n\nTo create a filter, click on the search bar and start typing. Suggestions will appear based on the available job attributes. You can select a suggestion to choose the criterion. After that, you can either type or select an operator and a value to filter by. \nThe search bar only suggests attributes, operators, and values that are available in your current set of jobs.\n\n## Edit a Filter\n\nTo edit a filter, click on it in the search bar. You can change the operator or value by clicking on them. You can also use the arrow keys to navigate through the equations and edit them. Press `ESCAPE` to return to the end of the search bar.\n\n## Remove a Filter\n\nTo remove a filter, press the `Backspace` key to remove the last token, or right-click on the equation to remove the entire equation. \nYou can also clear the entire search bar by clicking on the trash can button at the end of the search bar.\n" + }, + { + "title": "The Table", + "content": "# The Table\n\nThe table displays the jobs that match the criteria specified in the search bar. Each row represents a job, and the columns show various attributes of the job, such as its ID, status, type, and submission date.\n\n## Table display settings\nYou can click on the eye icon to select additional columns to display in the table. Some columns are hidden by default.\n\nYou can sort the table by clicking on the column headers. Clicking once will sort the table in ascending order; clicking again will sort it in descending order.\n\nYou can set the page size by using the `Rows per page` dropdown at the bottom of the table. This allows you to control how many jobs are displayed per page.\n\n## Select a Job\n\nYou can select one or multiple jobs using the checkboxes on the left side of the table. \nOnce you have selected at least one job, you can perform actions on it. You can manage the selected jobs or copy their IDs to your clipboard.\n" + } + ] + } + ] +}; diff --git a/packages/diracx-web-components/src/types/UserDocumentation.ts b/packages/diracx-web-components/src/types/UserDocumentation.ts new file mode 100644 index 00000000..b231492c --- /dev/null +++ b/packages/diracx-web-components/src/types/UserDocumentation.ts @@ -0,0 +1,14 @@ +interface DocumentationSection { + title: string; + content: string; +} + +interface appDocumentation { + appName: string; + sections: DocumentationSection[]; +} + +export interface UserDocumentation { + generalUsage: string; + applications: appDocumentation[]; +} diff --git a/packages/diracx-web-components/src/types/index.ts b/packages/diracx-web-components/src/types/index.ts index 880b578e..f369ee86 100644 --- a/packages/diracx-web-components/src/types/index.ts +++ b/packages/diracx-web-components/src/types/index.ts @@ -15,3 +15,4 @@ export * from "./EquationStatus"; export * from "./operators"; export * from "./SearchBarTokenNature"; export * from "./CategoryType"; +export * from "./UserDocumentation"; diff --git a/packages/diracx-web-components/stories/Dashboard.stories.tsx b/packages/diracx-web-components/stories/Dashboard.stories.tsx index 1a05227c..cdb76f31 100644 --- a/packages/diracx-web-components/stories/Dashboard.stories.tsx +++ b/packages/diracx-web-components/stories/Dashboard.stories.tsx @@ -7,6 +7,7 @@ import { applicationList } from "../src/components/applicationList"; import { DashboardGroup } from "../src/types/DashboardGroup"; import Dashboard from "../src/components/DashboardLayout/Dashboard"; import { ThemeProvider } from "../src/contexts/ThemeProvider"; +import { userDocumentation } from "../src/generatedDoc"; const meta = { title: "Dashboard Layout/Dashboard", @@ -52,6 +53,7 @@ const meta = { applicationList, currentAppId, setCurrentAppId, + userDocumentation, ]} > diff --git a/packages/extensions/README.md b/packages/extensions/README.md index ef02c6bf..09d3e70b 100644 --- a/packages/extensions/README.md +++ b/packages/extensions/README.md @@ -170,7 +170,7 @@ Having a directory dedicated to your extension components will help you keep you To add new apps to your extension, you can create new components in your extension directory. -[`testApp`](src/gubbins/components/TestApp/testApp.tsx) provides an example of a basic app component and the [Storybook documentation](https://diracgrid.github.io/diracx-web/) showcases all the components you can use from the library in an interactive interface. +[`OwnerMonitor`](src/gubbins/components/OwnerMonitor/OwnerMonitor.tsx) provides an example of a basic app component and the [Storybook documentation](https://diracgrid.github.io/diracx-web/) showcases all the components you can use from the library in an interactive interface. It is then pretty easy to add them to DiracX Web by extending the `applicationList` (the list of apps available in DiracX-Web) from `diracx-web-components/components`. diff --git a/packages/extensions/docs/dev/contribute.md b/packages/extensions/docs/dev/contribute.md new file mode 100644 index 00000000..f59434a7 --- /dev/null +++ b/packages/extensions/docs/dev/contribute.md @@ -0,0 +1,4 @@ +# Create your own extension + +This whole project is just an example about how you can create your own extension. +If you want more details, look at the documentation in the project [diracx-web](https://github.com/diracggrid/diracx-web). diff --git a/packages/extensions/docs/user/Owner_Monitor/definition.md b/packages/extensions/docs/user/Owner_Monitor/definition.md new file mode 100644 index 00000000..0c565a0a --- /dev/null +++ b/packages/extensions/docs/user/Owner_Monitor/definition.md @@ -0,0 +1,3 @@ +# Definition of Gubbins + +**Gubbins** is a British informal noun referring to small, miscellaneous items or bits and pieces, often of little value or importance. It can describe gadgets, parts, or knick-knacks whose exact names might not be known or remembered. The term is frequently used to refer to odds and ends lying around or small components in a machine. Sometimes, it can imply something trivial or unimportant, almost like "stuff" or "junk." In some contexts, it can also humorously refer to technical or mechanical parts, especially those that are confusing or complicated. While common in UK English, the word is less known in American English, where similar expressions might be "bits and bobs" or "thingamajigs." Overall, "gubbins" conveys a casual, somewhat affectionate sense of miscellaneous small items. diff --git a/packages/extensions/docs/user/Owner_Monitor/presentation.md b/packages/extensions/docs/user/Owner_Monitor/presentation.md new file mode 100644 index 00000000..2e082100 --- /dev/null +++ b/packages/extensions/docs/user/Owner_Monitor/presentation.md @@ -0,0 +1,3 @@ +# Presentation of this module + +This is just an example. diff --git a/packages/extensions/docs/user/generalUsage.md b/packages/extensions/docs/user/generalUsage.md new file mode 100644 index 00000000..e0440a91 --- /dev/null +++ b/packages/extensions/docs/user/generalUsage.md @@ -0,0 +1,3 @@ +# Custom general Usage + +You can define your own `General Usage`. diff --git a/packages/extensions/package.json b/packages/extensions/package.json index 350bddca..bdf736ac 100644 --- a/packages/extensions/package.json +++ b/packages/extensions/package.json @@ -6,13 +6,14 @@ "license": "GPL-3.0-only", "scripts": { "dev": "next dev", - "build": "next build", + "build": "npm run generate-doc && next build", "test": "cypress open --config baseUrl=$DIRACX_URL", "start": "next start", "lint": "next lint", "lint-staged": "lint-staged", "ts-lint": "tsc -noEmit -incremental", - "postinstall": "node ../../node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public" + "postinstall": "node ../../node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public", + "generate-doc": "node script/generateDoc.js" }, "dependencies": { "@axa-fr/react-oidc": "^7.24.0", @@ -39,6 +40,8 @@ "eslint": "^9", "eslint-config-next": "15.0.2", "eslint-config-prettier": "^10.0.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-unused-imports": "^4.1.4", "lint-staged": "^15.2.2", "prettier": "^3.2.5", "typescript": "^5" diff --git a/packages/extensions/script/generateDoc.js b/packages/extensions/script/generateDoc.js new file mode 100644 index 00000000..736ed7cf --- /dev/null +++ b/packages/extensions/script/generateDoc.js @@ -0,0 +1,78 @@ +import { promises } from "fs"; +import { join } from "path"; + +const DOCS_PATH = "./docs/user"; +const OUTPUT_PATH = "./src/generatedDoc.ts"; + +async function readMarkdown(filePath) { + return promises.readFile(filePath, "utf-8"); +} + +async function getTitleAndContent(filePath, fallbackName) { + const content = await readMarkdown(filePath); + const lines = content.split("\n").map((line) => line.trim()); + + let title = fallbackName; + + if (lines.length > 0 && lines[0].startsWith("# ")) { + title = lines[0].substring(2).trim(); + } + + return { title, content }; +} + +async function generate() { + const apps = []; + + const files = await promises.readdir(DOCS_PATH); + + let generalUsage = ""; + + for (const entry of files) { + const fullPath = join(DOCS_PATH, entry); + const stat = await promises.stat(fullPath); + + if (entry === "generalUsage.md") { + generalUsage = await readMarkdown(fullPath); + } else if (stat.isDirectory()) { + const sections = []; + const sectionFiles = await promises.readdir(fullPath); + for (const sectionFile of sectionFiles) { + const sectionPath = join(fullPath, sectionFile); + const { title, content } = await getTitleAndContent( + sectionPath, + sectionFile.replace(".md", "").replace(/_/g, " "), // Use file name as title + ); + + sections.push({ + title: title, + content, + }); + } + apps.push({ + appName: entry.replace(/_/g, " "), // Convert directory name to app name + sections, + }); + } + } + + const doc = { + generalUsage, + applications: apps, + }; + + const fileContent = `/* eslint-disable */ +/** +*File generated by generateDocs.js from /docs/user. +*Do not edit this file directly. +*/ + +import { UserDocumentation } from '@dirac-grid/diracx-web-components/types'; + +export const userDocumentation: UserDocumentation = ${JSON.stringify(doc, null, 2)}; +`; + + await promises.writeFile(OUTPUT_PATH, fileContent, "utf-8"); +} + +generate().catch(console.error); diff --git a/packages/extensions/src/app/(dashboard)/layout.tsx b/packages/extensions/src/app/(dashboard)/layout.tsx index 1f464574..d24d47ff 100644 --- a/packages/extensions/src/app/(dashboard)/layout.tsx +++ b/packages/extensions/src/app/(dashboard)/layout.tsx @@ -4,6 +4,7 @@ import { Box } from "@mui/material"; import { Dashboard } from "@dirac-grid/diracx-web-components/components"; import { DiracXWebProviders } from "@dirac-grid/diracx-web-components/contexts"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { userDocumentation } from "../../generatedDoc"; import { applicationList } from "@/gubbins/applicationList"; import { defaultSections } from "@/gubbins/DefaultUserDashboard"; @@ -29,6 +30,7 @@ export default function DashboardLayout({ // You can optionally pass a list of applications and a default user dashboard appList={applicationList} defaultUserDashboard={defaultSections} + userDocumentation={userDocumentation} > {/* Dashboard is the main layout for the applications, you can optionally give it a custom logo URL and a drawer width */} diff --git a/packages/extensions/src/generatedDoc.ts b/packages/extensions/src/generatedDoc.ts new file mode 100644 index 00000000..b6ee14df --- /dev/null +++ b/packages/extensions/src/generatedDoc.ts @@ -0,0 +1,29 @@ + +/** + *File generated by generateDocs.js from /docs/user. + *Do not edit this file directly. + */ + +import { UserDocumentation } from "@dirac-grid/diracx-web-components/types"; + +export const userDocumentation: UserDocumentation = { + generalUsage: + "# Custom general Usage\n\nYou can define your own `General Usage`.\n", + applications: [ + { + appName: "Owner Monitor", + sections: [ + { + title: "Definition of Gubbins", + content: + '# Definition of Gubbins\n\n**Gubbins** is a British informal noun referring to small, miscellaneous items or bits and pieces, often of little value or importance. It can describe gadgets, parts, or knick-knacks whose exact names might not be known or remembered. The term is frequently used to refer to odds and ends lying around or small components in a machine. Sometimes, it can imply something trivial or unimportant, almost like "stuff" or "junk." In some contexts, it can also humorously refer to technical or mechanical parts, especially those that are confusing or complicated. While common in UK English, the word is less known in American English, where similar expressions might be "bits and bobs" or "thingamajigs." Overall, "gubbins" conveys a casual, somewhat affectionate sense of miscellaneous small items.\n', + }, + { + title: "Presentation of this module", + content: + "# Presentation of this module\n\nThis is just an example.\n", + }, + ], + }, + ], +};