diff --git a/backend/package-lock.json b/backend/package-lock.json index 686e221e3..ce3a8ff68 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -17,9 +17,9 @@ "express": "^4.18.0", "mysql2": "2.3.3", "node-worker-threads-pool": "^1.5.1", - "socks-proxy-agent": "^6.2.0", - "typescript": "~4.7.2", - "ws": "~8.7.0" + "socks-proxy-agent": "~7.0.0", + "typescript": "~4.7.4", + "ws": "~8.8.0" }, "devDependencies": { "@types/compression": "^1.7.2", @@ -2734,9 +2734,9 @@ } }, "node_modules/socks-proxy-agent": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", - "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -2950,9 +2950,9 @@ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, "node_modules/typescript": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", - "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3052,9 +3052,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", - "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", + "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "engines": { "node": ">=10.0.0" }, @@ -5098,9 +5098,9 @@ } }, "socks-proxy-agent": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", - "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "requires": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -5256,9 +5256,9 @@ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, "typescript": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", - "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==" + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "unpipe": { "version": "1.0.0", @@ -5333,9 +5333,9 @@ "dev": true }, "ws": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", - "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", + "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "requires": {} }, "yallist": { diff --git a/backend/package.json b/backend/package.json index ba5d8ad1f..c5cd4380c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -37,9 +37,9 @@ "express": "^4.18.0", "mysql2": "2.3.3", "node-worker-threads-pool": "^1.5.1", - "socks-proxy-agent": "^6.2.0", - "typescript": "~4.7.2", - "ws": "~8.7.0" + "socks-proxy-agent": "~7.0.0", + "typescript": "~4.7.4", + "ws": "~8.8.0" }, "devDependencies": { "@types/compression": "^1.7.2", diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 4043a9276..631940dd2 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -295,7 +295,8 @@ class Blocks { } logger.notice(`Blocks summaries indexing completed: indexed ${newlyIndexed} blocks`); } catch (e) { - logger.err(`Blocks summaries indexing failed. Reason: ${(e instanceof Error ? e.message : e)}`); + logger.err(`Blocks summaries indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); + throw e; } } @@ -367,18 +368,12 @@ class Blocks { logger.notice(`Block indexing completed: indexed ${newlyIndexed} blocks`); loadingIndicators.setProgress('block-indexing', 100); } catch (e) { - logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e)); + logger.err('Block indexing failed. Trying again in 10 seconds. Reason: ' + (e instanceof Error ? e.message : e)); loadingIndicators.setProgress('block-indexing', 100); - return false; + throw e; } - const chainValid = await BlocksRepository.$validateChain(); - if (!chainValid) { - indexer.reindex(); - return false; - } - - return true; + return await BlocksRepository.$validateChain(); } public async $updateBlocks() { diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 8d9959cf2..c4107e426 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -4,7 +4,7 @@ import logger from '../logger'; import { Common } from './common'; class DatabaseMigration { - private static currentVersion = 22; + private static currentVersion = 24; private queryTimeout = 120000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -231,6 +231,23 @@ class DatabaseMigration { await this.$executeQuery('DROP TABLE IF EXISTS `difficulty_adjustments`'); await this.$executeQuery(this.getCreateDifficultyAdjustmentsTableQuery(), await this.$checkIfTableExists('difficulty_adjustments')); } + + if (databaseSchemaVersion < 23) { + await this.$executeQuery('TRUNCATE `prices`'); + await this.$executeQuery('ALTER TABLE `prices` DROP `avg_prices`'); + await this.$executeQuery('ALTER TABLE `prices` ADD `USD` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `EUR` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `GBP` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `CAD` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `CHF` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `AUD` float DEFAULT "0"'); + await this.$executeQuery('ALTER TABLE `prices` ADD `JPY` float DEFAULT "0"'); + } + + if (databaseSchemaVersion < 24 && isBitcoin == true) { + await this.$executeQuery('DROP TABLE IF EXISTS `blocks_audits`'); + await this.$executeQuery(this.getCreateBlocksAuditsTableQuery(), await this.$checkIfTableExists('blocks_audits')); + } } catch (e) { throw e; } @@ -555,6 +572,19 @@ class DatabaseMigration { ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; } + private getCreateBlocksAuditsTableQuery(): string { + return `CREATE TABLE IF NOT EXISTS blocks_audits ( + time timestamp NOT NULL, + hash varchar(65) NOT NULL, + height int(10) unsigned NOT NULL, + missing_txs JSON NOT NULL, + added_txs JSON NOT NULL, + match_rate float unsigned NOT NULL, + PRIMARY KEY (hash), + INDEX (height) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; + } + public async $truncateIndexedData(tables: string[]) { const allowedTables = ['blocks', 'hashrates', 'prices']; diff --git a/backend/src/api/mining.ts b/backend/src/api/mining.ts index 672f0970f..e9fe6bae7 100644 --- a/backend/src/api/mining.ts +++ b/backend/src/api/mining.ts @@ -7,12 +7,25 @@ import logger from '../logger'; import { Common } from './common'; import loadingIndicators from './loading-indicators'; import { escape } from 'mysql2'; +import indexer from '../indexer'; import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; +import config from '../config'; +import BlocksAuditsRepository from '../repositories/BlocksAuditsRepository'; class Mining { constructor() { } + /** + * Get historical block predictions match rate + */ + public async $getBlockPredictionsHistory(interval: string | null = null): Promise { + return await BlocksAuditsRepository.$getBlockPredictionsHistory( + this.getTimeRange(interval), + Common.getSqlInterval(interval) + ); + } + /** * Get historical block total fee */ @@ -263,6 +276,7 @@ class Mining { loadingIndicators.setProgress('weekly-hashrate-indexing', 100); } catch (e) { loadingIndicators.setProgress('weekly-hashrate-indexing', 100); + logger.err(`Weekly mining pools hashrates indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); throw e; } } @@ -302,7 +316,7 @@ class Mining { while (toTimestamp > genesisTimestamp) { const fromTimestamp = toTimestamp - 86400000; - // Skip already indexed weeks + // Skip already indexed days if (indexedTimestamp.includes(toTimestamp / 1000)) { toTimestamp -= 86400000; ++totalIndexed; @@ -313,7 +327,7 @@ class Mining { // we are currently indexing has complete data) const blockStatsPreviousDay: any = await BlocksRepository.$blockCountBetweenTimestamp( null, (fromTimestamp - 86400000) / 1000, (toTimestamp - 86400000) / 1000); - if (blockStatsPreviousDay.blockCount === 0) { // We are done indexing + if (blockStatsPreviousDay.blockCount === 0 && config.MEMPOOL.NETWORK === 'mainnet') { // We are done indexing break; } @@ -357,9 +371,10 @@ class Mining { // Add genesis block manually if (toTimestamp <= genesisTimestamp && !indexedTimestamp.includes(genesisTimestamp)) { hashrates.push({ - hashrateTimestamp: genesisTimestamp, + hashrateTimestamp: genesisTimestamp / 1000, avgHashrate: await bitcoinClient.getNetworkHashPs(1, 1), - poolId: null, + poolId: 0, + share: 1, type: 'daily', }); } @@ -374,6 +389,7 @@ class Mining { loadingIndicators.setProgress('daily-hashrate-indexing', 100); } catch (e) { loadingIndicators.setProgress('daily-hashrate-indexing', 100); + logger.err(`Daily network hashrate indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); throw e; } } @@ -393,6 +409,15 @@ class Mining { let currentDifficulty = 0; let totalIndexed = 0; + if (indexedHeights[0] === false) { + await DifficultyAdjustmentsRepository.$saveAdjustments({ + time: 1231006505, + height: 0, + difficulty: 1.0, + adjustment: 0.0, + }); + } + for (const block of blocks) { if (block.difficulty !== currentDifficulty) { if (block.height === 0 || indexedHeights[block.height] === true) { // Already indexed diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index 3c5b830cc..300341ef5 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -16,6 +16,7 @@ import transactionUtils from './transaction-utils'; import rbfCache from './rbf-cache'; import difficultyAdjustment from './difficulty-adjustment'; import feeApi from './fee-api'; +import BlocksAuditsRepository from '../repositories/BlocksAuditsRepository'; class WebsocketHandler { private wss: WebSocket.Server | undefined; @@ -416,17 +417,40 @@ class WebsocketHandler { if (_mempoolBlocks[0]) { const matches: string[] = []; + const added: string[] = []; + const missing: string[] = []; + for (const txId of txIds) { if (_mempoolBlocks[0].transactionIds.indexOf(txId) > -1) { matches.push(txId); + } else { + added.push(txId); } delete _memPool[txId]; } - matchRate = Math.round((matches.length / (txIds.length - 1)) * 100); + for (const txId of _mempoolBlocks[0].transactionIds) { + if (matches.includes(txId) || added.includes(txId)) { + continue; + } + missing.push(txId); + } + + matchRate = Math.round((Math.max(0, matches.length - missing.length - added.length) / txIds.length * 100) * 100) / 100; mempoolBlocks.updateMempoolBlocks(_memPool); mBlocks = mempoolBlocks.getMempoolBlocks(); mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas(); + + if (Common.indexingEnabled()) { + BlocksAuditsRepository.$saveAudit({ + time: block.timestamp, + height: block.height, + hash: block.id, + addedTxs: added, + missingTxs: missing, + matchRate: matchRate, + }); + } } if (block.extras) { diff --git a/backend/src/index.ts b/backend/src/index.ts index 28215945f..ff0209294 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -28,6 +28,7 @@ import { Common } from './api/common'; import poolsUpdater from './tasks/pools-updater'; import indexer from './indexer'; import priceUpdater from './tasks/price-updater'; +import BlocksAuditsRepository from './repositories/BlocksAuditsRepository'; class Server { private wss: WebSocket.Server | undefined; @@ -285,12 +286,14 @@ class Server { .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug', routes.$getPool) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools/:interval', routes.$getPoolsHistoricalHashrate) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/:interval', routes.$getHistoricalHashrate) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments', routes.$getDifficultyAdjustments) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/reward-stats/:blockCount', routes.$getRewardStats) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fees/:interval', routes.$getHistoricalBlockFees) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/rewards/:interval', routes.$getHistoricalBlockRewards) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fee-rates/:interval', routes.$getHistoricalBlockFeeRates) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/sizes-weights/:interval', routes.$getHistoricalBlockSizeAndWeight) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments/:interval', routes.$getDifficultyAdjustments) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/predictions/:interval', routes.$getHistoricalBlockPrediction) ; } diff --git a/backend/src/indexer.ts b/backend/src/indexer.ts index 48bae00e4..8e4e7e87f 100644 --- a/backend/src/indexer.ts +++ b/backend/src/indexer.ts @@ -39,6 +39,8 @@ class Indexer { const chainValid = await blocks.$generateBlockDatabase(); if (chainValid === false) { // Chain of block hash was invalid, so we need to reindex. Stop here and continue at the next iteration + logger.warn(`The chain of block hash is invalid, re-indexing invalid data in 10 seconds.`); + setTimeout(() => this.reindex(), 10000); this.indexerRunning = false; return; } @@ -49,8 +51,9 @@ class Indexer { await mining.$generatePoolHashrateHistory(); await blocks.$generateBlocksSummariesDatabase(); } catch (e) { - this.reindex(); - logger.err(`Indexer failed, trying again later. Reason: ` + (e instanceof Error ? e.message : e)); + this.indexerRunning = false; + logger.err(`Indexer failed, trying again in 10 seconds. Reason: ` + (e instanceof Error ? e.message : e)); + setTimeout(() => this.reindex(), 10000); } this.indexerRunning = false; @@ -62,6 +65,7 @@ class Indexer { await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', 0); } catch (e) { logger.err(`Cannot reset hashrate indexing timestamps. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; } } } diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 983434564..477c6a920 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -22,6 +22,15 @@ export interface PoolStats extends PoolInfo { emptyBlocks: number; } +export interface BlockAudit { + time: number, + height: number, + hash: string, + missingTxs: string[], + addedTxs: string[], + matchRate: number, +} + export interface MempoolBlock { blockSize: number; blockVSize: number; diff --git a/backend/src/repositories/BlocksAuditsRepository.ts b/backend/src/repositories/BlocksAuditsRepository.ts new file mode 100644 index 000000000..31d8ec785 --- /dev/null +++ b/backend/src/repositories/BlocksAuditsRepository.ts @@ -0,0 +1,51 @@ +import DB from '../database'; +import logger from '../logger'; +import { BlockAudit } from '../mempool.interfaces'; + +class BlocksAuditRepositories { + public async $saveAudit(audit: BlockAudit): Promise { + try { + await DB.query(`INSERT INTO blocks_audits(time, height, hash, missing_txs, added_txs, match_rate) + VALUE (FROM_UNIXTIME(?), ?, ?, ?, ?, ?)`, [audit.time, audit.height, audit.hash, JSON.stringify(audit.missingTxs), + JSON.stringify(audit.addedTxs), audit.matchRate]); + } catch (e: any) { + if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart + logger.debug(`Cannot save block audit for block ${audit.hash} because it has already been indexed, ignoring`); + } else { + logger.err(`Cannot save block audit into db. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + } + + public async $getBlockPredictionsHistory(div: number, interval: string | null): Promise { + try { + let query = `SELECT UNIX_TIMESTAMP(time) as time, height, match_rate FROM blocks_audits`; + + if (interval !== null) { + query += ` WHERE time BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`; + } + + query += ` GROUP BY UNIX_TIMESTAMP(time) DIV ${div} ORDER BY height`; + + const [rows] = await DB.query(query); + return rows; + } catch (e: any) { + logger.err(`Cannot fetch block prediction history. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + + public async $getPredictionsCount(): Promise { + try { + const [rows] = await DB.query(`SELECT count(hash) as count FROM blocks_audits`); + return rows[0].count; + } catch (e: any) { + logger.err(`Cannot fetch block prediction history. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } +} + +export default new BlocksAuditRepositories(); + diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts index e88ac7877..c6b14ff51 100644 --- a/backend/src/repositories/BlocksRepository.ts +++ b/backend/src/repositories/BlocksRepository.ts @@ -436,7 +436,7 @@ class BlocksRepository { } if (blocks[idx].previous_block_hash !== blocks[idx - 1].hash) { - logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}, re-indexing newer blocks and hashrates`); + logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}`); await this.$deleteBlocksFrom(blocks[idx - 1].height); await BlocksSummariesRepository.$deleteBlocksFrom(blocks[idx - 1].height); await HashratesRepository.$deleteHashratesFromTimestamp(blocks[idx - 1].timestamp - 604800); diff --git a/backend/src/repositories/DifficultyAdjustmentsRepository.ts b/backend/src/repositories/DifficultyAdjustmentsRepository.ts index 76324b5e6..6952b3be9 100644 --- a/backend/src/repositories/DifficultyAdjustmentsRepository.ts +++ b/backend/src/repositories/DifficultyAdjustmentsRepository.ts @@ -1,4 +1,5 @@ import { Common } from '../api/common'; +import config from '../config'; import DB from '../database'; import logger from '../logger'; import { IndexedDifficultyAdjustment } from '../mempool.interfaces'; @@ -31,13 +32,19 @@ class DifficultyAdjustmentsRepository { public async $getAdjustments(interval: string | null, descOrder: boolean = false): Promise { interval = Common.getSqlInterval(interval); - let query = `SELECT UNIX_TIMESTAMP(time) as time, height, difficulty, adjustment + let query = `SELECT + CAST(AVG(UNIX_TIMESTAMP(time)) as INT) as time, + CAST(AVG(height) AS INT) as height, + CAST(AVG(difficulty) as DOUBLE) as difficulty, + CAST(AVG(adjustment) as DOUBLE) as adjustment FROM difficulty_adjustments`; if (interval) { query += ` WHERE time BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`; } + query += ` GROUP BY UNIX_TIMESTAMP(time) DIV ${86400}`; + if (descOrder === true) { query += ` ORDER BY time DESC`; } else { diff --git a/backend/src/repositories/HashratesRepository.ts b/backend/src/repositories/HashratesRepository.ts index 531b6cdcf..5e6048abc 100644 --- a/backend/src/repositories/HashratesRepository.ts +++ b/backend/src/repositories/HashratesRepository.ts @@ -1,5 +1,6 @@ import { escape } from 'mysql2'; import { Common } from '../api/common'; +import config from '../config'; import DB from '../database'; import logger from '../logger'; import PoolsRepository from './PoolsRepository'; @@ -32,7 +33,9 @@ class HashratesRepository { public async $getNetworkDailyHashrate(interval: string | null): Promise { interval = Common.getSqlInterval(interval); - let query = `SELECT UNIX_TIMESTAMP(hashrate_timestamp) as timestamp, avg_hashrate as avgHashrate + let query = `SELECT + CAST(AVG(UNIX_TIMESTAMP(hashrate_timestamp)) as INT) as timestamp, + CAST(AVG(avg_hashrate) as DOUBLE) as avgHashrate FROM hashrates`; if (interval) { @@ -42,6 +45,7 @@ class HashratesRepository { query += ` WHERE hashrates.type = 'daily'`; } + query += ` GROUP BY UNIX_TIMESTAMP(hashrate_timestamp) DIV ${86400}`; query += ` ORDER by hashrate_timestamp`; try { @@ -75,6 +79,9 @@ class HashratesRepository { interval = Common.getSqlInterval(interval); const topPoolsId = (await PoolsRepository.$getPoolsInfo('1w')).map((pool) => pool.poolId); + if (topPoolsId.length === 0) { + return []; + } let query = `SELECT UNIX_TIMESTAMP(hashrate_timestamp) as timestamp, avg_hashrate as avgHashrate, share, pools.name as poolName FROM hashrates diff --git a/backend/src/repositories/PricesRepository.ts b/backend/src/repositories/PricesRepository.ts index d6eaf523a..61d092ca6 100644 --- a/backend/src/repositories/PricesRepository.ts +++ b/backend/src/repositories/PricesRepository.ts @@ -5,7 +5,11 @@ import { Prices } from '../tasks/price-updater'; class PricesRepository { public async $savePrices(time: number, prices: Prices): Promise { try { - await DB.query(`INSERT INTO prices(time, avg_prices) VALUE (FROM_UNIXTIME(?), ?)`, [time, JSON.stringify(prices)]); + await DB.query(` + INSERT INTO prices(time, USD, EUR, GBP, CAD, CHF, AUD, JPY) + VALUE (FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ? )`, + [time, prices.USD, prices.EUR, prices.GBP, prices.CAD, prices.CHF, prices.AUD, prices.JPY] + ); } catch (e: any) { logger.err(`Cannot save exchange rate into db. Reason: ` + (e instanceof Error ? e.message : e)); throw e; diff --git a/backend/src/routes.ts b/backend/src/routes.ts index 3676aa49a..57c64ddf5 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -27,6 +27,7 @@ import BlocksRepository from './repositories/BlocksRepository'; import HashratesRepository from './repositories/HashratesRepository'; import difficultyAdjustment from './api/difficulty-adjustment'; import DifficultyAdjustmentsRepository from './repositories/DifficultyAdjustmentsRepository'; +import BlocksAuditsRepository from './repositories/BlocksAuditsRepository'; class Routes { constructor() {} @@ -743,6 +744,20 @@ class Routes { } } + public async $getHistoricalBlockPrediction(req: Request, res: Response) { + try { + const blockPredictions = await mining.$getBlockPredictionsHistory(req.params.interval); + const blockCount = await BlocksAuditsRepository.$getPredictionsCount(); + res.header('Pragma', 'public'); + res.header('Cache-control', 'public'); + res.header('X-total-count', blockCount.toString()); + res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); + res.json(blockPredictions.map(prediction => [prediction.time, prediction.height, prediction.match_rate])); + } catch (e) { + res.status(500).send(e instanceof Error ? e.message : e); + } + } + public async getBlock(req: Request, res: Response) { try { const block = await blocks.$getBlock(req.params.hash); diff --git a/backend/src/tasks/price-feeds/kraken-api.ts b/backend/src/tasks/price-feeds/kraken-api.ts index 02d0d3af0..6c3cf93da 100644 --- a/backend/src/tasks/price-feeds/kraken-api.ts +++ b/backend/src/tasks/price-feeds/kraken-api.ts @@ -87,7 +87,7 @@ class KrakenApi implements PriceFeed { } if (Object.keys(priceHistory).length > 0) { - logger.info(`Inserted ${Object.keys(priceHistory).length} Kraken EUR, USD, GBP, JPY, CAD, CHF and AUD weekly price history into db`); + logger.notice(`Inserted ${Object.keys(priceHistory).length} Kraken EUR, USD, GBP, JPY, CAD, CHF and AUD weekly price history into db`); } } } diff --git a/backend/src/tasks/price-updater.ts b/backend/src/tasks/price-updater.ts index 254e8ef1c..caad6c54b 100644 --- a/backend/src/tasks/price-updater.ts +++ b/backend/src/tasks/price-updater.ts @@ -176,7 +176,7 @@ class PriceUpdater { ++insertedCount; } if (insertedCount > 0) { - logger.info(`Inserted ${insertedCount} MtGox USD weekly price history into db`); + logger.notice(`Inserted ${insertedCount} MtGox USD weekly price history into db`); } // Insert Kraken weekly prices @@ -205,23 +205,23 @@ class PriceUpdater { try { historicalPrices.push(await feed.$fetchRecentHourlyPrice(this.currencies)); } catch (e) { - logger.info(`Cannot fetch hourly historical price from ${feed.name}. Ignoring this feed. Reason: ${e instanceof Error ? e.message : e}`); + logger.err(`Cannot fetch hourly historical price from ${feed.name}. Ignoring this feed. Reason: ${e instanceof Error ? e.message : e}`); } } // Group them by timestamp and currency, for example // grouped[123456789]['USD'] = [1, 2, 3, 4]; - let grouped: Object = {}; + const grouped: Object = {}; for (const historicalEntry of historicalPrices) { for (const time in historicalEntry) { if (existingPriceTimes.includes(parseInt(time, 10))) { continue; } - if (grouped[time] == undefined) { + if (grouped[time] === undefined) { grouped[time] = { USD: [], EUR: [], GBP: [], CAD: [], CHF: [], AUD: [], JPY: [] - } + }; } for (const currency of this.currencies) { @@ -238,13 +238,20 @@ class PriceUpdater { for (const time in grouped) { const prices: Prices = this.getEmptyPricesObj(); for (const currency in grouped[time]) { - prices[currency] = Math.round((grouped[time][currency].reduce((partialSum, a) => partialSum + a, 0)) / grouped[time][currency].length); + if (grouped[time][currency].length === 0) { + continue; + } + prices[currency] = Math.round((grouped[time][currency].reduce( + (partialSum, a) => partialSum + a, 0) + ) / grouped[time][currency].length); } await PricesRepository.$savePrices(parseInt(time, 10), prices); ++totalInserted; } - logger.info(`Inserted ${totalInserted} hourly historical prices into the db`); + if (totalInserted > 0) { + logger.notice(`Inserted ${totalInserted} hourly historical prices into the db`); + } } } diff --git a/backend/src/utils/axios-query.ts b/backend/src/utils/axios-query.ts index 8333181f7..0a155fd55 100644 --- a/backend/src/utils/axios-query.ts +++ b/backend/src/utils/axios-query.ts @@ -50,10 +50,14 @@ export async function query(path): Promise { } return data.data; } catch (e) { - logger.err(`Could not connect to ${path}. Reason: ` + (e instanceof Error ? e.message : e)); + logger.warn(`Could not connect to ${path} (Attempt ${retry + 1}/${config.MEMPOOL.EXTERNAL_MAX_RETRY}). Reason: ` + (e instanceof Error ? e.message : e)); retry++; } - await setDelay(config.MEMPOOL.EXTERNAL_RETRY_INTERVAL); + if (retry < config.MEMPOOL.EXTERNAL_MAX_RETRY) { + await setDelay(config.MEMPOOL.EXTERNAL_RETRY_INTERVAL); + } } + + logger.err(`Could not connect to ${path}. All ${config.MEMPOOL.EXTERNAL_MAX_RETRY} attempts failed`); return undefined; } diff --git a/frontend/angular.json b/frontend/angular.json index 1d2fe3e6b..4eb697071 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -248,23 +248,6 @@ "browserTarget": "mempool:build" } }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "assets": [ - "src/favicon.ico", - "src/resources" - ], - "styles": [ - "src/styles.scss" - ], - "scripts": [] - } - }, "e2e": { "builder": "@cypress/schematic:cypress", "options": { diff --git a/frontend/karma.conf.js b/frontend/karma.conf.js deleted file mode 100644 index 5aca0c320..000000000 --- a/frontend/karma.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma') - ], - client: { - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, './coverage/mempool'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true - }); -}; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9dffa408b..9038b4ec4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -25,7 +25,6 @@ "@fortawesome/fontawesome-common-types": "~6.1.1", "@fortawesome/fontawesome-svg-core": "~6.1.1", "@fortawesome/free-solid-svg-icons": "~6.1.1", - "@juggle/resize-observer": "^3.3.1", "@mempool/mempool.js": "2.3.0", "@ng-bootstrap/ng-bootstrap": "^11.0.0", "@nguniversal/express-engine": "~13.1.1", @@ -36,7 +35,7 @@ "domino": "^2.1.6", "echarts": "~5.3.2", "express": "^4.17.1", - "lightweight-charts": "^3.3.0", + "lightweight-charts": "~3.8.0", "ngx-bootrap-multiselect": "^2.0.0", "ngx-echarts": "8.0.1", "ngx-infinite-scroll": "^10.0.1", @@ -52,32 +51,21 @@ "@angular/language-service": "~13.3.10", "@nguniversal/builders": "~13.1.1", "@types/express": "^4.17.0", - "@types/jasmine": "~4.0.3", - "@types/jasminewd2": "~2.0.10", "@types/node": "^12.11.1", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", - "codelyzer": "~6.0.2", "eslint": "^8.19.0", - "http-proxy-middleware": "^1.0.5", - "jasmine-core": "~4.1.0", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.3.19", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.0.3", - "karma-jasmine": "~5.0.0", - "karma-jasmine-html-reporter": "^1.5.0", - "ts-node": "~8.3.0", - "tslint": "~6.1.0", + "http-proxy-middleware": "~2.0.6", + "ts-node": "~10.8.1", "typescript": "~4.6.4" }, "optionalDependencies": { - "@cypress/schematic": "^1.3.0", + "@cypress/schematic": "~2.0.0", "cypress": "^10.0.2", - "cypress-fail-on-console-error": "^2.1.3", + "cypress-fail-on-console-error": "~2.1.4", "cypress-wait-until": "^1.7.1", - "mock-socket": "^9.0.3", - "start-server-and-test": "^1.12.6" + "mock-socket": "~9.1.4", + "start-server-and-test": "~1.14.0" } }, "node_modules/@ampproject/remapping": { @@ -388,25 +376,25 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@angular-devkit/schematics": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.6.tgz", - "integrity": "sha512-CmDNOdJg08p5QrV8dNdg3O5ErYM1hJT06PLnVZzTWkShAL0y/3zxXAP/Wwdg0vAvt9Kh38jvMtC3YTCOThR/hA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.17.tgz", + "integrity": "sha512-c0eNu/nx1Mnu7KcZgYTYHP736H4Y9pSyLBSmLAHYZv3t3m0dIPbhifRcLQX7hHQ8fGT2ZFxmOpaQG5/DcIghSw==", "optional": true, "dependencies": { - "@angular-devkit/core": "12.2.6", + "@angular-devkit/core": "12.2.17", "ora": "5.4.1", "rxjs": "6.6.7" }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "dependencies": { "ajv": "8.6.2", @@ -418,7 +406,7 @@ }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, @@ -438,23 +426,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", - "optional": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@angular-devkit/schematics/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -2648,11 +2619,24 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@csstools/postcss-progressive-custom-properties": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.2.0.tgz", @@ -2748,54 +2732,46 @@ } }, "node_modules/@cypress/schematic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-1.3.0.tgz", - "integrity": "sha512-MA5D4ggDXt0pSPqXxYxgejBCfXFsRhWTz29yfXDGV3nlj74MUywGMOVSR1WWr+NGA7XKqx37Gj802YExAl0omw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.0.0.tgz", + "integrity": "sha512-cKIyL1Gm/EU+eXTwYpxgFLdToVIpJwJHvUW+MVYpnoacfvPUU3UhgJsicPihw6e0hR0j/WImBkaIEqjH1MZK4Q==", "optional": true, "dependencies": { - "@angular-devkit/architect": "^0.1200.0", - "@angular-devkit/core": "^12.0.0", - "@angular-devkit/schematics": "^12.0.0", - "@schematics/angular": "^12.0.0", + "@angular-devkit/architect": "^0.1202.10", + "@angular-devkit/core": "^12.2.17", + "@angular-devkit/schematics": "^12.2.17", + "@schematics/angular": "^12.2.17", "jsonc-parser": "^3.0.0", - "rxjs": "6.6.2" + "rxjs": "~6.6.0" + }, + "peerDependencies": { + "@angular/cli": ">=12", + "@angular/core": ">=12" } }, "node_modules/@cypress/schematic/node_modules/@angular-devkit/architect": { - "version": "0.1200.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.3.tgz", - "integrity": "sha512-CaqushsPYQ3Us7eBIuZM9/u5H6Rjvm5tUCYS7D5lr5w4QbiwC+6L4dheWEu1PuS2TyyBt6lVwgUNguOmixDb0Q==", + "version": "0.1202.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1202.17.tgz", + "integrity": "sha512-uUQcHcLbPvr9adALQSLU1MTDduVUR2kZAHi2e7SmL9ioel84pPVXBoD0WpSBeUMKwPiDs3TQDaxDB49hl0nBSQ==", "optional": true, "dependencies": { - "@angular-devkit/core": "12.0.3", + "@angular-devkit/core": "12.2.17", "rxjs": "6.6.7" }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@cypress/schematic/node_modules/@angular-devkit/architect/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/@cypress/schematic/node_modules/@angular-devkit/core": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.3.tgz", - "integrity": "sha512-d6E4ldHzIerzFpXXZkynluIbZZeYD+VteFLBZ77lOXAuUYuuLEiW8h4bpJOqribeJli5c1cJ/yyELYHrbiiLcw==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "dependencies": { - "ajv": "8.2.0", - "ajv-formats": "2.0.2", + "ajv": "8.6.2", + "ajv-formats": "2.1.0", "fast-json-stable-stringify": "2.1.0", "magic-string": "0.25.7", "rxjs": "6.6.7", @@ -2803,32 +2779,24 @@ }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@cypress/schematic/node_modules/@angular-devkit/core/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/@cypress/schematic/node_modules/ajv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", - "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/@cypress/schematic/node_modules/json-schema-traverse": { @@ -2838,9 +2806,9 @@ "optional": true }, "node_modules/@cypress/schematic/node_modules/rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "optional": true, "dependencies": { "tslib": "^1.9.0" @@ -3056,9 +3024,9 @@ "integrity": "sha512-5TXltWJGc+RdnabUGzhRae1TRq6m4gr+3K2wQX0is5/F2yS6MJXJvLyI3ErAnsAXuJoGqvfVD5icRgim07DrxQ==" }, "node_modules/@hapi/hoek": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", - "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "optional": true }, "node_modules/@hapi/topo": { @@ -3155,11 +3123,6 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@juggle/resize-observer": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz", - "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==" - }, "node_modules/@mempool/mempool.js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.3.0.tgz", @@ -3237,30 +3200,6 @@ "@angular-devkit/build-angular": "^13.3.4" } }, - "node_modules/@nguniversal/builders/node_modules/http-proxy-middleware": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz", - "integrity": "sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, "node_modules/@nguniversal/builders/node_modules/piscina": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.1.0.tgz", @@ -3754,28 +3693,29 @@ "node_modules/@scarf/scarf": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.1.0.tgz", - "integrity": "sha512-b2iE8kjjzzUo2WZ0xuE2N77kfnTds7ClrDxcz3Atz7h2XrNVoAPUoT75i7CY0st5x++70V91Y+c6RpBX9MX7Jg==" + "integrity": "sha512-b2iE8kjjzzUo2WZ0xuE2N77kfnTds7ClrDxcz3Atz7h2XrNVoAPUoT75i7CY0st5x++70V91Y+c6RpBX9MX7Jg==", + "hasInstallScript": true }, "node_modules/@schematics/angular": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.6.tgz", - "integrity": "sha512-53yVIB43jPpqitJXT5IxPm9Kq1P8AyRgzrCIKAl4mESsPsOIFR6ZCpuNRlaumEinHnbMpgzZ2M+RlialzAOS6w==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.17.tgz", + "integrity": "sha512-HM/4KkQu944KL5ebhIyy1Ot5OV6prHNW7kmGeMVeQefLSbbfMQCHLa1psB9UU9BoahwGhUBvleLylNSitOBCgg==", "optional": true, "dependencies": { - "@angular-devkit/core": "12.2.6", - "@angular-devkit/schematics": "12.2.6", + "@angular-devkit/core": "12.2.17", + "@angular-devkit/schematics": "12.2.17", "jsonc-parser": "3.0.0" }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "dependencies": { "ajv": "8.6.2", @@ -3787,7 +3727,7 @@ }, "engines": { "node": "^12.14.1 || >=14.0.0", - "npm": "^6.11.0 || ^7.5.6", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, @@ -3807,23 +3747,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@schematics/angular/node_modules/ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", - "optional": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@schematics/angular/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -3849,9 +3772,9 @@ "optional": true }, "node_modules/@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "optional": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -3879,18 +3802,18 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "optional": true, "dependencies": { "@sinonjs/commons": "^1.7.0" } }, "node_modules/@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", "optional": true, "dependencies": { "@sinonjs/commons": "^1.6.0", @@ -3927,6 +3850,30 @@ "node": ">= 6" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", @@ -4031,21 +3978,6 @@ "@types/node": "*" } }, - "node_modules/@types/jasmine": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.0.3.tgz", - "integrity": "sha512-Opp1LvvEuZdk8fSSvchK2mZwhVrsNT0JgJE9Di6MjnaIpmEXM8TLCPPrVtNTYh8+5MPdY8j9bAHMu2SSfwpZJg==", - "dev": true - }, - "node_modules/@types/jasminewd2": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.10.tgz", - "integrity": "sha512-J7mDz7ovjwjc+Y9rR9rY53hFWKATcIkrr9DwQWmOas4/pnIPJTXawnzjwpHm3RSxz/e3ZVUvQ7cRbd5UQLo10g==", - "dev": true, - "dependencies": { - "@types/jasmine": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -4661,6 +4593,7 @@ "version": "0.0.27", "resolved": "https://registry.npmjs.org/@wessberg/ts-evaluator/-/ts-evaluator-0.0.27.tgz", "integrity": "sha512-7gOpVm3yYojUp/Yn7F4ZybJRxyqfMNf0LXK5KJiawbPfL0XTsJV+0mgrEDjOIR6Bi0OYk2Cyg4tjFu1r8MCZaA==", + "deprecated": "this package has been renamed to ts-evaluator. Please install ts-evaluator instead", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -4670,6 +4603,13 @@ }, "engines": { "node": ">=10.1.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/wessberg/ts-evaluator?sponsor=1" + }, + "peerDependencies": { + "typescript": ">=3.2.x || >= 4.x" } }, "node_modules/@wessberg/ts-evaluator/node_modules/ansi-styles": { @@ -4682,6 +4622,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@wessberg/ts-evaluator/node_modules/chalk": { @@ -4695,6 +4638,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@wessberg/ts-evaluator/node_modules/color-convert": { @@ -4877,27 +4823,43 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-formats": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.0.2.tgz", - "integrity": "sha512-Brah4Uo5/U8v76c6euTwtjVFFaVishwnJrQBYpev1JRh4vjA1F4HY3UzQez41YUCszUCXKagG8v6eVRBHV1gkw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", "optional": true, "dependencies": { "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", - "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { @@ -4909,7 +4871,10 @@ "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } }, "node_modules/amdefine": { "version": "1.0.1", @@ -4936,6 +4901,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-html-community": { @@ -4980,15 +4948,6 @@ "node": ">= 8" } }, - "node_modules/app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", - "dev": true, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -4998,6 +4957,20 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "optional": true }, "node_modules/are-we-there-yet": { @@ -5044,16 +5017,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "node_modules/aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, - "dependencies": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, "node_modules/array-filter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", @@ -5145,12 +5108,6 @@ "node": "*" } }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -5237,6 +5194,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/aws-sign2": { @@ -5263,15 +5223,6 @@ "follow-redirects": "^1.14.0" } }, - "node_modules/axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "dependencies": { - "ast-types-flow": "0.0.7" - } - }, "node_modules/babel-loader": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", @@ -5313,29 +5264,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", @@ -5388,7 +5316,21 @@ "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/base64id": { "version": "2.0.0", @@ -5550,7 +5492,15 @@ "node_modules/bootstrap": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz", - "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==" + "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + }, + "peerDependencies": { + "jquery": "1.9.1 - 3", + "popper.js": "^1.16.0" + } }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -5786,7 +5736,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", "dev": true, - "dependencies": { + "optionalDependencies": { "graceful-fs": "^4.1.6" } }, @@ -5992,7 +5942,21 @@ "node_modules/browserify-sign/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/browserify-zlib": { "version": "0.2.0", @@ -6134,6 +6098,20 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -6163,15 +6141,6 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -6266,6 +6235,9 @@ "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/call-matcher": { @@ -6419,6 +6391,9 @@ "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==", "engines": { "node": ">=6.0.0" + }, + "peerDependencies": { + "webpack": ">=4.0.1" } }, "node_modules/clean-stack": { @@ -6446,6 +6421,9 @@ "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-table3": { @@ -6474,6 +6452,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-width": { @@ -6525,76 +6506,6 @@ "node": ">=6" } }, - "node_modules/codelyzer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz", - "integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==", - "dev": true, - "dependencies": { - "@angular/compiler": "9.0.0", - "@angular/core": "9.0.0", - "app-root-path": "^3.0.0", - "aria-query": "^3.0.0", - "axobject-query": "2.0.2", - "css-selector-tokenizer": "^0.7.1", - "cssauron": "^1.4.0", - "damerau-levenshtein": "^1.0.4", - "rxjs": "^6.5.3", - "semver-dsl": "^1.0.1", - "source-map": "^0.5.7", - "sprintf-js": "^1.1.2", - "tslib": "^1.10.0", - "zone.js": "~0.10.3" - }, - "peerDependencies": { - "@angular/compiler": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", - "@angular/core": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", - "tslint": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/codelyzer/node_modules/@angular/compiler": { - "version": "9.0.0", - "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", - "dev": true - }, - "node_modules/codelyzer/node_modules/@angular/core": { - "version": "9.0.0", - "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", - "dev": true - }, - "node_modules/codelyzer/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/codelyzer/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/codelyzer/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/codelyzer/node_modules/zone.js": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", - "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", - "dev": true - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6626,7 +6537,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "devOptional": true, + "optional": true, "engines": { "node": ">=0.1.90" } @@ -6980,6 +6891,7 @@ "version": "3.20.3", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -7087,6 +6999,12 @@ "sha.js": "^2.4.8" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/critters": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", @@ -7310,16 +7228,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css-selector-tokenizer": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", - "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" - } - }, "node_modules/css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -7339,15 +7247,6 @@ "node": ">=0.10.0" } }, - "node_modules/cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", - "dev": true, - "dependencies": { - "through": "X.X.X" - } - }, "node_modules/cssdb": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-5.1.0.tgz", @@ -7390,7 +7289,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/cypress": { "version": "10.0.2", @@ -7450,13 +7350,13 @@ } }, "node_modules/cypress-fail-on-console-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.3.tgz", - "integrity": "sha512-VtGr48HPd0LiCUcTTKrU98gzF0gjOsMpyBV1EdCNOoyN02adZwLhRzQBvCVNAhBIeLAHC+sEcffc7ez/qEeazA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.4.tgz", + "integrity": "sha512-arjx2xfQN1FDM3s4HoKK0ZXszPgIZLAI61sbwaZfdo8HEIVJPdOwY+oBKM1XY9yso80rgtwlSY75KJOQTNOkdg==", "optional": true, "dependencies": { "chai": "^4.3.4", - "sinon": "^12.0.0", + "sinon": "^14.0.0", "sinon-chai": "^3.7.0" } }, @@ -7482,6 +7382,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cypress/node_modules/chalk": { @@ -7495,6 +7398,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/cypress/node_modules/chalk/node_modules/supports-color": { @@ -7554,6 +7460,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/cypress/node_modules/fs-extra": { @@ -7581,6 +7490,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cypress/node_modules/has-flag": { @@ -7602,6 +7514,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/cypress/node_modules/tmp": { @@ -7634,12 +7549,6 @@ "type": "^1.0.1" } }, - "node_modules/damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", - "dev": true - }, "node_modules/dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", @@ -7675,7 +7584,8 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz", "integrity": "sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -7751,6 +7661,9 @@ "object-is": "^1.0.1", "object-keys": "^1.1.1", "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/deep-is": { @@ -7956,7 +7869,8 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/diff": { "version": "4.0.2", @@ -8042,7 +7956,8 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "custom-event": "~1.0.0", "ent": "~2.2.0", @@ -8406,7 +8321,8 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/entities": { "version": "2.2.0", @@ -8473,6 +8389,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-module-lexer": { @@ -8491,6 +8410,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es5-ext": { @@ -8601,96 +8523,6 @@ "esbuild-windows-arm64": "0.14.22" } }, - "node_modules/esbuild-android-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.22.tgz", - "integrity": "sha512-k1Uu4uC4UOFgrnTj2zuj75EswFSEBK+H6lT70/DdS4mTAOfs2ECv2I9ZYvr3w0WL0T4YItzJdK7fPNxcPw6YmQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.22.tgz", - "integrity": "sha512-d8Ceuo6Vw6HM3fW218FB6jTY6O3r2WNcTAU0SGsBkXZ3k8SDoRLd3Nrc//EqzdgYnzDNMNtrWegK2Qsss4THhw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.22.tgz", - "integrity": "sha512-YAt9Tj3SkIUkswuzHxkaNlT9+sg0xvzDvE75LlBo4DI++ogSgSmKNR6B4eUhU5EUUepVXcXdRIdqMq9ppeRqfw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.22.tgz", - "integrity": "sha512-ek1HUv7fkXMy87Qm2G4IRohN+Qux4IcnrDBPZGXNN33KAL0pEJJzdTv0hB/42+DCYWylSrSKxk3KUXfqXOoH4A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.22.tgz", - "integrity": "sha512-zPh9SzjRvr9FwsouNYTqgqFlsMIW07O8mNXulGeQx6O5ApgGUBZBgtzSlBQXkHi18WjrosYfsvp5nzOKiWzkjQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-32": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.22.tgz", - "integrity": "sha512-SnpveoE4nzjb9t2hqCIzzTWBM0RzcCINDMBB67H6OXIuDa4KqFqaIgmTchNA9pJKOVLVIKd5FYxNiJStli21qg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/esbuild-linux-64": { "version": "0.14.22", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.22.tgz", @@ -8706,141 +8538,6 @@ "node": ">=12" } }, - "node_modules/esbuild-linux-arm": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.22.tgz", - "integrity": "sha512-soPDdbpt/C0XvOOK45p4EFt8HbH5g+0uHs5nUKjHVExfgR7du734kEkXR/mE5zmjrlymk5AA79I0VIvj90WZ4g==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.22.tgz", - "integrity": "sha512-8q/FRBJtV5IHnQChO3LHh/Jf7KLrxJ/RCTGdBvlVZhBde+dk3/qS9fFsUy+rs3dEi49aAsyVitTwlKw1SUFm+A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.22.tgz", - "integrity": "sha512-SiNDfuRXhGh1JQLLA9JPprBgPVFOsGuQ0yDfSPTNxztmVJd8W2mX++c4FfLpAwxuJe183mLuKf7qKCHQs5ZnBQ==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.22.tgz", - "integrity": "sha512-6t/GI9I+3o1EFm2AyN9+TsjdgWCpg2nwniEhjm2qJWtJyJ5VzTXGUU3alCO3evopu8G0hN2Bu1Jhz2YmZD0kng==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.22.tgz", - "integrity": "sha512-AyJHipZKe88sc+tp5layovquw5cvz45QXw5SaDgAq2M911wLHiCvDtf/07oDx8eweCyzYzG5Y39Ih568amMTCQ==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-s390x": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.22.tgz", - "integrity": "sha512-Sz1NjZewTIXSblQDZWEFZYjOK6p8tV6hrshYdXZ0NHTjWE+lwxpOpWeElUGtEmiPcMT71FiuA9ODplqzzSxkzw==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-netbsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.22.tgz", - "integrity": "sha512-TBbCtx+k32xydImsHxvFgsOCuFqCTGIxhzRNbgSL1Z2CKhzxwT92kQMhxort9N/fZM2CkRCPPs5wzQSamtzEHA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-openbsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.22.tgz", - "integrity": "sha512-vK912As725haT313ANZZZN+0EysEEQXWC/+YE4rQvOQzLuxAQc2tjbzlAFREx3C8+uMuZj/q7E5gyVB7TzpcTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-sunos-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.22.tgz", - "integrity": "sha512-/mbJdXTW7MTcsPhtfDsDyPEOju9EOABvCjeUU2OJ7fWpX/Em/H3WYDa86tzLUbcVg++BScQDzqV/7RYw5XNY0g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/esbuild-wasm": { "version": "0.14.22", "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.14.22.tgz", @@ -8852,51 +8549,6 @@ "node": ">=12" } }, - "node_modules/esbuild-windows-32": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.22.tgz", - "integrity": "sha512-1vRIkuvPTjeSVK3diVrnMLSbkuE36jxA+8zGLUOrT4bb7E/JZvDRhvtbWXWaveUc/7LbhaNFhHNvfPuSw2QOQg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.22.tgz", - "integrity": "sha512-AxjIDcOmx17vr31C5hp20HIwz1MymtMjKqX4qL6whPj0dT9lwxPexmLj6G1CpR3vFhui6m75EnBEe4QL82SYqw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.22.tgz", - "integrity": "sha512-5wvQ+39tHmRhNpu2Fx04l7QfeK3mQ9tKzDqqGR8n/4WUxsFxnVLfDRBGirIfk4AfWlxk60kqirlODPoT5LqMUg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9681,7 +9333,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "devOptional": true + "optional": true }, "node_modules/external-editor": { "version": "3.1.0", @@ -9702,7 +9354,6 @@ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "optional": true, "dependencies": { - "@types/yauzl": "^2.9.1", "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" @@ -9712,6 +9363,9 @@ }, "engines": { "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, "node_modules/extract-zip/node_modules/get-stream": { @@ -9724,6 +9378,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/extsprintf": { @@ -9789,12 +9446,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" }, - "node_modules/fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -9832,6 +9483,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/file-entry-cache": { @@ -10048,7 +9702,8 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -10062,7 +9717,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -10088,18 +9744,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -10168,6 +9812,9 @@ "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-package-type": { @@ -10258,6 +9905,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/global-dirs/node_modules/ini": { @@ -10316,6 +9966,9 @@ "dev": true, "dependencies": { "@wessberg/ts-evaluator": "0.0.27" + }, + "peerDependencies": { + "typescript": ">=3.7.5" } }, "node_modules/handle-thing": { @@ -10356,7 +10009,10 @@ "node_modules/has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/has-flag": { "version": "3.0.0", @@ -10372,6 +10028,9 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-unicode": { @@ -10408,7 +10067,21 @@ "node_modules/hash-base/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/hash.js": { "version": "1.1.7", @@ -10483,12 +10156,6 @@ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "node_modules/htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -10559,19 +10226,26 @@ } }, "node_modules/http-proxy-middleware": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz", - "integrity": "sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==", - "dev": true, + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dependencies": { - "@types/http-proxy": "^1.17.4", + "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", - "lodash": "^4.17.20", + "is-plain-obj": "^3.0.0", "micromatch": "^4.0.2" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, "node_modules/https-browserify": { @@ -10633,7 +10307,21 @@ "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/ignore": { "version": "5.2.0", @@ -10879,6 +10567,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { @@ -10889,7 +10580,10 @@ "node_modules/is-bigint": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -10911,6 +10605,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-buffer": { @@ -10924,6 +10621,9 @@ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-ci": { @@ -10955,6 +10655,9 @@ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-docker": { @@ -10993,6 +10696,9 @@ "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-glob": { @@ -11017,6 +10723,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-interactive": { @@ -11038,6 +10747,9 @@ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number": { @@ -11063,6 +10775,9 @@ "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-path-cwd": { @@ -11118,6 +10833,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { @@ -11137,6 +10855,9 @@ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { @@ -11148,6 +10869,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typed-array": { @@ -11163,6 +10887,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { @@ -11177,6 +10904,9 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-what": { @@ -11204,7 +10934,8 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">= 8.0.0" }, @@ -11240,14 +10971,14 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", "dependencies": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { @@ -11258,74 +10989,10 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jasmine-core": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.1.1.tgz", - "integrity": "sha512-lmUfT5XcK9KKvt3lLYzn93hc4MGzlUBowExFVgzbSW0ZCrdeyS574dfsyfRhxbg81Wj4gk+RxUiTnj7KBfDA1g==", - "dev": true - }, - "node_modules/jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "dependencies": { - "colors": "1.4.0" - } - }, "node_modules/jest-worker": { "version": "27.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz", @@ -11362,14 +11029,14 @@ } }, "node_modules/joi": { - "version": "17.4.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.1.tgz", - "integrity": "sha512-gDPOwQ5sr+BUxXuPDGrC1pSNcVR/yGGcTI0aCnjYxZEa3za60K/iCQ+OFIkEHWZGVCUcUlXlFKvMmrlmxrG6UQ==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", + "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", "optional": true, "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } @@ -11574,7 +11241,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "devOptional": true, + "optional": true, "dependencies": { "universalify": "^2.0.0" }, @@ -11586,7 +11253,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "devOptional": true, + "optional": true, "engines": { "node": ">= 10.0.0" } @@ -11624,7 +11291,8 @@ "version": "6.3.19", "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.19.tgz", "integrity": "sha512-NDhWckzES/Y9xMiddyU1RzaKL76/scCsu8Mp0vR0Z3lQRvC3p72+Ab4ppoxs36S9tyPNX5V48yvaV++RNEBPZw==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -11658,76 +11326,6 @@ "node": ">= 10" } }, - "node_modules/karma-chrome-launcher": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", - "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", - "dev": true, - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", - "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.1", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/karma-coverage/node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/karma-coverage/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/karma-jasmine": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.0.0.tgz", - "integrity": "sha512-dsFkCoTwyoNyQnMgegS72wIA/2xPDJG5yzTry0448U6lAY7P60Wgg4UuLlbdLv8YHbimgNpDXjjmfPdc99EDWQ==", - "dev": true, - "dependencies": { - "jasmine-core": "^4.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "karma": "^6.0.0" - } - }, - "node_modules/karma-jasmine-html-reporter": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.4.tgz", - "integrity": "sha512-PtilRLno5O6wH3lDihRnz0Ba8oSn0YUJqKjjux1peoYGwo0AQqrWRbdWk/RLzcGlb+onTyXAnHl6M+Hu3UxG/Q==", - "dev": true - }, "node_modules/karma-source-map-support": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", @@ -11740,7 +11338,8 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", @@ -11755,7 +11354,8 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -11764,7 +11364,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -11782,7 +11383,8 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -11791,13 +11393,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -11806,7 +11410,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "rimraf": "^3.0.0" }, @@ -11818,7 +11423,6 @@ "version": "0.7.31", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", - "devOptional": true, "funding": [ { "type": "opencollective", @@ -11829,6 +11433,8 @@ "url": "https://paypal.me/faisalman" } ], + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -11983,9 +11589,9 @@ } }, "node_modules/lightweight-charts": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-3.3.0.tgz", - "integrity": "sha512-W5jeBrXcHG8eHnIQ0L2CB9TLkrrsjNPlQq5SICPO8PnJ3dJ8jZkLCAwemZ7Ym7ZGCfKCz6ow1EPbyzNYxblnkw==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-3.8.0.tgz", + "integrity": "sha512-7yFGnYuE1RjRJG9RwUTBz5wvF1QtjBOSW4FFlikr8Dh+/TDNt4ci+HsWSYmStgQUpawpvkCJ3j5/W25GppGj9Q==", "dependencies": { "fancy-canvas": "0.2.2" } @@ -12017,6 +11623,9 @@ }, "engines": { "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" } }, "node_modules/listr2/node_modules/ansi-styles": { @@ -12029,6 +11638,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/listr2/node_modules/color-convert": { @@ -12079,6 +11691,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/loader-runner": { @@ -12241,7 +11856,7 @@ "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "optional": true }, "node_modules/lodash.isfinite": { @@ -12272,6 +11887,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols/node_modules/ansi-styles": { @@ -12283,6 +11901,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-symbols/node_modules/chalk": { @@ -12295,6 +11916,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/log-symbols/node_modules/color-convert": { @@ -12345,6 +11969,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-styles": { @@ -12357,6 +11984,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-update/node_modules/color-convert": { @@ -12389,13 +12019,17 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/log4js": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "date-format": "^4.0.3", "debug": "^4.3.3", @@ -12411,7 +12045,8 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "ms": "2.1.2" }, @@ -12452,6 +12087,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { @@ -12588,7 +12226,8 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "devOptional": true, + "optional": true, + "peer": true, "bin": { "mime": "cli.js" }, @@ -12925,13 +12564,10 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/mock-socket": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.0.3.tgz", - "integrity": "sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.1.5.tgz", + "integrity": "sha512-3DeNIcsQixWHHKk6NdoBhWI4t1VMj5/HzfnI1rE/pLl5qKx7+gd4DNA07ehTaZ6MoUU053si6Hd+YtiM/tQZfg==", "optional": true, - "dependencies": { - "url-parse": "^1.4.4" - }, "engines": { "node": ">= 8" } @@ -13157,6 +12793,11 @@ "integrity": "sha512-GV/2MigCS5oi6P+zWtFSmq1TLWW1kcKsJNAXLP3hHXxmY3HgMKeUPk57o3T+YHje73JRp5reXMhEIlYuoOmoRg==", "dependencies": { "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": "^10.0.6", + "@angular/core": "^10.0.6", + "@angular/forms": "^10.0.6" } }, "node_modules/ngx-echarts": { @@ -13174,6 +12815,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-10.0.1.tgz", "integrity": "sha512-7is0eJZ9kJPsaHohRmMhJ/QFHAW9jp9twO5HcHRvFM/Yl/R8QCiokgjwmH0/CR3MuxUanxfHZMfO3PbYTwlBEg==", + "hasInstallScript": true, "dependencies": { "@scarf/scarf": "^1.1.0", "opencollective-postinstall": "^2.0.2" @@ -13194,31 +12836,22 @@ } }, "node_modules/nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", "optional": true, "dependencies": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "optional": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, "node_modules/nise/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "optional": true }, "node_modules/nise/node_modules/path-to-regexp": { @@ -13433,6 +13066,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.4.0.tgz", "integrity": "sha512-YOfuyWa/Ee+PXbDm40j9WXyJrzQUynVbgn4Km643UYcWNcrSfRkKL0WaiUcxcIbkXcVTgNpDqSnPXntWXT75cw==", + "deprecated": "Please update to latest patch version to fix memory leak https://github.com/isaacs/node-lru-cache/issues/227", "engines": { "node": ">=12" } @@ -13523,7 +13157,10 @@ "node_modules/object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/object-is": { "version": "1.1.5", @@ -13535,6 +13172,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { @@ -13566,6 +13206,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/obuf": { @@ -13609,6 +13252,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/open": { @@ -13709,6 +13355,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/ora/node_modules/chalk": { @@ -13721,6 +13370,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/ora/node_modules/color-convert": { @@ -13811,6 +13463,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -13822,6 +13477,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-retry": { @@ -14688,6 +14346,9 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pretty-hrtime": { @@ -14812,7 +14473,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.9" } @@ -14868,6 +14530,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "engines": { "node": ">=0.4.x" } @@ -14880,12 +14543,6 @@ "node": ">=0.4.x" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "optional": true - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -15076,6 +14733,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { @@ -15273,7 +14933,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/rimraf": { "version": "3.0.2", @@ -15284,6 +14945,9 @@ }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ripemd160": { @@ -15485,24 +15149,6 @@ "node": ">=10" } }, - "node_modules/semver-dsl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", - "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", - "dev": true, - "dependencies": { - "semver": "^5.3.0" - } - }, - "node_modules/semver-dsl/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", @@ -15731,9 +15377,9 @@ } }, "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" }, "node_modules/signal-exit": { "version": "3.0.7", @@ -15743,19 +15389,33 @@ "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/sinon": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", - "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", + "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", "optional": true, "dependencies": { "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^8.1.0", - "@sinonjs/samsam": "^6.0.2", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^6.1.1", "diff": "^5.0.0", - "nise": "^5.1.0", + "nise": "^5.1.1", "supports-color": "^7.2.0" }, "funding": { @@ -15767,12 +15427,16 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "optional": true + "optional": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } }, "node_modules/sinon/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "optional": true, "engines": { "node": ">=0.3.1" @@ -15834,6 +15498,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/slice-ansi/node_modules/color-convert": { @@ -16015,6 +15682,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0" @@ -16095,12 +15763,6 @@ "node": "*" } }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -16117,6 +15779,11 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, "engines": { "node": ">=0.10.0" } @@ -16133,9 +15800,9 @@ } }, "node_modules/start-server-and-test": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.6.tgz", - "integrity": "sha512-2N+JgOCJIM36KqKZdER7+ybJqVCJRyND42wIUvK+T1iE015ee/FAVArjSHqnSBismQghPUsfV7fB8lCFcpL7/w==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz", + "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==", "optional": true, "dependencies": { "bluebird": "3.7.2", @@ -16144,7 +15811,7 @@ "execa": "5.1.1", "lazy-ass": "1.6.0", "ps-tree": "1.2.0", - "wait-on": "5.3.0" + "wait-on": "6.0.0" }, "bin": { "server-test": "src/bin/start.js", @@ -16215,7 +15882,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz", "integrity": "sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "date-format": "^4.0.3", "debug": "^4.1.1", @@ -16253,6 +15921,9 @@ "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { @@ -16262,6 +15933,9 @@ "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { @@ -16723,6 +16397,20 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "engines": { "node": ">=4" } @@ -16760,22 +16448,67 @@ } }, "node_modules/ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", + "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", "dev": true, "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" }, "bin": { - "ts-node": "dist/bin.js" + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=4.2.0" + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" } }, "node_modules/tslib": { @@ -16783,63 +16516,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, - "node_modules/tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - } - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/tslint/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -16889,6 +16565,9 @@ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { @@ -17040,6 +16719,9 @@ "has-bigints": "^1.0.1", "has-symbols": "^1.0.2", "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/undeclared-identifiers": { @@ -17151,16 +16833,6 @@ "querystring": "0.2.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "optional": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -17193,6 +16865,12 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -17232,7 +16910,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -17258,42 +16937,24 @@ } }, "node_modules/wait-on": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz", - "integrity": "sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz", + "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==", "optional": true, "dependencies": { "axios": "^0.21.1", - "joi": "^17.3.0", + "joi": "^17.4.0", "lodash": "^4.17.21", "minimist": "^1.2.5", - "rxjs": "^6.6.3" + "rxjs": "^7.1.0" }, "bin": { "wait-on": "bin/wait-on" }, "engines": { - "node": ">=8.9.0" + "node": ">=10.0.0" } }, - "node_modules/wait-on/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/wait-on/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "optional": true - }, "node_modules/watchpack": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", @@ -17577,29 +17238,6 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" }, - "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, "node_modules/webpack-dev-server/node_modules/ipaddr.js": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", @@ -17791,18 +17429,6 @@ "node": ">=10" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", @@ -17813,6 +17439,9 @@ "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-module": { @@ -17835,6 +17464,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/wide-align": { @@ -17880,6 +17512,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { @@ -17915,6 +17550,18 @@ "dev": true, "engines": { "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xhr2": { @@ -17975,7 +17622,8 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -18005,19 +17653,24 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/yargs/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -18028,7 +17681,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -18040,13 +17694,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/yargs/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -18054,13 +17710,17 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/yargs/node_modules/y18n": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.6.tgz", "integrity": "sha512-PlVX4Y0lDTN6E2V4ES2tEdyvXkeKzxa8c/vo0pxPr/TqbztddTP0yn7zZylIyiAuxerqj0Q5GhpJ1YJCP8LaZQ==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -18069,7 +17729,8 @@ "version": "20.2.7", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -18342,20 +18003,20 @@ } }, "@angular-devkit/schematics": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.6.tgz", - "integrity": "sha512-CmDNOdJg08p5QrV8dNdg3O5ErYM1hJT06PLnVZzTWkShAL0y/3zxXAP/Wwdg0vAvt9Kh38jvMtC3YTCOThR/hA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.2.17.tgz", + "integrity": "sha512-c0eNu/nx1Mnu7KcZgYTYHP736H4Y9pSyLBSmLAHYZv3t3m0dIPbhifRcLQX7hHQ8fGT2ZFxmOpaQG5/DcIghSw==", "optional": true, "requires": { - "@angular-devkit/core": "12.2.6", + "@angular-devkit/core": "12.2.17", "ora": "5.4.1", "rxjs": "6.6.7" }, "dependencies": { "@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "requires": { "ajv": "8.6.2", @@ -18378,15 +18039,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", - "optional": true, - "requires": { - "ajv": "^8.0.0" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -19879,7 +19531,17 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "devOptional": true + "optional": true, + "peer": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } }, "@csstools/postcss-progressive-custom-properties": { "version": "1.2.0", @@ -19957,69 +19619,47 @@ } }, "@cypress/schematic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-1.3.0.tgz", - "integrity": "sha512-MA5D4ggDXt0pSPqXxYxgejBCfXFsRhWTz29yfXDGV3nlj74MUywGMOVSR1WWr+NGA7XKqx37Gj802YExAl0omw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.0.0.tgz", + "integrity": "sha512-cKIyL1Gm/EU+eXTwYpxgFLdToVIpJwJHvUW+MVYpnoacfvPUU3UhgJsicPihw6e0hR0j/WImBkaIEqjH1MZK4Q==", "optional": true, "requires": { - "@angular-devkit/architect": "^0.1200.0", - "@angular-devkit/core": "^12.0.0", - "@angular-devkit/schematics": "^12.0.0", - "@schematics/angular": "^12.0.0", + "@angular-devkit/architect": "^0.1202.10", + "@angular-devkit/core": "^12.2.17", + "@angular-devkit/schematics": "^12.2.17", + "@schematics/angular": "^12.2.17", "jsonc-parser": "^3.0.0", - "rxjs": "6.6.2" + "rxjs": "~6.6.0" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.1200.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1200.3.tgz", - "integrity": "sha512-CaqushsPYQ3Us7eBIuZM9/u5H6Rjvm5tUCYS7D5lr5w4QbiwC+6L4dheWEu1PuS2TyyBt6lVwgUNguOmixDb0Q==", + "version": "0.1202.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1202.17.tgz", + "integrity": "sha512-uUQcHcLbPvr9adALQSLU1MTDduVUR2kZAHi2e7SmL9ioel84pPVXBoD0WpSBeUMKwPiDs3TQDaxDB49hl0nBSQ==", "optional": true, "requires": { - "@angular-devkit/core": "12.0.3", + "@angular-devkit/core": "12.2.17", "rxjs": "6.6.7" - }, - "dependencies": { - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "requires": { - "tslib": "^1.9.0" - } - } } }, "@angular-devkit/core": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.0.3.tgz", - "integrity": "sha512-d6E4ldHzIerzFpXXZkynluIbZZeYD+VteFLBZ77lOXAuUYuuLEiW8h4bpJOqribeJli5c1cJ/yyELYHrbiiLcw==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "requires": { - "ajv": "8.2.0", - "ajv-formats": "2.0.2", + "ajv": "8.6.2", + "ajv-formats": "2.1.0", "fast-json-stable-stringify": "2.1.0", "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" - }, - "dependencies": { - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "requires": { - "tslib": "^1.9.0" - } - } } }, "ajv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", - "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -20035,9 +19675,9 @@ "optional": true }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "optional": true, "requires": { "tslib": "^1.9.0" @@ -20218,9 +19858,9 @@ } }, "@hapi/hoek": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", - "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "optional": true }, "@hapi/topo": { @@ -20299,11 +19939,6 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "@juggle/resize-observer": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz", - "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==" - }, "@mempool/mempool.js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.3.0.tgz", @@ -20356,19 +19991,6 @@ "tree-kill": "^1.2.2" }, "dependencies": { - "http-proxy-middleware": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz", - "integrity": "sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, "piscina": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.1.0.tgz", @@ -20727,20 +20349,20 @@ "integrity": "sha512-b2iE8kjjzzUo2WZ0xuE2N77kfnTds7ClrDxcz3Atz7h2XrNVoAPUoT75i7CY0st5x++70V91Y+c6RpBX9MX7Jg==" }, "@schematics/angular": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.6.tgz", - "integrity": "sha512-53yVIB43jPpqitJXT5IxPm9Kq1P8AyRgzrCIKAl4mESsPsOIFR6ZCpuNRlaumEinHnbMpgzZ2M+RlialzAOS6w==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.2.17.tgz", + "integrity": "sha512-HM/4KkQu944KL5ebhIyy1Ot5OV6prHNW7kmGeMVeQefLSbbfMQCHLa1psB9UU9BoahwGhUBvleLylNSitOBCgg==", "optional": true, "requires": { - "@angular-devkit/core": "12.2.6", - "@angular-devkit/schematics": "12.2.6", + "@angular-devkit/core": "12.2.17", + "@angular-devkit/schematics": "12.2.17", "jsonc-parser": "3.0.0" }, "dependencies": { "@angular-devkit/core": { - "version": "12.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.6.tgz", - "integrity": "sha512-E+OhY34Vmwyy1/PaX/nzao40XM70wOr7Urh00sAtV8sPLXMLeW0gHk4DUchCKohxQkrIL0AxYt1aeUVgIc7bSA==", + "version": "12.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.2.17.tgz", + "integrity": "sha512-PyOY7LGUPPd6rakxUYbfQN6zAdOCMCouVp5tERY1WTdMdEiuULOtHsPee8kNbh75pD59KbJNU+fwozPRMuIm5g==", "optional": true, "requires": { "ajv": "8.6.2", @@ -20763,15 +20385,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", - "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", - "optional": true, - "requires": { - "ajv": "^8.0.0" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -20796,9 +20409,9 @@ } }, "@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "optional": true, "requires": { "@hapi/hoek": "^9.0.0" @@ -20826,18 +20439,18 @@ } }, "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "optional": true, "requires": { "@sinonjs/commons": "^1.7.0" } }, "@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", "optional": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -20868,6 +20481,30 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "@types/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", @@ -20972,21 +20609,6 @@ "@types/node": "*" } }, - "@types/jasmine": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.0.3.tgz", - "integrity": "sha512-Opp1LvvEuZdk8fSSvchK2mZwhVrsNT0JgJE9Di6MjnaIpmEXM8TLCPPrVtNTYh8+5MPdY8j9bAHMu2SSfwpZJg==", - "dev": true - }, - "@types/jasminewd2": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.10.tgz", - "integrity": "sha512-J7mDz7ovjwjc+Y9rR9rY53hFWKATcIkrr9DwQWmOas4/pnIPJTXawnzjwpHm3RSxz/e3ZVUvQ7cRbd5UQLo10g==", - "dev": true, - "requires": { - "@types/jasmine": "*" - } - }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -21624,18 +21246,18 @@ } }, "ajv-formats": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.0.2.tgz", - "integrity": "sha512-Brah4Uo5/U8v76c6euTwtjVFFaVishwnJrQBYpev1JRh4vjA1F4HY3UzQez41YUCszUCXKagG8v6eVRBHV1gkw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", "optional": true, "requires": { "ajv": "^8.0.0" }, "dependencies": { "ajv": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", - "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -21655,7 +21277,8 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} }, "amdefine": { "version": "1.0.1", @@ -21702,12 +21325,6 @@ "picomatch": "^2.0.4" } }, - "app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", - "dev": true - }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -21761,16 +21378,6 @@ } } }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, "array-filter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", @@ -21854,12 +21461,6 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "optional": true }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -21938,15 +21539,6 @@ "follow-redirects": "^1.14.0" } }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, "babel-loader": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", @@ -21976,25 +21568,6 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } } }, "babel-plugin-polyfill-corejs2": { @@ -22186,7 +21759,8 @@ "bootstrap": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz", - "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==" + "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==", + "requires": {} }, "brace-expansion": { "version": "1.1.11", @@ -22729,12 +22303,6 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -22930,7 +22498,8 @@ "circular-dependency-plugin": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz", - "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==" + "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==", + "requires": {} }, "clean-stack": { "version": "2.2.0", @@ -23010,67 +22579,6 @@ "shallow-clone": "^3.0.0" } }, - "codelyzer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz", - "integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==", - "dev": true, - "requires": { - "@angular/compiler": "9.0.0", - "@angular/core": "9.0.0", - "app-root-path": "^3.0.0", - "aria-query": "^3.0.0", - "axobject-query": "2.0.2", - "css-selector-tokenizer": "^0.7.1", - "cssauron": "^1.4.0", - "damerau-levenshtein": "^1.0.4", - "rxjs": "^6.5.3", - "semver-dsl": "^1.0.1", - "source-map": "^0.5.7", - "sprintf-js": "^1.1.2", - "tslib": "^1.10.0", - "zone.js": "~0.10.3" - }, - "dependencies": { - "@angular/compiler": { - "version": "9.0.0", - "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", - "dev": true - }, - "@angular/core": { - "version": "9.0.0", - "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "zone.js": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", - "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", - "dev": true - } - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -23099,7 +22607,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "devOptional": true + "optional": true }, "combine-source-map": { "version": "0.8.0", @@ -23477,6 +22985,12 @@ "sha.js": "^2.4.8" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "critters": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", @@ -23639,30 +23153,11 @@ "nth-check": "^2.0.1" } }, - "css-selector-tokenizer": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", - "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" - } - }, "css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" }, - "cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", - "dev": true, - "requires": { - "through": "X.X.X" - } - }, "cssdb": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-5.1.0.tgz", @@ -23698,7 +23193,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "devOptional": true + "optional": true, + "peer": true }, "cypress": { "version": "10.0.2", @@ -23878,13 +23374,13 @@ } }, "cypress-fail-on-console-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.3.tgz", - "integrity": "sha512-VtGr48HPd0LiCUcTTKrU98gzF0gjOsMpyBV1EdCNOoyN02adZwLhRzQBvCVNAhBIeLAHC+sEcffc7ez/qEeazA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.4.tgz", + "integrity": "sha512-arjx2xfQN1FDM3s4HoKK0ZXszPgIZLAI61sbwaZfdo8HEIVJPdOwY+oBKM1XY9yso80rgtwlSY75KJOQTNOkdg==", "optional": true, "requires": { "chai": "^4.3.4", - "sinon": "^12.0.0", + "sinon": "^14.0.0", "sinon-chai": "^3.7.0" } }, @@ -23903,12 +23399,6 @@ "type": "^1.0.1" } }, - "damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", - "dev": true - }, "dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", @@ -23938,7 +23428,8 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz", "integrity": "sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==", - "devOptional": true + "optional": true, + "peer": true }, "dayjs": { "version": "1.10.5", @@ -24150,7 +23641,8 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "devOptional": true + "optional": true, + "peer": true }, "diff": { "version": "4.0.2", @@ -24229,7 +23721,8 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "custom-event": "~1.0.0", "ent": "~2.2.0", @@ -24519,7 +24012,8 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "devOptional": true + "optional": true, + "peer": true }, "entities": { "version": "2.2.0", @@ -24694,125 +24188,17 @@ "esbuild-windows-arm64": "0.14.22" } }, - "esbuild-android-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.22.tgz", - "integrity": "sha512-k1Uu4uC4UOFgrnTj2zuj75EswFSEBK+H6lT70/DdS4mTAOfs2ECv2I9ZYvr3w0WL0T4YItzJdK7fPNxcPw6YmQ==", - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.22.tgz", - "integrity": "sha512-d8Ceuo6Vw6HM3fW218FB6jTY6O3r2WNcTAU0SGsBkXZ3k8SDoRLd3Nrc//EqzdgYnzDNMNtrWegK2Qsss4THhw==", - "optional": true - }, - "esbuild-darwin-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.22.tgz", - "integrity": "sha512-YAt9Tj3SkIUkswuzHxkaNlT9+sg0xvzDvE75LlBo4DI++ogSgSmKNR6B4eUhU5EUUepVXcXdRIdqMq9ppeRqfw==", - "optional": true - }, - "esbuild-freebsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.22.tgz", - "integrity": "sha512-ek1HUv7fkXMy87Qm2G4IRohN+Qux4IcnrDBPZGXNN33KAL0pEJJzdTv0hB/42+DCYWylSrSKxk3KUXfqXOoH4A==", - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.22.tgz", - "integrity": "sha512-zPh9SzjRvr9FwsouNYTqgqFlsMIW07O8mNXulGeQx6O5ApgGUBZBgtzSlBQXkHi18WjrosYfsvp5nzOKiWzkjQ==", - "optional": true - }, - "esbuild-linux-32": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.22.tgz", - "integrity": "sha512-SnpveoE4nzjb9t2hqCIzzTWBM0RzcCINDMBB67H6OXIuDa4KqFqaIgmTchNA9pJKOVLVIKd5FYxNiJStli21qg==", - "optional": true - }, "esbuild-linux-64": { "version": "0.14.22", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.22.tgz", "integrity": "sha512-Zcl9Wg7gKhOWWNqAjygyqzB+fJa19glgl2JG7GtuxHyL1uEnWlpSMytTLMqtfbmRykIHdab797IOZeKwk5g0zg==", "optional": true }, - "esbuild-linux-arm": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.22.tgz", - "integrity": "sha512-soPDdbpt/C0XvOOK45p4EFt8HbH5g+0uHs5nUKjHVExfgR7du734kEkXR/mE5zmjrlymk5AA79I0VIvj90WZ4g==", - "optional": true - }, - "esbuild-linux-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.22.tgz", - "integrity": "sha512-8q/FRBJtV5IHnQChO3LHh/Jf7KLrxJ/RCTGdBvlVZhBde+dk3/qS9fFsUy+rs3dEi49aAsyVitTwlKw1SUFm+A==", - "optional": true - }, - "esbuild-linux-mips64le": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.22.tgz", - "integrity": "sha512-SiNDfuRXhGh1JQLLA9JPprBgPVFOsGuQ0yDfSPTNxztmVJd8W2mX++c4FfLpAwxuJe183mLuKf7qKCHQs5ZnBQ==", - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.22.tgz", - "integrity": "sha512-6t/GI9I+3o1EFm2AyN9+TsjdgWCpg2nwniEhjm2qJWtJyJ5VzTXGUU3alCO3evopu8G0hN2Bu1Jhz2YmZD0kng==", - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.22.tgz", - "integrity": "sha512-AyJHipZKe88sc+tp5layovquw5cvz45QXw5SaDgAq2M911wLHiCvDtf/07oDx8eweCyzYzG5Y39Ih568amMTCQ==", - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.22.tgz", - "integrity": "sha512-Sz1NjZewTIXSblQDZWEFZYjOK6p8tV6hrshYdXZ0NHTjWE+lwxpOpWeElUGtEmiPcMT71FiuA9ODplqzzSxkzw==", - "optional": true - }, - "esbuild-netbsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.22.tgz", - "integrity": "sha512-TBbCtx+k32xydImsHxvFgsOCuFqCTGIxhzRNbgSL1Z2CKhzxwT92kQMhxort9N/fZM2CkRCPPs5wzQSamtzEHA==", - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.22.tgz", - "integrity": "sha512-vK912As725haT313ANZZZN+0EysEEQXWC/+YE4rQvOQzLuxAQc2tjbzlAFREx3C8+uMuZj/q7E5gyVB7TzpcTA==", - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.22.tgz", - "integrity": "sha512-/mbJdXTW7MTcsPhtfDsDyPEOju9EOABvCjeUU2OJ7fWpX/Em/H3WYDa86tzLUbcVg++BScQDzqV/7RYw5XNY0g==", - "optional": true - }, "esbuild-wasm": { "version": "0.14.22", "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.14.22.tgz", "integrity": "sha512-FOSAM29GN1fWusw0oLMv6JYhoheDIh5+atC72TkJKfIUMID6yISlicoQSd9gsNSFsNBvABvtE2jR4JB1j4FkFw==" }, - "esbuild-windows-32": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.22.tgz", - "integrity": "sha512-1vRIkuvPTjeSVK3diVrnMLSbkuE36jxA+8zGLUOrT4bb7E/JZvDRhvtbWXWaveUc/7LbhaNFhHNvfPuSw2QOQg==", - "optional": true - }, - "esbuild-windows-64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.22.tgz", - "integrity": "sha512-AxjIDcOmx17vr31C5hp20HIwz1MymtMjKqX4qL6whPj0dT9lwxPexmLj6G1CpR3vFhui6m75EnBEe4QL82SYqw==", - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.14.22", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.22.tgz", - "integrity": "sha512-5wvQ+39tHmRhNpu2Fx04l7QfeK3mQ9tKzDqqGR8n/4WUxsFxnVLfDRBGirIfk4AfWlxk60kqirlODPoT5LqMUg==", - "optional": true - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -25431,7 +24817,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "devOptional": true + "optional": true }, "external-editor": { "version": "3.1.0", @@ -25520,12 +24906,6 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -25718,7 +25098,8 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -25729,7 +25110,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "devOptional": true + "optional": true, + "peer": true } } }, @@ -25751,12 +25133,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -26076,12 +25452,6 @@ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -26142,15 +25512,14 @@ } }, "http-proxy-middleware": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz", - "integrity": "sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==", - "dev": true, + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "requires": { - "@types/http-proxy": "^1.17.4", + "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", - "lodash": "^4.17.20", + "is-plain-obj": "^3.0.0", "micromatch": "^4.0.2" } }, @@ -26617,7 +25986,8 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", - "devOptional": true + "optional": true, + "peer": true }, "isexe": { "version": "2.0.0", @@ -26641,78 +26011,24 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jasmine-core": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.1.1.tgz", - "integrity": "sha512-lmUfT5XcK9KKvt3lLYzn93hc4MGzlUBowExFVgzbSW0ZCrdeyS574dfsyfRhxbg81Wj4gk+RxUiTnj7KBfDA1g==", - "dev": true - }, - "jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "requires": { - "colors": "1.4.0" - } - }, "jest-worker": { "version": "27.2.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz", @@ -26739,14 +26055,14 @@ } }, "joi": { - "version": "17.4.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.1.tgz", - "integrity": "sha512-gDPOwQ5sr+BUxXuPDGrC1pSNcVR/yGGcTI0aCnjYxZEa3za60K/iCQ+OFIkEHWZGVCUcUlXlFKvMmrlmxrG6UQ==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", + "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", "optional": true, "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } @@ -26903,7 +26219,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "devOptional": true, + "optional": true, "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" @@ -26913,7 +26229,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "devOptional": true + "optional": true } } }, @@ -26941,7 +26257,8 @@ "version": "6.3.19", "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.19.tgz", "integrity": "sha512-NDhWckzES/Y9xMiddyU1RzaKL76/scCsu8Mp0vR0Z3lQRvC3p72+Ab4ppoxs36S9tyPNX5V48yvaV++RNEBPZw==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -26973,7 +26290,8 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "debug": "2.6.9", "finalhandler": "1.1.2", @@ -26985,7 +26303,8 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "ms": "2.0.0" } @@ -26996,7 +26315,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -27011,7 +26331,8 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "ms": "2.0.0" } @@ -27022,19 +26343,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "devOptional": true + "optional": true, + "peer": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "devOptional": true + "optional": true, + "peer": true }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "rimraf": "^3.0.0" } @@ -27043,67 +26367,11 @@ "version": "0.7.31", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", - "devOptional": true + "optional": true, + "peer": true } } }, - "karma-chrome-launcher": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", - "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", - "dev": true, - "requires": { - "which": "^1.2.1" - } - }, - "karma-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", - "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.1", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "minimatch": "^3.0.4" - }, - "dependencies": { - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "karma-jasmine": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.0.0.tgz", - "integrity": "sha512-dsFkCoTwyoNyQnMgegS72wIA/2xPDJG5yzTry0448U6lAY7P60Wgg4UuLlbdLv8YHbimgNpDXjjmfPdc99EDWQ==", - "dev": true, - "requires": { - "jasmine-core": "^4.1.0" - } - }, - "karma-jasmine-html-reporter": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.4.tgz", - "integrity": "sha512-PtilRLno5O6wH3lDihRnz0Ba8oSn0YUJqKjjux1peoYGwo0AQqrWRbdWk/RLzcGlb+onTyXAnHl6M+Hu3UxG/Q==", - "dev": true - }, "karma-source-map-support": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", @@ -27210,9 +26478,9 @@ } }, "lightweight-charts": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-3.3.0.tgz", - "integrity": "sha512-W5jeBrXcHG8eHnIQ0L2CB9TLkrrsjNPlQq5SICPO8PnJ3dJ8jZkLCAwemZ7Ym7ZGCfKCz6ow1EPbyzNYxblnkw==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-3.8.0.tgz", + "integrity": "sha512-7yFGnYuE1RjRJG9RwUTBz5wvF1QtjBOSW4FFlikr8Dh+/TDNt4ci+HsWSYmStgQUpawpvkCJ3j5/W25GppGj9Q==", "requires": { "fancy-canvas": "0.2.2" } @@ -27418,7 +26686,7 @@ "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "optional": true }, "lodash.isfinite": { @@ -27546,7 +26814,8 @@ "version": "6.4.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "date-format": "^4.0.3", "debug": "^4.3.3", @@ -27559,7 +26828,8 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "ms": "2.1.2" } @@ -27704,7 +26974,8 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "devOptional": true + "optional": true, + "peer": true }, "mime-db": { "version": "1.49.0", @@ -27951,13 +27222,10 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "mock-socket": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.0.3.tgz", - "integrity": "sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw==", - "optional": true, - "requires": { - "url-parse": "^1.4.4" - } + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.1.5.tgz", + "integrity": "sha512-3DeNIcsQixWHHKk6NdoBhWI4t1VMj5/HzfnI1rE/pLl5qKx7+gd4DNA07ehTaZ6MoUU053si6Hd+YtiM/tQZfg==", + "optional": true }, "module-deps": { "version": "6.2.3", @@ -28170,31 +27438,22 @@ } }, "nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", "optional": true, "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" }, "dependencies": { - "@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "optional": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "optional": true }, "path-to-regexp": { @@ -29363,7 +28622,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "devOptional": true + "optional": true, + "peer": true }, "qrcode": { "version": "1.5.0", @@ -29412,12 +28672,6 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "optional": true - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -29730,7 +28984,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "devOptional": true + "optional": true, + "peer": true }, "rimraf": { "version": "3.0.2", @@ -29875,23 +29130,6 @@ "lru-cache": "^6.0.0" } }, - "semver-dsl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", - "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", - "dev": true, - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", @@ -30091,9 +29329,9 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" }, "signal-exit": { "version": "3.0.7", @@ -30106,23 +29344,23 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "sinon": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", - "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", + "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", "optional": true, "requires": { "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^8.1.0", - "@sinonjs/samsam": "^6.0.2", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^6.1.1", "diff": "^5.0.0", - "nise": "^5.1.0", + "nise": "^5.1.1", "supports-color": "^7.2.0" }, "dependencies": { "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "optional": true }, "has-flag": { @@ -30146,7 +29384,8 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "optional": true + "optional": true, + "requires": {} }, "slash": { "version": "4.0.0", @@ -30385,12 +29624,6 @@ "through": "2" } }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -30417,9 +29650,9 @@ } }, "start-server-and-test": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.6.tgz", - "integrity": "sha512-2N+JgOCJIM36KqKZdER7+ybJqVCJRyND42wIUvK+T1iE015ee/FAVArjSHqnSBismQghPUsfV7fB8lCFcpL7/w==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.14.0.tgz", + "integrity": "sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==", "optional": true, "requires": { "bluebird": "3.7.2", @@ -30428,7 +29661,7 @@ "execa": "5.1.1", "lazy-ass": "1.6.0", "ps-tree": "1.2.0", - "wait-on": "5.3.0" + "wait-on": "6.0.0" } }, "statuses": { @@ -30482,7 +29715,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz", "integrity": "sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "date-format": "^4.0.3", "debug": "^4.1.1", @@ -30903,16 +30137,38 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" }, "ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", + "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", "dev": true, "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } } }, "tslib": { @@ -30920,58 +30176,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -31217,16 +30421,6 @@ } } }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "optional": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -31248,6 +30442,12 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -31281,7 +30481,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "devOptional": true + "optional": true, + "peer": true }, "w3c-hr-time": { "version": "1.0.2", @@ -31301,33 +30502,16 @@ } }, "wait-on": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz", - "integrity": "sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz", + "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==", "optional": true, "requires": { "axios": "^0.21.1", - "joi": "^17.3.0", + "joi": "^17.4.0", "lodash": "^4.17.21", "minimist": "^1.2.5", - "rxjs": "^6.6.3" - }, - "dependencies": { - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "optional": true - } + "rxjs": "^7.1.0" } }, "watchpack": { @@ -31550,18 +30734,6 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" }, - "http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, "ipaddr.js": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", @@ -31662,15 +30834,6 @@ "webidl-conversions": "^6.1.0" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", @@ -31767,7 +30930,8 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true + "dev": true, + "requires": {} }, "xhr2": { "version": "0.2.0", @@ -31815,7 +30979,8 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -31830,7 +30995,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "color-convert": "^2.0.1" } @@ -31839,7 +31005,8 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -31850,7 +31017,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "color-name": "~1.1.4" } @@ -31859,13 +31027,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "optional": true, + "peer": true }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, + "optional": true, + "peer": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -31876,13 +31046,15 @@ "version": "5.0.6", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.6.tgz", "integrity": "sha512-PlVX4Y0lDTN6E2V4ES2tEdyvXkeKzxa8c/vo0pxPr/TqbztddTP0yn7zZylIyiAuxerqj0Q5GhpJ1YJCP8LaZQ==", - "devOptional": true + "optional": true, + "peer": true }, "yargs-parser": { "version": "20.2.7", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "devOptional": true + "optional": true, + "peer": true } } }, diff --git a/frontend/package.json b/frontend/package.json index db1b27e6d..0f026b597 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -78,7 +78,6 @@ "@fortawesome/fontawesome-common-types": "~6.1.1", "@fortawesome/fontawesome-svg-core": "~6.1.1", "@fortawesome/free-solid-svg-icons": "~6.1.1", - "@juggle/resize-observer": "^3.3.1", "@mempool/mempool.js": "2.3.0", "@ng-bootstrap/ng-bootstrap": "^11.0.0", "@nguniversal/express-engine": "~13.1.1", @@ -89,7 +88,7 @@ "domino": "^2.1.6", "echarts": "~5.3.2", "express": "^4.17.1", - "lightweight-charts": "^3.3.0", + "lightweight-charts": "~3.8.0", "ngx-bootrap-multiselect": "^2.0.0", "ngx-echarts": "8.0.1", "ngx-infinite-scroll": "^10.0.1", @@ -105,31 +104,23 @@ "@angular/language-service": "~13.3.10", "@nguniversal/builders": "~13.1.1", "@types/express": "^4.17.0", - "@types/jasmine": "~4.0.3", - "@types/jasminewd2": "~2.0.10", "@types/node": "^12.11.1", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", - "codelyzer": "~6.0.2", "eslint": "^8.19.0", - "http-proxy-middleware": "^1.0.5", - "jasmine-core": "~4.1.0", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.3.19", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.0.3", - "karma-jasmine": "~5.0.0", - "karma-jasmine-html-reporter": "^1.5.0", - "ts-node": "~8.3.0", - "tslint": "~6.1.0", + "http-proxy-middleware": "~2.0.6", + "ts-node": "~10.8.1", "typescript": "~4.6.4" }, "optionalDependencies": { - "@cypress/schematic": "^1.3.0", + "@cypress/schematic": "~2.0.0", "cypress": "^10.0.2", - "cypress-fail-on-console-error": "^2.1.3", + "cypress-fail-on-console-error": "~2.1.4", "cypress-wait-until": "^1.7.1", - "mock-socket": "^9.0.3", - "start-server-and-test": "^1.12.6" + "mock-socket": "~9.1.4", + "start-server-and-test": "~1.14.0" + }, + "scarfSettings": { + "enabled": false } } diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 6951accb2..b62f586a4 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -171,7 +171,7 @@ let routes: Routes = [ { path: 'block', component: StartComponent, - children: [ + children: [ { path: ':id', component: BlockComponent @@ -258,7 +258,7 @@ let routes: Routes = [ { path: 'block', component: StartComponent, - children: [ + children: [ { path: ':id', component: BlockComponent @@ -361,7 +361,7 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') { { path: 'block', component: StartComponent, - children: [ + children: [ { path: ':id', component: BlockComponent @@ -465,7 +465,7 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') { { path: 'block', component: StartComponent, - children: [ + children: [ { path: ':id', component: BlockComponent diff --git a/frontend/src/app/components/address-labels/address-labels.component.spec.ts b/frontend/src/app/components/address-labels/address-labels.component.spec.ts deleted file mode 100644 index babcc824c..000000000 --- a/frontend/src/app/components/address-labels/address-labels.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { AddressLabelsComponent } from './address-labels.component'; - -describe('AddressLabelsComponent', () => { - let component: AddressLabelsComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ AddressLabelsComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(AddressLabelsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/amount/amount.component.spec.ts b/frontend/src/app/components/amount/amount.component.spec.ts deleted file mode 100644 index 963bdbb50..000000000 --- a/frontend/src/app/components/amount/amount.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { AmountComponent } from './amount.component'; - -describe('AmountComponent', () => { - let component: AmountComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ AmountComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(AmountComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/app/app.component.spec.ts b/frontend/src/app/components/app/app.component.spec.ts deleted file mode 100644 index edc031e56..000000000 --- a/frontend/src/app/components/app/app.component.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { TestBed, async } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], - }).compileComponents(); - })); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have as title 'mempool'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('mempool'); - }); - - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to mempool!'); - }); -}); diff --git a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss index 007a2cd06..5aaf8a91b 100644 --- a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss +++ b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss @@ -79,57 +79,3 @@ } } } - -.pool-distribution { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &:nth-child(2) { - order: 2; - @media (min-width: 485px) { - order: 3; - } - } - &:nth-child(3) { - order: 3; - @media (min-width: 485px) { - order: 2; - display: block; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: block; - } - } - .card-title { - font-size: 1rem; - color: #4a68b9; - } - .card-text { - font-size: 18px; - span { - color: #ffffff66; - font-size: 12px; - } - } - } -} - -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; -} diff --git a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts index e5ee42608..37243bd4a 100644 --- a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts +++ b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts @@ -174,7 +174,7 @@ export class BlockFeeRatesGraphComponent implements OnInit { align: 'left', }, borderColor: '#000', - formatter: function (data) { + formatter: function(data) { if (data.length <= 0) { return ''; } diff --git a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.scss b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.scss index 007a2cd06..5aaf8a91b 100644 --- a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.scss +++ b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.scss @@ -79,57 +79,3 @@ } } } - -.pool-distribution { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &:nth-child(2) { - order: 2; - @media (min-width: 485px) { - order: 3; - } - } - &:nth-child(3) { - order: 3; - @media (min-width: 485px) { - order: 2; - display: block; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: block; - } - } - .card-title { - font-size: 1rem; - color: #4a68b9; - } - .card-text { - font-size: 18px; - span { - color: #ffffff66; - font-size: 12px; - } - } - } -} - -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; -} diff --git a/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.html b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.html new file mode 100644 index 000000000..79806eb2b --- /dev/null +++ b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.html @@ -0,0 +1,52 @@ + + +
+
+ Block Predictions Accuracy + +
+
+ + + + + + + + + + +
+
+
+ +
+
+
+
+
+ +
diff --git a/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.scss b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.scss new file mode 100644 index 000000000..5aaf8a91b --- /dev/null +++ b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.scss @@ -0,0 +1,81 @@ +.card-header { + border-bottom: 0; + font-size: 18px; + @media (min-width: 465px) { + font-size: 20px; + } +} + +.main-title { + position: relative; + color: #ffffff91; + margin-top: -13px; + font-size: 10px; + text-transform: uppercase; + font-weight: 500; + text-align: center; + padding-bottom: 3px; +} + +.full-container { + padding: 0px 15px; + width: 100%; + min-height: 500px; + height: calc(100% - 150px); + @media (max-width: 992px) { + height: 100%; + padding-bottom: 100px; + }; +} + +.chart { + width: 100%; + height: 100%; + padding-bottom: 20px; + padding-right: 10px; + @media (max-width: 992px) { + padding-bottom: 25px; + } + @media (max-width: 829px) { + padding-bottom: 50px; + } + @media (max-width: 767px) { + padding-bottom: 25px; + } + @media (max-width: 629px) { + padding-bottom: 55px; + } + @media (max-width: 567px) { + padding-bottom: 55px; + } +} +.chart-widget { + width: 100%; + height: 100%; + max-height: 270px; +} + +.formRadioGroup { + margin-top: 6px; + display: flex; + flex-direction: column; + @media (min-width: 991px) { + position: relative; + top: -65px; + } + @media (min-width: 830px) and (max-width: 991px) { + position: relative; + top: 0px; + } + @media (min-width: 830px) { + flex-direction: row; + float: right; + margin-top: 0px; + } + .btn-sm { + font-size: 9px; + @media (min-width: 830px) { + font-size: 14px; + } + } +} diff --git a/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.ts b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.ts new file mode 100644 index 000000000..b2ec7116c --- /dev/null +++ b/frontend/src/app/components/block-predictions-graph/block-predictions-graph.component.ts @@ -0,0 +1,289 @@ +import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, OnInit } from '@angular/core'; +import { EChartsOption } from 'echarts'; +import { Observable } from 'rxjs'; +import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; +import { ApiService } from 'src/app/services/api.service'; +import { SeoService } from 'src/app/services/seo.service'; +import { formatNumber } from '@angular/common'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils'; +import { StorageService } from 'src/app/services/storage.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe'; +import { StateService } from 'src/app/services/state.service'; + +@Component({ + selector: 'app-block-predictions-graph', + templateUrl: './block-predictions-graph.component.html', + styleUrls: ['./block-predictions-graph.component.scss'], + styles: [` + .loadingGraphs { + position: absolute; + top: 50%; + left: calc(50% - 15px); + z-index: 100; + } + `], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BlockPredictionsGraphComponent implements OnInit { + @Input() right: number | string = 45; + @Input() left: number | string = 75; + + miningWindowPreference: string; + radioGroupForm: FormGroup; + + chartOptions: EChartsOption = {}; + chartInitOptions = { + renderer: 'svg', + }; + + statsObservable$: Observable; + isLoading = true; + formatNumber = formatNumber; + timespan = ''; + chartInstance: any = undefined; + + constructor( + @Inject(LOCALE_ID) public locale: string, + private seoService: SeoService, + private apiService: ApiService, + private formBuilder: FormBuilder, + private storageService: StorageService, + private zone: NgZone, + private route: ActivatedRoute, + private stateService: StateService, + private router: Router, + ) { + this.radioGroupForm = this.formBuilder.group({ dateSpan: '1y' }); + this.radioGroupForm.controls.dateSpan.setValue('1y'); + } + + ngOnInit(): void { + this.seoService.setTitle($localize`Block predictions accuracy`); + this.miningWindowPreference = '24h';//this.miningService.getDefaultTimespan('24h'); + this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); + this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); + + this.route + .fragment + .subscribe((fragment) => { + if (['24h', '3d', '1w', '1m', '3m', '6m', '1y', '2y', '3y', 'all'].indexOf(fragment) > -1) { + this.radioGroupForm.controls.dateSpan.setValue(fragment, { emitEvent: false }); + } + }); + + this.statsObservable$ = this.radioGroupForm.get('dateSpan').valueChanges + .pipe( + startWith(this.radioGroupForm.controls.dateSpan.value), + switchMap((timespan) => { + this.storageService.setValue('miningWindowPreference', timespan); + this.timespan = timespan; + this.isLoading = true; + return this.apiService.getHistoricalBlockPrediction$(timespan) + .pipe( + tap((response) => { + this.prepareChartOptions(response.body); + this.isLoading = false; + }), + map((response) => { + return { + blockCount: parseInt(response.headers.get('x-total-count'), 10), + }; + }), + ); + }), + share() + ); + } + + prepareChartOptions(data) { + this.chartOptions = { + animation: false, + grid: { + top: 30, + bottom: 80, + right: this.right, + left: this.left, + }, + tooltip: { + show: !this.isMobile(), + trigger: 'axis', + axisPointer: { + type: 'line' + }, + backgroundColor: 'rgba(17, 19, 31, 1)', + borderRadius: 4, + shadowColor: 'rgba(0, 0, 0, 0.5)', + textStyle: { + color: '#b1b1b1', + align: 'left', + }, + borderColor: '#000', + formatter: (ticks) => { + let tooltip = `${formatterXAxis(this.locale, this.timespan, parseInt(ticks[0].axisValue, 10) * 1000)}
`; + tooltip += `${ticks[0].marker} ${ticks[0].seriesName}: ${formatNumber(ticks[0].data.value, this.locale, '1.2-2')}%
`; + + if (['24h', '3d'].includes(this.timespan)) { + tooltip += `` + $localize`At block: ${ticks[0].data.block}` + ``; + } else { + tooltip += `` + $localize`Around block: ${ticks[0].data.block}` + ``; + } + + return tooltip; + } + }, + xAxis: { + name: formatterXAxisLabel(this.locale, this.timespan), + nameLocation: 'middle', + nameTextStyle: { + padding: [10, 0, 0, 0], + }, + type: 'category', + boundaryGap: false, + axisLine: { onZero: true }, + axisLabel: { + formatter: val => formatterXAxisTimeCategory(this.locale, this.timespan, parseInt(val, 10)), + align: 'center', + fontSize: 11, + lineHeight: 12, + hideOverlap: true, + padding: [0, 5], + }, + data: data.map(prediction => prediction[0]) + }, + yAxis: [ + { + type: 'value', + axisLabel: { + color: 'rgb(110, 112, 121)', + formatter: (val) => { + return `${val}%`; + } + }, + splitLine: { + lineStyle: { + type: 'dotted', + color: '#ffffff66', + opacity: 0.25, + } + }, + }, + ], + series: [ + { + zlevel: 0, + name: $localize`Match rate`, + data: data.map(prediction => ({ + value: prediction[2], + block: prediction[1], + itemStyle: { + color: this.getPredictionColor(prediction[2]) + } + })), + type: 'bar', + barWidth: '90%', + }, + ], + dataZoom: [{ + type: 'inside', + realtime: true, + zoomLock: true, + maxSpan: 100, + minSpan: 5, + moveOnMouseMove: false, + }, { + showDetail: false, + show: true, + type: 'slider', + brushSelect: false, + realtime: true, + left: 20, + right: 15, + selectedDataBackground: { + lineStyle: { + color: '#fff', + opacity: 0.45, + }, + areaStyle: { + opacity: 0, + } + }, + }], + }; + } + + colorGradient(fadeFraction, rgbColor1, rgbColor2, rgbColor3) { + let color1 = rgbColor1; + let color2 = rgbColor2; + let fade = fadeFraction; + + // Do we have 3 colors for the gradient? Need to adjust the params. + if (rgbColor3) { + fade = fade * 2; + + // Find which interval to use and adjust the fade percentage + if (fade >= 1) { + fade -= 1; + color1 = rgbColor2; + color2 = rgbColor3; + } + } + + const diffRed = color2.red - color1.red; + const diffGreen = color2.green - color1.green; + const diffBlue = color2.blue - color1.blue; + + const gradient = { + red: Math.floor(color1.red + (diffRed * fade)), + green: Math.floor(color1.green + (diffGreen * fade)), + blue: Math.floor(color1.blue + (diffBlue * fade)), + }; + + return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')'; + } + + getPredictionColor(matchRate) { + return this.colorGradient( + Math.pow((100 - matchRate) / 100, 0.5), + {red: 67, green: 171, blue: 71}, + {red: 253, green: 216, blue: 53}, + {red: 244, green: 0, blue: 0}, + ); + } + + onChartInit(ec) { + this.chartInstance = ec; + + this.chartInstance.on('click', (e) => { + this.zone.run(() => { + if (['24h', '3d'].includes(this.timespan)) { + const url = new RelativeUrlPipe(this.stateService).transform(`/block/${e.data.block}`); + this.router.navigate([url]); + } + }); + }); + } + + isMobile() { + return (window.innerWidth <= 767.98); + } + + onSaveChart() { + // @ts-ignore + const prevBottom = this.chartOptions.grid.bottom; + const now = new Date(); + // @ts-ignore + this.chartOptions.grid.bottom = 40; + this.chartOptions.backgroundColor = '#11131f'; + this.chartInstance.setOption(this.chartOptions); + download(this.chartInstance.getDataURL({ + pixelRatio: 2, + excludeComponents: ['dataZoom'], + }), `block-fees-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`); + // @ts-ignore + this.chartOptions.grid.bottom = prevBottom; + this.chartOptions.backgroundColor = 'none'; + this.chartInstance.setOption(this.chartOptions); + } +} diff --git a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.scss b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.scss index 007a2cd06..5aaf8a91b 100644 --- a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.scss +++ b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.scss @@ -79,57 +79,3 @@ } } } - -.pool-distribution { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &:nth-child(2) { - order: 2; - @media (min-width: 485px) { - order: 3; - } - } - &:nth-child(3) { - order: 3; - @media (min-width: 485px) { - order: 2; - display: block; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: block; - } - } - .card-title { - font-size: 1rem; - color: #4a68b9; - } - .card-text { - font-size: 18px; - span { - color: #ffffff66; - font-size: 12px; - } - } - } -} - -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; -} diff --git a/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.scss b/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.scss index 86c1f8ec3..a47f63923 100644 --- a/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.scss +++ b/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.scss @@ -79,57 +79,3 @@ } } } - -.pool-distribution { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &:nth-child(2) { - order: 2; - @media (min-width: 485px) { - order: 3; - } - } - &:nth-child(3) { - order: 3; - @media (min-width: 485px) { - order: 2; - display: block; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: block; - } - } - .card-title { - font-size: 1rem; - color: #4a68b9; - } - .card-text { - font-size: 18px; - span { - color: #ffffff66; - font-size: 12px; - } - } - } -} - -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; -} \ No newline at end of file diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index 1216ecc30..782a50b58 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -50,7 +50,7 @@ Hash - {{ block.id | shortenString : 13 }} + ‎{{ block.id | shortenString : 13 }} Timestamp @@ -358,7 +358,7 @@
Error loading data.

- {{ error.code }}: {{ error.error }} + {{ error.status }}: {{ error.error }}
diff --git a/frontend/src/app/components/clipboard/clipboard.component.spec.ts b/frontend/src/app/components/clipboard/clipboard.component.spec.ts deleted file mode 100644 index a9b89d62c..000000000 --- a/frontend/src/app/components/clipboard/clipboard.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ClipboardComponent } from './clipboard.component'; - -describe('ClipboardComponent', () => { - let component: ClipboardComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ ClipboardComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ClipboardComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/graphs/graphs.component.html b/frontend/src/app/components/graphs/graphs.component.html index b02adae5e..aca62a4dd 100644 --- a/frontend/src/app/components/graphs/graphs.component.html +++ b/frontend/src/app/components/graphs/graphs.component.html @@ -1,4 +1,4 @@ - diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts index 1ee3c20c0..0e9e05167 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -11,6 +11,7 @@ import { StorageService } from 'src/app/services/storage.service'; import { MiningService } from 'src/app/services/mining.service'; import { download } from 'src/app/shared/graphs.utils'; import { ActivatedRoute } from '@angular/router'; +import { StateService } from 'src/app/services/state.service'; @Component({ selector: 'app-hashrate-chart', @@ -47,7 +48,7 @@ export class HashrateChartComponent implements OnInit { formatNumber = formatNumber; timespan = ''; chartInstance: any = undefined; - maResolution: number = 30; + network = ''; constructor( @Inject(LOCALE_ID) public locale: string, @@ -57,17 +58,20 @@ export class HashrateChartComponent implements OnInit { private storageService: StorageService, private miningService: MiningService, private route: ActivatedRoute, + private stateService: StateService ) { } ngOnInit(): void { + this.stateService.networkChanged$.subscribe((network) => this.network = network); + let firstRun = true; if (this.widget) { this.miningWindowPreference = '1y'; } else { this.seoService.setTitle($localize`:@@3510fc6daa1d975f331e3a717bdf1a34efa06dff:Hashrate & Difficulty`); - this.miningWindowPreference = this.miningService.getDefaultTimespan('1m'); + this.miningWindowPreference = this.miningService.getDefaultTimespan('3m'); } this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); @@ -124,17 +128,14 @@ export class HashrateChartComponent implements OnInit { ++diffIndex; } - this.maResolution = 30; - if (["3m", "6m"].includes(this.timespan)) { - this.maResolution = 7; - } + let maResolution = 15; const hashrateMa = []; - for (let i = this.maResolution - 1; i < data.hashrates.length; ++i) { + for (let i = maResolution - 1; i < data.hashrates.length; ++i) { let avg = 0; - for (let y = this.maResolution - 1; y >= 0; --y) { + for (let y = maResolution - 1; y >= 0; --y) { avg += data.hashrates[i - y].avgHashrate; } - avg /= this.maResolution; + avg /= maResolution; hashrateMa.push([data.hashrates[i].timestamp * 1000, avg]); } @@ -276,17 +277,17 @@ export class HashrateChartComponent implements OnInit { }, }, { - name: $localize`::Difficulty`, + name: $localize`:@@25148835d92465353fc5fe8897c27d5369978e5a:Difficulty`, inactiveColor: 'rgb(110, 112, 121)', - textStyle: { + textStyle: { color: 'white', }, icon: 'roundRect', }, { - name: $localize`Hashrate` + ` (MA${this.maResolution})`, + name: $localize`Hashrate (MA)`, inactiveColor: 'rgb(110, 112, 121)', - textStyle: { + textStyle: { color: 'white', }, icon: 'roundRect', @@ -295,11 +296,18 @@ export class HashrateChartComponent implements OnInit { }, }, ], + selected: JSON.parse(this.storageService.getValue('hashrate_difficulty_legend')) ?? { + '$localize`:@@79a9dc5b1caca3cbeb1733a19515edacc5fc7920:Hashrate`': true, + '$localize`::Difficulty`': this.network === '', + '$localize`Hashrate (MA)`': true, + }, }, yAxis: data.hashrates.length === 0 ? undefined : [ { min: (value) => { - return value.min * 0.9; + const selectedPowerOfTen: any = selectPowerOfTen(value.min); + const newMin = Math.floor(value.min / selectedPowerOfTen.divider / 10); + return newMin * selectedPowerOfTen.divider * 10; }, type: 'value', axisLabel: { @@ -363,7 +371,7 @@ export class HashrateChartComponent implements OnInit { }, { zlevel: 2, - name: $localize`Hashrate` + ` (MA${this.maResolution})`, + name: $localize`Hashrate (MA)`, showSymbol: false, symbol: 'none', data: data.hashrateMa, @@ -404,6 +412,10 @@ export class HashrateChartComponent implements OnInit { onChartInit(ec) { this.chartInstance = ec; + + this.chartInstance.on('legendselectchanged', (e) => { + this.storageService.setValue('hashrate_difficulty_legend', JSON.stringify(e.selected)); + }); } isMobile() { diff --git a/frontend/src/app/components/mempool-block/mempool-block.component.spec.ts b/frontend/src/app/components/mempool-block/mempool-block.component.spec.ts deleted file mode 100644 index d3d98a433..000000000 --- a/frontend/src/app/components/mempool-block/mempool-block.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { MempoolBlockComponent } from './mempool-block.component'; - -describe('MempoolBlockComponent', () => { - let component: MempoolBlockComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ MempoolBlockComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MempoolBlockComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html index b0ec46ac5..5549698df 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html @@ -40,7 +40,7 @@ diff --git a/frontend/src/app/components/push-transaction/push-transaction.component.html b/frontend/src/app/components/push-transaction/push-transaction.component.html index d0693ed2c..dff79afbb 100644 --- a/frontend/src/app/components/push-transaction/push-transaction.component.html +++ b/frontend/src/app/components/push-transaction/push-transaction.component.html @@ -1,5 +1,5 @@
-

Broadcast Transaction

+

Broadcast Transaction

diff --git a/frontend/src/app/components/qrcode/qrcode.component.spec.ts b/frontend/src/app/components/qrcode/qrcode.component.spec.ts deleted file mode 100644 index 9597f88cf..000000000 --- a/frontend/src/app/components/qrcode/qrcode.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { QrcodeComponent } from './qrcode.component'; - -describe('QrcodeComponent', () => { - let component: QrcodeComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ QrcodeComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(QrcodeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/qrcode/qrcode.component.ts b/frontend/src/app/components/qrcode/qrcode.component.ts index 1a0c7604d..30c8a8362 100644 --- a/frontend/src/app/components/qrcode/qrcode.component.ts +++ b/frontend/src/app/components/qrcode/qrcode.component.ts @@ -24,7 +24,7 @@ export class QrcodeComponent implements AfterViewInit { return; } const opts: QRCode.QRCodeRenderersOptions = { - errorCorrectionLevel: 'H', + errorCorrectionLevel: 'L', margin: 0, color: { dark: '#000', @@ -38,7 +38,11 @@ export class QrcodeComponent implements AfterViewInit { } const address = this.data; - if (this.data.indexOf('bc1') === 0 || this.data.indexOf('tb1') === 0) { + if ( + this.data.indexOf('bc1') === 0 || + this.data.indexOf('tb1') === 0 || + this.data.indexOf('bcrt1') === 0 + ) { address.toUpperCase(); } diff --git a/frontend/src/app/components/search-form/search-form.component.spec.ts b/frontend/src/app/components/search-form/search-form.component.spec.ts deleted file mode 100644 index 2422e96d2..000000000 --- a/frontend/src/app/components/search-form/search-form.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { SearchFormComponent } from './search-form.component'; - -describe('SearchFormComponent', () => { - let component: SearchFormComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ SearchFormComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(SearchFormComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/start/start.component.spec.ts b/frontend/src/app/components/start/start.component.spec.ts deleted file mode 100644 index 01270a2d5..000000000 --- a/frontend/src/app/components/start/start.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { StartComponent } from './start.component'; - -describe('StartComponent', () => { - let component: StartComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ StartComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(StartComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.html b/frontend/src/app/components/transactions-list/transactions-list.component.html index 0c1e46390..16e6b9b2f 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.html +++ b/frontend/src/app/components/transactions-list/transactions-list.component.html @@ -66,9 +66,9 @@ - + {{ vin.prevout.scriptpubkey_address | shortenString : 16 }} - + {{ vin.prevout.scriptpubkey_address }} {{ vin.prevout.scriptpubkey_address | capAddress: 40: 10 }} @@ -164,9 +164,9 @@ 'highlight': vout.scriptpubkey_address === this.address && this.address !== '' }"> - + {{ vout.scriptpubkey_address | shortenString : 16 }} - + {{ vout.scriptpubkey_address }} {{ vout.scriptpubkey_address | capAddress: 40: 10 }} diff --git a/frontend/src/app/docs/api-docs/api-docs-data.ts b/frontend/src/app/docs/api-docs/api-docs-data.ts index f69aa4a0f..f8f0e23b8 100644 --- a/frontend/src/app/docs/api-docs/api-docs-data.ts +++ b/frontend/src/app/docs/api-docs/api-docs-data.ts @@ -6017,6 +6017,20 @@ export const faqData = [ fragment: "what-are-mining-pools", title: "What are mining pools?", }, + { + type: "endpoint", + category: "basics", + showConditions: bitcoinNetworks, + fragment: "what-are-vb-wu", + title: "What are virtual bytes (vB) and weight units (WU)?", + }, + { + type: "endpoint", + category: "basics", + showConditions: bitcoinNetworks, + fragment: "what-is-svb", + title: "What is sat/vB?", + }, { type: "endpoint", category: "basics", diff --git a/frontend/src/app/docs/api-docs/api-docs.component.html b/frontend/src/app/docs/api-docs/api-docs.component.html index 1f6fca48c..bae5dfd05 100644 --- a/frontend/src/app/docs/api-docs/api-docs.component.html +++ b/frontend/src/app/docs/api-docs/api-docs.component.html @@ -134,6 +134,19 @@ Mining pools are groups of miners that combine their computational power in order to increase the probability of finding new blocks. + +

Virtual bytes (vB) and weight units (WU) are used to measure the size of transactions and blocks on the Bitcoin network.

+

A Bitcoin transaction's size in the blockchain is not determined how much bitcoin it transfers—instead, a transaction's size is determined by technical factors such as how many inputs and outputs it has, how many signatures it has, and the format it uses (legacy, SegWit, etc). Since space in the Bitcoin blockchain is limited, bigger transactions pay more in mining fees than smaller transactions.

+

Block sizes are limited to 4,000,000 WU (or 1,000,000 vB since 1 vB = 4 WU).

+

Transaction sizes and block sizes used to be measured in plain bytes, but virtual bytes and weight units were devised to maintain backward compatibility after the SegWit upgrade in 2017. See this post for more details.

+ + + +

The priority of a pending Bitcoin transaction is determined by its feerate. Feerates are measured in sat/vB.

+

Using a higher sat/vB feerate for a Bitcoin transaction will generally result in quicker confirmation than using a lower feerate. But feerates change all the time, so it's important to check suggested feerates right before making a transaction to avoid it from getting stuck.

+

There are feerate estimates on the top of the main dashboard you can use as a guide. See this FAQ for more on picking the right feerate.

+
+

When a Bitcoin transaction is made, it is stored in a Bitcoin node's mempool before it is confirmed into a block. When the rate of incoming transactions exceeds the rate transactions are confirmed, the mempool grows in size.

The default maximum size of a Bitcoin node's mempool is 300MB, so when there are 300MB of transactions in the mempool, we say it's "full".

diff --git a/frontend/src/app/fiat/fiat.component.spec.ts b/frontend/src/app/fiat/fiat.component.spec.ts deleted file mode 100644 index a7f4821dc..000000000 --- a/frontend/src/app/fiat/fiat.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FiatComponent } from './fiat.component'; - -describe('FiatComponent', () => { - let component: FiatComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ FiatComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(FiatComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/graphs/graphs.module.ts b/frontend/src/app/graphs/graphs.module.ts index 5d17ae43a..8cdc51608 100644 --- a/frontend/src/app/graphs/graphs.module.ts +++ b/frontend/src/app/graphs/graphs.module.ts @@ -22,6 +22,7 @@ import { DashboardComponent } from '../dashboard/dashboard.component'; import { MiningDashboardComponent } from '../components/mining-dashboard/mining-dashboard.component'; import { HashrateChartComponent } from '../components/hashrate-chart/hashrate-chart.component'; import { HashrateChartPoolsComponent } from '../components/hashrates-chart-pools/hashrate-chart-pools.component'; +import { BlockPredictionsGraphComponent } from '../components/block-predictions-graph/block-predictions-graph.component'; import { CommonModule } from '@angular/common'; @NgModule({ @@ -47,6 +48,7 @@ import { CommonModule } from '@angular/common'; LbtcPegsGraphComponent, HashrateChartComponent, HashrateChartPoolsComponent, + BlockPredictionsGraphComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/graphs/graphs.routing.module.ts b/frontend/src/app/graphs/graphs.routing.module.ts index 5f2e89b59..fd3efaba4 100644 --- a/frontend/src/app/graphs/graphs.routing.module.ts +++ b/frontend/src/app/graphs/graphs.routing.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { BlockPredictionsGraphComponent } from '../components/block-predictions-graph/block-predictions-graph.component'; import { BlockFeeRatesGraphComponent } from '../components/block-fee-rates-graph/block-fee-rates-graph.component'; import { BlockFeesGraphComponent } from '../components/block-fees-graph/block-fees-graph.component'; import { BlockRewardsGraphComponent } from '../components/block-rewards-graph/block-rewards-graph.component'; @@ -92,6 +93,10 @@ const routes: Routes = [ path: '', redirectTo: 'mempool', }, + { + path: 'mining/block-predictions', + component: BlockPredictionsGraphComponent, + }, ] }, { diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 5efa745d1..a0b3d8ff7 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -221,6 +221,13 @@ export class ApiService { ); } + getHistoricalBlockPrediction$(interval: string | undefined) : Observable { + return this.httpClient.get( + this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/blocks/predictions` + + (interval !== undefined ? `/${interval}` : ''), { observe: 'response' } + ); + } + getRewardStats$(blockCount: number = 144): Observable { return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/reward-stats/${blockCount}`); } diff --git a/frontend/src/app/shared/pipes/absolute/absolute.pipe.spec.ts b/frontend/src/app/shared/pipes/absolute/absolute.pipe.spec.ts deleted file mode 100644 index d9ad3f3df..000000000 --- a/frontend/src/app/shared/pipes/absolute/absolute.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AbsolutePipe } from './absolute.pipe'; - -describe('AbsolutePipe', () => { - it('create an instance', () => { - const pipe = new AbsolutePipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/shared/pipes/asm-styler/asm-styler.pipe.spec.ts b/frontend/src/app/shared/pipes/asm-styler/asm-styler.pipe.spec.ts deleted file mode 100644 index 8e7d28265..000000000 --- a/frontend/src/app/shared/pipes/asm-styler/asm-styler.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AsmStylerPipe } from './asm-styler.pipe'; - -describe('OpcodesStylerPipe', () => { - it('create an instance', () => { - const pipe = new AsmStylerPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.spec.ts b/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.spec.ts deleted file mode 100644 index 0328ff748..000000000 --- a/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { FeeRoundingPipe } from './fee-rounding.pipe'; - -describe('FeeRoundingPipe', () => { - it('create an instance', () => { - const pipe = new FeeRoundingPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/shared/pipes/hex2ascii/hex2ascii.pipe.spec.ts b/frontend/src/app/shared/pipes/hex2ascii/hex2ascii.pipe.spec.ts deleted file mode 100644 index 7db7406ac..000000000 --- a/frontend/src/app/shared/pipes/hex2ascii/hex2ascii.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Hex2asciiPipe } from './hex2ascii.pipe'; - -describe('Hex2asciiPipe', () => { - it('create an instance', () => { - const pipe = new Hex2asciiPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.spec.ts b/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.spec.ts deleted file mode 100644 index 5bc82d35f..000000000 --- a/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RelativeUrlPipe } from './relative-url.pipe'; - -describe('RelativeUrlPipe', () => { - it('create an instance', () => { - const pipe = new RelativeUrlPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index a44d2c30d..7899d943f 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -852,6 +852,40 @@ th { } } + .fee-progress-bar { + @extend .fee-progress-bar; + &.priority { + @media (767px < width < 992px), (width < 576px) { + width: 100%; + } + width: 75%; + border-radius: 10px 0px 0px 10px !important; + } + } + + .fees-wrapper-tooltip-chart { + @extend .fees-wrapper-tooltip-chart; + .title { + direction: rtl; + } + } + + .btn-link { + padding: 0.1rem 0.5rem 0.25rem 0 !important; + } + + .shortable-address { + direction: ltr; + } + + .lastest-blocks-table { + @extend .lastest-blocks-table; + .table-cell-mined { + @extend .table-cell-mined; + text-align: right !important; + } + } + .mempool-graph { @extend .mempool-graph; direction: ltr; diff --git a/frontend/src/test.ts b/frontend/src/test.ts deleted file mode 100644 index 6b03dbe8b..000000000 --- a/frontend/src/test.ts +++ /dev/null @@ -1,22 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare const require: any; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), { - teardown: { destroyAfterEach: false } -} -); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/frontend/tslint.json b/frontend/tslint.json deleted file mode 100644 index 4b0e69b15..000000000 --- a/frontend/tslint.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "extends": "tslint:recommended", - "rules": { - "align": { - "options": [ - "parameters", - "statements" - ] - }, - "array-type": false, - "forin": false, - "arrow-parens": false, - "arrow-return-shorthand": true, - "curly": true, - "no-bitwise": false, - "deprecation": { - "severity": "warning" - }, - "component-class-suffix": true, - "contextual-lifecycle": true, - "directive-class-suffix": true, - "eofline": true, - "import-spacing": true, - "indent": { - "options": [ - "spaces" - ] - }, - "object-literal-shorthand": false, - "directive-selector": [ - true, - "attribute", - "app", - "camelCase" - ], - "component-selector": [ - true, - "element", - "app", - "kebab-case" - ], - "import-blacklist": [ - true, - "rxjs/Rx" - ], - "interface-name": false, - "max-classes-per-file": false, - "max-line-length": [ - true, - 140 - ], - "member-access": false, - "member-ordering": [ - true, - { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] - } - ], - "no-consecutive-blank-lines": false, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-empty": false, - "no-inferrable-types": [ - true, - "ignore-params" - ], - "no-non-null-assertion": true, - "no-redundant-jsdoc": true, - "no-switch-case-fall-through": true, - "no-var-requires": false, - "object-literal-key-quotes": [ - false, - "as-needed" - ], - "object-literal-sort-keys": false, - "ordered-imports": false, - "quotemark": [ - true, - "single" - ], - "semicolon": { - "options": [ - "always" - ] - }, - "space-before-function-paren": { - "options": { - "anonymous": "never", - "asyncArrow": "always", - "constructor": "never", - "method": "never", - "named": "never" - } - }, - "trailing-comma": false, - "no-conflicting-lifecycle": true, - "no-host-metadata-property": true, - "no-input-rename": true, - "no-inputs-metadata-property": true, - "no-output-native": true, - "no-output-on-prefix": true, - "no-output-rename": true, - "no-outputs-metadata-property": true, - "template-banana-in-box": true, - "template-no-negated-async": true, - "typedef-whitespace": { - "options": [ - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - }, - { - "call-signature": "onespace", - "index-signature": "onespace", - "parameter": "onespace", - "property-declaration": "onespace", - "variable-declaration": "onespace" - } - ] - }, - "use-lifecycle-interface": true, - "use-pipe-transform-interface": true - , "variable-name": { - "options": [ - "ban-keywords", - "check-format", - "allow-pascal-case" - ] - }, - "whitespace": { - "options": [ - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type", - "check-typecast" - ] - } -}, - "rulesDirectory": [ - "codelyzer" - ] -} \ No newline at end of file diff --git a/production/electrs-start-liquid b/production/electrs-start-liquid index 64564e7f7..a59004478 100755 --- a/production/electrs-start-liquid +++ b/production/electrs-start-liquid @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh cd "${HOME}/electrs" #source "${HOME}/.cargo/env" #export PATH="${HOME}/.cargo/bin:${PATH}" diff --git a/production/electrs-start-mainnet b/production/electrs-start-mainnet index d6f964f73..32227afd2 100755 --- a/production/electrs-start-mainnet +++ b/production/electrs-start-mainnet @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh cd "${HOME}/electrs" #source "${HOME}/.cargo/env" #export PATH="${HOME}/.cargo/bin:${PATH}" diff --git a/production/electrs-start-signet b/production/electrs-start-signet index 6f7919f83..c37b670f6 100755 --- a/production/electrs-start-signet +++ b/production/electrs-start-signet @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh cd "${HOME}/electrs" #source "${HOME}/.cargo/env" #export PATH="${HOME}/.cargo/bin:${PATH}" diff --git a/production/electrs-start-testnet b/production/electrs-start-testnet index 7096629dd..42e057a52 100755 --- a/production/electrs-start-testnet +++ b/production/electrs-start-testnet @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh cd "${HOME}/electrs" #source $HOME/.cargo/env #export PATH=$HOME/.cargo/bin:$PATH diff --git a/production/install b/production/install index 9f2533c61..19ff128a6 100755 --- a/production/install +++ b/production/install @@ -6,11 +6,13 @@ case `uname -s` in FreeBSD) OS=FreeBSD + NPROC=$(sysctl hw.ncpu | awk '{print $2}') ;; Linux) if [ "$(grep -Ei 'debian|buntu|mint' /etc/*release)" ]; then OS=Debian + NPROC=$(nproc --all) else echo "Your distribution of Linux is not yet supported by this installation script" exit 1 @@ -39,6 +41,7 @@ ELEMENTS_INSTALL=ON # configure 4 network instances BITCOIN_MAINNET_ENABLE=ON +BITCOIN_MAINNET_MINFEE_ENABLE=ON BITCOIN_TESTNET_ENABLE=ON BITCOIN_SIGNET_ENABLE=ON BISQ_MAINNET_ENABLE=ON @@ -682,6 +685,7 @@ $CUT >$input <<-EOF Tor:Enable Tor v3 HS Onion:ON Certbot:Enable HTTPS using Certbot:ON Mainnet:Enable Bitcoin Mainnet:ON +Mainnet-Minfee:Enable Bitcoin Mainnet Minfee:ON Testnet:Enable Bitcoin Testnet:ON Liquid:Enable Elements Liquid:ON Bisq:Enable Bisq:ON @@ -725,6 +729,12 @@ else BITCOIN_MAINNET_ENABLE=OFF fi +if grep Mainnet-Minfee $tempfile >/dev/null 2>&1;then + BITCOIN_MAINNET_MINFEE_ENABLE=ON +else + BITCOIN_MAINNET_MINFEE_ENABLE=OFF +fi + if grep Testnet $tempfile >/dev/null 2>&1;then BITCOIN_TESTNET_ENABLE=ON else @@ -964,7 +974,7 @@ if [ "${BITCOIN_INSTALL}" = ON ];then echo "[*] Building Bitcoin from source repo" osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && ./autogen.sh --quiet" osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && MAKE=gmake CC=cc CXX=c++ CPPFLAGS=-I/usr/local/include ./configure --with-gui=no --disable-wallet --disable-tests" - osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && gmake -j48" + osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && gmake -j${NPROC}" echo "[*] Installing Bitcoin binaries into OS" osSudo "${ROOT_USER}" sh -c "cd ${BITCOIN_HOME}/${BITCOIN_REPO_NAME} && gmake install" @@ -1009,7 +1019,7 @@ if [ "${ELEMENTS_INSTALL}" = ON ];then echo "[*] Building Elements from source repo" osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && ./autogen.sh --quiet" osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && MAKE=gmake CC=cc CXX=c++ CPPFLAGS=-I/usr/local/include ./configure --with-gui=no --disable-wallet --disable-tests" - osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && gmake -j48" + osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && gmake -j${NPROC}" echo "[*] Installing Elements binaries into OS" osSudo "${ROOT_USER}" sh -c "cd ${ELEMENTS_HOME}/${ELEMENTS_REPO_NAME} && gmake install" @@ -1048,7 +1058,7 @@ case $OS in ;; Debian) echo "[*] Installing Rust from rustup.rs" - osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" + osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y" ;; esac @@ -1095,15 +1105,6 @@ echo "[*] Cloning Liquid Asset Registry testnet repo from ${LIQUIDTESTNET_ASSET_ osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false osSudo "${ELEMENTS_USER}" git clone "${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUIDTESTNET_ASSET_REGISTRY_DB_NAME}" -case $OS in - FreeBSD) - ;; - Debian) - echo "[*] Installing Rust from rustup.rs" - osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" - ;; -esac - echo "[*] Building Liquid Electrs release binary" osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true @@ -1214,6 +1215,24 @@ if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then esac fi +####################################### +# Bitcoin instance for Mainnet Minfee # +####################################### + +if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then + echo "[*] Installing Bitcoin Minfee service" + case $OS in + + FreeBSD) + echo "[*] FIXME: Bitcoin Minfee service must be installed manually on FreeBSD" + ;; + + Debian) + osSudo "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/linux/bitcoin-minfee.service" "${DEBIAN_SERVICE_HOME}" + ;; + esac +fi + ################################ # Bitcoin instance for Testnet # ################################ @@ -1277,9 +1296,16 @@ if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-mainnet" "${BITCOIN_ELECTRS_HOME}" echo "[*] Installing Bitcoin crontab" - # FIXME: must only crontab enabled daemons - osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/bitcoin.crontab" - osSudo "${ROOT_USER}" crontab -u "${MINFEE_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/minfee.crontab" + case $OS in + FreeBSD) + echo [*] FIXME: must only crontab enabled daemons + osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/bitcoin.crontab" + osSudo "${ROOT_USER}" crontab -u "${MINFEE_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/minfee.crontab" + ;; + Debian) + (crontab -l ; echo "@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/electrs-start-mainnet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - + ;; + esac echo "[*] Configuring Bitcoin Mainnet RPC credentials in electrs start script" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-mainnet" @@ -1295,6 +1321,13 @@ if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then echo "[*] Installing Bitcoin Testnet electrs start script" osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-testnet" "${BITCOIN_ELECTRS_HOME}" + case $OS in + Debian) + echo "[*] Installing Bitcoin-testnet crontab" + (crontab -l ; echo "@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/electrs-start-testnet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - + ;; + esac + echo "[*] Configuring Bitcoin Testnet RPC credentials in electrs start script" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-testnet" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-testnet" @@ -1309,6 +1342,13 @@ if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then echo "[*] Installing Bitcoin Signet electrs start script" osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-signet" "${BITCOIN_ELECTRS_HOME}" + case $OS in + Debian) + echo "[*] Installing Bitcoin-signet crontab" + (crontab -l ; echo "@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/electrs-start-signet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - + ;; + esac + echo "[*] Configuring Bitcoin Signet RPC credentials in electrs start script" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-signet" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-signet" @@ -1324,8 +1364,15 @@ if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then osSudo "${ROOT_USER}" install -c -o "${ELEMENTS_USER}" -g "${ELEMENTS_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-liquid" "${ELEMENTS_ELECTRS_HOME}" echo "[*] Installing Elements crontab" - # FIXME: must only crontab enabled daemons - osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/elements.crontab" + case $OS in + FreeBSD) + echo [*] FIXME: must only crontab enabled daemons + osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/elements.crontab" + ;; + Debian) + (crontab -l ; echo "6 * * * * cd $HOME/asset_registry_db && git pull origin master >/dev/null 2>&1") | osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" - + ;; + esac echo "[*] Configuring Elements Liquid RPC credentials in electrs start script" osSudo "${ROOT_USER}" sed -i.orig "s/__ELEMENTS_RPC_USER__/${ELEMENTS_RPC_USER}/" "${ELEMENTS_ELECTRS_HOME}/electrs-start-liquid" @@ -1341,6 +1388,13 @@ if [ "${ELEMENTS_LIQUIDTESTNET_ENABLE}" = ON ];then echo "[*] Installing Elements Liquid Testnet electrs start script" osSudo "${ROOT_USER}" install -c -o "${ELEMENTS_USER}" -g "${ELEMENTS_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-liquidtestnet" "${ELEMENTS_ELECTRS_HOME}" + case $OS in + Debian) + echo "[*] Installing Elements-testnet crontab" + (crontab -l ; echo "6 * * * * cd $HOME/asset_registry_testnet_db && git pull origin master >/dev/null 2>&1") | osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" - + ;; + esac + echo "[*] Installing Elements Liquid Testnet RPC credentials" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${ELEMENTS_HOME}/elements.conf" osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${ELEMENTS_HOME}/elements.conf" @@ -1480,23 +1534,21 @@ case $OS in fi if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then osSudo "${ROOT_USER}" systemctl enable bitcoin.service - osSudo "${ROOT_USER}" systemctl enable mempool.service + fi + if [ "${BITCOIN_MAINNET_MINFEE_ENABLE}" = ON ];then + osSudo "${ROOT_USER}" systemctl enable bitcoin-minfee.service fi if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then osSudo "${ROOT_USER}" systemctl enable bitcoin-testnet.service - osSudo "${ROOT_USER}" systemctl enable mempool-testnet.service fi if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then osSudo "${ROOT_USER}" systemctl enable bitcoin-signet.service - osSudo "${ROOT_USER}" systemctl enable mempool-signet.service fi if [ "${BISQ_MAINNET_ENABLE}" = ON ];then osSudo "${ROOT_USER}" systemctl enable bisq.service - osSudo "${ROOT_USER}" systemctl enable mempool-bisq.service fi if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then osSudo "${ROOT_USER}" systemctl enable liquid.service - osSudo "${ROOT_USER}" systemctl enable mempool-liquid.service fi ;; esac diff --git a/production/linux/bitcoin-minfee.service b/production/linux/bitcoin-minfee.service new file mode 100644 index 000000000..fe70d99f0 --- /dev/null +++ b/production/linux/bitcoin-minfee.service @@ -0,0 +1,22 @@ +[Unit] +Description=Bitcoind-minfee +After=network.target + +[Service] +ExecStart=/usr/local/bin/bitcoind -daemon -printtoconsole -pid=/minfee/bitcoind-minfee.pid +ExecStop=/usr/local/bin/bitcoin-cli stop + +Type=forking +PIDFile=/minfee/bitcoind.pid +Restart=on-failure + +User=minfee +Group=minfee + +PrivateTmp=true +ProtectSystem=full +NoNewPrivileges=true +PrivateDevices=true + +[Install] +WantedBy=multi-user.target diff --git a/production/mempool-build-all b/production/mempool-build-all index d44569fe2..f50c8057b 100755 --- a/production/mempool-build-all +++ b/production/mempool-build-all @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin HOSTNAME=$(hostname) LOCATION=$(hostname|cut -d . -f2) @@ -16,10 +16,13 @@ if [ -f "${LOCKFILE}" ];then exit 1 fi -trap "rv=\$?; rm -rf "${LOCKFILE}"; exit \$rv" INT TERM EXIT +# on exit, remove lockfile but preserve exit code +trap "rv=\$?; rm -f "${LOCKFILE}"; exit \$rv" INT TERM EXIT +# create lockfile touch "${LOCKFILE}" +# notify logged in users echo "Upgrading mempool to ${REF}" | wall update_repo() @@ -84,25 +87,48 @@ ship_frontend() rsync -av "./dist/mempool/browser/" "${HOME}/public_html/${site}/" || exit 1 } +# load nvm if necessary export NVM_DIR="${HOME}/.nvm" source "${NVM_DIR}/nvm.sh" -for target in mainnet testnet signet liquid liquidtestnet bisq;do - update_repo "${target}" +# what to look for +frontends=(mainnet liquid bisq) +backends=(mainnet testnet signet liquid liquidtestnet bisq) +frontend_repos=() +backend_repos=() + +# find which frontend repos we have +for repo in $frontends;do + [ -d "${repo}" ] && frontend_repos+="${repo}" done -for target in mainnet testnet signet liquid liquidtestnet bisq;do - build_backend "${target}" +# find which backend repos we have +for repo in $backends;do + [ -d "${repo}" ] && backend_repos+="${repo}" + [ -d "${repo}-lightning" ] && backend_repos+="${repo}-lightning" done -for target in mainnet liquid bisq;do - build_frontend "${target}" +# update all repos +for repo in $backend_repos;do + update_repo "${repo}" done +# build backends +for repo in $backend_repos;do + build_backend "${repo}" +done + +# build frontends +for repo in $frontend_repos;do + build_frontend "${repo}" +done + +# ship frontend dist folders to public_html for target in mainnet liquid bisq;do ship_frontend "${target}" done +# notify everyone echo "${HOSTNAME} updated to \`${REF}\` @ \`${HASH}\`" | /usr/local/bin/keybase chat send --nonblock --channel general mempool.dev echo "${HOSTNAME} updated to \`${REF}\` @ \`${HASH}\`" | /usr/local/bin/keybase chat send --nonblock --channel general "mempool.ops.${LOCATION}" diff --git a/production/mempool-start-all b/production/mempool-start-all index 5d5199166..94766d5ce 100755 --- a/production/mempool-start-all +++ b/production/mempool-start-all @@ -1,8 +1,8 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh export NVM_DIR="$HOME/.nvm" source "$NVM_DIR/nvm.sh" -for site in mainnet liquid testnet bisq signet liquidtestnet -do + +for site in mainnet mainnet-lightning testnet testnet-lightning signet signet-lightning bisq liquid liquidtestnet;do cd "${HOME}/${site}/backend/" && \ screen -dmS "${site}" sh -c 'while true;do npm run start-production;sleep 1;done' done diff --git a/production/nginx/http-basic.conf b/production/nginx/http-basic.conf index a79c73382..5d707ca42 100644 --- a/production/nginx/http-basic.conf +++ b/production/nginx/http-basic.conf @@ -4,8 +4,6 @@ tcp_nopush on; tcp_nodelay on; server_tokens off; server_name_in_redirect off; -include /usr/local/etc/nginx/mime.types; -default_type application/octet-stream; # default logs access_log /var/log/nginx/access.log; diff --git a/production/nginx/location-api-v1-lightning.conf b/production/nginx/location-api-v1-lightning.conf new file mode 100644 index 000000000..288fe4184 --- /dev/null +++ b/production/nginx/location-api-v1-lightning.conf @@ -0,0 +1,20 @@ +# route lightning API endpoints to lightning backend +location /api/v1/lightning { + try_files /dev/null @mempool-api-v1-lightning; +} +location @mempool-api-v1-lightning { + proxy_pass $mempoolMainnetLightning; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} diff --git a/production/nginx/location-api.conf b/production/nginx/location-api.conf index 886681f5c..2b5cb0152 100644 --- a/production/nginx/location-api.conf +++ b/production/nginx/location-api.conf @@ -1,26 +1,51 @@ -location /api/v1/statistics { - try_files /dev/null @mempool-api-v1-warmcache; -} -location /api/v1/mining { - try_files /dev/null @mempool-api-v1-warmcache; -} -location /api/v1/block/ { - try_files /dev/null @mempool-api-v1-forevercache; -} -location /api/v1 { - try_files /dev/null @mempool-api-v1-coldcache; -} -location /api/block/ { - rewrite ^/api/(.*) /$1 break; - try_files /dev/null @electrs-api-forevercache; -} -location /api/ { - rewrite ^/api/(.*) /$1 break; - try_files /dev/null @electrs-api-nocache; +########### +# mempool # +########### + +# websocket has special HTTP headers +location /api/v1/ws { + try_files /dev/null @mempool-api-v1-websocket; } -location @mempool-api-v1-forevercache { - proxy_pass $mempoolBackend; +# warm cache mining and mempool API responses +location /api/v1/statistics { + try_files /dev/null @mempool-api-v1-cache-warm; +} +location /api/v1/mining { + try_files /dev/null @mempool-api-v1-cache-warm; +} + +# it's ok to cache blockchain data "forever", so we do 30d +location /api/v1/block/ { + try_files /dev/null @mempool-api-v1-cache-forever; +} + +# everything else gets "normal" cache +location /api/v1 { + try_files /dev/null @mempool-api-v1-cache-normal; +} + +########### +# esplora # +########### + +# it's ok to cache blockchain data "forever", so we do 30d +location /api/block/ { + rewrite ^/api/(.*) /$1 break; + try_files /dev/null @esplora-api-cache-forever; +} +# other API responses cannot be cached +location /api/ { + rewrite ^/api/(.*) /$1 break; + try_files /dev/null @esplora-api-cache-disabled; +} + +########### +# routing # +########### + +location @mempool-api-v1-websocket { + proxy_pass $mempoolMainnet; proxy_http_version 1.1; proxy_set_header Host $http_host; @@ -29,8 +54,16 @@ location @mempool-api-v1-forevercache { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; +} + +location @mempool-api-v1-cache-forever { + proxy_pass $mempoolMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_cache_background_update on; proxy_cache_use_stale updating; proxy_cache api; @@ -40,18 +73,14 @@ location @mempool-api-v1-forevercache { expires 30d; } -location @mempool-api-v1-warmcache { - proxy_pass $mempoolBackend; - proxy_http_version 1.1; +location @mempool-api-v1-cache-warm { + proxy_pass $mempoolMainnet; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_cache_background_update on; proxy_cache_use_stale updating; proxy_cache api; @@ -59,18 +88,14 @@ location @mempool-api-v1-warmcache { proxy_redirect off; } -location @mempool-api-v1-coldcache { - proxy_pass $mempoolBackend; - proxy_http_version 1.1; +location @mempool-api-v1-cache-normal { + proxy_pass $mempoolMainnet; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_cache api; proxy_cache_valid 200 10s; proxy_redirect off; @@ -78,54 +103,42 @@ location @mempool-api-v1-coldcache { expires 10s; } -location @mempool-api-v1-nocache { - proxy_pass $mempoolBackend; - proxy_http_version 1.1; +location @mempool-api-v1-cache-disabled { + proxy_pass $mempoolMainnet; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_redirect off; proxy_buffering off; expires -1; } -location @electrs-api-nocache { - proxy_pass $electrsBackend; - proxy_http_version 1.1; +location @esplora-api-cache-disabled { + proxy_pass $esploraMainnet; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_redirect off; proxy_buffering off; expires -1; } -location @electrs-api-forevercache { - proxy_pass $electrsBackend; - proxy_http_version 1.1; +location @esplora-api-cache-forever { + proxy_pass $esploraMainnet; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; - proxy_cache_bypass $http_upgrade; proxy_cache_background_update on; proxy_cache_use_stale updating; proxy_cache api; diff --git a/production/nginx/location-liquid-api.conf b/production/nginx/location-liquid-api.conf index 7c2f927a6..26ffffc70 100644 --- a/production/nginx/location-liquid-api.conf +++ b/production/nginx/location-liquid-api.conf @@ -1,12 +1,150 @@ +########### +# mempool # +########### + +# websocket has special HTTP headers location /liquid/api/v1/ws { - proxy_pass http://mempool-liquid-mainnet/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; + rewrite ^/liquid/(.*) /$1 break; + try_files /dev/null @mempool-liquid-api-v1-websocket; } + +# warm cache mempool API responses +location /liquid/api/v1/statistics { + rewrite ^/liquid/(.*) /$1 break; + try_files /dev/null @mempool-liquid-api-v1-cache-warm; +} + +# it's ok to cache blockchain data "forever", so we do 30d +location /liquid/api/v1/block/ { + rewrite ^/liquid/(.*) /$1 break; + try_files /dev/null @mempool-liquid-api-v1-cache-forever; +} + +# everything else gets "normal" cache location /liquid/api/v1 { - proxy_pass http://mempool-liquid-mainnet/api/v1; + rewrite ^/liquid/(.*) /$1 break; + try_files /dev/null @mempool-liquid-api-v1-cache-normal; } + +########### +# esplora # +########### + +# it's ok to cache blockchain data "forever", so we do 30d +location /liquid/api/block/ { + rewrite ^/liquid/api/(.*) /$1 break; + try_files /dev/null @esplora-liquid-api-cache-forever; +} +# other API responses cannot be cached location /liquid/api/ { - proxy_pass http://electrs-liquid-mainnet/; + rewrite ^/liquid/api/(.*) /$1 break; + try_files /dev/null @esplora-liquid-api-cache-disabled; +} + +########### +# routing # +########### + +location @mempool-liquid-api-v1-websocket { + proxy_pass $mempoolMainnet; + proxy_http_version 1.1; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Proto $scheme; +} + +location @mempool-liquid-api-v1-cache-forever { + proxy_pass $mempoolMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; +} + +location @mempool-liquid-api-v1-cache-warm { + proxy_pass $mempoolMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; +} + +location @mempool-liquid-api-v1-cache-normal { + proxy_pass $mempoolMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} + +location @mempool-liquid-api-v1-cache-disabled { + proxy_pass $mempoolMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-liquid-api-cache-disabled { + proxy_pass $esploraMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-liquid-api-cache-forever { + proxy_pass $esploraMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; } diff --git a/production/nginx/location-liquidtestnet-api.conf b/production/nginx/location-liquidtestnet-api.conf index 8b03c6fc4..311a6c317 100644 --- a/production/nginx/location-liquidtestnet-api.conf +++ b/production/nginx/location-liquidtestnet-api.conf @@ -1,12 +1,154 @@ +########### +# mempool # +########### + +# websocket has special HTTP headers location /liquidtestnet/api/v1/ws { - proxy_pass http://mempool-liquid-testnet/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; + rewrite ^/liquidtestnet/(.*) /$1 break; + try_files /dev/null @mempool-liquidtestnet-api-v1-websocket; } + +# warm cache mining and mempool API responses +location /liquidtestnet/api/v1/statistics { + rewrite ^/liquidtestnet/(.*) /$1 break; + try_files /dev/null @mempool-liquidtestnet-api-v1-cache-warm; +} +location /liquidtestnet/api/v1/mining { + rewrite ^/liquidtestnet/(.*) /$1 break; + try_files /dev/null @mempool-liquidtestnet-api-v1-cache-warm; +} + +# it's ok to cache blockchain data "forever", so we do 30d +location /liquidtestnet/api/v1/block/ { + rewrite ^/liquidtestnet/(.*) /$1 break; + try_files /dev/null @mempool-liquidtestnet-api-v1-cache-forever; +} + +# everything else gets "normal" cache location /liquidtestnet/api/v1 { - proxy_pass http://mempool-liquid-testnet/api/v1; + rewrite ^/liquidtestnet/(.*) /$1 break; + try_files /dev/null @mempool-liquidtestnet-api-v1-cache-normal; } + +########### +# esplora # +########### + +# it's ok to cache blockchain data "forever", so we do 30d +location /liquidtestnet/api/block/ { + rewrite ^/liquidtestnet/api/(.*) /$1 break; + try_files /dev/null @esplora-liquidtestnet-api-cache-forever; +} +# other API responses cannot be cached location /liquidtestnet/api/ { - proxy_pass http://electrs-liquid-testnet/; + rewrite ^/liquidtestnet/api/(.*) /$1 break; + try_files /dev/null @esplora-liquidtestnet-api-cache-disabled; +} + +########### +# routing # +########### + +location @mempool-liquidtestnet-api-v1-websocket { + proxy_pass $mempoolTestnet; + proxy_http_version 1.1; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Proto $scheme; +} + +location @mempool-liquidtestnet-api-v1-cache-forever { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; +} + +location @mempool-liquidtestnet-api-v1-cache-warm { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; +} + +location @mempool-liquidtestnet-api-v1-cache-normal { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} + +location @mempool-liquidtestnet-api-v1-cache-disabled { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-liquidtestnet-api-cache-disabled { + proxy_pass $esploraTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-liquidtestnet-api-cache-forever { + proxy_pass $esploraTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; } diff --git a/production/nginx/location-signet-api-v1-lightning.conf b/production/nginx/location-signet-api-v1-lightning.conf new file mode 100644 index 000000000..eb25c9820 --- /dev/null +++ b/production/nginx/location-signet-api-v1-lightning.conf @@ -0,0 +1,21 @@ +# route lightning API endpoints to lightning backend +location /signet/api/v1/lightning { + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-lightning; +} +location @mempool-signet-api-v1-lightning { + proxy_pass $mempoolSignetLightning; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} diff --git a/production/nginx/location-signet-api.conf b/production/nginx/location-signet-api.conf index 245979229..262dea48e 100644 --- a/production/nginx/location-signet-api.conf +++ b/production/nginx/location-signet-api.conf @@ -1,12 +1,154 @@ +########### +# mempool # +########### + +# websocket has special HTTP headers location /signet/api/v1/ws { - proxy_pass http://mempool-bitcoin-signet/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-websocket; } + +# warm cache mining and mempool API responses +location /signet/api/v1/statistics { + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-cache-warm; +} +location /signet/api/v1/mining { + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-cache-warm; +} + +# it's ok to cache blockchain data "forever", so we do 30d +location /signet/api/v1/block/ { + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-cache-forever; +} + +# everything else gets "normal" cache location /signet/api/v1 { - proxy_pass http://mempool-bitcoin-signet/api/v1; + rewrite ^/signet/(.*) /$1 break; + try_files /dev/null @mempool-signet-api-v1-cache-normal; } + +########### +# esplora # +########### + +# it's ok to cache blockchain data "forever", so we do 30d +location /signet/api/block/ { + rewrite ^/signet/api/(.*) /$1 break; + try_files /dev/null @esplora-signet-api-cache-forever; +} +# other API responses cannot be cached location /signet/api/ { - proxy_pass http://electrs-bitcoin-signet/; + rewrite ^/signet/api/(.*) /$1 break; + try_files /dev/null @esplora-signet-api-cache-disabled; +} + +########### +# routing # +########### + +location @mempool-signet-api-v1-websocket { + proxy_pass $mempoolSignet; + proxy_http_version 1.1; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Proto $scheme; +} + +location @mempool-signet-api-v1-cache-forever { + proxy_pass $mempoolSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; +} + +location @mempool-signet-api-v1-cache-warm { + proxy_pass $mempoolSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; +} + +location @mempool-signet-api-v1-cache-normal { + proxy_pass $mempoolSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} + +location @mempool-signet-api-v1-cache-disabled { + proxy_pass $mempoolSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-signet-api-cache-disabled { + proxy_pass $esploraSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-signet-api-cache-forever { + proxy_pass $esploraSignet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; } diff --git a/production/nginx/location-testnet-api-v1-lightning.conf b/production/nginx/location-testnet-api-v1-lightning.conf new file mode 100644 index 000000000..dbabc9aef --- /dev/null +++ b/production/nginx/location-testnet-api-v1-lightning.conf @@ -0,0 +1,21 @@ +# route lightning API endpoints to lightning backend +location /testnet/api/v1/lightning { + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-lightning; +} +location @mempool-testnet-api-v1-lightning { + proxy_pass $mempoolSignetLightning; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} diff --git a/production/nginx/location-testnet-api.conf b/production/nginx/location-testnet-api.conf index 857b1b957..1f74aa533 100644 --- a/production/nginx/location-testnet-api.conf +++ b/production/nginx/location-testnet-api.conf @@ -1,12 +1,154 @@ +########### +# mempool # +########### + +# websocket has special HTTP headers location /testnet/api/v1/ws { - proxy_pass http://mempool-bitcoin-testnet/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-websocket; } + +# warm cache mining and mempool API responses +location /testnet/api/v1/statistics { + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-cache-warm; +} +location /testnet/api/v1/mining { + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-cache-warm; +} + +# it's ok to cache blockchain data "forever", so we do 30d +location /testnet/api/v1/block/ { + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-cache-forever; +} + +# everything else gets "normal" cache location /testnet/api/v1 { - proxy_pass http://mempool-bitcoin-testnet/api/v1; + rewrite ^/testnet/(.*) /$1 break; + try_files /dev/null @mempool-testnet-api-v1-cache-normal; } + +########### +# esplora # +########### + +# it's ok to cache blockchain data "forever", so we do 30d +location /testnet/api/block/ { + rewrite ^/testnet/api/(.*) /$1 break; + try_files /dev/null @esplora-testnet-api-cache-forever; +} +# other API responses cannot be cached location /testnet/api/ { - proxy_pass http://electrs-bitcoin-testnet/; + rewrite ^/testnet/api/(.*) /$1 break; + try_files /dev/null @esplora-testnet-api-cache-disabled; +} + +########### +# routing # +########### + +location @mempool-testnet-api-v1-websocket { + proxy_pass $mempoolTestnet; + proxy_http_version 1.1; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Proto $scheme; +} + +location @mempool-testnet-api-v1-cache-forever { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; +} + +location @mempool-testnet-api-v1-cache-warm { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; +} + +location @mempool-testnet-api-v1-cache-normal { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache api; + proxy_cache_valid 200 10s; + proxy_redirect off; + + expires 10s; +} + +location @mempool-testnet-api-v1-cache-disabled { + proxy_pass $mempoolTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-testnet-api-cache-disabled { + proxy_pass $esploraTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; +} + +location @esplora-testnet-api-cache-forever { + proxy_pass $esploraTestnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_cache_background_update on; + proxy_cache_use_stale updating; + proxy_cache api; + proxy_cache_valid 200 30d; + proxy_redirect off; + + expires 30d; } diff --git a/production/nginx/nginx.conf b/production/nginx/nginx.conf index ed0d35e52..24f389533 100644 --- a/production/nginx/nginx.conf +++ b/production/nginx/nginx.conf @@ -1,4 +1,3 @@ -# FreeBSD configuration user nobody; pid /var/run/nginx.pid; @@ -14,17 +13,21 @@ http { # DNS servers for on-demand recursive resolver resolver 8.8.8.8; + # include default mime types + include /usr/local/etc/nginx/mime.types; + default_type application/octet-stream; + # HTTP basic configuration include mempool/production/nginx/http-basic.conf; include mempool/production/nginx/http-proxy-cache.conf; include mempool/production/nginx/http-language.conf; - # mempool backend configuration + # mempool configuration include mempool/production/nginx/upstream-mempool.conf; - # electrs backend configuration - include mempool/production/nginx/upstream-electrs.conf; - include mempool/production/nginx/server-electrs.conf; + # esplora configuration + include mempool/production/nginx/upstream-esplora.conf; + include mempool/production/nginx/server-esplora.conf; # MEMPOOL.NINJA server { @@ -36,11 +39,18 @@ http { # for services from mempool.space like contributors on about page set $mempoolSpaceServices "https://mempool.space"; - # for mempool/backend daemon, see upstream-mempool.conf - set $mempoolBackend "http://mempool-bitcoin-mainnet"; + # for mempool daemons, see upstream-mempool.conf + set $mempoolMainnet "http://mempool-bitcoin-mainnet"; + set $mempoolMainnetLightning "http://mempool-bitcoin-mainnet-lightning"; + set $mempoolTestnet "http://mempool-bitcoin-testnet"; + set $mempoolTestnetLightning "http://mempool-bitcoin-testnet-lightning"; + set $mempoolSignet "http://mempool-bitcoin-signet"; + set $mempoolSignetLightning "http://mempool-bitcoin-signet-lightning"; - # for blockstream/electrs daemon, see upstream-electrs.conf - set $electrsBackend "http://electrs-bitcoin-mainnet"; + # for blockstream/esplora daemons, see upstream-esplora.conf + set $esploraMainnet "http://esplora-bitcoin-mainnet"; + set $esploraTestnet "http://esplora-bitcoin-testnet"; + set $esploraSignet "http://esplora-bitcoin-signet"; # tor v3 listen 127.0.0.1:81; @@ -70,11 +80,11 @@ http { # for services from mempool.space like contributors on about page set $mempoolSpaceServices "https://mempool.space"; - # for mempool/backend daemon, see upstream-mempool.conf - set $mempoolBackend "http://mempool-bisq-mainnet"; + # for mempool daemons, see upstream-mempool.conf + set $mempoolBisq "http://mempool-bitcoin-bisq"; - # for blockstream/electrs daemon, see upstream-electrs.conf - set $electrsBackend "http://electrs-bitcoin-mainnet"; + # for blockstream/esplora daemon, see upstream-esplora.conf + set $esploraMainnet "http://esplora-bitcoin-mainnet"; # tor v3 listen 127.0.0.1:82; @@ -104,11 +114,13 @@ http { # for services from mempool.space like contributors on about page set $mempoolSpaceServices "https://mempool.space"; - # for mempool/backend daemon, see upstream-mempool.conf - set $mempoolBackend "http://mempool-liquid-mainnet"; + # for mempool daemons, see upstream-mempool.conf + set $mempoolMainnet "http://mempool-liquid-mainnet"; + set $mempoolTestnet "http://mempool-liquid-testnet"; - # for blockstream/electrs daemon, see upstream-electrs.conf - set $electrsBackend "http://electrs-liquid-mainnet"; + # for blockstream/esplora daemon, see upstream-esplora.conf + set $esploraMainnet "http://esplora-liquid-mainnet"; + set $esploraTestnet "http://esplora-liquid-testnet"; # tor v3 listen 127.0.0.1:83; diff --git a/production/nginx/server-bisq.conf b/production/nginx/server-bisq.conf index 3933b6e4d..704ef5a6c 100644 --- a/production/nginx/server-bisq.conf +++ b/production/nginx/server-bisq.conf @@ -4,80 +4,98 @@ include mempool/production/nginx/location-api-v1-services.conf; proxy_cache markets; proxy_cache_valid 200 30s; -# route electrs APIs to electrs +# route esplora APIs to esplora location /api/tx/ { - proxy_pass http://electrs-bitcoin-mainnet/tx/; + rewrite ^/api/(.*) /$1 break; + try_files /dev/null @esplora-api-cache-disabled; } # rewrite APIs to match what backend expects location /api/currencies { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/depth { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/hloc { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/offers { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/ticker { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/trades { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/volumes { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/markets { rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api/v1 { rewrite ^/api/v1/(.*) /api/v1/bisq/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /api { rewrite ^/api/(.*) /api/v1/bisq/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; +} +location /api/v1/ws { + rewrite ^/api/(.*) /api/v1/bisq/$1 break; + try_files /dev/null @mempool-bisq-websocket; +} +location /bisq/api/v1/ws { + rewrite ^/bisq/api/v1/(.*) /api/v1/bisq/$1 break; + try_files /dev/null @mempool-bisq-websocket; } location /bisq/api/v1 { rewrite ^/bisq/api/v1/(.*) /api/v1/bisq/$1 break; - try_files $uri $uri/ @mempool-bisq; + try_files /dev/null @mempool-bisq; } location /bisq/api { - rewrite ^/bisq/api/(.*) /api/v1/bisq/$1 break; - try_files $uri $uri/ @mempool-bisq; + rewrite ^/bisq/api/(.*) /api/v1/bisq/$1 break; + try_files /dev/null @mempool-bisq; } -# special handling for websocket -location /api/v1/ws { - proxy_pass http://mempool-bitcoin-bisq/; +location @mempool-bisq-websocket { + proxy_pass $mempoolBisq; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } location @mempool-bisq { - proxy_pass http://mempool-bitcoin-bisq; - proxy_http_version 1.1; + proxy_pass $mempoolBisq; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - proxy_cache_bypass $http_upgrade; - proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; +} + +location @esplora-api-cache-disabled { + proxy_pass $esploraMainnet; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + proxy_buffering off; + + expires -1; } diff --git a/production/nginx/server-electrs.conf b/production/nginx/server-esplora.conf similarity index 62% rename from production/nginx/server-electrs.conf rename to production/nginx/server-esplora.conf index b817b8163..38cdb0bc2 100644 --- a/production/nginx/server-electrs.conf +++ b/production/nginx/server-esplora.conf @@ -2,34 +2,34 @@ server { listen 127.0.0.1:4000; access_log /dev/null; location / { - proxy_pass http://electrs-bitcoin-mainnet; + proxy_pass http://esplora-bitcoin-mainnet; } } server { listen 127.0.0.1:4001; access_log /dev/null; location / { - proxy_pass http://electrs-liquid-mainnet; + proxy_pass http://esplora-liquid-mainnet; } } server { listen 127.0.0.1:4002; access_log /dev/null; location / { - proxy_pass http://electrs-bitcoin-testnet; + proxy_pass http://esplora-bitcoin-testnet; } } server { listen 127.0.0.1:4003; access_log /dev/null; location / { - proxy_pass http://electrs-bitcoin-signet; + proxy_pass http://esplora-bitcoin-signet; } } server { listen 127.0.0.1:4004; access_log /dev/null; location / { - proxy_pass http://electrs-liquid-testnet; + proxy_pass http://esplora-liquid-testnet; } } diff --git a/production/nginx/server-mempool.conf b/production/nginx/server-mempool.conf index 5a84cce17..892fe50e1 100644 --- a/production/nginx/server-mempool.conf +++ b/production/nginx/server-mempool.conf @@ -1,6 +1,9 @@ include mempool/production/nginx/server-common.conf; include mempool/production/nginx/location-redirects.conf; include mempool/production/nginx/location-api-v1-services.conf; +include mempool/production/nginx/location-api-v1-lightning.conf; include mempool/production/nginx/location-api.conf; include mempool/production/nginx/location-testnet-api.conf; +include mempool/production/nginx/location-testnet-api-v1-lightning.conf; include mempool/production/nginx/location-signet-api.conf; +include mempool/production/nginx/location-signet-api-v1-lightning.conf; diff --git a/production/nginx/upstream-electrs.conf b/production/nginx/upstream-esplora.conf similarity index 65% rename from production/nginx/upstream-electrs.conf rename to production/nginx/upstream-esplora.conf index 476b73054..6cad0730b 100644 --- a/production/nginx/upstream-electrs.conf +++ b/production/nginx/upstream-esplora.conf @@ -1,15 +1,15 @@ -upstream electrs-bitcoin-mainnet { +upstream esplora-bitcoin-mainnet { server [::1]:3000 fail_timeout=10s max_fails=10 weight=99999; } -upstream electrs-liquid-mainnet { +upstream esplora-liquid-mainnet { server [::1]:3001 fail_timeout=10s max_fails=10 weight=99999; } -upstream electrs-bitcoin-testnet { +upstream esplora-bitcoin-testnet { server [::1]:3002 fail_timeout=10s max_fails=10 weight=99999; } -upstream electrs-bitcoin-signet { +upstream esplora-bitcoin-signet { server [::1]:3003 fail_timeout=10s max_fails=10 weight=99999; } -upstream electrs-liquid-testnet { +upstream esplora-liquid-testnet { server [::1]:3004 fail_timeout=10s max_fails=10 weight=99999; } diff --git a/production/nginx/upstream-mempool.conf b/production/nginx/upstream-mempool.conf index 8e0f12ab6..c9cf9c2bb 100644 --- a/production/nginx/upstream-mempool.conf +++ b/production/nginx/upstream-mempool.conf @@ -16,3 +16,12 @@ upstream mempool-bitcoin-signet { upstream mempool-liquid-testnet { server 127.0.0.1:8994 fail_timeout=10s max_fails=10 weight=99999; } +upstream mempool-bitcoin-mainnet-lightning { + server 127.0.0.1:8993 fail_timeout=10s max_fails=10 weight=99999; +} +upstream mempool-bitcoin-testnet-lightning { + server 127.0.0.1:8992 fail_timeout=10s max_fails=10 weight=99999; +} +upstream mempool-bitcoin-signet-lightning { + server 127.0.0.1:8991 fail_timeout=10s max_fails=10 weight=99999; +} diff --git a/production/test-nginx b/production/test-nginx index 2216689a4..c1cebd8d8 100755 --- a/production/test-nginx +++ b/production/test-nginx @@ -1,4 +1,4 @@ -#!/usr/local/bin/zsh +#!/usr/bin/env zsh PROTO=https HOSTNAME=mempool.ninja URL_BASE=${PROTO}://${HOSTNAME}