Merge branch 'master' into mononaut/standalone-visualizations
This commit is contained in:
		
						commit
						80ecf77270
					
				
							
								
								
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @ -9,7 +9,7 @@ jobs: | ||||
|     if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')" | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node: ["16", "17", "18", "20"] | ||||
|         node: ["18", "20"] | ||||
|         flavor: ["dev", "prod"] | ||||
|       fail-fast: false | ||||
|     runs-on: "ubuntu-latest" | ||||
| @ -67,7 +67,7 @@ jobs: | ||||
|     if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')" | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node: ["16", "17", "18", "20"] | ||||
|         node: ["18", "20"] | ||||
|         flavor: ["dev", "prod"] | ||||
|       fail-fast: false | ||||
|     runs-on: "ubuntu-latest" | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/cypress.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/cypress.yml
									
									
									
									
										vendored
									
									
								
							| @ -38,7 +38,7 @@ jobs: | ||||
|       - name: Setup node | ||||
|         uses: actions/setup-node@v3 | ||||
|         with: | ||||
|           node-version: 18 | ||||
|           node-version: 20 | ||||
|           cache: "npm" | ||||
|           cache-dependency-path: ${{ matrix.module }}/frontend/package-lock.json | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										19
									
								
								.github/workflows/get_backend_hash.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/get_backend_hash.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| name: 'Print backend hashes' | ||||
| 
 | ||||
| on: [workflow_dispatch] | ||||
| 
 | ||||
| jobs: | ||||
|   print-backend-sha: | ||||
|     runs-on: 'ubuntu-latest' | ||||
|     name: Print backend hashes | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           path: repo | ||||
| 
 | ||||
|       - name: Run script | ||||
|         working-directory: repo | ||||
|         run: | | ||||
|           chmod +x ./scripts/get_backend_hash.sh | ||||
|           sh ./scripts/get_backend_hash.sh | ||||
							
								
								
									
										8
									
								
								.github/workflows/on-tag.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/on-tag.yml
									
									
									
									
										vendored
									
									
								
							| @ -68,17 +68,17 @@ jobs: | ||||
|         run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin | ||||
| 
 | ||||
|       - name: Checkout project | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
| 
 | ||||
|       - name: Init repo for Dockerization | ||||
|         run: docker/init.sh "$TAG" | ||||
| 
 | ||||
|       - name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|         id: qemu | ||||
| 
 | ||||
|       - name: Setup Docker buildx action | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         id: buildx | ||||
| 
 | ||||
|       - name: Available platforms | ||||
| @ -98,7 +98,7 @@ jobs: | ||||
|           docker buildx build \ | ||||
|           --cache-from "type=local,src=/tmp/.buildx-cache" \ | ||||
|           --cache-to "type=local,dest=/tmp/.buildx-cache" \ | ||||
|           --platform linux/amd64,linux/arm64,linux/arm/v7 \ | ||||
|           --platform linux/amd64,linux/arm64 \ | ||||
|           --tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:$TAG \ | ||||
|           --tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:latest \ | ||||
|           --output "type=registry" ./${{ matrix.service }}/ \ | ||||
|  | ||||
							
								
								
									
										47
									
								
								GNUmakefile
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								GNUmakefile
									
									
									
									
									
								
							| @ -1,47 +0,0 @@ | ||||
| # If you see pwd_unknown showing up check permissions
 | ||||
| PWD ?= pwd_unknown | ||||
| 
 | ||||
| # DATABASE DEPLOY FOLDER CONFIG - default ./data
 | ||||
| ifeq ($(data),) | ||||
| DATA := data | ||||
| export DATA | ||||
| else | ||||
| DATA := $(data) | ||||
| export DATA | ||||
| endif | ||||
| 
 | ||||
| .PHONY: help | ||||
| help: | ||||
| 	@echo '' | ||||
| 	@echo '' | ||||
| 	@echo '	Usage: make [COMMAND]' | ||||
| 	@echo '' | ||||
| 	@echo '		make all		# build init mempool and electrs' | ||||
| 	@echo '		make init		# setup some useful configs' | ||||
| 	@echo '		make mempool		# build q dockerized mempool.space' | ||||
| 	@echo '		make electrs		# build a docker electrs image' | ||||
| 	@echo '' | ||||
| 
 | ||||
| .PHONY: init | ||||
| init: | ||||
| 	@echo '' | ||||
| 	mkdir -p   $(DATA) $(DATA)/mysql $(DATA)/mysql/data  | ||||
| 	#REF: https://github.com/mempool/mempool/blob/master/docker/README.md | ||||
| 	cat docker/docker-compose.yml > docker-compose.yml | ||||
| 	cat backend/mempool-config.sample.json > backend/mempool-config.json | ||||
| .PHONY: mempool | ||||
| mempool: init | ||||
| 	@echo '' | ||||
| 	docker-compose up --force-recreate --always-recreate-deps | ||||
| 	@echo '' | ||||
| .PHONY: electrs | ||||
| electrum: | ||||
| 	#REF: https://hub.docker.com/r/beli/electrum | ||||
| 	@echo '' | ||||
| 	docker build -f docker/electrum/Dockerfile . | ||||
| 	@echo '' | ||||
| .PHONY: all | ||||
| all: init | ||||
| 	make mempool | ||||
| #######################
 | ||||
