diff --git a/package-lock.json b/package-lock.json index dac89ba..6a90784 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "eslint": "^9.39.1", "eslint-plugin-vue": "^10.6.1", "glob": "^13.0.6", + "mermaid": "^11.16.0", "prettier": "^3.6.2", "sass-embedded": "^1.99.0", "sharp": "^0.34.5", @@ -25,6 +26,19 @@ "vuepress-theme-hope": "^2.0.0-rc.106" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "dev": true, + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz", @@ -92,6 +106,13 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", + "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", + "dev": true, + "license": "MIT" + }, "node_modules/@bufbuild/protobuf": { "version": "2.11.0", "resolved": "https://registry.npmmirror.com/@bufbuild/protobuf/-/protobuf-2.11.0.tgz", @@ -99,6 +120,13 @@ "dev": true, "license": "(Apache-2.0 AND BSD-3-Clause)" }, + "node_modules/@chevrotain/types": { + "version": "11.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.10.0.tgz", @@ -815,6 +843,24 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true + }, + "node_modules/@iconify/utils": { + "version": "3.1.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@iconify/utils/-/utils-3.1.4.tgz", + "integrity": "sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "import-meta-resolve": "^4.2.0" + } + }, "node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@img/colour/-/colour-1.1.0.tgz", @@ -2078,6 +2124,16 @@ } } }, + "node_modules/@mermaid-js/parser": { + "version": "1.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@mermaid-js/parser/-/parser-1.2.0.tgz", + "integrity": "sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@chevrotain/types": "~11.1.2" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.4", "resolved": "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", @@ -2817,6 +2873,288 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dev": true, + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-random/-/d3-random-3.0.4.tgz", + "integrity": "sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.13", "resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.13.tgz", @@ -2845,6 +3183,13 @@ "@types/node": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/hash-sum": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/@types/hash-sum/-/hash-sum-1.0.2.tgz", @@ -3258,6 +3603,17 @@ "dev": true, "license": "ISC" }, + "node_modules/@upsetjs/venn.js": { + "version": "2.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", + "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "d3-selection": "^3.0.0", + "d3-transition": "^3.0.1" + } + }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.6", "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-6.0.6.tgz", @@ -4864,6 +5220,16 @@ "node": ">=0.8" } }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dev": true, + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/create-codepen": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/create-codepen/-/create-codepen-2.0.2.tgz", @@ -4939,6 +5305,564 @@ "dev": true, "license": "MIT" }, + "node_modules/cytoscape": { + "version": "3.34.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/cytoscape/-/cytoscape-3.34.0.tgz", + "integrity": "sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "dev": true, + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dev": true, + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "dev": true, + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.14", + "resolved": "https://mirrors.cloud.tencent.com/npm/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz", + "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, + "node_modules/dayjs": { + "version": "1.11.21", + "resolved": "https://mirrors.cloud.tencent.com/npm/dayjs/-/dayjs-1.11.21.tgz", + "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", @@ -4974,6 +5898,16 @@ "dev": true, "license": "MIT" }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz", @@ -5059,6 +5993,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.4.12", + "resolved": "https://mirrors.cloud.tencent.com/npm/dompurify/-/dompurify-3.4.12.tgz", + "integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==", + "dev": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz", @@ -5128,6 +6071,17 @@ "node": ">=4" } }, + "node_modules/es-toolkit": { + "version": "1.49.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/es-toolkit/-/es-toolkit-1.49.0.tgz", + "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==", + "dev": true, + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.27.7", "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.7.tgz", @@ -5791,6 +6745,13 @@ "node": ">=6.0" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "dev": true, + "license": "MIT" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", @@ -6032,6 +6993,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6042,6 +7014,16 @@ "node": ">=0.8.19" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmmirror.com/is-extendable/-/is-extendable-0.1.1.tgz", @@ -6205,6 +7187,33 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.47", + "resolved": "https://mirrors.cloud.tencent.com/npm/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", @@ -6215,6 +7224,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==", + "dev": true + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", @@ -6225,6 +7240,13 @@ "node": ">=0.10.0" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "dev": true, + "license": "MIT" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", @@ -6588,6 +7610,13 @@ "node": ">=8" } }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -6713,6 +7742,18 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmmirror.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", @@ -6742,6 +7783,36 @@ "dev": true, "license": "MIT" }, + "node_modules/mermaid": { + "version": "11.16.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/mermaid/-/mermaid-11.16.0.tgz", + "integrity": "sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.1.2", + "@iconify/utils": "^3.0.2", + "@mermaid-js/parser": "^1.2.0", + "@types/d3": "^7.4.3", + "@upsetjs/venn.js": "^2.0.0", + "cytoscape": "^3.33.3", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.14", + "dayjs": "^1.11.20", + "dompurify": "^3.3.3", + "es-toolkit": "^1.45.1", + "katex": "^0.16.45", + "khroma": "^2.1.0", + "marked": "^16.3.0", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" + } + }, "node_modules/micromark-util-character": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz", @@ -7087,6 +8158,13 @@ "node": ">=6" } }, + "node_modules/package-manager-detector": { + "version": "1.7.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/package-manager-detector/-/package-manager-detector-1.7.0.tgz", + "integrity": "sha512-xg1eHpwYL/D/HEdWw2goFZP6vV0FH7W+PZ5rFkGjdIDLtxq7EkzBUeT3m+lndYCt8wKbmofUu1MUdMCXkCk9ZQ==", + "dev": true, + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", @@ -7153,6 +8231,13 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", @@ -7256,6 +8341,24 @@ "node": ">=10.13.0" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { "version": "8.5.14", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.14.tgz", @@ -7573,6 +8676,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "dev": true, + "license": "Unlicense" + }, "node_modules/rolldown": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/rolldown/-/rolldown-1.0.0.tgz", @@ -7614,6 +8724,26 @@ "dev": true, "license": "MIT" }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.2.tgz", @@ -8334,6 +9464,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.4.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/stylis/-/stylis-4.4.0.tgz", + "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", + "dev": true, + "license": "MIT" + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", @@ -8389,6 +9526,16 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.16.tgz", @@ -8459,6 +9606,16 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-dedent": { + "version": "2.3.0", + "resolved": "https://mirrors.cloud.tencent.com/npm/ts-dedent/-/ts-dedent-2.3.0.tgz", + "integrity": "sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", @@ -8743,6 +9900,19 @@ "dev": true, "license": "MIT" }, + "node_modules/uuid": { + "version": "14.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/uuid/-/uuid-14.0.1.tgz", + "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, "node_modules/varint": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/varint/-/varint-6.0.0.tgz", diff --git a/package.json b/package.json index 4a2014d..2651ed6 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "eslint": "^9.39.1", "eslint-plugin-vue": "^10.6.1", "glob": "^13.0.6", + "mermaid": "^11.16.0", "prettier": "^3.6.2", "sass-embedded": "^1.99.0", "sharp": "^0.34.5", diff --git a/src/.vuepress/theme.ts b/src/.vuepress/theme.ts index 556eee9..45e9afb 100644 --- a/src/.vuepress/theme.ts +++ b/src/.vuepress/theme.ts @@ -85,6 +85,7 @@ export default hopeTheme( imgSize: true, // 启用图片尺寸设置 include: true, // 启用文件包含 mark: true, // 启用标记高亮 + mermaid: true, // 启用Mermaid图表 plantuml: true, // 启用PlantUML图表 spoiler: true, // 启用剧透标记 diff --git a/src/work/project-summary/智能巡视/README.md b/src/work/project-summary/智能巡视/README.md new file mode 100644 index 0000000..450cbe0 --- /dev/null +++ b/src/work/project-summary/智能巡视/README.md @@ -0,0 +1,11 @@ +--- +title: 智能巡视 +index: false +icon: fa6-solid:binoculars +category: + - 工作 + - 项目总结 +--- + + + diff --git a/src/work/project-summary/algosimulation-打包与交付记录.md b/src/work/project-summary/智能巡视/algosimulation-打包与交付记录.md similarity index 100% rename from src/work/project-summary/algosimulation-打包与交付记录.md rename to src/work/project-summary/智能巡视/algosimulation-打包与交付记录.md diff --git a/src/work/project-summary/pr7050-package-startup-flow.md b/src/work/project-summary/智能巡视/pr7050-package-startup-flow.md similarity index 100% rename from src/work/project-summary/pr7050-package-startup-flow.md rename to src/work/project-summary/智能巡视/pr7050-package-startup-flow.md diff --git a/src/work/project-summary/pr7050-panoramic-monitoring-data-flow.md b/src/work/project-summary/智能巡视/pr7050-panoramic-monitoring-data-flow.md similarity index 100% rename from src/work/project-summary/pr7050-panoramic-monitoring-data-flow.md rename to src/work/project-summary/智能巡视/pr7050-panoramic-monitoring-data-flow.md diff --git a/src/work/project-summary/pr7950-java-package-startup-flow.md b/src/work/project-summary/智能巡视/pr7950-java-package-startup-flow.md similarity index 100% rename from src/work/project-summary/pr7950-java-package-startup-flow.md rename to src/work/project-summary/智能巡视/pr7950-java-package-startup-flow.md diff --git a/src/work/project-summary/tcpclienttester-打包与启动工作总结.md b/src/work/project-summary/智能巡视/tcpclienttester-打包与启动工作总结.md similarity index 100% rename from src/work/project-summary/tcpclienttester-打包与启动工作总结.md rename to src/work/project-summary/智能巡视/tcpclienttester-打包与启动工作总结.md diff --git a/src/work/project-summary/录像回放权限配置说明.md b/src/work/project-summary/智能巡视/录像回放权限配置说明.md similarity index 100% rename from src/work/project-summary/录像回放权限配置说明.md rename to src/work/project-summary/智能巡视/录像回放权限配置说明.md diff --git a/src/work/project-summary/服务总线学习.md b/src/work/project-summary/智能巡视/服务总线学习.md similarity index 100% rename from src/work/project-summary/服务总线学习.md rename to src/work/project-summary/智能巡视/服务总线学习.md diff --git a/src/work/project-summary/权限管理系统文档.md b/src/work/project-summary/智能巡视/权限管理系统文档.md similarity index 100% rename from src/work/project-summary/权限管理系统文档.md rename to src/work/project-summary/智能巡视/权限管理系统文档.md diff --git a/src/work/project-summary/算法管理平台/README.md b/src/work/project-summary/算法管理平台/README.md new file mode 100644 index 0000000..55787a8 --- /dev/null +++ b/src/work/project-summary/算法管理平台/README.md @@ -0,0 +1,11 @@ +--- +title: 算法管理平台 +index: false +icon: fa6-solid:diagram-project +category: + - 工作 + - 项目总结 +--- + + + diff --git a/src/work/project-summary/算法管理平台/平台认证与鉴权流程.md b/src/work/project-summary/算法管理平台/平台认证与鉴权流程.md new file mode 100644 index 0000000..52e995f --- /dev/null +++ b/src/work/project-summary/算法管理平台/平台认证与鉴权流程.md @@ -0,0 +1,391 @@ +--- +title: 平台认证与鉴权流程 +icon: fa6-solid:shield-halved +date: 2026-07-14 +category: + - 工作 + - 项目总结 + - 算法管理平台 +tag: + - 认证 + - 鉴权 + - JWT + - 权限管理 +--- + +本文依据当前工程中的实际实现整理,重点覆盖: + +- `sunri-service-auth-spi`:认证、Token、权限和资源的 Service Bus 接口定义。 +- `sunri-service-auth`:账号校验、JWT 签发、实时库会话、角色权限位和资源关系实现。 +- `sunri-web-center`:HTTP 登录入口、请求拦截器、`@ApiRight` 接口鉴权和菜单过滤。 + +本文描述的是平台现状,不把它替换成 Spring Security/RBAC 的标准实现。 + + + +## 1. 先看结论 + +平台的核心授权链不是“用户 -> 角色 -> 权限记录 -> 接口”这种普通关联表模型,而是: + +```text +用户 -> 单个角色 -> 角色的 64 位权限位图 -> 权限位集合 + | + +-> 菜单所需权限位 + +-> API 所需权限位 +``` + +登录成功后,角色的 `ROLEAUTHORITY` 位图会被拆成 `Set`。这个权限集合会同时: + +1. 返回给 Web Center; +2. 写入实时库的登录会话; +3. 首次校验受保护请求时缓存在 Web Center 本地; +4. 用于过滤菜单; +5. 用于 API 请求鉴权。 + +## 2. 核心关系图 + +```mermaid +flowchart LR + U["用户
userinfo"] + UG["用户组
usergroup"] + R["角色
userroleinfo"] + RG["角色组
rolegroup"] + RB["角色权限位图
ROLEAUTHORITY: Long"] + P["权限位定义
cfgauthconst
right + desc"] + PT["权限类型
cfgauthtype"] + + RES["统一权限资源
cfgauthresource"] + MENU["菜单/页面/功能点
type != 2"] + API["API 接口
type = 2"] + RR["资源-权限位关联
cfgresourceright
resourceId + right"] + COMP["前端组件配置
cfgcomponent"] + + SESSION["实时库登录会话
token / right / clientIp / TTL"] + CACHE["Web Center 本地权限缓存
token -> UserAuthority"] + ACCESS["登录访问规则
cfgauthaccess
黑白名单/IP/MAC/时间"] + SYSCFG["认证策略配置
usersysteminfo / JKSysCfg"] + + U -->|"ROLESOFUSER = ROLEID
当前实现为单角色"| R + U -.->|"USERGROUPID"| UG + R -->|"rolegroup"| RG + R -->|"保存"| RB + RB -->|"RightBitUtils.extract"| P + P -->|"authtypeid"| PT + PT -.->|"rolegroupid / mutex"| RG + + RES --> MENU + RES --> API + MENU -->|"id = resourceId"| RR + API -->|"id = resourceId"| RR + RR -->|"right"| P + MENU -.->|"componentid = componentCode"| COMP + + U -->|"登录"| SESSION + P -->|"权限集合写入 right 字段"| SESSION + SESSION -->|"checkToken 后建立"| CACHE + ACCESS -->|"登录前置校验"| U + SYSCFG -->|"密码、锁定、并发登录、待机退出"| SESSION +``` + +### 2.1 主干关系 + +| 起点 | 终点 | 实际字段/规则 | 说明 | +|---|---|---|---| +| 用户 `userinfo` | 角色 `userroleinfo` | `ROLESOFUSER = ROLEID` | 当前实现是一个用户一个角色,不是用户角色多对多。 | +| 角色 | 权限位 | `ROLEAUTHORITY` | 使用 `Long` 位图保存角色拥有的权限。 | +| 权限位定义 | 权限类型 | `cfgauthconst.authtypeid` | 权限类型用于分类、角色组适配和互斥校验。 | +| 菜单/API | 权限位 | `cfgresourceright(resourceId, right)` | 一个资源可以关联多个权限位。 | +| 菜单/API | 统一资源表 | `cfgauthresource.type` | 菜单和 API 共用一张资源表。 | +| 菜单 | 前端组件 | `componentid` | 组件配置补充菜单的组件类型和展示配置。 | + +### 2.2 权限位如何保存 + +假设角色拥有权限位 `{0, 2, 5}`,其位图概念上是: + +```text +二进制: 100101 +十进制: 37 +``` + +数据库在 `userroleinfo.ROLEAUTHORITY` 中保存合并后的 `Long`;登录时通过 `RightBitUtils.extract()` 拆成整数集合。`cfgauthconst` 保存每个权限位的名称和分类信息,而不是给每个角色保存一条关联记录。 + +特殊权限使用 `-1`。项目中大量管理接口使用 `@ApiRight(value = -1)`,表示需要特殊/超级权限。 + +## 3. 登录认证流程 + +浏览器登录入口是 Web Center 的 `POST /api/doLogin`,Web Center 再通过 Service Bus 调用 `AuthorityVerifyService.loginVerify()`。 + +```mermaid +sequenceDiagram + autonumber + participant F as 前端 + participant WC as Web Center
UserLoginController + participant LH as LoginAuthorityHandler + participant BUS as Service Bus + participant AUTH as AuthorityVerifyService + participant PIPE as LoginVerify 登录管线 + participant DB as 权限数据库 + participant RT as 实时库会话 + participant LC as Web Center 本地缓存 + + F->>WC: POST /api/doLogin
username + password + loginDuration + WC->>WC: 解密用户名、验证码等 Web 前置处理 + WC->>LH: 执行登录处理管线 + LH->>BUS: loginVerify(request) + BUS->>AUTH: AuthorityVerifyServiceImpl.loginVerify + AUTH->>PIPE: VerifyModel(LOGIN).verify + PIPE->>DB: 检查访问规则、用户、状态、密码、有效期、角色 + DB-->>PIPE: ROLEAUTHORITY + PIPE->>PIPE: 拆分为 Set rights + PIPE->>PIPE: 签发 JWT + PIPE->>RT: 写入 token、rights、clientIp、loginLimit、TTL + RT-->>AUTH: 会话写入成功 + AUTH-->>LH: token + rights + expire + standbyTimes + LH->>LC: 清除旧权限缓存、建立待机心跳状态 + LH-->>WC: 登录结果 + WC->>WC: 使用平台安全算法加密返回 Token + WC-->>F: UserLoginVo +``` + +### 3.1 auth 服务登录管线 + +`LoginVerify` 的主处理顺序为: + +```text +UniqueLoginHandler(条件启用) + -> AuthAccessLoginHandler + -> APPLoginHandler + -> BrowserLoginHandler + -> HMILoginHandler +``` + +浏览器登录内部还会按顺序执行多个 `BrowserLoginPipeline`,主要完成: + +- 查询用户是否存在; +- 从用户角色读取权限位图并拆出权限集合; +- 检查账号状态、锁定状态、账号有效期和允许访问时间; +- 检查临时密码、普通密码、初始密码和密码有效期; +- 检查最大会话数和并发登录策略; +- 根据用户或系统配置切换 UKey、指纹等高级认证模式。 + +任一步设置 `errorStr` 后,后续成功逻辑不会签发有效 Token。 + +### 3.2 登录访问规则 + +`cfgauthaccess` 不属于角色权限,但属于完整认证关系: + +```mermaid +flowchart LR + REQ["登录请求
loginModel / IP / MAC / 时间"] + RULE["cfgauthaccess
黑名单或白名单"] + INT["规则解释器"] + PASS{"允许登录?"} + NEXT["账号和密码验证"] + DENY["返回登录失败"] + + REQ --> RULE --> INT --> PASS + PASS -->|是| NEXT + PASS -->|否| DENY +``` + +规则解释器支持日、月、星期、小时、时间段、IPv4 和 MAC 地址等条件。 + +## 4. 登录会话与 Token + +JWT 是客户端凭证,实时库记录才是平台在线会话。会话主要包含: + +| 字段 | 用途 | +|---|---| +| `username` | 当前登录用户。 | +| `token` | 当前会话 JWT。 | +| `right` | 登录时得到的权限位集合 JSON。 | +| `clientIp` | 当前来源或同源 IP 集合。 | +| `loginLimit` | 并发登录策略。 | +| `clientNum` | 同一会话下客户端数量。 | +| `interrupt` | HMI 登录中断标记。 | +| TTL | 剩余在线时间。 | + +单会话通常按以下键保存: + +```text +{pcname}:{paname}:token:{username} +``` + +允许多源同时在线时,使用 Token 的 MD5 作为会话键,并维护用户到 Token 哈希的集合: + +```text +{pcname}:{paname}:token:{md5(token)} +{pcname}:{paname}:bucket:{username} +``` + +`expandOnlineDuration()` 只延长实时库 TTL,且不超过平台配置的最大时长;它不会重新签发 JWT。 + +## 5. 普通请求的 Token 校验 + +Web Center 使用自己的 Spring MVC 拦截器体系,不使用 Spring Security 的 `SecurityContext`。 + +```mermaid +sequenceDiagram + autonumber + participant F as 前端 + participant JI as JwtAuthenticationInterceptor + participant AS as AssembleHandle + participant JWT as Web JwtUtils + participant LC as 本地 UserAuthority 缓存 + participant AUTH as Auth checkToken + participant RT as 实时库会话 + participant CTRL as Controller + + F->>JI: HTTP 请求 + 平台 Token + JI->>AS: 组装 ValidateObject / ReqUser + AS->>JWT: 解密并解析 JWT + JWT-->>AS: username / position / expire + AS->>LC: 按 Token 查询 UserAuthority + alt 缓存未命中 + AS->>AUTH: checkToken(username, token, clientIp) + AUTH->>RT: 查询会话、TTL、权限、IP策略 + RT-->>AUTH: 会话数据 + AUTH-->>AS: token + rights + expire + AS->>LC: 缓存 UserAuthority + end + AS->>AS: 比较请求 Token 与缓存 Token
按配置检查 IP 和过期时间 + AS->>JI: Token 校验通过 + JI->>CTRL: 进入接口权限校验或 Controller +``` + +`@PassToken` 用于无需登录的接口,例如登录和验证码。`@ApiRight(ctrl = false)` 表示接口不做权限位校验,但不等同于 `@PassToken`。 + +## 6. API 接口鉴权 + +API 权限不是 `@PreAuthorize`,而是平台的 `@ApiRight`、API资源表和 Web Center 校验管线共同完成。 + +### 6.1 API 资源初始化 + +应用启动时,`DefaultAPIAuthorityManager` 扫描 Controller 方法: + +1. 跳过带 `@PassToken` 的公共接口; +2. 读取请求路径、HTTP 方法和 Java 方法引用; +3. 读取 `@ApiRight` 的默认权限位和 `ctrl`; +4. 通过 `AuthorityResourcesService.updateAPI()` 同步到 `cfgauthresource(type = 2)`; +5. 从 `cfgresourceright` 加载管理员配置后的最终权限位; +6. 建立“Java 方法引用 -> API 所需权限集合”的内存映射。 + +### 6.2 运行时校验 + +```mermaid +flowchart LR + REQ["已通过 Token 校验的请求"] + M["Controller Method"] + AM["APIAuthorityManager
方法引用 -> 所需权限位"] + UR["用户权限集合
UserAuthority.userRights"] + INTER{"权限集合有交集?"} + OK["允许访问"] + NO["拒绝并记录越权审计"] + + REQ --> M --> AM --> INTER + UR --> INTER + INTER -->|是| OK + INTER -->|否| NO +``` + +系统支持两种执行模式: + +- 缓存鉴权:`AuthorityCacheValidateHandle` 直接比较 Web Center 缓存的用户权限与 API 权限。 +- 无缓存鉴权:`AuthorityRightCheckHandle` 调用 `AuthorityVerifyService.rightVerify()`,由 auth 服务比较权限。 + +判断逻辑是“用户权限集合”和“API 所需权限集合”存在交集即可通过,并非必须拥有接口配置的全部权限位。 + +## 7. 菜单鉴权 + +菜单和 API 使用相同的资源-权限位映射,但菜单鉴权主要决定前端资源是否可见或可用。 + +```mermaid +sequenceDiagram + participant F as 前端 + participant WC as AuthorityResourceController + participant RH as AuthorityResourceHandler + participant AUTH as AuthorityResourcesService + participant DB as cfgauthresource + cfgresourceright + participant LC as UserAuthority 缓存 + + F->>WC: GET /get/user/menu + WC->>RH: getAuthMenus(username, token) + RH->>LC: 读取用户权限集合 + RH->>AUTH: queryMenuTree(username) + AUTH->>DB: 查询菜单树及每个菜单所需权限 + DB-->>AUTH: 菜单 + rights + ctrl + hide + AUTH-->>RH: 完整菜单树 + RH->>RH: 用户权限与菜单权限求交集 + RH->>RH: 根据 ctrl/hide/invalidHide 删除无权节点 + RH-->>F: 用户可访问菜单树 +``` + +需要注意:auth 服务的 `queryMenuTree()` 返回菜单及其所需权限;真正结合当前登录用户权限进行过滤的逻辑在 Web Center 的 `AuthorityResourceHandler`。 + +## 8. 登出与权限变更 + +### 8.1 登出 + +`UserLogoutController -> LogoutHandler -> AuthorityVerifyService.loginOut()`: + +- 单客户端会话:删除实时库 Token 会话; +- 多客户端共享会话:减少 `clientNum`; +- 多源并存会话:同时清理用户的 Token 哈希集合; +- Web Center 清除本地 `UserAuthority` 和待机心跳状态。 + +浏览器关闭、待机超时、管理员踢出和部分用户配置变更也会触发登出或重新登录通知。 + +### 8.2 权限变更何时生效 + +角色权限在登录时写入实时库和 Web Center 缓存,因此修改角色权限后,代码会通知受影响用户重新登录。重新登录后才会完整刷新: + +```text +角色 ROLEAUTHORITY + -> 登录时拆分 rights + -> 实时库会话 right + -> Web Center UserAuthority.userRights + -> 菜单/API 鉴权 +``` + +## 9. 容易漏掉的关系 + +除了“用户、角色、权限位、菜单、API”,项目中还存在以下认证相关关系: + +| 关系 | 是否属于核心授权 | 作用 | +|---|---|---| +| 用户组 `usergroup` | 否 | 用户业务分类,通过 `USERGROUPID` 关联,不直接生成权限。 | +| 角色组 | 辅助 | 对角色分类,并限制可配置的权限类型。 | +| 权限类型 `cfgauthtype` | 辅助 | 对权限位分类,配置互斥关系和适用角色组。 | +| 登录访问规则 `cfgauthaccess` | 认证前置 | 按平台、IP、MAC、日期和时间执行黑白名单。 | +| 用户系统配置 | 认证策略 | 控制密码复杂度、失败锁定、账号有效期、并发登录和待机退出。 | +| 菜单组件 `cfgcomponent` | 展示辅助 | 为菜单补充前端组件类型、样式和数据配置。 | +| 实时库 Token 会话 | 核心认证 | 保存在线状态、权限快照、来源 IP 和 TTL。 | +| Web Center 权限缓存 | 核心鉴权 | 减少每个请求调用 auth 服务的次数。 | +| 双机通知 | 运行保障 | 同步 Token 检查结果、踢出状态和重新登录通知。 | +| 超级用户 | 特殊分支 | 权限来源可由配置提供,管理菜单和接口常使用权限位 `-1`。 | +| CAS/统一登录 | 特殊认证 | 通过 `genTokenFromCas()`、`unionLogin()` 接入平台会话体系。 | + +`CfgRightMenuResource` 实体目前没有对应 Mapper 或实际调用,不能作为当前生效关系理解;实际资源与权限位关系以 `cfgresourceright` 为准。 + +## 10. 当前实现边界 + +- auth SPI 是 Service Bus 接口;面向浏览器的 REST 接口位于 Web Center。 +- 平台使用自定义 MVC 拦截链,不使用 Spring Security。 +- 用户当前只关联一个角色;角色权限使用 64 位位图,权限位数量受该模型限制。 +- 菜单权限解决前端可见性,API 权限负责服务端访问控制;不能只配置菜单权限而不配置 API 权限。 +- `checkToken()` 在多源模式优先按 Token 哈希查会话,在其他情况下会回退按用户名查会话。Web Center 随后还会比较返回 Token 和请求 Token,但直接调用 auth SPI 时应理解这一现有行为。 +- 在线续期延长的是实时库会话 TTL,不是标准 OAuth2 Refresh Token 流程。 + +## 11. 关键代码入口 + +| 功能 | 代码入口 | +|---|---| +| auth SPI | `AuthorityVerifyService`、`AuthorityResourcesService`、`UserRoleService` | +| 登录实现 | `AuthorityVerifyServiceImpl.loginVerify()`、`LoginVerify` | +| 用户和角色权限加载 | `QueryBrowserLoginUserExistence`、`RightBitUtils` | +| Token 会话 | `LoginVerify.writeTokenToRedis()`、`AuthorityVerifyServiceImpl.checkToken()` | +| Web 登录入口 | `UserLoginController`、`LoginAuthorityHandler` | +| Web Token 拦截 | `JwtInterceptorConfig`、`AssembleHandle` | +| API 权限 | `ApiRight`、`DefaultAPIAuthorityManager`、`AuthorityCacheValidateHandle`、`AuthorityRightCheckHandle` | +| 菜单权限 | `AuthorityResourcesServiceImpl`、`MenuResourcesHandler`、`AuthorityResourceHandler` | +