From 9a24d9c834156ef265a8eabad61b5b2c606c1385 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 28 Aug 2023 15:19:02 +0200 Subject: [PATCH 1/5] Frist crude loop support --- package-lock.json | 1430 +++++++++-------- sdfv.css | 2 + src/index.ts | 36 +- src/overlays/logical_group_overlay.ts | 88 +- src/overlays/operational_intensity_overlay.ts | 2 +- src/renderer/canvas_manager.ts | 6 +- src/renderer/renderer.ts | 686 ++++---- src/renderer/renderer_elements.ts | 369 +++-- src/sdfv.ts | 4 +- src/utils/sdfg/sdfg_parser.ts | 91 +- src/utils/sdfg/sdfg_utils.ts | 59 +- src/utils/sdfg/traversal.ts | 41 +- 12 files changed, 1555 insertions(+), 1259 deletions(-) diff --git a/package-lock.json b/package-lock.json index 510cc4b0..9f85a7cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@spcl/sdfv", - "version": "1.0.38", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@spcl/sdfv", - "version": "1.0.38", + "version": "1.1.0", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -87,9 +87,9 @@ } }, "node_modules/@babel/cli": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.9.tgz", - "integrity": "sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.10.tgz", + "integrity": "sha512-rM9ZMmaII630zGvtMtQ3P4GyHs28CHLYE9apLG7L8TgaSqcfoIGrlLSLsh4Q8kDTdZQQEXZm1M0nQtOvU/2heg==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", @@ -116,12 +116,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", + "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.10", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -137,25 +138,25 @@ } }, "node_modules/@babel/core": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", - "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", + "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", + "@babel/helpers": "^7.22.11", + "@babel/parser": "^7.22.11", "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -167,12 +168,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", + "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -194,21 +195,21 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz", + "integrity": "sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", - "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", + "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", @@ -219,15 +220,12 @@ }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz", - "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", + "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -265,9 +263,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz", - "integrity": "sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -277,7 +275,7 @@ "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-environment-visitor": { @@ -476,41 +474,41 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz", - "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz", + "integrity": "sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==", "dev": true, "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", + "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", "dev": true, "dependencies": { "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", + "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -518,9 +516,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", + "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -573,22 +571,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -882,14 +864,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz", - "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.11.tgz", + "integrity": "sha512-0pAlmeRJn6wU84zzZsEOx1JV1Jf8fqO9ok7wofIJwUnplYo247dcd24P+cMJht7ts9xkzdtB0EPHmOb7F+KzXw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.9", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -932,9 +914,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz", + "integrity": "sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -963,12 +945,12 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -1019,9 +1001,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz", + "integrity": "sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1065,9 +1047,9 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1097,9 +1079,9 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1145,9 +1127,9 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1176,9 +1158,9 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1223,12 +1205,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz", + "integrity": "sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -1240,13 +1222,13 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz", + "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5" }, @@ -1305,9 +1287,9 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1321,9 +1303,9 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1337,13 +1319,13 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz", + "integrity": "sha512-nX8cPFa6+UmbepISvlf5jhQyaC7ASs/7UxHmMkuJ/k5xSHvDPPaibMo+v3TXwU/Pjqhep/nFNpd3zn4YR59pnw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.22.5" @@ -1372,9 +1354,9 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1388,9 +1370,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", - "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", + "version": "7.22.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.12.tgz", + "integrity": "sha512-7XXCVqZtyFWqjDsYDY4T45w4mlx1rf7aOgkc/Ww76xkgBiOlmjPkx36PBLHa1k1rwWvVgYMPsbuVnIamx2ZQJw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1436,13 +1418,13 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -1469,13 +1451,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.1" + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1500,16 +1482,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz", - "integrity": "sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.10.tgz", + "integrity": "sha512-RchI7HePu1eu0CYNKHHHQdfenZcM4nz8rew5B1VWqeRKdcwW5aQ5HeG9eTUbWiAS1UrmHVLmoxTWHt3iLD/NhA==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", "semver": "^6.3.1" }, "engines": { @@ -1596,13 +1578,13 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz", - "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz", + "integrity": "sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.9", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.22.5" }, @@ -1614,9 +1596,9 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1677,13 +1659,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", - "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.10.tgz", + "integrity": "sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", @@ -1708,15 +1690,15 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.7", + "@babel/plugin-transform-async-generator-functions": "^7.22.10", "@babel/plugin-transform-async-to-generator": "^7.22.5", "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.10", "@babel/plugin-transform-class-properties": "^7.22.5", "@babel/plugin-transform-class-static-block": "^7.22.5", "@babel/plugin-transform-classes": "^7.22.6", "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.10", "@babel/plugin-transform-dotall-regex": "^7.22.5", "@babel/plugin-transform-duplicate-keys": "^7.22.5", "@babel/plugin-transform-dynamic-import": "^7.22.5", @@ -1739,27 +1721,27 @@ "@babel/plugin-transform-object-rest-spread": "^7.22.5", "@babel/plugin-transform-object-super": "^7.22.5", "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.6", + "@babel/plugin-transform-optional-chaining": "^7.22.10", "@babel/plugin-transform-parameters": "^7.22.5", "@babel/plugin-transform-private-methods": "^7.22.5", "@babel/plugin-transform-private-property-in-object": "^7.22.5", "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", "@babel/plugin-transform-reserved-words": "^7.22.5", "@babel/plugin-transform-shorthand-properties": "^7.22.5", "@babel/plugin-transform-spread": "^7.22.5", "@babel/plugin-transform-sticky-regex": "^7.22.5", "@babel/plugin-transform-template-literals": "^7.22.5", "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", "@babel/plugin-transform-unicode-property-regex": "^7.22.5", "@babel/plugin-transform-unicode-regex": "^7.22.5", "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.22.10", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -1771,32 +1753,30 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/preset-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", - "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.11.tgz", + "integrity": "sha512-tWY5wyCZYBGY7IlalfKI1rLiGlIfnwsRHZqlky0HVv8qviwQ1Uo/05M6+s+TcTCVa6Bmoo2uJW5TMFX6Wa4qVg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-typescript": "^7.22.5" + "@babel/plugin-transform-modules-commonjs": "^7.22.11", + "@babel/plugin-transform-typescript": "^7.22.11" }, "engines": { "node": ">=6.9.0" @@ -1812,11 +1792,11 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1837,19 +1817,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", + "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.22.11", + "@babel/types": "^7.22.11", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1858,9 +1838,9 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", @@ -1924,18 +1904,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -1962,9 +1942,9 @@ "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2001,9 +1981,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2068,16 +2048,16 @@ } }, "node_modules/@jest/console": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.1.tgz", - "integrity": "sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", + "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.6.1", - "jest-util": "^29.6.1", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", "slash": "^3.0.0" }, "engines": { @@ -2164,37 +2144,37 @@ } }, "node_modules/@jest/core": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.1.tgz", - "integrity": "sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", + "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", "dev": true, "dependencies": { - "@jest/console": "^29.6.1", - "@jest/reporters": "^29.6.1", - "@jest/test-result": "^29.6.1", - "@jest/transform": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/console": "^29.6.4", + "@jest/reporters": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.6.1", - "jest-haste-map": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.1", - "jest-resolve-dependencies": "^29.6.1", - "jest-runner": "^29.6.1", - "jest-runtime": "^29.6.1", - "jest-snapshot": "^29.6.1", - "jest-util": "^29.6.1", - "jest-validate": "^29.6.1", - "jest-watcher": "^29.6.1", + "jest-changed-files": "^29.6.3", + "jest-config": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-resolve-dependencies": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "jest-watcher": "^29.6.4", "micromatch": "^4.0.4", - "pretty-format": "^29.6.1", + "pretty-format": "^29.6.3", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -2290,88 +2270,88 @@ } }, "node_modules/@jest/environment": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.1.tgz", - "integrity": "sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz", + "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.1" + "jest-mock": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.1.tgz", - "integrity": "sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==", "dev": true, "dependencies": { - "expect": "^29.6.1", - "jest-snapshot": "^29.6.1" + "expect": "^29.6.4", + "jest-snapshot": "^29.6.4" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", - "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz", + "integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.1.tgz", - "integrity": "sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz", + "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.6.1", - "jest-mock": "^29.6.1", - "jest-util": "^29.6.1" + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.1.tgz", - "integrity": "sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz", + "integrity": "sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.1", - "@jest/expect": "^29.6.1", - "@jest/types": "^29.6.1", - "jest-mock": "^29.6.1" + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/types": "^29.6.3", + "jest-mock": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.1.tgz", - "integrity": "sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz", + "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.6.1", - "@jest/test-result": "^29.6.1", - "@jest/transform": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/console": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", @@ -2380,13 +2360,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.6.1", - "jest-util": "^29.6.1", - "jest-worker": "^29.6.1", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -2462,6 +2442,49 @@ "node": ">=8" } }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz", + "integrity": "sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@jest/reporters/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2483,10 +2506,16 @@ "node": ">=8" } }, + "node_modules/@jest/reporters/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@jest/schemas": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -2496,9 +2525,9 @@ } }, "node_modules/@jest/source-map": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", - "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -2510,13 +2539,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.1.tgz", - "integrity": "sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz", + "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==", "dev": true, "dependencies": { - "@jest/console": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/console": "^29.6.4", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -2525,14 +2554,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz", - "integrity": "sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz", + "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.1", + "@jest/test-result": "^29.6.4", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.1", + "jest-haste-map": "^29.6.4", "slash": "^3.0.0" }, "engines": { @@ -2549,22 +2578,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.1.tgz", - "integrity": "sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz", + "integrity": "sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.1", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.6.1", + "jest-haste-map": "^29.6.4", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.6.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -2660,12 +2689,12 @@ } }, "node_modules/@jest/types": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", - "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.6.0", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -2761,9 +2790,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -2795,21 +2824,15 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@kurkle/color": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", @@ -2828,15 +2851,6 @@ "dev": true, "optional": true }, - "node_modules/@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", - "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3379,9 +3393,9 @@ } }, "node_modules/@types/dagre": { - "version": "0.7.48", - "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.48.tgz", - "integrity": "sha512-rF3yXSwHIrDxEkN6edCE4TXknb5YSEpiXfLaspw1I08grC49ZFuAVGOQCmZGIuLUGoFgcqGlUFBL/XrpgYpQgw==", + "version": "0.7.49", + "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.49.tgz", + "integrity": "sha512-dlqM5cavmHC0FeBlVl1HPKE/12K3TcIsTeBpRwhkS2FYOmuk36ndI7AuGQjPJ/fJQTz8LjeaetSV/+dsJwB6Ow==", "dev": true }, "node_modules/@types/earcut": { @@ -3390,9 +3404,9 @@ "integrity": "sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==" }, "node_modules/@types/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw==", + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", "dev": true, "dependencies": { "@types/estree": "*", @@ -3428,9 +3442,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "version": "4.17.36", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz", + "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==", "dev": true, "dependencies": { "@types/node": "*", @@ -3488,9 +3502,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.3.tgz", - "integrity": "sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==", + "version": "29.5.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz", + "integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -3498,9 +3512,9 @@ } }, "node_modules/@types/jquery": { - "version": "3.5.16", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz", - "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==", + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.17.tgz", + "integrity": "sha512-U40tNEAGSTZ7R1OC6kGkD7f4TKW5DoVx6jd9kTB9mo5truFMi1m9Yohnw9kl1WpTPvDdj7zAw38LfCHSqnk5kA==", "dev": true, "dependencies": { "@types/sizzle": "*" @@ -3519,15 +3533,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", "dev": true }, "node_modules/@types/qs": { @@ -4350,9 +4358,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "version": "10.4.15", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", + "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", "dev": true, "funding": [ { @@ -4362,11 +4370,15 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001464", + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001520", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -4489,15 +4501,15 @@ } }, "node_modules/babel-jest": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", - "integrity": "sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz", + "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==", "dev": true, "dependencies": { - "@jest/transform": "^29.6.1", + "@jest/transform": "^29.6.4", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -4631,9 +4643,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -4646,42 +4658,42 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", - "integrity": "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.1", - "@nicolo-ribaudo/semver-v6": "^6.3.3" + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz", - "integrity": "sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", + "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.1", + "@babel/helper-define-polyfill-provider": "^0.4.2", "core-js-compat": "^3.31.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz", - "integrity": "sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.1" + "@babel/helper-define-polyfill-provider": "^0.4.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-syntax-class-properties": { @@ -4726,12 +4738,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -4956,9 +4968,9 @@ } }, "node_modules/bootstrap": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", - "integrity": "sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", + "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", "funding": [ { "type": "github", @@ -4970,7 +4982,7 @@ } ], "peerDependencies": { - "@popperjs/core": "^2.11.7" + "@popperjs/core": "^2.11.8" } }, "node_modules/brace-expansion": { @@ -5002,9 +5014,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -5021,9 +5033,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", "update-browserslist-db": "^1.0.11" }, "bin": { @@ -5123,9 +5135,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001517", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", - "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", + "version": "1.0.30001524", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz", + "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==", "dev": true, "funding": [ { @@ -5166,9 +5178,9 @@ } }, "node_modules/chart.js": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.3.0.tgz", - "integrity": "sha512-ynG0E79xGfMaV2xAHdbhwiPLczxnNNnasrmPEXriXsPJGjmhOBYzFVEsB65w2qMDz+CaBJJuJD0inE/ab/h36g==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz", + "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==", "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -5454,12 +5466,12 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.31.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz", - "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==", + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz", + "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==", "dev": true, "dependencies": { - "browserslist": "^4.21.9" + "browserslist": "^4.21.10" }, "funding": { "type": "opencollective", @@ -5631,10 +5643,18 @@ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", @@ -5731,9 +5751,9 @@ } }, "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5758,9 +5778,9 @@ "dev": true }, "node_modules/dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -5793,9 +5813,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.464", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.464.tgz", - "integrity": "sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==", + "version": "1.4.503", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.503.tgz", + "integrity": "sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==", "dev": true }, "node_modules/emittery": { @@ -5900,27 +5920,27 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5967,9 +5987,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -6046,9 +6066,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", - "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -6099,9 +6119,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6334,17 +6354,16 @@ } }, "node_modules/expect": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", - "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.6.1", - "@types/node": "*", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-util": "^29.6.1" + "@jest/expect-utils": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6435,9 +6454,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6595,16 +6614,17 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.7", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12.0.0" } }, "node_modules/flatted": { @@ -6651,9 +6671,9 @@ } }, "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.1.tgz", + "integrity": "sha512-/KxoyCnPM0GwYI4NN0Iag38Tqt+od3/mLuguepLgCAKPn0ZhC544nssAW0tG2/00zXEYl9W+7hwAIpLHo6Oc7Q==", "engines": { "node": "*" }, @@ -6703,9 +6723,9 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -7337,9 +7357,9 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -7559,17 +7579,17 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-report/node_modules/has-flag": { @@ -7581,21 +7601,48 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7608,6 +7655,12 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -7623,9 +7676,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -7641,15 +7694,15 @@ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" }, "node_modules/jest": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", - "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz", + "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==", "dev": true, "dependencies": { - "@jest/core": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/core": "^29.6.4", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.6.1" + "jest-cli": "^29.6.4" }, "bin": { "jest": "bin/jest.js" @@ -7667,12 +7720,13 @@ } }, "node_modules/jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz", + "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==", "dev": true, "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.6.3", "p-limit": "^3.1.0" }, "engines": { @@ -7680,28 +7734,28 @@ } }, "node_modules/jest-circus": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.1.tgz", - "integrity": "sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz", + "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.1", - "@jest/expect": "^29.6.1", - "@jest/test-result": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.6.1", - "jest-matcher-utils": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-runtime": "^29.6.1", - "jest-snapshot": "^29.6.1", - "jest-util": "^29.6.1", + "jest-each": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", "p-limit": "^3.1.0", - "pretty-format": "^29.6.1", + "pretty-format": "^29.6.3", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -7790,21 +7844,21 @@ } }, "node_modules/jest-cli": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.1.tgz", - "integrity": "sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz", + "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==", "dev": true, "dependencies": { - "@jest/core": "^29.6.1", - "@jest/test-result": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/core": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.6.1", - "jest-util": "^29.6.1", - "jest-validate": "^29.6.1", + "jest-config": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -7894,31 +7948,31 @@ } }, "node_modules/jest-config": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.1.tgz", - "integrity": "sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz", + "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.6.1", - "@jest/types": "^29.6.1", - "babel-jest": "^29.6.1", + "@jest/test-sequencer": "^29.6.4", + "@jest/types": "^29.6.3", + "babel-jest": "^29.6.4", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.6.1", - "jest-environment-node": "^29.6.1", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.1", - "jest-runner": "^29.6.1", - "jest-util": "^29.6.1", - "jest-validate": "^29.6.1", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.6.1", + "pretty-format": "^29.6.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -8018,15 +8072,15 @@ } }, "node_modules/jest-diff": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", - "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz", + "integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.1" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8103,9 +8157,9 @@ } }, "node_modules/jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz", + "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -8115,16 +8169,16 @@ } }, "node_modules/jest-each": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.1.tgz", - "integrity": "sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz", + "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.6.1", - "pretty-format": "^29.6.1" + "jest-get-type": "^29.6.3", + "jest-util": "^29.6.3", + "pretty-format": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8201,46 +8255,46 @@ } }, "node_modules/jest-environment-node": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.1.tgz", - "integrity": "sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", + "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.1", - "@jest/fake-timers": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.1", - "jest-util": "^29.6.1" + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.1.tgz", - "integrity": "sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz", + "integrity": "sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.6.1", - "jest-worker": "^29.6.1", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -8252,28 +8306,28 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz", - "integrity": "sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz", + "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.1" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", - "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz", + "integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.6.1", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.1" + "jest-diff": "^29.6.4", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8350,18 +8404,18 @@ } }, "node_modules/jest-message-util": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", - "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz", + "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.6.1", + "pretty-format": "^29.6.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -8449,14 +8503,14 @@ } }, "node_modules/jest-mock": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.1.tgz", - "integrity": "sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz", + "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.6.1" + "jest-util": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8480,26 +8534,26 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.1.tgz", - "integrity": "sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz", + "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.1", + "jest-haste-map": "^29.6.4", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.6.1", - "jest-validate": "^29.6.1", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -8509,13 +8563,13 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz", - "integrity": "sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz", + "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==", "dev": true, "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.6.1" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.6.4" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -8601,30 +8655,30 @@ } }, "node_modules/jest-runner": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.1.tgz", - "integrity": "sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz", + "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==", "dev": true, "dependencies": { - "@jest/console": "^29.6.1", - "@jest/environment": "^29.6.1", - "@jest/test-result": "^29.6.1", - "@jest/transform": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/console": "^29.6.4", + "@jest/environment": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.6.1", - "jest-haste-map": "^29.6.1", - "jest-leak-detector": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-resolve": "^29.6.1", - "jest-runtime": "^29.6.1", - "jest-util": "^29.6.1", - "jest-watcher": "^29.6.1", - "jest-worker": "^29.6.1", + "jest-docblock": "^29.6.3", + "jest-environment-node": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-leak-detector": "^29.6.3", + "jest-message-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-util": "^29.6.3", + "jest-watcher": "^29.6.4", + "jest-worker": "^29.6.4", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -8703,31 +8757,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.1.tgz", - "integrity": "sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.6.1", - "@jest/fake-timers": "^29.6.1", - "@jest/globals": "^29.6.1", - "@jest/source-map": "^29.6.0", - "@jest/test-result": "^29.6.1", - "@jest/transform": "^29.6.1", - "@jest/types": "^29.6.1", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz", + "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/globals": "^29.6.4", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-mock": "^29.6.1", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.1", - "jest-snapshot": "^29.6.1", - "jest-util": "^29.6.1", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -8815,9 +8869,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.1.tgz", - "integrity": "sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz", + "integrity": "sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -8825,21 +8879,20 @@ "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.6.1", - "@jest/transform": "^29.6.1", - "@jest/types": "^29.6.1", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.6.1", + "expect": "^29.6.4", "graceful-fs": "^4.2.9", - "jest-diff": "^29.6.1", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-util": "^29.6.1", + "jest-diff": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", "natural-compare": "^1.4.0", - "pretty-format": "^29.6.1", + "pretty-format": "^29.6.3", "semver": "^7.5.3" }, "engines": { @@ -8950,12 +9003,12 @@ "dev": true }, "node_modules/jest-util": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", - "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", + "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -9037,17 +9090,17 @@ } }, "node_modules/jest-validate": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.1.tgz", - "integrity": "sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", + "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", "dev": true, "dependencies": { - "@jest/types": "^29.6.1", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.6.1" + "pretty-format": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -9136,18 +9189,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.1.tgz", - "integrity": "sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz", + "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.1", - "@jest/types": "^29.6.1", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.6.1", + "jest-util": "^29.6.3", "string-length": "^4.0.1" }, "engines": { @@ -9225,13 +9278,13 @@ } }, "node_modules/jest-worker": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.1.tgz", - "integrity": "sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz", + "integrity": "sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.6.1", + "jest-util": "^29.6.3", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -9264,9 +9317,9 @@ } }, "node_modules/jiti": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", - "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", + "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==", "dev": true, "bin": { "jiti": "bin/jiti.js" @@ -9308,6 +9361,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -9349,6 +9408,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9516,9 +9584,9 @@ } }, "node_modules/material-icons": { - "version": "1.13.8", - "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.8.tgz", - "integrity": "sha512-vnLGXKa/AwFUxUgkiX39EpYVFttPhDQcKdVylIqmUUqz+Eo/O9A3BkdPCU3/G5cJOTezHi5B/b8sEpKYgUNAwQ==" + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.10.tgz", + "integrity": "sha512-XSESl/zo7XzD9nz8ihUq5HO0DzsvnVex9t8hpH8pqY1SFlESAdHlMQQbcCyyP58mPp6Wm1tyt0OaDNZhBT9lXQ==" }, "node_modules/material-symbols": { "version": "0.6.0", @@ -9526,11 +9594,11 @@ "integrity": "sha512-CzQ3IPeIlHQLn2WLmp6nUBGGjaIlIMeGvTTsn1VrjeGZtw89gJx01VJmhmz6V+zvTIcFL8S+NBdKsj4+LRCVDg==" }, "node_modules/mathjs": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.8.2.tgz", - "integrity": "sha512-ZePu0oDbM0vuFExikIMY/9syjo/jbgNbX6ti+iMdaALDuxciMCsXIslGDBEn7QCpCWYBiVCYmc0lsmk5bwHBdQ==", + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.10.0.tgz", + "integrity": "sha512-PXzIHU+36OUCTJVkc6dwMB2MFMRykxcN9y+EnIhy/HUAIGYQMKEpDJrEjdLb7kCi1JSarmbZqNSpKFGxpZhWzw==", "dependencies": { - "@babel/runtime": "^7.22.5", + "@babel/runtime": "^7.22.6", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", @@ -10440,9 +10508,9 @@ } }, "node_modules/postcss": { - "version": "8.4.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", - "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", + "version": "8.4.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", + "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", "dev": true, "funding": [ { @@ -10610,12 +10678,12 @@ } }, "node_modules/pretty-format": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", - "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", + "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.6.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -10852,14 +10920,14 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" @@ -10928,12 +10996,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -11647,9 +11715,9 @@ } }, "node_modules/terser": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.1.tgz", - "integrity": "sha512-27hxBUVdV6GoNg1pKQ7Z5cbR6V9txPVyBA+FQw3BaZ1Wuzvztce5p156DaP0NVZNrMZZ+6iG9Syf7WgMNKDg2Q==", + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", diff --git a/sdfv.css b/sdfv.css index 59555955..a984bbfd 100644 --- a/sdfv.css +++ b/sdfv.css @@ -366,6 +366,8 @@ pre.code code { --node-missing-background-color: red; --state-background-color: #deebf7; --state-foreground-color: #000000; + --loop-background-color: #e0e0e0; + --loop-foreground-color: #000000; --interstate-edge-color: #86add9; --connector-scoped-color: #c1dfe690; --connector-unscoped-color: #f0fdff; diff --git a/src/index.ts b/src/index.ts index e3af1099..800e8883 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,16 +41,6 @@ export type InvalidSDFGError = { isedge_id: number | undefined, }; -export type JsonSDFG = { - type: string, - start_state: number, - sdfg_list_id: number, - attributes: any, - edges: any[], - nodes: any[], - error: InvalidSDFGError | undefined, -}; - export type JsonSDFGEdge = { attributes: any, dst: string, @@ -64,24 +54,42 @@ export type JsonSDFGEdge = { y?: number, }; -export type JsonSDFGNode = { +export interface JsonSDFGNode { attributes: any, id: number, label: string, scope_entry: string | null, scope_exit: string | null, type: string, -}; +} -export type JsonSDFGState = { +export interface JsonSDFGBlock { attributes: any, collapsed: boolean, edges: JsonSDFGEdge[], + nodes: (JsonSDFGBlock | JsonSDFGNode)[], id: number, label: string, - nodes: JsonSDFGNode[], + type: string, +} + +export interface JsonSDFGControlBlock extends JsonSDFGBlock { + nodes: JsonSDFGBlock[], +} + +export interface JsonSDFGState extends JsonSDFGBlock { scope_dict: any, + nodes: JsonSDFGNode[], +} + +export type JsonSDFG = { type: string, + start_state: number, + sdfg_list_id: number, + attributes: any, + edges: any[], // TODO + nodes: any[], // TODO + error: InvalidSDFGError | undefined, }; export type ModeButtons = { diff --git a/src/overlays/logical_group_overlay.ts b/src/overlays/logical_group_overlay.ts index 82079f6c..98c0c6f0 100644 --- a/src/overlays/logical_group_overlay.ts +++ b/src/overlays/logical_group_overlay.ts @@ -7,6 +7,7 @@ import { SDFGNode, SDFGElement, State, + SDFGElementType, } from '../renderer/renderer_elements'; import { SDFV } from '../sdfv'; import { GenericSdfgOverlay, OverlayType } from './generic_sdfg_overlay'; @@ -78,62 +79,69 @@ export class LogicalGroupOverlay extends GenericSdfgOverlay { } } - public recursively_shade_sdfg( - sdfg: JsonSDFG, - graph: DagreSDFG, - ctx: CanvasRenderingContext2D, - ppp: number, - visible_rect: SimpleRect + public recursivelyShadeSDFG( + sdfg: JsonSDFG, graph: DagreSDFG, ctx: CanvasRenderingContext2D, + ppp: number, visibleRect: SimpleRect ): void { // First go over visible states, skipping invisible ones. We only draw // something if the state is collapsed or we're zoomed out far enough. // In that case, we overlay the correct grouping color(s). // If it's expanded or zoomed in close enough, we traverse inside. - const sdfg_groups = sdfg.attributes.logical_groups; - if (sdfg_groups === undefined) + const sdfgGroups = sdfg.attributes.logical_groups; + if (sdfgGroups === undefined) return; graph.nodes().forEach(v => { - const state = graph.node(v); + const block = graph.node(v); // If the node's invisible, we skip it. - if ((ctx as any).lod && !state.intersect( - visible_rect.x, visible_rect.y, - visible_rect.w, visible_rect.h + if ((ctx as any).lod && !block.intersect( + visibleRect.x, visibleRect.y, + visibleRect.w, visibleRect.h )) return; if (((ctx as any).lod && (ppp >= SDFV.STATE_LOD || - state.width / ppp <= SDFV.STATE_LOD)) || - state.data.state.attributes.is_collapsed) { - this.shade_node(state, sdfg_groups, ctx); + block.width / ppp <= SDFV.STATE_LOD)) || + block.attributes().is_collapsed + ) { + this.shade_node(block, sdfgGroups, ctx); } else { - const state_graph = state.data.graph; - if (state_graph) { - state_graph.nodes().forEach((v: string) => { - const node = state_graph.node(v); - - // Skip the node if it's not visible. - if ((ctx as any).lod && !node.intersect(visible_rect.x, - visible_rect.y, visible_rect.w, visible_rect.h)) - return; - - if (node.data.node.attributes.is_collapsed || - ((ctx as any).lod && ppp >= SDFV.NODE_LOD)) { - this.shade_node(node, sdfg_groups, ctx); - } else { - if (node instanceof NestedSDFG && - node.attributes().sdfg && - node.attributes().sdfg.type !== 'SDFGShell') { - this.recursively_shade_sdfg( - node.data.node.attributes.sdfg, - node.data.graph, ctx, ppp, visible_rect - ); + if (block.type() === SDFGElementType.SDFGState) { + const stateGraph = block.data.graph; + if (stateGraph) { + stateGraph.nodes().forEach((v: string) => { + const node = stateGraph.node(v); + + // Skip the node if it's not visible. + if ((ctx as any).lod && !node.intersect( + visibleRect.x, + visibleRect.y, visibleRect.w, visibleRect.h) + ) + return; + + if (node.attributes().is_collapsed || + ((ctx as any).lod && ppp >= SDFV.NODE_LOD)) { + this.shade_node(node, sdfgGroups, ctx); } else { - this.shade_node(node, sdfg_groups, ctx); + if (node instanceof NestedSDFG && + node.attributes().sdfg && + node.attributes().sdfg.type !== 'SDFGShell' + ) { + this.recursivelyShadeSDFG( + node.data.node.attributes.sdfg, + node.data.graph, ctx, ppp, visibleRect + ); + } else { + this.shade_node(node, sdfgGroups, ctx); + } } - } - }); + }); + } + } else { + this.recursivelyShadeSDFG( + sdfg, block.data.graph, ctx, ppp, visibleRect + ); } } }); @@ -146,7 +154,7 @@ export class LogicalGroupOverlay extends GenericSdfgOverlay { const context = this.renderer.get_context(); const visible_rect = this.renderer.get_visible_rect(); if (graph && ppp !== undefined && context && visible_rect) - this.recursively_shade_sdfg( + this.recursivelyShadeSDFG( sdfg, graph, context, ppp, visible_rect ); } diff --git a/src/overlays/operational_intensity_overlay.ts b/src/overlays/operational_intensity_overlay.ts index 8cb2736a..2fa0f6df 100644 --- a/src/overlays/operational_intensity_overlay.ts +++ b/src/overlays/operational_intensity_overlay.ts @@ -1,7 +1,7 @@ // Copyright 2019-2022 ETH Zurich and the DaCe authors. All rights reserved. import { DagreSDFG, Point2D, SimpleRect, SymbolMap } from '../index'; -import { SDFGRenderer, SDFGRendererEvent } from '../renderer/renderer'; +import { SDFGRenderer } from '../renderer/renderer'; import { Edge, NestedSDFG, diff --git a/src/renderer/canvas_manager.ts b/src/renderer/canvas_manager.ts index aa2aec9e..b01e0b4d 100644 --- a/src/renderer/canvas_manager.ts +++ b/src/renderer/canvas_manager.ts @@ -4,7 +4,7 @@ import { Edge, EntryNode, SDFGElement, SDFGElementType, SDFGNode } from './rende import { lerpMatrix } from '../utils/lerp_matrix'; import { updateEdgeBoundingBox } from '../utils/bounding_box'; import { - get_positioning_info, + getPositioningInfo, initialize_positioning_info, } from '../utils/sdfg/sdfg_utils'; import { SDFGRenderer, SDFGListType } from './renderer'; @@ -483,7 +483,7 @@ export class CanvasManager { const points = el.get_points(); let position; if (update_position_info) { - position = get_positioning_info(el); + position = getPositioningInfo(el); if (!position) position = initialize_positioning_info(el); @@ -591,7 +591,7 @@ export class CanvasManager { // Store movement information in element (for relayouting) if (update_position_info) { - let position = get_positioning_info(el); + let position = getPositioningInfo(el); if (!position) position = initialize_positioning_info(el); diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts index 7172ccbf..87be271e 100644 --- a/src/renderer/renderer.ts +++ b/src/renderer/renderer.ts @@ -1,4 +1,4 @@ -// Copyright 2019-2022 ETH Zurich and the DaCe authors. All rights reserved. +// Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. import $ from 'jquery'; @@ -8,6 +8,7 @@ import { DagreSDFG, GenericSdfgOverlay, JsonSDFG, + JsonSDFGBlock, JsonSDFGEdge, JsonSDFGNode, JsonSDFGState, @@ -33,13 +34,13 @@ import { } from '../utils/bounding_box'; import { sdfg_property_to_string } from '../utils/sdfg/display'; import { - check_and_redirect_edge, delete_positioning_info, delete_sdfg_nodes, + check_and_redirect_edge, deletePositioningInfo, delete_sdfg_nodes, delete_sdfg_states, find_exit_for_entry, find_graph_element_by_uuid, - find_root_sdfg, get_positioning_info, get_uuid_graph_element + find_root_sdfg, getPositioningInfo, get_uuid_graph_element } from '../utils/sdfg/sdfg_utils'; import { memlet_tree_complete, - traverse_sdfg_scopes + traverseSDFGScopes } from '../utils/sdfg/traversal'; import { SDFVSettings } from '../utils/sdfv_settings'; import { deepCopy, intersectRect, showErrorModal } from '../utils/utils'; @@ -47,12 +48,13 @@ import { CanvasManager } from './canvas_manager'; import { AccessNode, Connector, Edge, EntryNode, InterstateEdge, Memlet, NestedSDFG, + SDFG, SDFGElement, SDFGElementType, SDFGElements, SDFGNode, State, - draw_sdfg, + drawSDFG, offset_sdfg, offset_state } from './renderer_elements'; @@ -1055,17 +1057,20 @@ export class SDFGRenderer extends EventEmitter { // Re-layout graph and nested graphs public relayout(): DagreSDFG { + if (!this.ctx) + throw new Error('No context found while performing layouting'); + this.sdfg_list = {}; - this.graph = relayout_sdfg( - this.ctx, this.sdfg, this.sdfg_list, - this.state_parent_list, !SDFVSettings.showAccessNodes + this.graph = relayoutStateMachine( + this.ctx, this.sdfg, this.sdfg, this.sdfg_list, + this.state_parent_list, !SDFVSettings.showAccessNodes, undefined ); this.onresize(); this.update_fast_memlet_lookup(); // Move the elements based on its positioning information - this.translate_moved_elements(); + this.translateMovedElements(); // Make sure all visible overlays get recalculated if there are any. if (this.overlay_manager !== null) @@ -1078,39 +1083,39 @@ export class SDFGRenderer extends EventEmitter { return this.graph; } - public translate_moved_elements(): void { + public translateMovedElements(): void { if (!this.graph) return; - traverse_sdfg_scopes(this.graph, (node: any, graph: any) => { + traverseSDFGScopes(this.graph, (node: any, graph: any) => { let scope_dx = 0; let scope_dy = 0; - function add_scope_movement(n: any) { + function addScopeMovement(n: any) { if (n.data.node.scope_entry) { const scope_entry_node = graph.node( n.data.node.scope_entry ); - const sp = get_positioning_info(scope_entry_node); + const sp = getPositioningInfo(scope_entry_node); if (sp && Number.isFinite(sp.scope_dx) && Number.isFinite(sp.scope_dy)) { scope_dx += sp.scope_dx; scope_dy += sp.scope_dy; } if (scope_entry_node) { - add_scope_movement(scope_entry_node); + addScopeMovement(scope_entry_node); } } } // Only add scope movement for nodes (and not states) if (node instanceof SDFGNode) - add_scope_movement(node); + addScopeMovement(node); let dx = scope_dx; let dy = scope_dy; - const position = get_positioning_info(node); + const position = getPositioningInfo(node); if (position) { dx += position.dx; dy += position.dy; @@ -1129,7 +1134,7 @@ export class SDFGRenderer extends EventEmitter { // Move edges (outgoing only) graph.inEdges(node.id)?.forEach((e_id: number) => { const edge = graph.edge(e_id); - const edge_pos = get_positioning_info(edge); + const edge_pos = getPositioningInfo(edge); let final_pos_d; // If edges are moved within a given scope, update the point @@ -1294,7 +1299,7 @@ export class SDFGRenderer extends EventEmitter { if (!this.graph) return; - traverse_sdfg_scopes( + traverseSDFGScopes( this.graph, (node: SDFGNode, _: DagreSDFG) => { if(node.attributes().is_collapsed) { node.attributes().is_collapsed = false; @@ -1328,7 +1333,7 @@ export class SDFGRenderer extends EventEmitter { public reset_positions(): void { this.for_all_sdfg_elements( (_t: SDFGElementGroup, _d: any, obj: any) => { - delete_positioning_info(obj); + deletePositioningInfo(obj); } ); @@ -1553,12 +1558,12 @@ export class SDFGRenderer extends EventEmitter { this.graph.nodes().forEach(x => { const n = this.graph?.node(x); if (n && this.minimap_ctx) - n.simple_draw(this, this.minimap_ctx, null); + n.simple_draw(this, this.minimap_ctx, undefined); }); this.graph.edges().forEach(x => { const e = this.graph?.edge(x); if (e && this.minimap_ctx) - e.draw(this, this.minimap_ctx, null); + e.draw(this, this.minimap_ctx, undefined); }); // Draw the viewport. @@ -1621,7 +1626,7 @@ export class SDFGRenderer extends EventEmitter { this.on_pre_draw(); - draw_sdfg(this, ctx, g, this.mousepos); + drawSDFG(this, ctx, g, this.mousepos ?? undefined); if (this.box_select_rect) { this.ctx.beginPath(); @@ -1780,7 +1785,7 @@ export class SDFGRenderer extends EventEmitter { const curw = (endx ? endx : 0) - curx; const curh = (endy ? endy : 0) - cury; const elements: any[] = []; - this.do_for_intersected_elements( + this.doForIntersectedElements( curx, cury, curw, curh, (type: any, e: any, _obj: any) => { const state_id = e.state ? Number(e.state) : -1; @@ -1806,7 +1811,7 @@ export class SDFGRenderer extends EventEmitter { return elements; } - public do_for_visible_elements(func: CallableFunction): void { + public doForVisibleElements(func: CallableFunction): void { if (!this.canvas_manager) return; @@ -1822,7 +1827,7 @@ export class SDFGRenderer extends EventEmitter { endy = this.canvas_manager.mapPixelToCoordsY(canvash); const curw = (endx ? endx : 0) - curx; const curh = (endy ? endy : 0) - cury; - this.do_for_intersected_elements(curx, cury, curw, curh, func); + this.doForIntersectedElements(curx, cury, curw, curh, func); } // Returns a dictionary of SDFG elements in a given rectangle. Used for @@ -1843,7 +1848,7 @@ export class SDFGRenderer extends EventEmitter { states: [], nodes: [], connectors: [], edges: [], isedges: [] }; - this.do_for_intersected_elements( + this.doForIntersectedElements( x, y, w, h, (type: string, e: any, obj: any) => { e.obj = obj; elements[type].push(e); @@ -1852,113 +1857,120 @@ export class SDFGRenderer extends EventEmitter { return elements; } - public do_for_intersected_elements( + public doForIntersectedElements( x: number, y: number, w: number, h: number, func: CallableFunction ): void { - // Traverse nested SDFGs recursively - function traverse_recursive( - g: DagreSDFG | null, sdfg_name: string, sdfg_id: number + if (!this.graph) + return; + + // Traverse nested SDFGs recursively. + function traverseRecursive( + g: DagreSDFG, sdfgName: string, sdfgId: number ): void { - g?.nodes().forEach((state_id: string) => { - const state: dagre.Node = g.node(state_id); - if (!state) + g.nodes().forEach((blockId: string) => { + const block: dagre.Node = g.node(blockId); + if (!block) return; - if (state.intersect(x, y, w, h)) { + if (block.intersect(x, y, w, h)) { // States func( 'states', { - sdfg: sdfg_name, sdfg_id: sdfg_id, id: state_id + sdfg: sdfgName, sdfg_id: sdfgId, id: blockId }, - state + block ); - if (state.data.state.attributes.is_collapsed) + if (block.attributes().is_collapsed) return; - const ng = state.data.graph; + const ng = block.data.graph; if (!ng) return; - ng.nodes().forEach((node_id: string) => { - const node = ng.node(node_id); - if (node.intersect(x, y, w, h)) { - // Selected nodes - func( - 'nodes', - { - sdfg: sdfg_name, sdfg_id: sdfg_id, - state: state_id, id: node_id - }, - node - ); - // If nested SDFG, traverse recursively - if (node.data.node.type === - SDFGElementType.NestedSDFG) - traverse_recursive( - node.data.graph, - node.data.node.attributes.sdfg.attributes - .name, - node.data.node.attributes.sdfg.sdfg_list_id + if (block.type() === SDFGElementType.SDFGState) { + ng.nodes().forEach((node_id: string) => { + const node = ng.node(node_id); + if (node.intersect(x, y, w, h)) { + // Selected nodes + func( + 'nodes', + { + sdfg: sdfgName, sdfg_id: sdfgId, + state: blockId, id: node_id + }, + node ); - } - // Connectors - node.in_connectors.forEach( - (c: Connector, i: number) => { - if (c.intersect(x, y, w, h)) - func( - 'connectors', - { - sdfg: sdfg_name, sdfg_id: sdfg_id, - state: state_id, node: node_id, - connector: i, conntype: 'in' - }, - c - ); - } - ); - node.out_connectors.forEach( - (c: Connector, i: number) => { - if (c.intersect(x, y, w, h)) - func( - 'connectors', - { - sdfg: sdfg_name, sdfg_id: sdfg_id, - state: state_id, node: node_id, - connector: i, conntype: 'out' - }, - c + + // If nested SDFG, traverse recursively + if (node.data.node.type === + SDFGElementType.NestedSDFG) + traverseRecursive( + node.data.graph, + node.attributes().sdfg.attributes.name, + node.attributes().sdfg.sdfg_list_id ); } - ); - }); - - // Selected edges - ng.edges().forEach((edge_id: number) => { - const edge = ng.edge(edge_id); - if (edge.intersect(x, y, w, h)) { - func( - 'edges', - { - sdfg: sdfg_name, sdfg_id: sdfg_id, - state: state_id, id: edge.id - }, - edge + // Connectors + node.in_connectors.forEach( + (c: Connector, i: number) => { + if (c.intersect(x, y, w, h)) + func( + 'connectors', + { + sdfg: sdfgName, sdfg_id: sdfgId, + state: blockId, node: node_id, + connector: i, conntype: 'in' + }, + c + ); + } ); - } - }); + node.out_connectors.forEach( + (c: Connector, i: number) => { + if (c.intersect(x, y, w, h)) + func( + 'connectors', + { + sdfg: sdfgName, sdfg_id: sdfgId, + state: blockId, node: node_id, + connector: i, conntype: 'out' + }, + c + ); + } + ); + }); + + // Selected edges + ng.edges().forEach((edge_id: number) => { + const edge = ng.edge(edge_id); + if (edge.intersect(x, y, w, h)) { + func( + 'edges', + { + sdfg: sdfgName, sdfg_id: sdfgId, + state: blockId, id: edge.id + }, + edge + ); + } + }); + } else { + traverseRecursive(block.data.graph, sdfgName, sdfgId); + } } }); // Selected inter-state edges - g?.edges().forEach(isedge_id => { + g.edges().forEach(isedge_id => { const isedge = g.edge(isedge_id); if (isedge.intersect(x, y, w, h)) { func( 'isedges', { - sdfg: sdfg_name, sdfg_id: sdfg_id, id: isedge.id + sdfg: sdfgName, sdfg_id: sdfgId, id: isedge.id }, isedge ); @@ -1966,10 +1978,9 @@ export class SDFGRenderer extends EventEmitter { }); } - // Start with top-level SDFG - traverse_recursive( - this.graph, this.sdfg.attributes.name, - this.sdfg.sdfg_list_id + // Start with top-level SDFG. + traverseRecursive( + this.graph, this.sdfg.attributes.name, this.sdfg.sdfg_list_id ); } @@ -2527,14 +2538,14 @@ export class SDFGRenderer extends EventEmitter { this.tooltip = null; // De-highlight all elements. - this.do_for_visible_elements( + this.doForVisibleElements( (type: any, e: any, obj: any) => { obj.hovered = false; obj.highlighted = false; } ); // Mark hovered and highlighted elements. - this.do_for_visible_elements( + this.doForVisibleElements( (type: any, e: any, obj: any) => { const intersected = obj.intersect( this.mousepos!.x, this.mousepos!.y, 0, 0 @@ -2554,7 +2565,7 @@ export class SDFGRenderer extends EventEmitter { // Highlight all access nodes with the same name in the same // nested sdfg if (intersected && obj instanceof AccessNode) { - traverse_sdfg_scopes( + traverseSDFGScopes( this.sdfg_list[obj.sdfg.sdfg_list_id], (node: any) => { // If node is a state, then visit sub-scope @@ -2574,7 +2585,7 @@ export class SDFGRenderer extends EventEmitter { if (intersected && obj instanceof Connector && e.graph) { const nested_graph = e.graph.node(obj.parent_id).data.graph; if (nested_graph) { - traverse_sdfg_scopes(nested_graph, (node: any) => { + traverseSDFGScopes(nested_graph, (node: any) => { // If node is a state, then visit sub-scope if (node instanceof State) { return true; @@ -2660,7 +2671,7 @@ export class SDFGRenderer extends EventEmitter { this.box_select_rect.y_end); const w = end_x - start_x; const h = end_y - start_y; - this.do_for_intersected_elements(start_x, start_y, w, h, + this.doForIntersectedElements(start_x, start_y, w, h, (type: any, e: any, obj: any) => { if (obj.contained_in(start_x, start_y, w, h)) elements_in_selection.push(obj); @@ -2821,7 +2832,7 @@ export class SDFGRenderer extends EventEmitter { let element_moved = false; let relayout_necessary = false; for (const el of elements_to_reset) { - const position = get_positioning_info(el); + const position = getPositioningInfo(el); if (el && !(el instanceof Connector) && position) { // Reset the position of the element (if it has been // manually moved) @@ -3251,52 +3262,75 @@ function calculateNodeSize( return size; } -// Layout SDFG elements (states, nodes, scopes, nested SDFGs) -function relayout_sdfg( - ctx: any, - sdfg: any, - sdfg_list: SDFGListType, - state_parent_list: any[], - omit_access_nodes: boolean +type StateMachineType = { + nodes: JsonSDFGBlock[]; + edges: JsonSDFGEdge[]; +}; + +function relayoutStateMachine( + ctx: CanvasRenderingContext2D, stateMachine: StateMachineType, + sdfg: JsonSDFG, sdfgList: SDFGListType, stateParentList: any[], + omitAccessNodes: boolean, parent?: SDFGElement ): DagreSDFG { - const STATE_MARGIN = 4 * SDFV.LINEHEIGHT; + const BLOCK_MARGIN = 4 * SDFV.LINEHEIGHT; - // Layout the SDFG as a dagre graph + // Layout the state machine as a dagre graph. const g: DagreSDFG = new dagre.graphlib.Graph(); g.setGraph({}); g.setDefaultEdgeLabel(() => { return {}; }); - // layout each state to get its size - sdfg.nodes.forEach((state: any) => { - let stateinfo: any = {}; + if (!parent) + parent = new SDFG(sdfg); + + // layout each block individually to get its size. + for (const block of stateMachine.nodes) { + let blockInfo: { + label?: string, + width: number, + height: number, + } = { + label: undefined, + width: 0, + height: 0, + }; + + const btype = + block.type === SDFGElementType.SDFGState ? 'State' : block.type; + const blockElem = new SDFGElements[btype]( + { layout: { width: 0, height: 0 } }, block.id, sdfg, null, parent + ); + if (block.type === SDFGElementType.SDFGState) + blockElem.data.state = block; + else + blockElem.data.block = block; - stateinfo.label = state.id; - let state_g = null; - if (state.attributes.is_collapsed) { - stateinfo.width = ctx.measureText(stateinfo.label).width; - stateinfo.height = SDFV.LINEHEIGHT; + blockInfo.label = block.id.toString(); + let blockGraph = null; + if (block.attributes.is_collapsed) { + blockInfo.width = ctx.measureText(blockInfo.label).width; + blockInfo.height = SDFV.LINEHEIGHT; } else { - state_g = relayout_state( - ctx, state, sdfg, sdfg_list, - state_parent_list, omit_access_nodes + blockGraph = relayoutSDFGBlock( + ctx, block, sdfg, sdfgList, stateParentList, omitAccessNodes, + blockElem ); - if (state_g) - stateinfo = calculateBoundingBox(state_g); - } - stateinfo.width += 2 * STATE_MARGIN; - stateinfo.height += 2 * STATE_MARGIN; - g.setNode(state.id, new State({ - state: state, - layout: stateinfo, - graph: state_g - }, state.id, sdfg)); - }); + if (blockGraph) + blockInfo = calculateBoundingBox(blockGraph); + } + blockInfo.width += 2 * BLOCK_MARGIN; + blockInfo.height += 2 * BLOCK_MARGIN; + blockElem.data.layout = blockInfo; + blockElem.data.graph = blockGraph; + blockElem.set_layout(); + g.setNode(block.id.toString(), blockElem); + } - sdfg.edges.forEach((edge: any, id: number) => { + for (let id = 0; id < stateMachine.edges.length; id++) { + const edge = stateMachine.edges[id]; g.setEdge(edge.src, edge.dst, new InterstateEdge( - edge.attributes.data, id, sdfg) - ); - }); + edge.attributes.data, id, sdfg + )); + } if (SDFVSettings.useVerticalStateMachineLayout) { // Fall back to dagre for anything that cannot be laid out with @@ -3311,16 +3345,16 @@ function relayout_sdfg( } // Annotate the sdfg with its layout info - sdfg.nodes.forEach((state: any) => { - const gnode = g.node(state.id); - state.attributes.layout = {}; - state.attributes.layout.x = gnode.x; - state.attributes.layout.y = gnode.y; - state.attributes.layout.width = gnode.width; - state.attributes.layout.height = gnode.height; - }); + for (const block of stateMachine.nodes) { + const gnode = g.node(block.id.toString()); + block.attributes.layout = {}; + block.attributes.layout.x = gnode.x; + block.attributes.layout.y = gnode.y; + block.attributes.layout.width = gnode.width; + block.attributes.layout.height = gnode.height; + } - sdfg.edges.forEach((edge: any) => { + for (const edge of stateMachine.edges) { const gedge = g.edge(edge.src, edge.dst); const bb = calculateEdgeBoundingBox(gedge); // Convert from top-left to center @@ -3337,72 +3371,78 @@ function relayout_sdfg( edge.attributes.layout.x = (bb as any).x; edge.attributes.layout.y = (bb as any).y; edge.attributes.layout.points = gedge.points; - }); + } // Offset node and edge locations to be in state margins - sdfg.nodes.forEach((s: any, sid: any) => { - if (s.attributes.is_collapsed) - return; - - const state: any = g.node(sid); - const topleft = state.topleft(); - offset_state(s, state, { - x: topleft.x + STATE_MARGIN, - y: topleft.y + STATE_MARGIN - }); - }); + for (let blockId = 0; blockId < stateMachine.nodes.length; blockId++) { + const block = stateMachine.nodes[blockId]; + if (!block.attributes.is_collapsed) { + const gBlock: any = g.node(blockId.toString()); + const topleft = gBlock.topleft(); + if (block.type === SDFGElementType.SDFGState) { + offset_state(block as JsonSDFGState, gBlock, { + x: topleft.x + BLOCK_MARGIN, + y: topleft.y + BLOCK_MARGIN + }); + } else { + offset_sdfg(block as any, gBlock.data.graph, { + x: topleft.x + SDFV.LINEHEIGHT, + y: topleft.y + SDFV.LINEHEIGHT + }); + } + } + } const bb = calculateBoundingBox(g); (g as any).width = bb.width; (g as any).height = bb.height; - // Add SDFG to global store - sdfg_list[sdfg.sdfg_list_id] = g; + // Add SDFG to global store. + sdfgList[sdfg.sdfg_list_id] = g; return g; } -function relayout_state( - ctx: CanvasRenderingContext2D, sdfg_state: JsonSDFGState, - sdfg: JsonSDFG, sdfg_list: JsonSDFG[], state_parent_list: any[], - omit_access_nodes: boolean +function relayoutSDFGState( + ctx: CanvasRenderingContext2D, state: JsonSDFGState, + sdfg: JsonSDFG, sdfgList: JsonSDFG[], stateParentList: any[], + omitAccessNodes: boolean, parent: State ): DagreSDFG | null { - // layout the state as a dagre graph + // layout the sdfg block as a dagre graph. const g: DagreSDFG = new dagre.graphlib.Graph({ multigraph: true }); - // Set layout options and a simpler algorithm for large graphs - const layout_options: any = { ranksep: 30 }; - if (sdfg_state.nodes.length >= 1000) - layout_options.ranker = 'longest-path'; + // Set layout options and a simpler algorithm for large graphs. + const layoutOptions: any = { ranksep: 30 }; + if (state.nodes.length >= 1000) + layoutOptions.ranker = 'longest-path'; - g.setGraph(layout_options); + g.setGraph(layoutOptions); - - // Set an object for the graph label + // Set an object for the graph label. g.setDefaultEdgeLabel(() => { return {}; }); // Add nodes to the graph. The first argument is the node id. The // second is metadata about the node (label, width, height), // which will be updated by dagre.layout (will add x,y). - // Process nodes hierarchically - let toplevel_nodes = sdfg_state.scope_dict[-1]; - if (toplevel_nodes === undefined) - toplevel_nodes = Object.keys(sdfg_state.nodes); - const drawn_nodes: Set = new Set(); - const hidden_nodes = new Map(); + // Process nodes hierarchically. + let topLevelNodes = state.scope_dict[-1]; + if (topLevelNodes === undefined) + topLevelNodes = Object.keys(state.nodes); + const drawnNodes: Set = new Set(); + const hiddenNodes = new Map(); - function layout_node(node: any) { - if (omit_access_nodes && node.type === SDFGElementType.AccessNode) { + function layoutNode(node: any) { + if (omitAccessNodes && node.type === SDFGElementType.AccessNode) { // add access node to hidden nodes; source and destinations will be - // set later - hidden_nodes.set( + // set later. + hiddenNodes.set( node.id.toString(), { node: node, src: null, dsts: [] } ); return; } - let nested_g = null; + let nestedGraph = null; node.attributes.layout = {}; // Set connectors prior to computing node size @@ -3411,53 +3451,53 @@ function relayout_state( node.type !== SDFGElementType.NestedSDFG && node.type !== SDFGElementType.ExternalNestedSDFG) node.attributes.layout.out_connectors = find_exit_for_entry( - sdfg_state.nodes, node + state.nodes, node )?.attributes.out_connectors; else node.attributes.layout.out_connectors = node.attributes.out_connectors; - const nodesize = calculateNodeSize(sdfg, node, ctx); - node.attributes.layout.width = nodesize.width; - node.attributes.layout.height = nodesize.height; + const nodeSize = calculateNodeSize(sdfg, node, ctx); + node.attributes.layout.width = nodeSize.width; + node.attributes.layout.height = nodeSize.height; node.attributes.layout.label = node.label; - // Recursively lay out nested SDFGs + // Recursively lay out nested SDFGs. if (node.type === SDFGElementType.NestedSDFG || node.type === SDFGElementType.ExternalNestedSDFG) { if (node.attributes.sdfg && node.attributes.sdfg.type !== 'SDFGShell') { - nested_g = relayout_sdfg( - ctx, node.attributes.sdfg, sdfg_list, state_parent_list, - omit_access_nodes + nestedGraph = relayoutStateMachine( + ctx, node.attributes.sdfg, node.attributes.sdfg, sdfgList, + stateParentList, omitAccessNodes, parent ); - const sdfginfo = calculateBoundingBox(nested_g); + const sdfgInfo = calculateBoundingBox(nestedGraph); node.attributes.layout.width = - sdfginfo.width + 2 * SDFV.LINEHEIGHT; + sdfgInfo.width + 2 * SDFV.LINEHEIGHT; node.attributes.layout.height = - sdfginfo.height + 2 * SDFV.LINEHEIGHT; + sdfgInfo.height + 2 * SDFV.LINEHEIGHT; } else { const emptyNSDFGLabel = 'No SDFG loaded'; - const textmetrics = ctx.measureText(emptyNSDFGLabel); + const textMetrics = ctx.measureText(emptyNSDFGLabel); node.attributes.layout.width = - textmetrics.width + 2 * SDFV.LINEHEIGHT; + textMetrics.width + 2 * SDFV.LINEHEIGHT; node.attributes.layout.height = 4 * SDFV.LINEHEIGHT; } } - // Dynamically create node type + // Dynamically create node type. const obj = new SDFGElements[node.type]( - { node: node, graph: nested_g }, node.id, sdfg, sdfg_state.id + { node: node, graph: nestedGraph }, node.id, sdfg, state.id, parent ); // If it's a nested SDFG, we need to record the node as all of its - // state's parent node + // state's parent node. if ((node.type === SDFGElementType.NestedSDFG || node.type === SDFGElementType.ExternalNestedSDFG) && node.attributes.sdfg && node.attributes.sdfg.type !== 'SDFGShell') - state_parent_list[node.attributes.sdfg.sdfg_list_id] = obj; + stateParentList[node.attributes.sdfg.sdfg_list_id] = obj; - // Add input connectors + // Add input connectors. let i = 0; let conns; if (Array.isArray(node.attributes.layout.in_connectors)) @@ -3470,7 +3510,7 @@ function relayout_state( i += 1; } - // Add output connectors -- if collapsed, uses exit node connectors + // Add output connectors -- if collapsed, uses exit node connectors. i = 0; if (Array.isArray(node.attributes.layout.out_connectors)) conns = node.attributes.layout.out_connectors; @@ -3483,97 +3523,97 @@ function relayout_state( } g.setNode(node.id, obj); - drawn_nodes.add(node.id.toString()); + drawnNodes.add(node.id.toString()); - // Recursively draw nodes - if (node.id in sdfg_state.scope_dict) { + // Recursively draw nodes. + if (node.id in state.scope_dict) { if (node.attributes.is_collapsed) return; - sdfg_state.scope_dict[node.id].forEach((nodeid: number) => { - const node = sdfg_state.nodes[nodeid]; - layout_node(node); + state.scope_dict[node.id].forEach((nodeid: number) => { + const node = state.nodes[nodeid]; + layoutNode(node); }); } } - toplevel_nodes.forEach((nodeid: number) => { - const node = sdfg_state.nodes[nodeid]; - layout_node(node); + topLevelNodes.forEach((nodeid: number) => { + const node = state.nodes[nodeid]; + layoutNode(node); }); - // add info to calculate shortcut edges - function add_edge_info_if_hidden(edge: any) { - const hidden_src = hidden_nodes.get(edge.src); - const hidden_dst = hidden_nodes.get(edge.dst); + // Add info to calculate shortcut edges. + function addEdgeInfoIfHidden(edge: any) { + const hiddenSrc = hiddenNodes.get(edge.src); + const hiddenDst = hiddenNodes.get(edge.dst); - if (hidden_src && hidden_dst) { - // if we have edges from an AccessNode to an AccessNode then just - // connect destinations - hidden_src.dsts = hidden_dst.dsts; + if (hiddenSrc && hiddenDst) { + // If we have edges from an AccessNode to an AccessNode then just + // connect destinations. + hiddenSrc.dsts = hiddenDst.dsts; edge.attributes.data.attributes.shortcut = false; - } else if (hidden_src) { - // if edge starts at hidden node, then add it as destination - hidden_src.dsts.push(edge); + } else if (hiddenSrc) { + // If edge starts at hidden node, then add it as destination. + hiddenSrc.dsts.push(edge); edge.attributes.data.attributes.shortcut = false; return true; - } else if (hidden_dst) { - // if edge ends at hidden node, then add it as source - hidden_dst.src = edge; + } else if (hiddenDst) { + // If edge ends at hidden node, then add it as source. + hiddenDst.src = edge; edge.attributes.data.attributes.shortcut = false; return true; } - // if it is a shortcut edge, but we don't omit access nodes, then ignore - // this edge - if (!omit_access_nodes && edge.attributes.data.attributes.shortcut) + // If it is a shortcut edge, but we don't omit access nodes, then ignore + // this edge. + if (!omitAccessNodes && edge.attributes.data.attributes.shortcut) return true; return false; } - sdfg_state.edges.forEach((edge: any, id: any) => { - if (add_edge_info_if_hidden(edge)) + state.edges.forEach((edge: any, id: any) => { + if (addEdgeInfoIfHidden(edge)) return; - edge = check_and_redirect_edge(edge, drawn_nodes, sdfg_state); + edge = check_and_redirect_edge(edge, drawnNodes, state); if (!edge) return; - const e = new Memlet(edge.attributes.data, id, sdfg, sdfg_state.id); + const e = new Memlet(edge.attributes.data, id, sdfg, state.id); edge.attributes.data.edge = e; (e as any).src_connector = edge.src_connector; (e as any).dst_connector = edge.dst_connector; g.setEdge(edge.src, edge.dst, e, id); }); - hidden_nodes.forEach(hidden_node => { - if (hidden_node.src) { - hidden_node.dsts.forEach((e: any) => { - // create shortcut edge with new destination - const tmp_edge = e.attributes.data.edge; + hiddenNodes.forEach(hiddenNode => { + if (hiddenNode.src) { + hiddenNode.dsts.forEach((e: any) => { + // Create shortcut edge with new destination. + const tmpEdge = e.attributes.data.edge; e.attributes.data.edge = null; - const shortcut_e = deepCopy(e); - e.attributes.data.edge = tmp_edge; - shortcut_e.src = hidden_node.src.src; - shortcut_e.src_connector = hidden_node.src.src_connector; - shortcut_e.dst_connector = e.dst_connector; - // attribute that only shortcut edges have; if it is explicitly - // false, then edge is ignored in omit access node mode - shortcut_e.attributes.data.attributes.shortcut = true; - - // draw the redirected edge - const redirected_e = check_and_redirect_edge( - shortcut_e, drawn_nodes, sdfg_state + const shortCutEdge = deepCopy(e); + e.attributes.data.edge = tmpEdge; + shortCutEdge.src = hiddenNode.src.src; + shortCutEdge.src_connector = hiddenNode.src.src_connector; + shortCutEdge.dst_connector = e.dst_connector; + // Attribute that only shortcut edges have; if it is explicitly + // false, then edge is ignored in omit access node mode. + shortCutEdge.attributes.data.attributes.shortcut = true; + + // Draw the redirected edge. + const redirectedEdge = check_and_redirect_edge( + shortCutEdge, drawnNodes, state ); - if (!redirected_e) return; + if (!redirectedEdge) return; - // abort if shortcut edge already exists - const edges = g.outEdges(redirected_e.src); + // Abort if shortcut edge already exists. + const edges = g.outEdges(redirectedEdge.src); if (edges) { for (const oe of edges) { if (oe.w === e.dst && oe.name && - sdfg_state.edges[ + state.edges[ parseInt(oe.name) ].dst_connector === e.dst_connector ) { @@ -3582,24 +3622,24 @@ function relayout_state( } } - // add shortcut edge (redirection is not done in this list) - sdfg_state.edges.push(shortcut_e); + // Add shortcut edge (redirection is not done in this list). + state.edges.push(shortCutEdge); - // add redirected shortcut edge to graph - const edge_id = sdfg_state.edges.length - 1; - const shortcut_edge = new Memlet( - deepCopy(redirected_e.attributes.data), edge_id, sdfg, - sdfg_state.id + // Add redirected shortcut edge to graph. + const edgeId = state.edges.length - 1; + const newShortCutEdge = new Memlet( + deepCopy(redirectedEdge.attributes.data), edgeId, sdfg, + state.id ); - (shortcut_edge as any).src_connector = - redirected_e.src_connector; - (shortcut_edge as any).dst_connector = - redirected_e.dst_connector; - shortcut_edge.data.attributes.shortcut = true; + (newShortCutEdge as any).src_connector = + redirectedEdge.src_connector; + (newShortCutEdge as any).dst_connector = + redirectedEdge.dst_connector; + newShortCutEdge.data.attributes.shortcut = true; g.setEdge( - redirected_e.src, redirected_e.dst, shortcut_edge, - edge_id.toString() + redirectedEdge.src, redirectedEdge.dst, newShortCutEdge, + edgeId.toString() ); }); } @@ -3607,16 +3647,16 @@ function relayout_state( dagre.layout(g); - // Layout connectors and nested SDFGs - sdfg_state.nodes.forEach((node: JsonSDFGNode, id: number) => { + // Layout connectors and nested SDFGs. + state.nodes.forEach((node: JsonSDFGNode, id: number) => { const gnode: any = g.node(id.toString()); - if (!gnode || (omit_access_nodes && gnode instanceof AccessNode)) { - // ignore nodes that should not be drawn + if (!gnode || (omitAccessNodes && gnode instanceof AccessNode)) { + // Rgnore nodes that should not be drawn. return; } const topleft = gnode.topleft(); - // Offset nested SDFG + // Offset nested SDFG. if (node.type === SDFGElementType.NestedSDFG) { offset_sdfg(node.attributes.sdfg, gnode.data.graph, { @@ -3624,51 +3664,52 @@ function relayout_state( y: topleft.y + SDFV.LINEHEIGHT }); } - // Write back layout information + // Write back layout information. node.attributes.layout.x = gnode.x; node.attributes.layout.y = gnode.y; - // Connector management + // Connector management. const SPACING = SDFV.LINEHEIGHT; - const iconn_length = (SDFV.LINEHEIGHT + SPACING) * Object.keys( + const iConnLength = (SDFV.LINEHEIGHT + SPACING) * Object.keys( node.attributes.layout.in_connectors ).length - SPACING; - const oconn_length = (SDFV.LINEHEIGHT + SPACING) * Object.keys( + const oConnLength = (SDFV.LINEHEIGHT + SPACING) * Object.keys( node.attributes.layout.out_connectors ).length - SPACING; - let iconn_x = gnode.x - iconn_length / 2.0 + SDFV.LINEHEIGHT / 2.0; - let oconn_x = gnode.x - oconn_length / 2.0 + SDFV.LINEHEIGHT / 2.0; + let iConnX = gnode.x - iConnLength / 2.0 + SDFV.LINEHEIGHT / 2.0; + let oConnX = gnode.x - oConnLength / 2.0 + SDFV.LINEHEIGHT / 2.0; for (const c of gnode.in_connectors) { c.width = SDFV.LINEHEIGHT; c.height = SDFV.LINEHEIGHT; - c.x = iconn_x; - iconn_x += SDFV.LINEHEIGHT + SPACING; + c.x = iConnX; + iConnX += SDFV.LINEHEIGHT + SPACING; c.y = topleft.y; } for (const c of gnode.out_connectors) { c.width = SDFV.LINEHEIGHT; c.height = SDFV.LINEHEIGHT; - c.x = oconn_x; - oconn_x += SDFV.LINEHEIGHT + SPACING; + c.x = oConnX; + oConnX += SDFV.LINEHEIGHT + SPACING; c.y = topleft.y + gnode.height; } }); - sdfg_state.edges.forEach((edge: JsonSDFGEdge, id: number) => { - const nedge = check_and_redirect_edge(edge, drawn_nodes, sdfg_state); + state.edges.forEach((edge: JsonSDFGEdge, id: number) => { + const nedge = check_and_redirect_edge(edge, drawnNodes, state); if (!nedge) return; edge = nedge; const gedge = g.edge(edge.src, edge.dst, id.toString()); - if (!gedge || (omit_access_nodes && + if (!gedge || (omitAccessNodes && gedge.data.attributes.shortcut === false - || !omit_access_nodes && gedge.data.attributes.shortcut)) { - // if access nodes omitted, don't draw non-shortcut edges and - // vice versa + || !omitAccessNodes && gedge.data.attributes.shortcut)) { + // If access nodes omitted, don't draw non-shortcut edges and + // vice versa. return; } - // Reposition first and last points according to connectors - let src_conn = null, dst_conn = null; + // Reposition first and last points according to connectors. + let srcConn = null; + let dstConn = null; if (edge.src_connector) { const src_node: SDFGNode = g.node(edge.src); let cindex = -1; @@ -3683,14 +3724,14 @@ function relayout_state( if (cindex >= 0) { gedge.points[0].x = src_node.out_connectors[cindex].x; gedge.points[0].y = src_node.out_connectors[cindex].y; - src_conn = src_node.out_connectors[cindex]; + srcConn = src_node.out_connectors[cindex]; } } if (edge.dst_connector) { - const dst_node: SDFGNode = g.node(edge.dst); + const dstNode: SDFGNode = g.node(edge.dst); let cindex = -1; - for (let i = 0; i < dst_node.in_connectors.length; i++) { - const c = dst_node.in_connectors[i]; + for (let i = 0; i < dstNode.in_connectors.length; i++) { + const c = dstNode.in_connectors[i]; if (c.data.name === edge.dst_connector) { cindex = i; break; @@ -3698,18 +3739,18 @@ function relayout_state( } if (cindex >= 0) { gedge.points[gedge.points.length - 1].x = - dst_node.in_connectors[cindex].x; + dstNode.in_connectors[cindex].x; gedge.points[gedge.points.length - 1].y = - dst_node.in_connectors[cindex].y; - dst_conn = dst_node.in_connectors[cindex]; + dstNode.in_connectors[cindex].y; + dstConn = dstNode.in_connectors[cindex]; } } const n = gedge.points.length - 1; - if (src_conn !== null) - gedge.points[0] = intersectRect(src_conn, gedge.points[n]); - if (dst_conn !== null) - gedge.points[n] = intersectRect(dst_conn, gedge.points[0]); + if (srcConn !== null) + gedge.points[0] = intersectRect(srcConn, gedge.points[n]); + if (dstConn !== null) + gedge.points[n] = intersectRect(dstConn, gedge.points[0]); if (gedge.points.length === 3 && gedge.points[0].x === gedge.points[n].x) @@ -3733,3 +3774,24 @@ function relayout_state( return g; } +function relayoutSDFGBlock( + ctx: CanvasRenderingContext2D, block: JsonSDFGBlock, + sdfg: JsonSDFG, sdfgList: JsonSDFG[], stateParentList: any[], + omitAccessNodes: boolean, parent: SDFGElement +): DagreSDFG | null { + switch (block.type) { + case SDFGElementType.LoopScopeBlock: + return relayoutStateMachine( + ctx, block as StateMachineType, sdfg, sdfgList, stateParentList, + omitAccessNodes, parent + ); + case SDFGElementType.SDFGState: + case SDFGElementType.BasicBlock: + default: + return relayoutSDFGState( + ctx, block as JsonSDFGState, sdfg, sdfgList, stateParentList, + omitAccessNodes, parent + ); + } +} + diff --git a/src/renderer/renderer_elements.ts b/src/renderer/renderer_elements.ts index 890003a8..0e3ae3ed 100644 --- a/src/renderer/renderer_elements.ts +++ b/src/renderer/renderer_elements.ts @@ -1,23 +1,24 @@ -// Copyright 2019-2022 ETH Zurich and the DaCe authors. All rights reserved. +// Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. -import { SDFV } from '../sdfv'; import { DagreSDFG, JsonSDFG, + JsonSDFGBlock, JsonSDFGEdge, JsonSDFGNode, JsonSDFGState, Point2D, - SimpleRect, + SimpleRect } from '../index'; +import { SDFV } from '../sdfv'; import { - sdfg_range_elem_to_string, sdfg_consume_elem_to_string, + sdfg_property_to_string, + sdfg_range_elem_to_string, } from '../utils/sdfg/display'; -import { sdfg_property_to_string } from '../utils/sdfg/display'; import { check_and_redirect_edge } from '../utils/sdfg/sdfg_utils'; -import { SDFGRenderer } from './renderer'; import { SDFVSettings } from '../utils/sdfv_settings'; +import { SDFGRenderer } from './renderer'; export enum SDFGElementType { Edge = 'Edge', @@ -35,6 +36,8 @@ export enum SDFGElementType { PipelineEntry = 'PipelineEntry', PipelineExit = 'PipelineExit', Reduce = 'Reduce', + BasicBlock = 'BasicBlock', + LoopScopeBlock = 'LoopScopeBlock', } export class SDFGElement { @@ -57,7 +60,8 @@ export class SDFGElement { public data: any, public id: number, public sdfg: JsonSDFG, - public parent_id: number | null = null + public parent_id: number | null = null, + public parentElem?: SDFGElement, ) { this.set_layout(); } @@ -70,14 +74,14 @@ export class SDFGElement { public draw( _renderer: SDFGRenderer, _ctx: CanvasRenderingContext2D, - _mousepos: Point2D | null + _mousepos?: Point2D ): void { return; } public simple_draw( _renderer: SDFGRenderer, _ctx: CanvasRenderingContext2D, - _mousepos: Point2D | null + _mousepos?: Point2D ): void { return; } @@ -223,7 +227,7 @@ export class State extends SDFGElement { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { const topleft = this.topleft(); const visible_rect = renderer.get_visible_rect(); @@ -282,7 +286,7 @@ export class State extends SDFGElement { } // If collapsed, draw a "+" sign in the middle - if (this.data.state.attributes.is_collapsed) { + if (this.attributes().is_collapsed) { ctx.beginPath(); ctx.moveTo(this.x, this.y - SDFV.LINEHEIGHT); ctx.lineTo(this.x, this.y + SDFV.LINEHEIGHT); @@ -297,7 +301,8 @@ export class State extends SDFGElement { } public simple_draw( - renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, mousepos: Point2D + renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, + mousepos?: Point2D ): void { // Fast drawing function for small states const topleft = this.topleft(); @@ -368,11 +373,139 @@ export class State extends SDFGElement { } +export class LoopScopeBlock extends State { + + public draw( + renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, + _mousepos?: Point2D + ): void { + const topleft = this.topleft(); + const visible_rect = renderer.get_visible_rect(); + let clamped; + if (visible_rect) + clamped = { + x: Math.max(topleft.x, visible_rect.x), + y: Math.max(topleft.y, visible_rect.y), + x2: Math.min( + topleft.x + this.width, visible_rect.x + visible_rect.w + ), + y2: Math.min( + topleft.y + this.height, visible_rect.y + visible_rect.h + ), + w: 0, + h: 0, + }; + else + clamped = { + x: topleft.x, + y: topleft.y, + x2: topleft.x + this.width, + y2: topleft.y + this.height, + w: 0, + h: 0, + }; + clamped.w = clamped.x2 - clamped.x; + clamped.h = clamped.y2 - clamped.y; + if (!(ctx as any).lod) + clamped = { + x: topleft.x, y: topleft.y, x2: 0, y2: 0, + w: this.width, h: this.height + }; + + ctx.fillStyle = this.getCssProperty( + renderer, '--loop-background-color' + ); + ctx.fillRect(clamped.x, clamped.y, clamped.w, clamped.h); + ctx.fillStyle = this.getCssProperty( + renderer, '--loop-foreground-color' + ); + ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h); + + if (visible_rect && visible_rect.x <= topleft.x && + visible_rect.y <= topleft.y + SDFV.LINEHEIGHT && + SDFVSettings.showStateNames) + ctx.fillText(this.label(), topleft.x, topleft.y + SDFV.LINEHEIGHT); + + // If this state is selected or hovered + if ((this.selected || this.highlighted || this.hovered) && + (clamped.x === topleft.x || + clamped.y === topleft.y || + clamped.x2 === topleft.x + this.width || + clamped.y2 === topleft.y + this.height)) { + ctx.strokeStyle = this.strokeStyle(renderer); + ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h); + } + + // If collapsed, draw a "+" sign in the middle + if (this.attributes().is_collapsed) { + ctx.beginPath(); + ctx.moveTo(this.x, this.y - SDFV.LINEHEIGHT); + ctx.lineTo(this.x, this.y + SDFV.LINEHEIGHT); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(this.x - SDFV.LINEHEIGHT, this.y); + ctx.lineTo(this.x + SDFV.LINEHEIGHT, this.y); + ctx.stroke(); + } + + ctx.strokeStyle = 'black'; + } + + public simple_draw( + renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, + mousepos?: Point2D + ): void { + // Fast drawing function for small states + const topleft = this.topleft(); + + ctx.fillStyle = this.getCssProperty( + renderer, '--loop-background-color' + ); + ctx.fillRect(topleft.x, topleft.y, this.width, this.height); + ctx.fillStyle = this.getCssProperty(renderer, '--loop-foreground-color'); + + if (mousepos && this.intersect(mousepos.x, mousepos.y)) + renderer.set_tooltip((c) => this.tooltip(c)); + + // Draw state name in center without contents (does not look good) + /* + let FONTSIZE = Math.min( + renderer.canvas_manager.points_per_pixel() * 16, 100 + ); + let label = this.label(); + + let oldfont = ctx.font; + ctx.font = FONTSIZE + "px Arial"; + + let textmetrics = ctx.measureText(label); + ctx.fillText( + label, this.x - textmetrics.width / 2.0, + this.y - this.height / 6.0 + FONTSIZE / 2.0 + ); + + ctx.font = oldfont; + */ + } + + public attributes(): any { + return this.data.block.attributes; + } + + public label(): string { + return this.data.block.label; + } + + public type(): string { + return this.data.block.type; + } + +} + export class SDFGNode extends SDFGElement { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D, + _mousepos?: Point2D, fgstyle: string = '--node-foreground-color', bgstyle: string = '--node-background-color' ): void { @@ -435,7 +568,7 @@ export class SDFGNode extends SDFGElement { public simple_draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { // Fast drawing function for small nodes const topleft = this.topleft(); @@ -657,7 +790,7 @@ export class Memlet extends Edge { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { ctx.beginPath(); this.create_arrow_line(ctx); @@ -695,7 +828,7 @@ export class Memlet extends Edge { } public tooltip( - container: HTMLElement, renderer: SDFGRenderer | undefined = undefined + container: HTMLElement, renderer?: SDFGRenderer ): void { if (!renderer) return; @@ -808,7 +941,7 @@ export class InterstateEdge extends Edge { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { ctx.beginPath(); this.create_arrow_line(ctx); @@ -843,7 +976,7 @@ export class InterstateEdge extends Edge { } public tooltip( - container: HTMLElement, renderer: SDFGRenderer | undefined = undefined + container: HTMLElement, renderer?: SDFGRenderer ): void { if (!renderer) return; @@ -861,7 +994,7 @@ export class Connector extends SDFGElement { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D | null, edge: Edge | null = null + _mousepos?: Point2D, edge: Edge | null = null ): void { const scope_connector = ( this.data.name.startsWith('IN_') || @@ -947,7 +1080,7 @@ export class AccessNode extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { const topleft = this.topleft(); ctx.beginPath(); @@ -1057,7 +1190,9 @@ export class AccessNode extends SDFGNode { public tooltip(container: HTMLElement): void { super.tooltip(container); - const nodedesc = this.sdfg.attributes._arrays[this.data.node.attributes.data]; + const nodedesc = this.sdfg.attributes._arrays[ + this.data.node.attributes.data + ]; if (nodedesc) return; container.classList.add('sdfvtooltip--error'); @@ -1090,7 +1225,7 @@ export class ScopeNode extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { let draw_shape; if (this.data.node.attributes.is_collapsed) { @@ -1354,7 +1489,7 @@ export class Tasklet extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { const canvas_manager = renderer.get_canvas_manager(); if (!canvas_manager) @@ -1449,7 +1584,7 @@ export class Reduce extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { const topleft = this.topleft(); const draw_shape = () => { @@ -1514,7 +1649,7 @@ export class NestedSDFG extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - mousepos: Point2D + mousepos?: Point2D ): void { if (this.data.node.attributes.is_collapsed) { const topleft = this.topleft(); @@ -1556,7 +1691,7 @@ export class NestedSDFG extends SDFGNode { if (this.attributes().sdfg && this.attributes().sdfg.type !== 'SDFGShell') { // Draw nested graph. - draw_sdfg(renderer, ctx, this.data.graph, mousepos); + drawSDFG(renderer, ctx, this.data.graph, mousepos); } else { // Expanded, but no SDFG present or loaded yet. const errColor = this.getCssProperty( @@ -1656,7 +1791,7 @@ export class LibraryNode extends SDFGNode { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - _mousepos: Point2D + _mousepos?: Point2D ): void { ctx.fillStyle = this.getCssProperty( renderer, '--node-background-color' @@ -1718,9 +1853,10 @@ export class LibraryNode extends SDFGNode { * @param mousepos Mouse position. * @param color Default edge color to use. */ -function batched_draw_edges( +function batchedDrawEdges( renderer: SDFGRenderer, graph: DagreSDFG, ctx: CanvasRenderingContext2D, - visible_rect: SimpleRect | null, mousepos: Point2D | null, color: string + visible_rect?: SimpleRect, mousepos?: Point2D, + color: string = '--color-default' ): void { const deferredEdges: any[] = []; const arrowEdges: any[] = []; @@ -1775,108 +1911,128 @@ function batched_draw_edges( } } -// Draw an entire SDFG -export function draw_sdfg( - renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, - sdfg_dagre: DagreSDFG, mousepos: Point2D | null +export function drawStateContents( + stateGraph: DagreSDFG, ctx: CanvasRenderingContext2D, + renderer: SDFGRenderer, ppp: number, lod?: number, + visibleRect?: SimpleRect, mousePos?: Point2D ): void { - const canvas_manager = renderer.get_canvas_manager(); - if (!canvas_manager) - return; + for (const nodeId of stateGraph.nodes()) { + const node = stateGraph.node(nodeId); - const ppp = canvas_manager.points_per_pixel(); + if (lod && visibleRect && !node.intersect( + visibleRect.x, visibleRect.y, visibleRect.w, visibleRect.h + )) + continue; - const visible_rect = renderer.get_visible_rect(); + if (lod && node.height / ppp < SDFV.NODE_LOD) { + node.simple_draw(renderer, ctx, mousePos); + node.debug_draw(renderer, ctx); + continue; + } - // Render state machine's edges. - const g = sdfg_dagre; - if (!(ctx as any).lod || ppp < SDFV.EDGE_LOD) - batched_draw_edges( - renderer, g, ctx, visible_rect, mousepos, '--interstate-edge-color' - ); + node.draw(renderer, ctx, mousePos); + node.debug_draw(renderer, ctx); + node.in_connectors.forEach((c: Connector) => { + let edge: Edge | null = null; + stateGraph.inEdges(nodeId)?.forEach((e) => { + const eobj = stateGraph.edge(e); + if (eobj.dst_connector == c.data.name) + edge = eobj as any; + }); + c.draw(renderer, ctx, mousePos, edge); + c.debug_draw(renderer, ctx); + }); + node.out_connectors.forEach((c: Connector) => { + let edge: Edge | null = null; + stateGraph.outEdges(nodeId)?.forEach((e) => { + const eobj = stateGraph.edge(e); + if (eobj.src_connector == c.data.name) + edge = eobj as any; + }); - // Render each visible state's contents - g.nodes().forEach((v: string) => { - const node = g.node(v); + c.draw(renderer, ctx, mousePos, edge); + c.debug_draw(renderer, ctx); + }); + } - if ((ctx as any).lod && - (Math.max(node.width, node.height) / ppp < SDFV.STATE_LOD)) { - node.simple_draw(renderer, ctx, mousepos); + if (lod && ppp >= SDFV.EDGE_LOD) + return; + + batchedDrawEdges( + renderer, stateGraph, ctx, visibleRect, mousePos, '--color-default' + ); +} + +export function drawStateMachine( + stateMachineGraph: DagreSDFG, ctx: CanvasRenderingContext2D, + renderer: SDFGRenderer, ppp: number, lod?: number, + visibleRect?: SimpleRect, mousePos?: Point2D +): void { + if (!lod || ppp < SDFV.EDGE_LOD) + batchedDrawEdges( + renderer, stateMachineGraph, ctx, visibleRect, mousePos, + '--interstate-edge-color' + ); + + for (const nodeId of stateMachineGraph.nodes()) { + const node = stateMachineGraph.node(nodeId); + + if (lod && (Math.max(node.width, node.height) / ppp < SDFV.STATE_LOD)) { + node.simple_draw(renderer, ctx, mousePos); node.debug_draw(renderer, ctx); - return; + continue; } + // Skip invisible states - if ((ctx as any).lod && visible_rect && !node.intersect( - visible_rect.x, visible_rect.y, visible_rect.w, visible_rect.h + if (lod && visibleRect && !node.intersect( + visibleRect.x, visibleRect.y, visibleRect.w, visibleRect.h )) - return; + continue; - node.draw(renderer, ctx, mousepos); + node.draw(renderer, ctx, mousePos); node.debug_draw(renderer, ctx); const ng = node.data.graph; + if (!node.attributes().is_collapsed && ng) { + if (node instanceof State) + drawStateContents(ng, ctx, renderer, ppp, lod, visibleRect, mousePos); + else + drawStateMachine(ng, ctx, renderer, ppp, lod, visibleRect, mousePos); + } + } +} - if (!node.data.state.attributes.is_collapsed && ng) { - ng.nodes().forEach((v: any) => { - const n = ng.node(v); - - if ((ctx as any).lod && visible_rect && !n.intersect( - visible_rect.x, visible_rect.y, visible_rect.w, - visible_rect.h - )) - return; - if ((ctx as any).lod && node.height / ppp < SDFV.NODE_LOD) { - n.simple_draw(renderer, ctx, mousepos); - n.debug_draw(renderer, ctx); - return; - } - - n.draw(renderer, ctx, mousepos); - n.debug_draw(renderer, ctx); - n.in_connectors.forEach((c: Connector) => { - let edge: Edge | null = null; - ng.inEdges(v).forEach((e: JsonSDFGEdge) => { - const eobj: Edge = ng.edge(e); - if (eobj.dst_connector == c.data.name) - edge = eobj; - }); - - c.draw(renderer, ctx, mousepos, edge); - c.debug_draw(renderer, ctx); - }); - n.out_connectors.forEach((c: Connector) => { - let edge: Edge | null = null; - ng.outEdges(v).forEach((e: JsonSDFGEdge) => { - const eobj: Edge = ng.edge(e); - if (eobj.src_connector == c.data.name) - edge = eobj; - }); - - c.draw(renderer, ctx, mousepos, edge); - c.debug_draw(renderer, ctx); - }); - }); - if ((ctx as any).lod && ppp >= SDFV.EDGE_LOD) - return; +// Draw an entire SDFG. +export function drawSDFG( + renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, g: DagreSDFG, + mousePos?: Point2D +): void { + const cManager = renderer.get_canvas_manager(); + if (!cManager) + return; + const ppp = cManager.points_per_pixel(); + const visibleRect = renderer.get_visible_rect() ?? undefined; - batched_draw_edges( - renderer, ng, ctx, visible_rect, mousepos, '--color-default' - ); - } - }); + drawStateMachine( + g, ctx, renderer, ppp, (ctx as any).lod, visibleRect, mousePos + ); } // Translate an SDFG by a given offset export function offset_sdfg( sdfg: JsonSDFG, sdfg_graph: DagreSDFG, offset: Point2D ): void { - sdfg.nodes.forEach((state: JsonSDFGState, id: number) => { + sdfg.nodes.forEach((state: JsonSDFGBlock, id: number) => { const g = sdfg_graph.node(id.toString()); g.x += offset.x; g.y += offset.y; - if (!state.attributes.is_collapsed) - offset_state(state, g, offset); + if (!state.attributes.is_collapsed) { + if (state.type === SDFGElementType.SDFGState) + offset_state(state as JsonSDFGState, g, offset); + else + offset_sdfg(state as any, g.data.graph, offset); + } }); sdfg.edges.forEach((e: JsonSDFGEdge, _eid: number) => { const edge = sdfg_graph.edge(e.src, e.dst); @@ -2155,5 +2311,6 @@ export const SDFGElements: { [name: string]: typeof SDFGElement } = { PipelineExit, NestedSDFG, ExternalNestedSDFG, - LibraryNode + LibraryNode, + LoopScopeBlock, }; diff --git a/src/sdfv.ts b/src/sdfv.ts index 139bf7c6..67a01fa8 100644 --- a/src/sdfv.ts +++ b/src/sdfv.ts @@ -16,7 +16,7 @@ import { Point2D, sdfg_property_to_string, showErrorModal, - traverse_sdfg_scopes + traverseSDFGScopes } from './index'; import { LViewRenderer } from './local_view/lview_renderer'; import { @@ -165,7 +165,7 @@ export class SDFV { const stack: any[] = [sidebar]; // Add elements to tree view in sidebar - traverse_sdfg_scopes(sdfg, (node: SDFGNode, parent: DagreSDFG) => { + traverseSDFGScopes(sdfg, (node: SDFGNode, parent: DagreSDFG) => { // Skip exit nodes when scopes are known if (node.type().endsWith('Exit') && node.data.node.scope_entry >= 0) { diff --git a/src/utils/sdfg/sdfg_parser.ts b/src/utils/sdfg/sdfg_parser.ts index ac7486b4..b23653da 100644 --- a/src/utils/sdfg/sdfg_parser.ts +++ b/src/utils/sdfg/sdfg_parser.ts @@ -1,68 +1,73 @@ -// Copyright 2019-2022 ETH Zurich and the DaCe authors. All rights reserved. +// Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. -import { JsonSDFG, JsonSDFGNode, JsonSDFGState } from '../../index'; +import { + JsonSDFG, + JsonSDFGBlock, + JsonSDFGNode, + SDFGElementType, +} from '../../index'; -export class SDFG_Parser { +export class SDFGParser { public constructor(private readonly sdfg: JsonSDFG) { } - public getStates(): SDFG_State_Parser[] { - return this.sdfg.nodes.map((x: JsonSDFGState) => new SDFG_State_Parser(x)); + public getStates(): SDFGStateParser[] { + return this.sdfg.nodes.map((x: JsonSDFGBlock) => new SDFGStateParser(x)); } - public static lookup_symbols( - sdfg: JsonSDFG, state_id: number, elem: any, - symbols_to_resolve: string[], depth: number = 0 + public static lookupSymbols( + sdfg: JsonSDFG, stateId: number, elem: any, + symbolsToResolve: string[], depth: number = 0 ): any[] { - // Resolve used symbols by following connectors in reverse order - const state = sdfg.nodes[state_id]; + // Resolve used symbols by following connectors in reverse order. + const state = sdfg.nodes[stateId]; let syms: any[] = []; if (elem.constructor == Object) { - // Memlet + // Memlet. const memlets = state.edges.filter((x: any) => { return x.dst == elem.dst && x.src == elem.src; }); // Recurse into parent (since this a multigraph, all edges need to - // be looked at) + // be looked at). for (const m of memlets) { - // Find symbols used (may be Indices or Range) + // Find symbols used (may be Indices or Range). const mdata = m.attributes.data.attributes.subset; // Check for indices if (mdata.type == 'subsets.Indices') { - // These are constants or variables - // Reverse to have smallest unit first + // These are constants or variables. + // Reverse to have smallest unit first. const tmp = mdata.indices.map((x: any) => x).reverse(); for (const x of tmp) { // Add the used variables as null and hope that they - // will be resolved + // will be resolved. depth += 1; syms.push({ var: x, val: null, depth: depth }); } } else if (mdata.type == 'subsets.Range') { - // These are ranges + // These are ranges. // These ranges are not of interest, as they specify what is - // copied and don't define new variables + // copied and don't define new variables. } - // Find parent nodes - const tmp = SDFG_Parser.lookup_symbols( - sdfg, state_id, m.src, symbols_to_resolve, depth + 1 + // Find parent nodes. + const tmp = SDFGParser.lookupSymbols( + sdfg, stateId, m.src, symbolsToResolve, depth + 1 ); syms = [...syms, ...tmp]; } } else { - // Node + // Node. const node = state.nodes[elem]; - // Maps (and Consumes) define ranges, extract symbols from there + // Maps (and Consumes) define ranges, extract symbols from there. try { - // The iterator ranges + // The iterator ranges. const rngs = node.attributes.range.ranges.map((x: any) => x); - // The iterators + // The iterators. const params = node.attributes.params.map((x: any) => x); console.assert( @@ -71,13 +76,13 @@ export class SDFG_Parser { ); // Reverse from big -> little to little -> big (or outer -> - // inner to inner -> outer) + // inner to inner -> outer). rngs.reverse(); params.reverse(); for (let i = 0; i < rngs.length; ++i) { // Check first if the variable is already defined, and if - // yes, if the value is the same + // yes, if the value is the same. const fltrd = syms.filter(x => x.var == params[i]); if (fltrd.length == 0) { depth += 1; @@ -96,13 +101,14 @@ export class SDFG_Parser { } } } catch (e) { - // Not a node defining ranges (every node except maps / consumes) + // Not a node defining ranges (every node except maps / + // consumes). } - // Find all incoming edges + // Find all incoming edges. const inc_edges = state.edges.filter((x: any) => x.dst == elem); for (const e of inc_edges) { - const tmp = SDFG_Parser.lookup_symbols( - sdfg, state_id, e, symbols_to_resolve, depth + 1 + const tmp = SDFGParser.lookupSymbols( + sdfg, stateId, e, symbolsToResolve, depth + 1 ); syms = [...syms, ...tmp]; } @@ -112,28 +118,37 @@ export class SDFG_Parser { } } -export class SDFG_State_Parser { +export class SDFGStateParser { - public constructor(private readonly sdfg_state: JsonSDFGState) { + public constructor(private readonly block: JsonSDFGBlock) { } public getNodes(): any { - return this.sdfg_state.nodes.map((x: any) => new SDFG_Node_Parser(x)); + return this.block.nodes.map((x) => { + switch (x.type) { + case SDFGElementType.SDFGState: + case SDFGElementType.BasicBlock: + case SDFGElementType.LoopScopeBlock: + return new SDFGStateParser(x as JsonSDFGBlock); + default: + return new SDFGNodeParser(x as JsonSDFGNode); + } + }); } } -export class SDFG_Node_Parser { +export class SDFGNodeParser { public constructor(private readonly node: JsonSDFGNode) { } - public isNodeType(node_type: string): boolean { - return this.node.attributes.type === node_type; + public isNodeType(nodeType: string): boolean { + return this.node.attributes.type === nodeType; } } -export class SDFG_PropUtil { +export class SDFGPropUtil { public static getMetaFor(obj: any, attr_name: string): any { return obj.attributes['_meta_' + attr_name]; diff --git a/src/utils/sdfg/sdfg_utils.ts b/src/utils/sdfg/sdfg_utils.ts index 047c685b..319dea01 100644 --- a/src/utils/sdfg/sdfg_utils.ts +++ b/src/utils/sdfg/sdfg_utils.ts @@ -1,4 +1,4 @@ -// Copyright 2019-2022 ETH Zurich and the DaCe authors. All rights reserved. +// Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. import { Edge, @@ -228,7 +228,7 @@ export function initialize_positioning_info(elem: any): any { position = { dx: 0, dy: 0, scope_dx: 0, scope_dy: 0 }; } - set_positioning_info(elem, position); + setPositioningInfo(elem, position); return position; } @@ -240,20 +240,14 @@ export function initialize_positioning_info(elem: any): any { * @param {SDFGElement} elem The element that receives new positioning info * @param {*} position The positioning information */ -export function set_positioning_info( +export function setPositioningInfo( elem: any, position: any ): void { - if (elem instanceof State) - elem.data.state.attributes.position = position; - else if (elem instanceof SDFGNode) - elem.data.node.attributes.position = position; - else if (elem instanceof Edge) - elem.data.attributes.position = position; - else if (elem.type === 'MultiConnectorEdge') - elem.attributes.data.attributes.position = position; - // Works also for other objects with attributes - else if (elem.attributes) - elem.attributes.position = position; + let attr = elem?.attributes() ?? elem?.attributes?.data?.attributes; + if (!attr) + attr = elem?.attributes; + if (attr) + attr.position = position; } /** @@ -262,20 +256,11 @@ export function set_positioning_info( * @param {SDFGElement} elem The element that contains the information * @returns Position information, undefined if not present */ -export function get_positioning_info(elem: any): any { - if (elem instanceof State) - return elem.data.state.attributes.position; - if (elem instanceof SDFGNode) - return elem.data.node.attributes.position; - if (elem instanceof Edge) - return elem.data.attributes.position; - if (elem?.type === 'MultiConnectorEdge') - return elem?.attributes?.data?.attributes?.position; - // Works also for other objects with attributes - if (elem?.attributes) - return elem.attributes.position; - - return undefined; +export function getPositioningInfo(elem: any): any { + let attr = elem?.attributes() ?? elem?.attributes?.data?.attributes; + if (!attr) + attr = elem?.attributes; + return attr?.position; } /** @@ -283,18 +268,12 @@ export function get_positioning_info(elem: any): any { * * @param {SDFGElement} elem The element that contains the information */ -export function delete_positioning_info(elem: any): void { - if (elem instanceof State) - delete elem.data.state.attributes.position; - if (elem instanceof SDFGNode) - delete elem.data.node.attributes.position; - if (elem instanceof Edge) - delete elem.data.attributes.position; - if (elem?.type === 'MultiConnectorEdge') - delete elem.attributes.data.attributes.position; - // Works also for other objects with attributes - if (elem?.attributes) - delete elem.attributes.position; +export function deletePositioningInfo(elem: any): void { + let attr = elem?.attributes() ?? elem?.attributes?.data?.attributes; + if (!attr) + attr = elem?.attributes; + if (attr) + delete attr.position; } diff --git a/src/utils/sdfg/traversal.ts b/src/utils/sdfg/traversal.ts index 117da474..50e02b92 100644 --- a/src/utils/sdfg/traversal.ts +++ b/src/utils/sdfg/traversal.ts @@ -25,37 +25,33 @@ import { * visited. The function also accepts an optional post-subscope callback (same * signature as `func`). **/ - export function traverse_sdfg_scopes( - sdfg: DagreSDFG, - func: CallableFunction, - post_subscope_func: CallableFunction | null = null + export function traverseSDFGScopes( + sdfg: DagreSDFG, func: CallableFunction, postSubscopeFunc?: CallableFunction ): void { - function scopes_recursive( - graph: DagreSDFG, - nodes: any[], - processed_nodes: Set | null = null + function scopesRecursive( + graph: DagreSDFG, nodes: string[], processedNodes?: Set ): void { - if (processed_nodes === null) - processed_nodes = new Set(); + if (processedNodes === undefined) + processedNodes = new Set(); for (const nodeid of nodes) { const node = graph.node(nodeid); - if (node === undefined || processed_nodes.has(node.id?.toString())) + if (node === undefined || processedNodes.has(node.id.toString())) continue; - // Invoke function + // Invoke function. const result = func(node, graph); - // Skip in case of e.g., collapsed nodes + // Skip in case of e.g., collapsed nodes. if (result !== false) { - // Traverse scopes recursively (if scope_dict provided) + // Traverse scopes recursively (if scope_dict provided). if (node.type().endsWith('Entry') && node.parent_id !== null && node.id !== null) { const state = node.sdfg.nodes[node.parent_id]; if (state.scope_dict[node.id] !== undefined) - scopes_recursive( - graph, state.scope_dict[node.id], processed_nodes + scopesRecursive( + graph, state.scope_dict[node.id], processedNodes ); } @@ -64,21 +60,22 @@ import { const state = node.data.state; if (state !== undefined && state.scope_dict[-1] !== undefined) - scopes_recursive(node.data.graph, state.scope_dict[-1]); + scopesRecursive(node.data.graph, state.scope_dict[-1]); else // No scope_dict, traverse all nodes as a flat hierarchy - scopes_recursive( + scopesRecursive( node.data.graph, node.data.graph.nodes() ); } } - if (post_subscope_func) - post_subscope_func(node, graph); + if (postSubscopeFunc) + postSubscopeFunc(node, graph); - processed_nodes.add(node.id?.toString()); + processedNodes.add(node.id?.toString()); } } - scopes_recursive(sdfg, sdfg.nodes()); + + scopesRecursive(sdfg, sdfg.nodes()); } From 64cf630004bdf6b4859c1aaf2cf58ce17da0c18a Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 28 Aug 2023 19:28:49 +0200 Subject: [PATCH 2/5] Bugfixes --- src/renderer/renderer_elements.ts | 86 ++++++++++++++++++++++--------- src/sdfv.ts | 2 +- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/renderer/renderer_elements.ts b/src/renderer/renderer_elements.ts index 0e3ae3ed..f1c83782 100644 --- a/src/renderer/renderer_elements.ts +++ b/src/renderer/renderer_elements.ts @@ -373,7 +373,7 @@ export class State extends SDFGElement { } -export class LoopScopeBlock extends State { +export class LoopScopeBlock extends SDFGElement { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, @@ -487,6 +487,29 @@ export class LoopScopeBlock extends State { */ } + public shade( + _renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, color: string, + alpha: number = 0.4 + ): void { + // Save the current style properties. + const orig_fill_style = ctx.fillStyle; + const orig_alpha = ctx.globalAlpha; + + ctx.globalAlpha = alpha; + ctx.fillStyle = color; + + const topleft = this.topleft(); + ctx.fillRect(topleft.x, topleft.y, this.width, this.height); + + // Restore the previous style properties. + ctx.fillStyle = orig_fill_style; + ctx.globalAlpha = orig_alpha; + } + + public tooltip(container: HTMLElement): void { + container.innerText = 'Loop: ' + this.label(); + } + public attributes(): any { return this.data.block.attributes; } @@ -1913,7 +1936,7 @@ function batchedDrawEdges( export function drawStateContents( stateGraph: DagreSDFG, ctx: CanvasRenderingContext2D, - renderer: SDFGRenderer, ppp: number, lod?: number, + renderer: SDFGRenderer, ppp: number, lod?: boolean, visibleRect?: SimpleRect, mousePos?: Point2D ): void { for (const nodeId of stateGraph.nodes()) { @@ -1924,10 +1947,20 @@ export function drawStateContents( )) continue; - if (lod && node.height / ppp < SDFV.NODE_LOD) { - node.simple_draw(renderer, ctx, mousePos); - node.debug_draw(renderer, ctx); - continue; + if (node instanceof NestedSDFG) { + if (lod && ( + Math.max(node.height, node.width) / ppp + ) < SDFV.STATE_LOD) { + node.simple_draw(renderer, ctx, mousePos); + node.debug_draw(renderer, ctx); + continue; + } + } else { + if (lod && ppp > SDFV.NODE_LOD) { + node.simple_draw(renderer, ctx, mousePos); + node.debug_draw(renderer, ctx); + continue; + } } node.draw(renderer, ctx, mousePos); @@ -1956,7 +1989,7 @@ export function drawStateContents( }); } - if (lod && ppp >= SDFV.EDGE_LOD) + if (lod && ppp > SDFV.EDGE_LOD) return; batchedDrawEdges( @@ -1966,7 +1999,7 @@ export function drawStateContents( export function drawStateMachine( stateMachineGraph: DagreSDFG, ctx: CanvasRenderingContext2D, - renderer: SDFGRenderer, ppp: number, lod?: number, + renderer: SDFGRenderer, ppp: number, lod?: boolean, visibleRect?: SimpleRect, mousePos?: Point2D ): void { if (!lod || ppp < SDFV.EDGE_LOD) @@ -1976,29 +2009,35 @@ export function drawStateMachine( ); for (const nodeId of stateMachineGraph.nodes()) { - const node = stateMachineGraph.node(nodeId); + const block = stateMachineGraph.node(nodeId); - if (lod && (Math.max(node.width, node.height) / ppp < SDFV.STATE_LOD)) { - node.simple_draw(renderer, ctx, mousePos); - node.debug_draw(renderer, ctx); + if (lod && (Math.max(block.width, block.height) / ppp) < SDFV.STATE_LOD) { + block.simple_draw(renderer, ctx, mousePos); + block.debug_draw(renderer, ctx); continue; } - // Skip invisible states - if (lod && visibleRect && !node.intersect( + // Skip invisible states. + if (lod && visibleRect && !block.intersect( visibleRect.x, visibleRect.y, visibleRect.w, visibleRect.h - )) + )) { continue; + } - node.draw(renderer, ctx, mousePos); - node.debug_draw(renderer, ctx); + block.draw(renderer, ctx, mousePos); + block.debug_draw(renderer, ctx); - const ng = node.data.graph; - if (!node.attributes().is_collapsed && ng) { - if (node instanceof State) - drawStateContents(ng, ctx, renderer, ppp, lod, visibleRect, mousePos); - else - drawStateMachine(ng, ctx, renderer, ppp, lod, visibleRect, mousePos); + const ng = block.data.graph; + if (!block.attributes().is_collapsed && ng) { + if (block instanceof State) { + drawStateContents( + ng, ctx, renderer, ppp, lod, visibleRect, mousePos + ); + } else { + drawStateMachine( + ng, ctx, renderer, ppp, lod, visibleRect, mousePos + ); + } } } } @@ -2013,6 +2052,7 @@ export function drawSDFG( return; const ppp = cManager.points_per_pixel(); const visibleRect = renderer.get_visible_rect() ?? undefined; + console.log(ppp); drawStateMachine( g, ctx, renderer, ppp, (ctx as any).lod, visibleRect, mousePos diff --git a/src/sdfv.ts b/src/sdfv.ts index 67a01fa8..91ec5d6c 100644 --- a/src/sdfv.ts +++ b/src/sdfv.ts @@ -50,7 +50,7 @@ export class SDFV { // Points-per-pixel threshold for not drawing memlets/interstate edges. public static EDGE_LOD: number = 8; // Points-per-pixel threshold for not drawing node shapes and labels. - public static NODE_LOD: number = 60; + public static NODE_LOD: number = 4.0; // Pixel threshold for not drawing state contents. public static STATE_LOD: number = 50; From 09d8ed6dfdf04f2354bd958e2a6b32753f9224f3 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Tue, 29 Aug 2023 11:51:08 +0200 Subject: [PATCH 3/5] Improved loop rendering --- sdfv.css | 3 +- src/renderer/renderer.ts | 61 +++++++++- src/renderer/renderer_elements.ts | 196 ++++++++++++++++++++++++------ 3 files changed, 214 insertions(+), 46 deletions(-) diff --git a/sdfv.css b/sdfv.css index a984bbfd..519b2ced 100644 --- a/sdfv.css +++ b/sdfv.css @@ -366,7 +366,8 @@ pre.code code { --node-missing-background-color: red; --state-background-color: #deebf7; --state-foreground-color: #000000; - --loop-background-color: #e0e0e0; + --loop-background-color: #ffffff; + --loop-background-simple-color: #e0e0e0; --loop-foreground-color: #000000; --interstate-edge-color: #86add9; --connector-scoped-color: #c1dfe690; diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts index 87be271e..b014db41 100644 --- a/src/renderer/renderer.ts +++ b/src/renderer/renderer.ts @@ -47,12 +47,13 @@ import { deepCopy, intersectRect, showErrorModal } from '../utils/utils'; import { CanvasManager } from './canvas_manager'; import { AccessNode, Connector, - Edge, EntryNode, InterstateEdge, Memlet, NestedSDFG, + Edge, EntryNode, InterstateEdge, LoopScopeBlock, Memlet, NestedSDFG, SDFG, SDFGElement, SDFGElementType, SDFGElements, SDFGNode, + ScopeBlock, State, drawSDFG, offset_sdfg, @@ -2624,6 +2625,8 @@ export class SDFGRenderer extends EventEmitter { let sdfg_elem = null; if (foreground_elem instanceof State) sdfg_elem = foreground_elem.data.state; + else if (foreground_elem instanceof ScopeBlock) + sdfg_elem = foreground_elem.data.block; else if (foreground_elem instanceof SDFGNode) { sdfg_elem = foreground_elem.data.node; @@ -3272,7 +3275,7 @@ function relayoutStateMachine( sdfg: JsonSDFG, sdfgList: SDFGListType, stateParentList: any[], omitAccessNodes: boolean, parent?: SDFGElement ): DagreSDFG { - const BLOCK_MARGIN = 4 * SDFV.LINEHEIGHT; + const BLOCK_MARGIN = 3 * SDFV.LINEHEIGHT; // Layout the state machine as a dagre graph. const g: DagreSDFG = new dagre.graphlib.Graph(); @@ -3307,8 +3310,32 @@ function relayoutStateMachine( blockInfo.label = block.id.toString(); let blockGraph = null; if (block.attributes.is_collapsed) { - blockInfo.width = ctx.measureText(blockInfo.label).width; blockInfo.height = SDFV.LINEHEIGHT; + if (blockElem instanceof LoopScopeBlock) { + const oldFont = ctx.font; + ctx.font = LoopScopeBlock.LOOP_STATEMENT_FONT; + const labelWidths = [ + ctx.measureText( + (block.attributes.scope_condition?.string_data ?? '') + + 'while' + ).width, + ctx.measureText( + (block.attributes.init_statement?.string_data ?? '') + + 'init' + ).width, + ctx.measureText( + (block.attributes.update_statement?.string_data ?? '') + + 'update' + ).width, + ]; + const maxLabelWidth = Math.max(...labelWidths); + ctx.font = oldFont; + blockInfo.width = Math.max( + maxLabelWidth, ctx.measureText(block.label).width + ) + 3 * LoopScopeBlock.META_LABEL_MARGIN; + } else if (blockElem instanceof State) { + blockInfo.width = ctx.measureText(blockInfo.label).width; + } } else { blockGraph = relayoutSDFGBlock( ctx, block, sdfg, sdfgList, stateParentList, omitAccessNodes, @@ -3319,6 +3346,19 @@ function relayoutStateMachine( } blockInfo.width += 2 * BLOCK_MARGIN; blockInfo.height += 2 * BLOCK_MARGIN; + + if (blockElem instanceof LoopScopeBlock) { + // Add spacing for the condition if the loop is not inverted. + if (!block.attributes.inverted) + blockInfo.height += LoopScopeBlock.CONDITION_SPACING; + // If there's an init statement, add space for it. + if (block.attributes.init_statement) + blockInfo.height += LoopScopeBlock.INIT_SPACING; + // If there's an update statement, also add space for it. + if (block.attributes.update_statement) + blockInfo.height += LoopScopeBlock.UPDATE_SPACING; + } + blockElem.data.layout = blockInfo; blockElem.data.graph = blockGraph; blockElem.set_layout(); @@ -3385,9 +3425,20 @@ function relayoutStateMachine( y: topleft.y + BLOCK_MARGIN }); } else { + // Base spacing for the inside. + let topSpacing = BLOCK_MARGIN; + + if (gBlock instanceof LoopScopeBlock) { + // Add spacing for the condition if the loop isn't inverted. + if (!block.attributes.inverted) + topSpacing += LoopScopeBlock.CONDITION_SPACING; + // If there's an init statement, add space for it. + if (block.attributes.init_statement) + topSpacing += LoopScopeBlock.INIT_SPACING; + } offset_sdfg(block as any, gBlock.data.graph, { - x: topleft.x + SDFV.LINEHEIGHT, - y: topleft.y + SDFV.LINEHEIGHT + x: topleft.x + BLOCK_MARGIN, + y: topleft.y + topSpacing, }); } } diff --git a/src/renderer/renderer_elements.ts b/src/renderer/renderer_elements.ts index f1c83782..4860a171 100644 --- a/src/renderer/renderer_elements.ts +++ b/src/renderer/renderer_elements.ts @@ -37,6 +37,8 @@ export enum SDFGElementType { PipelineExit = 'PipelineExit', Reduce = 'Reduce', BasicBlock = 'BasicBlock', + ControlFlowBlock = 'ControlFlowBlock', + ScopeBlock = 'ScopeBlock', LoopScopeBlock = 'LoopScopeBlock', } @@ -223,7 +225,16 @@ export class SDFG extends SDFGElement { export class SDFGShell extends SDFG { } -export class State extends SDFGElement { +export class ControlFlowBlock extends SDFGElement { +} + +export class BasicBlock extends SDFGElement { +} + +export class ScopeBlock extends ControlFlowBlock { +} + +export class State extends BasicBlock { public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, @@ -373,24 +384,44 @@ export class State extends SDFGElement { } -export class LoopScopeBlock extends SDFGElement { +export class LoopScopeBlock extends ScopeBlock { + + public static readonly META_LABEL_MARGIN: number = 5; + + public static get CONDITION_SPACING(): number { + return 3 * SDFV.LINEHEIGHT; + } + + public static get INIT_SPACING(): number { + return 3 * SDFV.LINEHEIGHT; + } + + public static get UPDATE_SPACING(): number { + return 3 * SDFV.LINEHEIGHT; + } + + public static get LOOP_STATEMENT_FONT(): string { + return (SDFV.DEFAULT_CANVAS_FONTSIZE * 1.5).toString() + + 'px sans-serif'; + } public draw( renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, _mousepos?: Point2D ): void { const topleft = this.topleft(); - const visible_rect = renderer.get_visible_rect(); + const visibleRect = renderer.get_visible_rect(); + let clamped; - if (visible_rect) + if (visibleRect) clamped = { - x: Math.max(topleft.x, visible_rect.x), - y: Math.max(topleft.y, visible_rect.y), + x: Math.max(topleft.x, visibleRect.x), + y: Math.max(topleft.y, visibleRect.y), x2: Math.min( - topleft.x + this.width, visible_rect.x + visible_rect.w + topleft.x + this.width, visibleRect.x + visibleRect.w ), y2: Math.min( - topleft.y + this.height, visible_rect.y + visible_rect.h + topleft.y + this.height, visibleRect.y + visibleRect.h ), w: 0, h: 0, @@ -412,19 +443,119 @@ export class LoopScopeBlock extends SDFGElement { w: this.width, h: this.height }; + // Draw the loop background below everything and stroke the border. ctx.fillStyle = this.getCssProperty( renderer, '--loop-background-color' ); + ctx.strokeStyle = this.getCssProperty( + renderer, '--loop-foreground-color' + ); ctx.fillRect(clamped.x, clamped.y, clamped.w, clamped.h); + ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h); ctx.fillStyle = this.getCssProperty( renderer, '--loop-foreground-color' ); - ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h); - if (visible_rect && visible_rect.x <= topleft.x && - visible_rect.y <= topleft.y + SDFV.LINEHEIGHT && + const oldFont = ctx.font; + let topSpacing = LoopScopeBlock.META_LABEL_MARGIN; + let remainingHeight = this.height; + + // Draw the init statement if there is one. + if (this.attributes().init_statement) { + topSpacing += LoopScopeBlock.INIT_SPACING; + const initBottomLineY = topleft.y + LoopScopeBlock.INIT_SPACING; + ctx.beginPath(); + ctx.moveTo(topleft.x, initBottomLineY); + ctx.lineTo(topleft.x + this.width, initBottomLineY); + ctx.stroke(); + + ctx.font = LoopScopeBlock.LOOP_STATEMENT_FONT; + const initStatement = this.attributes().init_statement.string_data; + const initTextY = ( + (topleft.y + (LoopScopeBlock.INIT_SPACING / 2)) + + (SDFV.LINEHEIGHT / 2) + ); + const initTextMetrics = ctx.measureText(initStatement); + const initTextX = this.x - (initTextMetrics.width / 2); + ctx.fillText(initStatement, initTextX, initTextY); + + ctx.font = oldFont; + ctx.fillText( + 'init', topleft.x + LoopScopeBlock.META_LABEL_MARGIN, initTextY + ); + } + + // Draw the condition (either on top if the loop is a regularly + // structured loop, or on the bottom if the loop is an inverted + // (do-while-style) loop). If the condition is drawn on top, make sure + // the init statement spacing is respected if there is one. + let condTopY = topleft.y; + let condLineY = condTopY + LoopScopeBlock.CONDITION_SPACING; + if (this.attributes().inverted) { + condTopY = topleft.y + + (this.height - LoopScopeBlock.CONDITION_SPACING); + condLineY = condTopY - LoopScopeBlock.CONDITION_SPACING; + } else if (this.attributes().init_statement) { + condTopY += LoopScopeBlock.INIT_SPACING; + condLineY = condTopY + LoopScopeBlock.CONDITION_SPACING; + } + topSpacing += LoopScopeBlock.CONDITION_SPACING; + ctx.beginPath(); + ctx.moveTo(topleft.x, condLineY); + ctx.lineTo(topleft.x + this.width, condLineY); + ctx.stroke(); + ctx.font = LoopScopeBlock.LOOP_STATEMENT_FONT; + const condStatement = this.attributes().scope_condition.string_data; + const condTextY = ( + (condTopY + (LoopScopeBlock.CONDITION_SPACING / 2)) + + (SDFV.LINEHEIGHT / 2) + ); + const condTextMetrics = ctx.measureText(condStatement); + const condTextX = this.x - (condTextMetrics.width / 2); + ctx.fillText(condStatement, condTextX, condTextY); + ctx.font = oldFont; + ctx.fillText( + 'while', topleft.x + LoopScopeBlock.META_LABEL_MARGIN, condTextY + ); + + // Draw the update statement if there is one. + if (this.attributes().update_statement) { + remainingHeight -= LoopScopeBlock.UPDATE_SPACING; + const updateTopY = topleft.y + ( + this.height - LoopScopeBlock.UPDATE_SPACING + ); + ctx.beginPath(); + ctx.moveTo(topleft.x, updateTopY); + ctx.lineTo(topleft.x + this.width, updateTopY); + ctx.stroke(); + + ctx.font = LoopScopeBlock.LOOP_STATEMENT_FONT; + const updateStatement = + this.attributes().update_statement.string_data; + const updateTextY = ( + (updateTopY + (LoopScopeBlock.UPDATE_SPACING / 2)) + + (SDFV.LINEHEIGHT / 2) + ); + const updateTextMetrics = ctx.measureText(updateStatement); + const updateTextX = this.x - (updateTextMetrics.width / 2); + ctx.fillText(updateStatement, updateTextX, updateTextY); + ctx.font = oldFont; + ctx.fillText( + 'update', topleft.x + LoopScopeBlock.META_LABEL_MARGIN, + updateTextY + ); + } + remainingHeight -= topSpacing; + + ctx.font = oldFont; + + if (visibleRect && visibleRect.x <= topleft.x && + visibleRect.y <= topleft.y + SDFV.LINEHEIGHT && SDFVSettings.showStateNames) - ctx.fillText(this.label(), topleft.x, topleft.y + SDFV.LINEHEIGHT); + ctx.fillText( + this.label(), topleft.x + LoopScopeBlock.META_LABEL_MARGIN, + topleft.y + topSpacing + SDFV.LINEHEIGHT + ); // If this state is selected or hovered if ((this.selected || this.highlighted || this.hovered) && @@ -438,13 +569,14 @@ export class LoopScopeBlock extends SDFGElement { // If collapsed, draw a "+" sign in the middle if (this.attributes().is_collapsed) { + const plusCenterY = topleft.y + (remainingHeight / 2) + topSpacing; ctx.beginPath(); - ctx.moveTo(this.x, this.y - SDFV.LINEHEIGHT); - ctx.lineTo(this.x, this.y + SDFV.LINEHEIGHT); + ctx.moveTo(this.x, plusCenterY - SDFV.LINEHEIGHT); + ctx.lineTo(this.x, plusCenterY + SDFV.LINEHEIGHT); ctx.stroke(); ctx.beginPath(); - ctx.moveTo(this.x - SDFV.LINEHEIGHT, this.y); - ctx.lineTo(this.x + SDFV.LINEHEIGHT, this.y); + ctx.moveTo(this.x - SDFV.LINEHEIGHT, plusCenterY); + ctx.lineTo(this.x + SDFV.LINEHEIGHT, plusCenterY); ctx.stroke(); } @@ -459,32 +591,13 @@ export class LoopScopeBlock extends SDFGElement { const topleft = this.topleft(); ctx.fillStyle = this.getCssProperty( - renderer, '--loop-background-color' + renderer, '--loop-background-simple-color' ); ctx.fillRect(topleft.x, topleft.y, this.width, this.height); ctx.fillStyle = this.getCssProperty(renderer, '--loop-foreground-color'); if (mousepos && this.intersect(mousepos.x, mousepos.y)) renderer.set_tooltip((c) => this.tooltip(c)); - - // Draw state name in center without contents (does not look good) - /* - let FONTSIZE = Math.min( - renderer.canvas_manager.points_per_pixel() * 16, 100 - ); - let label = this.label(); - - let oldfont = ctx.font; - ctx.font = FONTSIZE + "px Arial"; - - let textmetrics = ctx.measureText(label); - ctx.fillText( - label, this.x - textmetrics.width / 2.0, - this.y - this.height / 6.0 + FONTSIZE / 2.0 - ); - - ctx.font = oldfont; - */ } public shade( @@ -2011,7 +2124,8 @@ export function drawStateMachine( for (const nodeId of stateMachineGraph.nodes()) { const block = stateMachineGraph.node(nodeId); - if (lod && (Math.max(block.width, block.height) / ppp) < SDFV.STATE_LOD) { + const blockppp = Math.max(block.width, block.height) / ppp; + if (lod && blockppp < SDFV.STATE_LOD) { block.simple_draw(renderer, ctx, mousePos); block.debug_draw(renderer, ctx); continue; @@ -2052,7 +2166,6 @@ export function drawSDFG( return; const ppp = cManager.points_per_pixel(); const visibleRect = renderer.get_visible_rect() ?? undefined; - console.log(ppp); drawStateMachine( g, ctx, renderer, ppp, (ctx as any).lod, visibleRect, mousePos @@ -2147,7 +2260,7 @@ type AdaptiveTextPadding = { top?: number, right?: number, bottom?: number, -} +}; export function drawAdaptiveText( ctx: CanvasRenderingContext2D, renderer: SDFGRenderer, far_text: string, @@ -2332,7 +2445,6 @@ export const SDFGElements: { [name: string]: typeof SDFGElement } = { SDFGElement, SDFG, SDFGShell, - State, SDFGNode, InterstateEdge, Memlet, @@ -2352,5 +2464,9 @@ export const SDFGElements: { [name: string]: typeof SDFGElement } = { NestedSDFG, ExternalNestedSDFG, LibraryNode, + ControlFlowBlock, + BasicBlock, + State, + ScopeBlock, LoopScopeBlock, }; From 1102af15c27e0a1549ac9a706bf1104fe03f1256 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Wed, 30 Aug 2023 07:27:08 +0200 Subject: [PATCH 4/5] Sync --- .vscode/launch.json | 2 +- sdfv.css | 4 ++-- webpack.config.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f5397ab3..412a5087 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "type": "chrome", "request": "launch", "name": "Launch", - "url": "http://localhost:8080/sdfv.html", + "url": "http://localhost:3000/sdfv.html", "sourceMaps": true, "webRoot": "${workspaceFolder}", "preLaunchTask": "npm: serve", diff --git a/sdfv.css b/sdfv.css index 519b2ced..260f8a00 100644 --- a/sdfv.css +++ b/sdfv.css @@ -67,8 +67,8 @@ body { #contents { position: relative; resize: both; - width: 1024px; - height: 768px; + width: 90%; + height: 90%; border: 1px solid; overflow: hidden; } diff --git a/webpack.config.js b/webpack.config.js index 60122b7b..94666b55 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -66,7 +66,7 @@ module.exports = { }, devtool: 'source-map', devServer: { - port: 8080, + port: 3000, static: { directory: __dirname, }, From a6fb5fdbced187157878741317b273725fce2a37 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 9 Oct 2023 13:19:32 +0200 Subject: [PATCH 5/5] Rewert erroneous change in node LOD --- src/sdfv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdfv.ts b/src/sdfv.ts index 91ec5d6c..bac3f2fe 100644 --- a/src/sdfv.ts +++ b/src/sdfv.ts @@ -50,7 +50,7 @@ export class SDFV { // Points-per-pixel threshold for not drawing memlets/interstate edges. public static EDGE_LOD: number = 8; // Points-per-pixel threshold for not drawing node shapes and labels. - public static NODE_LOD: number = 4.0; + public static NODE_LOD: number = 60.0; // Pixel threshold for not drawing state contents. public static STATE_LOD: number = 50;