From dd4b3da174c471d25fdb2299867bc374fde1bf96 Mon Sep 17 00:00:00 2001 From: phink Date: Tue, 6 Feb 2024 15:28:22 +0100 Subject: [PATCH 1/4] Contrib/ai-simulator: .gitignore --- contrib/ai-simulator/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 contrib/ai-simulator/.gitignore diff --git a/contrib/ai-simulator/.gitignore b/contrib/ai-simulator/.gitignore new file mode 100644 index 000000000000..c2658d7d1b31 --- /dev/null +++ b/contrib/ai-simulator/.gitignore @@ -0,0 +1 @@ +node_modules/ -- GitLab From 26c2a7fee2a71b514d03a8e21f8aaa73e3f3ef3e Mon Sep 17 00:00:00 2001 From: phink Date: Thu, 29 Feb 2024 18:22:00 +0100 Subject: [PATCH 2/4] Contrib/ai-simulator: expected issuance --- contrib/ai-simulator/Makefile | 13 + contrib/ai-simulator/package-lock.json | 2438 +++++++++++++++++ contrib/ai-simulator/package.json | 31 + .../ai-simulator/script-scrap-weeklynet.sh | 93 + contrib/ai-simulator/site/index.html | 41 + contrib/ai-simulator/src/adaptive.js | 330 +++ contrib/ai-simulator/src/source.css | 9 + contrib/ai-simulator/src/source.js | 105 + .../src/total_frozen_stake_storage.js | 204 ++ .../ai-simulator/src/total_supply_storage.js | 204 ++ contrib/ai-simulator/tailwind.config.js | 8 + 11 files changed, 3476 insertions(+) create mode 100644 contrib/ai-simulator/Makefile create mode 100644 contrib/ai-simulator/package-lock.json create mode 100644 contrib/ai-simulator/package.json create mode 100755 contrib/ai-simulator/script-scrap-weeklynet.sh create mode 100644 contrib/ai-simulator/site/index.html create mode 100644 contrib/ai-simulator/src/adaptive.js create mode 100644 contrib/ai-simulator/src/source.css create mode 100644 contrib/ai-simulator/src/source.js create mode 100644 contrib/ai-simulator/src/total_frozen_stake_storage.js create mode 100644 contrib/ai-simulator/src/total_supply_storage.js create mode 100644 contrib/ai-simulator/tailwind.config.js diff --git a/contrib/ai-simulator/Makefile b/contrib/ai-simulator/Makefile new file mode 100644 index 000000000000..fbc4f89f78cc --- /dev/null +++ b/contrib/ai-simulator/Makefile @@ -0,0 +1,13 @@ +default: build + +server: + npm run server + +build: + npm run build + +css: + npm run css + +watch: + npm run watch diff --git a/contrib/ai-simulator/package-lock.json b/contrib/ai-simulator/package-lock.json new file mode 100644 index 000000000000..24d64e78b177 --- /dev/null +++ b/contrib/ai-simulator/package-lock.json @@ -0,0 +1,2438 @@ +{ + "name": "ai-simulator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ai-simulator", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "big-integer": "^1.6.52", + "big-rational": "^0.10.9", + "chart.js": "^4.4.1", + "chartjs-plugin-annotation": "^3.0.1", + "fraction.js": "^4.3.7", + "mathjs": "^12.3.0", + "prettier": "^3.2.5", + "snabbdom": "^3.6.2", + "watch": "^1.0.2" + }, + "devDependencies": { + "esbuild": "0.20.0", + "http-server": "^14.1.1", + "tailwindcss": "^3.4.1" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", + "integrity": "sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.0.tgz", + "integrity": "sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz", + "integrity": "sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.0.tgz", + "integrity": "sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz", + "integrity": "sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.0.tgz", + "integrity": "sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.0.tgz", + "integrity": "sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.0.tgz", + "integrity": "sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.0.tgz", + "integrity": "sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.0.tgz", + "integrity": "sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.0.tgz", + "integrity": "sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.0.tgz", + "integrity": "sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.0.tgz", + "integrity": "sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.0.tgz", + "integrity": "sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.0.tgz", + "integrity": "sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.0.tgz", + "integrity": "sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.0.tgz", + "integrity": "sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.0.tgz", + "integrity": "sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.0.tgz", + "integrity": "sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.0.tgz", + "integrity": "sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.0.tgz", + "integrity": "sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.0.tgz", + "integrity": "sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.0.tgz", + "integrity": "sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "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/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big-rational": { + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/big-rational/-/big-rational-0.10.9.tgz", + "integrity": "sha512-BV45yRpXsaueexsg5vfIB+75yHavzHRa8vqgaCvcJMibpsWNr8aVA2EQh44aeQKtRbjBouS/UVavxv8eb8bYxQ==", + "dependencies": { + "big-integer": "^1.6.40" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chart.js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz", + "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=7" + } + }, + "node_modules/chartjs-plugin-annotation": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.0.1.tgz", + "integrity": "sha512-hlIrXXKqSDgb+ZjVYHefmlZUXK8KbkCPiynSVrTb/HjTMkT62cOInaT1NTQCKtxKKOm9oHp958DY3RTAFKtkHg==", + "peerDependencies": { + "chart.js": ">=4.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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/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/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/complex.js": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", + "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.0.tgz", + "integrity": "sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.0", + "@esbuild/android-arm": "0.20.0", + "@esbuild/android-arm64": "0.20.0", + "@esbuild/android-x64": "0.20.0", + "@esbuild/darwin-arm64": "0.20.0", + "@esbuild/darwin-x64": "0.20.0", + "@esbuild/freebsd-arm64": "0.20.0", + "@esbuild/freebsd-x64": "0.20.0", + "@esbuild/linux-arm": "0.20.0", + "@esbuild/linux-arm64": "0.20.0", + "@esbuild/linux-ia32": "0.20.0", + "@esbuild/linux-loong64": "0.20.0", + "@esbuild/linux-mips64el": "0.20.0", + "@esbuild/linux-ppc64": "0.20.0", + "@esbuild/linux-riscv64": "0.20.0", + "@esbuild/linux-s390x": "0.20.0", + "@esbuild/linux-x64": "0.20.0", + "@esbuild/netbsd-x64": "0.20.0", + "@esbuild/openbsd-x64": "0.20.0", + "@esbuild/sunos-x64": "0.20.0", + "@esbuild/win32-arm64": "0.20.0", + "@esbuild/win32-ia32": "0.20.0", + "@esbuild/win32-x64": "0.20.0" + } + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "dependencies": { + "merge": "^1.2.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", + "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "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/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "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" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dev": true, + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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 + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/mathjs": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.3.0.tgz", + "integrity": "sha512-Mik+O8gbH14/1V2D/vdJNgu+qGXpF+2oeBJVBqN8nbOdZNuu4Nxw6aDbJ0QOkDSq/9bQ+AZpXoIxBuErRODS8w==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mathjs/node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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 + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "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==" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "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", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "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 + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/snabbdom": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.6.2.tgz", + "integrity": "sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==", + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/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/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "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/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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/supports-preserve-symlinks-flag": { + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "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/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/typed-function": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.1.tgz", + "integrity": "sha512-Pq1DVubcvibmm8bYcMowjVnnMwPVMeh0DIdA8ad8NZY2sJgapANJmiigSUwlt+EgXxpfIv8MWrQXTIzkfYZLYQ==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/watch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz", + "integrity": "sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==", + "dependencies": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/contrib/ai-simulator/package.json b/contrib/ai-simulator/package.json new file mode 100644 index 000000000000..aceedba993e5 --- /dev/null +++ b/contrib/ai-simulator/package.json @@ -0,0 +1,31 @@ +{ + "name": "ai-simulator", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "watch": "watch 'npm run build' ./src/ ./site/", + "build": "esbuild src/source.js --bundle --outfile=site/app.js", + "css": "npx tailwindcss -i ./src/source.css -o ./site/app.css --watch", + "server": "npx http-server site/ -p 8080" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "esbuild": "0.20.0", + "http-server": "^14.1.1", + "tailwindcss": "^3.4.1" + }, + "dependencies": { + "big-integer": "^1.6.52", + "big-rational": "^0.10.9", + "chart.js": "^4.4.1", + "chartjs-plugin-annotation": "^3.0.1", + "fraction.js": "^4.3.7", + "mathjs": "^12.3.0", + "prettier": "^3.2.5", + "snabbdom": "^3.6.2", + "watch": "^1.0.2" + } +} diff --git a/contrib/ai-simulator/script-scrap-weeklynet.sh b/contrib/ai-simulator/script-scrap-weeklynet.sh new file mode 100755 index 000000000000..33c694673bca --- /dev/null +++ b/contrib/ai-simulator/script-scrap-weeklynet.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +echo "var total_supply_storage = [" > src/total_supply_storage.js +echo "var total_frozen_stake_storage = [" > src/total_frozen_stake_storage.js +echo "var total_delegated_storage = [" > src/total_delegated_storage.js + +rm -rf "/tmp/ai-sim-supply/" +rm -rf "/tmp/ai-sim-frozen/" +rm -rf "/tmp/ai-sim-delegated/" + +mkdir -p "/tmp/ai-sim-supply" +mkdir -p "/tmp/ai-sim-frozen" +mkdir -p "/tmp/ai-sim-delegated" + +l=$1 + +for n in $(seq 0 $l); do + echo -ne "Launching data request for cycle: $n\r" + block=$((128 * (1 + n))) + + (curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/total_supply > "/tmp/ai-sim-supply/$n.txt" &) + + (curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/total_frozen_stake > "/tmp/ai-sim-frozen/$n.txt" &) + + ( + public_keys=$(curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/delegates) + public_keys=$(echo $public_keys | tr -d '[]"') + public_keys=$(echo $public_keys | tr ',' ' ') + + sum=0 + + for pkh in $public_keys; do + balance=$(curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/delegates/$pkh/delegated_balance) + balance=$(echo $balance | tr -d '"') + if ! [[ $balance =~ ^[0-9]+$ ]]; then + balance=0 + fi + sum=$(($sum + $balance)) + done + + echo "$sum" >> "/tmp/ai-sim-delegated/$n.txt" + ) & + +done + +echo +echo -ne "Waiting for data\r" + +for n in $(seq 0 $l); do + until [ -s "/tmp/ai-sim-supply/$n.txt" ]; do + sleep 0.1 + done +done + +for n in $(seq 0 $l); do + until [ -s "/tmp/ai-sim-frozen/$n.txt" ]; do + sleep 0.1 + done +done + +for n in $(seq 0 $l); do + until [ -s "/tmp/ai-sim-delegated/$n.txt" ]; do + sleep 0.1 + done +done + +for n in $(seq 0 $l); do + + supply=$(cat "/tmp/ai-sim-supply/$n.txt") + frozen=$(cat "/tmp/ai-sim-frozen/$n.txt") + delegated=$(cat "/tmp/ai-sim-delegated/$n.txt") + + echo "$supply," >> src/total_supply_storage.js + echo "$frozen," >> src/total_frozen_stake_storage.js + echo "$delegated," >> src/total_delegated_storage.js +done + +echo "];" >> src/total_supply_storage.js +echo "export {total_supply_storage};" >> src/total_supply_storage.js + +echo "];" >> src/total_frozen_stake_storage.js +echo "export {total_frozen_stake_storage};" >> src/total_frozen_stake_storage.js + +echo "];" >> src/total_delegated_storage.js +echo "export {total_delegated_storage};" >> src/total_delegated_storage.js + +echo + +rm -r "/tmp/ai-sim-supply/" +rm -r "/tmp/ai-sim-frozen/" +rm -r "/tmp/ai-sim-delegated/" + +echo "Data fetched and stored successfully." diff --git a/contrib/ai-simulator/site/index.html b/contrib/ai-simulator/site/index.html new file mode 100644 index 000000000000..9fb3f774313a --- /dev/null +++ b/contrib/ai-simulator/site/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CycleStartEndTotal supplyTotal delegatedTotal frozen stakeStaked ratioMin. ratioMax. ratioStaticBonusReward coeffAttesting reward per slotBaking reward fixed portionBaking reward bonus per slotSeed nonce revelation tipVdf revelation tip
+ + + diff --git a/contrib/ai-simulator/src/adaptive.js b/contrib/ai-simulator/src/adaptive.js new file mode 100644 index 000000000000..88dbe69f9fb3 --- /dev/null +++ b/contrib/ai-simulator/src/adaptive.js @@ -0,0 +1,330 @@ +import bigRat from "big-rational"; +import bigInt from "big-integer"; + +const seconds_per_day = bigRat(60 * 60 * 24); // 86400 + +Math.clip = (number, min, max) => Math.max(min, Math.min(number, max)); + +const initial_period = 10; // in cycles +const transition_period = 50; // in cycles + +const issuance_ratio_initial_min = bigRat(45, 1000); // 4.5% +const issuance_ratio_initial_max = bigRat(55, 1000); // 5.5% + +const issuance_ratio_global_min = bigRat(25, 10000); // 0.25% +const issuance_ratio_global_max = bigRat(10, 100); // 10% + +const growth_rate = bigRat(1, 100); +const ratio_target = bigRat(50, 100); +const ratio_radius = bigRat(2, 100); + +// Storage + +var storage_issuance_static = Array(1000).fill(0); +var storage_issuance_bonus = Array(1000).fill(0); +var storage_issuance_coeff = Array(1000).fill(bigRat.one); +var storage_staked_ratio = Array(1000).fill(0); +var storage_min_ratio = Array(1000).fill(0); +var storage_max_ratio = Array(1000).fill(0); +var storage_baking_power = Array(1000).fill(0); +var storage_rewards_ratio_for_delegating = Array(1000).fill(0); +var storage_rewards_ratio_for_staking = Array(1000).fill(0); +var storage_baking_reward_fixed_portion = Array(1000).fill(0); +var storage_baking_reward_bonus_per_slot = Array(1000).fill(0); +var storage_attestation_reward_per_slot = Array(1000).fill(0); +var storage_seed_nonce_revelation_tip = Array(1000).fill(0); +var storage_vdf_revelation_tip = Array(1000).fill(0); +var storage_estimated_rewards = Array(1000).fill(0); + +// + +const get_coeff = (c) => { + let coeff = storage_issuance_coeff[c]; + return coeff; +}; + +// + +const get_staked_ratio = (c) => bigRat(storage_staked_ratio[c]); + +const get_static_rate = (c) => bigRat(storage_issuance_static[c]); + +const get_bonus_rate = (c) => bigRat(storage_issuance_bonus[c]); + +const get_min_ratio = (c) => bigRat(storage_min_ratio[c]); + +const get_max_ratio = (c) => bigRat(storage_max_ratio[c]); + +// + +const get_total_estimated_rewards = (c) => storage_estimated_rewards[c]; + +// + +module.exports = (config) => { + const sum_weight = + config.proto.attestation_rewards + + config.proto.fixed_baking_rewards + + config.proto.bonus_baking_rewards + + config.proto.nonce_revelation + + config.proto.vdf_tip; + + const is_ai_activated = (cycle) => config.chain.ai_activation_cycle <= cycle; + + const in_initial_period = (cycle) => + cycle <= initial_period + config.chain.ai_activation_cycle; + + const in_transition_period = (cycle) => { + let l = initial_period + config.chain.ai_activation_cycle <= cycle; + let r = + cycle <= + initial_period + transition_period + config.chain.ai_activation_cycle; + return l && r; + }; + + const in_after_period = (cycle) => + cycle > + initial_period + transition_period + config.chain.ai_activation_cycle; + + const mul_ratio_z = (tez, n, d) => bigInt(tez).multiply(n).divide(d); + + const compute_extremum = (c, init, fin) => { + let trans = transition_period + 1; + let t1 = config.chain.ai_activation_cycle + initial_period; + let t2 = t1 + trans; + if (c <= t1) { + return init; + } else if (c >= t2) { + return fin; + } else { + let t = bigRat(c - t1); + let res = t + .multiply(fin - init) + .divide(trans) + .add(init); + return res; + } + }; + + const minimum_ratio = (c) => { + let res = compute_extremum( + c, + issuance_ratio_initial_min, + issuance_ratio_global_min, + ); + storage_min_ratio[c] = res; + return res; + }; + + const maximal_ratio = (c) => { + let res = compute_extremum( + c, + issuance_ratio_initial_max, + issuance_ratio_global_max, + ); + storage_max_ratio[c] = res; + return res; + }; + + const tez_from_weights = (weight) => { + let num = bigInt(weight).multiply(config.proto.minimal_block_delay); + let den = bigInt(sum_weight).multiply(60); + let res = mul_ratio_z(config.proto.base_total_issued_per_minute, num, den); + return res; + }; + + const reward_from_constants = (coeff, weight, d = 1) => { + let rewards = tez_from_weights(weight); + let num = coeff.numerator; + let den = coeff.denominator; + if (d == 1) { + let res = mul_ratio_z(rewards, num, den); + return res; + } else { + let base_rewards = rewards.divide(d); + let res = mul_ratio_z(base_rewards, num, den); + return res; + } + }; + + return { + // + + is_ai_activated: is_ai_activated, + + in_initial_period: in_initial_period, + + in_transition_period: in_transition_period, + + in_after_period: in_after_period, + + // + + get_coeff: get_coeff, + + get_staked_ratio: get_staked_ratio, + + get_static_rate: get_static_rate, + + get_bonus_rate: get_bonus_rate, + + get_total_estimated_rewards: get_total_estimated_rewards, + + get_min_ratio: get_min_ratio, + + get_max_ratio: get_max_ratio, + + // + + baking_reward_fixed_portion: function (c) { + let coeff = get_coeff(c); + let res = reward_from_constants(coeff, config.proto.fixed_baking_rewards); + storage_baking_reward_fixed_portion[c] = res; + return res; + }, + + baking_reward_bonus_per_slot: function (c) { + let coeff = get_coeff(c); + let bonus_committee_size = + config.proto.consensus_committee_size - + config.proto.consensus_threshold; + if (bonus_committee_size == 0) { + return 0; + } + let res = reward_from_constants( + coeff, + config.proto.bonus_baking_rewards, + bonus_committee_size, + ); + storage_baking_reward_bonus_per_slot[c] = res; + return res; + }, + + attestation_reward_per_slot: function (c) { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.attestation_rewards, + config.proto.consensus_committee_size, + ); + storage_attestation_reward_per_slot[c] = res; + return res; + }, + + seed_nonce_revelation_tip: function (c) { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.nonce_revelation * config.proto.blocks_per_commitment, + ); + storage_seed_nonce_revelation_tip[c] = res; + return res; + }, + + vdf_revelation_tip: function (c) { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.vdf_tip * config.proto.blocks_per_commitment, + ); + storage_vdf_revelation_tip[c] = res; + return res; + }, + + // + + compute_static: function (c, staked_ratio, issuance_min, issuance_max) { + let x = bigRat(1600).multiply(staked_ratio.pow(2)); + let res = x.reciprocate(); + storage_issuance_static[c] = res; + return Math.clip(res, issuance_min, issuance_max); + }, + + compute_bonus: function ( + issuance_ratio_max, + staked_ratio, + seconds_per_cycle, + base_reward_coeff_ratio, + previous_bonus, + ) { + let base_reward_coeff_dist_to_max = issuance_ratio_max.minus( + base_reward_coeff_ratio, + ); + let udist = staked_ratio.minus(ratio_target).abs().minus(ratio_radius); + let dist = staked_ratio.geq(ratio_target) ? udist.negate() : udist; + let days_per_cycle = bigRat(seconds_per_cycle).divide(86_400); + var new_bonus = previous_bonus.add( + dist.multiply(growth_rate).multiply(days_per_cycle), + ); + new_bonus = Math.max(new_bonus, bigRat.zero); + let max_new_bonus = Math.min( + base_reward_coeff_dist_to_max, + config.proto.max_bonus, + ); + new_bonus = Math.min(new_bonus, max_new_bonus); + return new_bonus; + // Issuance_bonus_repr.of_Q ~max_bonus new_bonus + }, + + compute_coeff: function ( + issuance_ratio_max, + issuance_ratio_min, + base_reward_coeff_ratio, + total_supply, + bonus, + ) { + let min_per_year = 525_600; + if (config.proto.base_total_issued_per_minute == 0) { + return 1; + } else { + let f1 = bigRat(base_reward_coeff_ratio).add(bonus); + let f2 = Math.clip(f1, issuance_ratio_min, issuance_ratio_max); + let f3 = bigRat(f2).divide(min_per_year); + let f4 = f3.multiply(total_supply); + let f5 = f4.divide(config.proto.base_total_issued_per_minute); + return f5; + } + }, + + compute_reward_coeff: function (current_cycle) { + let new_cycle = current_cycle + 1; + let for_cycle = new_cycle + config.proto.consensus_rights_delay; + let before_for_cycle = for_cycle - 1; + let total_supply = config.chain.get_total_supply(current_cycle); + let total_frozen_stake = config.chain.get_total_frozen_stake(for_cycle); + let staked_ratio = bigRat(total_frozen_stake).divide(total_supply); + storage_staked_ratio[new_cycle] = staked_ratio; + if (current_cycle < config.chain.ai_activation_cycle) { + return 1; + } else { + let previous_bonus = bigRat(storage_issuance_bonus[before_for_cycle]); + let seconds_per_cycle = + config.proto.blocks_per_cycle * config.proto.minimal_block_delay; + let issuance_ratio_min = minimum_ratio(new_cycle); + let issuance_ratio_max = maximal_ratio(new_cycle); + let base_reward_coeff_ratio = this.compute_static( + new_cycle, + staked_ratio, + issuance_ratio_min, + issuance_ratio_max, + ); + let bonus = this.compute_bonus( + issuance_ratio_max, + staked_ratio, + seconds_per_cycle, + base_reward_coeff_ratio, + previous_bonus, + ); + let coeff = this.compute_coeff( + issuance_ratio_max, + issuance_ratio_min, + base_reward_coeff_ratio, + total_supply, + bonus, + ); + storage_issuance_bonus[for_cycle] = bonus; + storage_issuance_coeff[for_cycle] = coeff; + } + }, + }; +}; diff --git a/contrib/ai-simulator/src/source.css b/contrib/ai-simulator/src/source.css new file mode 100644 index 000000000000..3caef6a677ea --- /dev/null +++ b/contrib/ai-simulator/src/source.css @@ -0,0 +1,9 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +table { + font-family: sans-serif; + font-size: 0.8rem; + letter-spacing: 1px; +} diff --git a/contrib/ai-simulator/src/source.js b/contrib/ai-simulator/src/source.js new file mode 100644 index 000000000000..c5589b1a16f5 --- /dev/null +++ b/contrib/ai-simulator/src/source.js @@ -0,0 +1,105 @@ +import { total_frozen_stake_storage } from "./total_frozen_stake_storage"; +import { total_supply_storage } from "./total_supply_storage"; +import { total_delegated_storage } from "./total_delegated_storage"; + +import bigInt from "big-integer"; + +// weeklynet configuration instance, next step is to generate it automatically. +const config = { + proto: { + attestation_rewards: 10_240, + base_total_issued_per_minute: 80_007_812, + blocks_per_cycle: 128, + blocks_per_commitment: 16, + bonus_baking_rewards: 5_120, + consensus_committee_size: 7000, + consensus_rights_delay: 3, + consensus_threshold: 4667, + fixed_baking_rewards: 5_120, + max_bonus: bigInt(50_000_000_000_000), + minimal_block_delay: 7, + nonce_revelation: 1, + vdf_tip: 1, + }, + + chain: { + ai_activation_cycle: 18, + get_total_frozen_stake: (c) => total_frozen_stake_storage[c], + get_total_supply: (c) => total_supply_storage[c], + }, +}; + +const simulator = require("./adaptive")(config); + +const tableBody = document.getElementById("report"); + +const decorate_row = (el, cycle) => { + if (cycle == config.ai_activation_cycle) { + el.classList.add("bg-green-600"); + } else if (simulator.is_ai_activated(cycle)) { + if (simulator.in_initial_period(cycle)) { + el.classList.add("bg-blue-100"); + } else if (simulator.in_transition_period(cycle)) { + el.classList.add("bg-pink-100"); + } else { + el.classList.add("bg-green-100"); + } + } else { + el.classList.add("bg-gray-100"); + } +}; + +const new_cell_for = (parent, content, rounded = true) => { + let el = document.createElement("td"); + el.classList.add("border-2"); + el.classList.add("px-4"); + el.classList.add("border-slate-600"); + parent.appendChild(el); + if (rounded) { + el.textContent = Math.trunc(content * 10_000) / 10_000; + } else { + el.textContent = content; + } + return el; +}; + +for ( + let cycle = 0; + cycle < total_supply_storage.length - config.proto.consensus_rights_delay - 3; + cycle++ +) { + simulator.compute_reward_coeff(cycle); + + let new_row = document.createElement("tr"); + new_row.classList.add("hover:bg-gray-200"); + + let new_cell = (content) => new_cell_for(new_row, content); + + decorate_row(new_cell(cycle), cycle); + + let first_block = 1 + config.proto.blocks_per_cycle * cycle; + let last_block = first_block + config.proto.blocks_per_cycle - 1; + + new_cell(first_block); + new_cell(last_block); + + new_cell(config.chain.get_total_supply(cycle)); + new_cell(config.chain.get_total_frozen_stake(cycle)); + + new_cell(simulator.get_staked_ratio(cycle)); + new_cell(simulator.get_min_ratio(cycle)); + new_cell(simulator.get_max_ratio(cycle)); + + new_cell(simulator.get_static_rate(cycle)); + new_cell(simulator.get_bonus_rate(cycle)); + + new_cell(simulator.get_coeff(cycle)); + + new_cell(simulator.attestation_reward_per_slot(cycle)); + new_cell(simulator.baking_reward_fixed_portion(cycle)); + new_cell(simulator.baking_reward_bonus_per_slot(cycle)); + new_cell(simulator.seed_nonce_revelation_tip(cycle)); + new_cell(simulator.vdf_revelation_tip(cycle)); + + tableBody.appendChild(new_row); +} diff --git a/contrib/ai-simulator/src/total_frozen_stake_storage.js b/contrib/ai-simulator/src/total_frozen_stake_storage.js new file mode 100644 index 000000000000..a69fde569247 --- /dev/null +++ b/contrib/ai-simulator/src/total_frozen_stake_storage.js @@ -0,0 +1,204 @@ +var total_frozen_stake_storage = [ +"694000000000", +"694000000000", +"694000000000", +"694000000000", +"694051383748", +"694135358027", +"694274336748", +"694358309715", +"694553524554", +"684167355337", +"684286764028", +"684406172786", +"684525581679", +"684644990436", +"684764399195", +"684883807953", +"685003216643", +"685122625468", +"685242034293", +"685361443119", +"685480851943", +"685600260502", +"685719687941", +"685839115724", +"685958543324", +"686077970761", +"687557272433", +"689036573136", +"1589515871889", +"1590995178417", +"1592476891919", +"1593959881689", +"1610528026751", +"1613159489870", +"1615966829775", +"1618480362175", +"1621475892468", +"1624249728113", +"2377249618249", +"2380086833794", +"2382891866809", +"2385854739835", +"2389582744235", +"2393307647869", +"2397529611563", +"2401568969530", +"2405381066407", +"2409407670951", +"2413547308884", +"2417604079612", +"2421589218987", +"2425839833317", +"2430165873255", +"2434346884533", +"2488558348874", +"2492929916897", +"2497376819412", +"2500735998951", +"2505211076781", +"2509568147453", +"2514236601257", +"2518852582593", +"2523350979289", +"2528070941067", +"2582639152778", +"2587502672872", +"2592541938124", +"2597390528747", +"2602223654015", +"2656849700060", +"2661734113106", +"2666661630494", +"2620894771268", +"2626177819062", +"2630955156710", +"2636101942056", +"2641484040355", +"2646902342952", +"2652395191219", +"2658154887737", +"2664184343761", +"2669793449351", +"2675499072626", +"2681192188806", +"2687496812686", +"2693848932480", +"2699440767885", +"2705492911971", +"2711484457500", +"2717585275652", +"2723627423005", +"2729845150977", +"2735702113244", +"2742105487886", +"2748330584966", +"2754329578216", +"2760508785339", +"2766562023245", +"2773069590102", +"2779057326547", +"2785455713234", +"2791553372814", +"2797860016929", +"2803942639030", +"2810303287615", +"2816650081021", +"2822916543214", +"2828946482606", +"2835023361693", +"2841362430952", +"2847449778724", +"2853208488753", +"2859591509350", +"2865618272448", +"2871230387321", +"2877261476747", +"2883263550277", +"2889291627581", +"2895739234317", +"2902217353486", +"2908173574720", +"2914133022495", +"2920341131407", +"2926280524320", +"2929623610712", +"2935806047784", +"2941655181765", +"2947677633481", +"2953753818436", +"2960084572243", +"2965983423358", +"2972283806660", +"2978749591871", +"2985095241698", +"2990958344609", +"2997564446075", +"3003628571522", +"3010210263793", +"3016451718347", +"3022954768998", +"3029289779254", +"3035728403573", +"3041874659133", +"3047940165602", +"3054178351692", +"3060602927100", +"3066948693904", +"3073320231327", +"3079968016143", +"3086413472521", +"3092612234587", +"3099392975373", +"3105885226967", +"3112247622906", +"3118345099346", +"3124709876587", +"3131417298136", +"3137622848126", +"3144220610069", +"3150470465803", +"3156581938262", +"3162902574309", +"3169189453869", +"3175653900261", +"3181927451829", +"3188313452313", +"3195101422184", +"3201447814467", +"3207861489899", +"3214050148050", +"3220348331390", +"3326789231215", +"3333268682840", +"3339831684988", +"3346125431861", +"3352711453686", +"3359584631045", +"3365973457215", +"3372073720841", +"3379085201558", +"3385747038900", +"3392166701033", +"3398475547401", +"3405116517997", +"3411875630316", +"3418323493394", +"3424976904974", +"3431269004317", +"3437679544629", +"3444253336841", +"3450342860450", +"3456741102739", +"3463200723737", +"3469688945591", +"3476200006101", +"3482489501173", +"3489309746772", +"3495557685107", +"3501891441594", +"3508311044395", +"3514921883320", +]; +export {total_frozen_stake_storage}; diff --git a/contrib/ai-simulator/src/total_supply_storage.js b/contrib/ai-simulator/src/total_supply_storage.js new file mode 100644 index 000000000000..c29bea70c4c6 --- /dev/null +++ b/contrib/ai-simulator/src/total_supply_storage.js @@ -0,0 +1,204 @@ +var total_supply_storage = [ +"5209319153837157", +"5209320343036208", +"5209321532700259", +"5209322721740310", +"5209323908995359", +"5209325121969820", +"5209326390723359", +"5209327659477564", +"5209328928233101", +"5209330196987306", +"5209331465741511", +"5209332734495716", +"5209334003249255", +"5209335272004126", +"5209336540758997", +"5209337809513868", +"5209339078268739", +"5209340347020946", +"5209341615775817", +"5209342884530022", +"5209344153284227", +"5209345422038432", +"5209353631704180", +"5209361841297116", +"5209370050762064", +"5209378260112635", +"5209386469783119", +"5209394679461340", +"5209402889129159", +"5209411098800178", +"5209419308465323", +"5209427518133668", +"5209435858424707", +"5209444329632929", +"5209452931455100", +"5209461663005012", +"5209470525159473", +"5209479518216943", +"5209488641893903", +"5209497896131497", +"5209507280440506", +"5209516795364543", +"5209526440898398", +"5209536217356910", +"5209546124425551", +"5209556162115417", +"5209566329812535", +"5209576628142738", +"5209587057002045", +"5209597616863908", +"5209608307196218", +"5209619127371792", +"5209630078468858", +"5209639576147222", +"5209650202253066", +"5209661017399724", +"5209671959656604", +"5209683440470268", +"5209695077896180", +"5209706918207290", +"5209718888985933", +"5209730996913444", +"5209743180910083", +"5209755518797807", +"5209767438294953", +"5209779429104640", +"5209791546934318", +"5209803790697691", +"5209816157311703", +"5209828649485922", +"5209841271239682", +"5209854011400448", +"5209867570919982", +"5209881263531789", +"5209895086749697", +"5209909040612494", +"5209923125388498", +"5209937340802984", +"5209951685928678", +"5209966161968184", +"5209980768639198", +"5209995505933944", +"5210010374143060", +"5210025242354293", +"5210040110575894", +"5210054978824365", +"5210069847083469", +"5210084715353069", +"5210099583641544", +"5210114451924022", +"5210129320208873", +"5210144188520722", +"5210159056826693", +"5210173925134918", +"5210188793478520", +"5210203661832618", +"5210218530205591", +"5210233398580818", +"5210248266966669", +"5210263135371267", +"5210278003745234", +"5210292872170961", +"5210307740599061", +"5210322609344532", +"5210337478084125", +"5210352346834223", +"5210367215603196", +"5210382084390916", +"5210396953189260", +"5210411821998109", +"5210426690801080", +"5210441559606296", +"5210456428430387", +"5210471297248481", +"5210486166997943", +"5210501036757901", +"5210515906536735", +"5210530776326074", +"5210545646117785", +"5210560515919992", +"5210575385724571", +"5210590255564411", +"5210605125381867", +"5210619995226323", +"5210634865064908", +"5210649734922241", +"5210664604790198", +"5210679474693407", +"5210694344582493", +"5210709214490327", +"5210724084392281", +"5210738954619859", +"5210753824841566", +"5210768695115029", +"5210783565366108", +"5210798431588345", +"5210813301860553", +"5210828172143385", +"5210843042444965", +"5210857912748917", +"5210872783071626", +"5210887653388455", +"5210902523732284", +"5210917394086737", +"5210932264451695", +"5210947134819025", +"5210962005213355", +"5210976875593553", +"5210991746009012", +"5211006616418591", +"5211021483183321", +"5211036353605768", +"5211051224055224", +"5211066094515304", +"5211080964977628", +"5211095835450585", +"5211110705950542", +"5211125576852612", +"5211140448261428", +"5211155318042880", +"5211170189763196", +"5211185061494136", +"5211199933227319", +"5211214804979388", +"5211229676733700", +"5211244548515142", +"5211259420282321", +"5211274292020642", +"5211289163817203", +"5211304015421289", +"5211318887255476", +"5211333759083790", +"5211348630922600", +"5211363502788540", +"5211378374656723", +"5211393246527286", +"5211408118416598", +"5211422990291775", +"5211437862210460", +"5211452734139778", +"5211467606063086", +"5211482477988765", +"5211497349941574", +"5211512214246632", +"5211527086220570", +"5211541958188498", +"5211556830191818", +"5211571702189128", +"5211586574495686", +"5211601446829246", +"5211616319165186", +"5211631191511622", +"5211646063852176", +"5211660936211479", +"5211675808589668", +"5211690680986606", +"5211705553377662", +"5211720425787467", +"5211735298216158", +"5211750171543082", +"5211765044872376", +]; +export {total_supply_storage}; diff --git a/contrib/ai-simulator/tailwind.config.js b/contrib/ai-simulator/tailwind.config.js new file mode 100644 index 000000000000..a43e15bab419 --- /dev/null +++ b/contrib/ai-simulator/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./site/**/*.{html, js}", "./src/**/*.js"], + theme: { + extend: {}, + }, + plugins: [], +}; -- GitLab From 8696fd5eba6ed966786190d2074d5492554c8943 Mon Sep 17 00:00:00 2001 From: phink Date: Tue, 5 Mar 2024 12:42:06 +0100 Subject: [PATCH 3/4] Contrib/ai-simulator: delegat(e/ors) reward computations --- .../ai-simulator/script-scrap-weeklynet.sh | 13 +- contrib/ai-simulator/site/index.html | 60 +- contrib/ai-simulator/src/adaptive.js | 839 ++++++++++++++---- contrib/ai-simulator/src/source.js | 98 +- .../src/total_delegated_storage.js | 204 +++++ 5 files changed, 994 insertions(+), 220 deletions(-) create mode 100644 contrib/ai-simulator/src/total_delegated_storage.js diff --git a/contrib/ai-simulator/script-scrap-weeklynet.sh b/contrib/ai-simulator/script-scrap-weeklynet.sh index 33c694673bca..592ecab19300 100755 --- a/contrib/ai-simulator/script-scrap-weeklynet.sh +++ b/contrib/ai-simulator/script-scrap-weeklynet.sh @@ -30,17 +30,20 @@ for n in $(seq 0 $l); do sum=0 for pkh in $public_keys; do - balance=$(curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/delegates/$pkh/delegated_balance) - balance=$(echo $balance | tr -d '"') - if ! [[ $balance =~ ^[0-9]+$ ]]; then - balance=0 - fi + balance1=$(curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/delegates/$pkh/delegated_balance | tr -d '"') + + balance2=$(curl -s https://rpc.weeklynet-2024-02-28.teztnets.com/chains/main/blocks/$block/context/delegates/$pkh/full_balance | tr -d '"') + + balance=$(($balance1 + $balance2)) + sum=$(($sum + $balance)) done echo "$sum" >> "/tmp/ai-sim-delegated/$n.txt" ) & + sleep 1 + done echo diff --git a/contrib/ai-simulator/site/index.html b/contrib/ai-simulator/site/index.html index 9fb3f774313a..cebe24da8948 100644 --- a/contrib/ai-simulator/site/index.html +++ b/contrib/ai-simulator/site/index.html @@ -14,21 +14,51 @@ Start End - Total supply - Total delegated - Total frozen stake - Staked ratio - Min. ratio - Max. ratio - Static - Bonus - Reward coeff - - Attesting reward per slot - Baking reward fixed portion - Baking reward bonus per slot - Seed nonce revelation tip - Vdf revelation tip + Total supply + Total delegated + Total frozen stake + Staked ratio + Min. ratio + Max. ratio + Static + Bonus + Reward coeff + Yearly rate + + Attesting reward per slot + Baking reward fixed portion + Baking reward bonus per slot + Seed nonce revelation tip + Vdf revelation tip + + Delegate fee + Edge of baking over staking + Limit of staking over baking + + + Delegate own staking balance + Delegate third-party staked balance + Delegate considered staked balance + Over staked balance + Free staked capacity + + Delegate spendable balance + Delegate third-party delegation balance + Delegate considered delegation balance + Over delegated balance + Free delegated capacity + + Delegate baking power + + Estimated total rewards + + Rewards ratio for staking + Estimated rewards for staking + + Rewards ratio for delegating + Estimated rewards for delegating + Estimated fee rewards + diff --git a/contrib/ai-simulator/src/adaptive.js b/contrib/ai-simulator/src/adaptive.js index 88dbe69f9fb3..cbc97291ab63 100644 --- a/contrib/ai-simulator/src/adaptive.js +++ b/contrib/ai-simulator/src/adaptive.js @@ -1,9 +1,11 @@ import bigRat from "big-rational"; import bigInt from "big-integer"; -const seconds_per_day = bigRat(60 * 60 * 24); // 86400 +const clip = (number, min, max) => Math.max(min, Math.min(number, max)); + +// Constants -Math.clip = (number, min, max) => Math.max(min, Math.min(number, max)); +const seconds_per_day = bigRat(60 * 60 * 24); // 86400 const initial_period = 10; // in cycles const transition_period = 50; // in cycles @@ -20,30 +22,49 @@ const ratio_radius = bigRat(2, 100); // Storage -var storage_issuance_static = Array(1000).fill(0); -var storage_issuance_bonus = Array(1000).fill(0); -var storage_issuance_coeff = Array(1000).fill(bigRat.one); -var storage_staked_ratio = Array(1000).fill(0); -var storage_min_ratio = Array(1000).fill(0); -var storage_max_ratio = Array(1000).fill(0); -var storage_baking_power = Array(1000).fill(0); -var storage_rewards_ratio_for_delegating = Array(1000).fill(0); -var storage_rewards_ratio_for_staking = Array(1000).fill(0); -var storage_baking_reward_fixed_portion = Array(1000).fill(0); -var storage_baking_reward_bonus_per_slot = Array(1000).fill(0); -var storage_attestation_reward_per_slot = Array(1000).fill(0); -var storage_seed_nonce_revelation_tip = Array(1000).fill(0); -var storage_vdf_revelation_tip = Array(1000).fill(0); -var storage_estimated_rewards = Array(1000).fill(0); - -// - -const get_coeff = (c) => { - let coeff = storage_issuance_coeff[c]; - return coeff; -}; +const storage_issuance_static = Array(1000).fill(0); +const storage_issuance_bonus = Array(1000).fill(0); +const storage_issuance_coeff = Array(1000).fill(bigRat.one); +const storage_staked_ratio = Array(1000).fill(0); + +const storage_min_ratio = Array(1000).fill(0); +const storage_max_ratio = Array(1000).fill(0); + +const storage_baking_reward_fixed_portion = Array(1000).fill(0); +const storage_baking_reward_bonus_per_slot = Array(1000).fill(0); +const storage_attestation_reward_per_slot = Array(1000).fill(0); +const storage_seed_nonce_revelation_tip = Array(1000).fill(0); +const storage_vdf_revelation_tip = Array(1000).fill(0); +const storage_estimated_rewards = Array(1000).fill(0); + +const storage_baking_power = Array(1000).fill(0); +const storage_rewards_ratio_for_delegating = Array(1000).fill(1); +const storage_rewards_ratio_for_staking = Array(1000).fill(1); + +const storage_delegate_spendable_balance = Array(1000).fill(0); +const storage_delegate_third_party_delegated_balance = Array(1000).fill(0); +const storage_delegate_own_staked_balance = Array(1000).fill(0); +const storage_delegate_third_party_staked_balance = Array(1000).fill(0); + +const storage_delegate_considered_staked_balance = Array(1000).fill(0); +const storage_delegate_considered_delegated_balance = Array(1000).fill(0); +const storage_delegate_over_staked_balance = Array(1000).fill(0); +const storage_delegate_over_delegated_balance = Array(1000).fill(0); + +const storage_delegate_available_staked_balance = Array(1000).fill(0); +const storage_delegate_available_delegated_balance = Array(1000).fill(0); + +const storage_delegate_rewards_baking_fee = Array(1000).fill(0); + +const storage_current_yearly_rate_value = Array(1000).fill(0); + +const storage_estimated_rewards_for_staking = Array(1000).fill(0); -// +const storage_estimated_rewards_for_delegating = Array(1000).fill(0); + +// Getters. + +const get_coeff = (c) => bigRat(storage_issuance_coeff[c]); const get_staked_ratio = (c) => bigRat(storage_staked_ratio[c]); @@ -55,11 +76,75 @@ const get_min_ratio = (c) => bigRat(storage_min_ratio[c]); const get_max_ratio = (c) => bigRat(storage_max_ratio[c]); -// +const get_delegate_spendable_balance = (c) => + storage_delegate_spendable_balance[c]; + +const get_delegate_third_party_delegated_balance = (c) => + storage_delegate_third_party_delegated_balance[c]; + +const get_delegate_own_staked_balance = (c) => + storage_delegate_own_staked_balance[c]; + +const get_delegate_third_party_staked_balance = (c) => + storage_delegate_third_party_staked_balance[c]; + +const get_delegate_baking_power = (c) => storage_baking_power[c]; + +const get_rewards_ratio_for_delegating = (c) => + storage_rewards_ratio_for_delegating[c]; + +const get_rewards_ratio_for_staking = (c) => + storage_rewards_ratio_for_staking[c]; const get_total_estimated_rewards = (c) => storage_estimated_rewards[c]; -// +const get_delegate_over_staked_balance = (c) => + storage_delegate_over_staked_balance[c]; + +const get_delegate_over_delegated_balance = (c) => + storage_delegate_over_delegated_balance[c]; + +const get_delegate_considered_staked_balance = (c) => + storage_delegate_considered_staked_balance[c]; + +const get_delegate_considered_delegated_balance = (c) => + storage_delegate_considered_delegated_balance[c]; + +const get_delegate_available_staked_balance = (c) => + storage_delegate_available_staked_balance[c]; + +const get_delegate_available_delegated_balance = (c) => + storage_delegate_available_delegated_balance[c]; + +const get_delegate_rewards_baking_fee = (c) => + storage_delegate_rewards_baking_fee[c]; + +const get_current_yearly_rate_value = (c) => + storage_current_yearly_rate_value[c]; + +const get_baking_reward_fixed_portion = (c) => + storage_baking_reward_fixed_portion[c]; + +const get_baking_reward_bonus_per_slot = (c) => + storage_baking_reward_bonus_per_slot[c]; + +const get_attestation_reward_per_slot = (c) => + storage_attestation_reward_per_slot[c]; + +const get_seed_nonce_revelation_tip = (c) => + storage_seed_nonce_revelation_tip[c]; + +const get_vdf_revelation_tip = (c) => storage_vdf_revelation_tip[c]; + +const get_estimated_rewards = (c) => storage_estimated_rewards[c]; + +const get_estimated_rewards_for_staking = (c) => + storage_estimated_rewards_for_staking[c]; + +const get_estimated_rewards_for_delegating = (c) => + storage_estimated_rewards_for_delegating[c]; + +// Export module.exports = (config) => { const sum_weight = @@ -71,8 +156,11 @@ module.exports = (config) => { const is_ai_activated = (cycle) => config.chain.ai_activation_cycle <= cycle; - const in_initial_period = (cycle) => - cycle <= initial_period + config.chain.ai_activation_cycle; + const in_initial_period = (cycle) => { + let l = config.chain.ai_activation_cycle < cycle; + let r = cycle <= initial_period + config.chain.ai_activation_cycle; + return l && r; + }; const in_transition_period = (cycle) => { let l = initial_period + config.chain.ai_activation_cycle <= cycle; @@ -137,194 +225,563 @@ module.exports = (config) => { let rewards = tez_from_weights(weight); let num = coeff.numerator; let den = coeff.denominator; - if (d == 1) { - let res = mul_ratio_z(rewards, num, den); - return res; + let base_rewards = rewards.divide(d); + return mul_ratio_z(base_rewards, num, den); + }; + + const compute_baking_reward_bonus_per_slot = (c) => { + let coeff = get_coeff(c); + let bonus_committee_size = + config.proto.consensus_committee_size - config.proto.consensus_threshold; + if (bonus_committee_size == 0) { + return 0; + } + let res = reward_from_constants( + coeff, + config.proto.bonus_baking_rewards, + bonus_committee_size, + ); + storage_baking_reward_bonus_per_slot[c] = res; + }; + + const current_rewards_per_minute = (c) => { + return bigRat(get_coeff(c)).times( + config.proto.base_total_issued_per_minute, + ); + }; + + const compute_current_yearly_rate_value = (c) => { + let min_per_year = 525600; + let total_supply = config.chain.get_total_supply(c); + let f = current_rewards_per_minute(c); + f = f.divide(total_supply); // issuance rate per minute + f = f.times(min_per_year); // issuance rate per year + let res = f.times(100); + storage_current_yearly_rate_value[c] = res; + }; + + const compute_attestation_reward_per_slot = (c) => { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.attestation_rewards, + config.proto.consensus_committee_size, + ); + storage_attestation_reward_per_slot[c] = res; + }; + + const compute_seed_nonce_revelation_tip = (c) => { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.nonce_revelation * config.proto.blocks_per_commitment, + ); + storage_seed_nonce_revelation_tip[c] = res; + }; + + const compute_baking_reward_fixed_portion = (c) => { + let coeff = get_coeff(c); + let res = reward_from_constants(coeff, config.proto.fixed_baking_rewards); + storage_baking_reward_fixed_portion[c] = res; + }; + + const compute_vdf_revelation_tip = (c) => { + let coeff = get_coeff(c); + let res = reward_from_constants( + coeff, + config.proto.vdf_tip * config.proto.blocks_per_commitment, + ); + storage_vdf_revelation_tip[c] = res; + }; + + const compute_static = (staked_ratio) => { + let res = bigRat(1600).multiply(staked_ratio.pow(2)).reciprocate(); + return res; + }; + + const compute_bonus = ( + issuance_ratio_max, + staked_ratio, + seconds_per_cycle, + base_reward_coeff_ratio, + previous_bonus, + ) => { + let base_reward_coeff_dist_to_max = issuance_ratio_max.minus( + base_reward_coeff_ratio, + ); + let udist = staked_ratio.minus(ratio_target).abs().minus(ratio_radius); + let dist = staked_ratio.geq(ratio_target) ? udist.negate() : udist; + let days_per_cycle = bigRat(seconds_per_cycle).divide(86_400); + var new_bonus = previous_bonus.add( + dist.multiply(growth_rate).multiply(days_per_cycle), + ); + new_bonus = Math.max(new_bonus, bigRat.zero); + let max_new_bonus = Math.min( + base_reward_coeff_dist_to_max, + config.proto.max_bonus, + ); + return Math.min(new_bonus, max_new_bonus); + // Issuance_bonus_repr.of_Q ~max_bonus new_bonus + }; + + const compute_coeff = ( + issuance_ratio_max, + issuance_ratio_min, + base_reward_coeff_ratio, + total_supply, + bonus, + ) => { + let min_per_year = 525_600; + if (config.proto.base_total_issued_per_minute == 0) { + return 1; } else { - let base_rewards = rewards.divide(d); - let res = mul_ratio_z(base_rewards, num, den); - return res; + let f1 = bigRat(base_reward_coeff_ratio).add(bonus); + let f2 = clip(f1, issuance_ratio_min, issuance_ratio_max); + let f3 = bigRat(f2).divide(min_per_year); + let f4 = f3.multiply(total_supply); + let f5 = f4.divide(config.proto.base_total_issued_per_minute); + return f5; } }; - return { - // + const compute_reward_coeff = (current_cycle) => { + let new_cycle = current_cycle + 1; + let for_cycle = new_cycle + config.proto.consensus_rights_delay; + let before_for_cycle = for_cycle - 1; + let total_supply = config.chain.get_total_supply(current_cycle); + let total_frozen_stake = config.chain.get_total_frozen_stake(for_cycle); + let staked_ratio = bigRat(total_frozen_stake).divide(total_supply); + storage_staked_ratio[new_cycle] = staked_ratio; + if (current_cycle < config.chain.ai_activation_cycle) { + return 1; + } else { + let previous_bonus = bigRat(storage_issuance_bonus[before_for_cycle]); + let seconds_per_cycle = + config.proto.blocks_per_cycle * config.proto.minimal_block_delay; + let issuance_ratio_min = minimum_ratio(new_cycle); + let issuance_ratio_max = maximal_ratio(new_cycle); + let base_reward_coeff_ratio = compute_static(staked_ratio); + storage_issuance_static[new_cycle] = base_reward_coeff_ratio; + base_reward_coeff_ratio = clip( + base_reward_coeff_ratio, + issuance_ratio_min, + issuance_ratio_max, + ); + let bonus = compute_bonus( + issuance_ratio_max, + staked_ratio, + seconds_per_cycle, + base_reward_coeff_ratio, + previous_bonus, + ); + let coeff = compute_coeff( + issuance_ratio_max, + issuance_ratio_min, + base_reward_coeff_ratio, + total_supply, + bonus, + ); - is_ai_activated: is_ai_activated, + storage_issuance_bonus[for_cycle] = bonus; + storage_issuance_coeff[for_cycle] = coeff; + } + }; - in_initial_period: in_initial_period, + const compute_delegate_baking_power = (cycle) => { + let own_staked = bigInt(get_delegate_own_staked_balance(cycle)); - in_transition_period: in_transition_period, + let third_party_staked = bigInt( + get_delegate_third_party_staked_balance(cycle), + ); - in_after_period: in_after_period, + let max_third_party_staked = own_staked.times( + Math.min( + config.delegate_policy.limit_of_staking_over_baking, + config.proto.max_limit_of_staking_over_baking, + ), + ); - // + let over_staked = third_party_staked.gt(max_third_party_staked) + ? third_party_staked.minus(max_third_party_staked) + : bigInt.zero; - get_coeff: get_coeff, + storage_delegate_over_staked_balance[cycle] = over_staked; - get_staked_ratio: get_staked_ratio, + let considered_staked = own_staked + .add(third_party_staked) + .minus(over_staked); - get_static_rate: get_static_rate, + storage_delegate_considered_staked_balance[cycle] = considered_staked; - get_bonus_rate: get_bonus_rate, + let available_staked = third_party_staked.gt(max_third_party_staked) + ? bigInt.zero + : max_third_party_staked.minus(third_party_staked); - get_total_estimated_rewards: get_total_estimated_rewards, + storage_delegate_available_staked_balance[cycle] = available_staked; - get_min_ratio: get_min_ratio, + let own_delegated = bigInt(get_delegate_spendable_balance(cycle)); - get_max_ratio: get_max_ratio, + let third_party_delegated = bigInt( + get_delegate_third_party_delegated_balance(cycle), + ); - // + let extended_delegated = own_delegated + .add(third_party_delegated) + .add(over_staked); - baking_reward_fixed_portion: function (c) { - let coeff = get_coeff(c); - let res = reward_from_constants(coeff, config.proto.fixed_baking_rewards); - storage_baking_reward_fixed_portion[c] = res; - return res; - }, - - baking_reward_bonus_per_slot: function (c) { - let coeff = get_coeff(c); - let bonus_committee_size = - config.proto.consensus_committee_size - - config.proto.consensus_threshold; - if (bonus_committee_size == 0) { - return 0; - } - let res = reward_from_constants( - coeff, + let max_delegated = considered_staked.times(9); + + let over_delegated = extended_delegated.gt(max_delegated) + ? extended_delegated.minus(max_delegated) + : bigInt.zero; + + storage_delegate_over_delegated_balance[cycle] = over_delegated; + + let available_delegated = extended_delegated.gt(max_delegated) + ? bigInt.zero + : max_delegated.minus(extended_delegated); + + storage_delegate_available_delegated_balance[cycle] = available_delegated; + + let considered_delegated = extended_delegated.minus(over_delegated); + + storage_delegate_considered_delegated_balance[cycle] = considered_delegated; + + let ratio_for_staking = bigRat(considered_staked.times(2)).divide( + considered_staked.times(2).add(considered_delegated), + ); + + let ratio_for_delegating = bigRat(considered_delegated).divide( + considered_staked.times(2).add(considered_delegated), + ); + + storage_rewards_ratio_for_staking[ + cycle + config.proto.consensus_rights_delay + 2 + ] = ratio_for_staking; + + storage_rewards_ratio_for_delegating[ + cycle + config.proto.consensus_rights_delay + 2 + ] = ratio_for_delegating; + + let total_staked = bigInt(config.chain.get_total_frozen_stake(cycle)); + let total_delegated = bigInt(config.chain.get_total_delegated(cycle)); + + let baking_power = bigRat( + considered_staked.times(2).add(considered_delegated), + ).divide(total_staked.times(2).add(total_delegated)); + + storage_baking_power[cycle + config.proto.consensus_rights_delay + 2] = + baking_power; + }; + + const compute_total_estimated_rewards = (cycle) => { + let coeff = get_coeff(cycle); + + let total_blocks = bigInt(get_baking_reward_fixed_portion(cycle)).times( + config.proto.blocks_per_cycle, + ); + + let total_bonus = bigInt( + get_baking_reward_bonus_per_slot( + cycle, config.proto.bonus_baking_rewards, - bonus_committee_size, - ); - storage_baking_reward_bonus_per_slot[c] = res; - return res; - }, - - attestation_reward_per_slot: function (c) { - let coeff = get_coeff(c); - let res = reward_from_constants( - coeff, - config.proto.attestation_rewards, - config.proto.consensus_committee_size, - ); - storage_attestation_reward_per_slot[c] = res; - return res; - }, + ), + ).times(config.proto.blocks_per_cycle); - seed_nonce_revelation_tip: function (c) { - let coeff = get_coeff(c); - let res = reward_from_constants( - coeff, - config.proto.nonce_revelation * config.proto.blocks_per_commitment, - ); - storage_seed_nonce_revelation_tip[c] = res; - return res; - }, + let total_attestations = bigInt( + reward_from_constants(coeff, config.proto.attestation_rewards), + ).times(config.proto.blocks_per_cycle); - vdf_revelation_tip: function (c) { - let coeff = get_coeff(c); - let res = reward_from_constants( - coeff, - config.proto.vdf_tip * config.proto.blocks_per_commitment, - ); - storage_vdf_revelation_tip[c] = res; - return res; - }, + let total_rewards = total_blocks + .add(total_bonus) + .add(total_attestations) + .add(get_seed_nonce_revelation_tip(cycle)) + .add(get_vdf_revelation_tip(cycle)); - // + let res = bigRat(total_rewards) + .times(get_delegate_baking_power(cycle)) + .round(); - compute_static: function (c, staked_ratio, issuance_min, issuance_max) { - let x = bigRat(1600).multiply(staked_ratio.pow(2)); - let res = x.reciprocate(); - storage_issuance_static[c] = res; - return Math.clip(res, issuance_min, issuance_max); - }, + storage_estimated_rewards[cycle] = res; + }; - compute_bonus: function ( - issuance_ratio_max, - staked_ratio, - seconds_per_cycle, - base_reward_coeff_ratio, - previous_bonus, - ) { - let base_reward_coeff_dist_to_max = issuance_ratio_max.minus( - base_reward_coeff_ratio, + const compute_estimated_rewards_for_staking = (c) => { + let res = bigRat(get_rewards_ratio_for_staking(c)) + .times(get_total_estimated_rewards(c)) + .round(); + storage_estimated_rewards_for_staking[c] = res; + }; + + const compute_estimated_rewards_for_delegating = (c) => { + let res = bigRat(get_rewards_ratio_for_delegating(c)) + .times(get_total_estimated_rewards(c)) + .round(); + storage_estimated_rewards_for_delegating[c] = res; + }; + + let compute_estimated_rewards_from_fees = (c) => { + let res = bigRat(get_estimated_rewards_for_delegating(c)) + .times(config.delegate_policy.fee) + .round(); + storage_delegate_rewards_baking_fee[c] = res; + }; + + const compute_delegate_own_spendable_balance = (cycle) => { + let rewards_from_delegating = get_estimated_rewards_for_delegating( + cycle - 1, + ); + + let own_rewards_from_delegating_fees = rewards_from_delegating + .times(config.delegate_policy.fee) + .round(); + + let rewards_from_delegating_stripped = rewards_from_delegating.minus( + own_rewards_from_delegating_fees, + ); + + let num = get_delegate_spendable_balance(cycle - 1); + + let den = + get_delegate_spendable_balance(cycle - 1) + + get_delegate_third_party_delegated_balance(cycle - 1); + + let ratio = bigRat(num).divide(den); + + let own_rewards_from_delegating_stripped = rewards_from_delegating_stripped + .times(ratio) + .round(); + + storage_delegate_spendable_balance[cycle] = + storage_delegate_spendable_balance[cycle - 1] + + own_rewards_from_delegating_stripped + + own_rewards_from_delegating_fees; + }; + + const compute_delegate_third_party_delegated_balance = (cycle) => { + let rewards_from_delegating_stripped = get_estimated_rewards_for_delegating( + cycle - 1, + ).times(1 - config.delegate_policy.fee); + + let num = get_delegate_third_party_delegated_balance(cycle - 1); + + let den = + get_delegate_spendable_balance(cycle - 1) + + get_delegate_third_party_delegated_balance(cycle - 1); + + let ratio = bigRat(num).divide(den); + + let third_party_rewards_from_delegating_stripped = + rewards_from_delegating_stripped.times(ratio).round(); + + storage_delegate_third_party_delegated_balance[cycle] = + storage_delegate_third_party_delegated_balance[cycle - 1] + + third_party_rewards_from_delegating_stripped; + }; + + const compute_delegate_own_staked_balance = (cycle) => { + let rewards_from_staking = get_estimated_rewards_for_staking(cycle - 1); + + let own_rewards_from_staking_edge = rewards_from_staking + .times(config.delegate_policy.edge_of_baking_over_staking) + .round(); + + let rewards_from_staking_stripped = rewards_from_staking.minus( + own_rewards_from_staking_edge, + ); + + let num = get_delegate_own_staked_balance(cycle - 1); + + let den = + get_delegate_own_staked_balance(cycle - 1) + + get_delegate_third_party_staked_balance(cycle - 1); + + let ratio = bigRat(num).divide(den); + + let own_rewards_from_staking_stripped = rewards_from_staking_stripped + .times(ratio) + .round(); + + storage_delegate_own_staked_balance[cycle] = + storage_delegate_own_staked_balance[cycle - 1] + + own_rewards_from_staking_stripped + + own_rewards_from_staking_edge; + }; + + const compute_delegate_third_party_staked_balance = (cycle) => { + let rewards_from_staking = get_estimated_rewards_for_staking(cycle - 1); + + let own_rewards_from_staking_edge = rewards_from_staking + .times(config.delegate_policy.edge_of_baking_over_staking) + .round(); + + let rewards_from_staking_stripped = rewards_from_staking.minus( + own_rewards_from_staking_edge, + ); + + let num = get_delegate_third_party_staked_balance(cycle - 1); + + let den = + get_delegate_own_staked_balance(cycle - 1) + + get_delegate_third_party_staked_balance(cycle - 1); + + let ratio = bigRat(num).divide(den); + + let third_party_rewards_from_staking_stripped = + rewards_from_staking_stripped.times(ratio).round(); + + storage_delegate_third_party_staked_balance[cycle] = + storage_delegate_third_party_staked_balance[cycle - 1] + + third_party_rewards_from_staking_stripped; + }; + + const storage_set_handler = (f, store, n, g) => { + f(n) == -1 ? g(n) : (store[n] = f(n)); + }; + + const compute_balances = (cycle) => { + if (cycle == 0) { + storage_set_handler( + config.chain.get_delegate_spendable_balance, + storage_delegate_spendable_balance, + 0, + (_) => 0, ); - let udist = staked_ratio.minus(ratio_target).abs().minus(ratio_radius); - let dist = staked_ratio.geq(ratio_target) ? udist.negate() : udist; - let days_per_cycle = bigRat(seconds_per_cycle).divide(86_400); - var new_bonus = previous_bonus.add( - dist.multiply(growth_rate).multiply(days_per_cycle), + storage_set_handler( + config.chain.get_delegate_third_party_delegated_balance, + storage_delegate_third_party_delegated_balance, + 0, + (_) => 0, ); - new_bonus = Math.max(new_bonus, bigRat.zero); - let max_new_bonus = Math.min( - base_reward_coeff_dist_to_max, - config.proto.max_bonus, + storage_set_handler( + config.chain.get_delegate_own_staked_balance, + storage_delegate_own_staked_balance, + 0, + (_) => 0, ); - new_bonus = Math.min(new_bonus, max_new_bonus); - return new_bonus; - // Issuance_bonus_repr.of_Q ~max_bonus new_bonus - }, - - compute_coeff: function ( - issuance_ratio_max, - issuance_ratio_min, - base_reward_coeff_ratio, - total_supply, - bonus, - ) { - let min_per_year = 525_600; - if (config.proto.base_total_issued_per_minute == 0) { - return 1; - } else { - let f1 = bigRat(base_reward_coeff_ratio).add(bonus); - let f2 = Math.clip(f1, issuance_ratio_min, issuance_ratio_max); - let f3 = bigRat(f2).divide(min_per_year); - let f4 = f3.multiply(total_supply); - let f5 = f4.divide(config.proto.base_total_issued_per_minute); - return f5; - } - }, - - compute_reward_coeff: function (current_cycle) { - let new_cycle = current_cycle + 1; - let for_cycle = new_cycle + config.proto.consensus_rights_delay; - let before_for_cycle = for_cycle - 1; - let total_supply = config.chain.get_total_supply(current_cycle); - let total_frozen_stake = config.chain.get_total_frozen_stake(for_cycle); - let staked_ratio = bigRat(total_frozen_stake).divide(total_supply); - storage_staked_ratio[new_cycle] = staked_ratio; - if (current_cycle < config.chain.ai_activation_cycle) { - return 1; - } else { - let previous_bonus = bigRat(storage_issuance_bonus[before_for_cycle]); - let seconds_per_cycle = - config.proto.blocks_per_cycle * config.proto.minimal_block_delay; - let issuance_ratio_min = minimum_ratio(new_cycle); - let issuance_ratio_max = maximal_ratio(new_cycle); - let base_reward_coeff_ratio = this.compute_static( - new_cycle, - staked_ratio, - issuance_ratio_min, - issuance_ratio_max, - ); - let bonus = this.compute_bonus( - issuance_ratio_max, - staked_ratio, - seconds_per_cycle, - base_reward_coeff_ratio, - previous_bonus, - ); - let coeff = this.compute_coeff( - issuance_ratio_max, - issuance_ratio_min, - base_reward_coeff_ratio, - total_supply, - bonus, - ); - storage_issuance_bonus[for_cycle] = bonus; - storage_issuance_coeff[for_cycle] = coeff; - } - }, + storage_set_handler( + config.chain.get_delegate_third_party_staked_balance, + storage_delegate_third_party_staked_balance, + 0, + (_) => 0, + ); + } else if (cycle > 0) { + storage_set_handler( + config.chain.get_delegate_spendable_balance, + storage_delegate_spendable_balance, + cycle, + compute_delegate_own_spendable_balance, + ); + storage_set_handler( + config.chain.get_delegate_third_party_delegated_balance, + storage_delegate_third_party_delegated_balance, + cycle, + compute_delegate_third_party_delegated_balance, + ); + storage_set_handler( + config.chain.get_delegate_own_staked_balance, + storage_delegate_own_staked_balance, + cycle, + compute_delegate_own_staked_balance, + ); + storage_set_handler( + config.chain.get_delegate_third_party_staked_balance, + storage_delegate_third_party_staked_balance, + cycle, + compute_delegate_third_party_staked_balance, + ); + } + }; + + for ( + let cycle = 0; + cycle < config.data.cycles - config.proto.consensus_rights_delay - 3; + cycle++ + ) { + compute_reward_coeff(cycle); + + compute_seed_nonce_revelation_tip(cycle); + compute_vdf_revelation_tip(cycle); + compute_attestation_reward_per_slot(cycle); + compute_baking_reward_fixed_portion(cycle); + compute_baking_reward_bonus_per_slot(cycle); + + compute_total_estimated_rewards(cycle); + + compute_balances(cycle); + compute_delegate_baking_power(cycle); + compute_current_yearly_rate_value(cycle); + compute_estimated_rewards_for_staking(cycle); + compute_estimated_rewards_for_delegating(cycle); + compute_estimated_rewards_from_fees(cycle); + } + + return { + is_ai_activated, + + in_initial_period, + + in_transition_period, + + in_after_period, + + get_coeff, + + get_staked_ratio, + + get_static_rate, + + get_bonus_rate, + + get_total_estimated_rewards, + + get_min_ratio, + + get_max_ratio, + + get_delegate_spendable_balance, + + get_delegate_third_party_delegated_balance, + + get_delegate_own_staked_balance, + + get_delegate_third_party_staked_balance, + + get_delegate_baking_power, + + get_rewards_ratio_for_delegating, + + get_rewards_ratio_for_staking, + + get_delegate_over_staked_balance, + + get_delegate_over_delegated_balance, + + get_delegate_considered_staked_balance, + + get_delegate_considered_delegated_balance, + + get_delegate_available_staked_balance, + + get_delegate_available_delegated_balance, + + get_delegate_rewards_baking_fee, + + get_current_yearly_rate_value, + + get_baking_reward_fixed_portion, + + get_baking_reward_bonus_per_slot, + + get_attestation_reward_per_slot, + + get_seed_nonce_revelation_tip, + + get_vdf_revelation_tip, + + get_estimated_rewards, + + get_estimated_rewards_for_staking, + + get_estimated_rewards_for_delegating, }; }; diff --git a/contrib/ai-simulator/src/source.js b/contrib/ai-simulator/src/source.js index c5589b1a16f5..dff4b69ee591 100644 --- a/contrib/ai-simulator/src/source.js +++ b/contrib/ai-simulator/src/source.js @@ -5,7 +5,10 @@ import { total_delegated_storage } from "./total_delegated_storage"; import bigInt from "big-integer"; // weeklynet configuration instance, next step is to generate it automatically. + const config = { + data: { cycles: 150 }, + proto: { attestation_rewards: 10_240, base_total_issued_per_minute: 80_007_812, @@ -20,12 +23,59 @@ const config = { minimal_block_delay: 7, nonce_revelation: 1, vdf_tip: 1, + max_limit_of_staking_over_baking: 5, }, chain: { ai_activation_cycle: 18, + + get_total_delegated: (c) => total_delegated_storage[c], + get_total_frozen_stake: (c) => total_frozen_stake_storage[c], + get_total_supply: (c) => total_supply_storage[c], + + get_delegate_spendable_balance: (c) => { + switch (c) { + case 0: + return 100_000_000_000; + default: + return -1; + } + }, + get_delegate_third_party_delegated_balance: (c) => { + switch (c) { + case 0: + return 300_000_000_000; + default: + return -1; + } + }, + + get_delegate_own_staked_balance: (c) => { + switch (c) { + case 0: + return 30_000_000_000; + default: + return -1; + } + }, + + get_delegate_third_party_staked_balance: (c) => { + switch (c) { + case 0: + return 90_500_000_000; + default: + return -1; + } + }, + }, + + // delegate policy + delegate_policy: { + fee: 0.07, // between 0 and 1 + edge_of_baking_over_staking: 0.15, // between 0 and 1 + limit_of_staking_over_baking: 2, // between 0 and 5 }, }; @@ -34,7 +84,7 @@ const simulator = require("./adaptive")(config); const tableBody = document.getElementById("report"); const decorate_row = (el, cycle) => { - if (cycle == config.ai_activation_cycle) { + if (cycle == config.chain.ai_activation_cycle) { el.classList.add("bg-green-600"); } else if (simulator.is_ai_activated(cycle)) { if (simulator.in_initial_period(cycle)) { @@ -65,11 +115,9 @@ const new_cell_for = (parent, content, rounded = true) => { for ( let cycle = 0; - cycle < total_supply_storage.length - config.proto.consensus_rights_delay - 3; + cycle < config.data.cycles - config.proto.consensus_rights_delay - 3; cycle++ ) { - simulator.compute_reward_coeff(cycle); - let new_row = document.createElement("tr"); new_row.classList.add("hover:bg-gray-200"); @@ -84,6 +132,7 @@ for ( new_cell(last_block); new_cell(config.chain.get_total_supply(cycle)); + new_cell(config.chain.get_total_delegated(cycle)); new_cell(config.chain.get_total_frozen_stake(cycle)); new_cell(simulator.get_staked_ratio(cycle)); @@ -94,12 +143,43 @@ for ( new_cell(simulator.get_bonus_rate(cycle)); new_cell(simulator.get_coeff(cycle)); + new_cell(simulator.get_current_yearly_rate_value(cycle)); + new_cell(simulator.get_attestation_reward_per_slot(cycle)); + new_cell(simulator.get_baking_reward_fixed_portion(cycle)); + new_cell(simulator.get_baking_reward_bonus_per_slot(cycle)); + new_cell(simulator.get_seed_nonce_revelation_tip(cycle)); + new_cell(simulator.get_vdf_revelation_tip(cycle)); + + // + + new_cell(config.delegate_policy.fee); + new_cell(config.delegate_policy.edge_of_baking_over_staking); + new_cell(config.delegate_policy.limit_of_staking_over_baking); + + // + + new_cell(simulator.get_delegate_own_staked_balance(cycle)); + new_cell(simulator.get_delegate_third_party_staked_balance(cycle)); + new_cell(simulator.get_delegate_considered_staked_balance(cycle)); + new_cell(simulator.get_delegate_over_staked_balance(cycle)); + new_cell(simulator.get_delegate_available_staked_balance(cycle)); + + new_cell(simulator.get_delegate_spendable_balance(cycle)); + new_cell(simulator.get_delegate_third_party_delegated_balance(cycle)); + new_cell(simulator.get_delegate_considered_delegated_balance(cycle)); + new_cell(simulator.get_delegate_over_delegated_balance(cycle)); + new_cell(simulator.get_delegate_available_delegated_balance(cycle)); + + new_cell(simulator.get_delegate_baking_power(cycle)); + + new_cell(simulator.get_total_estimated_rewards(cycle)); + + new_cell(simulator.get_rewards_ratio_for_staking(cycle)); + new_cell(simulator.get_estimated_rewards_for_staking(cycle)); - new_cell(simulator.attestation_reward_per_slot(cycle)); - new_cell(simulator.baking_reward_fixed_portion(cycle)); - new_cell(simulator.baking_reward_bonus_per_slot(cycle)); - new_cell(simulator.seed_nonce_revelation_tip(cycle)); - new_cell(simulator.vdf_revelation_tip(cycle)); + new_cell(simulator.get_rewards_ratio_for_delegating(cycle)); + new_cell(simulator.get_estimated_rewards_for_delegating(cycle)); + new_cell(simulator.get_delegate_rewards_baking_fee(cycle)); tableBody.appendChild(new_row); } diff --git a/contrib/ai-simulator/src/total_delegated_storage.js b/contrib/ai-simulator/src/total_delegated_storage.js new file mode 100644 index 000000000000..b598125b6f71 --- /dev/null +++ b/contrib/ai-simulator/src/total_delegated_storage.js @@ -0,0 +1,204 @@ +var total_delegated_storage = [ +6941078753766, +6942193286193, +6943308283620, +6944422657047, +6945535245472, +6841673553309, +6842867640224, +6844061727805, +6845255816718, +6846449904299, +6847643991880, +6848838079461, +6850032166376, +6851226254623, +6852420342870, +6853614431117, +6854808519364, +6856002604947, +6857196693194, +6858390780775, +6859584868356, +6860778955937, +6868913955061, +6877048946370, +8185183938476, +8243318945023, +9251453948883, +9259588960480, +9267723961675, +9275858966070, +9283993964591, +9292128966312, +9300394590727, +9308791132325, +10317318287872, +10325975171160, +10334762658997, +10343681049843, +10352730060179, +10361909695717, +10371219338102, +10380659595515, +10390230462746, +10399932254634, +10409764656651, +10419727679893, +10429820710387, +10440044373966, +10950398631217, +10960883826456, +11071499621278, +11082245130861, +11093121561303, +11102544573043, +11113096012263, +11123836492297, +11134704082553, +11146110229593, +11157672988881, +11169438633367, +11181334745386, +11193368006273, +11205477336288, +11217740557388, +11229585387910, +11241501530973, +11253544694027, +11265713790776, +11278005738164, +11290423245759, +11302970332895, +11315635827037, +11329120679947, +11342738625130, +11356487176414, +11370366372587, +11384376481967, +11398517229829, +11412787688899, +11427189061781, +11441721066171, +11456383694293, +11471177236785, +11485970781394, +11500764336371, +11515557918218, +11530351510698, +11545145113674, +11559938735525, +11574732351379, +11589525969606, +11604319614831, +11619113254178, +11633906895779, +11648700572757, +11663494260231, +11678287966580, +11693081675183, +11707875394410, +11722669132384, +11737462839727, +11752256598830, +11767050360306, +11781844439153, +11796638512122, +11811432595596, +11826226697945, +11841020819041, +11855814950761, +11870609092986, +11885403229333, +11900197367925, +11914991525392, +11929785676862, +11944580759700, +11959375853034, +11974170965244, +11988966087959, +12003761213046, +12018556348629, +12033351486584, +12048146659800, +12062941810632, +12077736988464, +12092532160425, +12107327351134, +12122122552467, +12136917789052, +12151713011514, +12166508252724, +12181303488054, +12196099049008, +12210894604091, +12225690210930, +12240485795385, +12255277350998, +12270072956582, +12284868572790, +12299664207746, +12314459845074, +12329255501159, +12344051151364, +12358846828569, +12373642516398, +12388438214732, +12403233915438, +12418029643144, +12432825356718, +12447621105553, +12462416848508, +12477208946614, +12492004702437, +12506800485269, +12521596278725, +12536392074425, +12551187880758, +12565983714091, +12580780448117, +12595577190309, +12610373971330, +12625171037834, +12639968112788, +12654765190907, +12669562287841, +12684359386167, +12699156513396, +12713953624589, +12828750772539, +12843547913965, +12858324862065, +12873122042039, +12887919214367, +12902716398113, +12917513608918, +12932310821115, +12947108037465, +12961905270791, +12976702490904, +12991499754454, +13006297027786, +13021094296881, +13035891566574, +13050688864319, +13065478514242, +13080275832194, +13095073145909, +13109870493243, +13124667835489, +13139465486912, +13154263164486, +13169060846213, +13183858536663, +13198656222153, +13213453926321, +13228251648524, +13243049391249, +13257847126319, +13272644881060, +13287442654616, +13302241325554, +13317040000635, +]; +export {total_delegated_storage}; -- GitLab From a168f45422d1ec75d610f3dcafe7b5da5f3e3732 Mon Sep 17 00:00:00 2001 From: phink Date: Wed, 6 Mar 2024 13:45:43 +0100 Subject: [PATCH 4/4] add estimated number of blocks/attestation and update reward computation --- contrib/ai-simulator/site/index.html | 20 +++-- contrib/ai-simulator/src/adaptive.js | 128 +++++++++++++++++++++------ contrib/ai-simulator/src/source.js | 11 ++- 3 files changed, 122 insertions(+), 37 deletions(-) diff --git a/contrib/ai-simulator/site/index.html b/contrib/ai-simulator/site/index.html index cebe24da8948..c2ed235000ea 100644 --- a/contrib/ai-simulator/site/index.html +++ b/contrib/ai-simulator/site/index.html @@ -35,7 +35,6 @@ Edge of baking over staking Limit of staking over baking - Delegate own staking balance Delegate third-party staked balance Delegate considered staked balance @@ -50,14 +49,23 @@ Delegate baking power + Estimated number of blocks + Estimated number of attestations + + Estimated rewards from fixed portion baking + Estimated rewards from bonus portion baking + Estimated rewards from nonce revelation + Estimated rewards from vdf revelation + Estimated total rewards - Rewards ratio for staking - Estimated rewards for staking + Rewards ratio for stakers + Estimated rewards for stakers + + Rewards ratio for delegators + Estimated rewards for delegators - Rewards ratio for delegating - Estimated rewards for delegating - Estimated fee rewards + Estimated rewards from delegate fees diff --git a/contrib/ai-simulator/src/adaptive.js b/contrib/ai-simulator/src/adaptive.js index cbc97291ab63..9ecd288e55b1 100644 --- a/contrib/ai-simulator/src/adaptive.js +++ b/contrib/ai-simulator/src/adaptive.js @@ -35,6 +35,13 @@ const storage_baking_reward_bonus_per_slot = Array(1000).fill(0); const storage_attestation_reward_per_slot = Array(1000).fill(0); const storage_seed_nonce_revelation_tip = Array(1000).fill(0); const storage_vdf_revelation_tip = Array(1000).fill(0); + +const storage_estimated_number_of_blocks_baked = Array(1000).fill(0); +const storage_estimated_number_of_attestations = Array(1000).fill(0); +const storage_estimated_rewards_for_fixed_portion_baking = Array(1000).fill(0); +const storage_estimated_rewards_for_baking_bonus = Array(1000).fill(0); +const storage_estimated_rewards_for_nonce_revelation = Array(1000).fill(0); +const storage_estimated_rewards_for_vdf_revelation = Array(1000).fill(0); const storage_estimated_rewards = Array(1000).fill(0); const storage_baking_power = Array(1000).fill(0); @@ -52,6 +59,7 @@ const storage_delegate_over_staked_balance = Array(1000).fill(0); const storage_delegate_over_delegated_balance = Array(1000).fill(0); const storage_delegate_available_staked_balance = Array(1000).fill(0); + const storage_delegate_available_delegated_balance = Array(1000).fill(0); const storage_delegate_rewards_baking_fee = Array(1000).fill(0); @@ -96,8 +104,6 @@ const get_rewards_ratio_for_delegating = (c) => const get_rewards_ratio_for_staking = (c) => storage_rewards_ratio_for_staking[c]; -const get_total_estimated_rewards = (c) => storage_estimated_rewards[c]; - const get_delegate_over_staked_balance = (c) => storage_delegate_over_staked_balance[c]; @@ -144,6 +150,24 @@ const get_estimated_rewards_for_staking = (c) => const get_estimated_rewards_for_delegating = (c) => storage_estimated_rewards_for_delegating[c]; +const get_estimated_number_of_blocks_baked = (c) => + storage_estimated_number_of_blocks_baked[c]; + +const get_estimated_number_of_attestations = (c) => + storage_estimated_number_of_attestations[c]; + +const get_estimated_rewards_for_fixed_portion_baking = (c) => + storage_estimated_rewards_for_fixed_portion_baking[c]; + +const get_estimated_rewards_for_baking_bonus = (c) => + storage_estimated_rewards_for_baking_bonus[c]; + +const get_estimated_rewards_for_nonce_revelation = (c) => + storage_estimated_rewards_for_nonce_revelation[c]; + +const get_estimated_rewards_for_vdf_revelation = (c) => + storage_estimated_rewards_for_vdf_revelation[c]; + // Export module.exports = (config) => { @@ -474,47 +498,83 @@ module.exports = (config) => { baking_power; }; - const compute_total_estimated_rewards = (cycle) => { - let coeff = get_coeff(cycle); + const compute_estimated_rewards = (cycle) => { + let estimated_number_of_blocks_baked = bigRat(config.proto.blocks_per_cycle) + .times(get_delegate_baking_power(cycle)) + .floor(); + + let estimated_rewards_for_fixed_portion_baking = + estimated_number_of_blocks_baked + .times(get_baking_reward_fixed_portion(cycle)) + .floor(); + + let bonus_committee_size = + config.proto.consensus_committee_size - config.proto.consensus_threshold; - let total_blocks = bigInt(get_baking_reward_fixed_portion(cycle)).times( + let estimated_rewards_for_baking_bonus = estimated_number_of_blocks_baked + .times(get_baking_reward_bonus_per_slot(cycle)) + .times(bonus_committee_size); + + let estimated_number_of_attestations = bigRat(config.proto.blocks_per_cycle) + .times(config.proto.consensus_committee_size) + .times(get_delegate_baking_power(cycle)) + .floor(); + + let estimated_rewards_for_attestations = + estimated_number_of_attestations.times( + get_attestation_reward_per_slot(cycle), + ); + + let estimated_rewards_for_nonce_revelation = + cycle == 0 + ? bigInt.zero + : get_estimated_number_of_blocks_baked(cycle - 1).times( + get_seed_nonce_revelation_tip(cycle), + ); + + let estimated_rewards_for_vdf_revelation = bigInt( config.proto.blocks_per_cycle, - ); + ) + .divide(config.proto.blocks_per_commitment) + .times(get_vdf_revelation_tip(cycle)); - let total_bonus = bigInt( - get_baking_reward_bonus_per_slot( - cycle, - config.proto.bonus_baking_rewards, - ), - ).times(config.proto.blocks_per_cycle); + let estimated_rewards = estimated_rewards_for_fixed_portion_baking + .add(estimated_rewards_for_baking_bonus) + .add(estimated_rewards_for_attestations) + .add(estimated_rewards_for_nonce_revelation) + .add(estimated_rewards_for_vdf_revelation); - let total_attestations = bigInt( - reward_from_constants(coeff, config.proto.attestation_rewards), - ).times(config.proto.blocks_per_cycle); + storage_estimated_number_of_blocks_baked[cycle] = + estimated_number_of_blocks_baked; - let total_rewards = total_blocks - .add(total_bonus) - .add(total_attestations) - .add(get_seed_nonce_revelation_tip(cycle)) - .add(get_vdf_revelation_tip(cycle)); + storage_estimated_number_of_attestations[cycle] = + estimated_number_of_attestations; - let res = bigRat(total_rewards) - .times(get_delegate_baking_power(cycle)) - .round(); + storage_estimated_rewards_for_fixed_portion_baking[cycle] = + estimated_rewards_for_fixed_portion_baking; + + storage_estimated_rewards_for_baking_bonus[cycle] = + estimated_rewards_for_baking_bonus; + + storage_estimated_rewards_for_nonce_revelation[cycle] = + estimated_rewards_for_nonce_revelation; - storage_estimated_rewards[cycle] = res; + storage_estimated_rewards_for_vdf_revelation[cycle] = + estimated_rewards_for_vdf_revelation; + + storage_estimated_rewards[cycle] = estimated_rewards; }; const compute_estimated_rewards_for_staking = (c) => { let res = bigRat(get_rewards_ratio_for_staking(c)) - .times(get_total_estimated_rewards(c)) + .times(get_estimated_rewards(c)) .round(); storage_estimated_rewards_for_staking[c] = res; }; const compute_estimated_rewards_for_delegating = (c) => { let res = bigRat(get_rewards_ratio_for_delegating(c)) - .times(get_total_estimated_rewards(c)) + .times(get_estimated_rewards(c)) .round(); storage_estimated_rewards_for_delegating[c] = res; }; @@ -705,7 +765,7 @@ module.exports = (config) => { compute_baking_reward_fixed_portion(cycle); compute_baking_reward_bonus_per_slot(cycle); - compute_total_estimated_rewards(cycle); + compute_estimated_rewards(cycle); compute_balances(cycle); compute_delegate_baking_power(cycle); @@ -732,8 +792,6 @@ module.exports = (config) => { get_bonus_rate, - get_total_estimated_rewards, - get_min_ratio, get_max_ratio, @@ -783,5 +841,17 @@ module.exports = (config) => { get_estimated_rewards_for_staking, get_estimated_rewards_for_delegating, + + get_estimated_number_of_blocks_baked, + + get_estimated_number_of_attestations, + + get_estimated_rewards_for_fixed_portion_baking, + + get_estimated_rewards_for_baking_bonus, + + get_estimated_rewards_for_nonce_revelation, + + get_estimated_rewards_for_vdf_revelation, }; }; diff --git a/contrib/ai-simulator/src/source.js b/contrib/ai-simulator/src/source.js index dff4b69ee591..5a924de12e5a 100644 --- a/contrib/ai-simulator/src/source.js +++ b/contrib/ai-simulator/src/source.js @@ -19,7 +19,7 @@ const config = { consensus_rights_delay: 3, consensus_threshold: 4667, fixed_baking_rewards: 5_120, - max_bonus: bigInt(50_000_000_000_000), + max_bonus: 50_000_000_000_000, minimal_block_delay: 7, nonce_revelation: 1, vdf_tip: 1, @@ -172,7 +172,14 @@ for ( new_cell(simulator.get_delegate_baking_power(cycle)); - new_cell(simulator.get_total_estimated_rewards(cycle)); + new_cell(simulator.get_estimated_number_of_blocks_baked(cycle)); + new_cell(simulator.get_estimated_number_of_attestations(cycle)); + + new_cell(simulator.get_estimated_rewards_for_fixed_portion_baking(cycle)); + new_cell(simulator.get_estimated_rewards_for_baking_bonus(cycle)); + new_cell(simulator.get_estimated_rewards_for_nonce_revelation(cycle)); + new_cell(simulator.get_estimated_rewards_for_vdf_revelation(cycle)); + new_cell(simulator.get_estimated_rewards(cycle)); new_cell(simulator.get_rewards_ratio_for_staking(cycle)); new_cell(simulator.get_estimated_rewards_for_staking(cycle)); -- GitLab