From 5cf1777c000e6714720bdfcb400992793b580afc Mon Sep 17 00:00:00 2001 From: tianyaxiang Date: Sun, 2 Feb 2025 17:45:05 +0800 Subject: [PATCH] =?UTF-8?q?add=20Mermaid=20=E6=B5=81=E7=A8=8B=E5=9B=BE?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 980 ++++++++++++++++++ src/components/editor/WechatEditor.tsx | 48 +- .../editor/components/EditorPreview.tsx | 127 ++- src/components/editor/utils/copy-handler.tsx | 198 ++++ src/lib/markdown/mermaid-init.ts | 177 ++++ src/lib/markdown/renderer.ts | 66 ++ src/lib/markdown/types.ts | 1 + 8 files changed, 1548 insertions(+), 50 deletions(-) create mode 100644 src/components/editor/utils/copy-handler.tsx create mode 100644 src/lib/markdown/mermaid-init.ts diff --git a/package.json b/package.json index 37c90b7..b6d411a 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "katex": "^0.16.21", "lucide-react": "^0.474.0", "marked": "^15.0.6", + "mermaid": "^11.4.1", "next": "14.1.0", "next-themes": "^0.4.4", "prismjs": "^1.29.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec19471..bd7f4bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ importers: marked: specifier: ^15.0.6 version: 15.0.6 + mermaid: + specifier: ^11.4.1 + version: 11.4.1 next: specifier: 14.1.0 version: 14.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -139,6 +142,30 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@braintree/sanitize-url@7.1.1': + resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + + '@chevrotain/cst-dts-gen@11.0.3': + resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + + '@chevrotain/gast@11.0.3': + resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} + + '@chevrotain/regexp-to-ast@11.0.3': + resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} + + '@chevrotain/types@11.0.3': + resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} + + '@chevrotain/utils@11.0.3': + resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -154,6 +181,12 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.2.1': + resolution: {integrity: sha512-0/7J7hk4PqXmxo5PDBDxmnecw5PxklZJfNjIVG9FM0mEfVrvfudS22rYWsqVk6gR3UJ/mSYS90X4R3znXnqfNA==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -176,6 +209,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@mermaid-js/parser@0.3.0': + resolution: {integrity: sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==} + '@next/env@14.1.0': resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==} @@ -825,6 +861,102 @@ packages: '@tiptap/starter-kit@2.11.3': resolution: {integrity: sha512-UGKS6+TA/7yMGqHBK5S/Kxis6iy3Tw0gvVg1EkYHUmkApLJypE87wUMkIeLeD9dd5+2WkxWcYMhC9R3ByjulBg==} + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.6': + resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.0': + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.8': + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + '@types/katex@0.16.7': resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} @@ -858,9 +990,17 @@ packages: '@types/react@18.3.18': resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -944,6 +1084,14 @@ packages: resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.0.3: + resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -985,10 +1133,23 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} @@ -1004,13 +1165,184 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.31.0: + resolution: {integrity: sha512-zDGn1K/tfZwEnoGOcHc0H4XazqAAXAuDpcYw9mUnUjATjqljyCNGJv8uEvbvxGaGHaVshxMecyl6oc6uKzRfbw==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.11: + resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} @@ -1020,6 +1352,9 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dompurify@3.2.4: + resolution: {integrity: sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1109,9 +1444,16 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + globals@15.14.0: + resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} + engines: {node: '>=18'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1120,12 +1462,23 @@ packages: resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} engines: {node: '>=14.18.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1182,10 +1535,26 @@ packages: resolution: {integrity: sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==} hasBin: true + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + langium@3.0.0: + resolution: {integrity: sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==} + engines: {node: '>=16.0.0'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -1199,6 +1568,13 @@ packages: linkifyjs@4.2.0: resolution: {integrity: sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==} + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.castarray@4.4.0: resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} @@ -1228,6 +1604,11 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true + marked@13.0.3: + resolution: {integrity: sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==} + engines: {node: '>= 18'} + hasBin: true + marked@15.0.6: resolution: {integrity: sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==} engines: {node: '>= 18'} @@ -1243,6 +1624,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + mermaid@11.4.1: + resolution: {integrity: sha512-Mb01JT/x6CKDWaxigwfZYuYmDZ6xtrNwNlidKZwkSrDaY9n90tdrJTV5Umk+wP1fZscGptmKFXHsXMDEVZ+Q6A==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1263,6 +1647,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -1341,6 +1731,12 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.9: + resolution: {integrity: sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1356,6 +1752,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + pathe@2.0.2: + resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1371,6 +1770,15 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -1556,15 +1964,27 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + rope-sequence@1.3.4: resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -1634,6 +2054,9 @@ packages: babel-plugin-macros: optional: true + stylis@4.3.5: + resolution: {integrity: sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==} + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -1663,6 +2086,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} @@ -1670,6 +2096,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -1684,6 +2114,9 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -1725,6 +2158,30 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -1760,6 +2217,32 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@antfu/install-pkg@0.4.1': + dependencies: + package-manager-detector: 0.2.9 + tinyexec: 0.3.2 + + '@antfu/utils@0.7.10': {} + + '@braintree/sanitize-url@7.1.1': {} + + '@chevrotain/cst-dts-gen@11.0.3': + dependencies: + '@chevrotain/gast': 11.0.3 + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/gast@11.0.3': + dependencies: + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/regexp-to-ast@11.0.3': {} + + '@chevrotain/types@11.0.3': {} + + '@chevrotain/utils@11.0.3': {} + '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 @@ -1777,6 +2260,21 @@ snapshots: '@floating-ui/utils@0.2.9': {} + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.2.1': + dependencies: + '@antfu/install-pkg': 0.4.1 + '@antfu/utils': 0.7.10 + '@iconify/types': 2.0.0 + debug: 4.4.0 + globals: 15.14.0 + kolorist: 1.8.0 + local-pkg: 0.5.1 + mlly: 1.7.4 + transitivePeerDependencies: + - supports-color + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1803,6 +2301,10 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@mermaid-js/parser@0.3.0': + dependencies: + langium: 3.0.0 + '@next/env@14.1.0': {} '@next/swc-darwin-arm64@14.1.0': @@ -2454,6 +2956,125 @@ snapshots: '@tiptap/extension-text-style': 2.11.3(@tiptap/core@2.11.3(@tiptap/pm@2.11.3)) '@tiptap/pm': 2.11.3 + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.6': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.0': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.8': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.0 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.6 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.0 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/geojson@7946.0.16': {} + '@types/katex@0.16.7': {} '@types/linkify-it@5.0.0': {} @@ -2486,8 +3107,13 @@ snapshots: '@types/prop-types': 15.7.14 csstype: 3.1.3 + '@types/trusted-types@2.0.7': + optional: true + '@types/use-sync-external-store@0.0.6': {} + acorn@8.14.0: {} + ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -2565,6 +3191,20 @@ snapshots: chalk@5.2.0: {} + chevrotain-allstar@0.3.1(chevrotain@11.0.3): + dependencies: + chevrotain: 11.0.3 + lodash-es: 4.17.21 + + chevrotain@11.0.3: + dependencies: + '@chevrotain/cst-dts-gen': 11.0.3 + '@chevrotain/gast': 11.0.3 + '@chevrotain/regexp-to-ast': 11.0.3 + '@chevrotain/types': 11.0.3 + '@chevrotain/utils': 11.0.3 + lodash-es: 4.17.21 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -2603,8 +3243,20 @@ snapshots: commander@4.1.1: {} + commander@7.2.0: {} + commander@8.3.0: {} + confbox@0.1.8: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + crelt@1.0.6: {} cross-spawn@7.0.6: @@ -2617,18 +3269,216 @@ snapshots: csstype@3.1.3: {} + cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.0): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.31.0 + + cytoscape-fcose@2.2.0(cytoscape@3.31.0): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.31.0 + + cytoscape@3.31.0: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.11: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + data-uri-to-buffer@4.0.1: {} + dayjs@1.11.13: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + defaults@1.0.4: dependencies: clone: 1.0.4 + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + detect-node-es@1.1.0: {} didyoumean@1.2.2: {} dlv@1.1.3: {} + dompurify@3.2.4: + optionalDependencies: + '@types/trusted-types': 2.0.7 + eastasianwidth@0.2.0: {} electron-to-chromium@1.5.88: {} @@ -2721,18 +3571,30 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + globals@15.14.0: {} + graceful-fs@4.2.11: {} + hachure-fill@0.5.2: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 human-signals@4.3.1: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} inherits@2.0.4: {} + internmap@1.0.1: {} + + internmap@2.0.3: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -2779,8 +3641,24 @@ snapshots: dependencies: commander: 8.3.0 + khroma@2.1.0: {} + kleur@3.0.3: {} + kolorist@1.8.0: {} + + langium@3.0.0: + dependencies: + chevrotain: 11.0.3 + chevrotain-allstar: 0.3.1(chevrotain@11.0.3) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -2791,6 +3669,13 @@ snapshots: linkifyjs@4.2.0: {} + local-pkg@0.5.1: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + lodash-es@4.17.21: {} + lodash.castarray@4.4.0: {} lodash.isplainobject@4.0.6: {} @@ -2821,6 +3706,8 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + marked@13.0.3: {} + marked@15.0.6: {} mdurl@2.0.0: {} @@ -2829,6 +3716,31 @@ snapshots: merge2@1.4.1: {} + mermaid@11.4.1: + dependencies: + '@braintree/sanitize-url': 7.1.1 + '@iconify/utils': 2.2.1 + '@mermaid-js/parser': 0.3.0 + '@types/d3': 7.4.3 + cytoscape: 3.31.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.31.0) + cytoscape-fcose: 2.2.0(cytoscape@3.31.0) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.11 + dayjs: 1.11.13 + dompurify: 3.2.4 + katex: 0.16.21 + khroma: 2.1.0 + lodash-es: 4.17.21 + marked: 13.0.3 + roughjs: 4.6.6 + stylis: 4.3.5 + ts-dedent: 2.2.0 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -2844,6 +3756,15 @@ snapshots: minipass@7.1.2: {} + mlly@1.7.4: + dependencies: + acorn: 8.14.0 + pathe: 2.0.2 + pkg-types: 1.3.1 + ufo: 1.5.4 + + ms@2.1.3: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -2928,6 +3849,10 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.9: {} + + path-data-parser@0.1.0: {} + path-key@3.1.1: {} path-key@4.0.0: {} @@ -2939,6 +3864,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + pathe@2.0.2: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -2947,6 +3874,19 @@ snapshots: pirates@4.0.6: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.2 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + postcss-import@15.1.0(postcss@8.5.1): dependencies: postcss: 8.5.1 @@ -3173,14 +4113,27 @@ snapshots: reusify@1.0.4: {} + robust-predicates@3.0.2: {} + rope-sequence@1.3.4: {} + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rw@1.3.3: {} + safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -3236,6 +4189,8 @@ snapshots: client-only: 0.0.1 react: 18.3.1 + stylis@4.3.5: {} + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -3289,6 +4244,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tinyexec@0.3.2: {} + tippy.js@6.3.7: dependencies: '@popperjs/core': 2.11.8 @@ -3297,6 +4254,8 @@ snapshots: dependencies: is-number: 7.0.0 + ts-dedent@2.2.0: {} + ts-interface-checker@0.1.13: {} tslib@2.8.1: {} @@ -3305,6 +4264,8 @@ snapshots: uc.micro@2.1.0: {} + ufo@1.5.4: {} + undici-types@6.19.8: {} universalify@2.0.1: {} @@ -3336,6 +4297,25 @@ snapshots: util-deprecate@1.0.2: {} + uuid@9.0.1: {} + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.0.8: {} + w3c-keyname@2.2.8: {} wcwidth@1.0.1: diff --git a/src/components/editor/WechatEditor.tsx b/src/components/editor/WechatEditor.tsx index 9581978..f4011b9 100644 --- a/src/components/editor/WechatEditor.tsx +++ b/src/components/editor/WechatEditor.tsx @@ -18,6 +18,7 @@ import { Copy, Clock, Type, Trash2 } from 'lucide-react' import { useLocalStorage } from '@/hooks/use-local-storage' import { codeThemes, type CodeThemeId } from '@/config/code-themes' import '@/styles/code-themes.css' +import { copyHandler } from './utils/copy-handler' // 计算阅读时间(假设每分钟阅读300字) const calculateReadingTime = (text: string): string => { @@ -185,46 +186,15 @@ export default function WechatEditor() { // 处理复制 const handleCopy = useCallback(async () => { - try { - const htmlContent = getPreviewContent() - const tempDiv = document.createElement('div') - tempDiv.innerHTML = htmlContent - const plainText = tempDiv.textContent || tempDiv.innerText - - await navigator.clipboard.write([ - new ClipboardItem({ - 'text/html': new Blob([htmlContent], { type: 'text/html' }), - 'text/plain': new Blob([plainText], { type: 'text/plain' }) - }) - ]) - - toast({ - title: "复制成功", - description: "已复制预览内容", - duration: 2000 - }) - return true - } catch (err) { - console.error('Copy error:', err) - try { - await navigator.clipboard.writeText(previewContent) - toast({ - title: "复制成功", - description: "已复制预览内容(仅文本)", - duration: 2000 - }) - return true - } catch (fallbackErr) { - toast({ - variant: "destructive", - title: "复制失败", - description: "无法访问剪贴板,请检查浏览器权限", - action: 重试, - }) - return false - } + // 获取预览容器中的实际内容 + const previewContainer = document.querySelector('.preview-content') + if (!previewContainer) { + return copyHandler(window.getSelection(), previewContent, { toast }) } - }, [previewContent, toast, getPreviewContent]) + + // 使用实际渲染后的内容 + return copyHandler(window.getSelection(), previewContainer.innerHTML, { toast }) + }, [previewContent, toast]) // 手动保存 const handleSave = useCallback(() => { diff --git a/src/components/editor/components/EditorPreview.tsx b/src/components/editor/components/EditorPreview.tsx index 8f34163..6ed35e8 100644 --- a/src/components/editor/components/EditorPreview.tsx +++ b/src/components/editor/components/EditorPreview.tsx @@ -2,8 +2,9 @@ import { cn } from '@/lib/utils' import { PREVIEW_SIZES, type PreviewSize } from '../constants' import { Loader2, ZoomIn, ZoomOut, Maximize2, Minimize2 } from 'lucide-react' import { templates } from '@/config/wechat-templates' -import { useState, useRef, useEffect } from 'react' +import { useState, useRef, useEffect, useMemo } from 'react' import { type CodeThemeId } from '@/config/code-themes' +import { initMermaid } from '@/lib/markdown/mermaid-init' import '@/styles/code-themes.css' interface EditorPreviewProps { @@ -28,6 +29,107 @@ export function EditorPreview({ const [zoom, setZoom] = useState(100) const [isFullscreen, setIsFullscreen] = useState(false) const isScrolling = useRef(false) + const contentRef = useRef('') + const renderTimeoutRef = useRef() + const stableKeyRef = useRef(`preview-${Date.now()}`) + + // Add useEffect to handle content changes and Mermaid initialization + useEffect(() => { + if (!isConverting && previewContent) { + // Clear any pending render timeout + if (renderTimeoutRef.current) { + window.clearTimeout(renderTimeoutRef.current) + } + + // Set a new timeout to render after content has settled + renderTimeoutRef.current = window.setTimeout(() => { + requestAnimationFrame(() => { + initMermaid().catch(error => { + console.error('Failed to initialize mermaid:', error) + }) + }) + }, 100) // Wait for 100ms after last content change + } + + // Cleanup timeout on unmount + return () => { + if (renderTimeoutRef.current) { + window.clearTimeout(renderTimeoutRef.current) + } + } + }, [isConverting, previewContent]) + + // Add useEffect to handle theme changes + useEffect(() => { + if (document.querySelector('div.mermaid')) { + if (renderTimeoutRef.current) { + window.clearTimeout(renderTimeoutRef.current) + } + + renderTimeoutRef.current = window.setTimeout(() => { + requestAnimationFrame(() => { + initMermaid().catch(error => { + console.error('Failed to initialize mermaid after theme change:', error) + }) + }) + }, 100) + } + }, [codeTheme]) + + // Add useEffect to handle copy events + useEffect(() => { + const handleCopy = async (e: ClipboardEvent) => { + const selection = window.getSelection() + if (!selection) return + + const selectedNode = selection.anchorNode?.parentElement + if (!selectedNode) return + + // 检查是否在 mermaid 图表内 + const mermaidElement = selectedNode.closest('.mermaid') + if (mermaidElement) { + e.preventDefault() + + // 获取渲染后的 SVG 元素 + const svgElement = mermaidElement.querySelector('svg') + if (svgElement) { + try { + // 创建一个临时的 div 来包含 SVG + const container = document.createElement('div') + container.appendChild(svgElement.cloneNode(true)) + + // 准备 HTML 和纯文本格式 + const htmlContent = container.innerHTML + const plainText = mermaidElement.querySelector('.mermaid-source')?.textContent || '' + + // 尝试复制为 HTML(保留图表效果) + await navigator.clipboard.write([ + new ClipboardItem({ + 'text/html': new Blob([htmlContent], { type: 'text/html' }), + 'text/plain': new Blob([plainText], { type: 'text/plain' }) + }) + ]) + } catch (error) { + // 如果复制 HTML 失败,退回到复制源代码 + console.error('Failed to copy as HTML:', error) + const sourceText = mermaidElement.querySelector('.mermaid-source')?.textContent || '' + if (e.clipboardData) { + e.clipboardData.setData('text/plain', sourceText) + } + } + } else { + // 如果找不到 SVG,退回到复制源代码 + const sourceText = mermaidElement.querySelector('.mermaid-source')?.textContent || '' + if (e.clipboardData) { + e.clipboardData.setData('text/plain', sourceText) + } + } + } + } + + document.addEventListener('copy', handleCopy) + return () => document.removeEventListener('copy', handleCopy) + }, []) const handleZoomIn = () => { setZoom(prev => Math.min(prev + 10, 200)) @@ -47,6 +149,17 @@ export function EditorPreview({ } } + // 使用 memo 包装预览内容 + const PreviewContent = useMemo(() => ( +
t.id === selectedTemplate)?.styles + )}> +
+
+ ), [previewContent, selectedTemplate]) + return (
t.id === selectedTemplate)?.styles, `code-theme-${codeTheme}` )} - key={codeTheme} + key={stableKeyRef.current} >
预览效果
@@ -138,15 +251,7 @@ export function EditorPreview({ 正在生成预览...
- ) : ( -
t.id === selectedTemplate)?.styles - )}> -
-
- )} + ) : PreviewContent}
diff --git a/src/components/editor/utils/copy-handler.tsx b/src/components/editor/utils/copy-handler.tsx new file mode 100644 index 0000000..351bbef --- /dev/null +++ b/src/components/editor/utils/copy-handler.tsx @@ -0,0 +1,198 @@ +import React from "react" + +declare global { + interface Window { + mermaid: { + init: (config: any, nodes: NodeListOf) => Promise + } + } +} + +type ToastFunction = { + (props: { + title?: string + description?: string + action?: React.ReactElement + duration?: number + variant?: "default" | "destructive" + }): void +} + +interface CopyHandlerOptions { + toast: ToastFunction +} + +/** + * 处理 Mermaid 图表的复制 + */ +async function handleMermaidCopy(mermaidElement: Element): Promise { + const svgElement = mermaidElement.querySelector('svg') + if (!svgElement) return false + + // 获取原始的 Mermaid 代码 + const originalCode = mermaidElement.getAttribute('data-source') || '' + + // 创建一个临时的 canvas 来转换 SVG 为图片 + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d') + if (!ctx) throw new Error('Failed to get canvas context') + + // 设置 canvas 尺寸为 SVG 的实际尺寸 + const svgRect = svgElement.getBoundingClientRect() + canvas.width = svgRect.width + canvas.height = svgRect.height + + // 创建图片对象 + const img = new Image() + const svgData = new XMLSerializer().serializeToString(svgElement) + const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' }) + const url = URL.createObjectURL(svgBlob) + + // 等待图片加载 + await new Promise((resolve, reject) => { + img.onload = resolve + img.onerror = reject + img.src = url + }) + + // 绘制图片到 canvas + ctx.fillStyle = '#FFFFFF' + ctx.fillRect(0, 0, canvas.width, canvas.height) + ctx.drawImage(img, 0, 0) + + // 转换为 PNG + const pngBlob = await new Promise((resolve) => { + canvas.toBlob((blob) => resolve(blob!), 'image/png', 1.0) + }) + + // 清理 + URL.revokeObjectURL(url) + + // 复制为图片、HTML 和原始文本 + await navigator.clipboard.write([ + new ClipboardItem({ + 'image/png': pngBlob, + 'text/html': new Blob([svgElement.outerHTML], { type: 'text/html' }), + 'text/plain': new Blob([originalCode], { type: 'text/plain' }) + }) + ]) + + return true +} + +/** + * 处理预览内容的复制 + */ +async function handlePreviewCopy(previewContent: string): Promise { + // 创建临时容器来处理内容 + const tempDiv = document.createElement('div') + tempDiv.innerHTML = previewContent + + // 等待所有 Mermaid 图表渲染完成 + const mermaidElements = tempDiv.querySelectorAll('.mermaid') + if (mermaidElements.length > 0) { + try { + // 确保 mermaid 已经初始化 + if (typeof window.mermaid !== 'undefined') { + // 重新初始化所有图表 + await window.mermaid.init(undefined, mermaidElements) + } + } catch (error) { + console.error('Mermaid rendering error:', error) + } + } + + // 处理所有的 Mermaid 图表 + const mermaidDiagrams = tempDiv.querySelectorAll('.mermaid svg') + mermaidDiagrams.forEach(svg => { + const container = svg.closest('.mermaid') + if (container) { + // 保存原始的 SVG 内容 + const originalSvg = svg.cloneNode(true) + container.innerHTML = '' + container.appendChild(originalSvg) + } + }) + + // 获取处理后的 HTML 内容 + const htmlContent = tempDiv.innerHTML + const plainText = tempDiv.textContent || tempDiv.innerText + + // 复制到剪贴板 + await navigator.clipboard.write([ + new ClipboardItem({ + 'text/html': new Blob([htmlContent], { type: 'text/html' }), + 'text/plain': new Blob([plainText], { type: 'text/plain' }) + }) + ]) + + return true +} + +/** + * 复制处理器 + */ +export async function copyHandler( + selection: Selection | null, + previewContent: string, + options: CopyHandlerOptions +): Promise { + const { toast } = options + + try { + // 检查是否有选中的 Mermaid 图表 + if (selection && !selection.isCollapsed) { + const selectedNode = selection.anchorNode?.parentElement + if (selectedNode) { + const mermaidElement = selectedNode.closest('.mermaid') + if (mermaidElement) { + const success = await handleMermaidCopy(mermaidElement) + if (success) { + toast({ + title: "复制成功", + description: "已复制图表(支持粘贴为图片或源代码)", + duration: 2000 + }) + return true + } + } + } + } + + // 复制整个预览内容 + const success = await handlePreviewCopy(previewContent) + if (success) { + toast({ + title: "复制成功", + description: "已复制预览内容", + duration: 2000 + }) + return true + } + + return false + } catch (err) { + console.error('Copy error:', err) + try { + await navigator.clipboard.writeText(previewContent) + toast({ + title: "复制成功", + description: "已复制预览内容(仅文本)", + duration: 2000 + }) + return true + } catch (fallbackErr) { + toast({ + variant: "destructive", + title: "复制失败", + description: "无法访问剪贴板,请检查浏览器权限", + action: ( + + ) + }) + return false + } + } +} \ No newline at end of file diff --git a/src/lib/markdown/mermaid-init.ts b/src/lib/markdown/mermaid-init.ts new file mode 100644 index 0000000..49cccb4 --- /dev/null +++ b/src/lib/markdown/mermaid-init.ts @@ -0,0 +1,177 @@ +import mermaid from 'mermaid' +import type { MermaidConfig } from 'mermaid' + +let initialized = false + +// Initialize mermaid with default configuration +const config: MermaidConfig = { + startOnLoad: false, + theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default', + securityLevel: 'loose' as const, + fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Microsoft YaHei", sans-serif', + themeVariables: { + 'fontSize': '16px', + 'fontFamily': '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Microsoft YaHei", sans-serif', + 'primaryColor': document.documentElement.classList.contains('dark') ? '#7c3aed' : '#4f46e5', + 'primaryTextColor': document.documentElement.classList.contains('dark') ? '#fff' : '#000', + 'primaryBorderColor': document.documentElement.classList.contains('dark') ? '#7c3aed' : '#4f46e5', + 'lineColor': document.documentElement.classList.contains('dark') ? '#666' : '#999', + 'textColor': document.documentElement.classList.contains('dark') ? '#fff' : '#333' + }, + pie: { + textPosition: 0.75, + useMaxWidth: true + } +} + +// 缓存已渲染的图表 +const renderedDiagrams = new Map() + +// Generate a valid ID for mermaid diagrams +function generateMermaidId() { + return `mermaid-${Math.floor(Math.random() * 100000)}` +} + +// Clean and format mermaid definition +function cleanMermaidDefinition(text: string): string { + return text + .replace(/"/g, '"') + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/ /g, ' ') + .replace(/[""]/g, '"') // 替换中文引号 + .replace(/:/g, ':') // 替换中文冒号 + .split('\n') + .map(line => line.trim()) + .filter(line => line) // 移除空行 + .join('\n') + .trim() +} + +// Process pie chart definition +function processPieChart(definition: string): string { + // 如果已经有 showData,直接返回 + if (definition.includes('showData')) { + return definition + } + + // 移除开头的 pie 并添加 showData + const lines = definition.split('\n') + if (lines[0].trim() === 'pie') { + lines[0] = 'pie showData' + } else { + lines.unshift('pie showData') + } + + return lines.join('\n') +} + +// Function to initialize Mermaid diagrams +export async function initMermaid() { + try { + // 确保只初始化一次 + if (!initialized) { + mermaid.initialize(config) + initialized = true + } + + // 查找所有 mermaid 图表 + const mermaidDivs = Array.from(document.querySelectorAll('div.mermaid')) + + // 处理每个图表 + for (const element of mermaidDivs) { + try { + const graphDefinition = element.textContent || '' + if (!graphDefinition.trim()) continue + + const cleanDefinition = cleanMermaidDefinition(graphDefinition) + const cacheKey = cleanDefinition + + // 检查缓存 + const cachedSvg = renderedDiagrams.get(cacheKey) + if (cachedSvg && element.getAttribute('data-source') === cleanDefinition) { + // 如果有缓存且内容没变,直接使用缓存 + const container = document.createElement('div') + container.style.width = '100%' + container.style.display = 'flex' + container.style.justifyContent = 'center' + container.style.margin = '1em 0' + container.innerHTML = cachedSvg + + // 保存原始内容用于复制 + const originalContent = document.createElement('div') + originalContent.style.display = 'none' + originalContent.className = 'mermaid-source' + originalContent.textContent = `\`\`\`mermaid +${graphDefinition.trim()} +\`\`\`` + + element.innerHTML = '' + element.appendChild(originalContent) + element.appendChild(container) + element.setAttribute('data-processed', 'true') + element.setAttribute('data-source', cleanDefinition) + continue + } + + // 创建容器 + const container = document.createElement('div') + container.style.width = '100%' + container.style.display = 'flex' + container.style.justifyContent = 'center' + container.style.margin = '1em 0' + + try { + // 处理不同类型的图表 + let finalDefinition = cleanDefinition + if (cleanDefinition.includes('pie')) { + finalDefinition = processPieChart(cleanDefinition) + } + + // 渲染图表 + const id = generateMermaidId() + const { svg } = await mermaid.render(id, finalDefinition) + + // 缓存渲染结果 + renderedDiagrams.set(cacheKey, svg) + + // 保存原始内容用于复制 + const originalContent = document.createElement('div') + originalContent.style.display = 'none' + originalContent.className = 'mermaid-source' + originalContent.textContent = `\`\`\`mermaid +${graphDefinition.trim()} +\`\`\`` + + // 更新 DOM + container.innerHTML = svg + element.innerHTML = '' + element.appendChild(originalContent) + element.appendChild(container) + element.setAttribute('data-processed', 'true') + element.setAttribute('data-source', finalDefinition) + + // 添加复制事件处理 + container.addEventListener('copy', (e) => { + e.preventDefault() + const sourceText = element.querySelector('.mermaid-source')?.textContent || '' + if (e.clipboardData) { + e.clipboardData.setData('text/plain', sourceText) + } + }) + } catch (renderError) { + console.error('Mermaid render error:', renderError) + console.log('Graph definition:', cleanDefinition) + element.innerHTML = `
${cleanDefinition}
` + element.setAttribute('data-processed', 'true') + element.setAttribute('data-source', cleanDefinition) + } + } catch (error) { + console.error('Mermaid processing error:', error) + } + } + } catch (error) { + console.error('Mermaid initialization error:', error) + } +} \ No newline at end of file diff --git a/src/lib/markdown/renderer.ts b/src/lib/markdown/renderer.ts index cb14f81..dece59d 100644 --- a/src/lib/markdown/renderer.ts +++ b/src/lib/markdown/renderer.ts @@ -12,6 +12,13 @@ interface LatexBlockToken extends Tokens.Generic { text: string } +// 自定义 Mermaid 块的 Token 类型 +interface MermaidBlockToken extends Tokens.Generic { + type: 'mermaidBlock' + raw: string + text: string +} + export class MarkdownRenderer { private renderer: typeof marked.Renderer.prototype private options: RendererOptions @@ -21,6 +28,7 @@ export class MarkdownRenderer { this.renderer = new marked.Renderer() this.initializeRenderer() this.initializeLatexExtension() + this.initializeMermaidExtension() } private initializeLatexExtension() { @@ -69,6 +77,64 @@ export class MarkdownRenderer { marked.use({ extensions: [latexBlockTokenizer] }) } + private initializeMermaidExtension() { + // 添加 Mermaid 块的 tokenizer + const mermaidBlockTokenizer: TokenizerAndRendererExtension = { + name: 'mermaidBlock', + level: 'block', + start(src: string) { + // 支持两种格式:```mermaid 和 ``` 后面跟 mermaid 内容 + return src.match(/^```(?:mermaid\s*$|[\s\n]*pie\s+|[\s\n]*graph\s+|[\s\n]*sequenceDiagram\s+|[\s\n]*gantt\s+|[\s\n]*classDiagram\s+|[\s\n]*flowchart\s+)/)?.index + }, + tokenizer(src: string) { + // 匹配两种格式 + const rule = /^```(?:mermaid\s*\n)?([\s\S]*?)\n*```(?:\s*\n|$)/ + const match = rule.exec(src) + if (match) { + const content = match[1].trim() + // 检查内容是否是 mermaid 图表 + if (content.match(/^(?:pie\s+|graph\s+|sequenceDiagram\s+|gantt\s+|classDiagram\s+|flowchart\s+)/)) { + // 如果是饼图,添加 showData 选项 + const processedContent = content.startsWith('pie') + ? `pie showData\n${content.replace(/^pie\s*/, '').trim()}` + : content + return { + type: 'mermaidBlock', + raw: match[0], + tokens: [], + text: processedContent + } + } + } + }, + renderer: (token) => { + try { + const mermaidStyle = (this.options.block?.mermaid || {}) + const style = { + ...mermaidStyle, + display: 'block', + margin: '1em 0', + textAlign: 'center', + background: 'transparent' // 确保背景透明以适应主题 + } + const styleStr = cssPropertiesToString(style) + + // Generate unique ID for the diagram + const id = `mermaid-${Math.random().toString(36).substring(2)}` + + // Since we can't use async/await in the renderer, we'll return a div that will be rendered by client-side JavaScript + return `${token.text}` + } catch (error) { + console.error('Mermaid rendering error:', error) + return `
${token.text}
` + } + } + } + + // 注册扩展 + marked.use({ extensions: [mermaidBlockTokenizer] }) + } + private initializeRenderer() { // 重写 text 方法来处理行内 LaTeX 公式 this.renderer.text = (token: Tokens.Text | Tokens.Escape) => { diff --git a/src/lib/markdown/types.ts b/src/lib/markdown/types.ts index 01e291a..ee2dac3 100644 --- a/src/lib/markdown/types.ts +++ b/src/lib/markdown/types.ts @@ -111,6 +111,7 @@ export interface RendererOptions { thead?: StyleOptions footnotes?: StyleOptions latex?: StyleOptions + mermaid?: StyleOptions } inline?: { strong?: StyleOptions