diff --git a/.gitignore b/.gitignore index 861b995..96d6ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,13 @@ # npm node_modules -# Don't include the compiled main.js file in the repo. +# Don't include the compiled files in the repo. # They should be uploaded to GitHub releases instead. main.js +styles.css + +# Obsidian plugin settings (generated at runtime) +data.json # Exclude sourcemaps *.map diff --git a/CLAUDE.md b/CLAUDE.md index a8ad2c4..b4f699c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -N-brace (also called Brainavigator) is an Obsidian plugin that provides interactive 2D graph navigation and visualization using react-force-graph-2d. It displays local graphs centered on the current note, allowing keyboard-based navigation through note connections. +N-brace is an Obsidian plugin that provides interactive 2D graph navigation and visualization using react-force-graph-2d. It displays local graphs centered on the current note, allowing keyboard-based navigation through note connections. ## Build Commands diff --git a/LICENSE b/LICENSE index 3934c11..b390778 100644 --- a/LICENSE +++ b/LICENSE @@ -2,6 +2,7 @@ MIT License Copyright (c) 2022 Alexander Weichart Copyright (c) 2023 Hananoshika Yomaru +Copyright (c) 2026 Rafael Hazan Copyright for portions util commit 7bfbc6ccbcadb350e451d15becfb375d6d8a6a6e are held by Alexander Weichart, 2022, up to caffbbb5c1bbb51a314fa2f29084b3c17c49cf55 are held by Hananoshika Yomaru, 2023. The rest is held by Rafael Hazan. diff --git a/README.md b/README.md index 3700196..9df37f6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Obsidian N-brace Plugin +# N-brace Plugin -[Obsidian N-brace Plugin](https://nn-ninja.github.io/n-brace/) Homepage +[N-brace Plugin](https://nn-ninja.github.io/n-brace/) Homepage A slightly different Graph navigation and visualization for Obsidian. @@ -61,16 +61,18 @@ I have in my plans to optimize this process. It is designed to rather operate on a local graph, not on huge and unclear global graph. +### Tag List + +The tag panel appears on the left side of the graph whenever any visible node carries a tag. Tags are sorted by frequency and color-coded consistently across the view. + +**Filtering:** Uncheck tags to hide nodes that don't share at least one checked tag. The graph contracts to show only nodes reachable from the selected note through the filtered set. A search box lets you filter the tag list itself by name (comma-separated terms supported). + +**Color modes:** Two coloring modes are available via the toggle buttons: +- **Cloudy tags** — each node is surrounded by a translucent color cloud showing its tags. Double-clicking a cloud segment isolates that tag. +- **Edgy tags** — links are colored by tags shared between their source and target nodes. + +**Node tags panel:** When a note is selected, a secondary panel shows the tags of that note alongside tags present on its direct neighbors (dimmed). You can add or remove tags from the selected note directly by clicking the checkboxes — changes are written back to the file immediately. + ### Save Setting You can update and save your general settings. - -## Acknowledgement - -I want to especially thank to the creators of this repos: -1. Force Graph repo: -2. The original 3D graph plugin: -3. The improved version: - -Their work was very helpful in getting my project off the ground. - diff --git a/bun.lockb b/bun.lockb index f9643ce..ea39087 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/data.json b/data.json deleted file mode 100644 index 720c537..0000000 --- a/data.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "savedSettings": [], - "temporaryLocalGraphSetting": { - "filter": { - "searchQuery": "", - "showOrphans": true, - "showAttachments": false, - "depth": 1, - "linkType": "both" - }, - "groups": [], - "display": { - "nodeSize": 3, - "linkThickness": 2, - "linkDistance": 100, - "nodeRepulsion": 2800, - "distanceFromFocal": 300, - "nodeHoverColor": "#ff0000", - "nodeHoverNeighbourColor": "#00ff00", - "linkHoverColor": "#0000ff", - "showExtension": false, - "showFullPath": false, - "showLinkArrow": true, - "dontMoveWhenDrag": false - } - }, - "pluginSetting": { - "baseFolder": "/", - "titleFontSize": 16, - "defaultGraphSpan": 5, - "linkColorTheme": "custom", - "linkColorIn": "122, 41, 143", - "linkColorOut": "13, 91, 130", - "linkColorOther": "148, 148, 148", - "maxNodeNumber": 1000, - "searchEngine": "default" - } -} \ No newline at end of file diff --git a/docs/graph.png b/docs/graph.png index a9628e9..870cf8d 100644 Binary files a/docs/graph.png and b/docs/graph.png differ diff --git a/package-lock.json b/package-lock.json index 5c56676..298b0a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "copy-anything": "^3.0.5", "d3": "^7.9.0", "d3-force": "^3.0.0", + "graphology": "^0.26.0", "jotai": "^2.9.1", "lucide-react": "^0.511.0", "observable-slim": "^0.1.6", @@ -44,7 +45,6 @@ "husky": "^8.0.3", "obsidian": "latest", "prettier": "^3.6.2", - "react-devtools": "^7.0.1", "semver": "^7.5.4", "tslib": "2.4.0", "typescript": "^5.0.5", @@ -316,68 +316,6 @@ "w3c-keyname": "^2.2.4" } }, - "node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/get/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", @@ -1108,30 +1046,6 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true }, - "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==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@total-typescript/ts-reset": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@total-typescript/ts-reset/-/ts-reset-0.5.1.tgz", @@ -1143,18 +1057,6 @@ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-21.1.1.tgz", "integrity": "sha512-O2GetAwEC/0MOiRb3lxCLIt/eeugoDPX0nu+1SFWLqGKf835ZdWsfM9RzDpjF+aKkpYMhvOnEhO+SxMnHHjpfw==" }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/codemirror": { "version": "5.60.8", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", @@ -1439,12 +1341,6 @@ "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", "dev": true }, - "node_modules/@types/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", - "dev": true - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1457,15 +1353,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { "version": "16.18.126", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", @@ -1497,15 +1384,6 @@ "@types/react": "^18.0.0" } }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/stats.js": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", @@ -1539,16 +1417,6 @@ "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", "dev": true }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.46.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz", @@ -1730,22 +1598,34 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", + "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -1824,9 +1704,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -1839,58 +1719,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==", - "dev": true, - "dependencies": { - "string-width": "^2.0.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -2155,146 +1983,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "optional": true - }, - "node_modules/boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "dependencies": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/boxen/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2374,15 +2062,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -2395,33 +2074,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2478,15 +2130,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001754", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", @@ -2518,18 +2161,6 @@ "node": ">=12" } }, - "node_modules/capture-stack-trace": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", - "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2546,21 +2177,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "node_modules/cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -2666,18 +2282,6 @@ "node": ">=0.8" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2710,23 +2314,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/configstore": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz", - "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==", - "dev": true, - "dependencies": { - "dot-prop": "^4.2.1", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2747,18 +2334,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", - "dev": true, - "dependencies": { - "capture-stack-trace": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", @@ -2780,15 +2355,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -3258,60 +2824,12 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -3324,15 +2842,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -3375,13 +2884,6 @@ "robust-predicates": "^3.0.2" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3394,18 +2896,6 @@ "node": ">=0.10.0" } }, - "node_modules/dot-prop": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", - "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", - "dev": true, - "dependencies": { - "is-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/dpdm": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/dpdm/-/dpdm-3.14.0.tgz", @@ -3444,36 +2934,12 @@ "node": ">= 0.4" } }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/electron": { - "version": "23.3.13", - "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.13.tgz", - "integrity": "sha512-BaXtHEb+KYKLouUXlUVDa/lj9pj4F5kiE0kwFdJV84Y2EU7euIDgPthfKtchhr5MVHmjtavRMIV/zAwEiSQ9rQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, "node_modules/electron-to-chromium": { "version": "1.5.250", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz", @@ -3486,24 +2952,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/es-abstract": { "version": "1.24.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", @@ -3673,13 +3121,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, "node_modules/esbuild": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", @@ -4122,65 +3563,12 @@ "node": ">=0.10.0" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "node": ">=0.8.x" } }, "node_modules/fast-deep-equal": { @@ -4244,15 +3632,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fflate": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", @@ -4503,21 +3882,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -4536,9 +3900,10 @@ } }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -4567,22 +3932,34 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", + "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -4591,36 +3968,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", - "dev": true, - "dependencies": { - "ini": "^1.3.4" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -4661,31 +4008,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4698,6 +4020,23 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/graphology": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz", + "integrity": "sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==", + "dependencies": { + "events": "^3.3.0" + }, + "peerDependencies": { + "graphology-types": ">=0.24.0" + } + }, + "node_modules/graphology-types": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz", + "integrity": "sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==", + "peer": true + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -4800,34 +4139,6 @@ "hermes-estree": "0.25.1" } }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "dev": true - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/husky": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", @@ -4899,15 +4210,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4931,30 +4233,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-ip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", - "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", - "dev": true, - "dependencies": { - "default-gateway": "^6.0.0", - "ipaddr.js": "^1.9.1", - "is-ip": "^3.1.0", - "p-event": "^4.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -4977,24 +4255,6 @@ "node": ">=12" } }, - "node_modules/ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -5074,18 +4334,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "dependencies": { - "ci-info": "^1.5.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -5198,19 +4446,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==", - "dev": true, - "dependencies": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -5220,18 +4455,6 @@ "node": ">=8" } }, - "node_modules/is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "dependencies": { - "ip-regex": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -5256,15 +4479,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5290,36 +4504,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", - "dev": true, - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -5338,15 +4522,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-set": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", @@ -5374,18 +4549,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -5627,13 +4790,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "optional": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -5693,18 +4849,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==", - "dev": true, - "dependencies": { - "package-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5734,9 +4878,9 @@ } }, "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==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -5771,15 +4915,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -5797,31 +4932,6 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -5831,12 +4941,6 @@ "node": ">= 0.4" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5874,19 +4978,10 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -5940,30 +5035,6 @@ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "devOptional": true }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6097,15 +5168,6 @@ "@codemirror/view": "6.38.6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -6199,39 +5261,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6262,97 +5291,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==", - "dev": true, - "dependencies": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true }, - "node_modules/package-json/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/package-json/node_modules/got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==", - "dev": true, - "dependencies": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/package-json/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/package-json/node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6374,12 +5318,6 @@ "node": ">=8" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -6417,12 +5355,6 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6441,15 +5373,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/polytype": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/polytype/-/polytype-0.17.0.tgz", @@ -6468,9 +5391,9 @@ } }, "node_modules/preact": { - "version": "10.27.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", - "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", + "version": "10.28.4", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.4.tgz", + "integrity": "sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -6485,15 +5408,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prettier": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", @@ -6521,15 +5435,6 @@ "node": ">=6.0.0" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -6540,22 +5445,6 @@ "react-is": "^16.13.1" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6585,42 +5474,6 @@ } ] }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -6632,93 +5485,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-devtools": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/react-devtools/-/react-devtools-7.0.1.tgz", - "integrity": "sha512-I2UXoJlsqNeN3uCrlrJw0V+K6HTHU5Q1x+BWJlF99hBC6A/lKhe+IuITZXyKb8BluMReSBYUhUYGkJGgr2KPQQ==", - "dev": true, - "dependencies": { - "cross-spawn": "^5.0.1", - "electron": "^23.1.2", - "internal-ip": "^6.2.0", - "minimist": "^1.2.3", - "react-devtools-core": "7.0.1", - "update-notifier": "^2.1.0" - }, - "bin": { - "react-devtools": "bin.js" - } - }, - "node_modules/react-devtools-core": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-7.0.1.tgz", - "integrity": "sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw==", - "dev": true, - "dependencies": { - "shell-quote": "^1.6.1", - "ws": "^7" - } - }, - "node_modules/react-devtools/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/react-devtools/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/react-devtools/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-devtools/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-devtools/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/react-devtools/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -6822,28 +5588,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", - "dev": true, - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", - "dev": true, - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6873,12 +5617,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -6888,18 +5626,6 @@ "node": ">=4" } }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -6929,24 +5655,6 @@ "node": ">=0.10.0" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", @@ -7077,50 +5785,6 @@ "node": ">=10" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "optional": true - }, - "node_modules/semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==", - "dev": true, - "dependencies": { - "semver": "^5.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -7188,18 +5852,6 @@ "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -7284,13 +5936,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "optional": true - }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -7511,24 +6156,6 @@ "node": ">=4" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7548,18 +6175,6 @@ "dev": true, "peer": true }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7599,155 +6214,11 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==", - "dev": true, - "dependencies": { - "execa": "^0.7.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/term-size/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "dev": true, - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/term-size/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/term-size/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/term-size/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/term-size/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/term-size/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/term-size/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/term-size/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, "node_modules/three": { "version": "0.157.0", "resolved": "https://registry.npmjs.org/three/-/three-0.157.0.tgz", "integrity": "sha512-CeAwQrf4x3z0/e+MC4F+nXLW5t0gh3pw+L6CCBqpHvOq3bGYIgRYub7Pv0j/9wR+d++OiEglyZzWyuSYbwWGOA==" }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", @@ -7819,19 +6290,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -7960,18 +6418,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -7981,15 +6427,6 @@ "node": ">= 10.0.0" } }, - "node_modules/unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/update-browserslist-db": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", @@ -8020,98 +6457,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", - "dev": true, - "dependencies": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/update-notifier/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/update-notifier/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/update-notifier/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-notifier/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -8121,18 +6466,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "dev": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8255,61 +6588,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dev": true, - "dependencies": { - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -8407,59 +6685,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -8543,16 +6768,6 @@ "node": ">=8" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 59d2b33..0768b22 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,7 @@ "release": "bash ./release.sh", "prepare": "husky install", "typecheck": "tsc -noEmit -skipLibCheck && bunx dpdm -T --exit-code circular:1 --warning false --tree false src/main.ts", - "lint": "eslint . --ext .ts,.tsx --fix", - "devtools": "ELECTRON_DISABLE_SANDBOX=1 react-devtools" + "lint": "eslint . --ext .ts,.tsx --fix" }, "keywords": [ "obsidian", @@ -44,7 +43,6 @@ "husky": "^8.0.3", "obsidian": "latest", "prettier": "^3.6.2", - "react-devtools": "^7.0.1", "semver": "^7.5.4", "tslib": "2.4.0", "typescript": "^5.0.5", @@ -55,6 +53,7 @@ "copy-anything": "^3.0.5", "d3": "^7.9.0", "d3-force": "^3.0.0", + "graphology": "^0.26.0", "jotai": "^2.9.1", "lucide-react": "^0.511.0", "observable-slim": "^0.1.6", diff --git a/src/atoms/graphAtoms.ts b/src/atoms/graphAtoms.ts index 55a2d7e..de037a2 100644 --- a/src/atoms/graphAtoms.ts +++ b/src/atoms/graphAtoms.ts @@ -21,11 +21,6 @@ export type GraphSettings = { linkColorOther: string; }; -export type NavHistory = { - backward: Record; - forward: Record; -}; - export type NavIndexHistory = { backward: Record; forward: Record; @@ -45,8 +40,6 @@ export const graphSettingsAtom = atom({ linkColorOther: DEFAULT_SETTING.pluginSetting.linkColorOther, }); -export const navHistoryAtom = atom({ backward: {}, forward: {} }); - export const navIndexHistoryAtom = atomWithReset({ backward: {}, forward: {} }); /** Temporal state turning into selected node. */ @@ -65,12 +58,3 @@ export const graphDataAtom = atom( links: set(linksAtom, newGraph.links), }) ); - -// const graphData = atom(async (get) => { -// const id = get(postId) -// const response = await fetch( -// `https://hacker-news.firebaseio.com/v0/item/${id}.json` -// ) -// const data: PostData = await response.json() -// return data -// }) diff --git a/src/atoms/graphOps.ts b/src/atoms/graphOps.ts index 9f9c659..fc5188c 100644 --- a/src/atoms/graphOps.ts +++ b/src/atoms/graphOps.ts @@ -1,27 +1,6 @@ -import type { NavHistory, NavIndexHistory } from "@/atoms/graphAtoms"; +import type { NavIndexHistory } from "@/atoms/graphAtoms"; import type { Node } from "@/graph/Node"; -export const stackOnHistory = (navHistory: NavHistory, soFarSelected: Node, newSelected: Node) => { - if (!soFarSelected) { - return navHistory; - } - - const shortPaths = getShortestPath(soFarSelected, newSelected); - if (!shortPaths || shortPaths.length <= 1) { - return navHistory; - } - // console.log(`SHORTPATH: ${shortPaths.map((n) => n.path)}`); - - for (const nodePair of consecutivePairs(shortPaths)) { - if (nodePair[0].isChildOf(nodePair[1].path)) { - navHistory.backward[nodePair[0].path] = nodePair[1].path; - navHistory.forward[nodePair[1].path] = nodePair[0].path; - } - } - - return navHistory; -}; - export const stackOnIndexHistory = ( navHistory: NavIndexHistory, soFarSelected: Node, @@ -46,18 +25,6 @@ export const stackOnIndexHistory = ( return navHistory; }; -export const getNavBackward = (navHistory: NavHistory, node: Node): string | undefined => { - function getFirstParent() { - const firstParent = node.links.find((l) => l.target.path === node.path); - if (firstParent) { - return firstParent.source.path; - } - return undefined; - } - - return navHistory.backward[node.path] ?? getFirstParent(); -}; - export const getNavIndexBackward = ( navHistory: NavIndexHistory, node: Node @@ -73,18 +40,6 @@ export const getNavIndexBackward = ( return navHistory.backward[node.idx] ?? getFirstParent(); }; -export const getNavForward = (navHistory: NavHistory, node: Node): string | undefined => { - function getFirstChild() { - const firstChild = node.links.find((l) => l.source.path === node.path); - if (firstChild) { - return firstChild.target.path; - } - return undefined; - } - - return navHistory.forward[node.path] ?? getFirstChild(); -}; - export const getNavIndexForward = (navHistory: NavIndexHistory, node: Node): number | undefined => { function getFirstChild() { const firstChild = node.links.find((l) => l.source.idx === node.idx); diff --git a/src/context.ts b/src/context.ts index 636199e..3caf585 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,4 +1,5 @@ import { createContext } from "react"; + import type { App } from "obsidian"; export const AppContext = createContext(undefined); diff --git a/src/graph/Graph.ts b/src/graph/Graph.ts index 354eb33..3255b42 100644 --- a/src/graph/Graph.ts +++ b/src/graph/Graph.ts @@ -219,7 +219,7 @@ const getMapFromMetaCache = ( ) .filter( (nodePath) => - nodePath.startsWith(baseFolder) && (nodePath.endsWith(".md") || isAvatarImg(nodePath)) + (baseFolder === "" || nodePath.startsWith(baseFolder + "/")) && (nodePath.endsWith(".md") || isAvatarImg(nodePath)) ); }); diff --git a/src/graph/Link.ts b/src/graph/Link.ts index 6cd535d..7234e47 100644 --- a/src/graph/Link.ts +++ b/src/graph/Link.ts @@ -1,4 +1,4 @@ -import { type Node, type ElemType } from "@/graph/Node"; +import { type Node } from "@/graph/Node"; export type LinkCache = Record>; @@ -6,7 +6,6 @@ export class Link { public source: Node & Coords; public target: Node & Coords; public color: string = "green"; - public type: ElemType = "note"; public label?: string; public distance: number = 0; @@ -19,23 +18,6 @@ export class Link { this.target = target; } - /** - * Creates a link index for an array of links - * @param links - * @returns - */ - static createLinkIndex(links: Link[]): Map> { - const linkIndex = new Map>(); - links.forEach((link, index) => { - if (!linkIndex.has(link.source.id)) { - linkIndex.set(link.source.id, new Map()); - } - linkIndex.get(link.source.id)?.set(link.target.id, index); - }); - - return linkIndex; - } - public static compare = (a: Link, b: Link) => { return a.source.id === b.source.id && a.target.id === b.target.id; }; diff --git a/src/graph/Node.ts b/src/graph/Node.ts index 3f15650..9819953 100644 --- a/src/graph/Node.ts +++ b/src/graph/Node.ts @@ -1,10 +1,7 @@ -import type { SectionData } from "@/views/graph/fileGraphMethods"; import type { TAbstractFile } from "obsidian"; import { type Link } from "@/graph/Link"; -export type ElemType = "note" | "para"; - export class Node { public readonly id: string; public readonly name: string; @@ -14,7 +11,6 @@ export class Node { public idx: number; public readonly neighbors: Node[]; - // public readonly parents: Node[]; public inlinkCount: number; public outlinkCount: number; public links: Link[]; @@ -22,15 +18,11 @@ export class Node { public imagePath?: string; public image?: ImageBitmap; public zIndex: number = 10; - public type: ElemType = "note"; public label?: string | null = null; public selected: boolean = false; public expanded: boolean = false; - public imploded: boolean = false; public tags: string[] = []; - public paras: Record = {}; - constructor( name: string, path: string, @@ -82,10 +74,6 @@ export class Node { } } - // addParent(parent: Node) { - // if (!this.parents.includes(parent)) this.parents.push(parent); - // } - // Pushes a link to the node's links array if it doesn't already exist addLink(link: Link, isGlobal: boolean = false) { if (!this.links.some((l) => l.source === link.source && l.target === link.target)) { @@ -107,15 +95,6 @@ export class Node { else return this.neighbors.some((neighbor) => neighbor.id === node); } - /** - * Child links has target pointing to the child. - * @param nodePath - */ - public isParentOf(nodePath: string) { - // return this.parents.some((parent) => parent.path === nodePath); - return this.path !== nodePath && this.links.some((link) => link.target.path === nodePath); - } - public isChildOf(nodePath: string) { return this.path !== nodePath && this.links.some((link) => link.source.path === nodePath); } @@ -123,12 +102,4 @@ export class Node { public static compare = (a: Node, b: Node) => { return a.path === b.path; }; - - public static createNodeIndex(nodes: Node[]) { - const nodeIndex = new Map(); - nodes.forEach((node, index) => { - nodeIndex.set(node.id, index); - }); - return nodeIndex; - } } diff --git a/src/hooks/useGraphForces.ts b/src/hooks/useGraphForces.ts index b7ff4e4..ca161e0 100644 --- a/src/hooks/useGraphForces.ts +++ b/src/hooks/useGraphForces.ts @@ -3,7 +3,6 @@ import { useEffect } from "react"; import type { GraphData } from "./useGraphFiltering"; import type { Graph } from "@/graph/Graph"; -import type { Link } from "@/graph/Link"; import type { MutableRefObject } from "react"; import type { ForceGraphMethods } from "react-force-graph-2d"; @@ -25,15 +24,6 @@ export function useGraphForces( console.debug("Setting Graph forces"); - fg.d3Force( - "link", - d3.forceLink().distance((link: Link) => { - if (link.label === "para") return 15; - if (link.source.imploded || link.target.imploded) return 50; - return 30; - }) - ); - fg.d3Force("collide", d3.forceCollide(12)); fg.d3Force("center", d3.forceCenter(dimensions.width / 2, dimensions.height / 2)); diff --git a/src/hooks/useGraphOperations.ts b/src/hooks/useGraphOperations.ts index e0d2354..68f8901 100644 --- a/src/hooks/useGraphOperations.ts +++ b/src/hooks/useGraphOperations.ts @@ -8,29 +8,25 @@ import { expandNodePathAtom, graphDataAtom, graphNavAtom, - navHistoryAtom, navIndexHistoryAtom, nodeIdxMaxAtom, } from "@/atoms/graphAtoms"; -import { stackOnHistory, stackOnIndexHistory } from "@/atoms/graphOps"; +import { stackOnIndexHistory } from "@/atoms/graphOps"; import { Link } from "@/graph/Link"; import { eventBus } from "@/util/EventBus"; interface UseGraphOperationsProps { getExpandNode: (nodePath: string | undefined) => Promise; - implodeNode: (nodePath: string | undefined) => Promise; zoomToFitNodes: (selectedPath: string | undefined, selectedIndex: number | undefined) => void; } export function useGraphOperations({ getExpandNode, - implodeNode, zoomToFitNodes, }: UseGraphOperationsProps) { const [nodeIdxMax, setNodeIdxMax] = useAtom(nodeIdxMaxAtom); const [selectedNode, setSelectedNode] = useAtom(graphNavAtom); const [expandNodePath, setExpandNodePath] = useAtom(expandNodePathAtom); - const [navHistory, setNavHistory] = useAtom(navHistoryAtom); const [navIndexHistory, setNavIndexHistory] = useAtom(navIndexHistoryAtom); const [graphData, setGraphData] = useAtom(graphDataAtom); @@ -52,13 +48,6 @@ export function useGraphOperations({ setSelectedNode({ selectedPath: node.path, selectedIndex: node.idx }); - const newHistory = stackOnHistory( - navHistory, - graphData.nodes.find((n) => n.path === selectedNode.selectedPath) as Node, - node - ); - setNavHistory(newHistory); - if (selectedNode.selectedIndex !== undefined) { const newIndexHistory = stackOnIndexHistory( navIndexHistory, @@ -144,7 +133,7 @@ export function useGraphOperations({ }; const expandNode = (node: Node) => { - if (node.expanded || node.label === "para") { + if (node.expanded) { signalSelectedNode(node); return; } @@ -152,94 +141,6 @@ export function useGraphOperations({ node.expanded = true; }; - const implodeNodeOp = async (implodedNode: Node) => { - if (!implodedNode) return; - - implodedNode.imploded = true; - const nodePath = implodedNode.path; - const { nodes } = await implodeNode(nodePath); - - const paraInLinks = nodes.map((node) => { - const link = new Link(implodedNode, node); - link.type = "para"; - link.label = "para"; - return link; - }); - - const graphLinks = graphData.links.map((link) => { - if (link.target.idx === implodedNode.idx && link.target.path.contains("#")) { - for (const paraNode of nodes) { - if (link.target.path === paraNode.path) { - link.target = paraNode as Node & Coords; - } - return link; - } - return link; - } - if (link.source.idx !== implodedNode.idx) { - return link; - } - for (const paraNode of nodes) { - const paraTargets = new Set( - paraNode.links.map((l) => - l.target.path.contains("#") - ? l.target.path.substring(0, l.target.path.indexOf("#")) - : l.target.path - ) - ); - if (paraTargets.has(link.target.path.substring(0, link.target.path.length - 3))) { - link.source = paraNode as Node & Coords; - return link; - } - } - return link; - }); - - setGraphData({ - nodes: [...graphData.nodes, ...assignIdx(nodes)], - links: [...graphLinks, ...paraInLinks], - } as Graph); - - signalSelectedNode(implodedNode); - }; - - const unimplodeNodeOp = async (implodedNode: Node) => { - if (!implodedNode) return; - - implodedNode.imploded = false; - const implodedLinks = graphData.links.filter( - (link) => link.label !== "para" || link.source.idx !== implodedNode.idx - ); - implodedLinks.forEach((link) => { - if (link.source.path.startsWith(implodedNode.path)) { - link.source = implodedNode as Node & Coords; - } - }); - - setGraphData({ - nodes: graphData.nodes.filter( - (node) => node.label !== "para" || !node.isChildOf(implodedNode.path) - ), - links: implodedLinks, - } as Graph); - - signalSelectedNode(implodedNode); - }; - - const handleImplode = () => { - const node = graphData.nodes.find((n) => - selectedNode.selectedIndex - ? n.idx === selectedNode.selectedIndex - : n.path === selectedNode.selectedPath - ) as Node; - - if (node.imploded) { - unimplodeNodeOp(node); - } else { - implodeNodeOp(node); - } - }; - const hoverNode = (node: Node) => { if (!node) return; @@ -263,13 +164,9 @@ export function useGraphOperations({ node.selected = node.path === selectedNode.selectedPath; }); graphData.links.forEach((link) => { - if (link.label === "para") { - // skip - } else if (link.target.path === selectedNode.selectedPath) { + if (link.target.path === selectedNode.selectedPath) { link.label = "parent"; - if (link.source.label !== "para") { - link.source.label = "parent"; - } + link.source.label = "parent"; } else if (link.source.path === selectedNode.selectedPath) { link.label = "child"; link.target.label = "child"; @@ -296,7 +193,6 @@ export function useGraphOperations({ assignIdx, expandNode, signalSelectedNode, - handleImplode, hoverNode, }; } diff --git a/src/main.ts b/src/main.ts index aec2653..b25514d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,43 +1,30 @@ +import "@total-typescript/ts-reset"; +import "@total-typescript/ts-reset/dom"; +import { getDefaultStore } from "jotai/index"; +import { RESET } from "jotai/utils"; import { Plugin, TFile } from "obsidian"; +import type { GraphSettings } from "@/atoms/graphAtoms"; import type { LinkCache } from "@/graph/Link"; -import type { App, HoverParent, HoverPopover, PluginManifest, WorkspaceLeaf } from "obsidian"; +import type { App, PluginManifest, WorkspaceLeaf } from "obsidian"; -import { - expandNodePathAtom, - graphDataAtom, - graphNavAtom, - graphSettingsAtom, - navIndexHistoryAtom, - nodeIdxMaxAtom, -} from "@/atoms/graphAtoms"; +import { expandNodePathAtom, graphDataAtom, graphNavAtom, graphSettingsAtom, navIndexHistoryAtom, nodeIdxMaxAtom } from "@/atoms/graphAtoms"; import { config } from "@/config"; import { Graph } from "@/graph/Graph"; import { PluginSettingManager } from "@/SettingManager"; import { deepCompare } from "@/util/deepCompare"; import { eventBus } from "@/util/EventBus"; import { State } from "@/util/State"; - - -import "@total-typescript/ts-reset"; -import "@total-typescript/ts-reset/dom"; import { ReactForceGraphView, VIEW_TYPE_REACT_FORCE_GRAPH } from "@/views/ReactForceGraphView"; import { SettingTab } from "@/views/SettingTab"; -import { getDefaultStore } from "jotai/index"; -import type { GraphSettings } from "@/atoms/graphAtoms"; - - -import { RESET } from "jotai/utils"; - -export default class ForceGraphPlugin extends Plugin implements HoverParent { +export default class ForceGraphPlugin extends Plugin { _resolvedCache: LinkCache; public readonly cacheIsReady: State = new State( - this.app.metadataCache.resolvedLinks !== undefined + this.app.metadataCache.resolvedLinks !== undefined, ); readonly store = getDefaultStore(); - private isCacheReadyOnce = false; /** * we keep a graph here because we dont want to create a new graph every time we open a graph view */ @@ -45,14 +32,11 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { public settingManager: PluginSettingManager; public baseFolder: string = ""; - public mousePosition = { x: 0, y: 0 }; - - public hoverPopover: HoverPopover | null = null; constructor(app: App, manifest: PluginManifest) { super(app, manifest); - console.debug('Main construct start.'); + console.debug("Main construct start."); // this will be initialized in the on cache changed function this._resolvedCache = undefined as unknown as LinkCache; @@ -69,7 +53,7 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { */ async onload() { - console.debug('Main onload start.'); + console.debug("Main onload start."); await this.settingManager.loadSettings(); // get the setting from setting manager @@ -84,12 +68,6 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { // init listeners this.initListeners(); - this.registerDomEvent(window, "mousemove", (event) => { - // set the mouse position - this.mousePosition.x = event.clientX; - this.mousePosition.y = event.clientY; - }); - this.addSettingTab(new SettingTab(this.app, this)); this.registerView(VIEW_TYPE_REACT_FORCE_GRAPH, (leaf) => { @@ -106,7 +84,7 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { this.store.set(expandNodePathAtom, file.path); } } - }) + }), ); this.registerHoverLinkSource("force-graph", { @@ -125,16 +103,13 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { onunload(): void { super.unload(); - // unregister the resolved cache listener - this.app.metadataCache.off("resolved", this.onGraphCacheReady); - this.app.metadataCache.off("resolve", this.onGraphCacheChanged); } private initListeners() { // all files are resolved, so the cache is ready: - this.app.metadataCache.on("resolved", this.onGraphCacheReady); + this.registerEvent(this.app.metadataCache.on("resolved", this.onGraphCacheReady)); // the cache changed: - this.app.metadataCache.on("resolve", this.onGraphCacheChanged); + this.registerEvent(this.app.metadataCache.on("resolve", this.onGraphCacheChanged)); // show open local graph button in file menu this.registerEvent( @@ -142,11 +117,11 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { if (!file) return; menu.addItem((item) => { item - .setTitle("use N-brace") + .setTitle("Use N-brace") .setIcon(config.icon) .onClick(() => this.openGraph()); }); - }) + }), ); } @@ -213,8 +188,6 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { let leafToUse: WorkspaceLeaf; if (targetLeaf !== undefined) { - leafToUse = targetLeaf; - if (filePath !== targetLeaf.view.file?.path) { await targetLeaf.openFile(file); } @@ -297,8 +270,6 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { this._resolvedCache = structuredClone(this.app.metadataCache.resolvedLinks); const pluginSetting = this.settingManager.getSettings().pluginSetting; this.resetGlobalGraph(pluginSetting.baseFolder); - } else { - this.isCacheReadyOnce = true; } }; @@ -314,7 +285,10 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { if (!leaves || !leaves.length) { return; } - const view = leaves[0]!.view as ReactForceGraphView; + const view = leaves[0]!.view; + if (!(view instanceof ReactForceGraphView)) { + return; + } const graph = await view.getNewGraphData(); let maxIdx = 0; @@ -344,7 +318,7 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { private openGraph = async () => { if (!this.app.workspace.lastActiveFile.path.startsWith(this.baseFolder)) { alert( - `Your file isn't under mind map base path ${this.baseFolder}. You can set it up in settings.` + `Your file isn't under base path ${this.baseFolder}. You can set it up in settings.`, ); return; } @@ -365,19 +339,11 @@ export default class ForceGraphPlugin extends Plugin implements HoverParent { let loadingOverlay: HTMLDivElement | undefined = undefined; if (graphView.length > 0) { loadingOverlay = graphView[0]?.view.containerEl.createDiv({ - cls: "loading-overlay", - attr: { - style: - "position: absolute; top: 0; left: 0; width: 100%; height: 100%; " + - "background: rgba(0, 0, 0, 0.5); z-index: 9999; display: flex; align-items: center;", - }, + cls: "nbrace-loading-overlay", }); loadingOverlay?.createEl("h2", { - text: "...loading...", - attr: { - style: - "color: white; font-family: Arial, sans-serif; font-size: 24px; text-align: center;", - }, + cls: "nbrace-loading-text", + text: "Loading…", }); } return loadingOverlay; diff --git a/src/util/ObsidianTheme.ts b/src/util/ObsidianTheme.ts deleted file mode 100644 index a211138..0000000 --- a/src/util/ObsidianTheme.ts +++ /dev/null @@ -1,79 +0,0 @@ -// function getColorFromStylesheet(selector: string, property: string): string | null { -// try { -// for (const sheet of Array.from(document.styleSheets)) { -// const rules = sheet.cssRules ? Array.from(sheet.cssRules) : []; - -// for (const rule of rules) { -// if (rule instanceof CSSStyleRule && rule.selectorText === selector) { -// return rule.style.getPropertyValue(property); -// } -// } -// } -// } catch (e) { -// console.error("Error accessing stylesheets: ", e); -// } -// return null; // Return null if not found -// } - -// Helper to access the current theme in TS -export class ObsidianTheme { - backgroundPrimary: string; - backgroundPrimaryAlt: string; - backgroundSecondary: string; - backgroundSecondaryAlt: string; - - backgroundModifierBorder: string; - backgroundModifierSuccess: string; - backgroundModifierError: string; - - colorAccent: string; - interactiveAccentHover: string; - - textNormal: string; - textMuted: string; - textFaint: string; - - textAccent: string; - - graphNode: string; - graphLine: string; - - // some others missing, but not needed currently - - constructor(root: HTMLElement) { - this.backgroundPrimary = getComputedStyle(root).getPropertyValue("--background-primary").trim(); - this.backgroundPrimaryAlt = getComputedStyle(root) - .getPropertyValue("--background-primary-alt") - .trim(); - this.backgroundSecondary = getComputedStyle(root) - .getPropertyValue("--background-secondary") - .trim(); - this.backgroundSecondaryAlt = getComputedStyle(root) - .getPropertyValue("--background-secondary-alt") - .trim(); - - this.backgroundModifierBorder = getComputedStyle(root) - .getPropertyValue("--background-modifier-border") - .trim(); - this.backgroundModifierSuccess = getComputedStyle(root) - .getPropertyValue("--background-modifier-success") - .trim(); - this.backgroundModifierError = getComputedStyle(root) - .getPropertyValue("--background-modifier-error") - .trim(); - - this.colorAccent = getComputedStyle(root).getPropertyValue("--color-accent").trim(); - - this.textNormal = getComputedStyle(root).getPropertyValue("--text-normal").trim(); - this.textMuted = getComputedStyle(root).getPropertyValue("--text-muted").trim(); - this.textFaint = getComputedStyle(root).getPropertyValue("--text-faint").trim(); - - this.textAccent = getComputedStyle(root).getPropertyValue("--text-accent").trim(); - this.interactiveAccentHover = getComputedStyle(root) - .getPropertyValue("--interactive-accent-hover") - .trim(); - - this.graphNode = getComputedStyle(root).getPropertyValue("--graph-node").trim(); - this.graphLine = getComputedStyle(root).getPropertyValue("--graph-line").trim(); - } -} diff --git a/src/util/awaitof.ts b/src/util/awaitof.ts deleted file mode 100644 index e44e68e..0000000 --- a/src/util/awaitof.ts +++ /dev/null @@ -1,46 +0,0 @@ -type OfReturnType = Readonly< - | { - data: T; - error: undefined; - } - | { - data: undefined; - error: Error; - } ->; - -export async function of(promise: Promise): Promise> { - return Promise.resolve(promise) - .then( - (result): Readonly<{ data: T; error: undefined }> => ({ - data: result, - error: undefined, - }) - ) - .catch((err): Readonly<{ data: undefined; error: Error }> => { - if (typeof err === "undefined") { - err = new Error("Rejection with empty value"); - } - - return { - data: undefined, - error: err as Error, - }; - }); -} - -export function syncOf(operation: () => T): OfReturnType { - try { - const result = operation(); // Execute the synchronous operation - return { - data: result, - error: undefined, - }; - } catch (error) { - // Handle any errors thrown by the operation - return { - data: undefined, - error: error instanceof Error ? error : new Error(String(error)), - }; - } -} diff --git a/src/util/generateUUID.ts b/src/util/generateUUID.ts deleted file mode 100644 index 6743bd9..0000000 --- a/src/util/generateUUID.ts +++ /dev/null @@ -1,12 +0,0 @@ -export function generateUUID() { - let d = new Date().getTime(); - if (typeof performance !== "undefined" && typeof performance.now === "function") { - d += performance.now(); //use high-precision timer if available - } - const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { - const r = (d + Math.random() * 16) % 16 | 0; - d = Math.floor(d / 16); - return (c === "x" ? r : (r & 0x3) | 0x8).toString(16); - }); - return uuid; -} diff --git a/src/util/hexToRGBA.ts b/src/util/hexToRGBA.ts deleted file mode 100644 index 5f7b146..0000000 --- a/src/util/hexToRGBA.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function hexToRGBA(hex: string, alpha: number): string { - // Remove the hash symbol if present - hex = hex.replace("#", ""); - - // Split the hex value into RGB components - const r = parseInt(hex.substring(0, 2), 16); - const g = parseInt(hex.substring(2, 4), 16); - const b = parseInt(hex.substring(4, 6), 16); - - // Create the RGBA color value - const rgba = `rgba(${r}, ${g}, ${b}, ${alpha})`; - return rgba; -} diff --git a/src/util/waitFor.ts b/src/util/waitFor.ts deleted file mode 100644 index 446f4be..0000000 --- a/src/util/waitFor.ts +++ /dev/null @@ -1,90 +0,0 @@ -export function wait(seconds: number): Promise { - return new Promise((resolve) => setTimeout(resolve, seconds * 1000)); -} - -/** - * wait for a condition to be true - */ -export function waitFor( - callback: () => boolean, - { - timeout = 30000, - interval = 100, - }: { - timeout?: number; - interval?: number; - } -): Promise { - const startTime = Date.now(); - return new Promise((resolve) => { - const intervalId = setInterval(() => { - if (callback()) { - clearInterval(intervalId); - resolve(); - } - if (Date.now() - startTime >= timeout) { - // timeout - clearInterval(intervalId); - resolve(); - } - }, interval); - }); -} - -export function waitForStable( - accessor: () => T, - { - timeout = 30000, - minDelay = 100, - interval = 100, - rehitCount = 3, - }: { - /** - * at most wait for timeout milliseconds - */ - timeout?: number; - /** - * start after reaching minDelay - */ - minDelay?: number; - /** - * check every interval milliseconds - */ - interval?: number; - /** - * number of time the value need to be the same before resolving - */ - rehitCount?: number; - } -) { - let previousValue = accessor(); - let hitCount = 0; - const startTime = Date.now(); - return new Promise((resolve) => { - const intervalId = setInterval(() => { - const currentValue = accessor(); - - if (Date.now() - startTime >= timeout) { - // timeout - clearInterval(intervalId); - resolve(undefined); - } - - if (currentValue === previousValue) { - hitCount += 1; - } else { - hitCount = 0; - previousValue = currentValue; - } - - if ( - hitCount >= rehitCount && - currentValue === previousValue && - Date.now() - startTime >= minDelay - ) { - clearInterval(intervalId); - resolve(currentValue); - } - }, interval); - }); -} diff --git a/src/views/ReactForceGraphView.tsx b/src/views/ReactForceGraphView.tsx index d74281f..24abc0a 100644 --- a/src/views/ReactForceGraphView.tsx +++ b/src/views/ReactForceGraphView.tsx @@ -1,4 +1,5 @@ import { getDefaultStore } from "jotai"; +import { RESET } from "jotai/utils"; import { ItemView } from "obsidian"; import { StrictMode, createContext } from "react"; import { createRoot } from "react-dom/client"; @@ -9,13 +10,13 @@ import type { IconName, WorkspaceLeaf } from "obsidian"; import type { Root } from "react-dom/client"; -import { dimensionsAtom } from "@/atoms/graphAtoms"; +import { dimensionsAtom, expandNodePathAtom, graphDataAtom, graphNavAtom, navIndexHistoryAtom, nodeIdxMaxAtom } from "@/atoms/graphAtoms"; import { config } from "@/config"; import { AppContext } from "@/context"; import { Graph } from "@/graph/Graph"; import { tagIndex } from "@/graph/TagIndex"; import { eventBus } from "@/util/EventBus"; -import { getNewLocalGraph, implodeGraph, loadImagesForGraph, loadTagsForGraph } from "@/views/graph/fileGraphMethods"; +import { getNewLocalGraph, loadImagesForGraph, loadTagsForGraph } from "@/views/graph/fileGraphMethods"; import { ReactForceGraph } from "@/views/graph/ReactForceGraph"; @@ -59,9 +60,7 @@ export class ReactForceGraphView extends ItemView { } private renderComponent() { - const initGraph = this.getNewGraphData.bind(this); const expandNodeFun = this.expandNode.bind(this); - const implodeFun = this.implodeNode.bind(this); if (this.root) { this.root.render( @@ -69,9 +68,7 @@ export class ReactForceGraphView extends ItemView { @@ -82,8 +79,20 @@ export class ReactForceGraphView extends ItemView { } async onOpen() { + // Reset all graph state so reopening always shows a fresh graph + this.store.set(graphDataAtom, Graph.createEmpty()); + this.store.set(graphNavAtom, RESET); + this.store.set(navIndexHistoryAtom, RESET); + this.store.set(nodeIdxMaxAtom, 0); + this.root = createRoot(this.containerEl.children[1]!); this.renderComponent(); + + const path = (this.plugin.app.workspace.getActiveFile() + ?? this.plugin.app.workspace.lastActiveFile)?.path; + if (path) { + this.store.set(expandNodePathAtom, path); + } } onResize() { @@ -122,10 +131,6 @@ export class ReactForceGraphView extends ItemView { return graph; } - private async implodeNode(nodePath: string): Promise { - return implodeGraph(this.app, this.plugin, nodePath); - }; - public async getNewGraphData(): Promise { return this.expandNode(this.plugin.app.workspace.getActiveFile()?.path ?? undefined); } diff --git a/src/views/SettingTab.ts b/src/views/SettingTab.ts index eb188e2..ce567ba 100644 --- a/src/views/SettingTab.ts +++ b/src/views/SettingTab.ts @@ -1,11 +1,24 @@ import { rgb } from "d3"; -import { PluginSettingTab, Setting } from "obsidian"; +import { AbstractInputSuggest, PluginSettingTab, Setting, normalizePath } from "obsidian"; import type { GraphSettings } from "@/atoms/graphAtoms"; import type ForceGraphPlugin from "@/main"; import type { Setting as SettingPlugin } from "@/SettingsSchemas"; import type { State } from "@/util/State"; -import type { App } from "obsidian"; +import type { App , TFolder} from "obsidian"; + +class FolderSuggest extends AbstractInputSuggest { + getSuggestions(query: string): TFolder[] { + const lower = query.toLowerCase(); + return this.app.vault.getAllFolders(true).filter((f) => + f.path.toLowerCase().includes(lower) + ); + } + + renderSuggestion(folder: TFolder, el: HTMLElement): void { + el.setText(normalizePath(folder.path)); + } +} import { DEFAULT_SETTING } from "@/SettingManager"; import { eventBus } from "@/util/EventBus"; @@ -41,34 +54,36 @@ export class SettingTab extends PluginSettingTab { containerEl.addClasses(["n-brace-setting-tab"]); new Setting(containerEl) - .setName("Base Folder") + .setName("Base folder") .setDesc( - "The base directory where your notes for exploration live — navigation builds from here." + "Only notes inside this folder will appear in the graph." ) .addText((text) => { text .setPlaceholder(`${DEFAULT_BASE_FOLDER}`) .setValue(String(pluginSetting.baseFolder ?? DEFAULT_BASE_FOLDER)) .onChange(async (value) => { - // check if value is a number if (!value.startsWith("/")) { - // set the error to the input text.inputEl.setCustomValidity("Please enter absolute path (beginning with /)."); this.plugin.settingManager.updateSettings((setting) => { setting.value.pluginSetting.baseFolder = DEFAULT_BASE_FOLDER; }); } else { - // remove the error text.inputEl.setCustomValidity(""); + const clean = ("/" + normalizePath(value)).replace("//", "/"); this.plugin.settingManager.updateSettings((setting) => { - setting.value.pluginSetting.baseFolder = value; + setting.value.pluginSetting.baseFolder = clean; }); - - this.plugin.resetGlobalGraph(value); + this.plugin.resetGlobalGraph(clean); } text.inputEl.reportValidity(); }); text.inputEl.setAttribute("type", "string"); + const folderSuggest = new FolderSuggest(this.app, text.inputEl); + folderSuggest.onSelect((folder) => { + folderSuggest.setValue(("/" + normalizePath(folder.path)).replace("//", "/")); + text.inputEl.dispatchEvent(new Event("input")); + }); }); new Setting(containerEl) @@ -132,13 +147,13 @@ export class SettingTab extends PluginSettingTab { }); new Setting(containerEl) - .setName("Link Color") + .setName("Link color") .setDesc("Choose predefined colors or a custom color for graph links") .addDropdown((dropdown) => dropdown .addOption("light", "Light") .addOption("dark", "Dark") - .addOption("custom", "Custom Color In & Out & Other") + .addOption("custom", "Custom color in & out & other") .setValue(pluginSetting.linkColorTheme) .onChange(async (value: "custom" | "light" | "dark") => { if (value === "dark") { diff --git a/src/views/graph/Drawing.ts b/src/views/graph/Drawing.ts index 592a096..526d2d6 100644 --- a/src/views/graph/Drawing.ts +++ b/src/views/graph/Drawing.ts @@ -17,9 +17,6 @@ export class Drawing { if (link.color === "parent") { return; } - if (link.label === "para") { - return Drawing.drawPara(link, ctx, navDescending); - } // Destructure the source and target coordinates let { x: x1, y: y1 } = navDescending ? link.source : link.target; let { x: x2, y: y2 } = navDescending ? link.target : link.source; @@ -54,9 +51,7 @@ export class Drawing { ? graphSettings.linkColorIn : link.label === "child" ? graphSettings.linkColorOut - : link.label === "para" - ? this.SELECTED_COLOR - : graphSettings.linkColorOther; + : graphSettings.linkColorOther; // Color edge only by tags shared between source and target const sourceTags = link.source.tags ?? []; const targetTags = link.target.tags ?? []; @@ -151,33 +146,6 @@ export class Drawing { ctx.restore(); } - static drawPara( - link: Link, - ctx: CanvasRenderingContext2D, - navDescending: boolean, - ) { - // Destructure the source and target coordinates - const { x: x1, y: y1 } = navDescending ? link.source : link.target; - const { x: x2, y: y2 } = navDescending ? link.target : link.source; - if (!x1) { - return; - } - if (!x2) { - return; - } - - ctx.save(); - ctx.strokeStyle = "rgba(150, 150, 150, 0.6)"; - ctx.lineWidth = 2; - ctx.setLineDash([4, 4]); - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - ctx.setLineDash([]); - ctx.restore(); - } - // Draw a glowing rectangle between two nodes sharing a tag. // Inset at both ends so the rect is fully hidden under the node clouds. static drawTagEdge( @@ -268,10 +236,6 @@ export class Drawing { graphSettings: GraphSettings ) { - if (node.label === 'para') { - return Drawing.drawParagraphNode(node, ctx, globalScale, titleFontSize, graphSettings); - } - const label = node.name.contains(".") ? node.name.substring(0, node.name.length - 3) : node.name; @@ -372,119 +336,6 @@ export class Drawing { } } - static drawParagraphNode( - node: Node & Coords & NodeData, - ctx: CanvasRenderingContext2D, - globalScale: number, - bodyFontSize: number, - graphSettings: GraphSettings - ) { - const text = node.name.contains(".") - ? node.name.substring(0, node.name.length - 3) - : node.name; - const fontSize = bodyFontSize / globalScale; - const lineHeight = fontSize * 1.3; - - ctx.font = `${fontSize}px Sans-Serif`; - - function wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number) { - const words = text.split(" "); - const lines: string[] = []; - let currentLine = ""; - - for (const word of words) { - const testLine = currentLine ? currentLine + " " + word : word; - if (ctx.measureText(testLine).width > maxWidth) { - lines.push(currentLine); - currentLine = word; - } else { - currentLine = testLine; - } - } - - if (currentLine) { - lines.push(currentLine); - } - return lines; - } - - function getWidestString( - ctx: CanvasRenderingContext2D, - strings: string[] - ): number { - let maxWidth = 0; - - for (const s of strings) { - const w = ctx.measureText(s).width; - if (w > maxWidth) { - maxWidth = w; - } - } - - return maxWidth; - } - - const maxWidth = 180 / globalScale; // you can modify this - const lines = wrapText(ctx, text, maxWidth); - - const padding = 6 / globalScale; - const foldSize = 12 / globalScale; - - const width = getWidestString(ctx, lines) + padding * 2; - const height = lines.length * lineHeight + padding * 2; - - const x = node.x - width / 2; - const y = node.y - height / 2; - - const color = - node.selected - ? this.SELECTED_COLOR - : node.label === "parent" - ? graphSettings.linkColorIn - : node.label === "child" - ? graphSettings.linkColorOut - : graphSettings.linkColorOther; - - // --- DRAW PARAGRAPH BOX WITH FOLDED CORNER --- - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.lineTo(x + width - foldSize, y); - ctx.lineTo(x + width, y + foldSize); - ctx.lineTo(x + width, y + height); - ctx.lineTo(x, y + height); - ctx.closePath(); - - ctx.fillStyle = "white"; - ctx.strokeStyle = `rgb(${color})`; - ctx.lineWidth = 2 / globalScale; - ctx.fill(); - ctx.stroke(); - - // --- DRAW THE FOLD --- - ctx.beginPath(); - ctx.moveTo(x + width - foldSize, y); - ctx.lineTo(x + width - foldSize, y + foldSize); - ctx.lineTo(x + width, y + foldSize); - ctx.closePath(); - - ctx.fillStyle = "#f0f0f0"; // folded corner color - ctx.fill(); - ctx.stroke(); - - // --- DRAW TEXT --- - ctx.fillStyle = "black"; - ctx.textAlign = "left"; - ctx.textBaseline = "top"; - - let textY = y + 2 * padding; - for (const line of lines) { - ctx.fillText(line, x + padding, textY); - textY += lineHeight; - } - - node.nodeDims = [width, height]; - } - private static hexToRgba(hex: string, alpha: number): string { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); diff --git a/src/views/graph/GraphControls.css b/src/views/graph/GraphControls.css index c1bc3e1..3de00a5 100644 --- a/src/views/graph/GraphControls.css +++ b/src/views/graph/GraphControls.css @@ -1,4 +1,4 @@ -.pm-graph-controls { +.nbrace-graph-controls { position: absolute; display: grid; gap: 5px; @@ -8,18 +8,18 @@ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } -.right-grid { +.nbrace-right-grid { top: 50px; right: 10px; grid-template-columns: 1fr 1fr; /* 2 columns */ } -.first-row { +.nbrace-first-row { top: 50px; left: 130px; } -.pm-graph-controls button { +.nbrace-graph-controls button { display: flex; align-items: center; justify-content: center; @@ -30,11 +30,11 @@ font-size: 16px; } -.pm-graph-controls button:hover { +.nbrace-graph-controls button:hover { background: var(--color-base-60); } -.slider-control { +.nbrace-slider-control { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr; @@ -42,12 +42,12 @@ color: var(--color-base-00); } -.slider-control input[type="range"] { +.nbrace-slider-control input[type="range"] { width: 100px; cursor: pointer; } -.slider-value { +.nbrace-slider-value { position: absolute; top: -20px; /* Above the slider */ left: 50%; @@ -58,7 +58,7 @@ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } -.pm-tag-list { +.nbrace-tag-list { position: absolute; top: 50px; left: 10px; @@ -74,13 +74,13 @@ pointer-events: auto; } -.pm-tag-left { +.nbrace-tag-left { display: flex; flex-direction: column; gap: 2px; } -.pm-tag-minimize-btn { +.nbrace-tag-minimize-btn { display: flex; align-items: center; justify-content: center; @@ -93,18 +93,18 @@ align-self: flex-start; } -.pm-tag-minimize-btn:hover { +.nbrace-tag-minimize-btn:hover { color: rgba(0, 0, 0, 0.7); } -.pm-tag-filter-panel { +.nbrace-tag-filter-panel { display: flex; flex-direction: column; gap: 2px; } -.pm-tag-node-panel { +.nbrace-tag-node-panel { display: flex; flex-direction: column; gap: 2px; @@ -113,7 +113,7 @@ min-width: 0; } -.pm-tag-node-panel-header { +.nbrace-tag-node-panel-header { font-size: 11px; font-weight: 600; color: gray; @@ -121,52 +121,52 @@ margin-bottom: 16px; } -.pm-tag-node-items { +.nbrace-tag-node-items { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; } -.pm-tag-node-items::-webkit-scrollbar { +.nbrace-tag-node-items::-webkit-scrollbar { width: 4px; } -.pm-tag-node-items::-webkit-scrollbar-thumb { +.nbrace-tag-node-items::-webkit-scrollbar-thumb { background: #2563eb; border-radius: 2px; } -.pm-tag-pill--neighbor { +.nbrace-tag-pill--neighbor { opacity: 0.55; } -.pm-tag-items { +.nbrace-tag-items { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; } -.pm-tag-items::-webkit-scrollbar { +.nbrace-tag-items::-webkit-scrollbar { width: 4px; } -.pm-tag-items::-webkit-scrollbar-track { +.nbrace-tag-items::-webkit-scrollbar-track { background: #2563eb; } -.pm-tag-items::-webkit-scrollbar-thumb { +.nbrace-tag-items::-webkit-scrollbar-thumb { background: #2563eb; border-radius: 2px; } -.pm-tag-search-wrap { +.nbrace-tag-search-wrap { position: relative; margin-bottom: 2px; } -.pm-tag-search { +.nbrace-tag-search { width: 100%; box-sizing: border-box; padding: 2px 20px 2px 5px; @@ -176,7 +176,7 @@ background: rgba(255, 255, 255, 0.9); } -.pm-tag-search-clear { +.nbrace-tag-search-clear { position: absolute; right: 3px; top: 50%; @@ -190,7 +190,7 @@ cursor: pointer; } -.pm-tag-item { +.nbrace-tag-item { display: flex; align-items: center; gap: 4px; @@ -198,18 +198,18 @@ cursor: pointer; } -.pm-tag-item input[type="checkbox"] { +.nbrace-tag-item input[type="checkbox"] { margin: 0; cursor: pointer; flex-shrink: 0; } -.pm-tag-item input[type="checkbox"]:disabled { +.nbrace-tag-item input[type="checkbox"]:disabled { cursor: default; opacity: 0.5; } -.pm-tag-pill { +.nbrace-tag-pill { border-radius: 8px; padding: 1px 6px; color: white; @@ -217,27 +217,27 @@ flex: 1; } -.pm-tag-select-all-label { +.nbrace-tag-select-all-label { color: gray; } -.pm-tag-name { +.nbrace-tag-name { color: var(--color-base-00); flex: 1; } -.pm-tag-count { +.nbrace-tag-count { color: var(--color-base-40); font-size: 11px; } -.pm-tag-color-toggle { +.nbrace-tag-color-toggle { display: flex; align-items: center; gap: 4px; } -.pm-tag-color-btn { +.nbrace-tag-color-btn { flex: 1; padding: 2px 6px; font-size: 11px; @@ -248,11 +248,30 @@ color: var(--color-base-00); } -.pm-tag-color-btn.active { +.nbrace-tag-color-btn.active { background: var(--color-base-40); color: white; } -.pm-tag-color-btn:hover:not(.active) { +.nbrace-tag-color-btn:hover:not(.active) { background: rgba(0, 0, 0, 0.06); } + +.nbrace-loading-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; +} + +.nbrace-loading-text { + color: white; + font-size: 24px; + text-align: center; +} diff --git a/src/views/graph/GraphControls.tsx b/src/views/graph/GraphControls.tsx index 8d90cee..7dca0fa 100644 --- a/src/views/graph/GraphControls.tsx +++ b/src/views/graph/GraphControls.tsx @@ -1,3 +1,4 @@ +import { useAtomValue } from "jotai/react"; import { ArrowDown, ArrowLeft, @@ -9,8 +10,8 @@ import { Sunrise, } from "lucide-react"; import React, { useEffect, useState } from "react"; + import "@/views/graph/GraphControls.css"; -import { useAtomValue } from "jotai/react"; import { graphSettingsAtom } from "@/atoms/graphAtoms"; @@ -22,7 +23,6 @@ interface GraphControlsProps { onDirectionToggle: () => void; isDescending: boolean; onMaxPathLengthChange: (maxPathLength: number) => void; - onImplode: () => void; } export const GraphControls: React.FC = ({ @@ -33,7 +33,6 @@ export const GraphControls: React.FC = ({ onDirectionToggle, isDescending, onMaxPathLengthChange, - onImplode, }) => { const [isHidden, setIsHidden] = useState(false); const graphSettings = useAtomValue(graphSettingsAtom); @@ -63,7 +62,7 @@ export const GraphControls: React.FC = ({ }, [maxPathLength, onMaxPathLengthChange]); return ( -
+
@@ -84,7 +83,7 @@ export const GraphControls: React.FC = ({ -
+
diff --git a/src/views/graph/ReactForceGraph.tsx b/src/views/graph/ReactForceGraph.tsx index eb3b984..6c8d853 100644 --- a/src/views/graph/ReactForceGraph.tsx +++ b/src/views/graph/ReactForceGraph.tsx @@ -23,16 +23,12 @@ import { TagList, UNTAGGED } from "@/views/graph/TagList"; interface GraphComponentProps { data?: Graph; - getInitialGraph: () => Promise; getExpandNode: (nodePath: string | undefined) => Promise; - implodeNode: (nodePath: string | undefined) => Promise; titleFontSize: number; } export const ReactForceGraph: React.FC = ({ - getInitialGraph, getExpandNode, - implodeNode, titleFontSize, }) => { const fgRef = useRef(undefined); @@ -52,14 +48,11 @@ export const ReactForceGraph: React.FC = ({ setGraphData, selectedNode, navIndexHistory, - assignIdx, expandNode, signalSelectedNode, - handleImplode, hoverNode, } = useGraphOperations({ getExpandNode, - implodeNode, zoomToFitNodes, }); @@ -100,13 +93,6 @@ export const ReactForceGraph: React.FC = ({ setGraphData({ nodes: graphData.nodes, links: graphData.links } as Graph); }, [graphData, setGraphData]); - // After tag mutations are committed, force a canvas redraw (simulation may be idle) - useEffect(() => { - if (nodeTagVersion > 0) { - (fgRef.current as any)?.refresh?.(); - } - }, [nodeTagVersion]); - const handleToggleTag = useCallback((tag: string) => { setUncheckedTags((prev) => { const next = new Set(prev); @@ -191,7 +177,7 @@ export const ReactForceGraph: React.FC = ({ const nodes = tagFilteredData.nodes as (Node & Coords & NodeData)[]; for (const node of nodes) { - if (node.label === "para" || node.x === undefined || node.y === undefined) continue; + if (node.x === undefined || node.y === undefined) continue; const nodeTags = (node.tags ?? []).filter((t) => !uncheckedTags.has(t)); if (nodeTags.length === 0) continue; @@ -242,7 +228,7 @@ export const ReactForceGraph: React.FC = ({ const allNodes = tagFilteredData.nodes as (Node & Coords & NodeData)[]; const visibleNodes = allNodes.filter( - (n) => n.label !== "para" && n.x !== undefined && n.y !== undefined + (n) => n.x !== undefined && n.y !== undefined ); const getHalfDiag = (n: Node & Coords & NodeData) => @@ -306,17 +292,8 @@ export const ReactForceGraph: React.FC = ({ // D3 force configuration useGraphForces(fgRef, dimensions, graphData, setGraphData); - // Initialize graph on mount + // Focus container for keyboard navigation on mount useEffect(() => { - const initGraph = async () => { - const graph = await getInitialGraph(); - console.debug(`Init Graph data starting with ${graph.rootPath}`); - assignIdx(graph.nodes); - setGraphData(graph); - }; - initGraph(); - - // Focus container for keyboard navigation containerRef.current?.focus(); }, []); @@ -385,7 +362,6 @@ export const ReactForceGraph: React.FC = ({ onDirectionToggle={navigation.handleDirectionToggle} isDescending={navigation.isDescending} onMaxPathLengthChange={setMaxPathLength} - onImplode={handleImplode} />
); diff --git a/src/views/graph/TagList.tsx b/src/views/graph/TagList.tsx index 8be8409..19bda87 100644 --- a/src/views/graph/TagList.tsx +++ b/src/views/graph/TagList.tsx @@ -204,32 +204,32 @@ export const TagList: React.FC = ({ nodes, links, selectedNodePath const showNodePanel = selectedNodePath && (ownTags.length > 0 || neighborOnlyTags.length > 0); return ( -
-
-
+
+
+
+ >Cloudy tags + >Edgy tags
{!isMinimized && ( -
-
+
+
= ({ nodes, links, selectedNodePath onKeyDown={(e) => { if (e.key === "Enter") handleSelectAll(); }} /> {search && ( - + )}
-