From 8149b2ef9c8bad9dbb8ae005dda0c7b618e6c8d3 Mon Sep 17 00:00:00 2001 From: miyuko Date: Sun, 12 Oct 2025 16:50:18 +0100 Subject: [PATCH 1/2] Add tsconfig.json --- package-lock.json | 17 ++++++++++++++++- package.json | 3 ++- src/d3wave.tsx | 4 +++- src/tsconfig.json | 13 +++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/tsconfig.json diff --git a/package-lock.json b/package-lock.json index b3fc824..9efebf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "monaco-editor": "^0.46.0", "pyodide": "^0.25.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "typescript": "^5.9.3" } }, "node_modules/@babel/code-frame": { @@ -2483,6 +2484,20 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", diff --git a/package.json b/package.json index 64b1056..73c71c4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "monaco-editor": "^0.46.0", "pyodide": "^0.25.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "typescript": "^5.9.3" } } diff --git a/src/d3wave.tsx b/src/d3wave.tsx index fcc98b5..da8c301 100644 --- a/src/d3wave.tsx +++ b/src/d3wave.tsx @@ -5,9 +5,11 @@ import { WaveGraph } from 'd3-wave'; import { RowRendererBits } from 'd3-wave'; export class RowRendererString extends RowRendererBits { + FORMATTERS: { STRING: any }; + DEFAULT_FORMAT: any; + constructor(waveGraph: WaveGraph) { super(waveGraph); - // @ts-ignore this.FORMATTERS = { "STRING": (data: { toString(): string }) => data.toString() diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..3f0934f --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "noEmit": true, + "skipLibCheck": true, + "jsx": "preserve", + "module": "preserve", + "target": "esnext", + "lib": [ + "ESNext", + "DOM", + ], + }, +} From 0822e11964b180d51ba4afb0f4fa88b758047c22 Mon Sep 17 00:00:00 2001 From: miyuko Date: Sun, 12 Oct 2025 16:50:18 +0100 Subject: [PATCH 2/2] Compress share links using Zstandard. --- build.mjs | 2 +- package-lock.json | 275 +++++++++---------------------------- package.json | 15 +- src/app.tsx | 107 ++++++++++++--- src/types.d.ts | 31 +++++ src/zstd/dictionary.bin | Bin 0 -> 5120 bytes src/zstd/index.ts | 106 ++++++++++++++ src/zstd/zstd-wrapper.c | 169 +++++++++++++++++++++++ src/zstd/zstd-wrapper.wasm | Bin 0 -> 79508 bytes src/zstd/zstd.diff | 79 +++++++++++ 10 files changed, 552 insertions(+), 232 deletions(-) create mode 100644 src/types.d.ts create mode 100644 src/zstd/dictionary.bin create mode 100644 src/zstd/index.ts create mode 100644 src/zstd/zstd-wrapper.c create mode 100755 src/zstd/zstd-wrapper.wasm create mode 100644 src/zstd/zstd.diff diff --git a/build.mjs b/build.mjs index 4985575..b1f688b 100644 --- a/build.mjs +++ b/build.mjs @@ -29,7 +29,7 @@ const options = { 'globalThis.GIT_COMMIT': `"${mode === 'minify' ? gitCommit : 'HEAD'}"`, 'globalThis.IS_PRODUCTION': (mode === 'minify' ? 'true' : 'false'), }, - target: 'es2021', + target: 'es2022', format: 'esm', sourcemap: 'linked', minify: (mode === 'minify'), diff --git a/package-lock.json b/package-lock.json index 9efebf0..19eae1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,23 +8,26 @@ "name": "amaranth-playground", "version": "0.0.0", "license": "BSD-2-Clause", - "devDependencies": { + "dependencies": { "@chialab/esbuild-plugin-meta-url": "^0.18.0", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@fontsource/inter": "^5.0.16", "@mui/icons-material": "^5.15.10", "@mui/joy": "^5.0.0-beta.28", - "@types/d3": "^7.4.3", - "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.19", "@yowasp/yosys": "release", + "core-js": "^3.46.0", "d3-wave": "^1.1.5", - "esbuild": "^0.25.0", "monaco-editor": "^0.46.0", "pyodide": "^0.25.0", "react": "^18.0.0", - "react-dom": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@types/d3": "^7.4.3", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", + "esbuild": "^0.25.0", "typescript": "^5.9.3" } }, @@ -32,7 +35,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -45,7 +47,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", - "dev": true, "dependencies": { "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", @@ -60,7 +61,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -73,7 +73,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -82,7 +81,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -91,7 +89,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -106,7 +103,6 @@ "version": "7.25.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", - "dev": true, "dependencies": { "@babel/types": "^7.25.2" }, @@ -121,7 +117,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -133,7 +128,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.25.0", @@ -147,7 +141,6 @@ "version": "7.25.3", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.25.0", @@ -165,7 +158,6 @@ "version": "7.25.2", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -179,7 +171,6 @@ "version": "0.18.2", "resolved": "https://registry.npmjs.org/@chialab/esbuild-plugin-meta-url/-/esbuild-plugin-meta-url-0.18.2.tgz", "integrity": "sha512-uIRIdLvYnw5mLrTRXY0BTgeZx6ANL2/OHkWFl8FaiTYNb7cyXmwEDRE1mh6kBXPRPtGuqv6XSpNX+koEkElu4g==", - "dev": true, "dependencies": { "@chialab/esbuild-rna": "^0.18.1", "@chialab/estransform": "^0.18.1", @@ -193,7 +184,6 @@ "version": "0.18.2", "resolved": "https://registry.npmjs.org/@chialab/esbuild-rna/-/esbuild-rna-0.18.2.tgz", "integrity": "sha512-ckzskez7bxstVQ4c5cxbx0DRP2teldzrcSGQl2KPh1VJGdO2ZmRrb6vNkBBD5K3dx9tgTyvskWp4dV+Fbg07Ag==", - "dev": true, "dependencies": { "@chialab/estransform": "^0.18.0", "@chialab/node-resolve": "^0.18.0" @@ -206,7 +196,6 @@ "version": "0.18.1", "resolved": "https://registry.npmjs.org/@chialab/estransform/-/estransform-0.18.1.tgz", "integrity": "sha512-W/WmjpQL2hndD0/XfR0FcPBAUj+aLNeoAVehOjV/Q9bSnioz0GVSAXXhzp59S33ZynxJBBfn8DNiMTVNJmk4Aw==", - "dev": true, "dependencies": { "@parcel/source-map": "^2.0.0" }, @@ -218,7 +207,6 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/@chialab/node-resolve/-/node-resolve-0.18.0.tgz", "integrity": "sha512-eV1m70Qn9pLY9xwFmZ2FlcOzwiaUywsJ7NB/ud8VB7DouvCQtIHkQ3Om7uPX0ojXGEG1LCyO96kZkvbNTxNu0Q==", - "dev": true, "engines": { "node": ">=18" } @@ -227,7 +215,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", - "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -246,7 +233,6 @@ "version": "11.13.1", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", - "dev": true, "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", @@ -258,14 +244,12 @@ "node_modules/@emotion/hash": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "dev": true + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", - "dev": true, "dependencies": { "@emotion/memoize": "^0.9.0" } @@ -273,14 +257,12 @@ "node_modules/@emotion/memoize": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "dev": true + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { "version": "11.13.0", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", - "dev": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", @@ -304,7 +286,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", - "dev": true, "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", @@ -316,14 +297,12 @@ "node_modules/@emotion/sheet": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "dev": true + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/styled": { "version": "11.13.0", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", - "dev": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", @@ -345,14 +324,12 @@ "node_modules/@emotion/unitless": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", - "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==", - "dev": true + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", - "dev": true, "peerDependencies": { "react": ">=16.8.0" } @@ -360,14 +337,12 @@ "node_modules/@emotion/utils": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==", - "dev": true + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "dev": true + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.4", @@ -773,7 +748,6 @@ "version": "1.6.6", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.6.tgz", "integrity": "sha512-Vkvsw6EcpMHjvZZdMkSY+djMGFbt7CRssW99Ne8tar2WLnZ/l3dbxeTShbLQj+/s35h+Qb4cmnob+EzwtjrXGQ==", - "dev": true, "dependencies": { "@floating-ui/utils": "^0.2.6" } @@ -782,7 +756,6 @@ "version": "1.6.9", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.9.tgz", "integrity": "sha512-zB1PcI350t4tkm3rvUhSRKa9sT7vH5CrAbQxW+VaPYJXKAO0gsg4CTueL+6Ajp7XzAQC8CW4Jj1Wgqc0sB6oUQ==", - "dev": true, "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.6" @@ -792,7 +765,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dev": true, "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -804,20 +776,17 @@ "node_modules/@floating-ui/utils": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.6.tgz", - "integrity": "sha512-0KI3zGxIUs1KDR/pjQPdJH4Z8nGBm0yJ5WRoRfdw1Kzeh45jkIfA0rmD0kBF6fKHH+xaH7g8y4jIXyAV5MGK3g==", - "dev": true + "integrity": "sha512-0KI3zGxIUs1KDR/pjQPdJH4Z8nGBm0yJ5WRoRfdw1Kzeh45jkIfA0rmD0kBF6fKHH+xaH7g8y4jIXyAV5MGK3g==" }, "node_modules/@fontsource/inter": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.0.20.tgz", - "integrity": "sha512-rtw2F7xfM7rJmmnncXnR4ADr5wXsp4GyN1O1jmQJ1PMjAK+bm620/ZkQkeOYOkGoa09OksGinOeMA+Mkt6K9PQ==", - "dev": true + "integrity": "sha512-rtw2F7xfM7rJmmnncXnR4ADr5wXsp4GyN1O1jmQJ1PMjAK+bm620/ZkQkeOYOkGoa09OksGinOeMA+Mkt6K9PQ==" }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "0.2.36", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", "integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==", - "dev": true, "hasInstallScript": true, "engines": { "node": ">=6" @@ -827,7 +796,6 @@ "version": "5.15.4", "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz", "integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==", - "dev": true, "hasInstallScript": true, "dependencies": { "@fortawesome/fontawesome-common-types": "^0.2.36" @@ -840,7 +808,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -854,7 +821,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -863,7 +829,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -871,14 +836,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -888,7 +851,6 @@ "version": "5.0.0-beta.40", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@floating-ui/react-dom": "^2.0.8", @@ -920,7 +882,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.6.tgz", "integrity": "sha512-kytg6LheUG42V8H/o/Ptz3olSO5kUXW9zF0ox18VnblX6bO2yif1FPItgc3ey1t5ansb1+gbe7SatntqusQupg==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" @@ -930,7 +891,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz", "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -956,7 +916,6 @@ "version": "5.0.0-beta.48", "resolved": "https://registry.npmjs.org/@mui/joy/-/joy-5.0.0-beta.48.tgz", "integrity": "sha512-OhTvjuGl9I5IvpBr0BQyDehIW/xb2yteW6YglHJMdOb/279nItn76X1NBtPV9ImldNlBjReGwvpOXmBTTGER9w==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/base": "5.0.0-beta.40", @@ -997,7 +956,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.6.tgz", "integrity": "sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==", - "dev": true, "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", @@ -1043,7 +1001,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/utils": "^5.16.6", @@ -1070,7 +1027,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -1102,7 +1058,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.6.tgz", "integrity": "sha512-5xgyJjBIMPw8HIaZpfbGAaFYPwImQn7Nyh+wwKWhvkoIeDosQ1ZMVrbTclefi7G8hNmqhip04duYwYpbBFnBgw==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/private-theming": "^5.16.6", @@ -1142,7 +1097,6 @@ "version": "7.2.15", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", - "dev": true, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0" }, @@ -1156,7 +1110,6 @@ "version": "5.16.6", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", - "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/types": "^7.2.15", @@ -1186,7 +1139,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", - "dev": true, "dependencies": { "detect-libc": "^1.0.3" }, @@ -1198,7 +1150,6 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -1466,20 +1417,17 @@ "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1498,7 +1446,6 @@ "version": "4.4.10", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", - "dev": true, "peer": true, "dependencies": { "@types/react": "*" @@ -1507,14 +1454,12 @@ "node_modules/@yowasp/yosys": { "version": "0.44.759", "resolved": "https://registry.npmjs.org/@yowasp/yosys/-/yosys-0.44.759.tgz", - "integrity": "sha512-G7ZjA40dCXeVAYi+cYYI1A0JE1j9orZO0P1NFuE14PUa2miVbCcznyK6gERaCyi6tNv1x7IYRoGAqpBl7KTKZA==", - "dev": true + "integrity": "sha512-G7ZjA40dCXeVAYi+cYYI1A0JE1j9orZO0P1NFuE14PUa2miVbCcznyK6gERaCyi6tNv1x7IYRoGAqpBl7KTKZA==" }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -1526,7 +1471,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -1540,14 +1484,12 @@ "node_modules/base-64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", - "dev": true + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -1556,7 +1498,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1570,7 +1511,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -1579,7 +1519,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "dev": true, "engines": { "node": ">=6" } @@ -1588,7 +1527,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -1596,26 +1534,33 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "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==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/core-js": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.46.0.tgz", + "integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -1630,14 +1575,12 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "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==", - "dev": true, "dependencies": { "d3-array": "2", "d3-axis": "2", @@ -1675,7 +1618,6 @@ "version": "2.12.1", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dev": true, "dependencies": { "internmap": "^1.0.0" } @@ -1683,14 +1625,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 2", "d3-drag": "2", @@ -1703,7 +1643,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-2.0.0.tgz", "integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==", - "dev": true, "dependencies": { "d3-path": "1 - 2" } @@ -1711,14 +1650,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-array": "2" } @@ -1727,7 +1664,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", - "dev": true, "dependencies": { "delaunator": "4" } @@ -1735,14 +1671,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 2", "d3-selection": "2" @@ -1752,7 +1686,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", - "dev": true, "dependencies": { "commander": "2", "iconv-lite": "0.4", @@ -1773,14 +1706,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-dsv": "1 - 2" } @@ -1789,7 +1720,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 2", "d3-quadtree": "1 - 2", @@ -1799,14 +1729,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-array": "^2.5.0" } @@ -1814,14 +1742,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-color": "1 - 2" } @@ -1829,32 +1755,27 @@ "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==", - "dev": true + "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==", - "dev": true + "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==", - "dev": true + "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-array": "^2.3.0", "d3-format": "1 - 2", @@ -1867,7 +1788,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", - "dev": true, "dependencies": { "d3-color": "1 - 2", "d3-interpolate": "1 - 2" @@ -1876,14 +1796,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-path": "1 - 2" } @@ -1892,7 +1810,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", - "dev": true, "dependencies": { "d3-array": "2" } @@ -1901,7 +1818,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", - "dev": true, "dependencies": { "d3-time": "1 - 2" } @@ -1909,14 +1825,12 @@ "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==", - "dev": true + "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==", - "dev": true, "dependencies": { "d3-color": "1 - 2", "d3-dispatch": "1 - 2", @@ -1932,7 +1846,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/d3-wave/-/d3-wave-1.1.5.tgz", "integrity": "sha512-F89EXvF9AWikScz5liFW/q30y4b6NOcL0rUYuXij1Cacx7aclIML5FMZFiH3Oan05quExPsNvABzVdX7mThggw==", - "dev": true, "dependencies": { "@fortawesome/free-solid-svg-icons": "^5.15.0", "d3": "^6.5.0" @@ -1942,7 +1855,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 2", "d3-drag": "2", @@ -1955,7 +1867,6 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1971,14 +1882,12 @@ "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==", - "dev": true + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -1990,7 +1899,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dev": true, "peer": true, "dependencies": { "@babel/runtime": "^7.8.7", @@ -2001,7 +1909,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -2050,7 +1957,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -2061,14 +1967,12 @@ "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2077,7 +1981,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -2086,7 +1989,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -2095,7 +1997,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -2107,7 +2008,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, "dependencies": { "react-is": "^16.7.0" } @@ -2115,14 +2015,12 @@ "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "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" }, @@ -2134,7 +2032,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2149,20 +2046,17 @@ "node_modules/internmap": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", - "dev": true + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-core-module": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", - "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -2176,14 +2070,12 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -2194,20 +2086,17 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -2219,7 +2108,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -2228,7 +2116,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -2239,20 +2126,17 @@ "node_modules/monaco-editor": { "version": "0.46.0", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.46.0.tgz", - "integrity": "sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ==", - "dev": true + "integrity": "sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ==" }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2261,7 +2145,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -2273,7 +2156,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -2290,14 +2172,12 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -2305,14 +2185,12 @@ "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -2322,14 +2200,12 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/pyodide": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.25.1.tgz", "integrity": "sha512-y0nJ/fLA3bxD2iZRzvVTbP2O+wp4Ewm2wThfV4HF0BytQ6hsoqTJFLNY4usLOcCVBrK8TTWqFqrmsVPzHe4rsw==", - "dev": true, "dependencies": { "base-64": "^1.0.0", "ws": "^8.5.0" @@ -2339,7 +2215,6 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -2351,7 +2226,6 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -2363,14 +2237,12 @@ "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dev": true, "peer": true, "dependencies": { "@babel/runtime": "^7.5.5", @@ -2386,14 +2258,12 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -2410,7 +2280,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -2418,20 +2287,17 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "dev": true + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "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.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -2440,7 +2306,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2448,14 +2313,12 @@ "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "dev": true + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2467,7 +2330,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -2479,7 +2341,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -2502,7 +2363,6 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -2523,7 +2383,6 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, "engines": { "node": ">= 6" } diff --git a/package.json b/package.json index 73c71c4..c1a449c 100644 --- a/package.json +++ b/package.json @@ -18,23 +18,26 @@ "watch": "node build.mjs watch", "serve": "node build.mjs serve" }, - "devDependencies": { + "dependencies": { "@chialab/esbuild-plugin-meta-url": "^0.18.0", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@fontsource/inter": "^5.0.16", "@mui/icons-material": "^5.15.10", "@mui/joy": "^5.0.0-beta.28", - "@types/d3": "^7.4.3", - "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.19", "@yowasp/yosys": "release", + "core-js": "^3.46.0", "d3-wave": "^1.1.5", - "esbuild": "^0.25.0", "monaco-editor": "^0.46.0", "pyodide": "^0.25.0", "react": "^18.0.0", - "react-dom": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@types/d3": "^7.4.3", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", + "esbuild": "^0.25.0", "typescript": "^5.9.3" } } diff --git a/src/app.tsx b/src/app.tsx index b9612d0..dea04bb 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,3 +1,6 @@ +import 'core-js/modules/es.uint8-array.from-base64'; +import 'core-js/modules/es.uint8-array.to-base64'; + import { createRoot } from 'react-dom/client'; import * as React from 'react'; @@ -13,6 +16,7 @@ import IconButton from '@mui/joy/IconButton'; import Select from '@mui/joy/Select'; import Option from '@mui/joy/Option'; import Link from '@mui/joy/Link'; +import CircularProgress from '@mui/joy/CircularProgress'; import Snackbar from '@mui/joy/Snackbar'; import Alert from '@mui/joy/Alert'; import Tabs from '@mui/joy/Tabs'; @@ -30,26 +34,90 @@ import * as monaco from 'monaco-editor'; import { EditorState, Editor } from './monaco'; import { Viewer as WaveformViewer } from './d3wave'; import { PythonError, runner } from './runner'; +import { compress, decompress } from './zstd'; import data from './config'; import './app.css'; -function stealHashQuery() { +interface SharePayload { + av: string; + s: string; +} + +const zstdMagic = new Uint8Array([0x28, 0xb5, 0x2f, 0xfd]); + +const getSharePayloadDictionary = (() => { + let promise: Promise | undefined; + return async () => { + return promise ??= + fetch(new URL('zstd/dictionary.bin', import.meta.url).toString()) + .then((response) => response.arrayBuffer()) + .then((buffer) => new Uint8Array(buffer)); + }; +})(); + +async function createShareFragment(sourceCode: string, amaranthVersion: string): Promise { + let payload = JSON.stringify({ + av: amaranthVersion, + s: sourceCode, + } satisfies SharePayload); + + let compressed = await compress( + new TextEncoder().encode(payload), + getSharePayloadDictionary(), + ); + + // Remove the Zstandard magic bytes and add a version field + let result = new Uint8Array(1 + compressed.length - zstdMagic.length); + result[0] = 1; // version + result.set(compressed.subarray(zstdMagic.length), 1); + + return result.toBase64(); +} + +async function decodeShareFragment(hashQuery: string): Promise { + if (/^[0-9A-Za-z+/=]+$/.test(hashQuery)) { + let bytes = Uint8Array.fromBase64(hashQuery); + // Check the version + if (bytes[0] === 1) { + let zstdPayload = bytes.subarray(1); + if (indexedDB.cmp(bytes.subarray(0, 4), zstdMagic) !== 0) { + zstdPayload = (() => { + let result = new Uint8Array(zstdMagic.length + zstdPayload.length); + result.set(zstdMagic); + result.set(zstdPayload, zstdMagic.length); + return result; + })(); + } + bytes = await decompress( + zstdPayload, + getSharePayloadDictionary(), + ); + } else if (bytes[0] !== '{'.charCodeAt(0)) { + return; + } + return JSON.parse(new TextDecoder().decode(bytes)); + } else { + // Legacy encoding, used 2024-02-16 to 2024-02-24. + return JSON.parse(decodeURIComponent(hashQuery.replace('+', '%20'))); + } +} + +async function stealHashQuery() { const { hash } = window.location; if (hash !== '') { history.replaceState(null, '', ' '); // remove #... from URL entirely const hashQuery = hash.substring(1); try { - return JSON.parse(atob(hashQuery)); - } catch { - try { - // Legacy encoding, used 2024-02-16 to 2024-02-24. - return JSON.parse(decodeURIComponent(hashQuery.replace('+', '%20'))); - } catch {} + return decodeShareFragment(hashQuery); + } catch (error) { + console.warn('Could not parse the URL fragment, ignoring.', error); } } } +const query: { av?: string, s?: string } | undefined = await stealHashQuery(); + interface TerminalChunk { stream: 'stdout' | 'stderr'; text: string; @@ -64,7 +132,6 @@ function AppContent() { const {mode, setMode} = useColorScheme(); useEffect(() => monaco.editor.setTheme(mode === 'light' ? 'vs' : 'vs-dark'), [mode]); - const query: { av?: string, s?: string } | undefined = stealHashQuery(); const [amaranthVersion, setAmaranthVersion] = useState( query?.av ?? localStorage.getItem('amaranth-playground.amaranthVersion') @@ -72,6 +139,7 @@ function AppContent() { useEffect(() => localStorage.setItem('amaranth-playground.amaranthVersion', amaranthVersion), [amaranthVersion]); const [running, setRunning] = useState(false); const [sharingOpen, setSharingOpen] = useState(false); + const [shareURL, setShareURL] = useState(''); const [tutorialDone, setTutorialDone] = useState(localStorage.getItem('amaranth-playground.tutorialDone') !== null); useEffect(() => tutorialDone ? localStorage.setItem('amaranth-playground.tutorialDone', '') : void 0, [tutorialDone]); const [activeTab, setActiveTab] = useState(tutorialDone ? 'amaranth-source' : 'tutorial'); @@ -160,6 +228,14 @@ function AppContent() { const runCodeRef = useRef(runCode); runCodeRef.current = runCode; + async function shareCode() { + setSharingOpen(true); + setShareURL(''); + let fragment = await createShareFragment(amaranthSource, amaranthVersion); + let url = new URL('#' + fragment, window.location.href).toString(); + setShareURL(url); + } + const amaranthSourceEditorActions = React.useMemo(() => [ { id: 'amaranth-playground.run', @@ -472,7 +548,7 @@ function AppContent() { color='neutral' variant='outlined' endDecorator={} - onClick={() => setSharingOpen(true)} + onClick={() => shareCode()} > Share @@ -482,14 +558,11 @@ function AppContent() { open={sharingOpen} onClose={(_event, _reason) => setSharingOpen(false)} > - - Copy this link to share the source code - + {shareURL === '' ? : ( + + Copy this link to share the source code + + )} { + /** + * Converts the `Uint8Array` to a base64-encoded string. + * @param options If provided, sets the alphabet and padding behavior used. + * @returns A base64-encoded string. + */ + toBase64( + options?: { + alphabet?: "base64" | "base64url" | undefined; + omitPadding?: boolean | undefined; + }, + ): string; +} + +interface Uint8ArrayConstructor { + /** + * Creates a new `Uint8Array` from a base64-encoded string. + * @param string The base64-encoded string. + * @param options If provided, specifies the alphabet and handling of the last chunk. + * @returns A new `Uint8Array` instance. + * @throws {SyntaxError} If the input string contains characters outside the specified alphabet, or if the last + * chunk is inconsistent with the `lastChunkHandling` option. + */ + fromBase64( + string: string, + options?: { + alphabet?: "base64" | "base64url" | undefined; + lastChunkHandling?: "loose" | "strict" | "stop-before-partial" | undefined; + }, + ): Uint8Array; +} diff --git a/src/zstd/dictionary.bin b/src/zstd/dictionary.bin new file mode 100644 index 0000000000000000000000000000000000000000..11393b8f38352365161b281bec12e7e2757b5ae3 GIT binary patch literal 5120 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 literal 0 HcmV?d00001 diff --git a/src/zstd/index.ts b/src/zstd/index.ts new file mode 100644 index 0000000..fce4500 --- /dev/null +++ b/src/zstd/index.ts @@ -0,0 +1,106 @@ +let modules = new Map>(); + +async function createWasmInstance(moduleURL: string) { + let instance: WebAssembly.Instance; + if (!modules.has(moduleURL)) { + let promiseWithResolvers = Promise.withResolvers(); + modules.set(moduleURL, promiseWithResolvers.promise); + let result = await WebAssembly.instantiateStreaming(fetch(moduleURL)); + instance = result.instance; + promiseWithResolvers.resolve(result.module); + } else { + instance = await WebAssembly.instantiate(await modules.get(moduleURL)); + } + return { + instance, + exports: instance.exports as { + memory: WebAssembly.Memory; + + allocate: (size: number) => number; + + compress: ( + decompressed_data: number, decompressed_size: number, + dictionary_data: number, dictionary_size: number, + ) => number; + + decompress: ( + compressed_data: number, compressed_size: number, + dictionary_data: number, dictionary_size: number, + ) => number; + + get_result_error: (result: number) => number; + get_result_size: (result: number) => number; + get_result_data: (result: number) => number; + } + }; +} + +export async function compress(data: Uint8Array, dictionaryPromise: Promise) { + let [{ exports }, dictionary] = await Promise.all([ + createWasmInstance(new URL('zstd-wrapper.wasm', import.meta.url).toString()), + dictionaryPromise, + ]); + + let { + memory, allocate, compress, + get_result_error, + get_result_size, + get_result_data, + } = exports; + + let dictionaryPtr = allocate(dictionary.byteLength); + new Uint8Array(memory.buffer, dictionaryPtr, dictionary.byteLength).set(dictionary); + + let dataPtr = allocate(data.byteLength); + new Uint8Array(memory.buffer, dataPtr, data.byteLength).set(data); + + let resultPtr = compress( + dataPtr, data.byteLength, + dictionaryPtr, dictionary.byteLength, + ); + + let error = get_result_error(resultPtr); + let size = get_result_size(resultPtr); + let compressed_data = get_result_data(resultPtr); + + if (error !== 0) { + throw new Error(`Zstandard compression error ${error}`); + } + + return new Uint8Array(memory.buffer, compressed_data, size); +} + +export async function decompress(data: Uint8Array, dictionaryPromise: Promise) { + let [{ exports }, dictionary] = await Promise.all([ + createWasmInstance(new URL('zstd-wrapper.wasm', import.meta.url).toString()), + dictionaryPromise, + ]); + + let { + memory, allocate, decompress, + get_result_error, + get_result_size, + get_result_data, + } = exports; + + let dictionaryPtr = allocate(dictionary.byteLength); + new Uint8Array(memory.buffer, dictionaryPtr, dictionary.byteLength).set(dictionary); + + let dataPtr = allocate(data.byteLength); + new Uint8Array(memory.buffer, dataPtr, data.byteLength).set(data); + + let resultPtr = decompress( + dataPtr, data.byteLength, + dictionaryPtr, dictionary.byteLength, + ); + + let error = get_result_error(resultPtr); + let size = get_result_size(resultPtr); + let compressed_data = get_result_data(resultPtr); + + if (error !== 0) { + throw new Error(`Zstandard decompression error ${error}`); + } + + return new Uint8Array(memory.buffer, compressed_data, size); +} diff --git a/src/zstd/zstd-wrapper.c b/src/zstd/zstd-wrapper.c new file mode 100644 index 0000000..ef31fdd --- /dev/null +++ b/src/zstd/zstd-wrapper.c @@ -0,0 +1,169 @@ +/* + * Generate zstd.c: + * git clone https://github.com/facebook/zstd.git \ + * --revision 23dae4bf49a8b36ab88509c85137b49f74bbc76d + * git -C zstd apply < zstd.patch + * cd zstd/build/single_file_libs + * ./combine.py -r ../../lib -x legacy/zstd_legacy.h -o zstd.c zstd-in.c + * + * Build: + * clang --target=wasm32-wasi --std=c23 -Oz -nostdlib -flto \ + * -Wl,--no-entry -Wl,--lto-O3 zstd-wrapper.c -o zstd-wrapper.wasm + * wasm-opt --enable-bulk-memory-opt -c -Oz zstd-wrapper.wasm -o zstd-wrapper.wasm + * wasm-strip zstd-wrapper.wasm + */ + +#include +#include + +extern void __heap_base; + +bool malloc_initialized = false; +char *heap_end = 0; + +void *malloc(size_t size) +{ + if (size == 0) { + return nullptr; + } + if (!malloc_initialized) { + heap_end = &__heap_base; + malloc_initialized = true; + } + size_t avail_pages = __builtin_wasm_memory_size(0); + size_t used_pages = (((size_t)heap_end + size - 1) / 0x10000) + 1; + if (used_pages > avail_pages) { + __builtin_wasm_memory_grow(0, used_pages - avail_pages); + } + char *ptr = heap_end; + heap_end += size; + return ptr; +} + +void *calloc(size_t count, size_t size) +{ + void *ptr = malloc(count * size); + __builtin_memset(ptr, 0, count * size); + return ptr; +} + +void free(void *ptr) +{ + // do nothing +} + +#include "zstd.c" + +#define COMPRESSION_LEVEL 19 + +struct result { + uint32_t error; + size_t size; + uint8_t *data; +}; + +[[clang::export_name("allocate")]] +void *allocate(size_t size) +{ + return malloc(size); +} + +#ifndef DISABLE_COMPRESSION + +[[clang::export_name("compress")]] +struct result *compress(char *decompressed_data, size_t decompressed_size, + char *dictionary_data, size_t dictionary_size) +{ + struct result *result = malloc(sizeof(struct result)); + memset(result, 0, sizeof(struct result)); + + ZSTD_CCtx *cctx = ZSTD_createCCtx(); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, COMPRESSION_LEVEL); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); + + size_t load_dict_result = ZSTD_CCtx_loadDictionary(cctx, + dictionary_data, dictionary_size); + if (ZSTD_isError(load_dict_result)) { + result->error = ZSTD_getErrorCode(load_dict_result); + return result; + } + + size_t compressed_cap = ZSTD_compressBound(decompressed_size); + char *compressed_data = malloc(compressed_cap); + + size_t compressed_size = ZSTD_compress2(cctx, + compressed_data, compressed_cap, + decompressed_data, decompressed_size); + + ZSTD_freeCCtx(cctx); + + if (ZSTD_isError(compressed_size)) { + free(compressed_data); + result->error = ZSTD_getErrorCode(compressed_size); + return result; + } + + result->size = compressed_size; + result->data = compressed_data; + return result; +} + +#endif + +#ifndef DISABLE_DECOMPRESSION + +[[clang::export_name("decompress")]] +struct result *decompress(char *compressed_data, size_t compressed_size, + char *dictionary_data, size_t dictionary_size) +{ + struct result *result = malloc(sizeof(struct result)); + memset(result, 0, sizeof(struct result)); + + uint64_t decompressed_cap = ZSTD_getFrameContentSize( + compressed_data, compressed_size); + if (decompressed_cap == ZSTD_CONTENTSIZE_UNKNOWN || + decompressed_cap == ZSTD_CONTENTSIZE_ERROR) { + result->error = (decompressed_cap ^ (0ULL - 1)) + 1001; + return result; + } + + char *decompressed_data = malloc(decompressed_cap); + + ZSTD_DCtx *dctx = ZSTD_createDCtx(); + size_t decompressed_size = ZSTD_decompress_usingDict(dctx, + decompressed_data, decompressed_cap, + compressed_data, compressed_size, + dictionary_data, dictionary_size); + ZSTD_freeDCtx(dctx); + + if (ZSTD_isError(decompressed_size)) { + free(decompressed_data); + result->error = ZSTD_getErrorCode(decompressed_size); + return result; + } + + result->size = decompressed_size; + result->data = decompressed_data; + return result; +} + +#endif + +[[clang::export_name("get_result_error")]] +uint32_t get_result_error(struct result *result) +{ + return result->error; +} + +[[clang::export_name("get_result_size")]] +size_t get_result_size(struct result *result) +{ + return result->size; +} + +[[clang::export_name("get_result_data")]] +uint8_t *get_result_data(struct result *result) +{ + return result->data; +} diff --git a/src/zstd/zstd-wrapper.wasm b/src/zstd/zstd-wrapper.wasm new file mode 100755 index 0000000000000000000000000000000000000000..02be803907d5f80704613c2a3539de944e9336b2 GIT binary patch literal 79508 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 literal 0 HcmV?d00001 diff --git a/src/zstd/zstd.diff b/src/zstd/zstd.diff new file mode 100644 index 0000000..106725e --- /dev/null +++ b/src/zstd/zstd.diff @@ -0,0 +1,79 @@ +diff --git a/build/single_file_libs/zstd-in.c b/build/single_file_libs/zstd-in.c +index f381ecc4..f53c53e3 100644 +--- a/build/single_file_libs/zstd-in.c ++++ b/build/single_file_libs/zstd-in.c +@@ -42,16 +42,41 @@ + #define XXH_PRIVATE_API + #undef XXH_INLINE_ALL + #define XXH_INLINE_ALL ++#define XXH_NO_STDLIB + #define ZSTD_LEGACY_SUPPORT 0 +-#ifndef __EMSCRIPTEN__ +-#define ZSTD_MULTITHREAD +-#endif + #define ZSTD_TRACE 0 + /* TODO: Can't amalgamate ASM function */ + #define ZSTD_DISABLE_ASM 1 + ++#define HUF_FORCE_DECOMPRESS_X1 ++#define ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ++#define ZSTD_NO_INLINE ++#define ZSTD_STRIP_ERROR_STRINGS ++#define ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR ++#define ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR ++#define ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR ++#define ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR ++#define ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR ++#define ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR ++ ++#define ZSTD_DEPS_COMMON ++#include ++#include ++ ++#define memcpy(d,s,l) __builtin_memcpy((d),(s),(l)) ++#define memmove(d,s,l) __builtin_memmove((d),(s),(l)) ++#define memset(p,v,l) __builtin_memset((p),(v),(l)) ++ ++#define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l)) ++#define ZSTD_memmove(d,s,l) memmove((d),(s),(l)) ++#define ZSTD_memset(p,v,l) memset((p),(v),(l)) ++ ++#define ZSTD_DEPS_MALLOC ++#define ZSTD_malloc(s) malloc(s) ++#define ZSTD_calloc(n,s) calloc((n), (s)) ++#define ZSTD_free(p) free((p)) ++ + /* Include zstd_deps.h first with all the options we need enabled. */ +-#define ZSTD_DEPS_NEED_MALLOC + #define ZSTD_DEPS_NEED_MATH64 + #include "common/zstd_deps.h" + +@@ -59,7 +84,6 @@ + #include "common/entropy_common.c" + #include "common/error_private.c" + #include "common/fse_decompress.c" +-#include "common/threading.c" + #include "common/pool.c" + #include "common/zstd_common.c" + +@@ -84,8 +108,3 @@ + #include "decompress/zstd_ddict.c" + #include "decompress/zstd_decompress.c" + #include "decompress/zstd_decompress_block.c" +- +-#include "dictBuilder/cover.c" +-#include "dictBuilder/divsufsort.c" +-#include "dictBuilder/fastcover.c" +-#include "dictBuilder/zdict.c" +diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h +index b6af402f..d07e46cd 100644 +--- a/lib/common/xxhash.h ++++ b/lib/common/xxhash.h +@@ -2292,7 +2292,6 @@ XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + /* ************************************* + * Includes & Memory related functions + ***************************************/ +-#include /* memcmp, memcpy */ + #include /* ULLONG_MAX */ + + #if defined(XXH_NO_STREAM)