| -include Makefile | ||||
| @ -23,6 +23,7 @@ Mempool can be conveniently installed on the following full-node distros: | ||||
| - [RoninDojo](https://code.samourai.io/ronindojo/RoninDojo) | ||||
| - [myNode](https://github.com/mynodebtc/mynode) | ||||
| - [Start9](https://github.com/Start9Labs/embassy-os) | ||||
| - [nix-bitcoin](https://github.com/fort-nix/nix-bitcoin/blob/a1eacce6768ca4894f365af8f79be5bbd594e1c3/examples/configuration.nix#L129) | ||||
| 
 | ||||
| **We highly recommend you deploy your own Mempool instance this way.** No matter which option you pick, you'll be able to get your own fully-sovereign instance of Mempool up quickly without needing to fiddle with any settings. | ||||
| 
 | ||||
|  | ||||
| @ -68,7 +68,8 @@ | ||||
|     "DATABASE": "mempool", | ||||
|     "USERNAME": "mempool", | ||||
|     "PASSWORD": "mempool", | ||||
|     "TIMEOUT": 180000 | ||||
|     "TIMEOUT": 180000, | ||||
|     "PID_DIR": "" | ||||
|   }, | ||||
|   "SYSLOG": { | ||||
|     "ENABLED": true, | ||||
|  | ||||
							
								
								
									
										586
									
								
								backend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										586
									
								
								backend/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -9,12 +9,12 @@ | ||||
|       "version": "3.0.0-dev", | ||||
|       "license": "GNU Affero General Public License v3.0", | ||||
|       "dependencies": { | ||||
|         "@babel/core": "^7.21.3", | ||||
|         "@babel/core": "^7.23.2", | ||||
|         "@mempool/electrum-client": "1.1.9", | ||||
|         "@types/node": "^18.15.3", | ||||
|         "axios": "~1.4.0", | ||||
|         "axios": "~1.5.0", | ||||
|         "bitcoinjs-lib": "~6.1.3", | ||||
|         "crypto-js": "~4.1.1", | ||||
|         "crypto-js": "~4.2.0", | ||||
|         "express": "~4.18.2", | ||||
|         "maxmind": "~4.3.11", | ||||
|         "mysql2": "~3.6.0", | ||||
| @ -26,7 +26,7 @@ | ||||
|       }, | ||||
|       "devDependencies": { | ||||
|         "@babel/code-frame": "^7.18.6", | ||||
|         "@babel/core": "^7.21.3", | ||||
|         "@babel/core": "^7.23.2", | ||||
|         "@types/compression": "^1.7.2", | ||||
|         "@types/crypto-js": "^4.1.1", | ||||
|         "@types/express": "^4.17.17", | ||||
| @ -65,47 +65,48 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/code-frame": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", | ||||
|       "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", | ||||
|       "version": "7.22.13", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", | ||||
|       "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/highlight": "^7.18.6" | ||||
|         "@babel/highlight": "^7.22.13", | ||||
|         "chalk": "^2.4.2" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/compat-data": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", | ||||
|       "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", | ||||
|       "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/core": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", | ||||
|       "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", | ||||
|       "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@ampproject/remapping": "^2.2.0", | ||||
|         "@babel/code-frame": "^7.21.4", | ||||
|         "@babel/generator": "^7.21.4", | ||||
|         "@babel/helper-compilation-targets": "^7.21.4", | ||||
|         "@babel/helper-module-transforms": "^7.21.2", | ||||
|         "@babel/helpers": "^7.21.0", | ||||
|         "@babel/parser": "^7.21.4", | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.4", | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "convert-source-map": "^1.7.0", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-compilation-targets": "^7.22.15", | ||||
|         "@babel/helper-module-transforms": "^7.23.0", | ||||
|         "@babel/helpers": "^7.23.2", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/traverse": "^7.23.2", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "convert-source-map": "^2.0.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "gensync": "^1.0.0-beta.2", | ||||
|         "json5": "^2.2.2", | ||||
|         "semver": "^6.3.0" | ||||
|         "json5": "^2.2.3", | ||||
|         "semver": "^6.3.1" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
| @ -115,13 +116,19 @@ | ||||
|         "url": "https://opencollective.com/babel" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/core/node_modules/convert-source-map": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", | ||||
|       "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/@babel/generator": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", | ||||
|       "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", | ||||
|       "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "@jridgewell/gen-mapping": "^0.3.2", | ||||
|         "@jridgewell/trace-mapping": "^0.3.17", | ||||
|         "jsesc": "^2.5.1" | ||||
| @ -145,87 +152,84 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-compilation-targets": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", | ||||
|       "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", | ||||
|       "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/compat-data": "^7.21.4", | ||||
|         "@babel/helper-validator-option": "^7.21.0", | ||||
|         "browserslist": "^4.21.3", | ||||
|         "@babel/compat-data": "^7.22.9", | ||||
|         "@babel/helper-validator-option": "^7.22.15", | ||||
|         "browserslist": "^4.21.9", | ||||
|         "lru-cache": "^5.1.1", | ||||
|         "semver": "^6.3.0" | ||||
|         "semver": "^6.3.1" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "@babel/core": "^7.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-environment-visitor": { | ||||
|       "version": "7.18.9", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", | ||||
|       "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", | ||||
|       "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-function-name": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", | ||||
|       "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", | ||||
|       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/types": "^7.21.0" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-hoist-variables": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", | ||||
|       "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", | ||||
|       "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.18.6" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-module-imports": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", | ||||
|       "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", | ||||
|       "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.21.4" | ||||
|         "@babel/types": "^7.22.15" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-module-transforms": { | ||||
|       "version": "7.21.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", | ||||
|       "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", | ||||
|       "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/helper-environment-visitor": "^7.18.9", | ||||
|         "@babel/helper-module-imports": "^7.18.6", | ||||
|         "@babel/helper-simple-access": "^7.20.2", | ||||
|         "@babel/helper-split-export-declaration": "^7.18.6", | ||||
|         "@babel/helper-validator-identifier": "^7.19.1", | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.2", | ||||
|         "@babel/types": "^7.21.2" | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-module-imports": "^7.22.15", | ||||
|         "@babel/helper-simple-access": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "@babel/core": "^7.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-plugin-utils": { | ||||
| @ -238,78 +242,78 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-simple-access": { | ||||
|       "version": "7.20.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", | ||||
|       "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", | ||||
|       "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.20.2" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-split-export-declaration": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", | ||||
|       "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", | ||||
|       "version": "7.22.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", | ||||
|       "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.18.6" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-string-parser": { | ||||
|       "version": "7.19.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", | ||||
|       "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", | ||||
|       "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-validator-identifier": { | ||||
|       "version": "7.19.1", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", | ||||
|       "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", | ||||
|       "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-validator-option": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", | ||||
|       "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", | ||||
|       "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", | ||||
|       "dev": true, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helpers": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", | ||||
|       "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", | ||||
|       "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.0", | ||||
|         "@babel/types": "^7.21.0" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/traverse": "^7.23.2", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/highlight": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", | ||||
|       "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", | ||||
|       "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/helper-validator-identifier": "^7.18.6", | ||||
|         "chalk": "^2.0.0", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "chalk": "^2.4.2", | ||||
|         "js-tokens": "^4.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -317,9 +321,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/parser": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", | ||||
|       "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", | ||||
|       "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", | ||||
|       "dev": true, | ||||
|       "bin": { | ||||
|         "parser": "bin/babel-parser.js" | ||||
| @ -506,33 +510,33 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/template": { | ||||
|       "version": "7.20.7", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", | ||||
|       "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", | ||||
|       "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/code-frame": "^7.18.6", | ||||
|         "@babel/parser": "^7.20.7", | ||||
|         "@babel/types": "^7.20.7" | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/parser": "^7.22.15", | ||||
|         "@babel/types": "^7.22.15" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/traverse": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", | ||||
|       "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", | ||||
|       "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/code-frame": "^7.21.4", | ||||
|         "@babel/generator": "^7.21.4", | ||||
|         "@babel/helper-environment-visitor": "^7.18.9", | ||||
|         "@babel/helper-function-name": "^7.21.0", | ||||
|         "@babel/helper-hoist-variables": "^7.18.6", | ||||
|         "@babel/helper-split-export-declaration": "^7.18.6", | ||||
|         "@babel/parser": "^7.21.4", | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-function-name": "^7.23.0", | ||||
|         "@babel/helper-hoist-variables": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "globals": "^11.1.0" | ||||
|       }, | ||||
| @ -541,13 +545,13 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/types": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", | ||||
|       "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", | ||||
|       "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", | ||||
|       "dev": true, | ||||
|       "dependencies": { | ||||
|         "@babel/helper-string-parser": "^7.19.4", | ||||
|         "@babel/helper-validator-identifier": "^7.19.1", | ||||
|         "@babel/helper-string-parser": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "to-fast-properties": "^2.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -2321,9 +2325,9 @@ | ||||
|       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" | ||||
|     }, | ||||
|     "node_modules/axios": { | ||||
|       "version": "1.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", | ||||
|       "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", | ||||
|       "version": "1.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", | ||||
|       "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", | ||||
|       "dependencies": { | ||||
|         "follow-redirects": "^1.15.0", | ||||
|         "form-data": "^4.0.0", | ||||
| @ -2590,9 +2594,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/browserslist": { | ||||
|       "version": "4.21.5", | ||||
|       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", | ||||
|       "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", | ||||
|       "version": "4.22.1", | ||||
|       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", | ||||
|       "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", | ||||
|       "dev": true, | ||||
|       "funding": [ | ||||
|         { | ||||
| @ -2602,13 +2606,17 @@ | ||||
|         { | ||||
|           "type": "tidelift", | ||||
|           "url": "https://tidelift.com/funding/github/npm/browserslist" | ||||
|         }, | ||||
|         { | ||||
|           "type": "github", | ||||
|           "url": "https://github.com/sponsors/ai" | ||||
|         } | ||||
|       ], | ||||
|       "dependencies": { | ||||
|         "caniuse-lite": "^1.0.30001449", | ||||
|         "electron-to-chromium": "^1.4.284", | ||||
|         "node-releases": "^2.0.8", | ||||
|         "update-browserslist-db": "^1.0.10" | ||||
|         "caniuse-lite": "^1.0.30001541", | ||||
|         "electron-to-chromium": "^1.4.535", | ||||
|         "node-releases": "^2.0.13", | ||||
|         "update-browserslist-db": "^1.0.13" | ||||
|       }, | ||||
|       "bin": { | ||||
|         "browserslist": "cli.js" | ||||
| @ -2700,9 +2708,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/caniuse-lite": { | ||||
|       "version": "1.0.30001473", | ||||
|       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz", | ||||
|       "integrity": "sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg==", | ||||
|       "version": "1.0.30001547", | ||||
|       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", | ||||
|       "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", | ||||
|       "dev": true, | ||||
|       "funding": [ | ||||
|         { | ||||
| @ -2892,9 +2900,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/crypto-js": { | ||||
|       "version": "4.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", | ||||
|       "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" | ||||
|       "version": "4.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", | ||||
|       "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" | ||||
|     }, | ||||
|     "node_modules/debug": { | ||||
|       "version": "4.3.4", | ||||
| @ -3023,9 +3031,9 @@ | ||||
|       "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" | ||||
|     }, | ||||
|     "node_modules/electron-to-chromium": { | ||||
|       "version": "1.4.348", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.348.tgz", | ||||
|       "integrity": "sha512-gM7TdwuG3amns/1rlgxMbeeyNoBFPa+4Uu0c7FeROWh4qWmvSOnvcslKmWy51ggLKZ2n/F/4i2HJ+PVNxH9uCQ==", | ||||
|       "version": "1.4.551", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", | ||||
|       "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/emittery": { | ||||
| @ -6184,9 +6192,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/node-releases": { | ||||
|       "version": "2.0.10", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", | ||||
|       "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", | ||||
|       "version": "2.0.13", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", | ||||
|       "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/normalize-path": { | ||||
| @ -7399,9 +7407,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/update-browserslist-db": { | ||||
|       "version": "1.0.10", | ||||
|       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", | ||||
|       "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", | ||||
|       "version": "1.0.13", | ||||
|       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", | ||||
|       "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", | ||||
|       "dev": true, | ||||
|       "funding": [ | ||||
|         { | ||||
| @ -7411,6 +7419,10 @@ | ||||
|         { | ||||
|           "type": "tidelift", | ||||
|           "url": "https://tidelift.com/funding/github/npm/browserslist" | ||||
|         }, | ||||
|         { | ||||
|           "type": "github", | ||||
|           "url": "https://github.com/sponsors/ai" | ||||
|         } | ||||
|       ], | ||||
|       "dependencies": { | ||||
| @ -7418,7 +7430,7 @@ | ||||
|         "picocolors": "^1.0.0" | ||||
|       }, | ||||
|       "bin": { | ||||
|         "browserslist-lint": "cli.js" | ||||
|         "update-browserslist-db": "cli.js" | ||||
|       }, | ||||
|       "peerDependencies": { | ||||
|         "browserslist": ">= 4.21.0" | ||||
| @ -7683,50 +7695,59 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/code-frame": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", | ||||
|       "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", | ||||
|       "version": "7.22.13", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", | ||||
|       "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/highlight": "^7.18.6" | ||||
|         "@babel/highlight": "^7.22.13", | ||||
|         "chalk": "^2.4.2" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/compat-data": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", | ||||
|       "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", | ||||
|       "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/core": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", | ||||
|       "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", | ||||
|       "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@ampproject/remapping": "^2.2.0", | ||||
|         "@babel/code-frame": "^7.21.4", | ||||
|         "@babel/generator": "^7.21.4", | ||||
|         "@babel/helper-compilation-targets": "^7.21.4", | ||||
|         "@babel/helper-module-transforms": "^7.21.2", | ||||
|         "@babel/helpers": "^7.21.0", | ||||
|         "@babel/parser": "^7.21.4", | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.4", | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "convert-source-map": "^1.7.0", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-compilation-targets": "^7.22.15", | ||||
|         "@babel/helper-module-transforms": "^7.23.0", | ||||
|         "@babel/helpers": "^7.23.2", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/traverse": "^7.23.2", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "convert-source-map": "^2.0.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "gensync": "^1.0.0-beta.2", | ||||
|         "json5": "^2.2.2", | ||||
|         "semver": "^6.3.0" | ||||
|         "json5": "^2.2.3", | ||||
|         "semver": "^6.3.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "convert-source-map": { | ||||
|           "version": "2.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", | ||||
|           "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", | ||||
|           "dev": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@babel/generator": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", | ||||
|       "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", | ||||
|       "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "@jridgewell/gen-mapping": "^0.3.2", | ||||
|         "@jridgewell/trace-mapping": "^0.3.17", | ||||
|         "jsesc": "^2.5.1" | ||||
| @ -7746,66 +7767,63 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-compilation-targets": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", | ||||
|       "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", | ||||
|       "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/compat-data": "^7.21.4", | ||||
|         "@babel/helper-validator-option": "^7.21.0", | ||||
|         "browserslist": "^4.21.3", | ||||
|         "@babel/compat-data": "^7.22.9", | ||||
|         "@babel/helper-validator-option": "^7.22.15", | ||||
|         "browserslist": "^4.21.9", | ||||
|         "lru-cache": "^5.1.1", | ||||
|         "semver": "^6.3.0" | ||||
|         "semver": "^6.3.1" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-environment-visitor": { | ||||
|       "version": "7.18.9", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", | ||||
|       "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", | ||||
|       "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/helper-function-name": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", | ||||
|       "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", | ||||
|       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/types": "^7.21.0" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-hoist-variables": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", | ||||
|       "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", | ||||
|       "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/types": "^7.18.6" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-module-imports": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", | ||||
|       "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", | ||||
|       "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/types": "^7.21.4" | ||||
|         "@babel/types": "^7.22.15" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-module-transforms": { | ||||
|       "version": "7.21.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", | ||||
|       "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", | ||||
|       "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/helper-environment-visitor": "^7.18.9", | ||||
|         "@babel/helper-module-imports": "^7.18.6", | ||||
|         "@babel/helper-simple-access": "^7.20.2", | ||||
|         "@babel/helper-split-export-declaration": "^7.18.6", | ||||
|         "@babel/helper-validator-identifier": "^7.19.1", | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.2", | ||||
|         "@babel/types": "^7.21.2" | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-module-imports": "^7.22.15", | ||||
|         "@babel/helper-simple-access": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-plugin-utils": { | ||||
| @ -7815,67 +7833,67 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/helper-simple-access": { | ||||
|       "version": "7.20.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", | ||||
|       "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", | ||||
|       "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/types": "^7.20.2" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-split-export-declaration": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", | ||||
|       "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", | ||||
|       "version": "7.22.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", | ||||
|       "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/types": "^7.18.6" | ||||
|         "@babel/types": "^7.22.5" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-string-parser": { | ||||
|       "version": "7.19.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", | ||||
|       "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", | ||||
|       "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/helper-validator-identifier": { | ||||
|       "version": "7.19.1", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", | ||||
|       "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", | ||||
|       "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/helper-validator-option": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", | ||||
|       "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", | ||||
|       "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/helpers": { | ||||
|       "version": "7.21.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", | ||||
|       "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", | ||||
|       "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/template": "^7.20.7", | ||||
|         "@babel/traverse": "^7.21.0", | ||||
|         "@babel/types": "^7.21.0" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/traverse": "^7.23.2", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/highlight": { | ||||
|       "version": "7.18.6", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", | ||||
|       "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", | ||||
|       "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/helper-validator-identifier": "^7.18.6", | ||||
|         "chalk": "^2.0.0", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "chalk": "^2.4.2", | ||||
|         "js-tokens": "^4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/parser": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", | ||||
|       "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", | ||||
|       "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@babel/plugin-syntax-async-generators": { | ||||
| @ -8005,42 +8023,42 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/template": { | ||||
|       "version": "7.20.7", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", | ||||
|       "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", | ||||
|       "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/code-frame": "^7.18.6", | ||||
|         "@babel/parser": "^7.20.7", | ||||
|         "@babel/types": "^7.20.7" | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/parser": "^7.22.15", | ||||
|         "@babel/types": "^7.22.15" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/traverse": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", | ||||
|       "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", | ||||
|       "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/code-frame": "^7.21.4", | ||||
|         "@babel/generator": "^7.21.4", | ||||
|         "@babel/helper-environment-visitor": "^7.18.9", | ||||
|         "@babel/helper-function-name": "^7.21.0", | ||||
|         "@babel/helper-hoist-variables": "^7.18.6", | ||||
|         "@babel/helper-split-export-declaration": "^7.18.6", | ||||
|         "@babel/parser": "^7.21.4", | ||||
|         "@babel/types": "^7.21.4", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-function-name": "^7.23.0", | ||||
|         "@babel/helper-hoist-variables": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "globals": "^11.1.0" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/types": { | ||||
|       "version": "7.21.4", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", | ||||
|       "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", | ||||
|       "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@babel/helper-string-parser": "^7.19.4", | ||||
|         "@babel/helper-validator-identifier": "^7.19.1", | ||||
|         "@babel/helper-string-parser": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "to-fast-properties": "^2.0.0" | ||||
|       } | ||||
|     }, | ||||
| @ -9397,9 +9415,9 @@ | ||||
|       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" | ||||
|     }, | ||||
|     "axios": { | ||||
|       "version": "1.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", | ||||
|       "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", | ||||
|       "version": "1.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", | ||||
|       "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", | ||||
|       "requires": { | ||||
|         "follow-redirects": "^1.15.0", | ||||
|         "form-data": "^4.0.0", | ||||
| @ -9615,15 +9633,15 @@ | ||||
|       } | ||||
|     }, | ||||
|     "browserslist": { | ||||
|       "version": "4.21.5", | ||||
|       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", | ||||
|       "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", | ||||
|       "version": "4.22.1", | ||||
|       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", | ||||
|       "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "caniuse-lite": "^1.0.30001449", | ||||
|         "electron-to-chromium": "^1.4.284", | ||||
|         "node-releases": "^2.0.8", | ||||
|         "update-browserslist-db": "^1.0.10" | ||||
|         "caniuse-lite": "^1.0.30001541", | ||||
|         "electron-to-chromium": "^1.4.535", | ||||
|         "node-releases": "^2.0.13", | ||||
|         "update-browserslist-db": "^1.0.13" | ||||
|       } | ||||
|     }, | ||||
|     "bs-logger": { | ||||
| @ -9694,9 +9712,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "caniuse-lite": { | ||||
|       "version": "1.0.30001473", | ||||
|       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz", | ||||
|       "integrity": "sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg==", | ||||
|       "version": "1.0.30001547", | ||||
|       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", | ||||
|       "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "chalk": { | ||||
| @ -9832,9 +9850,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "crypto-js": { | ||||
|       "version": "4.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", | ||||
|       "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" | ||||
|       "version": "4.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", | ||||
|       "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" | ||||
|     }, | ||||
|     "debug": { | ||||
|       "version": "4.3.4", | ||||
| @ -9924,9 +9942,9 @@ | ||||
|       "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" | ||||
|     }, | ||||
|     "electron-to-chromium": { | ||||
|       "version": "1.4.348", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.348.tgz", | ||||
|       "integrity": "sha512-gM7TdwuG3amns/1rlgxMbeeyNoBFPa+4Uu0c7FeROWh4qWmvSOnvcslKmWy51ggLKZ2n/F/4i2HJ+PVNxH9uCQ==", | ||||
|       "version": "1.4.551", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", | ||||
|       "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "emittery": { | ||||
| @ -12280,9 +12298,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node-releases": { | ||||
|       "version": "2.0.10", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", | ||||
|       "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", | ||||
|       "version": "2.0.13", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", | ||||
|       "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "normalize-path": { | ||||
| @ -13118,9 +13136,9 @@ | ||||
|       "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" | ||||
|     }, | ||||
|     "update-browserslist-db": { | ||||
|       "version": "1.0.10", | ||||
|       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", | ||||
|       "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", | ||||
|       "version": "1.0.13", | ||||
|       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", | ||||
|       "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "escalade": "^3.1.1", | ||||
|  | ||||
| @ -38,12 +38,12 @@ | ||||
|     "rust-build": "cd rust-gbt && npm run build-release" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@babel/core": "^7.21.3", | ||||
|     "@babel/core": "^7.23.2", | ||||
|     "@mempool/electrum-client": "1.1.9", | ||||
|     "@types/node": "^18.15.3", | ||||
|     "axios": "~1.4.0", | ||||
|     "axios": "~1.5.0", | ||||
|     "bitcoinjs-lib": "~6.1.3", | ||||
|     "crypto-js": "~4.1.1", | ||||
|     "crypto-js": "~4.2.0", | ||||
|     "express": "~4.18.2", | ||||
|     "maxmind": "~4.3.11", | ||||
|     "mysql2": "~3.6.0", | ||||
| @ -55,7 +55,7 @@ | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@babel/code-frame": "^7.18.6", | ||||
|     "@babel/core": "^7.21.3", | ||||
|     "@babel/core": "^7.23.2", | ||||
|     "@types/compression": "^1.7.2", | ||||
|     "@types/crypto-js": "^4.1.1", | ||||
|     "@types/express": "^4.17.17", | ||||
|  | ||||
| @ -69,6 +69,7 @@ | ||||
|     "DATABASE": "__DATABASE_DATABASE__", | ||||
|     "USERNAME": "__DATABASE_USERNAME__", | ||||
|     "PASSWORD": "__DATABASE_PASSWORD__", | ||||
|     "PID_DIR": "__DATABASE_PID_FILE__", | ||||
|     "TIMEOUT": 3000 | ||||
|   }, | ||||
|   "SYSLOG": { | ||||
|  | ||||
| @ -84,6 +84,7 @@ describe('Mempool Backend Config', () => { | ||||
|         USERNAME: 'mempool', | ||||
|         PASSWORD: 'mempool', | ||||
|         TIMEOUT: 180000, | ||||
|         PID_DIR: '' | ||||
|       }); | ||||
| 
 | ||||
|       expect(config.SYSLOG).toStrictEqual({ | ||||
|  | ||||
| @ -478,7 +478,7 @@ class BitcoinRoutes { | ||||
|       } | ||||
| 
 | ||||
|       let nextHash = startFromHash; | ||||
|       for (let i = 0; i < 10 && nextHash; i++) { | ||||
|       for (let i = 0; i < 15 && nextHash; i++) { | ||||
|         const localBlock = blocks.getBlocks().find((b) => b.id === nextHash); | ||||
|         if (localBlock) { | ||||
|           returnBlocks.push(localBlock); | ||||
|  | ||||
| @ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository'; | ||||
| import { RowDataPacket } from 'mysql2'; | ||||
| 
 | ||||
| class DatabaseMigration { | ||||
|   private static currentVersion = 65; | ||||
|   private static currentVersion = 66; | ||||
|   private queryTimeout = 3600_000; | ||||
|   private statisticsAddedIndexed = false; | ||||
|   private uniqueLogs: string[] = []; | ||||
| @ -553,6 +553,11 @@ class DatabaseMigration { | ||||
|       await this.$executeQuery('ALTER TABLE `blocks_audits` ADD accelerated_txs JSON DEFAULT "[]"'); | ||||
|       await this.updateToSchemaVersion(65); | ||||
|     } | ||||
| 
 | ||||
|     if (databaseSchemaVersion < 66) { | ||||
|       await this.$executeQuery('ALTER TABLE `statistics` ADD min_fee FLOAT UNSIGNED DEFAULT NULL'); | ||||
|       await this.updateToSchemaVersion(66); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  | ||||
| @ -3,21 +3,30 @@ import { Common } from './common'; | ||||
| import mempool from './mempool'; | ||||
| import projectedBlocks from './mempool-blocks'; | ||||
| 
 | ||||
| interface RecommendedFees { | ||||
|   fastestFee: number, | ||||
|   halfHourFee: number, | ||||
|   hourFee: number, | ||||
|   economyFee: number, | ||||
|   minimumFee: number, | ||||
| } | ||||
| 
 | ||||
| class FeeApi { | ||||
|   constructor() { } | ||||
| 
 | ||||
|   defaultFee = Common.isLiquid() ? 0.1 : 1; | ||||
| 
 | ||||
|   public getRecommendedFee() { | ||||
|   public getRecommendedFee(): RecommendedFees { | ||||
|     const pBlocks = projectedBlocks.getMempoolBlocks(); | ||||
|     const mPool = mempool.getMempoolInfo(); | ||||
|     const minimumFee = Math.ceil(mPool.mempoolminfee * 100000); | ||||
|     const defaultMinFee = Math.max(minimumFee, this.defaultFee); | ||||
| 
 | ||||
|     if (!pBlocks.length) { | ||||
|       return { | ||||
|         'fastestFee': this.defaultFee, | ||||
|         'halfHourFee': this.defaultFee, | ||||
|         'hourFee': this.defaultFee, | ||||
|         'fastestFee': defaultMinFee, | ||||
|         'halfHourFee': defaultMinFee, | ||||
|         'hourFee': defaultMinFee, | ||||
|         'economyFee': minimumFee, | ||||
|         'minimumFee': minimumFee, | ||||
|       }; | ||||
| @ -27,11 +36,15 @@ class FeeApi { | ||||
|     const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee) : this.defaultFee; | ||||
|     const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee) : this.defaultFee; | ||||
| 
 | ||||
|     // explicitly enforce a minimum of ceil(mempoolminfee) on all recommendations.
 | ||||
|     // simply rounding up recommended rates is insufficient, as the purging rate
 | ||||
|     // can exceed the median rate of projected blocks in some extreme scenarios
 | ||||
|     // (see https://bitcoin.stackexchange.com/a/120024)
 | ||||
|     return { | ||||
|       'fastestFee': firstMedianFee, | ||||
|       'halfHourFee': secondMedianFee, | ||||
|       'hourFee': thirdMedianFee, | ||||
|       'economyFee': Math.min(2 * minimumFee, thirdMedianFee), | ||||
|       'fastestFee': Math.max(minimumFee, firstMedianFee), | ||||
|       'halfHourFee': Math.max(minimumFee, secondMedianFee), | ||||
|       'hourFee': Math.max(minimumFee, thirdMedianFee), | ||||
|       'economyFee': Math.max(minimumFee, Math.min(2 * minimumFee, thirdMedianFee)), | ||||
|       'minimumFee': minimumFee, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
| @ -31,7 +31,7 @@ class MemoryCache { | ||||
|   } | ||||
| 
 | ||||
|   private cleanup() { | ||||
|     this.cache = this.cache.filter((cache) => cache.expires < (new Date())); | ||||
|     this.cache = this.cache.filter((cache) => cache.expires > (new Date())); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -15,6 +15,7 @@ class StatisticsApi { | ||||
|               mempool_byte_weight, | ||||
|               fee_data, | ||||
|               total_fee, | ||||
|               min_fee, | ||||
|               vsize_1, | ||||
|               vsize_2, | ||||
|               vsize_3, | ||||
| @ -54,7 +55,7 @@ class StatisticsApi { | ||||
|               vsize_1800, | ||||
|               vsize_2000 | ||||
|             ) | ||||
|             VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|             VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
|                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)`;
 | ||||
|       const [result]: any = await DB.query(query); | ||||
|       return result.insertId; | ||||
| @ -73,6 +74,7 @@ class StatisticsApi { | ||||
|               mempool_byte_weight, | ||||
|               fee_data, | ||||
|               total_fee, | ||||
|               min_fee, | ||||
|               vsize_1, | ||||
|               vsize_2, | ||||
|               vsize_3, | ||||
| @ -112,7 +114,7 @@ class StatisticsApi { | ||||
|               vsize_1800, | ||||
|               vsize_2000 | ||||
|             ) | ||||
|             VALUES (${statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, | ||||
|             VALUES (${statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, | ||||
|                ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
 | ||||
| 
 | ||||
|       const params: (string | number)[] = [ | ||||
| @ -122,6 +124,7 @@ class StatisticsApi { | ||||
|         statistics.mempool_byte_weight, | ||||
|         statistics.fee_data, | ||||
|         statistics.total_fee, | ||||
|         statistics.min_fee, | ||||
|         statistics.vsize_1, | ||||
|         statistics.vsize_2, | ||||
|         statistics.vsize_3, | ||||
| @ -173,6 +176,7 @@ class StatisticsApi { | ||||
|       UNIX_TIMESTAMP(added) as added, | ||||
|       CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions, | ||||
|       CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second, | ||||
|       CAST(avg(min_fee) as DOUBLE) as min_fee, | ||||
|       CAST(avg(vsize_1) as DOUBLE) as vsize_1, | ||||
|       CAST(avg(vsize_2) as DOUBLE) as vsize_2, | ||||
|       CAST(avg(vsize_3) as DOUBLE) as vsize_3, | ||||
| @ -222,6 +226,7 @@ class StatisticsApi { | ||||
|       UNIX_TIMESTAMP(added) as added, | ||||
|       CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions, | ||||
|       CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second, | ||||
|       CAST(avg(min_fee) as DOUBLE) as min_fee, | ||||
|       vsize_1, | ||||
|       vsize_2, | ||||
|       vsize_3, | ||||
| @ -407,6 +412,7 @@ class StatisticsApi { | ||||
|         vbytes_per_second: s.vbytes_per_second, | ||||
|         mempool_byte_weight: s.mempool_byte_weight, | ||||
|         total_fee: s.total_fee, | ||||
|         min_fee: s.min_fee, | ||||
|         vsizes: [ | ||||
|           s.vsize_1, | ||||
|           s.vsize_2, | ||||
|  | ||||
| @ -89,6 +89,9 @@ class Statistics { | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     // get minFee and convert to sats/vb
 | ||||
|     const minFee = memPool.getMempoolInfo().mempoolminfee * 100000; | ||||
| 
 | ||||
|     try { | ||||
|       const insertId = await statisticsApi.$create({ | ||||
|         added: 'NOW()', | ||||
| @ -98,6 +101,7 @@ class Statistics { | ||||
|         mempool_byte_weight: totalWeight, | ||||
|         total_fee: totalFee, | ||||
|         fee_data: '', | ||||
|         min_fee: minFee, | ||||
|         vsize_1: weightVsizeFees['1'] || 0, | ||||
|         vsize_2: weightVsizeFees['2'] || 0, | ||||
|         vsize_3: weightVsizeFees['3'] || 0, | ||||
|  | ||||
| @ -93,6 +93,7 @@ interface IConfig { | ||||
|     USERNAME: string; | ||||
|     PASSWORD: string; | ||||
|     TIMEOUT: number; | ||||
|     PID_DIR: string; | ||||
|   }; | ||||
|   SYSLOG: { | ||||
|     ENABLED: boolean; | ||||
| @ -219,6 +220,7 @@ const defaults: IConfig = { | ||||
|     'USERNAME': 'mempool', | ||||
|     'PASSWORD': 'mempool', | ||||
|     'TIMEOUT': 180000, | ||||
|     'PID_DIR': '', | ||||
|   }, | ||||
|   'SYSLOG': { | ||||
|     'ENABLED': true, | ||||
|  | ||||
| @ -1,3 +1,5 @@ | ||||
| import * as fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import config from './config'; | ||||
| import { createPool, Pool, PoolConnection } from 'mysql2/promise'; | ||||
| import logger from './logger'; | ||||
| @ -101,6 +103,33 @@ import { FieldPacket, OkPacket, PoolOptions, ResultSetHeader, RowDataPacket } fr | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public getPidLock(): boolean { | ||||
|     const filePath = path.join(config.DATABASE.PID_DIR || __dirname, `/mempool-${config.DATABASE.DATABASE}.pid`); | ||||
|     if (fs.existsSync(filePath)) { | ||||
|       const pid = fs.readFileSync(filePath).toString(); | ||||
|       if (pid !== `${process.pid}`) { | ||||
|         const msg = `Already running on PID ${pid} (or pid file '${filePath}' is stale)`; | ||||
|         logger.err(msg); | ||||
|         throw new Error(msg); | ||||
|       } else { | ||||
|         return true; | ||||
|       } | ||||
|     } else { | ||||
|       fs.writeFileSync(filePath, `${process.pid}`); | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public releasePidLock(): void { | ||||
|     const filePath = path.join(config.DATABASE.PID_DIR || __dirname, `/mempool-${config.DATABASE.DATABASE}.pid`); | ||||
|     if (fs.existsSync(filePath)) { | ||||
|       const pid = fs.readFileSync(filePath).toString(); | ||||
|       if (pid === `${process.pid}`) { | ||||
|         fs.unlinkSync(filePath); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   private async getPool(): Promise<Pool> { | ||||
|     if (this.pool === null) { | ||||
|       this.pool = createPool(this.poolConfig); | ||||
|  | ||||
| @ -91,11 +91,18 @@ class Server { | ||||
|   async startServer(worker = false): Promise<void> { | ||||
|     logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`); | ||||
| 
 | ||||
|     // Register cleanup listeners for exit events
 | ||||
|     ['exit', 'SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'unhandledRejection'].forEach(event => { | ||||
|       process.on(event, () => { this.onExit(event); }); | ||||
|     }); | ||||
| 
 | ||||
|     if (config.MEMPOOL.BACKEND === 'esplora') { | ||||
|       bitcoinApi.startHealthChecks(); | ||||
|     } | ||||
| 
 | ||||
|     if (config.DATABASE.ENABLED) { | ||||
|       DB.getPidLock(); | ||||
| 
 | ||||
|       await DB.checkDbConnection(); | ||||
|       try { | ||||
|         if (process.env.npm_config_reindex_blocks === 'true') { // Re-index requests
 | ||||
| @ -306,6 +313,15 @@ class Server { | ||||
|       this.lastHeapLogTime = now; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   onExit(exitEvent): void { | ||||
|     if (config.DATABASE.ENABLED) { | ||||
|       DB.releasePidLock(); | ||||
|     } | ||||
|     process.exit(0); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ((): Server => new Server())(); | ||||
|  | ||||
| @ -300,6 +300,7 @@ export interface Statistic { | ||||
|   total_fee: number; | ||||
|   mempool_byte_weight: number; | ||||
|   fee_data: string; | ||||
|   min_fee: number; | ||||
| 
 | ||||
|   vsize_1: number; | ||||
|   vsize_2: number; | ||||
| @ -346,6 +347,7 @@ export interface OptimizedStatistic { | ||||
|   vbytes_per_second: number; | ||||
|   total_fee: number; | ||||
|   mempool_byte_weight: number; | ||||
|   min_fee: number; | ||||
|   vsizes: number[]; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										3
									
								
								contributors/TKone7.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								contributors/TKone7.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of October 23, 2023. | ||||
| 
 | ||||
| Signed: TKone7 | ||||
							
								
								
									
										3
									
								
								contributors/fanquake.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								contributors/fanquake.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of October 23, 2023. | ||||
| 
 | ||||
| Signed: fanquake | ||||
							
								
								
									
										3
									
								
								contributors/fubz.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								contributors/fubz.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of January 25, 2022. | ||||
| 
 | ||||
| Signed: fubz | ||||
| @ -1,4 +1,4 @@ | ||||
| FROM node:16.16.0-buster-slim AS builder | ||||
| FROM node:20.8.0-buster-slim AS builder | ||||
| 
 | ||||
| ARG commitHash | ||||
| ENV MEMPOOL_COMMIT_HASH=${commitHash} | ||||
| @ -17,7 +17,7 @@ ENV PATH="/root/.cargo/bin:$PATH" | ||||
| RUN npm install --omit=dev --omit=optional | ||||
| RUN npm run package | ||||
| 
 | ||||
| FROM node:16.16.0-buster-slim | ||||
| FROM node:20.8.0-buster-slim | ||||
| 
 | ||||
| WORKDIR /backend | ||||
| 
 | ||||
|  | ||||
| @ -69,7 +69,8 @@ | ||||
|     "DATABASE": "__DATABASE_DATABASE__", | ||||
|     "USERNAME": "__DATABASE_USERNAME__", | ||||
|     "PASSWORD": "__DATABASE_PASSWORD__", | ||||
|     "TIMEOUT": __DATABASE_TIMEOUT__ | ||||
|     "TIMEOUT": __DATABASE_TIMEOUT__, | ||||
|     "PID_DIR": "__DATABASE_PID_DIR__" | ||||
|   }, | ||||
|   "SYSLOG": { | ||||
|     "ENABLED": __SYSLOG_ENABLED__, | ||||
|  | ||||
| @ -71,6 +71,7 @@ __DATABASE_DATABASE__=${DATABASE_DATABASE:=mempool} | ||||
| __DATABASE_USERNAME__=${DATABASE_USERNAME:=mempool} | ||||
| __DATABASE_PASSWORD__=${DATABASE_PASSWORD:=mempool} | ||||
| __DATABASE_TIMEOUT__=${DATABASE_TIMEOUT:=180000} | ||||
| __DATABASE_PID_DIR__=${DATABASE_PID_DIR:=""} | ||||
| 
 | ||||
| # SYSLOG | ||||
| __SYSLOG_ENABLED__=${SYSLOG_ENABLED:=false} | ||||
| @ -139,7 +140,7 @@ __MEMPOOL_SERVICES_API__=${MEMPOOL_SERVICES_API:=""} | ||||
| __MEMPOOL_SERVICES_ACCELERATIONS__=${MEMPOOL_SERVICES_ACCELERATIONS:=false} | ||||
| 
 | ||||
| # REDIS | ||||
| __REDIS_ENABLED__=${REDIS_ENABLED:=true} | ||||
| __REDIS_ENABLED__=${REDIS_ENABLED:=false} | ||||
| __REDIS_UNIX_SOCKET_PATH__=${REDIS_UNIX_SOCKET_PATH:=true} | ||||
| 
 | ||||
| mkdir -p "${__MEMPOOL_CACHE_DIR__}" | ||||
| @ -209,6 +210,7 @@ sed -i "s!__DATABASE_DATABASE__!${__DATABASE_DATABASE__}!g" mempool-config.json | ||||
| sed -i "s!__DATABASE_USERNAME__!${__DATABASE_USERNAME__}!g" mempool-config.json | ||||
| sed -i "s!__DATABASE_PASSWORD__!${__DATABASE_PASSWORD__}!g" mempool-config.json | ||||
| sed -i "s!__DATABASE_TIMEOUT__!${__DATABASE_TIMEOUT__}!g" mempool-config.json | ||||
| sed -i "s!__DATABASE_PID_DIR__!${__DATABASE_PID_DIR__}!g" mempool-config.json | ||||
| 
 | ||||
| sed -i "s!__SYSLOG_ENABLED__!${__SYSLOG_ENABLED__}!g" mempool-config.json | ||||
| sed -i "s!__SYSLOG_HOST__!${__SYSLOG_HOST__}!g" mempool-config.json | ||||
|  | ||||
| @ -38,7 +38,7 @@ services: | ||||
|       MYSQL_USER: "mempool" | ||||
|       MYSQL_PASSWORD: "mempool" | ||||
|       MYSQL_ROOT_PASSWORD: "admin" | ||||
|     image: mariadb:10.5.8 | ||||
|     image: mariadb:10.5.21 | ||||
|     user: "1000:1000" | ||||
|     restart: on-failure | ||||
|     stop_grace_period: 1m | ||||
|  | ||||
| @ -1,32 +0,0 @@ | ||||
| FROM ubuntu:18.04 | ||||
| MAINTAINER mempool.space developers | ||||
| EXPOSE 50002 | ||||
| 
 | ||||
| # runs as UID 1000 GID 1000 inside the container | ||||
| 
 | ||||
| ENV VERSION 4.0.9 | ||||
| RUN set -x \ | ||||
|         && apt-get update \ | ||||
| 	&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gpg gpg-agent dirmngr \ | ||||
| 	&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends wget xpra python3-pyqt5 python3-wheel python3-pip python3-setuptools libsecp256k1-0 libsecp256k1-dev python3-numpy python3-dev build-essential \ | ||||
| 	&& wget -O /tmp/Electrum-${VERSION}.tar.gz https://download.electrum.org/${VERSION}/Electrum-${VERSION}.tar.gz \ | ||||
| 	&& wget -O /tmp/Electrum-${VERSION}.tar.gz.asc https://download.electrum.org/${VERSION}/Electrum-${VERSION}.tar.gz.asc \ | ||||
| 	&& gpg --keyserver keys.gnupg.net --recv-keys 6694D8DE7BE8EE5631BED9502BD5824B7F9470E6 \ | ||||
| 	&& gpg --verify /tmp/Electrum-${VERSION}.tar.gz.asc /tmp/Electrum-${VERSION}.tar.gz \ | ||||
| 	&& pip3 install /tmp/Electrum-${VERSION}.tar.gz \ | ||||
| 	&& test -f /usr/local/bin/electrum \ | ||||
| 	&& rm -vrf /tmp/Electrum-${VERSION}.tar.gz /tmp/Electrum-${VERSION}.tar.gz.asc ${HOME}/.gnupg \ | ||||
| 	&& apt-get purge --autoremove -y python3-wheel python3-pip python3-setuptools python3-dev build-essential libsecp256k1-dev curl gpg gpg-agent dirmngr \ | ||||
| 	&& apt-get clean && rm -rf /var/lib/apt/lists/* \ | ||||
| 	&& useradd -d /home/mempool -m mempool \ | ||||
| 	&& mkdir /electrum \ | ||||
| 	&& ln -s /electrum /home/mempool/.electrum \ | ||||
| 	&& chown mempool:mempool /electrum | ||||
| 
 | ||||
| USER mempool | ||||
| ENV HOME /home/mempool | ||||
| WORKDIR /home/mempool | ||||
| VOLUME /electrum | ||||
| 
 | ||||
| CMD ["/usr/bin/xpra", "start", ":100", "--start-child=/usr/local/bin/electrum", "--bind-tcp=0.0.0.0:50002","--daemon=yes", "--notifications=no", "--mdns=no", "--pulseaudio=no", "--html=off", "--speaker=disabled", "--microphone=disabled", "--webcam=no", "--printing=no", "--dbus-launch=", "--exit-with-children"] | ||||
| ENTRYPOINT ["electrum"] | ||||
| @ -1,4 +1,4 @@ | ||||
| FROM node:16.16.0-buster-slim AS builder | ||||
| FROM node:20.8.0-buster-slim AS builder | ||||
| 
 | ||||
| ARG commitHash | ||||
| ENV DOCKER_COMMIT_HASH=${commitHash} | ||||
| @ -13,7 +13,7 @@ RUN npm install --omit=dev --omit=optional | ||||
| 
 | ||||
| RUN npm run build | ||||
| 
 | ||||
| FROM nginx:1.17.8-alpine | ||||
| FROM nginx:1.24.0-alpine | ||||
| 
 | ||||
| WORKDIR /patch | ||||
| 
 | ||||
|  | ||||
| @ -39,6 +39,7 @@ __AUDIT__=${AUDIT:=false} | ||||
| __MAINNET_BLOCK_AUDIT_START_HEIGHT__=${MAINNET_BLOCK_AUDIT_START_HEIGHT:=0} | ||||
| __TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0} | ||||
| __SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0} | ||||
| __ACCELERATOR__=${ACCELERATOR:=false} | ||||
| __HISTORICAL_PRICE__=${HISTORICAL_PRICE:=true} | ||||
| 
 | ||||
| # Export as environment variables to be used by envsubst | ||||
| @ -65,6 +66,7 @@ export __AUDIT__ | ||||
| export __MAINNET_BLOCK_AUDIT_START_HEIGHT__ | ||||
| export __TESTNET_BLOCK_AUDIT_START_HEIGHT__ | ||||
| export __SIGNET_BLOCK_AUDIT_START_HEIGHT__ | ||||
| export __ACCELERATOR__ | ||||
| export __HISTORICAL_PRICE__ | ||||
| 
 | ||||
| folder=$(find /var/www/mempool -name "config.js" | xargs dirname) | ||||
|  | ||||
							
								
								
									
										462
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										462
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -59,9 +59,9 @@ | ||||
|       "optionalDependencies": { | ||||
|         "@cypress/schematic": "^2.5.0", | ||||
|         "@types/cypress": "^1.1.3", | ||||
|         "cypress": "^12.17.2", | ||||
|         "cypress-fail-on-console-error": "~4.0.3", | ||||
|         "cypress-wait-until": "^2.0.0", | ||||
|         "cypress": "^13.3.0", | ||||
|         "cypress-fail-on-console-error": "~5.0.0", | ||||
|         "cypress-wait-until": "^2.0.1", | ||||
|         "mock-socket": "~9.2.1", | ||||
|         "start-server-and-test": "~2.0.0" | ||||
|       } | ||||
| @ -1250,11 +1250,12 @@ | ||||
|       "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==" | ||||
|     }, | ||||
|     "node_modules/@babel/code-frame": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", | ||||
|       "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", | ||||
|       "version": "7.22.13", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", | ||||
|       "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", | ||||
|       "dependencies": { | ||||
|         "@babel/highlight": "^7.22.5" | ||||
|         "@babel/highlight": "^7.22.13", | ||||
|         "chalk": "^2.4.2" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
| @ -1464,20 +1465,33 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-environment-visitor": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", | ||||
|       "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", | ||||
|       "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-function-name": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", | ||||
|       "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", | ||||
|       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", | ||||
|       "dependencies": { | ||||
|         "@babel/template": "^7.22.5", | ||||
|         "@babel/types": "^7.22.5" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-function-name/node_modules/@babel/template": { | ||||
|       "version": "7.22.15", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", | ||||
|       "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", | ||||
|       "dependencies": { | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/parser": "^7.22.15", | ||||
|         "@babel/types": "^7.22.15" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
| @ -1627,9 +1641,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/helper-validator-identifier": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", | ||||
|       "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", | ||||
|       "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
| @ -1669,12 +1683,12 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/highlight": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", | ||||
|       "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", | ||||
|       "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", | ||||
|       "dependencies": { | ||||
|         "@babel/helper-validator-identifier": "^7.22.5", | ||||
|         "chalk": "^2.0.0", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "chalk": "^2.4.2", | ||||
|         "js-tokens": "^4.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -1682,9 +1696,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/parser": { | ||||
|       "version": "7.22.7", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", | ||||
|       "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", | ||||
|       "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", | ||||
|       "bin": { | ||||
|         "parser": "bin/babel-parser.js" | ||||
|       }, | ||||
| @ -2879,18 +2893,18 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/traverse": { | ||||
|       "version": "7.22.8", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", | ||||
|       "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", | ||||
|       "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", | ||||
|       "dependencies": { | ||||
|         "@babel/code-frame": "^7.22.5", | ||||
|         "@babel/generator": "^7.22.7", | ||||
|         "@babel/helper-environment-visitor": "^7.22.5", | ||||
|         "@babel/helper-function-name": "^7.22.5", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-function-name": "^7.23.0", | ||||
|         "@babel/helper-hoist-variables": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/parser": "^7.22.7", | ||||
|         "@babel/types": "^7.22.5", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "globals": "^11.1.0" | ||||
|       }, | ||||
| @ -2898,13 +2912,36 @@ | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/traverse/node_modules/@babel/generator": { | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", | ||||
|       "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", | ||||
|       "dependencies": { | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "@jridgewell/gen-mapping": "^0.3.2", | ||||
|         "@jridgewell/trace-mapping": "^0.3.17", | ||||
|         "jsesc": "^2.5.1" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/traverse/node_modules/@jridgewell/trace-mapping": { | ||||
|       "version": "0.3.20", | ||||
|       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", | ||||
|       "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", | ||||
|       "dependencies": { | ||||
|         "@jridgewell/resolve-uri": "^3.1.0", | ||||
|         "@jridgewell/sourcemap-codec": "^1.4.14" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/types": { | ||||
|       "version": "7.22.10", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", | ||||
|       "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", | ||||
|       "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", | ||||
|       "dependencies": { | ||||
|         "@babel/helper-string-parser": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "to-fast-properties": "^2.0.0" | ||||
|       }, | ||||
|       "engines": { | ||||
| @ -3016,9 +3053,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@cypress/request": { | ||||
|       "version": "2.88.11", | ||||
|       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", | ||||
|       "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", | ||||
|       "version": "3.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", | ||||
|       "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", | ||||
|       "optional": true, | ||||
|       "dependencies": { | ||||
|         "aws-sign2": "~0.7.0", | ||||
| @ -3034,9 +3071,9 @@ | ||||
|         "json-stringify-safe": "~5.0.1", | ||||
|         "mime-types": "~2.1.19", | ||||
|         "performance-now": "^2.1.0", | ||||
|         "qs": "~6.10.3", | ||||
|         "qs": "6.10.4", | ||||
|         "safe-buffer": "^5.1.2", | ||||
|         "tough-cookie": "~2.5.0", | ||||
|         "tough-cookie": "^4.1.3", | ||||
|         "tunnel-agent": "^0.6.0", | ||||
|         "uuid": "^8.3.2" | ||||
|       }, | ||||
| @ -4333,9 +4370,9 @@ | ||||
|       "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==" | ||||
|     }, | ||||
|     "node_modules/@types/node": { | ||||
|       "version": "18.11.9", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", | ||||
|       "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" | ||||
|       "version": "18.17.18", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.18.tgz", | ||||
|       "integrity": "sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw==" | ||||
|     }, | ||||
|     "node_modules/@types/qrcode": { | ||||
|       "version": "1.5.0", | ||||
| @ -5574,9 +5611,9 @@ | ||||
|       "optional": true | ||||
|     }, | ||||
|     "node_modules/bn.js": { | ||||
|       "version": "5.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", | ||||
|       "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" | ||||
|       "version": "5.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", | ||||
|       "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" | ||||
|     }, | ||||
|     "node_modules/body-parser": { | ||||
|       "version": "1.20.1", | ||||
| @ -5871,25 +5908,28 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/browserify-sign": { | ||||
|       "version": "4.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", | ||||
|       "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", | ||||
|       "version": "4.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", | ||||
|       "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", | ||||
|       "dependencies": { | ||||
|         "bn.js": "^5.1.1", | ||||
|         "browserify-rsa": "^4.0.1", | ||||
|         "bn.js": "^5.2.1", | ||||
|         "browserify-rsa": "^4.1.0", | ||||
|         "create-hash": "^1.2.0", | ||||
|         "create-hmac": "^1.1.7", | ||||
|         "elliptic": "^6.5.3", | ||||
|         "elliptic": "^6.5.4", | ||||
|         "inherits": "^2.0.4", | ||||
|         "parse-asn1": "^5.1.5", | ||||
|         "readable-stream": "^3.6.0", | ||||
|         "safe-buffer": "^5.2.0" | ||||
|         "parse-asn1": "^5.1.6", | ||||
|         "readable-stream": "^3.6.2", | ||||
|         "safe-buffer": "^5.2.1" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">= 4" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/browserify-sign/node_modules/readable-stream": { | ||||
|       "version": "3.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", | ||||
|       "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", | ||||
|       "version": "3.6.2", | ||||
|       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", | ||||
|       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", | ||||
|       "dependencies": { | ||||
|         "inherits": "^2.0.3", | ||||
|         "string_decoder": "^1.1.1", | ||||
| @ -7113,15 +7153,15 @@ | ||||
|       "peer": true | ||||
|     }, | ||||
|     "node_modules/cypress": { | ||||
|       "version": "12.17.2", | ||||
|       "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.2.tgz", | ||||
|       "integrity": "sha512-hxWAaWbqQBzzMuadSGSuQg5PDvIGOovm6xm0hIfpCVcORsCAj/gF2p0EvfnJ4f+jK2PCiDgP6D2eeE9/FK4Mjg==", | ||||
|       "version": "13.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.3.0.tgz", | ||||
|       "integrity": "sha512-mpI8qcTwLGiA4zEQvTC/U1xGUezVV4V8HQCOYjlEOrVmU1etVvxOjkCXHGwrlYdZU/EPmUiWfsO3yt1o+Q2bgw==", | ||||
|       "hasInstallScript": true, | ||||
|       "optional": true, | ||||
|       "dependencies": { | ||||
|         "@cypress/request": "^2.88.11", | ||||
|         "@cypress/request": "^3.0.0", | ||||
|         "@cypress/xvfb": "^1.2.4", | ||||
|         "@types/node": "^14.14.31", | ||||
|         "@types/node": "^18.17.5", | ||||
|         "@types/sinonjs__fake-timers": "8.1.1", | ||||
|         "@types/sizzle": "^2.3.2", | ||||
|         "arch": "^2.2.0", | ||||
| @ -7154,6 +7194,7 @@ | ||||
|         "minimist": "^1.2.8", | ||||
|         "ospath": "^1.2.2", | ||||
|         "pretty-bytes": "^5.6.0", | ||||
|         "process": "^0.11.10", | ||||
|         "proxy-from-env": "1.0.0", | ||||
|         "request-progress": "^3.0.0", | ||||
|         "semver": "^7.5.3", | ||||
| @ -7166,13 +7207,13 @@ | ||||
|         "cypress": "bin/cypress" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": "^14.0.0 || ^16.0.0 || >=18.0.0" | ||||
|         "node": "^16.0.0 || ^18.0.0 || >=20.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/cypress-fail-on-console-error": { | ||||
|       "version": "4.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-4.0.3.tgz", | ||||
|       "integrity": "sha512-v2nPupd2brtxKLkDQX58SbEPWRF/2nDbqPTnYyhPIYHqG7U3P2dGUZ3zraETKKoLhU3+C0otjgB6Vg/bHhocQw==", | ||||
|       "version": "5.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-5.0.0.tgz", | ||||
|       "integrity": "sha512-xui/aSu8rmExZjZNgId3iX0MsGZih6ZoFH+54vNHrK3HaqIZZX5hUuNhAcmfSoM1rIDc2DeITeVaMn/hiQ9IWQ==", | ||||
|       "optional": true, | ||||
|       "dependencies": { | ||||
|         "chai": "^4.3.4", | ||||
| @ -7182,19 +7223,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/cypress-wait-until": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.0.tgz", | ||||
|       "integrity": "sha512-ulUZyrWBn+OuC8oiQuGKAScDYfpaWnE3dEE/raUo64w4RHQxZrQ/iMIWT4ZjGMMPr3P+BFEALCRnjQeRqzZj6g==", | ||||
|       "optional": true, | ||||
|       "engines": { | ||||
|         "node": ">=18.16.0", | ||||
|         "npm": ">=9.5.1" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/cypress/node_modules/@types/node": { | ||||
|       "version": "14.18.53", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", | ||||
|       "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==", | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.1.tgz", | ||||
|       "integrity": "sha512-+IyVnYNiaX1+C+V/LazrJWAi/CqiwfNoRSrFviECQEyolW1gDRy765PZosL2alSSGK8V10Y7BGfOQyZUDgmnjQ==", | ||||
|       "optional": true | ||||
|     }, | ||||
|     "node_modules/cypress/node_modules/ansi-styles": { | ||||
| @ -10976,28 +11007,6 @@ | ||||
|       "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", | ||||
|       "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" | ||||
|     }, | ||||
|     "node_modules/jsdom/node_modules/tough-cookie": { | ||||
|       "version": "4.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", | ||||
|       "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", | ||||
|       "dependencies": { | ||||
|         "psl": "^1.1.33", | ||||
|         "punycode": "^2.1.1", | ||||
|         "universalify": "^0.2.0", | ||||
|         "url-parse": "^1.5.3" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/jsdom/node_modules/universalify": { | ||||
|       "version": "0.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", | ||||
|       "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", | ||||
|       "engines": { | ||||
|         "node": ">= 4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/jsesc": { | ||||
|       "version": "2.5.2", | ||||
|       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", | ||||
| @ -15682,16 +15691,25 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/tough-cookie": { | ||||
|       "version": "2.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", | ||||
|       "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", | ||||
|       "optional": true, | ||||
|       "version": "4.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", | ||||
|       "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", | ||||
|       "dependencies": { | ||||
|         "psl": "^1.1.28", | ||||
|         "punycode": "^2.1.1" | ||||
|         "psl": "^1.1.33", | ||||
|         "punycode": "^2.1.1", | ||||
|         "universalify": "^0.2.0", | ||||
|         "url-parse": "^1.5.3" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=0.8" | ||||
|         "node": ">=6" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/tough-cookie/node_modules/universalify": { | ||||
|       "version": "0.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", | ||||
|       "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", | ||||
|       "engines": { | ||||
|         "node": ">= 4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/tr46": { | ||||
| @ -17790,11 +17808,12 @@ | ||||
|       "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==" | ||||
|     }, | ||||
|     "@babel/code-frame": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", | ||||
|       "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", | ||||
|       "version": "7.22.13", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", | ||||
|       "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", | ||||
|       "requires": { | ||||
|         "@babel/highlight": "^7.22.5" | ||||
|         "@babel/highlight": "^7.22.13", | ||||
|         "chalk": "^2.4.2" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/compat-data": { | ||||
| @ -17959,17 +17978,29 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-environment-visitor": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", | ||||
|       "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==" | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", | ||||
|       "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" | ||||
|     }, | ||||
|     "@babel/helper-function-name": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", | ||||
|       "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", | ||||
|       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", | ||||
|       "requires": { | ||||
|         "@babel/template": "^7.22.5", | ||||
|         "@babel/types": "^7.22.5" | ||||
|         "@babel/template": "^7.22.15", | ||||
|         "@babel/types": "^7.23.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@babel/template": { | ||||
|           "version": "7.22.15", | ||||
|           "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", | ||||
|           "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", | ||||
|           "requires": { | ||||
|             "@babel/code-frame": "^7.22.13", | ||||
|             "@babel/parser": "^7.22.15", | ||||
|             "@babel/types": "^7.22.15" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@babel/helper-hoist-variables": { | ||||
| @ -18071,9 +18102,9 @@ | ||||
|       "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" | ||||
|     }, | ||||
|     "@babel/helper-validator-identifier": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", | ||||
|       "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", | ||||
|       "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" | ||||
|     }, | ||||
|     "@babel/helper-validator-option": { | ||||
|       "version": "7.22.5", | ||||
| @ -18101,19 +18132,19 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/highlight": { | ||||
|       "version": "7.22.5", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", | ||||
|       "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", | ||||
|       "version": "7.22.20", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", | ||||
|       "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", | ||||
|       "requires": { | ||||
|         "@babel/helper-validator-identifier": "^7.22.5", | ||||
|         "chalk": "^2.0.0", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "chalk": "^2.4.2", | ||||
|         "js-tokens": "^4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "@babel/parser": { | ||||
|       "version": "7.22.7", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", | ||||
|       "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==" | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", | ||||
|       "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" | ||||
|     }, | ||||
|     "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { | ||||
|       "version": "7.22.5", | ||||
| @ -18890,29 +18921,51 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@babel/traverse": { | ||||
|       "version": "7.22.8", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", | ||||
|       "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", | ||||
|       "version": "7.23.2", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", | ||||
|       "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", | ||||
|       "requires": { | ||||
|         "@babel/code-frame": "^7.22.5", | ||||
|         "@babel/generator": "^7.22.7", | ||||
|         "@babel/helper-environment-visitor": "^7.22.5", | ||||
|         "@babel/helper-function-name": "^7.22.5", | ||||
|         "@babel/code-frame": "^7.22.13", | ||||
|         "@babel/generator": "^7.23.0", | ||||
|         "@babel/helper-environment-visitor": "^7.22.20", | ||||
|         "@babel/helper-function-name": "^7.23.0", | ||||
|         "@babel/helper-hoist-variables": "^7.22.5", | ||||
|         "@babel/helper-split-export-declaration": "^7.22.6", | ||||
|         "@babel/parser": "^7.22.7", | ||||
|         "@babel/types": "^7.22.5", | ||||
|         "@babel/parser": "^7.23.0", | ||||
|         "@babel/types": "^7.23.0", | ||||
|         "debug": "^4.1.0", | ||||
|         "globals": "^11.1.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@babel/generator": { | ||||
|           "version": "7.23.0", | ||||
|           "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", | ||||
|           "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", | ||||
|           "requires": { | ||||
|             "@babel/types": "^7.23.0", | ||||
|             "@jridgewell/gen-mapping": "^0.3.2", | ||||
|             "@jridgewell/trace-mapping": "^0.3.17", | ||||
|             "jsesc": "^2.5.1" | ||||
|           } | ||||
|         }, | ||||
|         "@jridgewell/trace-mapping": { | ||||
|           "version": "0.3.20", | ||||
|           "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", | ||||
|           "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", | ||||
|           "requires": { | ||||
|             "@jridgewell/resolve-uri": "^3.1.0", | ||||
|             "@jridgewell/sourcemap-codec": "^1.4.14" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@babel/types": { | ||||
|       "version": "7.22.10", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", | ||||
|       "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", | ||||
|       "version": "7.23.0", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", | ||||
|       "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", | ||||
|       "requires": { | ||||
|         "@babel/helper-string-parser": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.5", | ||||
|         "@babel/helper-validator-identifier": "^7.22.20", | ||||
|         "to-fast-properties": "^2.0.0" | ||||
|       } | ||||
|     }, | ||||
| @ -19010,9 +19063,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@cypress/request": { | ||||
|       "version": "2.88.11", | ||||
|       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", | ||||
|       "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", | ||||
|       "version": "3.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", | ||||
|       "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "aws-sign2": "~0.7.0", | ||||
| @ -19028,9 +19081,9 @@ | ||||
|         "json-stringify-safe": "~5.0.1", | ||||
|         "mime-types": "~2.1.19", | ||||
|         "performance-now": "^2.1.0", | ||||
|         "qs": "~6.10.3", | ||||
|         "qs": "6.10.4", | ||||
|         "safe-buffer": "^5.1.2", | ||||
|         "tough-cookie": "~2.5.0", | ||||
|         "tough-cookie": "^4.1.3", | ||||
|         "tunnel-agent": "^0.6.0", | ||||
|         "uuid": "^8.3.2" | ||||
|       } | ||||
| @ -19927,9 +19980,9 @@ | ||||
|       "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==" | ||||
|     }, | ||||
|     "@types/node": { | ||||
|       "version": "18.11.9", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", | ||||
|       "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" | ||||
|       "version": "18.17.18", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.18.tgz", | ||||
|       "integrity": "sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw==" | ||||
|     }, | ||||
|     "@types/qrcode": { | ||||
|       "version": "1.5.0", | ||||
| @ -20868,9 +20921,9 @@ | ||||
|       "optional": true | ||||
|     }, | ||||
|     "bn.js": { | ||||
|       "version": "5.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", | ||||
|       "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" | ||||
|       "version": "5.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", | ||||
|       "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" | ||||
|     }, | ||||
|     "body-parser": { | ||||
|       "version": "1.20.1", | ||||
| @ -21214,25 +21267,25 @@ | ||||
|       } | ||||
|     }, | ||||
|     "browserify-sign": { | ||||
|       "version": "4.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", | ||||
|       "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", | ||||
|       "version": "4.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", | ||||
|       "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", | ||||
|       "requires": { | ||||
|         "bn.js": "^5.1.1", | ||||
|         "browserify-rsa": "^4.0.1", | ||||
|         "bn.js": "^5.2.1", | ||||
|         "browserify-rsa": "^4.1.0", | ||||
|         "create-hash": "^1.2.0", | ||||
|         "create-hmac": "^1.1.7", | ||||
|         "elliptic": "^6.5.3", | ||||
|         "elliptic": "^6.5.4", | ||||
|         "inherits": "^2.0.4", | ||||
|         "parse-asn1": "^5.1.5", | ||||
|         "readable-stream": "^3.6.0", | ||||
|         "safe-buffer": "^5.2.0" | ||||
|         "parse-asn1": "^5.1.6", | ||||
|         "readable-stream": "^3.6.2", | ||||
|         "safe-buffer": "^5.2.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "readable-stream": { | ||||
|           "version": "3.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", | ||||
|           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", | ||||
|           "version": "3.6.2", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", | ||||
|           "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", | ||||
|           "requires": { | ||||
|             "inherits": "^2.0.3", | ||||
|             "string_decoder": "^1.1.1", | ||||
| @ -22065,14 +22118,14 @@ | ||||
|       "peer": true | ||||
|     }, | ||||
|     "cypress": { | ||||
|       "version": "12.17.2", | ||||
|       "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.2.tgz", | ||||
|       "integrity": "sha512-hxWAaWbqQBzzMuadSGSuQg5PDvIGOovm6xm0hIfpCVcORsCAj/gF2p0EvfnJ4f+jK2PCiDgP6D2eeE9/FK4Mjg==", | ||||
|       "version": "13.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.3.0.tgz", | ||||
|       "integrity": "sha512-mpI8qcTwLGiA4zEQvTC/U1xGUezVV4V8HQCOYjlEOrVmU1etVvxOjkCXHGwrlYdZU/EPmUiWfsO3yt1o+Q2bgw==", | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "@cypress/request": "^2.88.11", | ||||
|         "@cypress/request": "^3.0.0", | ||||
|         "@cypress/xvfb": "^1.2.4", | ||||
|         "@types/node": "^14.14.31", | ||||
|         "@types/node": "^18.17.5", | ||||
|         "@types/sinonjs__fake-timers": "8.1.1", | ||||
|         "@types/sizzle": "^2.3.2", | ||||
|         "arch": "^2.2.0", | ||||
| @ -22105,6 +22158,7 @@ | ||||
|         "minimist": "^1.2.8", | ||||
|         "ospath": "^1.2.2", | ||||
|         "pretty-bytes": "^5.6.0", | ||||
|         "process": "^0.11.10", | ||||
|         "proxy-from-env": "1.0.0", | ||||
|         "request-progress": "^3.0.0", | ||||
|         "semver": "^7.5.3", | ||||
| @ -22114,12 +22168,6 @@ | ||||
|         "yauzl": "^2.10.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@types/node": { | ||||
|           "version": "14.18.53", | ||||
|           "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", | ||||
|           "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "ansi-styles": { | ||||
|           "version": "4.3.0", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", | ||||
| @ -22236,9 +22284,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "cypress-fail-on-console-error": { | ||||
|       "version": "4.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-4.0.3.tgz", | ||||
|       "integrity": "sha512-v2nPupd2brtxKLkDQX58SbEPWRF/2nDbqPTnYyhPIYHqG7U3P2dGUZ3zraETKKoLhU3+C0otjgB6Vg/bHhocQw==", | ||||
|       "version": "5.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-5.0.0.tgz", | ||||
|       "integrity": "sha512-xui/aSu8rmExZjZNgId3iX0MsGZih6ZoFH+54vNHrK3HaqIZZX5hUuNhAcmfSoM1rIDc2DeITeVaMn/hiQ9IWQ==", | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "chai": "^4.3.4", | ||||
| @ -22248,9 +22296,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "cypress-wait-until": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.0.tgz", | ||||
|       "integrity": "sha512-ulUZyrWBn+OuC8oiQuGKAScDYfpaWnE3dEE/raUo64w4RHQxZrQ/iMIWT4ZjGMMPr3P+BFEALCRnjQeRqzZj6g==", | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.1.tgz", | ||||
|       "integrity": "sha512-+IyVnYNiaX1+C+V/LazrJWAi/CqiwfNoRSrFviECQEyolW1gDRy765PZosL2alSSGK8V10Y7BGfOQyZUDgmnjQ==", | ||||
|       "optional": true | ||||
|     }, | ||||
|     "d": { | ||||
| @ -24967,22 +25015,6 @@ | ||||
|           "version": "6.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", | ||||
|           "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" | ||||
|         }, | ||||
|         "tough-cookie": { | ||||
|           "version": "4.1.3", | ||||
|           "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", | ||||
|           "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", | ||||
|           "requires": { | ||||
|             "psl": "^1.1.33", | ||||
|             "punycode": "^2.1.1", | ||||
|             "universalify": "^0.2.0", | ||||
|             "url-parse": "^1.5.3" | ||||
|           } | ||||
|         }, | ||||
|         "universalify": { | ||||
|           "version": "0.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", | ||||
|           "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| @ -28497,13 +28529,21 @@ | ||||
|       "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" | ||||
|     }, | ||||
|     "tough-cookie": { | ||||
|       "version": "2.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", | ||||
|       "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", | ||||
|       "optional": true, | ||||
|       "version": "4.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", | ||||
|       "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", | ||||
|       "requires": { | ||||
|         "psl": "^1.1.28", | ||||
|         "punycode": "^2.1.1" | ||||
|         "psl": "^1.1.33", | ||||
|         "punycode": "^2.1.1", | ||||
|         "universalify": "^0.2.0", | ||||
|         "url-parse": "^1.5.3" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "universalify": { | ||||
|           "version": "0.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", | ||||
|           "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "tr46": { | ||||
|  | ||||
| @ -35,7 +35,7 @@ | ||||
|     "start:local-staging": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local-staging", | ||||
|     "start:mixed": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c mixed", | ||||
|     "build": "npm run generate-config && npm run ng -- build --configuration production --localize && npm run sync-assets && npm run build-mempool.js", | ||||
|     "sync-assets": "rsync -av ./src/resources ./dist/mempool/browser && node sync-assets.js 'dist/mempool/browser/resources'", | ||||
|     "sync-assets": "rsync -av ./src/resources ./dist/mempool/browser && node sync-assets.js 'dist/mempool/browser/resources/'", | ||||
|     "sync-assets-dev": "node sync-assets.js 'src/resources/'", | ||||
|     "generate-config": "node generate-config.js", | ||||
|     "build-mempool.js": "npm run build-mempool-js && npm run build-mempool-liquid-js && npm run build-mempool-bisq-js", | ||||
| @ -85,7 +85,6 @@ | ||||
|     "clipboard": "^2.0.11", | ||||
|     "domino": "^2.1.6", | ||||
|     "echarts": "~5.4.3", | ||||
|     "echarts-gl": "^2.0.9", | ||||
|     "lightweight-charts": "~3.8.0", | ||||
|     "ngx-echarts": "~16.0.0", | ||||
|     "ngx-infinite-scroll": "^16.0.0", | ||||
| @ -111,9 +110,9 @@ | ||||
|   "optionalDependencies": { | ||||
|     "@cypress/schematic": "^2.5.0", | ||||
|     "@types/cypress": "^1.1.3", | ||||
|     "cypress": "^12.17.2", | ||||
|     "cypress-fail-on-console-error": "~4.0.3", | ||||
|     "cypress-wait-until": "^2.0.0", | ||||
|     "cypress": "^13.3.0", | ||||
|     "cypress-fail-on-console-error": "~5.0.0", | ||||
|     "cypress-wait-until": "^2.0.1", | ||||
|     "mock-socket": "~9.2.1", | ||||
|     "start-server-and-test": "~2.0.0" | ||||
|   }, | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, OnInit } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable, Subscription, combineLatest } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
| @ -123,11 +123,11 @@ export class BlockFeesGraphComponent implements OnInit { | ||||
|     this.chartOptions = { | ||||
|       title: title, | ||||
|       color: [ | ||||
|         new graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|           { offset: 0, color: '#FDD835' }, | ||||
|           { offset: 1, color: '#FB8C00' }, | ||||
|         ]), | ||||
|         new graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|           { offset: 0, color: '#C0CA33' }, | ||||
|           { offset: 1, color: '#1B5E20' }, | ||||
|         ]), | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, OnInit } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
| @ -123,11 +123,11 @@ export class BlockRewardsGraphComponent implements OnInit { | ||||
|       title: title, | ||||
|       animation: false, | ||||
|       color: [ | ||||
|         new graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|           { offset: 0, color: '#FDD835' }, | ||||
|           { offset: 1, color: '#FB8C00' }, | ||||
|         ]), | ||||
|         new graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | ||||
|           { offset: 0, color: '#C0CA33' }, | ||||
|           { offset: 1, color: '#1B5E20' }, | ||||
|         ]), | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption} from 'echarts'; | ||||
| import { EChartsOption} from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <app-indexing-progress *ngIf="!widget"></app-indexing-progress> | ||||
| 
 | ||||
| <div class="container-xl" style="min-height: 335px" [ngClass]="{'widget': widget, 'full-height': !widget, 'legacy': !indexingAvailable}"> | ||||
| <div class="container-xl" style="min-height: 335px" [ngClass]="{'widget': widget, 'full-height': !widget, 'legacy': !isMempoolModule}"> | ||||
|   <h1 *ngIf="!widget" class="float-left" i18n="master-page.blocks">Blocks</h1> | ||||
|   <div *ngIf="!widget && isLoading" class="spinner-border ml-3" role="status"></div> | ||||
| 
 | ||||
| @ -9,28 +9,28 @@ | ||||
|   <div style="min-height: 295px"> | ||||
|     <table class="table table-borderless"> | ||||
|       <thead> | ||||
|         <th class="height text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}" i18n="latest-blocks.height">Height</th> | ||||
|         <th *ngIf="indexingAvailable" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}" i18n="mining.pool-name" | ||||
|         <th class="height text-left" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}" i18n="latest-blocks.height">Height</th> | ||||
|         <th *ngIf="isMempoolModule" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}" i18n="mining.pool-name" | ||||
|           i18n-ngbTooltip="mining.pool-name" ngbTooltip="Pool" placement="bottom" #miningpool [disableTooltip]="!isEllipsisActive(miningpool)">Pool</th> | ||||
|         <th class="timestamp" i18n="latest-blocks.timestamp" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'">Timestamp</th> | ||||
|         <th *ngIf="auditAvailable" class="health text-right" i18n="latest-blocks.health" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}" | ||||
|         <th class="timestamp" i18n="latest-blocks.timestamp" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'">Timestamp</th> | ||||
|         <th *ngIf="auditAvailable" class="health text-right" i18n="latest-blocks.health" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}" | ||||
|           i18n-ngbTooltip="latest-blocks.health" ngbTooltip="Health" placement="bottom" #health [disableTooltip]="!isEllipsisActive(health)">Health</th> | ||||
|         <th *ngIf="indexingAvailable" class="reward text-right" i18n="latest-blocks.reward" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}" | ||||
|         <th *ngIf="isMempoolModule" class="reward text-right" i18n="latest-blocks.reward" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}" | ||||
|           i18n-ngbTooltip="latest-blocks.reward" ngbTooltip="Reward" placement="bottom" #reward [disableTooltip]="!isEllipsisActive(reward)">Reward</th> | ||||
|         <th *ngIf="indexingAvailable && !widget" class="fees text-right" i18n="latest-blocks.fees" [class]="indexingAvailable ? '' : 'legacy'">Fees</th> | ||||
|         <th *ngIf="auditAvailable && !widget" class="fee-delta" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"></th> | ||||
|         <th *ngIf="indexingAvailable" class="txs text-right" i18n="dashboard.txs" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}" | ||||
|         <th *ngIf="isMempoolModule && !auditAvailable || isMempoolModule && !widget" class="fees text-right" i18n="latest-blocks.fees" [class]="isMempoolModule ? '' : 'legacy'">Fees</th> | ||||
|         <th *ngIf="auditAvailable && !widget" class="fee-delta" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"></th> | ||||
|         <th *ngIf="isMempoolModule" class="txs text-right" i18n="dashboard.txs" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}" | ||||
|           i18n-ngbTooltip="dashboard.txs" ngbTooltip="TXs" placement="bottom" #txs [disableTooltip]="!isEllipsisActive(txs)">TXs</th> | ||||
|         <th *ngIf="!indexingAvailable" class="txs text-right" i18n="dashboard.txs" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">Transactions</th> | ||||
|         <th class="size" i18n="latest-blocks.size" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'">Size</th> | ||||
|         <th *ngIf="!isMempoolModule" class="txs text-right" i18n="dashboard.txs" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}">Transactions</th> | ||||
|         <th class="size" i18n="latest-blocks.size" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'">Size</th> | ||||
|       </thead> | ||||
|       <tbody *ngIf="blocks$ | async as blocks; else skeleton" [style]="isLoading ? 'opacity: 0.75' : ''"> | ||||
|         <tr *ngFor="let block of blocks; let i= index; trackBy: trackByBlock"> | ||||
|           <td class="height text-left" [class]="widget ? 'widget' : ''"> | ||||
|             <a [routerLink]="['/block' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a> | ||||
|           </td> | ||||
|           <td  *ngIf="indexingAvailable" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <div class="tooltip-custom"> | ||||
|           <td  *ngIf="isMempoolModule" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             <div *ngIf="indexingAvailable" class="tooltip-custom"> | ||||
|               <a class="clear-link" [routerLink]="['/mining/pool' | relativeUrl, block.extras.pool.slug]"> | ||||
|                 <img width="22" height="22" src="{{ block.extras.pool['logo'] }}" | ||||
|                   onError="this.src = '/resources/mining-pools/default.svg'" [alt]="'Logo of ' + block.extras.pool.name + ' mining pool'"> | ||||
| @ -38,11 +38,17 @@ | ||||
|               </a> | ||||
|               <span *ngIf="!widget" class="tooltiptext badge badge-secondary scriptmessage">{{ block.extras.coinbaseRaw | hex2ascii }}</span> | ||||
|             </div> | ||||
|             <div *ngIf="!indexingAvailable" class="tooltip-custom"> | ||||
|               <img width="22" height="22" src="{{ block.extras.pool['logo'] }}" | ||||
|                 onError="this.src = '/resources/mining-pools/default.svg'" [alt]="'Logo of ' + block.extras.pool.name + ' mining pool'"> | ||||
|               <span class="pool-name">{{ block.extras.pool.name }}</span> | ||||
|               <span *ngIf="!widget" class="tooltiptext badge badge-secondary scriptmessage">{{ block.extras.coinbaseRaw | hex2ascii }}</span> | ||||
|             </div> | ||||
|           </td> | ||||
|           <td class="timestamp" *ngIf="!widget" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|           <td class="timestamp" *ngIf="!widget" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             ‎{{ block.timestamp * 1000 | date:'yyyy-MM-dd HH:mm' }} | ||||
|           </td> | ||||
|           <td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|           <td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             <a | ||||
|               *ngIf="block?.extras?.matchRate != null; else nullHealth" | ||||
|               class="health-badge badge" | ||||
| @ -56,21 +62,21 @@ | ||||
|               <span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span> | ||||
|             </ng-template> | ||||
|           </td> | ||||
|           <td *ngIf="indexingAvailable" class="reward text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|           <td *ngIf="isMempoolModule" class="reward text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             <app-amount [satoshis]="block.extras.reward" [noFiat]="true" digitsInfo="1.2-2"></app-amount> | ||||
|           </td> | ||||
|           <td *ngIf="indexingAvailable && !widget" class="fees text-right" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|           <td *ngIf="isMempoolModule && !auditAvailable || isMempoolModule && !widget" class="fees text-right" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|             <app-amount [satoshis]="block.extras.totalFees" [noFiat]="true" digitsInfo="1.2-2"></app-amount> | ||||
|           </td> | ||||
|           <td *ngIf="auditAvailable" class="fee-delta" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|           <td *ngIf="auditAvailable" class="fee-delta" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             <span *ngIf="block.extras.feeDelta" class="difference" [class.positive]="block.extras.feeDelta >= 0" [class.negative]="block.extras.feeDelta < 0"> | ||||
|               {{ block.extras.feeDelta > 0 ? '+' : '' }}{{ (block.extras.feeDelta * 100) | amountShortener: 2 }}% | ||||
|             </span> | ||||
|           </td> | ||||
|           <td class="txs text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|           <td class="txs text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|             {{ block.tx_count | number }} | ||||
|           </td> | ||||
|           <td class="size" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|           <td class="size" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|             <div class="progress"> | ||||
|               <div class="progress-bar progress-mempool" role="progressbar" | ||||
|                 [ngStyle]="{'width': (block.weight / stateService.env.BLOCK_WEIGHT_UNITS)*100 + '%' }"></div> | ||||
| @ -82,34 +88,34 @@ | ||||
|       <ng-template #skeleton> | ||||
|         <tbody> | ||||
|           <tr *ngFor="let item of skeletonLines"> | ||||
|             <td class="height text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <td class="height text-left" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td *ngIf="indexingAvailable" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <td *ngIf="isMempoolModule" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|               <span class="skeleton-loader" style="max-width: 125px"></span> | ||||
|             </td> | ||||
|             <td class="timestamp" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|             <td class="timestamp" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|               <span class="skeleton-loader" style="max-width: 150px"></span> | ||||
|             </td> | ||||
|             <td class="mined" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|             <td class="mined" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|               <span class="skeleton-loader" style="max-width: 125px"></span> | ||||
|             </td> | ||||
|             <td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td *ngIf="indexingAvailable" class="reward text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <td *ngIf="isMempoolModule" class="reward text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td *ngIf="indexingAvailable && !widget" class="fees text-right" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|             <td *ngIf="isMempoolModule && !widget" class="fees text-right" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td *ngIf="auditAvailable && !widget" class="fee-delta" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|             <td *ngIf="auditAvailable && !widget" class="fee-delta" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td class="txs text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> | ||||
|             <td class="txs text-right" [ngClass]="{'widget': widget, 'legacy': !isMempoolModule}"> | ||||
|               <span class="skeleton-loader" style="max-width: 75px"></span> | ||||
|             </td> | ||||
|             <td class="size" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'"> | ||||
|             <td class="size" *ngIf="!widget" [class]="isMempoolModule ? '' : 'legacy'"> | ||||
|               <span class="skeleton-loader"></span> | ||||
|             </td> | ||||
|           </tr> | ||||
|  | ||||
| @ -19,6 +19,7 @@ export class BlocksList implements OnInit { | ||||
| 
 | ||||
|   blocks$: Observable<BlockExtended[]> = undefined; | ||||
| 
 | ||||
|   isMempoolModule = false; | ||||
|   indexingAvailable = false; | ||||
|   auditAvailable = false; | ||||
|   isLoading = true; | ||||
| @ -39,6 +40,7 @@ export class BlocksList implements OnInit { | ||||
|     private cd: ChangeDetectorRef, | ||||
|     private seoService: SeoService, | ||||
|   ) { | ||||
|     this.isMempoolModule = this.stateService.env.BASE_MODULE === 'mempool'; | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit(): void { | ||||
| @ -75,11 +77,10 @@ export class BlocksList implements OnInit { | ||||
|                 this.lastBlockHeight = Math.max(...blocks.map(o => o.height)); | ||||
|               }), | ||||
|               map(blocks => { | ||||
|                 if (this.indexingAvailable) { | ||||
|                 if (this.stateService.env.BASE_MODULE === 'mempool') { | ||||
|                   for (const block of blocks) { | ||||
|                     // @ts-ignore: Need to add an extra field for the template
 | ||||
|                     block.extras.pool.logo = `/resources/mining-pools/` + | ||||
|                       block.extras.pool.slug + '.svg'; | ||||
|                     block.extras.pool.logo = `/resources/mining-pools/` + block.extras.pool.slug + '.svg'; | ||||
|                   } | ||||
|                 } | ||||
|                 if (this.widget) { | ||||
| @ -110,7 +111,7 @@ export class BlocksList implements OnInit { | ||||
|           } | ||||
|           if (blocks[1]) { | ||||
|             this.blocksCount = Math.max(this.blocksCount, blocks[1][0].height) + 1; | ||||
|             if (this.stateService.env.MINING_DASHBOARD) { | ||||
|             if (this.isMempoolModule) { | ||||
|               // @ts-ignore: Need to add an extra field for the template
 | ||||
|               blocks[1][0].extras.pool.logo = `/resources/mining-pools/` + | ||||
|                 blocks[1][0].extras.pool.slug + '.svg'; | ||||
| @ -121,9 +122,11 @@ export class BlocksList implements OnInit { | ||||
|           return acc; | ||||
|         }, []), | ||||
|         switchMap((blocks) => { | ||||
|           if (this.isMempoolModule && this.auditAvailable) { | ||||
|             blocks.forEach(block => { | ||||
|               block.extras.feeDelta = block.extras.expectedFees ? (block.extras.totalFees - block.extras.expectedFees) / block.extras.expectedFees : 0; | ||||
|             }); | ||||
|           } | ||||
|           return of(blocks); | ||||
|         }) | ||||
|       ); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { merge, Observable, of } from 'rxjs'; | ||||
| import { map, mergeMap, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
| @ -204,7 +204,7 @@ export class HashrateChartComponent implements OnInit { | ||||
|       title: title, | ||||
|       animation: false, | ||||
|       color: [ | ||||
|         new graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|           { offset: 0, color: '#F4511E99' }, | ||||
|           { offset: 0.25, color: '#FB8C0099' }, | ||||
|           { offset: 0.5, color: '#FFB30099' }, | ||||
| @ -212,7 +212,7 @@ export class HashrateChartComponent implements OnInit { | ||||
|           { offset: 1, color: '#7CB34299' } | ||||
|         ]), | ||||
|         '#D81B60', | ||||
|         new graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|           { offset: 0, color: '#F4511E' }, | ||||
|           { offset: 0.25, color: '#FB8C00' }, | ||||
|           { offset: 0.5, color: '#FFB300' }, | ||||
| @ -342,7 +342,7 @@ export class HashrateChartComponent implements OnInit { | ||||
|           type: 'value', | ||||
|           axisLabel: { | ||||
|             color: 'rgb(110, 112, 121)', | ||||
|             formatter: (val) => { | ||||
|             formatter: (val): string => { | ||||
|               const selectedPowerOfTen: any = selectPowerOfTen(val); | ||||
|               const newVal = Math.round(val / selectedPowerOfTen.divider); | ||||
|               return `${newVal} ${selectedPowerOfTen.unit}H/s`; | ||||
| @ -364,9 +364,9 @@ export class HashrateChartComponent implements OnInit { | ||||
|           position: 'right', | ||||
|           axisLabel: { | ||||
|             color: 'rgb(110, 112, 121)', | ||||
|             formatter: (val) => { | ||||
|             formatter: (val): string => { | ||||
|               if (this.stateService.network === 'signet') { | ||||
|                 return val; | ||||
|                 return `${val}`; | ||||
|               } | ||||
|               const selectedPowerOfTen: any = selectPowerOfTen(val); | ||||
|               const newVal = Math.round(val / selectedPowerOfTen.divider); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { delay, map, retryWhen, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { OnChanges } from '@angular/core'; | ||||
| import { StorageService } from '../../services/storage.service'; | ||||
| import { download, formatterXAxis, formatterXAxisLabel } from '../../shared/graphs.utils'; | ||||
| @ -37,6 +37,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On | ||||
|   }; | ||||
|   windowPreference: string; | ||||
|   chartInstance: any = undefined; | ||||
|   MA: number[][] = []; | ||||
|   weightMode: boolean = false; | ||||
|   rateUnitSub: Subscription; | ||||
| 
 | ||||
| @ -62,6 +63,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On | ||||
|       return; | ||||
|     } | ||||
|     this.windowPreference = this.windowPreferenceOverride ? this.windowPreferenceOverride : this.storageService.getValue('graphWindowPreference'); | ||||
|     this.MA = this.calculateMA(this.data.series[0]); | ||||
|     this.mountChart(); | ||||
|   } | ||||
| 
 | ||||
| @ -72,7 +74,101 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On | ||||
|     this.isLoading = false; | ||||
|   } | ||||
| 
 | ||||
|   /// calculate the moving average of maData
 | ||||
|   calculateMA(maData): number[][] { | ||||
|     //update const variables that are not changed
 | ||||
|     const ma: number[][] = []; | ||||
|     let sum = 0; | ||||
|     let i = 0; | ||||
|     const len = maData.length; | ||||
| 
 | ||||
|     //Adjust window length based on the length of the data
 | ||||
|     //5% appeared as a good amount from tests
 | ||||
|     //TODO: make this a text box in the UI
 | ||||
|     const maWindowLen = Math.ceil(len * 0.05); | ||||
| 
 | ||||
|     //calculate the center of the moving average window
 | ||||
|     const center = Math.floor(maWindowLen / 2); | ||||
| 
 | ||||
|     //calculate the centered moving average
 | ||||
|     for (i = center; i < len - center; i++) { | ||||
|       sum = 0; | ||||
|       //build out ma as we loop through the data
 | ||||
|       ma[i] = []; | ||||
|       ma[i].push(maData[i][0]); | ||||
|       for (let j = i - center; j <= i + center; j++) { | ||||
|         sum += maData[j][1]; | ||||
|       } | ||||
| 
 | ||||
|       ma[i].push(sum / maWindowLen); | ||||
|     } | ||||
| 
 | ||||
|     //return the moving average array
 | ||||
|     return ma; | ||||
|   } | ||||
| 
 | ||||
|   mountChart(): void { | ||||
|     //create an array for the echart series
 | ||||
|     //similar to how it is done in mempool-graph.component.ts
 | ||||
|     const seriesGraph = []; | ||||
|     seriesGraph.push({ | ||||
|       zlevel: 0, | ||||
|       name: 'data', | ||||
|       data: this.data.series[0], | ||||
|       type: 'line', | ||||
|       smooth: false, | ||||
|       showSymbol: false, | ||||
|       symbol: 'none', | ||||
|       lineStyle: { | ||||
|         width: 3, | ||||
|       }, | ||||
|       markLine: { | ||||
|         silent: true, | ||||
|         symbol: 'none', | ||||
|         lineStyle: { | ||||
|           color: '#fff', | ||||
|           opacity: 1, | ||||
|           width: 2, | ||||
|         }, | ||||
|         data: [{ | ||||
|           yAxis: 1667, | ||||
|           label: { | ||||
|             show: false, | ||||
|             color: '#ffffff', | ||||
|           } | ||||
|         }], | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       zlevel: 0, | ||||
|       name: 'MA', | ||||
|       data: this.MA, | ||||
|       type: 'line', | ||||
|       smooth: false, | ||||
|       showSymbol: false, | ||||
|       symbol: 'none', | ||||
|       lineStyle: { | ||||
|         width: 1, | ||||
|         color: "white", | ||||
|       }, | ||||
|       markLine: { | ||||
|         silent: true, | ||||
|         symbol: 'none', | ||||
|         lineStyle: { | ||||
|           color: '#fff', | ||||
|           opacity: 1, | ||||
|           width: 2, | ||||
|         }, | ||||
|         data: [{ | ||||
|           yAxis: 1667, | ||||
|           label: { | ||||
|             show: false, | ||||
|             color: '#ffffff', | ||||
|           } | ||||
|         }], | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     this.mempoolStatsChartOption = { | ||||
|       grid: { | ||||
|         height: this.height, | ||||
| @ -126,13 +222,17 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On | ||||
|           const colorSpan = (color: string) => `<span class="indicator" style="background-color: ` + color + `"></span>`; | ||||
|           let itemFormatted = '<div class="title">' + axisValueLabel + '</div>'; | ||||
|           params.map((item: any, index: number) => { | ||||
| 
 | ||||
|             //Do no include MA in tooltip legend!
 | ||||
|             if (item.seriesName !== 'MA') { | ||||
|               if (index < 26) { | ||||
|                 itemFormatted += `<div class="item">
 | ||||
|                   <div class="indicator-container">${colorSpan(item.color)}</div> | ||||
|                   <div class="grow"></div> | ||||
|                 <div class="value">${formatNumber(this.weightMode ? item.value[1] * 4 : item.value[1], this.locale, '1.0-0')} <span class="symbol">${this.weightMode ? 'WU' : 'vB'}/s</span></div> | ||||
|                   <div class="value">${formatNumber(item.value[1], this.locale, '1.0-0')}<span class="symbol">vB/s</span></div> | ||||
|                 </div>`;
 | ||||
|               } | ||||
|             } | ||||
|           }); | ||||
|           return `<div class="tx-wrapper-tooltip-chart ${(this.template === 'advanced') ? 'tx-wrapper-tooltip-chart-advanced' : ''}">${itemFormatted}</div>`; | ||||
|         } | ||||
| @ -171,35 +271,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       series: [ | ||||
|         { | ||||
|           zlevel: 0, | ||||
|           data: this.data.series[0], | ||||
|           type: 'line', | ||||
|           smooth: false, | ||||
|           showSymbol: false, | ||||
|           symbol: 'none', | ||||
|           lineStyle: { | ||||
|             width: 3, | ||||
|           }, | ||||
|           markLine: { | ||||
|             silent: true, | ||||
|             symbol: 'none', | ||||
|             lineStyle: { | ||||
|               color: '#fff', | ||||
|               opacity: 1, | ||||
|               width: 2, | ||||
|             }, | ||||
|             data: [{ | ||||
|               yAxis: 1667, | ||||
|               label: { | ||||
|                 show: false, | ||||
|                 color: '#ffffff', | ||||
|               } | ||||
|             }], | ||||
|           } | ||||
|         }, | ||||
|       ], | ||||
|       series: seriesGraph, | ||||
|       visualMap: { | ||||
|         show: false, | ||||
|         top: 50, | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { Component, Inject, LOCALE_ID, ChangeDetectionStrategy, Input, OnChanges, OnInit } from '@angular/core'; | ||||
| import { formatDate, formatNumber } from '@angular/common'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'app-lbtc-pegs-graph', | ||||
|  | ||||
| @ -6,7 +6,7 @@ import { formatNumber } from '@angular/common'; | ||||
| import { OptimizedMempoolStats } from '../../interfaces/node-api.interface'; | ||||
| import { StateService } from '../../services/state.service'; | ||||
| import { StorageService } from '../../services/storage.service'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { feeLevels, chartColors } from '../../app.constants'; | ||||
| import { download, formatterXAxis, formatterXAxisLabel } from '../../shared/graphs.utils'; | ||||
| 
 | ||||
| @ -27,7 +27,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { | ||||
|   @Input() data: any[]; | ||||
|   @Input() filterSize = 100000; | ||||
|   @Input() limitFilterFee = 1; | ||||
|   @Input() hideCount: boolean = false; | ||||
|   @Input() hideCount: boolean = true; | ||||
|   @Input() height: number | string = 200; | ||||
|   @Input() top: number | string = 20; | ||||
|   @Input() right: number | string = 10; | ||||
| @ -53,7 +53,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { | ||||
|   chartInstance: any = undefined; | ||||
|   weightMode: boolean = false; | ||||
|   isWidget: boolean = false; | ||||
|   showCount: boolean = true; | ||||
|   showCount: boolean = false; | ||||
| 
 | ||||
|   constructor( | ||||
|     private vbytesPipe: VbytesPipe, | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import { ChangeDetectionStrategy, Component, Input, NgZone, OnInit, HostBinding } from '@angular/core'; | ||||
| import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; | ||||
| import { ActivatedRoute, Router } from '@angular/router'; | ||||
| import { EChartsOption, PieSeriesOption } from 'echarts'; | ||||
| import { EChartsOption, PieSeriesOption } from '../../graphs/echarts'; | ||||
| import { merge, Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { SeoService } from '../../services/seo.service'; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core'; | ||||
| import { ActivatedRoute } from '@angular/router'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable, of } from 'rxjs'; | ||||
| import { map, switchMap, catchError } from 'rxjs/operators'; | ||||
| import { PoolStat } from '../../interfaces/node-api.interface'; | ||||
| @ -127,7 +127,7 @@ export class PoolPreviewComponent implements OnInit { | ||||
|       title: title, | ||||
|       animation: false, | ||||
|       color: [ | ||||
|         new graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|           { offset: 0, color: '#F4511E' }, | ||||
|           { offset: 0.25, color: '#FB8C00' }, | ||||
|           { offset: 0.5, color: '#FFB300' }, | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; | ||||
| import { ActivatedRoute } from '@angular/router'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { BehaviorSubject, Observable, of, timer } from 'rxjs'; | ||||
| import { catchError, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators'; | ||||
| import { BlockExtended, PoolStat } from '../../interfaces/node-api.interface'; | ||||
| @ -131,7 +131,7 @@ export class PoolComponent implements OnInit { | ||||
|       title: title, | ||||
|       animation: false, | ||||
|       color: [ | ||||
|         new graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0, 0, 0.65, [ | ||||
|           { offset: 0, color: '#F4511E' }, | ||||
|           { offset: 0.25, color: '#FB8C00' }, | ||||
|           { offset: 0.5, color: '#FFB300' }, | ||||
|  | ||||
| @ -14,6 +14,7 @@ | ||||
|   <div id="blockchain-container" [dir]="timeLtr ? 'rtl' : 'ltr'" #blockchainContainer | ||||
|     [class.menu-open]="menuOpen" | ||||
|     [class.menu-closing]="menuSliding && !menuOpen" | ||||
|     [class.with-menu]="hasMenu" | ||||
|     (mousedown)="onMouseDown($event)" | ||||
|     (pointerdown)="onPointerDown($event)" | ||||
|     (touchmove)="onTouchMove($event)" | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
|   overflow-y: hidden; | ||||
|   scrollbar-width: none; | ||||
|   -ms-overflow-style: none; | ||||
|   width: calc(100% + 120px); | ||||
|   width: 100%; | ||||
| 
 | ||||
|   transform: translateX(0px); | ||||
|   transition: transform 0; | ||||
| @ -20,6 +20,10 @@ | ||||
|     transform: translateX(0px); | ||||
|     transition: transform 0.25s; | ||||
|   } | ||||
| 
 | ||||
|   &.with-menu { | ||||
|     width: calc(100% + 120px); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #blockchain-container::-webkit-scrollbar { | ||||
|  | ||||
| @ -60,11 +60,16 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy { | ||||
|   menuSliding: boolean = false; | ||||
|   menuTimeout: number; | ||||
| 
 | ||||
|   hasMenu = false; | ||||
| 
 | ||||
|   constructor( | ||||
|     private stateService: StateService, | ||||
|     private cd: ChangeDetectorRef, | ||||
|   ) { | ||||
|     this.isiOS = ['iPhone','iPod','iPad'].includes((navigator as any)?.userAgentData?.platform || navigator.platform); | ||||
|     if (this.stateService.network === '') { | ||||
|       this.hasMenu = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit() { | ||||
|  | ||||
| @ -32,7 +32,7 @@ export class StatisticsComponent implements OnInit { | ||||
|   chartColors = chartColors; | ||||
|   filterSize = 100000; | ||||
|   filterFeeIndex = 1; | ||||
|   showCount = true; | ||||
|   showCount = false; | ||||
|   maxFeeIndex: number; | ||||
|   dropDownOpen = false; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										17
									
								
								frontend/src/app/graphs/echarts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/src/app/graphs/echarts.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| // Import tree-shakeable echarts
 | ||||
| import * as echarts from 'echarts/core'; | ||||
| import { LineChart, LinesChart, BarChart, TreemapChart, PieChart, ScatterChart } from 'echarts/charts'; | ||||
| import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, GeoComponent, DataZoomComponent, VisualMapComponent } from 'echarts/components'; | ||||
| import { SVGRenderer, CanvasRenderer } from 'echarts/renderers'; | ||||
| // Typescript interfaces
 | ||||
| import { EChartsOption, TreemapSeriesOption, LineSeriesOption, PieSeriesOption } from 'echarts'; | ||||
| 
 | ||||
| 
 | ||||
| echarts.use([ | ||||
|   SVGRenderer, CanvasRenderer, | ||||
|   TitleComponent, TooltipComponent, GridComponent, | ||||
|   LegendComponent, GeoComponent, DataZoomComponent, | ||||
|   VisualMapComponent, | ||||
|   LineChart, LinesChart, BarChart, TreemapChart, PieChart, ScatterChart | ||||
| ]); | ||||
| export { echarts, EChartsOption, TreemapSeriesOption, LineSeriesOption, PieSeriesOption }; | ||||
| @ -53,7 +53,7 @@ import { CommonModule } from '@angular/common'; | ||||
|     SharedModule, | ||||
|     GraphsRoutingModule, | ||||
|     NgxEchartsModule.forRoot({ | ||||
|       echarts: () => import('echarts') | ||||
|       echarts: () => import('./echarts').then(m => m.echarts), | ||||
|     }) | ||||
|   ], | ||||
|   exports: [ | ||||
|  | ||||
| @ -57,7 +57,7 @@ export class GroupPreviewComponent implements OnInit { | ||||
|             return of(null); | ||||
|           } | ||||
| 
 | ||||
|           return this.lightningApiService.getNodGroupNodes$(this.groupId); | ||||
|           return this.lightningApiService.getNodeGroup$(this.groupId); | ||||
|         }), | ||||
|         map((nodes) => { | ||||
|           for (const node of nodes) { | ||||
|  | ||||
| @ -41,7 +41,7 @@ export class GroupComponent implements OnInit { | ||||
|     this.seoService.setTitle(`Mempool.space Lightning Nodes`); | ||||
|     this.seoService.setDescription(`See all Lightning nodes run by mempool.space -- these are the nodes that provide the data on the mempool.space Lightning dashboard.`); | ||||
| 
 | ||||
|     this.nodes$ = this.lightningApiService.getNodGroupNodes$('mempool.space') | ||||
|     this.nodes$ = this.lightningApiService.getNodeGroup$('mempool.space') | ||||
|       .pipe( | ||||
|         map((nodes) => { | ||||
|           for (const node of nodes) { | ||||
|  | ||||
| @ -27,7 +27,7 @@ export class LightningApiService { | ||||
|     return this.httpClient.get<any>(this.apiBasePath + '/api/v1/lightning/nodes/' + publicKey); | ||||
|   } | ||||
| 
 | ||||
|   getNodGroupNodes$(name: string): Observable<any[]> { | ||||
|   getNodeGroup$(name: string): Observable<any[]> { | ||||
|     return this.httpClient.get<any[]>(this.apiBasePath + '/api/v1/lightning/nodes/group/' + name); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { switchMap } from 'rxjs/operators'; | ||||
| import { download } from '../../shared/graphs.utils'; | ||||
| import { LightningApiService } from '../lightning-api.service'; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption } from 'echarts'; | ||||
| import { EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { switchMap, tap } from 'rxjs/operators'; | ||||
| import { formatNumber } from '@angular/common'; | ||||
|  | ||||
| @ -6,8 +6,7 @@ import { AssetsService } from '../../services/assets.service'; | ||||
| import { ActivatedRoute, ParamMap, Router } from '@angular/router'; | ||||
| import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | ||||
| import { StateService } from '../../services/state.service'; | ||||
| import { EChartsOption, registerMap } from 'echarts'; | ||||
| import 'echarts-gl'; | ||||
| import { EChartsOption, echarts } from '../../graphs/echarts'; | ||||
| import { isMobile } from '../../shared/common.utils'; | ||||
| 
 | ||||
| @Component({ | ||||
| @ -88,7 +87,7 @@ export class NodesChannelsMap implements OnInit { | ||||
|           this.style !== 'channelpage' ? this.apiService.getChannelsGeo$(params.get('public_key') ?? undefined, this.style) : [''], | ||||
|           [params.get('public_key') ?? undefined] | ||||
|         ).pipe(tap((data) => { | ||||
|           registerMap('world', data[0]); | ||||
|           echarts.registerMap('world', data[0]); | ||||
| 
 | ||||
|           const channelsLoc = []; | ||||
|           const nodes = []; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import { formatNumber } from '@angular/common'; | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, OnChanges } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { ECharts, EChartsOption, TreemapSeriesOption } from 'echarts'; | ||||
| import { EChartsOption, TreemapSeriesOption } from '../../graphs/echarts'; | ||||
| import { Observable, share, switchMap, tap } from 'rxjs'; | ||||
| import { lerpColor } from '../../shared/graphs.utils'; | ||||
| import { AmountShortenerPipe } from '../../shared/pipes/amount-shortener.pipe'; | ||||
| @ -18,7 +18,7 @@ import { StateService } from '../../services/state.service'; | ||||
| export class NodeChannels implements OnChanges { | ||||
|   @Input() publicKey: string; | ||||
| 
 | ||||
|   chartInstance: ECharts; | ||||
|   chartInstance: any; | ||||
|   chartOptions: EChartsOption = {}; | ||||
|   chartInitOptions = { | ||||
|     renderer: 'svg', | ||||
| @ -129,7 +129,7 @@ export class NodeChannels implements OnChanges { | ||||
|     };     | ||||
|   } | ||||
| 
 | ||||
|   onChartInit(ec: ECharts): void { | ||||
|   onChartInit(ec: any): void { | ||||
|     this.chartInstance = ec; | ||||
| 
 | ||||
|     this.chartInstance.on('click', (e) => { | ||||
|  | ||||
| @ -3,7 +3,7 @@ import { SeoService } from '../../services/seo.service'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
| import { Observable, BehaviorSubject, switchMap, tap, combineLatest } from 'rxjs'; | ||||
| import { AssetsService } from '../../services/assets.service'; | ||||
| import { EChartsOption, registerMap } from 'echarts'; | ||||
| import { EChartsOption, echarts } from '../../graphs/echarts'; | ||||
| import { lerpColor } from '../../shared/graphs.utils'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | ||||
| @ -63,7 +63,7 @@ export class NodesMap implements OnInit, OnChanges { | ||||
|       this.assetsService.getWorldMapJson$, | ||||
|       this.nodes$ | ||||
|     ).pipe(tap((data) => { | ||||
|       registerMap('world', data[0]); | ||||
|       echarts.registerMap('world', data[0]); | ||||
| 
 | ||||
|       let maxLiquidity = data[1].maxLiquidity; | ||||
|       let inputNodes: any[] = data[1].nodes; | ||||
| @ -88,7 +88,7 @@ export class NodesMap implements OnInit, OnChanges { | ||||
|             node.public_key, | ||||
|             node.alias, | ||||
|             node.capacity, | ||||
|             node.channels, | ||||
|             node.active_channel_count, | ||||
|             node.country, | ||||
|             node.iso_code, | ||||
|           ]); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption, graphic, LineSeriesOption} from 'echarts'; | ||||
| import { echarts, EChartsOption, LineSeriesOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { formatNumber } from '@angular/common'; | ||||
| @ -152,7 +152,7 @@ export class NodesNetworksChartComponent implements OnInit { | ||||
|           opacity: 0.5, | ||||
|         }, | ||||
|         stack: 'Total', | ||||
|         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|         color: new echarts.graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|           { offset: 0, color: '#D81B60' }, | ||||
|           { offset: 1, color: '#D81B60AA' }, | ||||
|         ]), | ||||
| @ -174,7 +174,7 @@ export class NodesNetworksChartComponent implements OnInit { | ||||
|           opacity: 0.5, | ||||
|         }, | ||||
|         stack: 'Total', | ||||
|         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|         color: new echarts.graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|           { offset: 0, color: '#be7d4c' }, | ||||
|           { offset: 1, color: '#be7d4cAA' }, | ||||
|         ]), | ||||
| @ -195,7 +195,7 @@ export class NodesNetworksChartComponent implements OnInit { | ||||
|           opacity: 0.5, | ||||
|         }, | ||||
|         stack: 'Total', | ||||
|         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|         color: new echarts.graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|           { offset: 0, color: '#FFB300' }, | ||||
|           { offset: 1, color: '#FFB300AA' }, | ||||
|         ]), | ||||
| @ -216,7 +216,7 @@ export class NodesNetworksChartComponent implements OnInit { | ||||
|           opacity: 0.5, | ||||
|         }, | ||||
|         stack: 'Total', | ||||
|         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|         color: new echarts.graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|           { offset: 0, color: '#7D4698' }, | ||||
|           { offset: 1, color: '#7D4698AA' }, | ||||
|         ]), | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { ChangeDetectionStrategy, Component, OnInit, HostBinding, NgZone } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { EChartsOption, PieSeriesOption } from 'echarts'; | ||||
| import { EChartsOption, PieSeriesOption } from '../../graphs/echarts'; | ||||
| import { map, Observable, share, tap } from 'rxjs'; | ||||
| import { chartColors } from '../../app.constants'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { ChangeDetectionStrategy, Component, OnInit, HostBinding, NgZone, Input } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { EChartsOption, PieSeriesOption } from 'echarts'; | ||||
| import { EChartsOption, PieSeriesOption } from '../../graphs/echarts'; | ||||
| import { combineLatest, map, Observable, share, startWith, Subject, switchMap, tap } from 'rxjs'; | ||||
| import { chartColors } from '../../app.constants'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||
| import { EChartsOption, graphic } from 'echarts'; | ||||
| import { echarts, EChartsOption } from '../../graphs/echarts'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||
| import { SeoService } from '../../services/seo.service'; | ||||
| @ -132,7 +132,7 @@ export class LightningStatisticsChartComponent implements OnInit { | ||||
|       animation: false, | ||||
|       color: [ | ||||
|         '#FFB300', | ||||
|         new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|         new echarts.graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||
|           { offset: 0, color: '#D81B60' }, | ||||
|           { offset: 1, color: '#D81B60AA' }, | ||||
|         ]), | ||||
|  | ||||
| @ -84,6 +84,7 @@ | ||||
|         <a href="https://github.com/mempool" target="_blank"><svg fill="#fff" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a> | ||||
|         <a href="https://twitter.com/mempool" target="_blank"><svg fill="#fff" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg></a> | ||||
|         <a href="nostr:npub18d4r6wanxkyrdfjdrjqzj2ukua5cas669ew2g5w7lf4a8te7awzqey6lt3" target="_blank"><svg fill="#fff" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 875 875"><path d="M684.72 485.57c.22 12.59-11.93 51.47-38.67 81.3-26.74 29.83-56.02 20.85-58.42 20.16s-3.09-4.46-7.89-3.77-9.6 6.17-18.86 7.2-17.49 1.71-26.06-1.37c-4.46.69-5.14.71-7.2 2.24s-17.83 10.79-21.6 11.47c0 7.2-1.37 44.57 0 55.89s3.77 25.71 7.54 36 2.74 10.63 7.54 9.94 13.37.34 15.77 4.11c2.4 3.77 1.37 6.51 5.49 8.23s60.69 17.14 99.43 19.2c26.74.69 42.86 2.74 52.12 19.54 1.37 7.89 7.54 13.03 11.31 14.06s8.23 2.06 12 5.83 1.03 8.23 5.49 11.66c4.46 3.43 14.74 8.57 25.37 13.71 10.63 5.14 15.09 13.37 15.77 16.11s1.71 10.97 1.71 10.97-8.91 0-10.97-2.06-2.74-5.83-2.74-5.83-6.17 1.03-7.54 3.43.69 2.74-7.89.69-11.66-3.77-18.17-8.57c-6.51-4.8-16.46-17.14-25.03-16.8 4.11 8.23 5.83 8.23 10.63 10.97s8.23 5.83 8.23 5.83l-7.2 4.46s-4.46 2.06-14.74-.69-11.66-4.46-12.69-10.63 0-9.26-2.74-14.4-4.11-15.77-22.29-21.26c-18.17-5.49-66.52-21.26-100.12-24.69s-22.63-2.74-28.11-1.37-15.77 4.46-26.4-1.37c-10.63-5.83-16.8-13.71-17.49-20.23s-1.71-10.97 0-19.2 3.43-19.89 1.71-26.74-14.06-55.89-19.89-64.12c-13.03 1.03-50.74-.69-50.74-.69s-2.4-.69-17.49 5.83-36.48 13.76-46.77 19.93-14.4 9.7-16.12 13.13c.12 3-1.23 7.72-2.79 9.06s-12.48 2.42-12.48 2.42-5.85 5.86-8.25 9.97c-6.86 9.6-55.2 125.14-66.52 149.83-13.54 32.57-9.77 27.43-37.71 27.43s-8.06.3-8.06.3-12.34 5.88-16.8 5.88-18.86-2.4-26.4 0-16.46 9.26-23.31 10.29-4.95-1.34-8.38-3.74c-4-.21-14.27-.12-14.27-.12s1.74-6.51 7.91-10.88c8.23-5.83 25.37-16.11 34.63-21.26s17.49-7.89 23.31-9.26 18.51-6.17 30.51-9.94 19.54-8.23 29.83-31.54 50.4-111.43 51.43-116.23c.63-2.96 3.73-6.48 4.8-15.09.66-5.35-2.49-13.04 1.71-22.63 10.97-25.03 21.6-20.23 26.4-20.23s17.14.34 26.4-1.37 15.43-2.74 24.69-7.89 11.31-8.91 11.31-8.91l-19.89-3.43s-18.51.69-25.03-4.46-15.43-15.77-15.43-15.77l-7.54-7.2 1.03 8.57s-5.14-8.91-6.51-10.29-8.57-6.51-11.31-11.31-7.54-25.03-7.54-25.03l-6.17 13.03-1.71-18.86-5.14 7.2-2.74-16.11-4.8 8.23-3.43-14.4-5.83 4.46-2.4-10.29-5.83-3.43s-14.06-9.26-16.46-9.6-4.46 3.43-4.46 3.43l1.37 12-12.2-6.27-7-11.9s2.36 4.01-9.62 7.53c-20.55 0-21.89-2.28-24.93-3.94-1.31-6.56-5.57-10.11-5.57-10.11h-20.57l-.34-6.86-7.89 3.09.69-10.29h-14.06l1.03-11.31h-8.91s3.09-9.26 25.71-22.97 25.03-16.46 46.29-17.14c21.26-.69 32.91 2.74 46.29 8.23s38.74 13.71 43.89 17.49c11.31-9.94 28.46-19.89 34.29-19.89 1.03-2.4 6.19-12.33 17.96-17.6 35.31-15.81 108.13-34 131.53-35.54 31.2-2.06 7.89-1.37 39.09 2.06 31.2 3.43 54.17 7.54 69.6 12.69 12.58 4.19 25.03 9.6 34.29 2.06 4.33-1.81 11.81-1.34 17.83-5.14 30.69-25.09 34.72-32.35 43.63-41.95s20.14-24.91 22.54-45.14 4.46-58.29-10.63-88.12-28.8-45.26-34.63-69.26c-5.83-24-8.23-61.03-6.17-73.03 2.06-12 5.14-22.29 6.86-30.51s9.94-14.74 19.89-16.46c9.94-1.71 17.83 1.37 22.29 4.8 4.46 3.43 11.65 6.28 13.37 10.29.34 1.71-1.37 6.51 8.23 8.23 9.6 1.71 16.05 4.16 16.05 4.16s15.64 4.29 3.11 7.73c-12.69 2.06-20.52-.71-24.29 1.69s-7.21 10.08-9.61 11.1-7.2.34-12 4.11-9.6 6.86-12.69 14.4-5.49 15.77-3.43 26.74 8.57 31.54 14.4 43.2c5.83 11.66 20.23 40.8 24.34 47.66s15.77 29.49 16.8 53.83 1.03 44.23 0 54.86-10.84 51.65-35.53 85.94c-8.16 14.14-23.21 31.9-24.67 35.03-1.45 3.13-3.02 4.88-1.61 7.65 4.62 9.05 12.87 22.13 14.71 29.22 2.29 6.64 6.99 16.13 7.22 28.72Z" style="stroke:#000;stroke-miterlimit:10;stroke-width:6px"/></svg></a> | ||||
|         <a href="https://primal.net/mempool" target="_blank"><svg fill="#fff" role="img" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" ><path d="m155.5 253c-8.9 2-18.1 3-27.5 3-25.9 0-50-7.7-70.2-20.9-5-7.2-7.2-11.1-8.9-14-0.8-1.4-1.5-2.6-2.2-3.8-7.7-12.2-11.7-28-12.5-46.6-2.7-57.4 32.2-94 67.8-100.1 22.6-3.8 40.6 0.1 54.3 7.5-12.1-3.4-26.6-3.6-43.2 1.1-40.1 12.9-53.5 52.3-47.8 95.8 10 54.6 63.5 74.1 90.2 78zm-114.3-30.9c-7.4-13.2-14.2-33-15-51-2.9-60.9 34.4-101.6 74.5-108.3 54.7-9.3 85.1 23.1 95.6 47.1 0.4-0.3 0.6-0.9 0.3-1.4-17.2-37.4-52.8-63.2-94-63.2-46.8 0-88.5 33.6-102.6 83.4 0.2 36.9 16 70.2 41.2 93.4zm158.8 11.7c-9.2 6.3-19.3 11.5-30.1 15.2-5.1-0.9-10.9-2-14.9-2.8-1.9-0.4-3.4-0.7-4.3-0.9-24.4-4.4-67.9-20.1-77.5-71.6-2.6-20.6-0.7-39.7 6.1-54.8 6.7-14.9 18.4-26.3 36.1-32 20.6-5.6 37.7-2.9 50.3 3.9q-4.7-0.9-9.6-1c-27.4 0-49.7 23.9-49.7 53.3 0 11.7 3.6 22.5 9.6 31.3 0 0 17.2 32.5 64 29.6 41.7-2.6 63.4-40 66-53.8 1.3-7.2 2-14.6 2-22.2 0-66.3-53.7-120-120-120-50.1 0-93.1 30.8-111.1 74.4-6 7.9-11.2 16.7-15.4 26.2 9.3-61.5 62.4-108.6 126.5-108.6 70.7 0 128 57.3 128 128 0 44-22.2 82.8-56 105.8z" style="fill:#ffffff"/></svg></a> | ||||
|         <a href="https://youtube.com/@mempool" target="_blank"><svg fill="#fff" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg></a> | ||||
|         <a href="https://bitcointv.com/c/mempool/videos" target="_blank"><svg _ngcontent-serverApp-c90="" xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 440 440"><path _ngcontent-serverApp-c90="" d="M225.57,2.08l-.69-.45a4.22,4.22,0,0,0-5.72,1.23L182.33,46.09a4,4,0,0,0,.88,5.81l9.38,6.38L173.48,97.49a4.22,4.22,0,0,0,2.45,4.19s3.55.7,4.53-1l41.92-40.56a3.62,3.62,0,0,0-1.51-5.1l-10.55-6.12L227.44,6.79A4.26,4.26,0,0,0,225.57,2.08Z" fill="#fff"></path><path _ngcontent-serverApp-c90="" d="M118.52,401.83c-62.51,0-113.37-51-113.37-113.67V214.68C5.15,152,56,101,118.52,101H342.08a24.82,24.82,0,0,1,24.76,24.83V377a24.81,24.81,0,0,1-24.76,24.82Z"></path><path _ngcontent-serverApp-c90="" d="M342.08,105.18a20.65,20.65,0,0,1,20.61,20.66V377a20.66,20.66,0,0,1-20.61,20.66H118.52C58.3,397.67,9.31,348.55,9.31,288.16V214.68c0-60.38,49-109.5,109.21-109.5H342.08m0-8.34H118.52C53.62,96.84,1,149.6,1,214.68v73.48C1,353.24,53.62,406,118.52,406H342.08A29,29,0,0,0,371,377V125.84a29,29,0,0,0-28.92-29Z" fill="#fff"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M344.69,346.23A25.84,25.84,0,1,0,335,369.87l-10.22-10.2a11.69,11.69,0,1,1,4.77-5.12l10.31,10.28A25.84,25.84,0,0,0,344.69,346.23Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M315.82,257.61a25.67,25.67,0,0,0-12.53,5.22L315,274.49a9.58,9.58,0,0,1,2.11-.73A9.72,9.72,0,1,1,309.4,283a9.4,9.4,0,0,1,.75-3.41L298.4,267.84a25.77,25.77,0,1,0,17.42-10.23Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M313,214a7.76,7.76,0,1,1,1.41,10.91,7.62,7.62,0,0,1-2.19-2.69l-18.67-.14a25.94,25.94,0,1,0,.05-7l18.64.14A7.4,7.4,0,0,1,313,214Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M341.2,144.08h-6.32c-1.67,0-3.61,1.87-3.61,4.29s1.94,4.29,3.61,4.29h6.32c1.67,0,3.61-1.87,3.61-4.29S342.87,144.08,341.2,144.08Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M301.75,144.08h-6.44c-1.67,0-3.61,1.87-3.61,4.29s1.94,4.29,3.61,4.29h6.44c1.67,0,3.61-1.87,3.61-4.29S303.42,144.08,301.75,144.08Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M321.77,144.08h-7c-1.67,0-3.62,1.87-3.62,4.29s1.95,4.29,3.62,4.29h7c1.67,0,3.62-1.87,3.62-4.29S323.44,144.08,321.77,144.08Z"></path><ellipse _ngcontent-serverApp-c90="" fill="#fff" cx="295.97" cy="127.61" rx="4.27" ry="4.29"></ellipse><path _ngcontent-serverApp-c90="" fill="#fff" d="M340.54,131.9a4.29,4.29,0,1,0-4.27-4.29A4.28,4.28,0,0,0,340.54,131.9Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M318.26,131.9a4.29,4.29,0,1,0-4.27-4.29A4.29,4.29,0,0,0,318.26,131.9Z"></path><ellipse _ngcontent-serverApp-c90="" fill="#fff" cx="295.97" cy="169.13" rx="4.27" ry="4.29"></ellipse><path _ngcontent-serverApp-c90="" fill="#fff" d="M340.54,164.84a4.3,4.3,0,1,0,4.27,4.29A4.29,4.29,0,0,0,340.54,164.84Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M318.26,164.84a4.3,4.3,0,1,0,4.28,4.29A4.29,4.29,0,0,0,318.26,164.84Z"></path><path _ngcontent-serverApp-c90="" d="M108.62,256.87c8.36-1,7.68-7.76,3.14-17-3.64-7.4-9.74-16.39-15.75-25.36-14.23-21.23-27.69-42.23-5.35-41.07,19.55,1,42.9,18.63,68.22,36.74,31.1,22.24,65.16,45.21,98.81,39.11a151.19,151.19,0,0,1,20-2.37V221a92,92,0,0,0-91.91-92.16H124.33A92,92,0,0,0,32.42,221v17.59c17.71,3.81,31,9.94,43.8,14.15C86.6,256.16,96.69,258.31,108.62,256.87Z"></path><path _ngcontent-serverApp-c90="" d="M273.37,310.79c-35-15.26-76.67-32.1-104-23.59-3.15,1-5,2.3-6,3.85-3.35,5.31,4.67,13.57,14.89,22.17,7.17,6,15.36,12.21,21.44,17.64,11.47,10.26,15.35,17.84-9.89,16.62-29.75-1.44-49.18-13.75-71.18-24l-.29-.14a165.84,165.84,0,0,0-22.93-8.91c-15.74-4.67-34.22-6.79-58.51-3.28A91.93,91.93,0,0,0,124.33,375h61.45A92,92,0,0,0,273.37,310.79Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M257.69,249.31C224,255.41,190,232.44,158.88,210.2c-25.32-18.11-48.67-35.72-68.22-36.74C68.32,172.3,81.78,193.3,96,214.53c6,9,12.11,18,15.75,25.36,4.54,9.22,5.22,16-3.14,17-11.93,1.44-22-.71-32.4-4.13-12.8-4.21-26.09-10.34-43.8-14.15v44.26c0,1.26.14,2.48.19,3.72a91.8,91.8,0,0,0,2.9,19.62c.43,1.67.84,3.34,1.37,5,24.29-3.51,42.77-1.39,58.51,3.28a165.84,165.84,0,0,1,22.93,8.91c.39-.12.76-.26,1.14-.39l-.85.53c22,10.25,41.43,22.56,71.18,24,25.24,1.22,21.36-6.36,9.89-16.62-6.08-5.43-14.27-11.61-21.44-17.64-10.22-8.6-18.24-16.86-14.89-22.17,1-1.55,2.87-2.87,6-3.85,27.33-8.51,69,8.33,104,23.59.32-1,.56-2.05.84-3.07a92.33,92.33,0,0,0,3.48-24.87V246.94A151.19,151.19,0,0,0,257.69,249.31Z"></path><path _ngcontent-serverApp-c90="" fill="#fff" d="M192,137a78,78,0,0,1,77.78,78v73.91a78,78,0,0,1-77.78,78H118.51a78,78,0,0,1-77.78-78V215a78,78,0,0,1,77.78-78H192m0-8.33H118.51A86.21,86.21,0,0,0,32.42,215v73.91a86.21,86.21,0,0,0,86.09,86.33H192a86.21,86.21,0,0,0,86.09-86.33V215A86.21,86.21,0,0,0,192,128.64Z"></path></svg></a> | ||||
|         <a href="https://mempool.chat" target="_blank"><svg fill="#fff" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Matrix</title><path d="M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z"/></svg></a> | ||||
|  | ||||
| @ -88,7 +88,14 @@ footer .row.link-tree { | ||||
| 
 | ||||
| footer .row.social-links { | ||||
|   text-align: center; | ||||
|   margin: 24px 0; | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   width: fit-content; | ||||
|   margin: 0 auto;  | ||||
| 
 | ||||
|   @media (max-width: 450px){ | ||||
|     width: 250px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| footer .row.social-links a { | ||||
| @ -97,6 +104,7 @@ footer .row.social-links a { | ||||
| 
 | ||||
| footer .row.social-links svg { | ||||
|   width: 20px; | ||||
|   margin: 10px 0 10px 0; | ||||
| } | ||||
| 
 | ||||
| footer .row.version { | ||||
| @ -189,10 +197,6 @@ footer .sponsor { | ||||
|     margin-top: 15px; | ||||
|   } | ||||
| 
 | ||||
|   footer .row.social-links { | ||||
|     margin: 48px 0 24px 0; | ||||
|   } | ||||
| 
 | ||||
|   footer .selector:not(:last-child) { | ||||
|     margin-right: 10px; | ||||
|   } | ||||
| @ -236,10 +240,6 @@ footer .sponsor { | ||||
|     margin-top: 15px; | ||||
|   } | ||||
| 
 | ||||
|   footer .services.row.social-links { | ||||
|     margin: 48px 0 24px 0; | ||||
|   } | ||||
| 
 | ||||
|   footer .services.selector:not(:last-child) { | ||||
|     margin-right: 10px; | ||||
|   } | ||||
|  | ||||
| @ -1,6 +1,19 @@ | ||||
| var https = require('https'); | ||||
| var fs = require('fs'); | ||||
| var crypto = require('crypto'); | ||||
| var path = require('node:path'); | ||||
| const LOG_TAG = '[sync-assets]'; | ||||
| let verbose = false; | ||||
| 
 | ||||
| if (parseInt(process.env.SKIP_SYNC) === 1) { | ||||
|   console.log(`${LOG_TAG} SKIP_SYNC is set, not checking any assets`); | ||||
|   process.exit(0); | ||||
| } | ||||
| 
 | ||||
| if (parseInt(process.env.VERBOSE) === 1) { | ||||
|   console.log(`${LOG_TAG} VERBOSE is set, logs will be more verbose`); | ||||
|   verbose = true; | ||||
| } | ||||
| 
 | ||||
| const CONFIG_FILE_NAME = 'mempool-frontend-config.json'; | ||||
| let configContent = {}; | ||||
| @ -8,6 +21,13 @@ let configContent = {}; | ||||
| var PATH; | ||||
| if (process.argv[2]) { | ||||
|   PATH = process.argv[2]; | ||||
|   PATH += PATH.endsWith("/") ? "" : "/" | ||||
|   PATH = path.normalize(PATH); | ||||
|   console.log(`[sync-assets] using PATH ${PATH}`); | ||||
|   if (!fs.existsSync(PATH)){ | ||||
|     console.log(`${LOG_TAG} ${PATH} does not exist, creating`); | ||||
|     fs.mkdirSync(PATH, { recursive: true }); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| if (!PATH) { | ||||
| @ -17,12 +37,12 @@ if (!PATH) { | ||||
| try { | ||||
|   const rawConfig = fs.readFileSync(CONFIG_FILE_NAME); | ||||
|   configContent = JSON.parse(rawConfig); | ||||
|   console.log(`${CONFIG_FILE_NAME} file found, using provided config`); | ||||
|   console.log(`${LOG_TAG} ${CONFIG_FILE_NAME} file found, using provided config`); | ||||
| } catch (e) { | ||||
|   if (e.code !== 'ENOENT') { | ||||
|     throw new Error(e); | ||||
|   } else { | ||||
|     console.log(`${CONFIG_FILE_NAME} file not found, using default config`); | ||||
|     console.log(`${LOG_TAG} ${CONFIG_FILE_NAME} file not found, using default config`); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -37,6 +57,11 @@ function download(filename, url) { | ||||
|   }) | ||||
|   .on('error', function(e) { | ||||
|     throw new Error(e); | ||||
|   }) | ||||
|   .on('finish', () => { | ||||
|     if (verbose) { | ||||
|       console.log(`${LOG_TAG} Finished downloading ${url} to ${filename}`); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| @ -44,12 +69,18 @@ function getLocalHash(filePath) { | ||||
|   const size = fs.statSync(filePath); | ||||
|   const buffer = fs.readFileSync(filePath); | ||||
|   const bufferWithHeader = Buffer.concat([Buffer.from('blob '), Buffer.from(`${size.size}`), Buffer.from('\0'), buffer]); | ||||
|   return crypto.createHash('sha1').update(bufferWithHeader).digest('hex'); | ||||
|   const hash = crypto.createHash('sha1').update(bufferWithHeader).digest('hex'); | ||||
| 
 | ||||
|   if (verbose) { | ||||
|     console.log(`${LOG_TAG} \tgetLocalHash ${filePath} ${hash}`); | ||||
|   } | ||||
| 
 | ||||
|   return hash; | ||||
| } | ||||
| 
 | ||||
| function downloadMiningPoolLogos$() { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     console.log('Checking if mining pool logos needs downloading or updating...'); | ||||
|     console.log(`${LOG_TAG} Checking if mining pool logos needs downloading or updating...`); | ||||
|     const options = { | ||||
|       host: 'api.github.com', | ||||
|       path: '/repos/mempool/mining-pool-logos/contents/', | ||||
| @ -58,7 +89,7 @@ function downloadMiningPoolLogos$() { | ||||
|     }; | ||||
| 
 | ||||
|     if (githubSecret) { | ||||
|       console.log('Downloading the mining pool logos with authentication'); | ||||
|       console.log(`${LOG_TAG} Downloading the mining pool logos with authentication`); | ||||
|       options.headers['authorization'] = `Bearer ${githubSecret}`; | ||||
|       options.headers['X-GitHub-Api-Version'] = '2022-11-28'; | ||||
|     } | ||||
| @ -79,21 +110,29 @@ function downloadMiningPoolLogos$() { | ||||
|           } | ||||
|           let downloadedCount = 0; | ||||
|           for (const poolLogo of poolLogos) { | ||||
|             const filePath = `${PATH}/mining-pools/${poolLogo.name}`; | ||||
|             const filePath = PATH + `mining-pools/${poolLogo.name}`; | ||||
|             if (fs.existsSync(filePath)) { | ||||
|               const localHash = getLocalHash(filePath); | ||||
|               if (verbose) { | ||||
|                 console.log(`${LOG_TAG} Remote ${poolLogo.name} logo hash ${poolLogo.sha}`); | ||||
|                 console.log(`${LOG_TAG} \tchecking if ${filePath} exists: ${fs.existsSync(filePath)}`); | ||||
|               } | ||||
|               if (localHash !== poolLogo.sha) { | ||||
|                 console.log(`${poolLogo.name} is different on the remote, downloading...`); | ||||
|                 console.log(`${LOG_TAG} \t\t${poolLogo.name} is different on the remote, downloading...`); | ||||
|                 download(filePath, poolLogo.download_url); | ||||
|                 downloadedCount++; | ||||
|               } | ||||
|             } else { | ||||
|               console.log(`${poolLogo.name} is missing, downloading...`); | ||||
|               console.log(`${LOG_TAG} ${poolLogo.name} is missing, downloading...`); | ||||
|               const miningPoolsDir = PATH + `mining-pools/`; | ||||
|               if (!fs.existsSync(miningPoolsDir)){ | ||||
|                 fs.mkdirSync(miningPoolsDir, { recursive: true }); | ||||
|               } | ||||
|               download(filePath, poolLogo.download_url); | ||||
|               downloadedCount++; | ||||
|             } | ||||
|           } | ||||
|           console.log(`Downloaded ${downloadedCount} and skipped ${poolLogos.length - downloadedCount} existing mining pool logos`); | ||||
|           console.log(`${LOG_TAG} Downloaded ${downloadedCount} and skipped ${poolLogos.length - downloadedCount} existing mining pool logos`); | ||||
|           resolve(); | ||||
|         } catch (e) { | ||||
|           reject(`Unable to download mining pool logos. Trying again at next restart. Reason: ${e instanceof Error ? e.message : e}`); | ||||
| @ -109,7 +148,7 @@ function downloadMiningPoolLogos$() { | ||||
| 
 | ||||
| function downloadPromoVideoSubtiles$() { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     console.log('Checking if promo video subtitles needs downloading or updating...'); | ||||
|     console.log(`${LOG_TAG} Checking if promo video subtitles needs downloading or updating...`); | ||||
|     const options = { | ||||
|       host: 'api.github.com', | ||||
|       path: '/repos/mempool/mempool-promo/contents/subtitles', | ||||
| @ -118,7 +157,7 @@ function downloadPromoVideoSubtiles$() { | ||||
|     }; | ||||
| 
 | ||||
|     if (githubSecret) { | ||||
|       console.log('Downloading the promo video subtitles with authentication'); | ||||
|       console.log(`${LOG_TAG} Downloading the promo video subtitles with authentication`); | ||||
|       options.headers['authorization'] = `Bearer ${githubSecret}`; | ||||
|       options.headers['X-GitHub-Api-Version'] = '2022-11-28'; | ||||
|     } | ||||
| @ -140,21 +179,30 @@ function downloadPromoVideoSubtiles$() { | ||||
|           } | ||||
|           let downloadedCount = 0; | ||||
|           for (const language of videoLanguages) { | ||||
|             const filePath = `${PATH}/promo-video/${language.name}`; | ||||
|             const filePath = PATH + `promo-video/${language.name}`; | ||||
|             if (fs.existsSync(filePath)) { | ||||
|               if (verbose) { | ||||
|                 console.log(`${LOG_TAG} ${language.name} remote promo video hash ${language.sha}`); | ||||
|               } | ||||
|               const localHash = getLocalHash(filePath); | ||||
| 
 | ||||
|               if (localHash !== language.sha) { | ||||
|                 console.log(`${language.name} is different on the remote, updating`); | ||||
|                 console.log(`${LOG_TAG} ${language.name} is different on the remote, updating`); | ||||
|                 download(filePath, language.download_url); | ||||
|                 downloadedCount++; | ||||
|               } | ||||
|             } else { | ||||
|               console.log(`${language.name} is missing, downloading`); | ||||
|               console.log(`${LOG_TAG} ${language.name} is missing, downloading`); | ||||
|               const promoVideosDir = PATH + `promo-video/`; | ||||
|               if (!fs.existsSync(promoVideosDir)){ | ||||
|                 fs.mkdirSync(promoVideosDir, { recursive: true }); | ||||
|               } | ||||
| 
 | ||||
|               download(filePath, language.download_url); | ||||
|               downloadedCount++; | ||||
|             } | ||||
|           } | ||||
|           console.log(`Downloaded ${downloadedCount} and skipped ${videoLanguages.length - downloadedCount} existing video subtitles`); | ||||
|           console.log(`${LOG_TAG} Downloaded ${downloadedCount} and skipped ${videoLanguages.length - downloadedCount} existing video subtitles`); | ||||
|           resolve(); | ||||
|         } catch (e) { | ||||
|           reject(`Unable to download video subtitles. Trying again at next restart. Reason: ${e instanceof Error ? e.message : e}`); | ||||
| @ -170,7 +218,7 @@ function downloadPromoVideoSubtiles$() { | ||||
| 
 | ||||
| function downloadPromoVideo$() { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     console.log('Checking if promo video needs downloading or updating...'); | ||||
|     console.log(`${LOG_TAG} Checking if promo video needs downloading or updating...`); | ||||
|     const options = { | ||||
|       host: 'api.github.com', | ||||
|       path: '/repos/mempool/mempool-promo/contents', | ||||
| @ -179,7 +227,7 @@ function downloadPromoVideo$() { | ||||
|     }; | ||||
| 
 | ||||
|     if (githubSecret) { | ||||
|       console.log('Downloading the promo videos with authentication'); | ||||
|       console.log(`${LOG_TAG} Downloading the promo video with authentication`); | ||||
|       options.headers['authorization'] = `Bearer ${githubSecret}`; | ||||
|       options.headers['X-GitHub-Api-Version'] = '2022-11-28'; | ||||
|     } | ||||
| @ -202,18 +250,19 @@ function downloadPromoVideo$() { | ||||
|             if (item.name !== 'promo.mp4') { | ||||
|               continue; | ||||
|             } | ||||
|             const filePath = `${PATH}/promo-video/mempool-promo.mp4`; | ||||
|             const filePath = PATH + `promo-video/mempool-promo.mp4`; | ||||
|             if (fs.existsSync(filePath)) { | ||||
|               const localHash = getLocalHash(filePath); | ||||
| 
 | ||||
|               if (localHash !== item.sha) { | ||||
|                 console.log(`mempool-promo.mp4 is different on the remote, updating`); | ||||
|                 console.log(`${LOG_TAG} \tmempool-promo.mp4 is different on the remote, updating`); | ||||
|                 download(filePath, item.download_url); | ||||
|                 console.log('mempool-promo.mp4 downloaded.'); | ||||
|                 console.log(`${LOG_TAG} \tmempool-promo.mp4 downloaded.`); | ||||
|               } else { | ||||
|                 console.log(`mempool-promo.mp4 is already up to date. Skipping.`); | ||||
|                 console.log(`${LOG_TAG} \tmempool-promo.mp4 is already up to date. Skipping.`); | ||||
|               } | ||||
|             } else { | ||||
|               console.log(`mempool-promo.mp4 is missing, downloading`); | ||||
|               console.log(`${LOG_TAG} \tmempool-promo.mp4 is missing, downloading`); | ||||
|               download(filePath, item.download_url); | ||||
|             } | ||||
|           } | ||||
| @ -232,30 +281,47 @@ function downloadPromoVideo$() { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| let assetsJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.json'; | ||||
| let assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.minimal.json'; | ||||
| 
 | ||||
| if (configContent.BASE_MODULE && configContent.BASE_MODULE === 'liquid') { | ||||
|   assetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.json'; | ||||
|   assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.minimal.json'; | ||||
|   const assetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.json'; | ||||
|   const assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.minimal.json'; | ||||
|   const testnetAssetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.json'; | ||||
|   const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.minimal.json'; | ||||
| 
 | ||||
|   console.log(`${LOG_TAG} Downloading assets`); | ||||
|   download(PATH + 'assets.json', assetsJsonUrl); | ||||
| 
 | ||||
|   console.log(`${LOG_TAG} Downloading assets minimal`); | ||||
|   download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl); | ||||
| 
 | ||||
|   console.log(`${LOG_TAG} Downloading testnet assets`); | ||||
|   download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl); | ||||
| 
 | ||||
|   console.log(`${LOG_TAG} Downloading testnet assets minimal`); | ||||
|   download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl); | ||||
| } else { | ||||
|   if (verbose) { | ||||
|     console.log(`${LOG_TAG} BASE_MODULE is not set to Liquid (${configContent.BASE_MODULE}), skipping downloading assets`); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const testnetAssetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.json'; | ||||
| const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.minimal.json'; | ||||
| 
 | ||||
| console.log('Downloading assets'); | ||||
| download(PATH + 'assets.json', assetsJsonUrl); | ||||
| console.log('Downloading assets minimal'); | ||||
| download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl); | ||||
| console.log('Downloading testnet assets'); | ||||
| download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl); | ||||
| console.log('Downloading testnet assets minimal'); | ||||
| download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl); | ||||
| 
 | ||||
| downloadMiningPoolLogos$() | ||||
|   .then(() => downloadPromoVideoSubtiles$()) | ||||
|   .then(() => downloadPromoVideo$()) | ||||
| (() => { | ||||
|   if (verbose) { | ||||
|     console.log(`${LOG_TAG} Downloading mining pool logos`); | ||||
|   } | ||||
|   downloadMiningPoolLogos$() | ||||
|   .then(() => { | ||||
|     if (verbose) { | ||||
|       console.log(`${LOG_TAG} Downloading promo video subtitles`); | ||||
|     } | ||||
|     downloadPromoVideoSubtiles$(); | ||||
|   }) | ||||
|   .then(() => { | ||||
|     if (verbose) { | ||||
|       console.log(`${LOG_TAG} Downloading promo video`); | ||||
|     } | ||||
|     downloadPromoVideo$(); | ||||
|   }) | ||||
|   .catch((error) => { | ||||
|     throw new Error(error); | ||||
|   }); | ||||
| })(); | ||||
| @ -332,7 +332,7 @@ BITCOIN_REPO_URL=https://github.com/bitcoin/bitcoin | ||||
| BITCOIN_REPO_NAME=bitcoin | ||||
| BITCOIN_REPO_BRANCH=master | ||||
| #BITCOIN_LATEST_RELEASE=$(curl -s https://api.github.com/repos/bitcoin/bitcoin/releases/latest|grep tag_name|head -1|cut -d '"' -f4) | ||||
| BITCOIN_LATEST_RELEASE=v25.0 | ||||
| BITCOIN_LATEST_RELEASE=v25.1 | ||||
| echo -n '.' | ||||
| 
 | ||||
| BISQ_REPO_URL=https://github.com/bisq-network/bisq | ||||
| @ -1046,8 +1046,8 @@ echo "[*] Installing nvm.sh from GitHub" | ||||
| osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh' | ||||
| 
 | ||||
| echo "[*] Building NodeJS v20.5.1 via nvm.sh" | ||||
| osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.5.1 --shared-zlib' | ||||
| osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 20.5.1' | ||||
| osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.7.0 --shared-zlib' | ||||
| osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 20.7.0' | ||||
| 
 | ||||
| #################### | ||||
| # Tor installation # | ||||
| @ -1489,7 +1489,7 @@ EOF | ||||
|             osSudo "${UNFURL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh' | ||||
| 
 | ||||
|             echo "[*] Building NodeJS via nvm.sh" | ||||
|             osSudo "${UNFURL_USER}" zsh -c 'source ~/.zshrc ; nvm install v16.16.0 --shared-zlib' | ||||
|             osSudo "${UNFURL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.7.0 --shared-zlib' | ||||
| 
 | ||||
|         ;; | ||||
|     esac | ||||
| @ -1660,15 +1660,15 @@ case $OS in | ||||
|         crontab_bitcoin=() | ||||
|         if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then | ||||
|             echo "[*] Installing Electrs Mainnet Cronjob" | ||||
|             crontab_bitcoin+="@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/electrs-start-mainnet\n" | ||||
|             crontab_bitcoin+="@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/start mainnet\n" | ||||
|         fi | ||||
|         if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then | ||||
|             echo "[*] Installing Electrs Testnet Cronjob" | ||||
|             crontab_bitcoin+="@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/electrs-start-testnet\n" | ||||
|             crontab_bitcoin+="@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/start testnet\n" | ||||
|         fi | ||||
|         if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then | ||||
|             echo "[*] Installing Electrs Signet Cronjob" | ||||
|             crontab_bitcoin+="@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/electrs-start-signet\n" | ||||
|             crontab_bitcoin+="@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/start signet\n" | ||||
|         fi | ||||
|         if [ "${BITCOIN_MAINNET_ENABLE}" = ON -o "${BITCOIN_TESTNET_ENABLE}" = ON -o "${BITCOIN_SIGNET_ENABLE}" = ON ];then | ||||
|             echo "${crontab_bitcoin}" | crontab -u "${BITCOIN_USER}" - | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #!/usr/bin/env zsh | ||||
| export NVM_DIR="$HOME/.nvm" | ||||
| source "$NVM_DIR/nvm.sh" | ||||
| nvm use v20.5.1 | ||||
| nvm use v20.7.0 | ||||
| 
 | ||||
| # start all mempool backends that exist | ||||
| for site in mainnet mainnet-lightning testnet testnet-lightning signet signet-lightning bisq liquid liquidtestnet;do | ||||
|  | ||||
| @ -5,3 +5,4 @@ proxy_cache_path /var/cache/nginx/slurper keys_zone=slurper:20m levels=1:2 inact | ||||
| proxy_cache_path /var/cache/nginx/services keys_zone=services:20m levels=1:2 inactive=365d max_size=100m; | ||||
| proxy_cache_path /var/cache/nginx/markets keys_zone=markets:20m levels=1:2 inactive=365d max_size=100m; | ||||
| types_hash_max_size 4096; | ||||
| proxy_buffer_size 8k; | ||||
							
								
								
									
										7
									
								
								scripts/get_backend_hash.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								scripts/get_backend_hash.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| for LOCATION in fmt va1 fra tk7 | ||||
| do | ||||
|   for NODE in 201 202 203 204 205 206 | ||||
|   do | ||||
|     echo $(curl -sk https://node$NODE.$LOCATION.mempool.space/api/v1/backend-info) | ||||
|   done | ||||
| done | ||||
| @ -1,4 +1,16 @@ | ||||
| const configFile = require('../config.json'); | ||||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
| 
 | ||||
| const configPath = process.env.UNFURLER_CONFIG || './config.json'; | ||||
| const absolutePath = path.resolve(configPath); | ||||
| let config; | ||||
| 
 | ||||
| try { | ||||
|   config = JSON.parse(fs.readFileSync(absolutePath, 'utf8')); | ||||
| } catch (e) { | ||||
|   console.error(`Could not read config file ${absolutePath}: ${e}`); | ||||
|   process.exit(-1); | ||||
| } | ||||
| 
 | ||||
| interface IConfig { | ||||
|   SERVER: { | ||||
| @ -57,7 +69,7 @@ class Config implements IConfig { | ||||
|   SYSLOG: IConfig['SYSLOG']; | ||||
| 
 | ||||
|   constructor() { | ||||
|     const configs = this.merge(configFile, defaults); | ||||
|     const configs = this.merge(config, defaults); | ||||
|     this.SERVER = configs.SERVER; | ||||
|     this.MEMPOOL = configs.MEMPOOL; | ||||
|     this.PUPPETEER = configs.PUPPETEER; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user