diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0f83ac463..22c1a476b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '14.14.0' + node-version: '16.13.0' - name: Install dependencies working-directory: extensions/ql-vscode @@ -82,7 +82,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '14.14.0' + node-version: '16.13.0' - name: Install dependencies working-directory: extensions/ql-vscode @@ -147,7 +147,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '14.14.0' + node-version: '16.13.0' - name: Install dependencies working-directory: extensions/ql-vscode diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05f57aac3..9b084159a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '10.18.1' + node-version: '16.13.0' - name: Install dependencies run: | diff --git a/extensions/ql-vscode/package-lock.json b/extensions/ql-vscode/package-lock.json index 159520313..94f03dd32 100644 --- a/extensions/ql-vscode/package-lock.json +++ b/extensions/ql-vscode/package-lock.json @@ -14,6 +14,8 @@ "@primer/react": "^34.3.0", "child-process-promise": "^2.2.1", "classnames": "~2.2.6", + "d3": "^6.3.1", + "d3-graphviz": "^2.6.1", "fs-extra": "^9.0.1", "glob-promise": "^3.4.0", "js-yaml": "^3.14.0", @@ -44,6 +46,8 @@ "@types/chai-as-promised": "~7.1.2", "@types/child-process-promise": "^2.2.1", "@types/classnames": "~2.2.9", + "@types/d3": "^6.2.0", + "@types/d3-graphviz": "^2.6.6", "@types/del": "^4.0.0", "@types/fs-extra": "^9.0.6", "@types/glob": "^7.1.1", @@ -932,6 +936,310 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/d3": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-6.7.5.tgz", + "integrity": "sha512-TUZ6zuT/KIvbHSv81kwAiO5gG5aTuoiLGnWR/KxHJ15Idy/xmGUXaaF5zMG+UMIsndcGlSHTmrvwRgdvZlNKaA==", + "dev": true, + "dependencies": { + "@types/d3-array": "^2", + "@types/d3-axis": "^2", + "@types/d3-brush": "^2", + "@types/d3-chord": "^2", + "@types/d3-color": "^2", + "@types/d3-contour": "^2", + "@types/d3-delaunay": "^5", + "@types/d3-dispatch": "^2", + "@types/d3-drag": "^2", + "@types/d3-dsv": "^2", + "@types/d3-ease": "^2", + "@types/d3-fetch": "^2", + "@types/d3-force": "^2", + "@types/d3-format": "^2", + "@types/d3-geo": "^2", + "@types/d3-hierarchy": "^2", + "@types/d3-interpolate": "^2", + "@types/d3-path": "^2", + "@types/d3-polygon": "^2", + "@types/d3-quadtree": "^2", + "@types/d3-random": "^2", + "@types/d3-scale": "^3", + "@types/d3-scale-chromatic": "^2", + "@types/d3-selection": "^2", + "@types/d3-shape": "^2", + "@types/d3-time": "^2", + "@types/d3-time-format": "^3", + "@types/d3-timer": "^2", + "@types/d3-transition": "^2", + "@types/d3-zoom": "^2" + } + }, + "node_modules/@types/d3-array": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.3.tgz", + "integrity": "sha512-hN879HLPTVqZV3FQEXy7ptt083UXwguNbnxdTGzVW4y4KjX5uyNKljrQixZcSJfLyFirbpUokxpXtvR+N5+KIg==", + "dev": true + }, + "node_modules/@types/d3-axis": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-2.1.3.tgz", + "integrity": "sha512-QjXjwZ0xzyrW2ndkmkb09ErgWDEYtbLBKGui73QLMFm3woqWpxptfD5Y7vqQdybMcu7WEbjZ5q+w2w5+uh2IjA==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^2" + } + }, + "node_modules/@types/d3-brush": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-2.1.2.tgz", + "integrity": "sha512-DnZmjdK1ycX1CMiW9r5E3xSf1tL+bp3yob1ON8bf0xB0/odfmGXeYOTafU+2SmU1F0/dvcqaO4SMjw62onOu6A==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^2" + } + }, + "node_modules/@types/d3-chord": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-2.0.3.tgz", + "integrity": "sha512-koIqSNQLPRQPXt7c55hgRF6Lr9Ps72r1+Biv55jdYR+SHJ463MsB2lp4ktzttFNmrQw/9yWthf/OmSUj5dNXKw==", + "dev": true + }, + "node_modules/@types/d3-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", + "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==", + "dev": true + }, + "node_modules/@types/d3-contour": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-2.0.4.tgz", + "integrity": "sha512-WMac1xV/mXAgkgr5dUvzsBV5OrgNZDBDpJk9s3v2SadTqGgDRirKABb2Ek2H1pFlYVH4Oly9XJGnuzxKDduqWA==", + "dev": true, + "dependencies": { + "@types/d3-array": "^2", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-5.3.1.tgz", + "integrity": "sha512-F6itHi2DxdatHil1rJ2yEFUNhejj8+0Acd55LZ6Ggwbdoks0+DxVY2cawNj16sjCBiWvubVlh6eBMVsYRNGLew==", + "dev": true + }, + "node_modules/@types/d3-dispatch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-2.0.1.tgz", + "integrity": "sha512-eT2K8uG3rXkmRiCpPn0rNrekuSLdBfV83vbTvfZliA5K7dbeaqWS/CBHtJ9SQoF8aDTsWSY4A0RU67U/HcKdJQ==", + "dev": true + }, + "node_modules/@types/d3-drag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-2.0.2.tgz", + "integrity": "sha512-m9USoFaTgVw2mmE7vLjWTApT9dMxMlql/dl3Gj503x+1a2n6K455iDWydqy2dfCpkUBCoF82yRGDgcSk9FUEyQ==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^2" + } + }, + "node_modules/@types/d3-dsv": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-2.0.2.tgz", + "integrity": "sha512-T4aL2ZzaILkLGKbxssipYVRs8334PSR9FQzTGftZbc3jIPGkiXXS7qUCh8/q8UWFzxBZQ92dvR0v7+AM9wL2PA==", + "dev": true + }, + "node_modules/@types/d3-ease": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-2.0.1.tgz", + "integrity": "sha512-Af1ftZXv82ktPCk1+Vxe7f+VSfxDsQ1mwwakDl17+UzI/ii3vsDIAzaBDDSEQd2Cg9BYPTSx8wXH8rJNDuSjeg==", + "dev": true + }, + "node_modules/@types/d3-fetch": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-2.0.2.tgz", + "integrity": "sha512-sllsCSWrNdSvzOJWN5RnxkmtvW9pCttONGajSxHX9FUQ9kOkGE391xlz6VDBdZxLnpwjp3I+mipbwsaCjq4m5A==", + "dev": true, + "dependencies": { + "@types/d3-dsv": "^2" + } + }, + "node_modules/@types/d3-force": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-2.1.4.tgz", + "integrity": "sha512-1XVRc2QbeUSL1FRVE53Irdz7jY+drTwESHIMVirCwkAAMB/yVC8ezAfx/1Alq0t0uOnphoyhRle1ht5CuPgSJQ==", + "dev": true + }, + "node_modules/@types/d3-format": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-2.0.2.tgz", + "integrity": "sha512-OhQPuTeeMhD9A0Ksqo4q1S9Z1Q57O/t4tTPBxBQxRB4IERnxeoEYLPe72fA/GYpPSUrfKZVOgLHidkxwbzLdJA==", + "dev": true + }, + "node_modules/@types/d3-geo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-2.0.3.tgz", + "integrity": "sha512-kFwLEMXq1mGJ2Eho7KrOUYvLcc2YTDeKj+kTFt87JlEbRQ0rgo8ZENNb5vTYmZrJ2xL/vVM5M7yqVZGOPH2JFg==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-graphviz": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/d3-graphviz/-/d3-graphviz-2.6.7.tgz", + "integrity": "sha512-dKJjD5HiFvAmC0FL/c70VB1diie8FCpyiCZfxMlf6TwYBqUyFvS4XJt6MoxjIuQTJhKDBGzrIvDOgM8gYMLSVA==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^1", + "@types/d3-transition": "^1", + "@types/d3-zoom": "^1" + } + }, + "node_modules/@types/d3-graphviz/node_modules/@types/d3-color": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz", + "integrity": "sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA==", + "dev": true + }, + "node_modules/@types/d3-graphviz/node_modules/@types/d3-interpolate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz", + "integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==", + "dev": true, + "dependencies": { + "@types/d3-color": "^1" + } + }, + "node_modules/@types/d3-graphviz/node_modules/@types/d3-selection": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.3.tgz", + "integrity": "sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==", + "dev": true + }, + "node_modules/@types/d3-graphviz/node_modules/@types/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-graphviz/node_modules/@types/d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-3kHkL6sPiDdbfGhzlp5gIHyu3kULhtnHTTAl3UBZVtWB1PzcLL8vdmz5mTx7plLiUqOA2Y+yT2GKjt/TdA2p7Q==", + "dev": true, + "dependencies": { + "@types/d3-interpolate": "^1", + "@types/d3-selection": "^1" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-2.0.2.tgz", + "integrity": "sha512-6PlBRwbjUPPt0ZFq/HTUyOAdOF3p73EUYots74lHMUyAVtdFSOS/hAeNXtEIM9i7qRDntuIblXxHGUMb9MuNRA==", + "dev": true + }, + "node_modules/@types/d3-interpolate": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz", + "integrity": "sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw==", + "dev": true, + "dependencies": { + "@types/d3-color": "^2" + } + }, + "node_modules/@types/d3-path": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz", + "integrity": "sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw==", + "dev": true + }, + "node_modules/@types/d3-polygon": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-2.0.1.tgz", + "integrity": "sha512-X3XTIwBxlzRIWe4yaD1KsmcfItjSPLTGL04QDyP08jyHDVsnz3+NZJMwtD4vCaTAVpGSjbqS+jrBo8cO2V/xMA==", + "dev": true + }, + "node_modules/@types/d3-quadtree": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-2.0.2.tgz", + "integrity": "sha512-KgWL4jlz8QJJZX01E4HKXJ9FLU94RTuObsAYqsPp8YOAcYDmEgJIQJ+ojZcnKUAnrUb78ik8JBKWas5XZPqJnQ==", + "dev": true + }, + "node_modules/@types/d3-random": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-2.2.1.tgz", + "integrity": "sha512-5vvxn6//poNeOxt1ZwC7QU//dG9QqABjy1T7fP/xmFHY95GnaOw3yABf29hiu5SR1Oo34XcpyHFbzod+vemQjA==", + "dev": true + }, + "node_modules/@types/d3-scale": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", + "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", + "dev": true, + "dependencies": { + "@types/d3-time": "^2" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-2.0.1.tgz", + "integrity": "sha512-3EuZlbPu+pvclZcb1DhlymTWT2W+lYsRKBjvkH2ojDbCWDYavifqu1vYX9WGzlPgCgcS4Alhk1+zapXbGEGylQ==", + "dev": true + }, + "node_modules/@types/d3-selection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.1.tgz", + "integrity": "sha512-3mhtPnGE+c71rl/T5HMy+ykg7migAZ4T6gzU0HxpgBFKcasBrSnwRbYV1/UZR6o5fkpySxhWxAhd7yhjj8jL7g==", + "dev": true + }, + "node_modules/@types/d3-shape": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", + "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", + "dev": true, + "dependencies": { + "@types/d3-path": "^2" + } + }, + "node_modules/@types/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", + "dev": true + }, + "node_modules/@types/d3-time-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.1.tgz", + "integrity": "sha512-5GIimz5IqaRsdnxs4YlyTZPwAMfALu/wA4jqSiuqgdbCxUZ2WjrnwANqOtoBJQgeaUTdYNfALJO0Yb0YrDqduA==", + "dev": true + }, + "node_modules/@types/d3-timer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-2.0.1.tgz", + "integrity": "sha512-TF8aoF5cHcLO7W7403blM7L1T+6NF3XMyN3fxyUolq2uOcFeicG/khQg/dGxiCJWoAcmYulYN7LYSRKO54IXaA==", + "dev": true + }, + "node_modules/@types/d3-transition": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-2.0.2.tgz", + "integrity": "sha512-376TICEykdXOEA9uUIYpjshEkxfGwCPnkHUl8+6gphzKbf5NMnUhKT7wR59Yxrd9wtJ/rmE3SVLx6/8w4eY6Zg==", + "dev": true, + "dependencies": { + "@types/d3-selection": "^2" + } + }, + "node_modules/@types/d3-zoom": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-2.0.3.tgz", + "integrity": "sha512-9X9uDYKk2U8w775OHj36s9Q7GkNAnJKGw6+sbkP5DpHSjELwKvTGzEK6+IISYfLpJRL/V3mRXMhgDnnJ5LkwJg==", + "dev": true, + "dependencies": { + "@types/d3-interpolate": "^2", + "@types/d3-selection": "^2" + } + }, "node_modules/@types/del": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/del/-/del-4.0.0.tgz", @@ -983,6 +1291,12 @@ "@types/node": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -1444,9 +1758,9 @@ } }, "node_modules/@types/vscode": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.59.0.tgz", - "integrity": "sha512-Zg38rusx2nU6gy6QdF7v4iqgxNfxzlBlDhrRCjOiPQp+sfaNrp3f9J6OHIhpGNN1oOAca4+9Hq0+8u3jwzPMlQ==", + "version": "1.63.1", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.63.1.tgz", + "integrity": "sha512-Z+ZqjRcnGfHP86dvx/BtSwWyZPKQ/LBdmAVImY82TphyjOw2KgTKcp7Nx92oNwCTsHzlshwexAG/WiY2JuUm3g==", "dev": true }, "node_modules/@types/webpack": { @@ -1666,9 +1980,6 @@ "@typescript-eslint/types": "4.26.0", "@typescript-eslint/visitor-keys": "4.26.0" }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" @@ -1979,10 +2290,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0" - } + "dev": true }, "node_modules/agent-base": { "version": "4.3.0", @@ -2029,10 +2337,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "peerDependencies": { - "ajv": ">=5.0.0" - } + "dev": true }, "node_modules/ajv-keywords": { "version": "3.5.2", @@ -2062,9 +2367,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-escapes/node_modules/type-fest": { @@ -2074,9 +2376,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-gray": { @@ -2308,9 +2607,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-initial": { @@ -2615,44 +2911,6 @@ "node": ">=0.10.0" } }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", @@ -2687,9 +2945,6 @@ "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" } }, "node_modules/binary-extensions": { @@ -2708,9 +2963,6 @@ "dev": true, "engines": { "node": ">=0.8" - }, - "funding": { - "url": "https://bevry.me/fund" } }, "node_modules/bindings": { @@ -2966,9 +3218,6 @@ "dev": true, "dependencies": { "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 5" } }, "node_modules/chainsaw": { @@ -2977,9 +3226,6 @@ "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", "dependencies": { "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" } }, "node_modules/chalk": { @@ -3078,7 +3324,6 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "dev": true, "dependencies": { "anymatch": "^2.0.0", @@ -3098,9 +3343,7 @@ } }, "node_modules/chokidar/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "~6.0.0", "dev": true, "dependencies": { "is-glob": "^3.1.0", @@ -3201,9 +3444,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate/node_modules/ansi-styles": { @@ -3217,9 +3457,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cli-truncate/node_modules/astral-regex": { @@ -3292,18 +3529,6 @@ "node": ">=0.10.0" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui/node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -3592,12 +3817,7 @@ "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } + "dev": true }, "node_modules/core-util-is": { "version": "1.0.2", @@ -3727,9 +3947,6 @@ }, "engines": { "node": ">= 8.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" } }, "node_modules/css-select": { @@ -3806,6 +4023,381 @@ "type": "^1.0.1" } }, + "node_modules/d3": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-6.7.0.tgz", + "integrity": "sha512-hNHRhe+yCDLUG6Q2LwvR/WdNFPOJQ5VWqsJcwIYVeI401+d2/rrCjxSXkiAdIlpx7/73eApFB4Olsmh3YN7a6g==", + "dependencies": { + "d3-array": "2", + "d3-axis": "2", + "d3-brush": "2", + "d3-chord": "2", + "d3-color": "2", + "d3-contour": "2", + "d3-delaunay": "5", + "d3-dispatch": "2", + "d3-drag": "2", + "d3-dsv": "2", + "d3-ease": "2", + "d3-fetch": "2", + "d3-force": "2", + "d3-format": "2", + "d3-geo": "2", + "d3-hierarchy": "2", + "d3-interpolate": "2", + "d3-path": "2", + "d3-polygon": "2", + "d3-quadtree": "2", + "d3-random": "2", + "d3-scale": "3", + "d3-scale-chromatic": "2", + "d3-selection": "2", + "d3-shape": "2", + "d3-time": "2", + "d3-time-format": "3", + "d3-timer": "2", + "d3-transition": "2", + "d3-zoom": "2" + } + }, + "node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-axis": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", + "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" + }, + "node_modules/d3-brush": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", + "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "node_modules/d3-chord": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-2.0.0.tgz", + "integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==", + "dependencies": { + "d3-path": "1 - 2" + } + }, + "node_modules/d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "node_modules/d3-contour": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-2.0.0.tgz", + "integrity": "sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-delaunay": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", + "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", + "dependencies": { + "delaunator": "4" + } + }, + "node_modules/d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "node_modules/d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "node_modules/d3-dsv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", + "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", + "dependencies": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json", + "csv2tsv": "bin/dsv2dsv", + "dsv2dsv": "bin/dsv2dsv", + "dsv2json": "bin/dsv2json", + "json2csv": "bin/json2dsv", + "json2dsv": "bin/json2dsv", + "json2tsv": "bin/json2dsv", + "tsv2csv": "bin/dsv2dsv", + "tsv2json": "bin/dsv2json" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" + }, + "node_modules/d3-fetch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-2.0.0.tgz", + "integrity": "sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw==", + "dependencies": { + "d3-dsv": "1 - 2" + } + }, + "node_modules/d3-force": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", + "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-quadtree": "1 - 2", + "d3-timer": "1 - 2" + } + }, + "node_modules/d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "node_modules/d3-geo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz", + "integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==", + "dependencies": { + "d3-array": "^2.5.0" + } + }, + "node_modules/d3-graphviz": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-2.6.1.tgz", + "integrity": "sha512-878AFSagQyr5tTOrM7YiVYeUC2/NoFcOB3/oew+LAML0xekyJSw9j3WOCUMBsc95KYe9XBYZ+SKKuObVya1tJQ==", + "dependencies": { + "d3-dispatch": "^1.0.3", + "d3-format": "^1.2.0", + "d3-interpolate": "^1.1.5", + "d3-path": "^1.0.5", + "d3-selection": "^1.1.0", + "d3-timer": "^1.0.6", + "d3-transition": "^1.1.1", + "d3-zoom": "^1.5.0", + "viz.js": "^1.8.2" + } + }, + "node_modules/d3-graphviz/node_modules/d3-color": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" + }, + "node_modules/d3-graphviz/node_modules/d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" + }, + "node_modules/d3-graphviz/node_modules/d3-drag": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz", + "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==", + "dependencies": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "node_modules/d3-graphviz/node_modules/d3-ease": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz", + "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==" + }, + "node_modules/d3-graphviz/node_modules/d3-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" + }, + "node_modules/d3-graphviz/node_modules/d3-interpolate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz", + "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==", + "dependencies": { + "d3-color": "1" + } + }, + "node_modules/d3-graphviz/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "node_modules/d3-graphviz/node_modules/d3-selection": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz", + "integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==" + }, + "node_modules/d3-graphviz/node_modules/d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" + }, + "node_modules/d3-graphviz/node_modules/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==", + "dependencies": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "node_modules/d3-graphviz/node_modules/d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==", + "dependencies": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "node_modules/d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "node_modules/d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "dependencies": { + "d3-color": "1 - 2" + } + }, + "node_modules/d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "node_modules/d3-polygon": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz", + "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ==" + }, + "node_modules/d3-quadtree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", + "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" + }, + "node_modules/d3-random": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-2.2.2.tgz", + "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" + }, + "node_modules/d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "dependencies": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", + "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", + "dependencies": { + "d3-color": "1 - 2", + "d3-interpolate": "1 - 2" + } + }, + "node_modules/d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" + }, + "node_modules/d3-shape": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", + "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "dependencies": { + "d3-path": "1 - 2" + } + }, + "node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "dependencies": { + "d3-time": "1 - 2" + } + }, + "node_modules/d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, + "node_modules/d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "dependencies": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + }, + "peerDependencies": { + "d3-selection": "2" + } + }, + "node_modules/d3-zoom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", + "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", + "dependencies": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3830,7 +4422,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" @@ -3959,18 +4550,6 @@ "node": ">=0.10.0" } }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/define-property/node_modules/is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", @@ -4022,6 +4601,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -4073,10 +4657,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.4.1.tgz", "integrity": "sha512-NpZ7IOVUfea/kAx4+ub4NIYZyRCSymjXM5BZxnThs3ul9gAKqjm7J8QDDQW3Ecuo2XxjNLoWLeKmrPUWKNZaYw==", - "dev": true, - "peerDependencies": { - "diagnostic-channel": "*" - } + "dev": true }, "node_modules/diagnostic-channel/node_modules/semver": { "version": "5.7.1", @@ -4233,9 +4814,6 @@ "lru-cache": "^4.1.5", "semver": "^5.6.0", "sigmund": "^1.0.1" - }, - "bin": { - "editorconfig": "bin/editorconfig" } }, "node_modules/editorconfig/node_modules/commander": { @@ -4383,9 +4961,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-module-lexer": { @@ -4406,9 +4981,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es5-ext": { @@ -4536,9 +5108,6 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-plugin-react": { @@ -4562,9 +5131,6 @@ }, "engines": { "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { @@ -4651,7 +5217,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" @@ -4804,9 +5369,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/execa/node_modules/cross-spawn": { @@ -4844,15 +5406,6 @@ "node": ">=8" } }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/execa/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5125,27 +5678,6 @@ "node": ">=8" } }, - "node_modules/fast-glob/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-glob/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/fast-glob/node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -5159,18 +5691,6 @@ "node": ">=8.6" } }, - "node_modules/fast-glob/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5217,9 +5737,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/file-entry-cache": { @@ -5500,7 +6017,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", "dev": true, "hasInstallScript": true, "optional": true, @@ -5647,9 +6163,6 @@ }, "engines": { "node": ">=4" - }, - "peerDependencies": { - "glob": "*" } }, "node_modules/glob-stream": { @@ -5674,9 +6187,7 @@ } }, "node_modules/glob-stream/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "~6.0.0", "dev": true, "dependencies": { "is-glob": "^3.1.0", @@ -5759,9 +6270,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { @@ -5827,7 +6335,7 @@ "dependencies": { "glob-watcher": "^5.0.3", "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", + "undertaker": "^1.2.7", "vinyl-fs": "^3.0.0" }, "bin": { @@ -5919,9 +6427,6 @@ }, "engines": { "node": ">= 8" - }, - "peerDependencies": { - "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" } }, "node_modules/gulp-typescript/node_modules/ansi-colors": { @@ -5942,18 +6447,6 @@ "node": ">= 8" } }, - "node_modules/gulp/node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/gulp/node_modules/gulp-cli": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", @@ -6025,9 +6518,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-value": { @@ -6162,7 +6652,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" @@ -6188,7 +6677,6 @@ "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==", "dev": true, - "hasInstallScript": true, "dependencies": { "chalk": "^4.0.0", "ci-info": "^2.0.0", @@ -6207,25 +6695,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" - } - }, - "node_modules/husky/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/husky/node_modules/chalk": { @@ -6239,55 +6708,12 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/husky/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/husky/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/husky/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/husky/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" } }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6429,9 +6855,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/inquirer/node_modules/chalk": { @@ -6445,9 +6868,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/inquirer/node_modules/color-convert": { @@ -6515,6 +6935,11 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -6601,9 +7026,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-descriptor": { @@ -6637,9 +7059,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-descriptor": { @@ -6807,9 +7226,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-regexp": { @@ -6849,9 +7265,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { @@ -6864,9 +7277,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-unc-path": { @@ -7054,10 +7464,8 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" } }, "node_modules/jsonfile/node_modules/universalify": { @@ -7230,9 +7638,6 @@ }, "bin": { "lint-staged": "bin/lint-staged.js" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" } }, "node_modules/lint-staged/node_modules/ansi-styles": { @@ -7246,9 +7651,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/lint-staged/node_modules/braces": { @@ -7274,9 +7676,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/lint-staged/node_modules/color-convert": { @@ -7301,7 +7700,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" @@ -7402,9 +7800,6 @@ }, "engines": { "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" } }, "node_modules/listr2/node_modules/ansi-styles": { @@ -7418,9 +7813,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/listr2/node_modules/chalk": { @@ -7434,29 +7826,8 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/listr2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/listr2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/listr2/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7592,9 +7963,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-symbols/node_modules/chalk": { @@ -7608,9 +7976,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/log-symbols/node_modules/color-convert": { @@ -7665,9 +8030,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-styles": { @@ -7681,9 +8043,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-update/node_modules/astral-regex": { @@ -7695,24 +8054,6 @@ "node": ">=8" } }, - "node_modules/log-update/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-update/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -7725,21 +8066,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" } }, "node_modules/log-update/node_modules/wrap-ansi": { @@ -8121,10 +8447,6 @@ "dev": true, "engines": { "npm": ">1.2" - }, - "peerDependencies": { - "mocha": "*", - "sinon": "*" } }, "node_modules/mocha/node_modules/ansi-styles": { @@ -8271,9 +8593,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/fill-range": { @@ -8299,9 +8618,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/fsevents": { @@ -8369,21 +8685,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8402,36 +8703,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9035,9 +9306,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.map": { @@ -9091,9 +9359,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/once": { @@ -9204,9 +9469,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -9231,9 +9493,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -9977,9 +10236,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { @@ -9989,9 +10245,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/remove-bom-buffer": { @@ -10111,9 +10364,6 @@ "dev": true, "dependencies": { "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-cwd": { @@ -10175,7 +10425,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, "node_modules/restore-cursor": { @@ -10253,6 +10502,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "node_modules/rxjs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", @@ -10282,8 +10536,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/scheduler": { "version": "0.20.2", @@ -10306,10 +10559,6 @@ }, "engines": { "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" } }, "node_modules/semver": { @@ -10504,21 +10753,13 @@ "diff": "^4.0.2", "nise": "^4.0.1", "supports-color": "^7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" } }, "node_modules/sinon-chai": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true, - "peerDependencies": { - "chai": "^4.0.0", - "sinon": ">=4.0.0 <10.0.0" - } + "dev": true }, "node_modules/sinon/node_modules/has-flag": { "version": "4.0.0", @@ -10722,7 +10963,6 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, "dependencies": { "atob": "^2.1.2", @@ -10755,7 +10995,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", "dev": true }, "node_modules/sparkles": { @@ -10943,9 +11182,6 @@ "internal-slot": "^1.0.2", "regexp.prototype.flags": "^1.3.0", "side-channel": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.padend": { @@ -10959,9 +11195,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { @@ -10972,9 +11205,6 @@ "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { @@ -10985,9 +11215,6 @@ "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/stringify-object": { @@ -11062,9 +11289,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/style-loader": { @@ -11368,9 +11592,6 @@ "dev": true, "engines": { "node": ">=0.8" - }, - "funding": { - "url": "https://bevry.me/fund" } }, "node_modules/through": { @@ -11456,9 +11677,6 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/tmp-promise/node_modules/tmp": { @@ -11575,10 +11793,7 @@ "node_modules/traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "engines": { - "node": "*" - } + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "node_modules/tree-kill": { "version": "1.2.2", @@ -11785,9 +12000,6 @@ }, "engines": { "node": ">=6.0.0" - }, - "peerDependencies": { - "typescript": ">=2.7" } }, "node_modules/ts-protoc-gen": { @@ -11908,9 +12120,6 @@ }, "engines": { "node": ">= 4.2.0" - }, - "peerDependencies": { - "typescript": "^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev" } }, "node_modules/uc.micro": { @@ -12095,7 +12304,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, "node_modules/url-join": { @@ -12240,6 +12448,12 @@ "node": ">=0.10.0" } }, + "node_modules/viz.js": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/viz.js/-/viz.js-1.8.2.tgz", + "integrity": "sha512-W+1+N/hdzLpQZEcvz79n2IgUE9pfx6JLdHh3Kh8RGvLL8P1LdJVQmi2OsDcLdY4QVID4OUy+FPelyerX0nJxIQ==", + "deprecated": "no longer supported" + }, "node_modules/vsce": { "version": "1.88.0", "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.88.0.tgz", @@ -12308,7 +12522,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.6.tgz", "integrity": "sha512-rbzSg7k4NnsCdF4Lz0gI4jl3JLXR0hnlmfFgsY8CSDYhXgdoIxcre8jw5rjkobY0xhSDhbG7xCjP8zxskySJ/g==", - "deprecated": "This package has been renamed to @vscode/extension-telemetry, please update to the new name", "dependencies": { "applicationinsights": "1.7.4" }, @@ -12338,10 +12551,7 @@ "node_modules/vscode-extension-telemetry/node_modules/diagnostic-channel-publishers": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz", - "integrity": "sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==", - "peerDependencies": { - "diagnostic-channel": "*" - } + "integrity": "sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==" }, "node_modules/vscode-extension-telemetry/node_modules/semver": { "version": "5.7.1", @@ -12839,18 +13049,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -12984,9 +13182,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs-unparser/node_modules/decamelize": { @@ -12996,9 +13191,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/node_modules/ansi-regex": { @@ -13102,9 +13294,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zip-a-folder": { @@ -13843,6 +14032,312 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/d3": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-6.7.5.tgz", + "integrity": "sha512-TUZ6zuT/KIvbHSv81kwAiO5gG5aTuoiLGnWR/KxHJ15Idy/xmGUXaaF5zMG+UMIsndcGlSHTmrvwRgdvZlNKaA==", + "dev": true, + "requires": { + "@types/d3-array": "^2", + "@types/d3-axis": "^2", + "@types/d3-brush": "^2", + "@types/d3-chord": "^2", + "@types/d3-color": "^2", + "@types/d3-contour": "^2", + "@types/d3-delaunay": "^5", + "@types/d3-dispatch": "^2", + "@types/d3-drag": "^2", + "@types/d3-dsv": "^2", + "@types/d3-ease": "^2", + "@types/d3-fetch": "^2", + "@types/d3-force": "^2", + "@types/d3-format": "^2", + "@types/d3-geo": "^2", + "@types/d3-hierarchy": "^2", + "@types/d3-interpolate": "^2", + "@types/d3-path": "^2", + "@types/d3-polygon": "^2", + "@types/d3-quadtree": "^2", + "@types/d3-random": "^2", + "@types/d3-scale": "^3", + "@types/d3-scale-chromatic": "^2", + "@types/d3-selection": "^2", + "@types/d3-shape": "^2", + "@types/d3-time": "^2", + "@types/d3-time-format": "^3", + "@types/d3-timer": "^2", + "@types/d3-transition": "^2", + "@types/d3-zoom": "^2" + } + }, + "@types/d3-array": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.3.tgz", + "integrity": "sha512-hN879HLPTVqZV3FQEXy7ptt083UXwguNbnxdTGzVW4y4KjX5uyNKljrQixZcSJfLyFirbpUokxpXtvR+N5+KIg==", + "dev": true + }, + "@types/d3-axis": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-2.1.3.tgz", + "integrity": "sha512-QjXjwZ0xzyrW2ndkmkb09ErgWDEYtbLBKGui73QLMFm3woqWpxptfD5Y7vqQdybMcu7WEbjZ5q+w2w5+uh2IjA==", + "dev": true, + "requires": { + "@types/d3-selection": "^2" + } + }, + "@types/d3-brush": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-2.1.2.tgz", + "integrity": "sha512-DnZmjdK1ycX1CMiW9r5E3xSf1tL+bp3yob1ON8bf0xB0/odfmGXeYOTafU+2SmU1F0/dvcqaO4SMjw62onOu6A==", + "dev": true, + "requires": { + "@types/d3-selection": "^2" + } + }, + "@types/d3-chord": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-2.0.3.tgz", + "integrity": "sha512-koIqSNQLPRQPXt7c55hgRF6Lr9Ps72r1+Biv55jdYR+SHJ463MsB2lp4ktzttFNmrQw/9yWthf/OmSUj5dNXKw==", + "dev": true + }, + "@types/d3-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", + "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==", + "dev": true + }, + "@types/d3-contour": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-2.0.4.tgz", + "integrity": "sha512-WMac1xV/mXAgkgr5dUvzsBV5OrgNZDBDpJk9s3v2SadTqGgDRirKABb2Ek2H1pFlYVH4Oly9XJGnuzxKDduqWA==", + "dev": true, + "requires": { + "@types/d3-array": "^2", + "@types/geojson": "*" + } + }, + "@types/d3-delaunay": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-5.3.1.tgz", + "integrity": "sha512-F6itHi2DxdatHil1rJ2yEFUNhejj8+0Acd55LZ6Ggwbdoks0+DxVY2cawNj16sjCBiWvubVlh6eBMVsYRNGLew==", + "dev": true + }, + "@types/d3-dispatch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-2.0.1.tgz", + "integrity": "sha512-eT2K8uG3rXkmRiCpPn0rNrekuSLdBfV83vbTvfZliA5K7dbeaqWS/CBHtJ9SQoF8aDTsWSY4A0RU67U/HcKdJQ==", + "dev": true + }, + "@types/d3-drag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-2.0.2.tgz", + "integrity": "sha512-m9USoFaTgVw2mmE7vLjWTApT9dMxMlql/dl3Gj503x+1a2n6K455iDWydqy2dfCpkUBCoF82yRGDgcSk9FUEyQ==", + "dev": true, + "requires": { + "@types/d3-selection": "^2" + } + }, + "@types/d3-dsv": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-2.0.2.tgz", + "integrity": "sha512-T4aL2ZzaILkLGKbxssipYVRs8334PSR9FQzTGftZbc3jIPGkiXXS7qUCh8/q8UWFzxBZQ92dvR0v7+AM9wL2PA==", + "dev": true + }, + "@types/d3-ease": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-2.0.1.tgz", + "integrity": "sha512-Af1ftZXv82ktPCk1+Vxe7f+VSfxDsQ1mwwakDl17+UzI/ii3vsDIAzaBDDSEQd2Cg9BYPTSx8wXH8rJNDuSjeg==", + "dev": true + }, + "@types/d3-fetch": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-2.0.2.tgz", + "integrity": "sha512-sllsCSWrNdSvzOJWN5RnxkmtvW9pCttONGajSxHX9FUQ9kOkGE391xlz6VDBdZxLnpwjp3I+mipbwsaCjq4m5A==", + "dev": true, + "requires": { + "@types/d3-dsv": "^2" + } + }, + "@types/d3-force": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-2.1.4.tgz", + "integrity": "sha512-1XVRc2QbeUSL1FRVE53Irdz7jY+drTwESHIMVirCwkAAMB/yVC8ezAfx/1Alq0t0uOnphoyhRle1ht5CuPgSJQ==", + "dev": true + }, + "@types/d3-format": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-2.0.2.tgz", + "integrity": "sha512-OhQPuTeeMhD9A0Ksqo4q1S9Z1Q57O/t4tTPBxBQxRB4IERnxeoEYLPe72fA/GYpPSUrfKZVOgLHidkxwbzLdJA==", + "dev": true + }, + "@types/d3-geo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-2.0.3.tgz", + "integrity": "sha512-kFwLEMXq1mGJ2Eho7KrOUYvLcc2YTDeKj+kTFt87JlEbRQ0rgo8ZENNb5vTYmZrJ2xL/vVM5M7yqVZGOPH2JFg==", + "dev": true, + "requires": { + "@types/geojson": "*" + } + }, + "@types/d3-graphviz": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/d3-graphviz/-/d3-graphviz-2.6.7.tgz", + "integrity": "sha512-dKJjD5HiFvAmC0FL/c70VB1diie8FCpyiCZfxMlf6TwYBqUyFvS4XJt6MoxjIuQTJhKDBGzrIvDOgM8gYMLSVA==", + "dev": true, + "requires": { + "@types/d3-selection": "^1", + "@types/d3-transition": "^1", + "@types/d3-zoom": "^1" + }, + "dependencies": { + "@types/d3-color": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz", + "integrity": "sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA==", + "dev": true + }, + "@types/d3-interpolate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz", + "integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==", + "dev": true, + "requires": { + "@types/d3-color": "^1" + } + }, + "@types/d3-selection": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.3.tgz", + "integrity": "sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==", + "dev": true + }, + "@types/d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg==", + "dev": true, + "requires": { + "@types/d3-selection": "^1" + } + }, + "@types/d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-3kHkL6sPiDdbfGhzlp5gIHyu3kULhtnHTTAl3UBZVtWB1PzcLL8vdmz5mTx7plLiUqOA2Y+yT2GKjt/TdA2p7Q==", + "dev": true, + "requires": { + "@types/d3-interpolate": "^1", + "@types/d3-selection": "^1" + } + } + } + }, + "@types/d3-hierarchy": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-2.0.2.tgz", + "integrity": "sha512-6PlBRwbjUPPt0ZFq/HTUyOAdOF3p73EUYots74lHMUyAVtdFSOS/hAeNXtEIM9i7qRDntuIblXxHGUMb9MuNRA==", + "dev": true + }, + "@types/d3-interpolate": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz", + "integrity": "sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw==", + "dev": true, + "requires": { + "@types/d3-color": "^2" + } + }, + "@types/d3-path": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz", + "integrity": "sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw==", + "dev": true + }, + "@types/d3-polygon": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-2.0.1.tgz", + "integrity": "sha512-X3XTIwBxlzRIWe4yaD1KsmcfItjSPLTGL04QDyP08jyHDVsnz3+NZJMwtD4vCaTAVpGSjbqS+jrBo8cO2V/xMA==", + "dev": true + }, + "@types/d3-quadtree": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-2.0.2.tgz", + "integrity": "sha512-KgWL4jlz8QJJZX01E4HKXJ9FLU94RTuObsAYqsPp8YOAcYDmEgJIQJ+ojZcnKUAnrUb78ik8JBKWas5XZPqJnQ==", + "dev": true + }, + "@types/d3-random": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-2.2.1.tgz", + "integrity": "sha512-5vvxn6//poNeOxt1ZwC7QU//dG9QqABjy1T7fP/xmFHY95GnaOw3yABf29hiu5SR1Oo34XcpyHFbzod+vemQjA==", + "dev": true + }, + "@types/d3-scale": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", + "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", + "dev": true, + "requires": { + "@types/d3-time": "^2" + } + }, + "@types/d3-scale-chromatic": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-2.0.1.tgz", + "integrity": "sha512-3EuZlbPu+pvclZcb1DhlymTWT2W+lYsRKBjvkH2ojDbCWDYavifqu1vYX9WGzlPgCgcS4Alhk1+zapXbGEGylQ==", + "dev": true + }, + "@types/d3-selection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.1.tgz", + "integrity": "sha512-3mhtPnGE+c71rl/T5HMy+ykg7migAZ4T6gzU0HxpgBFKcasBrSnwRbYV1/UZR6o5fkpySxhWxAhd7yhjj8jL7g==", + "dev": true + }, + "@types/d3-shape": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", + "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", + "dev": true, + "requires": { + "@types/d3-path": "^2" + } + }, + "@types/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", + "dev": true + }, + "@types/d3-time-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.1.tgz", + "integrity": "sha512-5GIimz5IqaRsdnxs4YlyTZPwAMfALu/wA4jqSiuqgdbCxUZ2WjrnwANqOtoBJQgeaUTdYNfALJO0Yb0YrDqduA==", + "dev": true + }, + "@types/d3-timer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-2.0.1.tgz", + "integrity": "sha512-TF8aoF5cHcLO7W7403blM7L1T+6NF3XMyN3fxyUolq2uOcFeicG/khQg/dGxiCJWoAcmYulYN7LYSRKO54IXaA==", + "dev": true + }, + "@types/d3-transition": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-2.0.2.tgz", + "integrity": "sha512-376TICEykdXOEA9uUIYpjshEkxfGwCPnkHUl8+6gphzKbf5NMnUhKT7wR59Yxrd9wtJ/rmE3SVLx6/8w4eY6Zg==", + "dev": true, + "requires": { + "@types/d3-selection": "^2" + } + }, + "@types/d3-zoom": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-2.0.3.tgz", + "integrity": "sha512-9X9uDYKk2U8w775OHj36s9Q7GkNAnJKGw6+sbkP5DpHSjELwKvTGzEK6+IISYfLpJRL/V3mRXMhgDnnJ5LkwJg==", + "dev": true, + "requires": { + "@types/d3-interpolate": "^2", + "@types/d3-selection": "^2" + } + }, "@types/del": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/del/-/del-4.0.0.tgz", @@ -13893,6 +14388,12 @@ "@types/node": "*" } }, + "@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", + "dev": true + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -14318,9 +14819,9 @@ } }, "@types/vscode": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.59.0.tgz", - "integrity": "sha512-Zg38rusx2nU6gy6QdF7v4iqgxNfxzlBlDhrRCjOiPQp+sfaNrp3f9J6OHIhpGNN1oOAca4+9Hq0+8u3jwzPMlQ==", + "version": "1.63.1", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.63.1.tgz", + "integrity": "sha512-Z+ZqjRcnGfHP86dvx/BtSwWyZPKQ/LBdmAVImY82TphyjOw2KgTKcp7Nx92oNwCTsHzlshwexAG/WiY2JuUm3g==", "dev": true }, "@types/webpack": { @@ -14729,8 +15230,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true, - "requires": {} + "dev": true }, "agent-base": { "version": "4.3.0", @@ -14767,8 +15267,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true, - "requires": {} + "dev": true }, "ajv-keywords": { "version": "3.5.2", @@ -15224,35 +15723,6 @@ "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -15614,9 +16084,7 @@ }, "dependencies": { "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "~6.0.0", "dev": true, "requires": { "is-glob": "^3.1.0", @@ -15771,15 +16239,6 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -16196,6 +16655,371 @@ "type": "^1.0.1" } }, + "d3": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-6.7.0.tgz", + "integrity": "sha512-hNHRhe+yCDLUG6Q2LwvR/WdNFPOJQ5VWqsJcwIYVeI401+d2/rrCjxSXkiAdIlpx7/73eApFB4Olsmh3YN7a6g==", + "requires": { + "d3-array": "2", + "d3-axis": "2", + "d3-brush": "2", + "d3-chord": "2", + "d3-color": "2", + "d3-contour": "2", + "d3-delaunay": "5", + "d3-dispatch": "2", + "d3-drag": "2", + "d3-dsv": "2", + "d3-ease": "2", + "d3-fetch": "2", + "d3-force": "2", + "d3-format": "2", + "d3-geo": "2", + "d3-hierarchy": "2", + "d3-interpolate": "2", + "d3-path": "2", + "d3-polygon": "2", + "d3-quadtree": "2", + "d3-random": "2", + "d3-scale": "3", + "d3-scale-chromatic": "2", + "d3-selection": "2", + "d3-shape": "2", + "d3-time": "2", + "d3-time-format": "3", + "d3-timer": "2", + "d3-transition": "2", + "d3-zoom": "2" + } + }, + "d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } + }, + "d3-axis": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", + "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" + }, + "d3-brush": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", + "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "d3-chord": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-2.0.0.tgz", + "integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==", + "requires": { + "d3-path": "1 - 2" + } + }, + "d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "d3-contour": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-2.0.0.tgz", + "integrity": "sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA==", + "requires": { + "d3-array": "2" + } + }, + "d3-delaunay": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", + "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", + "requires": { + "delaunator": "4" + } + }, + "d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "d3-dsv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", + "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" + }, + "d3-fetch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-2.0.0.tgz", + "integrity": "sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw==", + "requires": { + "d3-dsv": "1 - 2" + } + }, + "d3-force": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", + "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-quadtree": "1 - 2", + "d3-timer": "1 - 2" + } + }, + "d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "d3-geo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz", + "integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==", + "requires": { + "d3-array": "^2.5.0" + } + }, + "d3-graphviz": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-2.6.1.tgz", + "integrity": "sha512-878AFSagQyr5tTOrM7YiVYeUC2/NoFcOB3/oew+LAML0xekyJSw9j3WOCUMBsc95KYe9XBYZ+SKKuObVya1tJQ==", + "requires": { + "d3-dispatch": "^1.0.3", + "d3-format": "^1.2.0", + "d3-interpolate": "^1.1.5", + "d3-path": "^1.0.5", + "d3-selection": "^1.1.0", + "d3-timer": "^1.0.6", + "d3-transition": "^1.1.1", + "d3-zoom": "^1.5.0", + "viz.js": "^1.8.2" + }, + "dependencies": { + "d3-color": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" + }, + "d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" + }, + "d3-drag": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz", + "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==", + "requires": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "d3-ease": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz", + "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==" + }, + "d3-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" + }, + "d3-interpolate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz", + "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==", + "requires": { + "d3-color": "1" + } + }, + "d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "d3-selection": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz", + "integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==" + }, + "d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" + }, + "d3-transition": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz", + "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==", + "requires": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "d3-zoom": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz", + "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + } + } + }, + "d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + }, + "d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "d3-polygon": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-2.0.0.tgz", + "integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ==" + }, + "d3-quadtree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", + "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" + }, + "d3-random": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-2.2.2.tgz", + "integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==" + }, + "d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "d3-scale-chromatic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", + "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", + "requires": { + "d3-color": "1 - 2", + "d3-interpolate": "1 - 2" + } + }, + "d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" + }, + "d3-shape": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", + "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "requires": { + "d3-path": "1 - 2" + } + }, + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } + }, + "d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "requires": { + "d3-time": "1 - 2" + } + }, + "d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, + "d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "requires": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + } + }, + "d3-zoom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", + "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -16322,15 +17146,6 @@ "kind-of": "^6.0.0" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", @@ -16371,6 +17186,11 @@ } } }, + "delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -16421,8 +17241,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.4.1.tgz", "integrity": "sha512-NpZ7IOVUfea/kAx4+ub4NIYZyRCSymjXM5BZxnThs3ul9gAKqjm7J8QDDQW3Ecuo2XxjNLoWLeKmrPUWKNZaYw==", - "dev": true, - "requires": {} + "dev": true }, "diff": { "version": "4.0.2", @@ -17028,12 +17847,6 @@ "shebang-regex": "^3.0.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -17261,21 +18074,6 @@ "fill-range": "^7.0.1" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -17285,15 +18083,6 @@ "braces": "^3.0.1", "picomatch": "^2.2.3" } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -17707,9 +18496,7 @@ }, "dependencies": { "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "~6.0.0", "dev": true, "requires": { "is-glob": "^3.1.0", @@ -17831,19 +18618,10 @@ "requires": { "glob-watcher": "^5.0.3", "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", + "undertaker": "^1.2.7", "vinyl-fs": "^3.0.0" }, "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, "gulp-cli": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", @@ -18128,15 +18906,6 @@ "which-pm-runs": "^1.0.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -18146,36 +18915,6 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, @@ -18183,7 +18922,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -18359,6 +19097,11 @@ "side-channel": "^1.0.2" } }, + "internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -19057,21 +19800,6 @@ "supports-color": "^7.1.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -19254,21 +19982,6 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -19280,15 +19993,6 @@ "is-fullwidth-code-point": "^3.0.0" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -19765,15 +20469,6 @@ "argparse": "^2.0.1" } }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -19786,24 +20481,6 @@ "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", "dev": true }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -19902,8 +20579,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/mocha-sinon/-/mocha-sinon-2.1.2.tgz", "integrity": "sha512-j6eIQGgOFddcgE1kUFKSvXR9oCuSEiRzv2XUK4iJcntObi2X2vYDvRwvOWxECUZl2dJ+Ciex5fYYni05Lx4azA==", - "dev": true, - "requires": {} + "dev": true }, "module-not-found-error": { "version": "1.0.1", @@ -21204,6 +21880,11 @@ "queue-microtask": "^1.2.2" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "rxjs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", @@ -21230,8 +21911,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "scheduler": { "version": "0.20.2", @@ -21439,8 +22119,7 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true, - "requires": {} + "dev": true }, "slash": { "version": "3.0.0", @@ -22535,8 +23214,7 @@ "dev": true }, "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "version": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", "dev": true, "requires": { @@ -22798,6 +23476,11 @@ } } }, + "viz.js": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/viz.js/-/viz.js-1.8.2.tgz", + "integrity": "sha512-W+1+N/hdzLpQZEcvz79n2IgUE9pfx6JLdHh3Kh8RGvLL8P1LdJVQmi2OsDcLdY4QVID4OUy+FPelyerX0nJxIQ==" + }, "vsce": { "version": "1.88.0", "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.88.0.tgz", @@ -22879,8 +23562,7 @@ "diagnostic-channel-publishers": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz", - "integrity": "sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==", - "requires": {} + "integrity": "sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==" }, "semver": { "version": "5.7.1", @@ -23243,15 +23925,6 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", diff --git a/extensions/ql-vscode/package.json b/extensions/ql-vscode/package.json index 39c741477..f4dfcba2e 100644 --- a/extensions/ql-vscode/package.json +++ b/extensions/ql-vscode/package.json @@ -48,6 +48,7 @@ "onCommand:codeQLDatabases.chooseDatabaseLgtm", "onCommand:codeQL.setCurrentDatabase", "onCommand:codeQL.viewAst", + "onCommand:codeQL.viewCfg", "onCommand:codeQL.openReferencedFile", "onCommand:codeQL.previewQueryHelp", "onCommand:codeQL.chooseDatabaseFolder", @@ -374,6 +375,10 @@ "command": "codeQL.viewAst", "title": "CodeQL: View AST" }, + { + "command": "codeQL.viewCfg", + "title": "CodeQL: View CFG" + }, { "command": "codeQL.upgradeCurrentDatabase", "title": "CodeQL: Upgrade Current Database" @@ -743,6 +748,11 @@ "group": "9_qlCommands", "when": "resourceScheme == codeql-zip-archive && !explorerResourceIsFolder && !listMultiSelection" }, + { + "command": "codeQL.viewCfg", + "group": "9_qlCommands", + "when": "resourceScheme == codeql-zip-archive && config.codeQL.canary" + }, { "command": "codeQL.runQueries", "group": "9_qlCommands", @@ -804,6 +814,10 @@ "command": "codeQL.viewAst", "when": "resourceScheme == codeql-zip-archive" }, + { + "command": "codeQL.viewCfg", + "when": "resourceScheme == codeql-zip-archive && config.codeQL.canary" + }, { "command": "codeQLDatabases.setCurrentDatabase", "when": "false" @@ -950,6 +964,10 @@ "command": "codeQL.viewAst", "when": "resourceScheme == codeql-zip-archive" }, + { + "command": "codeQL.viewCfg", + "when": "resourceScheme == codeql-zip-archive && config.codeQL.canary" + }, { "command": "codeQL.quickEval", "when": "editorLangId == ql" @@ -1023,6 +1041,8 @@ "@primer/react": "^34.3.0", "child-process-promise": "^2.2.1", "classnames": "~2.2.6", + "d3": "^6.3.1", + "d3-graphviz": "^2.6.1", "fs-extra": "^9.0.1", "glob-promise": "^3.4.0", "js-yaml": "^3.14.0", @@ -1054,6 +1074,8 @@ "@types/child-process-promise": "^2.2.1", "@types/classnames": "~2.2.9", "@types/del": "^4.0.0", + "@types/d3": "^6.2.0", + "@types/d3-graphviz": "^2.6.6", "@types/fs-extra": "^9.0.6", "@types/glob": "^7.1.1", "@types/google-protobuf": "^3.2.7", diff --git a/extensions/ql-vscode/src/additional-typings.d.ts b/extensions/ql-vscode/src/additional-typings.d.ts new file mode 100644 index 000000000..d5a10a5f0 --- /dev/null +++ b/extensions/ql-vscode/src/additional-typings.d.ts @@ -0,0 +1,15 @@ +/** + * The d3 library is designed to work in both the browser and + * node. Consequently their typings files refer to both node + * types like `Buffer` (which don't exist in the browser), and browser + * types like `Blob` (which don't exist in node). Instead of sticking + * all of `dom` in `compilerOptions.lib`, it suffices just to put in a + * stub definition of the affected types so that compilation + * succeeds. + */ + +declare type RequestInit = Record; +declare type ElementTagNameMap = any; +declare type NodeListOf = Record; +declare type Node = Record; +declare type XMLDocument = Record; diff --git a/extensions/ql-vscode/src/cli.ts b/extensions/ql-vscode/src/cli.ts index 8e8187467..965108bd0 100644 --- a/extensions/ql-vscode/src/cli.ts +++ b/extensions/ql-vscode/src/cli.ts @@ -1,5 +1,6 @@ import * as cpp from 'child-process-promise'; import * as child_process from 'child_process'; +import * as fs from 'fs-extra'; import * as path from 'path'; import * as sarif from 'sarif'; import { SemVer } from 'semver'; @@ -17,7 +18,7 @@ import { QueryMetadata, SortDirection } from './pure/interface-types'; import { Logger, ProgressReporter } from './logging'; import { CompilationMessage } from './pure/messages'; import { sarifParser } from './sarif-parser'; -import { dbSchemeToLanguage } from './helpers'; +import { dbSchemeToLanguage, walkDirectory } from './helpers'; /** * The version of the SARIF format that we are using. @@ -687,20 +688,13 @@ export class CodeQLCliServer implements Disposable { return await this.runJsonCodeQlCliCommand(['bqrs', 'decode'], subcommandArgs, 'Reading bqrs data'); } - async runInterpretCommand(format: string, metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo) { + async runInterpretCommand(format: string, additonalArgs: string[], metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo) { const args = [ '--output', interpretedResultsPath, '--format', format, // Forward all of the query metadata. ...Object.entries(metadata).map(([key, value]) => `-t=${key}=${value}`) - ]; - if (format == SARIF_FORMAT) { - // TODO: This flag means that we don't group interpreted results - // by primary location. We may want to revisit whether we call - // interpretation with and without this flag, or do some - // grouping client-side. - args.push('--no-group-results'); - } + ].concat(additonalArgs); if (sourceInfo !== undefined) { args.push( '--source-archive', sourceInfo.sourceArchive, @@ -722,13 +716,47 @@ export class CodeQLCliServer implements Disposable { await this.runCodeQlCliCommand(['bqrs', 'interpret'], args, 'Interpreting query results'); } - async interpretBqrs(metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo): Promise { - await this.runInterpretCommand(SARIF_FORMAT, metadata, resultsPath, interpretedResultsPath, sourceInfo); + async interpretBqrsSarif(metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo): Promise { + const additionalArgs = [ + // TODO: This flag means that we don't group interpreted results + // by primary location. We may want to revisit whether we call + // interpretation with and without this flag, or do some + // grouping client-side. + '--no-group-results' + ]; + + await this.runInterpretCommand(SARIF_FORMAT, additionalArgs, metadata, resultsPath, interpretedResultsPath, sourceInfo); return await sarifParser(interpretedResultsPath); } + // Warning: this function is untenable for large dot files, + async readDotFiles(dir: string): Promise { + const dotFiles: Promise[] = []; + for await (const file of walkDirectory(dir)) { + if (file.endsWith('.dot')) { + dotFiles.push(fs.readFile(file, 'utf8')); + } + } + return Promise.all(dotFiles); + } + + async interpretBqrsGraph(metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo): Promise { + const additionalArgs = sourceInfo + ? ['--dot-location-url-format', 'file://' + sourceInfo.sourceLocationPrefix + '{path}:{start:line}:{start:column}:{end:line}:{end:column}'] + : []; + + await this.runInterpretCommand('dot', additionalArgs, metadata, resultsPath, interpretedResultsPath, sourceInfo); + + try { + const dot = await this.readDotFiles(interpretedResultsPath); + return dot; + } catch (err) { + throw new Error(`Reading output of interpretation failed: ${err.stderr || err}`); + } + } + async generateResultsCsv(metadata: QueryMetadata, resultsPath: string, csvPath: string, sourceInfo?: SourceInfo): Promise { - await this.runInterpretCommand(CSV_FORMAT, metadata, resultsPath, csvPath, sourceInfo); + await this.runInterpretCommand(CSV_FORMAT, [], metadata, resultsPath, csvPath, sourceInfo); } async sortBqrs(resultsPath: string, sortedResultsPath: string, resultSet: string, sortKeys: number[], sortDirections: SortDirection[]): Promise { @@ -1224,9 +1252,9 @@ export class CliVersionConstraint { /** * CLI version where the `--evaluator-log` and related options to the query server were introduced, - * on a per-query server basis. + * on a per-query server basis. */ - public static CLI_VERSION_WITH_STRUCTURED_EVAL_LOG = new SemVer('2.8.2'); + public static CLI_VERSION_WITH_STRUCTURED_EVAL_LOG = new SemVer('2.8.2'); constructor(private readonly cli: CodeQLCliServer) { /**/ diff --git a/extensions/ql-vscode/src/config.ts b/extensions/ql-vscode/src/config.ts index bb3a57e40..3e145ea7c 100644 --- a/extensions/ql-vscode/src/config.ts +++ b/extensions/ql-vscode/src/config.ts @@ -95,8 +95,8 @@ const CUSTOM_LOG_DIRECTORY_SETTING = new Setting('customLogDirectory', RUNNING_Q /** When these settings change, the running query server should be restarted. */ const QUERY_SERVER_RESTARTING_SETTINGS = [ - NUMBER_OF_THREADS_SETTING, SAVE_CACHE_SETTING, CACHE_SIZE_SETTING, MEMORY_SETTING, - DEBUG_SETTING, CUSTOM_LOG_DIRECTORY_SETTING, + NUMBER_OF_THREADS_SETTING, SAVE_CACHE_SETTING, CACHE_SIZE_SETTING, MEMORY_SETTING, + DEBUG_SETTING, CUSTOM_LOG_DIRECTORY_SETTING, ]; export interface QueryServerConfig { diff --git a/extensions/ql-vscode/src/contextual/keyType.ts b/extensions/ql-vscode/src/contextual/keyType.ts index c21fbebfd..af5777cb1 100644 --- a/extensions/ql-vscode/src/contextual/keyType.ts +++ b/extensions/ql-vscode/src/contextual/keyType.ts @@ -2,6 +2,7 @@ export enum KeyType { DefinitionQuery = 'DefinitionQuery', ReferenceQuery = 'ReferenceQuery', PrintAstQuery = 'PrintAstQuery', + PrintCfgQuery = 'PrintCfgQuery', } export function tagOfKeyType(keyType: KeyType): string { @@ -12,6 +13,8 @@ export function tagOfKeyType(keyType: KeyType): string { return 'ide-contextual-queries/local-references'; case KeyType.PrintAstQuery: return 'ide-contextual-queries/print-ast'; + case KeyType.PrintCfgQuery: + return 'ide-contextual-queries/print-cfg'; } } @@ -23,6 +26,8 @@ export function nameOfKeyType(keyType: KeyType): string { return 'references'; case KeyType.PrintAstQuery: return 'print AST'; + case KeyType.PrintCfgQuery: + return 'print CFG'; } } @@ -32,6 +37,7 @@ export function kindOfKeyType(keyType: KeyType): string { case KeyType.ReferenceQuery: return 'definitions'; case KeyType.PrintAstQuery: + case KeyType.PrintCfgQuery: return 'graph'; } } diff --git a/extensions/ql-vscode/src/contextual/templateProvider.ts b/extensions/ql-vscode/src/contextual/templateProvider.ts index 653595189..282fddfea 100644 --- a/extensions/ql-vscode/src/contextual/templateProvider.ts +++ b/extensions/ql-vscode/src/contextual/templateProvider.ts @@ -230,3 +230,62 @@ export class TemplatePrintAstProvider { }; } } + +export class TemplatePrintCfgProvider { + private cache: CachedOperation<[Uri, messages.TemplateDefinitions] | undefined>; + + constructor( + private cli: CodeQLCliServer, + private dbm: DatabaseManager, + ) { + this.cache = new CachedOperation<[Uri, messages.TemplateDefinitions] | undefined>(this.getCfgUri.bind(this)); + } + + async provideCfgUri(document?: TextDocument): Promise<[Uri, messages.TemplateDefinitions] | undefined> { + if (!document) { + return; + } + return await this.cache.get(document.uri.toString()); + } + + private async getCfgUri(uriString: string): Promise<[Uri, messages.TemplateDefinitions]> { + const uri = Uri.parse(uriString, true); + if (uri.scheme !== zipArchiveScheme) { + throw new Error('CFG Viewing is only available for databases with zipped source archives.'); + } + + const zippedArchive = decodeSourceArchiveUri(uri); + const sourceArchiveUri = encodeArchiveBasePath(zippedArchive.sourceArchiveZipPath); + const db = this.dbm.findDatabaseItemBySourceArchive(sourceArchiveUri); + + if (!db) { + throw new Error('Can\'t infer database from the provided source.'); + } + + const qlpack = await qlpackOfDatabase(this.cli, db); + if (!qlpack) { + throw new Error('Can\'t infer qlpack from database source archive.'); + } + const queries = await resolveQueries(this.cli, qlpack, KeyType.PrintCfgQuery); + if (queries.length > 1) { + throw new Error(`Found multiple Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`); + } + if (queries.length === 0) { + throw new Error(`Did not find any Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`); + } + + const queryUri = Uri.file(queries[0]); + + const templates: messages.TemplateDefinitions = { + [TEMPLATE_NAME]: { + values: { + tuples: [[{ + stringValue: zippedArchive.pathWithinSourceArchive + }]] + } + } + }; + + return [queryUri, templates]; + } +} diff --git a/extensions/ql-vscode/src/extension.ts b/extensions/ql-vscode/src/extension.ts index 56506ed0c..6a5a44935 100644 --- a/extensions/ql-vscode/src/extension.ts +++ b/extensions/ql-vscode/src/extension.ts @@ -42,7 +42,8 @@ import { DatabaseUI } from './databases-ui'; import { TemplateQueryDefinitionProvider, TemplateQueryReferenceProvider, - TemplatePrintAstProvider + TemplatePrintAstProvider, + TemplatePrintCfgProvider } from './contextual/templateProvider'; import { DEFAULT_DISTRIBUTION_VERSION_RANGE, @@ -1047,7 +1048,8 @@ async function activateWithInstalledDistribution( ); const astViewer = new AstViewer(); - const templateProvider = new TemplatePrintAstProvider(cliServer, qs, dbm, contextualQueryStorageDir); + const printAstTemplateProvider = new TemplatePrintAstProvider(cliServer, qs, dbm, contextualQueryStorageDir); + const cfgTemplateProvider = new TemplatePrintCfgProvider(cliServer, dbm); ctx.subscriptions.push(astViewer); ctx.subscriptions.push(commandRunnerWithProgress('codeQL.viewAst', async ( @@ -1055,7 +1057,7 @@ async function activateWithInstalledDistribution( token: CancellationToken, selectedFile: Uri ) => { - const ast = await templateProvider.provideAst( + const ast = await printAstTemplateProvider.provideAst( progress, token, selectedFile ?? window.activeTextEditor?.document.uri, @@ -1068,6 +1070,25 @@ async function activateWithInstalledDistribution( title: 'Calculate AST' })); + ctx.subscriptions.push( + commandRunnerWithProgress( + 'codeQL.viewCfg', + async ( + progress: ProgressCallback, + token: CancellationToken + ) => { + const res = await cfgTemplateProvider.provideCfgUri(window.activeTextEditor?.document); + if (res) { + await compileAndRunQuery(false, res[0], progress, token, undefined); + } + }, + { + title: 'Calculating Control Flow Graph', + cancellable: true + } + ) + ); + await commands.executeCommand('codeQLDatabases.removeOrphanedDatabases'); void logger.log('Successfully finished extension initialization.'); diff --git a/extensions/ql-vscode/src/helpers.ts b/extensions/ql-vscode/src/helpers.ts index 4dc8cfbc1..fe2760bb5 100644 --- a/extensions/ql-vscode/src/helpers.ts +++ b/extensions/ql-vscode/src/helpers.ts @@ -558,3 +558,25 @@ export async function createTimestampFile(storagePath: string) { await fs.ensureDir(storagePath); await fs.writeFile(timestampPath, Date.now().toString(), 'utf8'); } + + +/** + * Recursively walk a directory and return the full path to all files found. + * Symbolic links are ignored. + * + * @param dir the directory to walk + * + * @return An iterator of the full path to all files recursively found in the directory. + */ +export async function* walkDirectory(dir: string): AsyncIterableIterator { + const seenFiles = new Set(); + for await (const d of await fs.opendir(dir)) { + const entry = path.join(dir, d.name); + seenFiles.add(entry); + if (d.isDirectory()) { + yield* walkDirectory(entry); + } else if (d.isFile()) { + yield entry; + } + } +} diff --git a/extensions/ql-vscode/src/interface.ts b/extensions/ql-vscode/src/interface.ts index 12e007014..7954e1a46 100644 --- a/extensions/ql-vscode/src/interface.ts +++ b/extensions/ql-vscode/src/interface.ts @@ -27,12 +27,13 @@ import { InterpretedResultsSortState, SortDirection, ALERTS_TABLE_NAME, + GRAPH_TABLE_NAME, RawResultsSortState, } from './pure/interface-types'; import { Logger } from './logging'; import * as messages from './pure/messages'; import { commandRunner } from './commandRunner'; -import { CompletedQueryInfo, interpretResults } from './query-results'; +import { CompletedQueryInfo, interpretResultsSarif, interpretGraphResults } from './query-results'; import { QueryEvaluationInfo } from './run-queries'; import { parseSarifLocation, parseSarifPlainTextMessage } from './pure/sarif-utils'; import { @@ -88,12 +89,36 @@ function sortInterpretedResults( } } -function numPagesOfResultSet(resultSet: RawResultSet): number { - return Math.ceil(resultSet.schema.rows / PAGE_SIZE.getValue()); +function interpretedPageSize(interpretation: Interpretation | undefined): number { + if (interpretation?.data.t == 'GraphInterpretationData') { + // Graph views always have one result per page. + return 1; + } + return PAGE_SIZE.getValue(); +} + +function numPagesOfResultSet(resultSet: RawResultSet, interpretation?: Interpretation): number { + const pageSize = interpretedPageSize(interpretation); + + const n = interpretation?.data.t == 'GraphInterpretationData' + ? interpretation.data.dot.length + : resultSet.schema.rows; + + return Math.ceil(n / pageSize); } function numInterpretedPages(interpretation: Interpretation | undefined): number { - return Math.ceil((interpretation?.sarif.runs[0].results?.length || 0) / PAGE_SIZE.getValue()); + if (!interpretation) { + return 0; + } + + const pageSize = interpretedPageSize(interpretation); + + const n = interpretation.data.t == 'GraphInterpretationData' + ? interpretation.data.dot.length + : interpretation.data.runs[0].results?.length || 0; + + return Math.ceil(n / pageSize); } export class InterfaceManager extends DisposableObject { @@ -181,6 +206,7 @@ export class InterfaceManager extends DisposableObject { () => { this._panel = undefined; this._displayedQuery = undefined; + this._panelLoaded = false; }, null, ctx.subscriptions @@ -305,7 +331,7 @@ export class InterfaceManager extends DisposableObject { await this.changeInterpretedSortState(msg.sortState); break; case 'changePage': - if (msg.selectedTable === ALERTS_TABLE_NAME) { + if (msg.selectedTable === ALERTS_TABLE_NAME || msg.selectedTable === GRAPH_TABLE_NAME) { await this.showPageOfInterpretedResults(msg.pageNumber); } else { @@ -438,7 +464,7 @@ export class InterfaceManager extends DisposableObject { const parsedResultSets: ParsedResultSets = { pageNumber: 0, pageSize, - numPages: numPagesOfResultSet(resultSet), + numPages: numPagesOfResultSet(resultSet, this._interpretation), numInterpretedPages: numInterpretedPages(this._interpretation), resultSet: { ...resultSet, t: 'RawResultSet' }, selectedTable: undefined, @@ -474,7 +500,7 @@ export class InterfaceManager extends DisposableObject { if (this._interpretation === undefined) { throw new Error('Trying to show interpreted results but interpretation was undefined'); } - if (this._interpretation.sarif.runs[0].results === undefined) { + if (this._interpretation.data.t === 'SarifInterpretationData' && this._interpretation.data.runs[0].results === undefined) { throw new Error('Trying to show interpreted results but results were undefined'); } @@ -488,7 +514,7 @@ export class InterfaceManager extends DisposableObject { metadata: this._displayedQuery.completedQuery.query.metadata, pageNumber, resultSetNames, - pageSize: PAGE_SIZE.getValue(), + pageSize: interpretedPageSize(this._interpretation), numPages: numInterpretedPages(this._interpretation), queryName: this._displayedQuery.label, queryPath: this._displayedQuery.initialInfo.queryPath @@ -591,28 +617,45 @@ export class InterfaceManager extends DisposableObject { void this.logger.log('No results path. Cannot display interpreted results.'); return undefined; } + let data; + let numTotalResults; + if (metadata?.kind === GRAPH_TABLE_NAME) { + data = await interpretGraphResults( + this.cliServer, + metadata, + resultsPaths, + sourceInfo + ); + numTotalResults = data.dot.length; + } else { + const sarif = await interpretResultsSarif( + this.cliServer, + metadata, + resultsPaths, + sourceInfo + ); - const sarif = await interpretResults( - this.cliServer, - metadata, - resultsPaths, - sourceInfo - ); + sarif.runs.forEach(run => { + if (run.results) { + sortInterpretedResults(run.results, sortState); + } + }); - sarif.runs.forEach(run => { - if (run.results !== undefined) { - sortInterpretedResults(run.results, sortState); - } - }); + sarif.sortState = sortState; + data = sarif; - const numTotalResults = sarif.runs[0]?.results?.length || 0; + numTotalResults = (() => { + return sarif.runs?.[0]?.results + ? sarif.runs[0].results.length + : 0; + })(); + } const interpretation: Interpretation = { - sarif, + data, sourceLocationPrefix, numTruncatedResults: 0, - numTotalResults, - sortState, + numTotalResults }; this._interpretation = interpretation; return interpretation; @@ -621,7 +664,6 @@ export class InterfaceManager extends DisposableObject { private getPageOfInterpretedResults( pageNumber: number ): Interpretation { - function getPageOfRun(run: Sarif.Run): Sarif.Run { return { ...run, results: run.results?.slice( @@ -631,16 +673,24 @@ export class InterfaceManager extends DisposableObject { }; } - if (this._interpretation === undefined) { + const interp = this._interpretation; + if (interp === undefined) { throw new Error('Tried to get interpreted results before interpretation finished'); } - if (this._interpretation.sarif.runs.length !== 1) { - void this.logger.log(`Warning: SARIF file had ${this._interpretation.sarif.runs.length} runs, expected 1`); + + if (interp.data.t !== 'SarifInterpretationData') + return interp; + + if (interp.data.runs.length !== 1) { + void this.logger.log(`Warning: SARIF file had ${interp.data.runs.length} runs, expected 1`); } - const interp = this._interpretation; + return { ...interp, - sarif: { ...interp.sarif, runs: [getPageOfRun(interp.sarif.runs[0])] }, + data: { + ...interp.data, + runs: [getPageOfRun(interp.data.runs[0])] + } }; } @@ -730,9 +780,12 @@ export class InterfaceManager extends DisposableObject { interpretation: Interpretation, databaseItem: DatabaseItem ): Promise { - const { sarif, sourceLocationPrefix } = interpretation; + const { data, sourceLocationPrefix } = interpretation; - if (!sarif.runs || !sarif.runs[0].results) { + if (data.t !== 'SarifInterpretationData') + return; + + if (!data.runs || !data.runs[0].results) { void this.logger.log( 'Didn\'t find a run in the sarif results. Error processing sarif?' ); @@ -741,7 +794,7 @@ export class InterfaceManager extends DisposableObject { const diagnostics: [Uri, ReadonlyArray][] = []; - for (const result of sarif.runs[0].results) { + for (const result of data.runs[0].results) { const message = result.message.text; if (message === undefined) { void this.logger.log('Sarif had result without plaintext message'); diff --git a/extensions/ql-vscode/src/pure/helpers-pure.ts b/extensions/ql-vscode/src/pure/helpers-pure.ts index f11626a75..3940344b6 100644 --- a/extensions/ql-vscode/src/pure/helpers-pure.ts +++ b/extensions/ql-vscode/src/pure/helpers-pure.ts @@ -1,3 +1,4 @@ + /** * helpers-pure.ts * ------------ diff --git a/extensions/ql-vscode/src/pure/interface-types.ts b/extensions/ql-vscode/src/pure/interface-types.ts index e2e3bb899..a0f2dbc0f 100644 --- a/extensions/ql-vscode/src/pure/interface-types.ts +++ b/extensions/ql-vscode/src/pure/interface-types.ts @@ -10,15 +10,17 @@ import { RawResultSet, ResultRow, ResultSetSchema, Column, ResolvableLocationVal export const SELECT_TABLE_NAME = '#select'; export const ALERTS_TABLE_NAME = 'alerts'; +export const GRAPH_TABLE_NAME = 'graph'; export type RawTableResultSet = { t: 'RawResultSet' } & RawResultSet; -export type PathTableResultSet = { - t: 'SarifResultSet'; +export type InterpretedResultSet = { + t: 'InterpretedResultSet'; readonly schema: ResultSetSchema; name: string; -} & Interpretation; + interpretation: InterpretationT; +}; -export type ResultSet = RawTableResultSet | PathTableResultSet; +export type ResultSet = RawTableResultSet | InterpretedResultSet; /** * Only ever show this many rows in a raw result table. @@ -46,18 +48,31 @@ export interface PreviousExecution { durationSeconds: number; } -export interface Interpretation { - sourceLocationPrefix: string; - numTruncatedResults: number; - numTotalResults: number; +export type SarifInterpretationData = { + t: 'SarifInterpretationData'; /** * sortState being undefined means don't sort, just present results in the order * they appear in the sarif file. */ sortState?: InterpretedResultsSortState; - sarif: sarif.Log; +} & sarif.Log; + +export type GraphInterpretationData = { + t: 'GraphInterpretationData'; + dot: string[]; +}; + +export type InterpretationData = SarifInterpretationData | GraphInterpretationData; + +export interface InterpretationT { + sourceLocationPrefix: string; + numTruncatedResults: number; + numTotalResults: number; + data: T; } +export type Interpretation = InterpretationT; + export interface ResultsPaths { resultsPath: string; interpretedResultsPath: string; @@ -357,8 +372,9 @@ export function getDefaultResultSetName( // Choose first available result set from the array return [ ALERTS_TABLE_NAME, + GRAPH_TABLE_NAME, SELECT_TABLE_NAME, - resultSetNames[0], + resultSetNames[0] ].filter((resultSetName) => resultSetNames.includes(resultSetName))[0]; } diff --git a/extensions/ql-vscode/src/query-results.ts b/extensions/ql-vscode/src/query-results.ts index 2c34d8703..53313332f 100644 --- a/extensions/ql-vscode/src/query-results.ts +++ b/extensions/ql-vscode/src/query-results.ts @@ -3,7 +3,6 @@ import { CancellationTokenSource, env } from 'vscode'; import { QueryWithResults, QueryEvaluationInfo } from './run-queries'; import * as messages from './pure/messages'; import * as cli from './cli'; -import * as sarif from 'sarif'; import * as fs from 'fs-extra'; import * as path from 'path'; import { @@ -11,7 +10,9 @@ import { SortedResultSetInfo, QueryMetadata, InterpretedResultsSortState, - ResultsPaths + ResultsPaths, + SarifInterpretationData, + GraphInterpretationData } from './pure/interface-types'; import { QueryHistoryConfig } from './config'; import { DatabaseInfo } from './pure/interface-types'; @@ -151,19 +152,39 @@ export class CompletedQueryInfo implements QueryWithResults { /** - * Call cli command to interpret results. + * Call cli command to interpret SARIF results. */ -export async function interpretResults( - server: cli.CodeQLCliServer, +export async function interpretResultsSarif( + cli: cli.CodeQLCliServer, metadata: QueryMetadata | undefined, resultsPaths: ResultsPaths, sourceInfo?: cli.SourceInfo -): Promise { +): Promise { const { resultsPath, interpretedResultsPath } = resultsPaths; if (await fs.pathExists(interpretedResultsPath)) { - return JSON.parse(await fs.readFile(interpretedResultsPath, 'utf8')); + return { ...JSON.parse(await fs.readFile(interpretedResultsPath, 'utf8')), t: 'SarifInterpretationData' }; } - return await server.interpretBqrs(ensureMetadataIsComplete(metadata), resultsPath, interpretedResultsPath, sourceInfo); + const res = await cli.interpretBqrsSarif(ensureMetadataIsComplete(metadata), resultsPath, interpretedResultsPath, sourceInfo); + return { ...res, t: 'SarifInterpretationData' }; +} + +/** + * Call cli command to interpret graph results. + */ +export async function interpretGraphResults( + cli: cli.CodeQLCliServer, + metadata: QueryMetadata | undefined, + resultsPaths: ResultsPaths, + sourceInfo?: cli.SourceInfo +): Promise { + const { resultsPath, interpretedResultsPath } = resultsPaths; + if (await fs.pathExists(interpretedResultsPath)) { + const dot = await cli.readDotFiles(interpretedResultsPath); + return { dot, t: 'GraphInterpretationData' }; + } + + const dot = await cli.interpretBqrsGraph(ensureMetadataIsComplete(metadata), resultsPath, interpretedResultsPath, sourceInfo); + return { dot, t: 'GraphInterpretationData' }; } export function ensureMetadataIsComplete(metadata: QueryMetadata | undefined) { @@ -181,7 +202,6 @@ export function ensureMetadataIsComplete(metadata: QueryMetadata | undefined) { return metadata; } - /** * Used in Interface and Compare-Interface for queries that we know have been complated. */ diff --git a/extensions/ql-vscode/src/queryserver-client.ts b/extensions/ql-vscode/src/queryserver-client.ts index 5baff7036..cc7423d65 100644 --- a/extensions/ql-vscode/src/queryserver-client.ts +++ b/extensions/ql-vscode/src/queryserver-client.ts @@ -174,7 +174,7 @@ export class QueryServerClient extends DisposableObject { if (await this.cliServer.cliConstraints.supportsStructuredEvalLog()) { args.push('--evaluator-log'); args.push(`${this.opts.contextStoragePath}/structured-evaluator-log.json`); - + // We hard-code the verbosity level to 5 and minify to false. // This will be the behavior of the per-query structured logging in the CLI after 2.8.3. args.push('--evaluator-log-level'); diff --git a/extensions/ql-vscode/src/run-queries.ts b/extensions/ql-vscode/src/run-queries.ts index 996a97045..6b34abd3f 100644 --- a/extensions/ql-vscode/src/run-queries.ts +++ b/extensions/ql-vscode/src/run-queries.ts @@ -86,7 +86,11 @@ export class QueryEvaluationInfo { get resultsPaths() { return { resultsPath: path.join(this.querySaveDir, 'results.bqrs'), - interpretedResultsPath: path.join(this.querySaveDir, 'interpretedResults.sarif'), + interpretedResultsPath: path.join(this.querySaveDir, + this.metadata?.kind === 'graph' + ? 'graphResults' + : 'interpretedResults.sarif' + ), }; } @@ -202,16 +206,21 @@ export class QueryEvaluationInfo { return false; } - const hasKind = !!this.metadata?.kind; + const kind = this.metadata?.kind; + const hasKind = !!kind; if (!hasKind) { void logger.log('Cannot produce interpreted results since the query does not have @kind metadata.'); return false; } + // Graph queries only return interpreted results if we are in canary mode. + if (kind === 'graph') { + return config.isCanary(); + } + // table is the default query kind. It does not produce interpreted results. // any query kind that is not table can, in principle, produce interpreted results. - const isTable = hasKind && this.metadata?.kind === 'table'; - return !isTable; + return kind !== 'table'; } /** diff --git a/extensions/ql-vscode/src/view/alert-table.tsx b/extensions/ql-vscode/src/view/alert-table.tsx index 16e8a93a7..1ed563910 100644 --- a/extensions/ql-vscode/src/view/alert-table.tsx +++ b/extensions/ql-vscode/src/view/alert-table.tsx @@ -5,7 +5,7 @@ import * as Keys from '../pure/result-keys'; import * as octicons from './octicons'; import { className, renderLocation, ResultTableProps, zebraStripe, selectableZebraStripe, jumpToLocation, nextSortDirection, emptyQueryResultsMessage } from './result-table-utils'; import { onNavigation, NavigationEvent } from './results'; -import { PathTableResultSet } from '../pure/interface-types'; +import { InterpretedResultSet, SarifInterpretationData } from '../pure/interface-types'; import { parseSarifPlainTextMessage, parseSarifLocation, @@ -15,7 +15,7 @@ import { InterpretedResultsSortColumn, SortDirection, InterpretedResultsSortStat import { vscode } from './vscode-api'; import { isWholeFileLoc, isLineColumnLoc } from '../pure/bqrs-utils'; -export type PathTableProps = ResultTableProps & { resultSet: PathTableResultSet }; +export type PathTableProps = ResultTableProps & { resultSet: InterpretedResultSet }; export interface PathTableState { expanded: { [k: string]: boolean }; selectedPathNode: undefined | Keys.PathNode; @@ -51,7 +51,7 @@ export class PathTable extends React.Component { } sortClass(column: InterpretedResultsSortColumn): string { - const sortState = this.props.resultSet.sortState; + const sortState = this.props.resultSet.interpretation.data.sortState; if (sortState !== undefined && sortState.sortBy === column) { return sortState.sortDirection === SortDirection.asc ? 'sort-asc' : 'sort-desc'; } @@ -61,7 +61,7 @@ export class PathTable extends React.Component { } getNextSortState(column: InterpretedResultsSortColumn): InterpretedResultsSortState | undefined { - const oldSortState = this.props.resultSet.sortState; + const oldSortState = this.props.resultSet.interpretation.data.sortState; const prevDirection = oldSortState && oldSortState.sortBy === column ? oldSortState.sortDirection : undefined; const nextDirection = nextSortDirection(prevDirection, true); return nextDirection === undefined ? undefined : @@ -94,7 +94,7 @@ export class PathTable extends React.Component { ; const rows: JSX.Element[] = []; - const { numTruncatedResults, sourceLocationPrefix } = resultSet; + const { numTruncatedResults, sourceLocationPrefix } = resultSet.interpretation; function renderRelatedLocations(msg: string, relatedLocations: Sarif.Location[]): JSX.Element[] { const relatedLocationsById: { [k: string]: Sarif.Location } = {}; @@ -188,13 +188,13 @@ export class PathTable extends React.Component { return (e) => this.toggle(e, indices); }; - if (!resultSet.sarif.runs?.[0]?.results?.length) { + if (!resultSet.interpretation.data.runs?.[0]?.results?.length) { return this.renderNoResults(); } let expansionIndex = 0; - resultSet.sarif.runs[0].results.forEach((result, resultIndex) => { + resultSet.interpretation.data.runs[0].results.forEach((result, resultIndex) => { const text = result.message.text || '[no text]'; const msg: JSX.Element[] = result.relatedLocations === undefined ? @@ -307,7 +307,7 @@ export class PathTable extends React.Component { const { selectedPathNode } = prevState; if (selectedPathNode === undefined) return prevState; - const path = Keys.getPath(this.props.resultSet.sarif, selectedPathNode); + const path = Keys.getPath(this.props.resultSet.interpretation.data, selectedPathNode); if (path === undefined) return prevState; const nextIndex = selectedPathNode.pathNodeIndex + event.direction; @@ -318,7 +318,7 @@ export class PathTable extends React.Component { return prevState; } - const loc = parseSarifLocation(sarifLoc, this.props.resultSet.sourceLocationPrefix); + const loc = parseSarifLocation(sarifLoc, this.props.resultSet.interpretation.sourceLocationPrefix); if (isNoLocation(loc)) { return prevState; } diff --git a/extensions/ql-vscode/src/view/graph.tsx b/extensions/ql-vscode/src/view/graph.tsx new file mode 100644 index 000000000..e04d40733 --- /dev/null +++ b/extensions/ql-vscode/src/view/graph.tsx @@ -0,0 +1,100 @@ +import * as React from 'react'; +import * as d3 from 'd3'; +import { ResultTableProps } from './result-table-utils'; +import { InterpretedResultSet, GraphInterpretationData } from '../pure/interface-types'; +import { graphviz } from 'd3-graphviz'; +import { jumpToLocation } from './result-table-utils'; +import { tryGetLocationFromString } from '../pure/bqrs-utils'; +export type GraphProps = ResultTableProps & { resultSet: InterpretedResultSet }; + +const graphClassName = 'vscode-codeql__result-tables-graph'; +const graphId = 'graph-results'; +export class Graph extends React.Component { + constructor(props: GraphProps) { + super(props); + } + + public render = (): JSX.Element => { + const { resultSet, offset } = this.props; + const graphData = resultSet.interpretation?.data?.dot[offset]; + + if (!graphData) { + return <> +
Graph is not available.
+ ; + } + + return <> +
+ Warning: The Graph Viewer is not a publicly released feature and will crash on large graphs. +
+
Rendering graph...
+ ; + }; + + public componentDidMount = () => { + this.renderGraph(); + }; + + public componentDidUpdate = () => { + this.renderGraph(); + }; + + private renderGraph = () => { + const { databaseUri, resultSet, offset } = this.props; + const graphData = resultSet.interpretation?.data?.dot[offset]; + + if (!graphData) { + return; + } + + const options = { + fit: true, + fade: false, + growEnteringEdges: false, + zoom: true, + }; + + const element = document.querySelector(`#${graphId}`); + if (!element) { + return; + } + element.firstChild?.remove(); + + const color = getComputedStyle(element).color; + const backgroundColor = getComputedStyle(element).backgroundColor; + const borderColor = getComputedStyle(element).borderColor; + let firstPolygon = true; + + graphviz(`#${graphId}`) + .options(options) + .attributer(function(d) { + if (d.tag == 'a') { + const url = d.attributes['xlink:href'] || d.attributes['href']; + const loc = tryGetLocationFromString(url); + if (loc !== undefined) { + d.attributes['xlink:href'] = '#'; + d.attributes['href'] = '#'; + loc.uri = 'file://' + loc.uri; + d3.select(this).on('click', function(e) { jumpToLocation(loc, databaseUri); }); + } + } + + if ('fill' in d.attributes) { + d.attributes.fill = d.tag == 'text' ? color : backgroundColor; + } + if ('stroke' in d.attributes) { + // There is no proper way to identify the element containing the graph (which we + // don't want a border around), as it is just has tag 'polygon'. Instead we assume + // that the first polygon we see is that element + if (d.tag != 'polygon' || !firstPolygon) { + d.attributes.stroke = borderColor; + } else { + firstPolygon = false; + } + } + + }) + .renderDot(graphData); + }; +} diff --git a/extensions/ql-vscode/src/view/result-tables.tsx b/extensions/ql-vscode/src/view/result-tables.tsx index c34dc2938..9eff046ed 100644 --- a/extensions/ql-vscode/src/view/result-tables.tsx +++ b/extensions/ql-vscode/src/view/result-tables.tsx @@ -8,12 +8,14 @@ import { InterpretedResultsSortState, ResultSet, ALERTS_TABLE_NAME, + GRAPH_TABLE_NAME, SELECT_TABLE_NAME, getDefaultResultSetName, ParsedResultSets, IntoResultsViewMsg, } from '../pure/interface-types'; import { PathTable } from './alert-table'; +import { Graph } from './graph'; import { RawTable } from './raw-results-table'; import { ResultTableProps, @@ -61,8 +63,8 @@ function getResultCount(resultSet: ResultSet): number { switch (resultSet.t) { case 'RawResultSet': return resultSet.schema.rows; - case 'SarifResultSet': - return resultSet.numTotalResults; + case 'InterpretedResultSet': + return resultSet.interpretation.numTotalResults; } } @@ -87,27 +89,32 @@ export class ResultTables this.props.rawResultSets.map((rs) => ({ t: 'RawResultSet', ...rs })); if (this.props.interpretation != undefined) { + const tableName = this.getInterpretedTableName(); resultSets.push({ - t: 'SarifResultSet', + t: 'InterpretedResultSet', // FIXME: The values of version, columns, tupleCount are - // unused stubs because a SarifResultSet schema isn't used the + // unused stubs because a InterpretedResultSet schema isn't used the // same way as a RawResultSet. Probably should pull `name` field // out. schema: { - name: ALERTS_TABLE_NAME, + name: tableName, rows: 1, columns: [] }, - name: ALERTS_TABLE_NAME, - ...this.props.interpretation, + name: tableName, + interpretation: this.props.interpretation, }); } return resultSets; } + private getInterpretedTableName(): string { + return this.props.interpretation?.data.t === 'GraphInterpretationData' ? GRAPH_TABLE_NAME : ALERTS_TABLE_NAME; + } + private getResultSetNames(): string[] { return this.props.interpretation - ? this.props.parsedResultSets.resultSetNames.concat([ALERTS_TABLE_NAME]) + ? this.props.parsedResultSets.resultSetNames.concat([this.getInterpretedTableName()]) : this.props.parsedResultSets.resultSetNames; } @@ -349,8 +356,19 @@ class ResultTable extends React.Component; - case 'SarifResultSet': return ; + case 'InterpretedResultSet': { + const data = resultSet.interpretation.data; + switch (data.t) { + case 'SarifInterpretationData': { + const sarifResultSet = { ...resultSet, interpretation: { ...resultSet.interpretation, data } }; + return ; + } + case 'GraphInterpretationData': { + const grapResultSet = { ...resultSet, interpretation: { ...resultSet.interpretation, data } }; + return ; + } + } + } } } } diff --git a/extensions/ql-vscode/src/view/results.tsx b/extensions/ql-vscode/src/view/results.tsx index d20c0f7eb..c3fb886af 100644 --- a/extensions/ql-vscode/src/view/results.tsx +++ b/extensions/ql-vscode/src/view/results.tsx @@ -11,6 +11,7 @@ import { QueryMetadata, ResultsPaths, ALERTS_TABLE_NAME, + GRAPH_TABLE_NAME, ParsedResultSets, } from '../pure/interface-types'; import { EventHandlers as EventHandlerList } from './event-handler-list'; @@ -104,7 +105,9 @@ class App extends React.Component, ResultsViewState> { void this.loadResults(); break; - case 'showInterpretedPage': + case 'showInterpretedPage': { + const tableName = msg.interpretation.data.t === 'GraphInterpretationData' ? GRAPH_TABLE_NAME : ALERTS_TABLE_NAME; + this.updateStateWithNewResultsInfo({ resultsPath: '', // FIXME: Not used for interpreted, refactor so this is not needed parsedResultSets: { @@ -114,16 +117,16 @@ class App extends React.Component, ResultsViewState> { resultSetNames: msg.resultSetNames, pageNumber: msg.pageNumber, resultSet: { - t: 'SarifResultSet', - name: ALERTS_TABLE_NAME, + t: 'InterpretedResultSet', + name: tableName, schema: { - name: ALERTS_TABLE_NAME, + name: tableName, rows: 1, columns: [] }, - ...msg.interpretation, + interpretation: msg.interpretation, }, - selectedTable: ALERTS_TABLE_NAME, + selectedTable: tableName, }, origResultsPaths: undefined as any, // FIXME: Not used for interpreted, refactor so this is not needed sortedResultsMap: new Map(), // FIXME: Not used for interpreted, refactor so this is not needed @@ -136,6 +139,7 @@ class App extends React.Component, ResultsViewState> { }); void this.loadResults(); break; + } case 'resultsUpdating': this.setState({ isExpectingResultsUpdate: true, @@ -191,7 +195,7 @@ class App extends React.Component, ResultsViewState> { const resultSet = parsedResultSets.resultSet; if (!resultSet.t) { throw new Error( - 'Missing result set type. Should be either "SarifResultSet" or "RawResultSet".' + 'Missing result set type. Should be either "InterpretedResultSet" or "RawResultSet".' ); } return [resultSet]; @@ -260,6 +264,8 @@ class App extends React.Component, ResultsViewState> { ) { const parsedResultSets = displayedResults.resultsInfo.parsedResultSets; const key = (parsedResultSets.selectedTable || '') + parsedResultSets.pageNumber; + const data = displayedResults.resultsInfo.interpretation?.data; + return ( , ResultsViewState> { : undefined } sortStates={displayedResults.results.sortStates} - interpretedSortState={ - displayedResults.resultsInfo.interpretation?.sortState - } + interpretedSortState={data?.t == 'SarifInterpretationData' ? data.sortState : undefined} isLoadingNewResults={ this.state.isExpectingResultsUpdate || this.state.nextResultsInfo !== null @@ -298,6 +302,7 @@ class App extends React.Component, ResultsViewState> { componentDidMount(): void { this.vscodeMessageHandler = this.vscodeMessageHandler.bind(this); window.addEventListener('message', this.vscodeMessageHandler); + vscode.postMessage({ t: 'resultViewLoaded' }); } componentWillUnmount(): void { @@ -316,5 +321,3 @@ class App extends React.Component, ResultsViewState> { } Rdom.render(, document.getElementById('root')); - -vscode.postMessage({ t: 'resultViewLoaded' }); diff --git a/extensions/ql-vscode/src/view/resultsView.css b/extensions/ql-vscode/src/view/resultsView.css index 1d8c02084..fdb35ba73 100644 --- a/extensions/ql-vscode/src/view/resultsView.css +++ b/extensions/ql-vscode/src/view/resultsView.css @@ -134,6 +134,14 @@ select { font-size: inherit; } +.vscode-codeql__result-tables-graph { + background-color: transparent; + border-color: var(--vscode-dropdown-border); + color: var(--vscode-editor-foreground); + text-align: center; + width: 100%; +} + .vscode-codeql__result-tables-updating-text { margin-left: 1em; } diff --git a/extensions/ql-vscode/src/vscode-tests/directory-walker.ts b/extensions/ql-vscode/src/vscode-tests/directory-walker.ts deleted file mode 100644 index da0aa7b91..000000000 --- a/extensions/ql-vscode/src/vscode-tests/directory-walker.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import * as fs from 'fs-extra'; - -/** - * Recursively walk a directory and return the full path to all files found. - * Note that this function uses synchronous fs calls, so it should only be used in tests. - * - * @param dir the directory to walk - * - * @return An iterator of the full path to all files recursively found in the directory. - */ -export function* walk(dir: string): IterableIterator { - const files = fs.readdirSync(dir); - for (const file of files) { - const filePath = path.join(dir, file); - const stat = fs.statSync(filePath); - if (stat.isDirectory()) { - yield* walk(filePath); - } else { - yield filePath; - } - } -} diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts index 71a463785..ea1b3a6b6 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts @@ -65,8 +65,6 @@ describe('queryResolver', () => { it('should throw an error when there are no queries found', async () => { mockCli.resolveQueriesInSuite.returns([]); - // TODO: Figure out why chai-as-promised isn't failing the test on an - // unhandled rejection. try { await module.resolveQueries(mockCli, { dbschemePack: 'my-qlpack' }, KeyType.DefinitionQuery); // should reject diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/helpers.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/helpers.test.ts index 212733b6a..6af5fdda7 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/helpers.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/helpers.test.ts @@ -1,11 +1,23 @@ import { expect } from 'chai'; import 'mocha'; -import { EnvironmentVariableCollection, EnvironmentVariableMutator, Event, ExtensionContext, ExtensionMode, Memento, SecretStorage, SecretStorageChangeEvent, Uri, window } from 'vscode'; +import { + EnvironmentVariableCollection, + EnvironmentVariableMutator, + Event, + ExtensionContext, + ExtensionMode, + Memento, + SecretStorage, + SecretStorageChangeEvent, + Uri, + window +} from 'vscode'; import * as yaml from 'js-yaml'; import * as tmp from 'tmp'; import * as path from 'path'; import * as fs from 'fs-extra'; import * as sinon from 'sinon'; +import { DirResult } from 'tmp'; import { getInitialQueryContents, @@ -13,7 +25,8 @@ import { isLikelyDbLanguageFolder, showBinaryChoiceDialog, showBinaryChoiceWithUrlDialog, - showInformationMessageWithAction + showInformationMessageWithAction, + walkDirectory } from '../../helpers'; import { reportStreamProgress } from '../../commandRunner'; import Sinon = require('sinon'); @@ -377,3 +390,68 @@ describe('helpers', () => { }); }); }); + +describe('walkDirectory', () => { + let tmpDir: DirResult; + let dir: string; + let dir2: string; + + beforeEach(() => { + tmpDir = tmp.dirSync({ unsafeCleanup: true }); + dir = path.join(tmpDir.name, 'dir'); + fs.ensureDirSync(dir); + dir2 = path.join(tmpDir.name, 'dir2'); + }); + + afterEach(() => { + tmpDir.removeCallback(); + }); + + + it('should walk a directory', async () => { + const file1 = path.join(dir, 'file1'); + const file2 = path.join(dir, 'file2'); + const file3 = path.join(dir, 'file3'); + const dir3 = path.join(dir, 'dir3'); + const file4 = path.join(dir, 'file4'); + const file5 = path.join(dir, 'file5'); + const file6 = path.join(dir, 'file6'); + + // These symlinks link back to paths that are already existing, so ignore. + const symLinkFile7 = path.join(dir, 'symlink0'); + const symlinkDir = path.join(dir2, 'symlink1'); + + // some symlinks that point outside of the base dir. + const file8 = path.join(tmpDir.name, 'file8'); + const file9 = path.join(dir2, 'file8'); + const symlinkDir2 = path.join(dir2, 'symlink2'); + const symlinkFile2 = path.join(dir2, 'symlinkFile3'); + + fs.ensureDirSync(dir2); + fs.ensureDirSync(dir3); + + fs.writeFileSync(file1, 'file1'); + fs.writeFileSync(file2, 'file2'); + fs.writeFileSync(file3, 'file3'); + fs.writeFileSync(file4, 'file4'); + fs.writeFileSync(file5, 'file5'); + fs.writeFileSync(file6, 'file6'); + fs.writeFileSync(file8, 'file8'); + fs.writeFileSync(file9, 'file9'); + + // We don't really need to be testing all of these variants of symlinks, + // but it doesn't hurt, and will help us if we ever do decide to support them. + fs.symlinkSync(file6, symLinkFile7, 'file'); + fs.symlinkSync(dir3, symlinkDir, 'dir'); + fs.symlinkSync(file8, symlinkFile2, 'file'); + fs.symlinkSync(dir2, symlinkDir2, 'dir'); + + const files = []; + for await (const file of walkDirectory(dir)) { + files.push(file); + } + + // Only real files should be returned. + expect(files.sort()).to.deep.eq([file1, file2, file3, file4, file5, file6]); + }); +}); diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/query-results.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/query-results.test.ts index 0aa6843fc..893ef6127 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/query-results.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/query-results.test.ts @@ -5,7 +5,7 @@ import 'mocha'; import 'sinon-chai'; import * as sinon from 'sinon'; import * as chaiAsPromised from 'chai-as-promised'; -import { LocalQueryInfo, InitialQueryInfo, interpretResults } from '../../query-results'; +import { LocalQueryInfo, InitialQueryInfo, interpretResultsSarif } from '../../query-results'; import { QueryEvaluationInfo, QueryWithResults } from '../../run-queries'; import { QueryHistoryConfig } from '../../config'; import { EvaluationResult, QueryResultType } from '../../pure/messages'; @@ -189,11 +189,11 @@ describe('query-results', () => { }); }); - it('should interpretResults', async () => { + it('should interpretResultsSarif', async () => { const spy = sandbox.mock(); - spy.returns('1234'); + spy.returns({ a: '1234' }); const mockServer = { - interpretBqrs: spy + interpretBqrsSarif: spy } as unknown as CodeQLCliServer; const interpretedResultsPath = path.join(tmpDir.name, 'interpreted.json'); @@ -204,7 +204,7 @@ describe('query-results', () => { id: 'my-id' as string | undefined, scored: undefined }; - const results1 = await interpretResults( + const results1 = await interpretResultsSarif( mockServer, metadata, { @@ -213,7 +213,7 @@ describe('query-results', () => { sourceInfo as SourceInfo ); - expect(results1).to.eq('1234'); + expect(results1).to.deep.eq({ a: '1234', t: 'SarifInterpretationData' }); expect(spy).to.have.been.calledWith( metadata, resultsPath, interpretedResultsPath, sourceInfo @@ -221,9 +221,9 @@ describe('query-results', () => { // Try again, but with no id spy.reset(); - spy.returns('1234'); + spy.returns({ a: '1234' }); delete metadata.id; - const results2 = await interpretResults( + const results2 = await interpretResultsSarif( mockServer, metadata, { @@ -231,7 +231,7 @@ describe('query-results', () => { }, sourceInfo as SourceInfo ); - expect(results2).to.eq('1234'); + expect(results2).to.deep.eq({ a: '1234', t: 'SarifInterpretationData' }); expect(spy).to.have.been.calledWith( { kind: 'my-kind', id: 'dummy-id', scored: undefined }, resultsPath, interpretedResultsPath, sourceInfo @@ -242,7 +242,7 @@ describe('query-results', () => { fs.writeFileSync(interpretedResultsPath, JSON.stringify({ a: 6 }), 'utf8'); - const results3 = await interpretResults( + const results3 = await interpretResultsSarif( mockServer, metadata, { @@ -250,7 +250,7 @@ describe('query-results', () => { }, sourceInfo as SourceInfo ); - expect(results3).to.deep.eq({ a: 6 }); + expect(results3).to.deep.eq({ a: 6, t: 'SarifInterpretationData' }); }); describe('splat and slurp', () => { diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts index d64e11938..b8839ee38 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts @@ -17,7 +17,7 @@ import { AnalysesResultsManager } from '../../remote-queries/analyses-results-ma import { RemoteQueryResult } from '../../remote-queries/shared/remote-query-result'; import { DisposableBucket } from '../disposable-bucket'; import { testDisposeHandler } from '../test-dispose-handler'; -import { walk } from '../directory-walker'; +import { walkDirectory } from '../../helpers'; chai.use(chaiAsPromised); const expect = chai.expect; @@ -41,13 +41,19 @@ describe('Remote queries and query history manager', function() { let showTextDocumentSpy: sinon.SinonSpy; let openTextDocumentSpy: sinon.SinonSpy; - beforeEach(() => { + beforeEach(async function() { + + // set a higher timeout since recursive delete below may take a while, expecially on Windows. + this.timeout(120000); + // Since these tests change the state of the query history manager, we need to copy the original // to a temporary folder where we can manipulate it for tests - copyHistoryState(); + await copyHistoryState(); }); - afterEach(() => { + afterEach(function() { + // set a higher timeout since recursive delete below may take a while, expecially on Windows. + this.timeout(120000); deleteHistoryState(); }); @@ -321,18 +327,23 @@ describe('Remote queries and query history manager', function() { }); }); - function copyHistoryState() { + async function copyHistoryState() { fs.ensureDirSync(STORAGE_DIR); fs.copySync(path.join(__dirname, 'data/remote-queries/'), path.join(tmpDir.name, 'remote-queries')); // also, replace the files with "PLACEHOLDER" so that they have the correct directory - for (const p of walk(STORAGE_DIR)) { + for await (const p of walkDirectory(STORAGE_DIR)) { replacePlaceholder(path.join(p)); } } function deleteHistoryState() { - fs.removeSync(STORAGE_DIR); + fs.rmSync(STORAGE_DIR, { + recursive: true, + force: true, + maxRetries: 10, + retryDelay: 100 + }); } function replacePlaceholder(filePath: string) { diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/run-queries.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/run-queries.test.ts index 3b0a9f776..1b34faf79 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/run-queries.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/run-queries.test.ts @@ -4,15 +4,27 @@ import 'mocha'; import 'sinon-chai'; import * as sinon from 'sinon'; import * as chaiAsPromised from 'chai-as-promised'; +import { Uri } from 'vscode'; import { QueryEvaluationInfo } from '../../run-queries'; import { Severity, compileQuery } from '../../pure/messages'; -import { Uri } from 'vscode'; +import * as config from '../../config'; chai.use(chaiAsPromised); const expect = chai.expect; describe('run-queries', () => { + let sandbox: sinon.SinonSandbox; + beforeEach(() => { + sandbox = sinon.createSandbox(); + + sandbox.stub(config, 'isCanary').returns(false); + }); + + afterEach(() => { + sandbox.restore(); + }); + it('should create a QueryEvaluationInfo', () => { const saveDir = 'query-save-dir'; const info = createMockQueryInfo(true, saveDir); @@ -38,6 +50,13 @@ describe('run-queries', () => { info.metadata!.kind = 'table'; expect(info.canHaveInterpretedResults()).to.eq(false); + + // Graphs are not interpreted unless canary is set + info.metadata!.kind = 'graph'; + expect(info.canHaveInterpretedResults()).to.eq(false); + + (config.isCanary as sinon.SinonStub).returns(true); + expect(info.canHaveInterpretedResults()).to.eq(true); }); describe('compile', () => { @@ -108,7 +127,7 @@ describe('run-queries', () => { config: { timeoutSecs: 5 }, - sendRequest: sinon.stub().returns(new Promise(resolve => { + sendRequest: sandbox.stub().returns(new Promise(resolve => { resolve({ messages: [ { message: 'err', severity: Severity.ERROR }, @@ -117,7 +136,7 @@ describe('run-queries', () => { }); })), logger: { - log: sinon.spy() + log: sandbox.spy() } }; } diff --git a/extensions/ql-vscode/test/pure-tests/helpers-pure.test.ts b/extensions/ql-vscode/test/pure-tests/helpers-pure.test.ts index bc6935629..caa51edb9 100644 --- a/extensions/ql-vscode/test/pure-tests/helpers-pure.test.ts +++ b/extensions/ql-vscode/test/pure-tests/helpers-pure.test.ts @@ -1,5 +1,6 @@ import { fail } from 'assert'; import { expect } from 'chai'; + import { asyncFilter } from '../../src/pure/helpers-pure'; describe('helpers-pure', () => {