diff --git a/cashtab/src/components/Agora/__tests__/index.test.js b/cashtab/src/components/Agora/__tests__/index.test.js
index 882d50e7a..132f5b348 100644
--- a/cashtab/src/components/Agora/__tests__/index.test.js
+++ b/cashtab/src/components/Agora/__tests__/index.test.js
@@ -1,986 +1,982 @@
 // Copyright (c) 2024 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 import React from 'react';
 import { render, screen, waitFor } from '@testing-library/react';
 import '@testing-library/jest-dom';
 import userEvent from '@testing-library/user-event';
 import { when } from 'jest-when';
 import {
     initializeCashtabStateForTests,
     clearLocalForage,
 } from 'components/App/fixtures/helpers';
 import CashtabTestWrapper from 'components/App/fixtures/CashtabTestWrapper';
 import appConfig from 'config/app';
 import 'fake-indexeddb/auto';
 import localforage from 'localforage';
 import {
     agoraPartialAlphaWallet,
     agoraOfferCachetAlphaOne,
     agoraOfferCachetAlphaTwo,
     agoraOfferCachetBetaOne,
     agoraOfferBullAlphaOne,
     scamAgoraOffer,
     cachetCacheMocks,
     bullCacheMocks,
     scamCacheMocks,
     agoraPartialBetaWallet,
     agoraPartialAlphaKeypair,
     agoraPartialBetaKeypair,
 } from 'components/Agora/fixtures/mocks';
 import { Ecc, initWasm, toHex } from 'ecash-lib';
 import { MockAgora } from '../../../../../modules/mock-chronik-client';
 import { token as tokenConfig } from 'config/token';
 
 describe('<Agora />', () => {
     let ecc;
     const CACHET_TOKEN_ID = cachetCacheMocks.token.tokenId;
     const BULL_TOKEN_ID = bullCacheMocks.token.tokenId;
     const SCAM_TOKEN_ID = scamCacheMocks.token.tokenId;
     beforeAll(async () => {
         await initWasm();
         ecc = new Ecc();
     });
 
     let mockedChronik;
     beforeEach(async () => {
         const mockedDate = new Date('2022-01-01T12:00:00.000Z');
         jest.spyOn(global, 'Date').mockImplementation(() => mockedDate);
         // Mock the app with context at the Token Action screen
         mockedChronik = await initializeCashtabStateForTests(
             [agoraPartialAlphaWallet, agoraPartialBetaWallet],
             localforage,
         );
 
-        // We need to give mockedChronik a plugin function
-        // This is required for creating a new Agora(mockedChronik)
-        mockedChronik.plugin = () => 'dummy plugin';
-
         // Mock chronik calls used to build token cache to show
         // the user can load a page without having the token info cached
         for (const tokenCacheMock of [
             cachetCacheMocks,
             bullCacheMocks,
             scamCacheMocks,
         ]) {
             mockedChronik.setMock('token', {
                 input: tokenCacheMock.token.tokenId,
                 output: tokenCacheMock.token,
             });
             mockedChronik.setMock('tx', {
                 input: tokenCacheMock.token.tokenId,
                 output: tokenCacheMock.tx,
             });
         }
 
         // Mock the fetch call to Cashtab's price API
         global.fetch = jest.fn();
         const fiatCode = 'usd'; // Use usd until you mock getting settings from localforage
         const cryptoId = appConfig.coingeckoId;
         // Keep this in the code, because different URLs will have different outputs requiring different parsing
         const priceApiUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${cryptoId}&vs_currencies=${fiatCode}&include_last_updated_at=true`;
         const xecPrice = 0.00003;
         const priceResponse = {
             ecash: {
                 usd: xecPrice,
                 last_updated_at: 1706644626,
             },
         };
         when(fetch)
             .calledWith(priceApiUrl)
             .mockResolvedValue({
                 json: () => Promise.resolve(priceResponse),
             });
     });
     afterEach(async () => {
         jest.clearAllMocks();
         await clearLocalForage(localforage);
     });
     it('Screen loads as expected if there are no agora partial listings', async () => {
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds();
         mockedAgora.setOfferedFungibleTokenIds([]);
 
         // also mock await agora.activeOffersByPubKey(toHex(activePk))
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We see the Token Offers section
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // But we have no offers
         expect(
             screen.getByText('No tokens are currently listed for sale'),
         ).toBeInTheDocument();
 
         // We switch to see our created offers
         await userEvent.click(screen.getByTitle('Toggle Active Offers'));
 
         // We have made no offers
         // This is always empty if active offers is empty, as for partials, active offers will render both
         // public offers and offers created by your wallet
         // Your offers you can only cancel, not buy
         expect(
             screen.getByText('You do not have any listed tokens'),
         ).toBeInTheDocument();
     });
     it('A chronik error notice is rendered if there is some error in querying listings', async () => {
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds();
         mockedAgora.setOfferedFungibleTokenIds(new Error('some chronik error'));
 
         // also mock await agora.activeOffersByPubKey(toHex(activePk))
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // A chronik error notice is rendered
         expect(
             await screen.findByText(
                 'Error querying listed tokens. Please try again later.',
             ),
         ).toBeInTheDocument();
     });
     it('We can see a rendered offer', async () => {
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds();
         mockedAgora.setOfferedFungibleTokenIds([CACHET_TOKEN_ID]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(CACHET_TOKEN_ID, [
             agoraOfferCachetAlphaOne,
         ]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk))
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [agoraOfferCachetAlphaOne],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We have an offer
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // We see the token name and ticker above its PartialOffer after OrderBooks load
         expect(await screen.findByText('Cachet (CACHET)')).toBeInTheDocument();
 
         // Because this offer was created by this wallet, we have the option to cancel it
         expect(
             await screen.findByRole('button', { name: 'Cancel your offer' }),
         ).toBeInTheDocument();
     });
     it('We can fetch and use the blacklist from token server', async () => {
         when(fetch)
             .calledWith(`${tokenConfig.blacklistServerUrl}/blacklist`)
             .mockResolvedValue({
                 json: () => Promise.resolve({ tokenIds: [SCAM_TOKEN_ID] }),
             });
 
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds();
         mockedAgora.setOfferedFungibleTokenIds([SCAM_TOKEN_ID]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(SCAM_TOKEN_ID, [scamAgoraOffer]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk))
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [scamAgoraOffer],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We see the Token Offers section
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // But we have no offers
         expect(
             screen.getByText('No tokens are currently listed for sale'),
         ).toBeInTheDocument();
 
         // We switch to see our created offers
         await userEvent.click(screen.getByTitle('Toggle Active Offers'));
 
         expect(screen.getByText('Manage your listings')).toBeInTheDocument();
 
         // We see the token name and ticker above its PartialOffer
         expect(
             screen.getByText('Badger Universal Token (BUX)'),
         ).toBeInTheDocument();
 
         // Because this offer was created by this wallet, we have the option to cancel it
         expect(
             screen.getByRole('button', { name: 'Cancel your offer' }),
         ).toBeInTheDocument();
     });
     it('On token server API fail, we fall back to locally maintained blacklist. A blacklisted offer does not render in all offers, but will render in My offers', async () => {
         when(fetch)
             .calledWith(`${tokenConfig.blacklistServerUrl}/blacklist`)
             .mockResolvedValue({
                 json: () =>
                     Promise.resolve(new Error('some token server api error')),
             });
 
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds();
         mockedAgora.setOfferedFungibleTokenIds([SCAM_TOKEN_ID]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(SCAM_TOKEN_ID, [scamAgoraOffer]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk))
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [scamAgoraOffer],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We see the Token Offers section
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // But we have no offers
         expect(
             screen.getByText('No tokens are currently listed for sale'),
         ).toBeInTheDocument();
 
         // We switch to see our created offers
         await userEvent.click(screen.getByTitle('Toggle Active Offers'));
 
         expect(screen.getByText('Manage your listings')).toBeInTheDocument();
 
         // We see the token name and ticker above its PartialOffer
         expect(
             screen.getByText('Badger Universal Token (BUX)'),
         ).toBeInTheDocument();
 
         // Because this offer was created by this wallet, we have the option to cancel it
         expect(
             screen.getByRole('button', { name: 'Cancel your offer' }),
         ).toBeInTheDocument();
     });
     it('We can see multiple offers, some we made, others we did not, and we can cancel an offer', async () => {
         // We do not want the date mocked here, it interferes with changing wallets somehow
         jest.spyOn(global, 'Date').mockRestore();
 
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds() to return offers for both tokens
         mockedAgora.setOfferedFungibleTokenIds([
             CACHET_TOKEN_ID,
             BULL_TOKEN_ID,
         ]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(CACHET_TOKEN_ID, [
             agoraOfferCachetAlphaOne,
             agoraOfferCachetAlphaTwo,
             agoraOfferCachetBetaOne,
         ]);
         mockedAgora.setActiveOffersByTokenId(BULL_TOKEN_ID, [
             agoraOfferBullAlphaOne,
         ]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk)), for both walletse
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [
                 agoraOfferCachetAlphaOne,
                 agoraOfferCachetAlphaTwo,
                 agoraOfferBullAlphaOne,
             ],
         );
         mockedAgora.setActiveOffersByPubKey(toHex(agoraPartialBetaKeypair.pk), [
             agoraOfferCachetBetaOne,
         ]);
 
         // Set mocks for tx that cancels a listing
         const cancelHex =
             '0200000002f7bb552354b6f5076eb2664a8bcbbedc87b42f2ebfcb1480ee0a9141bbae635900000000644159fdead8c105622e86245089e53c93b61aca17ed1d2407faa40a595ed0d232217578ce586ca14c88cc851dc17c3fe21689dffe572c89d725abddd04b3d289dc141210233f09cd4dc3381162f09975f90866f085350a5ec890d7fba5f6739c9c0ac2afdffffffff4c48dd93dcc794ee5c9df7a7bc5637e6c78419842b8b9459727db116aed4c42501000000fdad010441475230075041525449414c413e20e3f9d86a991e416d956a1db69e0a2be9cf3cd02f2392f2d4f063d9af49dd1fe3c351ef684eafbae5399ed161e2b21895ae84c364daa9cc06846063abaa9f41004d5a014c766a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f89608000000000000000000027de6240000000000d17b000000000000e833270100000000a16f7e500233f09cd4dc3381162f09975f90866f085350a5ec890d7fba5f6739c9c0ac2afd089881ff7f00000000ab7b63817b6ea2697604e8332701a26976037de6249700887d94527901377f75789263587e78037de624965880bc007e7e68587e5279037de624965880bc007e7e825980bc7c7e0200007e7b02d07b9302d17b9656807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d8007f5c7f7701207f547f7504a16f7e50886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087ffffffff030000000000000000376a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f89608000000000000037822020000000000001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488acb2620600000000001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488ac00000000';
         const cancelTxid =
             'de8f638c5b11592825ff74f2ec59892f721bc1151486efe86d99a44bf05865bf';
 
         mockedChronik.setMock('broadcastTx', {
             input: cancelHex,
             output: { txid: cancelTxid },
         });
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We have an offer
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // We see all token names and tickers above their PartialOffers
         expect(await screen.findByText('Cachet (CACHET)')).toBeInTheDocument();
         expect(await screen.findByText('Bull (BULL)')).toBeInTheDocument();
 
         // For BULL, there is only one offer, so that offer is the spot price
         const BULL_SPOT_MIN_QTY = '8';
         const BULL_SPOT_PRICE_MIN_BUY = '400.42k XEC';
         const BULL_SPOT_PRICE_FIAT_MIN_BUY = '$12.01 USD';
 
         // We await this as the component will load and render token info before
         // the offers have finished loading
         expect(
             await screen.findByText(`${BULL_SPOT_MIN_QTY} BULL`),
         ).toBeInTheDocument();
         expect(screen.getByText(BULL_SPOT_PRICE_MIN_BUY)).toBeInTheDocument();
         expect(
             screen.getByText(BULL_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         // For tokens with multiple partial offers available, the lowest-priced
         // offer is selected by default ("spot price")
         const CACHET_SPOT_MIN_QTY = '.20';
         const CACHET_SPOT_PRICE_MIN_BUY = '240.64 XEC';
         const CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.0072 USD';
         // Quantities are not displayed until they load, so we await
         expect(
             await screen.findByText(`${CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(screen.getByText(CACHET_SPOT_PRICE_MIN_BUY)).toBeInTheDocument();
         expect(
             screen.getByText(CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         // Because both spot offers were created by the active Alpha wallet,
         // we see two cancel buttons
         expect(
             screen.getAllByRole('button', { name: 'Cancel your offer' })[1],
         ).toBeInTheDocument();
 
         // Change wallets using the dropdown menu at the top of the screen
         // NB you cannot have the Date() function mocked if you want to test changing wallets
         await userEvent.selectOptions(
             screen.getByTestId('wallet-select'),
             screen.getByText('Agora Partial Beta'),
         );
 
         expect(await screen.findByText('42.00 XEC')).toBeInTheDocument();
 
         // Wait for tokens to re-load (triggered by wallet change)
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for the wallet to load
         await waitFor(() =>
             expect(screen.queryByTitle('Loading')).not.toBeInTheDocument(),
         );
 
         // Wait for active offers to load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // Switching wallets triggers a refresh of the offers
         // Now that we are using the other wallet, we see two Buy buttons
         expect(
             await screen.findByRole('button', { name: 'Buy Cachet (CACHET)' }),
         ).toBeInTheDocument();
         expect(
             await screen.findByRole('button', { name: 'Buy Bull (BULL)' }),
         ).toBeInTheDocument();
 
         // Hit the switch to show listings created by the active wallet (now Beta)
         const toggleAllVsMyOffersSwitch = screen.getByTitle(
             'Toggle Active Offers',
         );
         await userEvent.click(toggleAllVsMyOffersSwitch);
         // we see only the beta-created Cachet offer
         expect(screen.getByText('Cachet (CACHET)')).toBeInTheDocument();
         // We do not see any offers for Bull, this was created by alpha
         expect(screen.queryByText('Bull (BULL)')).not.toBeInTheDocument();
 
         // Note that we only see orderbooks that we have offers for
         // But we see all offers for these orderbooks
 
         // The spot price offer is rendered by default
         // This happens to not be our offer
         expect(
             await screen.findByText(`${CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         // We can buy this offer from the Manage screen
         expect(
             screen.getByRole('button', { name: 'Buy Cachet (CACHET)' }),
         ).toBeInTheDocument();
 
         // Select our offer
         await userEvent.click(screen.getByText('$0.36 USD'));
         // Now we can only cancel our offer
         expect(
             screen.getByRole('button', { name: 'Cancel your offer' }),
         ).toBeInTheDocument();
         expect(
             screen.queryByRole('button', { name: 'Buy Cachet (CACHET)' }),
         ).not.toBeInTheDocument();
 
         // OK go back to all offers
         await userEvent.click(toggleAllVsMyOffersSwitch);
 
         // Nice but let's go back to the first wallet
         // Change wallets using the dropdown menu at the top of the screen
         // NB you cannot have the Date() function mocked if you want to test changing wallets
         await userEvent.selectOptions(
             screen.getByTestId('wallet-select'),
             screen.getByText('Agora Partial Alpha'),
         );
 
         expect(await screen.findByText('4,200.00 XEC')).toBeInTheDocument();
 
         // Wait for tokens to re-load (triggered by wallet change)
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
         // Wait for the wallet to load
         await waitFor(() =>
             expect(screen.queryByTitle('Loading')).not.toBeInTheDocument(),
         );
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // Now we see cancel buttons again
         expect(
             (
                 await screen.findAllByRole('button', {
                     name: 'Cancel your offer',
                 })
             )[1],
         ).toBeInTheDocument();
 
         // If we select the offer created by the Beta wallet, we see a buy button
         await userEvent.click(screen.getByText('$0.36 USD'));
 
         // We also see updates to the rendered spot details
         const UPDATED_CACHET_SPOT_MIN_QTY = '.30';
         const UPDATED_CACHET_SPOT_PRICE_MIN_BUY = '3.6k XEC';
         const UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.11 USD';
         expect(
             screen.getByText(`${UPDATED_CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_MIN_BUY),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         expect(
             screen.getByRole('button', { name: 'Buy Cachet (CACHET)' }),
         ).toBeInTheDocument();
 
         // Let's cancel the BULL offer
         await userEvent.click(
             screen.getByRole('button', { name: 'Cancel your offer' }),
         );
 
         // We see a confirmation modal
         expect(
             screen.getByText(
                 'Cancel your offer to sell 888 Bull (BULL) for 400,424.96 XEC ($12.01 USD)?',
             ),
         ).toBeInTheDocument();
 
         // We cancel
         await userEvent.click(screen.getByText('OK'));
 
         // Notification on successful cancel
         expect(await screen.findByText(`Canceled listing`)).toBeInTheDocument();
 
         // Note we can't test that offers are refreshed as we cannot dynamically adjust chronik mocks
         // Would need regtest integration to do this
     });
     it('We can buy an offer', async () => {
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds() to return offers for both tokens
         mockedAgora.setOfferedFungibleTokenIds([
             CACHET_TOKEN_ID,
             BULL_TOKEN_ID,
         ]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(CACHET_TOKEN_ID, [
             agoraOfferCachetAlphaOne,
             agoraOfferCachetAlphaTwo,
             agoraOfferCachetBetaOne,
         ]);
         mockedAgora.setActiveOffersByTokenId(BULL_TOKEN_ID, [
             agoraOfferBullAlphaOne,
         ]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk)), for both walletse
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [
                 agoraOfferCachetAlphaOne,
                 agoraOfferCachetAlphaTwo,
                 agoraOfferBullAlphaOne,
             ],
         );
         mockedAgora.setActiveOffersByPubKey(toHex(agoraPartialBetaKeypair.pk), [
             agoraOfferCachetBetaOne,
         ]);
 
         // Set mocks for tx that buys a listing
         const buyHex =
             '02000000023f091a214fdf5ff45e1cae5f7830800a73740cbd3b752f3694090c' +
             'c962b59c8101000000fd47030441475230075041525449414c21023c72addb4f' +
             'df09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b140727d4804' +
             '0c07efcd104ceb7b7aef07834dbd094f93d1728f584859383c476e5c2c369a51' +
             'b2900ac670eebea381a1db8811609b5b19c22d886c808d6ecd31cc8344220200' +
             '00000000001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488acaf' +
             'dd0000000000001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488' +
             'ac4d2f013f091a214fdf5ff45e1cae5f7830800a73740cbd3b752f3694090cc9' +
             '62b59c8101000000d67b63817b6ea269760384c420a26976039e17019700887d' +
             '94527901377f75789263587e78039e1701965880bc007e7e68587e5279039e17' +
             '01965880bc007e7e825980bc7c7e01007e7b02f6059302f7059657807e041976' +
             'a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c767258' +
             '7d807e7e7e01ab7e537901257f7702d6007f5c7f7701207f547f7504ce731f40' +
             '886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea8' +
             '6f7bbb7501c17e7c677501557f7768ad075041525449414c8804414752308722' +
             '02000000000000ffffffff7388db19d999ee9eb8b07c726d4fb078a003c9ccea' +
             'fbdb5b89b56b15be464908ce731f40c10000000384c420514d58014c766a0453' +
             '4c500001010453454e4420aed861a31b96934b88c0252ede135cb9700d7649f6' +
             '9191235087a3030e553cb108000000000000000000019e17010000000000f705' +
             '00000000000084c4200000000000ce731f40021e75febb8ae57a8805e80df937' +
             '32ab7d5d8606377cb30c0f02444809cc085f3908a0a3ff7f00000000ab7b6381' +
             '7b6ea269760384c420a26976039e17019700887d94527901377f75789263587e' +
             '78039e1701965880bc007e7e68587e5279039e1701965880bc007e7e825980bc' +
             '7c7e01007e7b02f6059302f7059657807e041976a914707501557f77a97e0288' +
             'ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e53790125' +
             '7f7702d6007f5c7f7701207f547f7504ce731f40886b7ea97e01877e7c926475' +
             '00687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c67750155' +
             '7f7768ad075041525449414c88044147523087fffffffff7bb552354b6f5076e' +
             'b2664a8bcbbedc87b42f2ebfcb1480ee0a9141bbae63590000000064412ea299' +
             '62ae7585308ea45ac92adb7aaa13920e333de700fda95852726016c25a9c25b6' +
             '2e18621d9c834d1369985bd9fe91c8fdac3783a00eea94cd8e1fa629d7412102' +
             '33f09cd4dc3381162f09975f90866f085350a5ec890d7fba5f6739c9c0ac2afd' +
             'ffffffff050000000000000000496a04534c500001010453454e4420aed861a3' +
             '1b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb108000000' +
             '000000000008000000000000751208000000000000001e007f05000000000019' +
             '76a914f208ef75eb0dd778ea4540cbd966a830c7b94bb088ac22020000000000' +
             '0017a914211be508fb7608c0a3b3d7a36279894d0450e7378722020000000000' +
             '001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488acafdd000000' +
             '0000001976a91403b830e4b9dce347f3495431e1f9d1005f4b420488acce731f' +
             '40';
         const buyTxid =
             '6fbee4e0460e3730f000e2927d69d881b8a536b80fd43b839d32e34c3490ff00';
 
         mockedChronik.setMock('broadcastTx', {
             input: buyHex,
             output: { txid: buyTxid },
         });
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We have an offer
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // We see all token names and tickers above their PartialOffers
         expect(await screen.findByText('Cachet (CACHET)')).toBeInTheDocument();
         expect(await screen.findByText('Bull (BULL)')).toBeInTheDocument();
 
         // We see the expected spot offer for CACHET
         const CACHET_SPOT_MIN_QTY = '.20';
         const CACHET_SPOT_PRICE_MIN_BUY = '240.64 XEC';
         const CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.0072 USD';
         // Quantities are not displayed until they load, so we await
         expect(
             await screen.findByText(`${CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(screen.getByText(CACHET_SPOT_PRICE_MIN_BUY)).toBeInTheDocument();
         expect(
             screen.getByText(CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         // Because both spot offers were created by the active Alpha wallet,
         // we see two cancel buttons
         expect(
             screen.getAllByRole('button', { name: 'Cancel your offer' })[1],
         ).toBeInTheDocument();
 
         // If we select the offer created by the Beta wallet, we see a buy button
         await userEvent.click(screen.getByText('$0.36 USD'));
 
         // We also see updates to the rendered spot details
         const UPDATED_CACHET_SPOT_MIN_QTY = '.30';
         const UPDATED_CACHET_SPOT_PRICE_MIN_BUY = '3.6k XEC';
         const UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.11 USD';
         expect(
             screen.getByText(`${UPDATED_CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_MIN_BUY),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         const buyCachetButton = screen.getByRole('button', {
             name: 'Buy Cachet (CACHET)',
         });
         expect(buyCachetButton).toBeInTheDocument();
 
         // Note I was not able to adjust the slider value in react testing library
         // We do the min buy
 
         await userEvent.click(buyCachetButton);
         // We see a confirmation modal
         expect(
             screen.getByText(
                 `Buy ${UPDATED_CACHET_SPOT_MIN_QTY} Cachet (CACHET) for 3,601.92 XEC (${UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY})?`,
             ),
         ).toBeInTheDocument();
 
         // We buy
         await userEvent.click(screen.getByText('OK'));
 
         // Notification on successful buy
         expect(
             await screen.findByText(
                 `Bought ${UPDATED_CACHET_SPOT_MIN_QTY} Cachet (CACHET) for 3,601.92 XEC (${UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY})`,
             ),
         ).toBeInTheDocument();
 
         // Note we can't test that offers are refreshed as we cannot dynamically adjust chronik mocks
         // Would need regtest integration to do this
     });
     it('We get expected error if we try to buy an offer we cannot afford', async () => {
         // Need to mock agora API endpoints
         const mockedAgora = new MockAgora();
 
         // mock await agora.offeredFungibleTokenIds() to return offers for both tokens
         mockedAgora.setOfferedFungibleTokenIds([
             CACHET_TOKEN_ID,
             BULL_TOKEN_ID,
         ]);
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(CACHET_TOKEN_ID, [
             agoraOfferCachetAlphaOne,
             agoraOfferCachetAlphaTwo,
             agoraOfferCachetBetaOne,
         ]);
         mockedAgora.setActiveOffersByTokenId(BULL_TOKEN_ID, [
             agoraOfferBullAlphaOne,
         ]);
         // also mock await agora.activeOffersByPubKey(toHex(activePk)), for both walletse
         mockedAgora.setActiveOffersByPubKey(
             toHex(agoraPartialAlphaKeypair.pk),
             [
                 agoraOfferCachetAlphaOne,
                 agoraOfferCachetAlphaTwo,
                 agoraOfferBullAlphaOne,
             ],
         );
         mockedAgora.setActiveOffersByPubKey(toHex(agoraPartialBetaKeypair.pk), [
             agoraOfferCachetBetaOne,
         ]);
 
         const emptyWalletMockedChronik = await initializeCashtabStateForTests(
             [
                 {
                     ...agoraPartialAlphaWallet,
                     state: {
                         ...agoraPartialAlphaWallet.state,
                         nonSlpUtxos: [],
                     },
                 },
                 agoraPartialBetaWallet,
             ],
             localforage,
         );
 
         // Mock chronik calls used to build token cache to show
         // the user can load a page without having the token info cached
         for (const tokenCacheMock of [cachetCacheMocks, bullCacheMocks]) {
             emptyWalletMockedChronik.setMock('token', {
                 input: tokenCacheMock.token.tokenId,
                 output: tokenCacheMock.token,
             });
             emptyWalletMockedChronik.setMock('tx', {
                 input: tokenCacheMock.token.tokenId,
                 output: tokenCacheMock.tx,
             });
         }
 
         render(
             <CashtabTestWrapper
                 chronik={emptyWalletMockedChronik}
                 ecc={ecc}
                 agora={mockedAgora}
                 route={`/agora/`}
             />,
         );
 
         // Wait for the screen to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for agora offers to load
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Loading active offers'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(await screen.findByTitle('Active Offers')).toBeInTheDocument();
 
         // We have an offer
         expect(screen.getByText('Token Offers')).toBeInTheDocument();
 
         // We see all token names and tickers above their PartialOffers
         expect(await screen.findByText('Cachet (CACHET)')).toBeInTheDocument();
         expect(await screen.findByText('Bull (BULL)')).toBeInTheDocument();
 
         // We see the expected spot offer for CACHET
         const CACHET_SPOT_MIN_QTY = '.20';
         const CACHET_SPOT_PRICE_MIN_BUY = '240.64 XEC';
         const CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.0072 USD';
         // Quantities are not displayed until they load, so we await
         expect(
             await screen.findByText(`${CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(screen.getByText(CACHET_SPOT_PRICE_MIN_BUY)).toBeInTheDocument();
         expect(
             screen.getByText(CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         // Because both spot offers were created by the active Alpha wallet,
         // we see two cancel buttons
         expect(
             screen.getAllByRole('button', { name: 'Cancel your offer' })[1],
         ).toBeInTheDocument();
 
         // If we select the offer created by the Beta wallet, we see a buy button
         await userEvent.click(screen.getByText('$0.36 USD'));
 
         // We also see updates to the rendered spot details
         const UPDATED_CACHET_SPOT_MIN_QTY = '.30';
         const UPDATED_CACHET_SPOT_PRICE_MIN_BUY = '3.6k XEC';
         const UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY = '$0.11 USD';
         expect(
             screen.getByText(`${UPDATED_CACHET_SPOT_MIN_QTY} CACHET`),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_MIN_BUY),
         ).toBeInTheDocument();
         expect(
             screen.getByText(UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY),
         ).toBeInTheDocument();
 
         const buyCachetButton = screen.getByRole('button', {
             name: 'Buy Cachet (CACHET)',
         });
         expect(buyCachetButton).toBeInTheDocument();
 
         // Note I was not able to adjust the slider value in react testing library
         // We do the min buy
 
         await userEvent.click(buyCachetButton);
 
         expect(
             screen.getByText(
                 `Buy ${UPDATED_CACHET_SPOT_MIN_QTY} Cachet (CACHET) for 3,601.92 XEC (${UPDATED_CACHET_SPOT_PRICE_FIAT_MIN_BUY})?`,
             ),
         ).toBeInTheDocument();
 
         // We buy
         await userEvent.click(screen.getByText('OK'));
 
         // Error notification for buy we can't afford
         expect(
             await screen.findByText(
                 `Error: Insufficient utxos to accept this offer`,
             ),
         ).toBeInTheDocument();
     });
 });
diff --git a/cashtab/src/components/Etokens/__tests__/TokenActions.test.js b/cashtab/src/components/Etokens/__tests__/TokenActions.test.js
index c1531aee4..1ef8d4bcf 100644
--- a/cashtab/src/components/Etokens/__tests__/TokenActions.test.js
+++ b/cashtab/src/components/Etokens/__tests__/TokenActions.test.js
@@ -1,1941 +1,1933 @@
 // Copyright (c) 2024 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 import React from 'react';
 import { render, screen, waitFor } from '@testing-library/react';
 import '@testing-library/jest-dom';
 import userEvent from '@testing-library/user-event';
 import { when } from 'jest-when';
 import {
     initializeCashtabStateForTests,
     clearLocalForage,
 } from 'components/App/fixtures/helpers';
 import CashtabTestWrapper from 'components/App/fixtures/CashtabTestWrapper';
 import appConfig from 'config/app';
 import 'fake-indexeddb/auto';
 import localforage from 'localforage';
 import {
     tokenTestWallet,
     supportedTokens,
     slp1FixedMocks,
     slp1VarMocks,
     alpMocks,
     slp1NftParentMocks,
     slp1NftParentWithChildrenMocks,
     slp1NftChildMocks,
 } from 'components/Etokens/fixtures/mocks';
 import {
     cachedHeismanNftOne,
     heismanNftOneOffer,
     heismanNftOneCache,
     heismanCollectionCacheMocks,
 } from 'components/Agora/fixtures/mocks';
 import CashtabCache from 'config/CashtabCache';
 import { cashtabCacheToJSON } from 'helpers';
 import { Ecc, initWasm } from 'ecash-lib';
 import { MockAgora } from '../../../../../modules/mock-chronik-client';
 import { Agora } from 'ecash-agora';
 import { token as tokenConfig } from 'config/token';
 import { explorer } from 'config/explorer';
 
 describe('<Token /> available actions rendered', () => {
     let ecc;
     beforeAll(async () => {
         await initWasm();
         ecc = new Ecc();
     });
     let mockedChronik;
     beforeEach(async () => {
         const mockedDate = new Date('2022-01-01T12:00:00.000Z');
         jest.spyOn(global, 'Date').mockImplementation(() => mockedDate);
         // Mock the app with context at the Token Action screen
         mockedChronik = await initializeCashtabStateForTests(
             tokenTestWallet,
             localforage,
         );
 
         // Build chronik mocks that Cashtab would use to add token info to cache
         for (const tokenMock of supportedTokens) {
             mockedChronik.setMock('token', {
                 input: tokenMock.tokenId,
                 output: tokenMock.token,
             });
             mockedChronik.setMock('tx', {
                 input: tokenMock.tokenId,
                 output: tokenMock.tx,
             });
             mockedChronik.setTokenId(tokenMock.tokenId);
             mockedChronik.setUtxosByTokenId(tokenMock.tokenId, {
                 tokenId: tokenMock.tokenId,
                 utxos: tokenMock.utxos,
             });
             // Set empty tx history to mock no existing NFTs
             mockedChronik.setTxHistoryByTokenId(tokenMock.tokenId, []);
         }
 
         // Mock the fetch call to Cashtab's price API
         global.fetch = jest.fn();
         const fiatCode = 'usd'; // Use usd until you mock getting settings from localforage
         const cryptoId = appConfig.coingeckoId;
         // Keep this in the code, because different URLs will have different outputs requiring different parsing
         const priceApiUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${cryptoId}&vs_currencies=${fiatCode}&include_last_updated_at=true`;
         const xecPrice = 0.00003;
         const priceResponse = {
             ecash: {
                 usd: xecPrice,
                 last_updated_at: 1706644626,
             },
         };
         when(fetch)
             .calledWith(priceApiUrl)
             .mockResolvedValue({
                 json: () => Promise.resolve(priceResponse),
             });
     });
     afterEach(async () => {
         jest.clearAllMocks();
         await clearLocalForage(localforage);
     });
     it('SLP1 fixed supply token', async () => {
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 route={`/send-token/${slp1FixedMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1FixedMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `SLP 1 fungible token. Token may be of fixed supply if no mint batons exist. If you have a mint baton, you can mint more of this token at any time. May have up to 9 decimal places.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The supply is correctly rendered as fixed
         expect(
             screen.getByText('2,999,998,798.000000000 (fixed)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // The sell switch is turned on by default
         expect(screen.getByTitle('Toggle Sell Token')).toHaveProperty(
             'checked',
             true,
         );
 
         // The send switch is present
         expect(screen.getByTitle('Toggle Send')).toBeInTheDocument();
 
         // The Airdrop switch is present
         expect(screen.getByTitle('Toggle Airdrop')).toBeInTheDocument();
 
         // The Burn switch is present
         expect(screen.getByTitle('Toggle Burn')).toBeInTheDocument();
 
         // The Mint switch is not rendered
         expect(screen.queryByTitle('Toggle Mint')).not.toBeInTheDocument();
     });
     it('SLP1 variable supply token with mint baton', async () => {
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 route={`/send-token/${slp1VarMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1VarMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `SLP 1 fungible token. Token may be of fixed supply if no mint batons exist. If you have a mint baton, you can mint more of this token at any time. May have up to 9 decimal places.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The supply is correctly rendered as fixed
         expect(
             screen.getByText('18,446,744,073.709551615 (var.)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // The sell switch is turned on by default
         expect(screen.getByTitle('Toggle Sell Token')).toHaveProperty(
             'checked',
             true,
         );
 
         // The send switch is present
         expect(screen.getByTitle('Toggle Send')).toBeInTheDocument();
 
         // The Airdrop switch is present
         expect(screen.getByTitle('Toggle Airdrop')).toBeInTheDocument();
 
         // The Burn switch is present
         expect(screen.getByTitle('Toggle Burn')).toBeInTheDocument();
 
         // The Mint switch is present and not disabled
         expect(screen.getByTitle('Toggle Mint')).toHaveProperty(
             'disabled',
             false,
         );
     });
     it('We can list an SLP1 fungible token', async () => {
         // Mock Math.random()
         jest.spyOn(global.Math, 'random').mockReturnValue(0.5); // set a fixed value
 
         // SLP1 ad prep
         const adPrepHex =
             '0200000002666de5d5852807a13612b6ea0373643266d435822daeb39c29e5d4b67e893cda0100000064414feb64ffdf50b0eb40a6fe0c34da65e94e0cbbbc2e58f2b290f3b2bf31480b34a57c4862ee177129dc8a1ce645573cd240e5e83d336d19ff22c3a7675bc903564121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf7926180300000064410f0461f0e843cc5b78196e3fdb3b89d64948629645f3b44ea960c2a5ac8f5835189697165a01cc259a0f4eff931c83e110019ee5c7721a43e0dde11ba04e068d4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff040000000000000000406a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f80800000019d80000000800000000001d9600060500000000000017a914e49e695e2f466e34447cb253567b8b277b60e3908722020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac2c2e0f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const adPrepTxid =
             '280b6fda5a11a94145f3b4203fb4f199d875d3621c8e4cc9d63501e73b9649bc';
 
         mockedChronik.setMock('broadcastTx', {
             input: adPrepHex,
             output: { txid: adPrepTxid },
         });
 
         // SLP1 ad list
         const adListHex =
             '0200000001bc49963be70135d6c94c8e1c62d375d899f1b43f20b4f34541a9115ada6f0b2801000000dd0441475230075041525449414c41b11b013fb8140dcce13f93ee99584b1c6b547ee076ed63f9ec0a6c0068ad84c5420ecd608af68134366576bae4196a83f6a8f521c50dea4acc75dda6215c7fec414c8c4c766a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f80800000000000000000300dbf30400000000003dc7010000000000d226af0c000000002099c53f031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02d01557f77ad075041525449414c88044147523087ffffffff020000000000000000376a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f80800000019d8000000220200000000000017a91472df09389a835adb0e13e32bf1c91144ed107eef8700000000';
         const adListTxid =
             '823f652e22d154fc7bdd77ee9d9fa37c77e9649235f1430958bef68b7428b9ae';
 
         mockedChronik.setMock('broadcastTx', {
             input: adListHex,
             output: { txid: adListTxid },
         });
 
-        // We need to give mockedChronik a plugin function
-        // This is required for creating a new Agora(mockedChronik)
-        mockedChronik.plugin = () => 'dummy plugin';
-
         // Mock response for agora select params check
         // Note
         // We obtain EXPECTED_OFFER_P2SH by adding
         // console.log(toHex(shaRmd160(agoraScript.bytecode)));
         // to ecash-agora lib and running this test
         // Note that Date() and Math.random() must be mocked to keep this deterministic
         const EXPECTED_OFFER_P2SH = '72df09389a835adb0e13e32bf1c91144ed107eef';
 
         mockedChronik.setScript('p2sh', EXPECTED_OFFER_P2SH);
         // We mock no existing utxos
         mockedChronik.setUtxos('p2sh', EXPECTED_OFFER_P2SH, { utxos: [] });
         const agora = new Agora(mockedChronik);
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={agora}
                 route={`/send-token/${slp1FixedMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1FixedMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Token image is rendered
         expect(
             screen.getByAltText(`icon for ${slp1FixedMocks.tokenId}`),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, default action for SLP is to list it
         expect(screen.getByTitle('Toggle Sell Token')).toBeEnabled();
 
         // The list button is disabled on load
         const listButton = screen.getByRole('button', {
             name: /List Vespene Gas/,
         });
         expect(listButton).toHaveProperty('disabled', true);
 
         // The price input is disabled until qty values are entered
         const priceInput = screen.getByPlaceholderText(
             'Enter list price (per token)',
         );
         expect(priceInput).toHaveProperty('disabled', true);
 
         // Enter token balance as offered qty
         await userEvent.type(screen.getByPlaceholderText('Offered qty'), '111');
 
         // Enter a min qty
         await userEvent.type(screen.getByPlaceholderText('Min buy'), '11');
 
         // The price input is no longer disabled
         expect(priceInput).toHaveProperty('disabled', false);
 
         // We see expected error msg if we try to list the token at a price where the min buy would cost less than dust
         await userEvent.type(priceInput, '0.001');
 
         expect(
             screen.getByText(
                 'Minimum buy costs 0.011 XEC, must be at least 5.46 XEC',
             ),
         ).toBeInTheDocument();
 
         // The buy button is disabled with invalid price
         expect(listButton).toHaveProperty('disabled', true);
 
         // Increase the price to a valid one
         await userEvent.clear(priceInput);
         await userEvent.type(priceInput, '0.5');
 
         // The list button is no longer disabled
         expect(listButton).toHaveProperty('disabled', false);
 
         // The fiat price is previewed correctly
         expect(
             screen.getByText('0.50 XEC ($0.000015 USD) per token'),
         ).toBeInTheDocument();
 
         // We can also set the price in fiat currency
         await userEvent.selectOptions(
             screen.getByTestId('currency-select-dropdown'),
             screen.getByTestId('fiat-option'),
         );
 
         // The price input is cleared when the user changes from XEC price to fiat price
         expect(priceInput).toHaveValue(null);
 
         // We list for $2 per token
         await userEvent.type(priceInput, '5');
 
         // The fiat price is previewed correctly
         expect(
             screen.getByText('$5 USD (166,666.67 XEC) per token'),
         ).toBeInTheDocument();
 
         // We enter a low price in fiat
         await userEvent.clear(priceInput);
         await userEvent.type(priceInput, '0.00005');
 
         // The fiat price is previewed correctly
         expect(
             await screen.findByText('$0.00005 USD (1.67 XEC) per token'),
         ).toBeInTheDocument();
 
         // Click the now-enabled list button
         await userEvent.click(listButton);
 
         // We see expected confirmation modal to list the Token
         expect(screen.getByText('List VSP?')).toBeInTheDocument();
         expect(
             screen.getByText('Create the following sell offer?'),
         ).toBeInTheDocument();
         // Offered qty (actual, calculated from AgoraOffer)
         const actualOfferedQty = '110.998061056';
         expect(screen.getByText(actualOfferedQty)).toBeInTheDocument();
         // Min by (actual, calculated from AgoraOffer)
         expect(screen.getByText('11.005853696')).toBeInTheDocument();
         // Actual price calculated from AgoraOffer
         const actualPricePerTokenForMinBuy = '1.66 XEC';
         expect(
             screen.getByText(actualPricePerTokenForMinBuy),
         ).toBeInTheDocument();
         // User input price
         expect(screen.getByText('1.67 XEC')).toBeInTheDocument();
 
         // We can cancel and not create this listing
         await userEvent.click(screen.getByText('Cancel'));
 
         // The confirmation modal is gone
         expect(screen.queryByText('List VSP?')).not.toBeInTheDocument();
 
         // We change our mind and list it
         await userEvent.click(listButton);
         // We wait for the preview to be calculated again
 
         expect(await screen.findByText('List VSP?')).toBeInTheDocument();
         await userEvent.click(screen.getByText('OK'));
 
         // We see expected toast notification for the ad setup tx
         expect(
             await screen.findByText(
                 `Successful ad setup tx to offer ${actualOfferedQty} Vespene Gas for ${actualPricePerTokenForMinBuy} per token`,
             ),
         ).toBeInTheDocument();
 
         // We see the expected toast notification for the successful listing tx
         expect(
             await screen.findByText(
                 `${actualOfferedQty} Vespene Gas listed for ${actualPricePerTokenForMinBuy} per token`,
             ),
         ).toBeInTheDocument();
     });
     it('We can correctly render an SLP1 NFT Parent token with no NFT Mint inputs, then create some NFT Mint inputs', async () => {
         const hex =
             '0200000002cc04a35686950a66845ebf8e37677fffcc5ee0e2b63e3f05822838273149660c010000006441878aa7e698097a4961646a2da44f701d8895cb065113fcf1d2e9f073afbc37025a5587e121bd0311a24a7af60445abfc4de7e3675a3a9f51cffddc875d88fca24121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf7926180300000064412f509f90f23f4b85b27452e0f25d33cef07ad8fef898e2d308c43fb0dfd6f7e00f7201336be4089171ddc094a24688882b518ec0c6958c904df12d0239a7342f4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff150000000000000000d96a04534c500001810453454e44200c66493127382882053f3eb6e2e05eccff7f67378ebf5e84660a958656a304cc08000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000000108000000000000005222020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac0d070f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'cdc6afbf1ddd796388692ec9106816be1f9229ece11e545c1cbe6854ccf087ec';
 
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 route={`/token/${slp1NftParentMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftParentMocks.token.genesisInfo;
 
         // Wait for the component to finish loading
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `The parent tokens for an NFT collection. Can be used to mint NFTs. No decimal places. The supply of this token is the potential quantity of NFTs which could be minted. If no mint batons exist, the supply is fixed.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The supply is correctly rendered
         expect(screen.getByText('100 (var.)')).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // The fan-out action is available
         expect(
             screen.getByTitle('Toggle NFT Parent Fan-out'),
         ).toBeInTheDocument();
 
         // This action is checked by default if the user has no fanInputs
         expect(screen.getByTitle('Toggle NFT Parent Fan-out')).toHaveProperty(
             'checked',
             true,
         );
 
         // The mint NFT option is available
         expect(screen.getByTitle('Toggle Mint NFT')).toBeInTheDocument();
 
         // The mint NFT option is disabled if there are no mint inputs
         expect(screen.getByTitle('Toggle Mint NFT')).toHaveProperty(
             'disabled',
             true,
         );
 
         // The mint NFT switch label explains why it is disabled
         expect(screen.getByText('(no NFT mint inputs)')).toBeInTheDocument();
 
         // The Airdrop action is available
         expect(screen.getByTitle('Toggle Airdrop')).toBeInTheDocument();
 
         // The Burn action is NOT available
         expect(screen.queryByTitle('Toggle Burn')).not.toBeInTheDocument();
 
         // We can create NFT mint inputs by executing a fan-out tx
         await userEvent.click(
             screen.getByRole('button', { name: /Create NFT Mint Inputs/ }),
         );
 
         // We see expected toast notification
         expect(
             await screen.findByText('NFT Mint inputs created'),
         ).toBeInTheDocument();
     });
     it('We can correctly render an SLP1 NFT Parent token with NFT Mint inputs, then mint an NFT', async () => {
         // We need to use a unique mockedChronik for this test, with at least one nft mint input utxo
         // Mock the app with context at the Token Action screen
         const mintNftMockedChronik = await initializeCashtabStateForTests(
             {
                 ...tokenTestWallet,
                 state: {
                     ...tokenTestWallet.state,
                     slpUtxos: [
                         ...tokenTestWallet.state.slpUtxos,
                         {
                             outpoint: {
                                 txid: '3333333333333333333333333333333333333333333333333333333333333333',
                                 outIdx: 1,
                             },
                             blockHeight: 840012,
                             isCoinbase: false,
                             value: 546,
                             isFinal: true,
                             token: {
                                 tokenId:
                                     '0c66493127382882053f3eb6e2e05eccff7f67378ebf5e84660a958656a304cc',
                                 tokenType: {
                                     protocol: 'SLP',
                                     type: 'SLP_TOKEN_TYPE_NFT1_GROUP',
                                     number: 129,
                                 },
                                 amount: '1',
                                 isMintBaton: false,
                             },
                             path: 1899,
                         },
                     ],
                 },
             },
             localforage,
         );
 
         // Build chronik mocks that Cashtab would use to add token info to cache
         for (const tokenMock of supportedTokens) {
             mintNftMockedChronik.setMock('token', {
                 input: tokenMock.tokenId,
                 output: tokenMock.token,
             });
             mintNftMockedChronik.setMock('tx', {
                 input: tokenMock.tokenId,
                 output: tokenMock.tx,
             });
             mintNftMockedChronik.setTokenId(tokenMock.tokenId);
             mintNftMockedChronik.setUtxosByTokenId(tokenMock.tokenId, {
                 tokenId: tokenMock.tokenId,
                 utxos: tokenMock.utxos,
             });
             // Set empty tx history to mock no existing NFTs
             mintNftMockedChronik.setTxHistoryByTokenId(tokenMock.tokenId, []);
         }
 
         const hex =
             '020000000233333333333333333333333333333333333333333333333333333333333333330100000064412564b7504e0ec0a094aae832fee07ce86f21de56153a71c99bcc50a20d4f79ba264cccd4fc39d4840af59e0f013cb535b07ae31795197db0fcda47b8ef91973b4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf7926180300000064418758fd9e1a9eec69b262ba29227a1cbb0990dca35f7deadb91145af82e922cabe1efcb688c4a498fefbc903d6d4b5cdb8facdf624e7cbde95065b7ad014a54864121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff0300000000000000003c6a04534c500001410747454e4553495304414243310b426974636f696e204142430b636173687461622e636f6d4c0001004c0008000000000000000122020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac7a330f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'd215995b67194576b66ef9c593a66d9255a3ec21e424ecfbb6046643b8e0dbe6';
 
         mintNftMockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
         render(
             <CashtabTestWrapper
                 chronik={mintNftMockedChronik}
                 ecc={ecc}
                 route={`/token/${slp1NftParentMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftParentMocks.token.genesisInfo;
 
         // Wait for the component to finish loading
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `The parent tokens for an NFT collection. Can be used to mint NFTs. No decimal places. The supply of this token is the potential quantity of NFTs which could be minted. If no mint batons exist, the supply is fixed.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The supply is correctly rendered
         expect(screen.getByText('100 (var.)')).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // The fan-out action is available
         expect(
             screen.getByTitle('Toggle NFT Parent Fan-out'),
         ).toBeInTheDocument();
 
         // The fan-out action is NOT checked by default because we have a single fan input
         expect(screen.getByTitle('Toggle NFT Parent Fan-out')).toHaveProperty(
             'checked',
             false,
         );
 
         // The mint NFT option is available
         expect(screen.getByTitle('Toggle Mint NFT')).toBeInTheDocument();
 
         // The mint NFT option is NOT disabled as we have a single mint input
         expect(screen.getByTitle('Toggle Mint NFT')).toHaveProperty(
             'disabled',
             false,
         );
 
         // The mint NFT switch label does not include the disabled explanation
         expect(
             screen.queryByText('(no NFT mint inputs)'),
         ).not.toBeInTheDocument();
 
         // The mint NFT switch label shows available NFT mint inputs
         expect(screen.getByText('(1 input available)')).toBeInTheDocument();
 
         // The Airdrop action is available
         expect(screen.getByTitle('Toggle Airdrop')).toBeInTheDocument();
 
         // The Burn action is NOT available
         expect(screen.queryByTitle('Toggle Burn')).not.toBeInTheDocument();
 
         // We can mint an NFT if we give it a name and a ticker
         await userEvent.type(
             await screen.findByPlaceholderText('Enter a name for your NFT'),
             'Bitcoin ABC',
         );
 
         // The mint button is disabled as the user has not entered a ticker
         expect(screen.getByRole('button', { name: /Mint NFT/ })).toHaveProperty(
             'disabled',
             true,
         );
 
         expect(
             screen.getByText('NFT must have a name and a ticker'),
         ).toBeInTheDocument();
 
         // We give the NFT a ticker
         await userEvent.type(
             await screen.findByPlaceholderText('Enter a ticker for your NFT'),
             'ABC1',
         );
 
         // The mint button is no longer disabled
         expect(screen.getByRole('button', { name: /Mint NFT/ })).toHaveProperty(
             'disabled',
             false,
         );
 
         await userEvent.click(screen.getByRole('button', { name: /Mint NFT/ }));
 
         // We see a preview modal, click OK
         await userEvent.click(screen.getByText('OK'));
 
         // We see expected toast notification
         expect(await screen.findByText('NFT Minted!')).toBeInTheDocument();
     });
     it('We can render an SLP1 NFT Parent token with a minted NFT in its collection', async () => {
         // We need to use a unique mockedChronik for this test, with at least one nft mint input utxo
         // Mock the app with context at the Token Action screen
 
         // Note the Token page will render all NFTs in a collection based on whether or not they exist,
         // not based on whether or not they are in the user's wallet
         // The user actions available for the child NFTs depend on whether or not the NFTs exist in the user's wallet
         const renderChildNftsMockedChronik =
             await initializeCashtabStateForTests(
                 {
                     ...tokenTestWallet,
                     state: {
                         ...tokenTestWallet.state,
                         slpUtxos: [
                             ...tokenTestWallet.state.slpUtxos,
                             // Its parent NFT so this is cached
                             slp1NftParentWithChildrenMocks.utxos[0],
                             // A child NFT in the utxo set
                             slp1NftChildMocks.utxos[0],
                         ],
                     },
                 },
                 localforage,
             );
 
         // Build chronik mocks that Cashtab would use to add token info to cache
         for (const tokenMock of supportedTokens) {
             renderChildNftsMockedChronik.setMock('token', {
                 input: tokenMock.tokenId,
                 output: tokenMock.token,
             });
             renderChildNftsMockedChronik.setMock('tx', {
                 input: tokenMock.tokenId,
                 output: tokenMock.tx,
             });
             renderChildNftsMockedChronik.setTokenId(tokenMock.tokenId);
             renderChildNftsMockedChronik.setUtxosByTokenId(tokenMock.tokenId, {
                 tokenId: tokenMock.tokenId,
                 utxos: tokenMock.utxos,
             });
             // Set tx history of parent tokenId to empty
             renderChildNftsMockedChronik.setTxHistoryByTokenId(
                 tokenMock.tokenId,
                 [],
             );
         }
 
         // Set tx history of parent tokenId to include an NFT
         renderChildNftsMockedChronik.setTxHistoryByTokenId(
             slp1NftParentWithChildrenMocks.tokenId,
             [slp1NftChildMocks.tx],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={renderChildNftsMockedChronik}
                 ecc={ecc}
                 route={`/token/${slp1NftParentWithChildrenMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftParentWithChildrenMocks.token.genesisInfo;
 
         // Wait for the component to finish loading
         await waitFor(() =>
             expect(
                 screen.queryByTitle('Cashtab Loading'),
             ).not.toBeInTheDocument(),
         );
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `The parent tokens for an NFT collection. Can be used to mint NFTs. No decimal places. The supply of this token is the potential quantity of NFTs which could be minted. If no mint batons exist, the supply is fixed.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The wallet balance of this token is correctly rendered
         expect(screen.getByText('1 (fixed)')).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // The fan-out action is available
         expect(
             screen.getByTitle('Toggle NFT Parent Fan-out'),
         ).toBeInTheDocument();
 
         // The fan-out action is NOT checked by default because we have a single fan input
         expect(screen.getByTitle('Toggle NFT Parent Fan-out')).toHaveProperty(
             'checked',
             false,
         );
 
         // The mint NFT option is available
         expect(screen.getByTitle('Toggle Mint NFT')).toBeInTheDocument();
 
         // The mint NFT option is NOT disabled as we have a single mint input
         expect(screen.getByTitle('Toggle Mint NFT')).toHaveProperty(
             'disabled',
             false,
         );
 
         // The mint NFT switch label does not include the disabled explanation
         expect(
             screen.queryByText('(no NFT mint inputs)'),
         ).not.toBeInTheDocument();
 
         // The mint NFT switch label shows available NFT mint inputs
         expect(screen.getByText('(1 input available)')).toBeInTheDocument();
 
         // The Airdrop action is available
         expect(screen.getByTitle('Toggle Airdrop')).toBeInTheDocument();
 
         // The Burn action is NOT available
         expect(screen.queryByTitle('Toggle Burn')).not.toBeInTheDocument();
 
         // A child NFT is rendered
         expect(screen.getByText('NFTs in this Collection')).toBeInTheDocument();
 
         // NFT image is rendered
         expect(
             screen.getByAltText(`icon for ${slp1NftChildMocks.tokenId}`),
         ).toBeInTheDocument();
 
         // NFT name is rendered
         expect(screen.getByText('Gordon Chen')).toBeInTheDocument();
     });
     it('We can list an SLP1 NFT', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(slp1NftChildMocks.tokenId, []);
 
         // activeOffersByPubKey
         // The test wallet is selling the Saturn V NFT
         mockedAgora.setActiveOffersByPubKey(
             tokenTestWallet.paths.get(appConfig.derivationPath).pk,
             [],
         );
 
         // activeOffersByGroupTokenId does not need to be mocked since there are no offers here
 
         // NFT ad prep
         const adPrepHex =
             '0200000002268322a2a8e67fe9efdaf15c9eb7397fb640ae32d8a245c2933f9eb967ff9b5d010000006441e4365d350b1dfee55e60cc2600ba094ed0e05c1d6a297bd3fe3f0721b88d9ec09b7d114cf0aab08a3b264153858f1a48f839f3639a8a8f9b11214038080cb9e34121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf7926180300000064411e9913b28017832fa38944675eb8815411fd210f9dfc8f0aa806bed055f52b6592488fdd1f9be942c19dcb98d7ddd7c55bc8b1233a64ad3dfa1c65eebbd48f254121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff030000000000000000376a04534c500001410453454e44205d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a22283260800000000000000019a0400000000000017a91407d2b0e6ec7b96cbfbe4a7d54e28d28fbcf65e408710310f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const adPrepTxid =
             '7b4f2b1cf9716ead03f91910bd0c08956c381987e1cb3cd9f9b4d555a7b9ba25';
 
         mockedChronik.setMock('broadcastTx', {
             input: adPrepHex,
             output: { txid: adPrepTxid },
         });
 
         // NFT ad list
         const adListHex =
             '020000000125bab9a755d5b4f9d93ccbe18719386c95080cbd1019f903ad6e71f91c2b4f7b01000000a70441475230074f4e4553484f544106bd7c3cc4f6aca45a7f97644b8cb5e745dee224246f38605171e8f9e0d6e036af3ea4853b08e1baa92e091bd0ceabf83d4a246e07e6b0b008a3e091b111f22a414c56222b50fe00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac7521031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dad074f4e4553484f5488044147523087ffffffff020000000000000000376a04534c500001410453454e44205d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a2228326080000000000000001220200000000000017a914729833ae294590bbcf28bfbb9ad54c01b6cdb6288700000000';
         const adListTxid =
             '97cf0fed5062419ad456f22457cfeb3b15909f1de2350be48c53b24944e0de89';
 
         mockedChronik.setMock('broadcastTx', {
             input: adListHex,
             output: { txid: adListTxid },
         });
 
         // NFT send
         const hex =
             '0200000002268322a2a8e67fe9efdaf15c9eb7397fb640ae32d8a245c2933f9eb967ff9b5d010000006441fff60607ba0fb6eda064075b321abc3980c249efcc0e91d4d95e464500a654476e59b76dd19bdd66f5d207a0d731550c93ce724a09e00a3bff3fcfbc08c970844121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf792618030000006441fe754300443dfb293619693087016c9d9a8437489d48cb7c0c3fcb6b5af6277833ff7156355aeb557145c4075b7917d90d79239ba7bf776a38fef935d8da2f7c4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff030000000000000000376a04534c500001410453454e44205d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a222832608000000000000000122020000000000001976a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac84330f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'daa5872d1ef95a05bd3ee59fc532aa7921a54b783a5af68c5aa9146f61d2e134';
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${slp1NftChildMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftChildMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // NFT image is rendered
         expect(
             screen.getByAltText(`icon for ${slp1NftChildMocks.tokenId}`),
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `eCash NFT. NFT supply is always 1. This NFT may belong to an NFT collection.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // For an NFT, we render the NFT name, not balance, as it is always 1 if we can see this page
         expect(screen.getByText('Gordon Chen')).toBeInTheDocument();
 
         // We see what collection this NFT is from
         expect(screen.getByText(/NFT from collection/)).toBeInTheDocument();
         expect(
             screen.getByText('The Four Half-Coins of Jin-qua'),
         ).toBeInTheDocument();
 
         // Token actions are available for NFTs
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, default action for NFT is to list it
         expect(screen.getByTitle('Toggle Sell NFT')).toHaveProperty(
             'checked',
             true,
         );
 
         // We see a price input field for listing this NFT
         const priceInput = screen.getByPlaceholderText('Enter NFT list price');
         expect(priceInput).toBeInTheDocument();
 
         // We see expected error msg if we try to list the NFT for less than dust
         await userEvent.type(priceInput, '5.45');
         expect(
             screen.getByText('List price cannot be less than dust (5.46 XEC).'),
         ).toBeInTheDocument();
 
         // The List button is disabled on bad validation
         const listButton = screen.getByRole('button', {
             name: /List Gordon Chen/,
         });
         expect(listButton).toHaveProperty('disabled', true);
 
         await userEvent.clear(priceInput);
 
         // No validation error if NFT list price is for more than dust
         await userEvent.type(priceInput, '10000');
         expect(
             screen.queryByText(
                 'List price cannot be less than dust (5.46 XEC).',
             ),
         ).not.toBeInTheDocument();
 
         // The List button is NOT disabled if price is greater than dust
         expect(listButton).toHaveProperty('disabled', false);
 
         // The fiat price is previewed correctly
         expect(screen.getByText('10,000 XEC = $ 0.30 USD')).toBeInTheDocument();
 
         // We can also set the price in fiat currency
         await userEvent.selectOptions(
             screen.getByTestId('currency-select-dropdown'),
             screen.getByTestId('fiat-option'),
         );
 
         // The price input is cleared when the user changes from XEC price to fiat price
         expect(priceInput).toHaveValue(null);
 
         // We list the NFT for $5
         await userEvent.type(priceInput, '5');
 
         // The fiat price is previewed correctly
         expect(
             screen.getByText(/\$ 5 USD = 166,666.67 XEC/),
         ).toBeInTheDocument();
 
         // Click the now-enabled list button
         await userEvent.click(listButton);
 
         // We see expected confirmation modal to list the NFT
         expect(screen.getByText(/List GC for \$ 5 USD/)).toBeInTheDocument();
 
         // We can cancel and not list the NFT
         await userEvent.click(screen.getByText('Cancel'));
 
         // The confirmation modal is gone
         expect(
             screen.queryByText(/List GC for \$ 5 USD/),
         ).not.toBeInTheDocument();
 
         // We change our mind
         await userEvent.click(listButton);
         await userEvent.click(screen.getByText('OK'));
 
         // We see expected toast notification for the ad setup tx
         expect(await screen.findByText('Created NFT ad')).toBeInTheDocument();
         // We see the expected toast notification for the successful listing tx
         expect(
             await screen.findByText(/NFT listed for 166,666.67 XEC/),
         ).toBeInTheDocument();
 
         // Screen should check for new listings and show the listing on this page
         // Cannot test this without regtest, as we would need MockedAgora to show no
         // active offers on load, then 1 offer after listing
         // Can confirm in manual testing
     });
     it('We can send an SLP1 NFT', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(slp1NftChildMocks.tokenId, []);
 
         // NFT send
         const hex =
             '0200000002268322a2a8e67fe9efdaf15c9eb7397fb640ae32d8a245c2933f9eb967ff9b5d010000006441fff60607ba0fb6eda064075b321abc3980c249efcc0e91d4d95e464500a654476e59b76dd19bdd66f5d207a0d731550c93ce724a09e00a3bff3fcfbc08c970844121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf792618030000006441fe754300443dfb293619693087016c9d9a8437489d48cb7c0c3fcb6b5af6277833ff7156355aeb557145c4075b7917d90d79239ba7bf776a38fef935d8da2f7c4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff030000000000000000376a04534c500001410453454e44205d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a222832608000000000000000122020000000000001976a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac84330f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'daa5872d1ef95a05bd3ee59fc532aa7921a54b783a5af68c5aa9146f61d2e134';
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${slp1NftChildMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftChildMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // On load, default action for NFT is to list it
         const sellActionSwitch = screen.getByTitle('Toggle Sell NFT');
         expect(sellActionSwitch).toHaveProperty('checked', true);
 
         // Sending is disabled
         const sendActionSwitch = screen.getByTitle('Toggle Send');
 
         expect(sendActionSwitch).toHaveProperty('checked', false);
 
         // When we enable Sending, Selling is disabled, and Sending is enabled
         await userEvent.click(sendActionSwitch);
         expect(sendActionSwitch).toHaveProperty('checked', true);
         expect(sellActionSwitch).toHaveProperty('checked', false);
 
         // We see an Address input
         const addrInput = screen.getByPlaceholderText('Address');
         expect(addrInput).toBeInTheDocument();
 
         // Send button is disabled before address entry
         const sendButton = screen.getByRole('button', {
             name: /Send GC/,
         });
         expect(sendButton).toHaveProperty('disabled', true);
 
         // We can enter an address
         await userEvent.type(
             addrInput,
             'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035',
         );
 
         // Now the button is enabled
         expect(sendButton).toHaveProperty('disabled', false);
 
         // We can send an NFT
         await userEvent.click(sendButton);
 
         expect(await screen.findByText('NFT sent')).toBeInTheDocument();
     });
     it('SLP1 NFT page will update cashtab token cache for the NFT if it does not include groupTokenId, and for its parent if it is not in cache', async () => {
         // Use wallet with nft utxo as only utxo
         // Preset a cache without groupTokenId
         // Use existing tx and token mocks
 
         // We need to use a unique mockedChronik for this test, with a minted NFT utxo but no parent utxo
 
         // The user actions available for the child NFTs depend on whether or not the NFTs exist in the user's wallet
         const renderChildNftsMockedChronik =
             await initializeCashtabStateForTests(
                 {
                     ...tokenTestWallet,
                     state: {
                         ...tokenTestWallet.state,
                         slpUtxos: [
                             // Only a child NFT in the utxo set
                             slp1NftChildMocks.utxos[0],
                         ],
                         tokens: new Map([
                             [
                                 '5d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a2228326',
                                 '1',
                             ],
                         ]),
                     },
                 },
                 localforage,
             );
         const mockCashtabCacheWithNft = new CashtabCache([
             [
                 slp1NftChildMocks.tokenId,
                 {
                     // note that this mock DOES NOT include groupTokenId
                     ...slp1NftChildMocks.token,
                     genesisSupply: '1',
                     genesisOutputScripts: [
                         '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac',
                     ],
                     genesisMintBatons: 0,
                 },
             ],
         ]);
 
         await localforage.setItem(
             'cashtabCache',
             cashtabCacheToJSON(mockCashtabCacheWithNft),
         );
 
         // Build chronik mocks that Cashtab would use to add token info to cache
         for (const tokenMock of supportedTokens) {
             renderChildNftsMockedChronik.setMock('token', {
                 input: tokenMock.tokenId,
                 output: tokenMock.token,
             });
             renderChildNftsMockedChronik.setMock('tx', {
                 input: tokenMock.tokenId,
                 output: tokenMock.tx,
             });
             renderChildNftsMockedChronik.setTokenId(tokenMock.tokenId);
             renderChildNftsMockedChronik.setUtxosByTokenId(tokenMock.tokenId, {
                 tokenId: tokenMock.tokenId,
                 utxos: tokenMock.utxos,
             });
             // Set tx history of parent tokenId to empty
             renderChildNftsMockedChronik.setTxHistoryByTokenId(
                 tokenMock.tokenId,
                 [],
             );
         }
 
         // Set tx history of parent tokenId to include an NFT
         renderChildNftsMockedChronik.setTxHistoryByTokenId(
             slp1NftParentWithChildrenMocks.tokenId,
             [slp1NftChildMocks.tx],
         );
 
         render(
             <CashtabTestWrapper
                 chronik={renderChildNftsMockedChronik}
                 ecc={ecc}
                 route={`/token/${slp1NftChildMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = slp1NftChildMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // NFT image is rendered
         expect(
             screen.getByAltText(`icon for ${slp1NftChildMocks.tokenId}`),
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 `eCash NFT. NFT supply is always 1. This NFT may belong to an NFT collection.`,
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The NFT Token name is the title
         expect(screen.getByText('Gordon Chen')).toBeInTheDocument();
 
         // We see what collection this NFT is from
         expect(screen.getByText(/NFT from collection/)).toBeInTheDocument();
         expect(
             screen.getByText('The Four Half-Coins of Jin-qua'),
         ).toBeInTheDocument();
 
         // Token actions are available for NFTs
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, the default action for an NFT is to list it
         const nftListInput = screen.getByPlaceholderText(
             'Enter NFT list price',
         );
         expect(nftListInput).toBeInTheDocument();
     });
     it('We show an agora query error if we cannot get active offers for an NFT token id', async () => {
         const heismanNftTokenId = heismanNftOneOffer.token.tokenId;
 
         // Mock the API calls for getting and caching this token's info
         mockedChronik.setMock('token', {
             input: heismanNftTokenId,
             output: heismanNftOneCache.token,
         });
         mockedChronik.setMock('tx', {
             input: heismanNftTokenId,
             output: heismanNftOneCache.tx,
         });
         // Also mock for the collection
         mockedChronik.setMock('token', {
             input: heismanCollectionCacheMocks.tokenId,
             output: heismanCollectionCacheMocks.token,
         });
         mockedChronik.setMock('tx', {
             input: heismanCollectionCacheMocks.tokenId,
             output: heismanCollectionCacheMocks.tx,
         });
 
         // Mock an error querying this NFT listing
         const mockedAgora = new MockAgora();
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(
             heismanNftTokenId,
             new Error('some agora error'),
         );
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${heismanNftTokenId}`}
             />,
         );
 
         const { tokenName } = cachedHeismanNftOne.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // On load, we see expected agora query error
         expect(
             await screen.findByText('Error querying NFT offers'),
         ).toBeInTheDocument();
     });
     it('We show an agora oneshot listing for an SLP1 NFT if it is for sale', async () => {
         const heismanNftTokenId = heismanNftOneOffer.token.tokenId;
 
         // Mock the API calls for getting and caching this token's info
         mockedChronik.setMock('token', {
             input: heismanNftTokenId,
             output: heismanNftOneCache.token,
         });
         mockedChronik.setMock('tx', {
             input: heismanNftTokenId,
             output: heismanNftOneCache.tx,
         });
         // Also mock for the collection
         mockedChronik.setMock('token', {
             input: heismanCollectionCacheMocks.tokenId,
             output: heismanCollectionCacheMocks.token,
         });
         mockedChronik.setMock('tx', {
             input: heismanCollectionCacheMocks.tokenId,
             output: heismanCollectionCacheMocks.tx,
         });
 
         // Mock an error querying this NFT listing
         const mockedAgora = new MockAgora();
 
         // then mock for each one agora.activeOffersByTokenId(offeredTokenId)
         mockedAgora.setActiveOffersByTokenId(heismanNftTokenId, [
             heismanNftOneOffer,
         ]);
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${heismanNftTokenId}`}
             />,
         );
 
         const { tokenName, tokenTicker } = cachedHeismanNftOne.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // On load, we can buy the offer
         expect(
             await screen.findByText(`Buy ${tokenName} (${tokenTicker})`),
         ).toBeInTheDocument();
     });
     it('ALP token', async () => {
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // We can click an info icon to learn more about this token type
         await userEvent.click(
             await screen.findByRole('button', {
                 name: 'Click for more info about this token type',
             }),
         );
 
         expect(
             screen.getByText(
                 'ALP v1 fungible token. Token may be of fixed or variable supply. If you have a mint baton, you can mint more of this token at any time. May have up to 9 decimal places. ALP tokens use EMPP technology, which supports more token actions compared to SLP and more complex combinations of token and app actions. ALP token txs may have up to 127 outputs, though current OP_RETURN size de facto limits a single tx to 29 outputs.',
             ),
         ).toBeInTheDocument();
 
         // Close out of the info modal
         await userEvent.click(screen.getByText('OK'));
 
         // The supply is correctly rendered
         expect(screen.getByText('111,367.0000 (var.)')).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // We can list, which is also the default action
         expect(screen.getByTitle('Toggle Sell Token')).toBeEnabled();
         // We can send
         expect(screen.getByTitle('Toggle Send')).toBeInTheDocument();
         // We can burn
         expect(screen.getByTitle('Toggle Burn')).toBeInTheDocument();
         // Because we do not have the mint baton for this token, the Mint action is NOT available
         expect(screen.queryByTitle('Toggle Mint')).not.toBeInTheDocument();
     });
     it('We can send an ALP token', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(alpMocks.tokenId, []);
 
         // ALP send
         const hex =
             '020000000288bb5c0d60e11b4038b00af152f9792fa954571ffdd2413a85f1c26bfd930c25010000006441999a894cafbab21d590da6ce07e572935144c480bce48c4df3efb74e9ee2fd3a4de61a40f93c28775c7b135a6a9ccba7d880bd5776d289b6c8ae5752afee24b34121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf792618030000006441f6e2b2a66d8676854e281f5af375bc56d4f359cb4be1e178d330720384da79a5216bd7a132bfd44654835c95a8d81b099b03e953d4a720187255ef1c9a1b646e4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff0400000000000000003a6a5037534c5032000453454e4449884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c02102700000000301b0f00000022020000000000001976a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac18310f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             '33313eaf3365d9bf440645c5fffa8ed91681d1e1464afe598a564cdc76855c04';
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
 
         // Mock NOT blacklisted
         when(fetch)
             .calledWith(
                 `${tokenConfig.blacklistServerUrl}/blacklist/${alpMocks.tokenId}`,
             )
             .mockResolvedValue({
                 json: () => Promise.resolve({ isBlacklisted: false }),
             });
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Wait for supply and actions to load
         // The supply is correctly rendered
         expect(
             await screen.findByText('111,367.0000 (var.)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // Click Send
         await userEvent.click(screen.getByTitle('Toggle Send'));
 
         // Wait for address input to render
         expect(
             await screen.findByPlaceholderText('Address'),
         ).toBeInTheDocument();
 
         // On load, default action for ALP is to send it
         const sendActionSwitch = screen.getByTitle('Toggle Send');
         await waitFor(() =>
             expect(sendActionSwitch).toHaveProperty('checked', true),
         );
 
         // We see an Address input
         const addrInput = screen.getByPlaceholderText('Address');
         expect(addrInput).toBeInTheDocument();
 
         // Send button is disabled before address and amount entry
         const sendButton = screen.getByRole('button', {
             name: /Send tCRD/,
         });
         expect(sendButton).toBeDisabled();
 
         // We can enter an address
         await userEvent.type(
             addrInput,
             'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035',
         );
         const amountInputEl = screen.getByPlaceholderText('Amount');
         const amountInput = '1';
         await userEvent.type(amountInputEl, amountInput);
 
         // Now the button is enabled
         expect(sendButton).toBeEnabled();
 
         // We can send an ALP token
         await userEvent.click(sendButton);
 
         const sendTokenSuccessNotification = await screen.findByText(
             'eToken sent',
         );
         expect(sendTokenSuccessNotification).toHaveAttribute(
             'href',
             `${explorer.blockExplorerUrl}/tx/${txid}`,
         );
     });
     it('We can burn an ALP token with change', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(alpMocks.tokenId, []);
 
         // ALP burn
         const hex =
             '020000000288bb5c0d60e11b4038b00af152f9792fa954571ffdd2413a85f1c26bfd930c250100000064416f667f359f04e273d524eac5fdaede0bfaf483daaf74f2ab5ba849c3a126b36b059003ef22b647d5265b74938e50c40505c1ad56474d0af2930192994011b9c84121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf792618030000006441ed0c24a83ec9137bc2cc367f674b1932de280f3bc2fbfd9cd70b840e61ccf5fa272e714ba06d3060574df97bc135acae2367d00fdd67ce2bbf347193a871348c4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff030000000000000000656a5030534c503200044255524e49884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c10270000000031534c5032000453454e4449884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c01301b0f00000022020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac28330f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'f71293a94bd444c0b82ce6a6a8a1d2ae182f6a848cd2382bb6ca496955184fdf';
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
 
         // Mock NOT blacklisted
         when(fetch)
             .calledWith(
                 `${tokenConfig.blacklistServerUrl}/blacklist/${alpMocks.tokenId}`,
             )
             .mockResolvedValue({
                 json: () => Promise.resolve({ isBlacklisted: false }),
             });
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Wait for supply and actions to load
         // The supply is correctly rendered
         expect(
             await screen.findByText('111,367.0000 (var.)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, default action for ALP is to list
 
         // Select burn
         await userEvent.click(screen.getByTitle('Toggle Burn'));
 
         await userEvent.type(screen.getByPlaceholderText('Burn Amount'), '1');
 
         // Click the Burn button
         // Note we button title is the token ticker
         await userEvent.click(
             await screen.findByRole('button', { name: /Burn tCRD/ }),
         );
 
         // We see a modal and enter the correct confirmation msg
         await userEvent.type(
             screen.getByPlaceholderText(`Type "burn tCRD" to confirm`),
             'burn tCRD',
         );
 
         // Click the Confirm button
         await userEvent.click(screen.getByRole('button', { name: /OK/ }));
 
         const burnTokenSuccessNotification = await screen.findByText(
             '🔥 Burn successful',
         );
         await waitFor(() =>
             expect(burnTokenSuccessNotification).toHaveAttribute(
                 'href',
                 `${explorer.blockExplorerUrl}/tx/${txid}`,
             ),
         );
     });
     it('We can burn an ALP token without change', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(alpMocks.tokenId, []);
 
         // ALP burn all
         const hex =
             '020000000288bb5c0d60e11b4038b00af152f9792fa954571ffdd2413a85f1c26bfd930c250100000064413919d2894e681586f285af178ef2c8d86b2f008e31519b1592c76cae7bee17eb4bb1558db35b225a15a2ba1c1f3d86564e12adfa0d5c012427f096398cdff20e4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf79261803000000644126a0f23966db5ba3212e4d5c545a186d407af4d110335e521c867e63549ade8d25da8a911343d9bf9275bbb58255cd445a1b3fc14ae35a89b8964cfbe47299aa4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff030000000000000000336a5030534c503200044255524e49884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c40420f00000022020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac8c330f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             'f413a14acc391c2541f0dea477cf7ee07cf6256bc3b201d6b276272f2fdda407';
         mockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
 
         // Mock NOT blacklisted
         when(fetch)
             .calledWith(
                 `${tokenConfig.blacklistServerUrl}/blacklist/${alpMocks.tokenId}`,
             )
             .mockResolvedValue({
                 json: () => Promise.resolve({ isBlacklisted: false }),
             });
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Wait for supply and actions to load
         // The supply is correctly rendered
         expect(
             await screen.findByText('111,367.0000 (var.)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, default action for ALP is to list
 
         // Select burn
         await userEvent.click(screen.getByTitle('Toggle Burn'));
 
         // Hit max for max burn
         await userEvent.click(screen.getByRole('button', { name: /max/ }));
 
         // Max is input
         const thisWalletAlpBalance = 100;
         expect(screen.getByPlaceholderText('Burn Amount')).toHaveValue(
             thisWalletAlpBalance,
         );
 
         // Click the Burn button
         // Note we button title is the token ticker
         await userEvent.click(
             await screen.findByRole('button', { name: /Burn tCRD/ }),
         );
 
         // We see a modal and enter the correct confirmation msg
         await userEvent.type(
             screen.getByPlaceholderText(`Type "burn tCRD" to confirm`),
             'burn tCRD',
         );
 
         // Click the Confirm button
         await userEvent.click(screen.getByRole('button', { name: /OK/ }));
 
         const burnTokenSuccessNotification = await screen.findByText(
             '🔥 Burn successful',
         );
         await waitFor(() =>
             expect(burnTokenSuccessNotification).toHaveAttribute(
                 'href',
                 `${explorer.blockExplorerUrl}/tx/${txid}`,
             ),
         );
     });
     it('We can mint max one-output ALP token qty', async () => {
         const mockedAgora = new MockAgora();
 
         mockedAgora.setOfferedGroupTokenIds([]);
 
         // It's not listed yet
         mockedAgora.setActiveOffersByTokenId(alpMocks.tokenId, []);
 
         // New mocked chronik since we change the wallet to include a mint baton for this token
         const walletWithAlpMintBaton = {
             ...tokenTestWallet,
             state: {
                 ...tokenTestWallet.state,
                 slpUtxos: [
                     ...tokenTestWallet.state.slpUtxos,
                     {
                         outpoint: {
                             txid: '250c93fd6bc2f1853a41d2fd1f5754a92f79f952f10ab038401be1600d5cbb88',
                             outIdx: 2,
                         },
                         blockHeight: 836452,
                         isCoinbase: false,
                         value: 546,
                         isFinal: true,
                         token: {
                             tokenId:
                                 '7cd7cd7c54167d306e770f972b564584c44cb412ee45839b4b97bb6e724c8849',
                             tokenType: {
                                 protocol: 'ALP',
                                 type: 'ALP_TOKEN_TYPE_STANDARD',
                                 number: 0,
                             },
                             amount: '0',
                             isMintBaton: true,
                         },
                         path: 1899,
                     },
                 ],
             },
         };
         const mintAlpMockedChronik = await initializeCashtabStateForTests(
             walletWithAlpMintBaton,
             localforage,
         );
 
         // Mock cache info
         mintAlpMockedChronik.setMock('token', {
             input: alpMocks.tokenId,
             output: alpMocks.token,
         });
         mintAlpMockedChronik.setMock('tx', {
             input: alpMocks.tokenId,
             output: alpMocks.tx,
         });
         mintAlpMockedChronik.setTokenId(alpMocks.tokenId);
         mintAlpMockedChronik.setUtxosByTokenId(alpMocks.tokenId, {
             tokenId: alpMocks.tokenId,
             utxos: alpMocks.utxos,
         });
         // Set empty tx history
         mintAlpMockedChronik.setTxHistoryByTokenId(alpMocks.tokenId, []);
 
         // ALP mint
         const hex =
             '020000000288bb5c0d60e11b4038b00af152f9792fa954571ffdd2413a85f1c26bfd930c25020000006441acdadb019c561b7bfa761695503eb1250d3ae1f34e66eeb3c4c8fb561b4ec95291bde678871451316a8f0472922d25936dd341eb90eb6bb3ccde98b00a2138da4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf792618030000006441fc7a554a708c3e6a2fc72e7c96871521678d0a36e336a599b39eac6a36f4ecedcfd2a728c8e639b5946fde677f1afa9e31468531476dd66fce1adfc760e7e2ff4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff040000000000000000356a5032534c503200044d494e5449884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c01ffffffffffff0122020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac22310f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const txid =
             '28c733455a50be334948600bcdf0817610b0321ceba3da52c7c7ffec995320f0';
         mintAlpMockedChronik.setMock('broadcastTx', {
             input: hex,
             output: { txid },
         });
 
         // Mock NOT blacklisted
         when(fetch)
             .calledWith(
                 `${tokenConfig.blacklistServerUrl}/blacklist/${alpMocks.tokenId}`,
             )
             .mockResolvedValue({
                 json: () => Promise.resolve({ isBlacklisted: false }),
             });
 
         render(
             <CashtabTestWrapper
                 chronik={mintAlpMockedChronik}
                 agora={mockedAgora}
                 ecc={ecc}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Wait for supply and actions to load
         // The supply is correctly rendered
         expect(
             await screen.findByText('111,367.0000 (var.)'),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // Select mint
         await userEvent.click(screen.getByTitle('Toggle Mint'));
 
         // Max qty
         await userEvent.click(screen.getByRole('button', { name: /max/ }));
 
         // Max is input
         // eslint-disable-next-line @typescript-eslint/no-loss-of-precision
         const maxMintQty = 28147497671.0655;
 
         expect(screen.getByPlaceholderText('Mint Amount')).toHaveValue(
             maxMintQty,
         );
 
         // Click the Mint button
         // Note we button title is the token ticker
         await userEvent.click(
             await screen.findByRole('button', { name: /Mint tCRD/ }),
         );
 
         const successNotification = await screen.findByText(
             '⚗️ Minted 28147497671.0655 tCRD',
         );
         await waitFor(() =>
             expect(successNotification).toHaveAttribute(
                 'href',
                 `${explorer.blockExplorerUrl}/tx/${txid}`,
             ),
         );
     });
     it('We can list an ALP fungible token', async () => {
         // Mock Math.random()
         jest.spyOn(global.Math, 'random').mockReturnValue(0.5); // set a fixed value
 
         // ALP offer tx
         const offerHex =
             '020000000288bb5c0d60e11b4038b00af152f9792fa954571ffdd2413a85f1c26bfd930c25010000006441d32ae72fa880a40975a475147443a3a7fe10308178ad38d80e6a2428921732b0699849443d8e24124a8ee5b75f1e9f74628fdb8cd0c9704d8cd0c70df65828e94121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffffef76d01776229a95c45696cf68f2f98c8332d0c53e3f24e73fd9c6deaf7926180300000064415fc18bb026bc3122776e708b8cdba9225494c704c1feca7aefb36b592abed96568cd57cb3504769bc4019ec0f36990c28c57012cefe805e4d3b046cc308bc86b4121031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02dffffffff040000000000000000866a504b41475230075041525449414c01009b630800000000005532000000000000d6b24701000000002099c53f031d4603bdc23aca9432f903e3cf5975a3f655cc3fa5057c61d00dfc1ca5dfd02d37534c5032000453454e4449884c726ebb974b9b8345ee12b44cc48445562b970f776e307d16547ccdd77c0200420f000000400000000000220200000000000017a91450eb4978c85ec89b63e37e6b87409c9f5815c7058722020000000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac83300f00000000001976a91400549451e5c22b18686cacdf34dce649e5ec3be288ac00000000';
         const offerTxid =
             'e00be7011ee5d585cbd54049570ea0754ab0d5c05acf6cb01c25afa3aa61663d';
 
         mockedChronik.setMock('broadcastTx', {
             input: offerHex,
             output: { txid: offerTxid },
         });
 
-        // We need to give mockedChronik a plugin function
-        // This is required for creating a new Agora(mockedChronik)
-        mockedChronik.plugin = () => 'dummy plugin';
-
         // Mock response for agora select params check
         // Note
         // We obtain EXPECTED_OFFER_P2SH by adding
         // console.log(toHex(shaRmd160(agoraScript.bytecode)));
         // to ecash-agora lib and running this test
         // Note that Date() and Math.random() must be mocked to keep this deterministic
         const EXPECTED_OFFER_P2SH = '50eb4978c85ec89b63e37e6b87409c9f5815c705';
 
         mockedChronik.setScript('p2sh', EXPECTED_OFFER_P2SH);
         // We mock no existing utxos
         mockedChronik.setUtxos('p2sh', EXPECTED_OFFER_P2SH, { utxos: [] });
 
         // Note that we cannot use mockedAgora to avoid agoraQueryErrors, as we need a proper
         // agora object to build the partial
         const agora = new Agora(mockedChronik);
 
         render(
             <CashtabTestWrapper
                 chronik={mockedChronik}
                 ecc={ecc}
                 agora={agora}
                 route={`/send-token/${alpMocks.tokenId}`}
             />,
         );
 
         const { tokenName } = alpMocks.token.genesisInfo;
 
         // Wait for element to get token info and load
         expect(
             (await screen.findAllByText(new RegExp(tokenName)))[0],
         ).toBeInTheDocument();
 
         // Token image is rendered
         expect(
             screen.getByAltText(`icon for ${alpMocks.tokenId}`),
         ).toBeInTheDocument();
 
         // Token actions are available
         expect(screen.getByTitle('Token Actions')).toBeInTheDocument();
 
         // On load, default action for ALP is to list it
         expect(screen.getByTitle('Toggle Sell Token')).toBeEnabled();
 
         // The list button is disabled on load
         const listButton = screen.getByRole('button', {
             name: /List Test CRD/,
         });
         expect(listButton).toBeDisabled();
 
         // The price input is disabled until qty values are entered
         const priceInput = screen.getByPlaceholderText(
             'Enter list price (per token)',
         );
         expect(priceInput).toHaveProperty('disabled', true);
 
         // Enter token balance as offered qty
         await userEvent.type(screen.getByPlaceholderText('Offered qty'), '100');
 
         // Enter a min qty
         await userEvent.type(screen.getByPlaceholderText('Min buy'), '1');
 
         // The price input is no longer disabled
         expect(priceInput).toBeEnabled();
 
         // We see expected error msg if we try to list the token at a price where the min buy would cost less than dust
         await userEvent.type(priceInput, '0.001');
 
         expect(
             screen.getByText(
                 'Minimum buy costs 0.001 XEC, must be at least 5.46 XEC',
             ),
         ).toBeInTheDocument();
 
         // The buy button is disabled with invalid price
         expect(listButton).toBeDisabled();
 
         // Increase the price to a valid one
         await userEvent.clear(priceInput);
         await userEvent.type(priceInput, '33');
 
         // The list button is no longer disabled
         expect(listButton).toBeEnabled();
 
         // The fiat price is previewed correctly
         expect(
             screen.getByText('33.00 XEC ($0.00099 USD) per token'),
         ).toBeInTheDocument();
 
         // We can also set the price in fiat currency
         await userEvent.selectOptions(
             screen.getByTestId('currency-select-dropdown'),
             screen.getByTestId('fiat-option'),
         );
 
         // The price input is cleared when the user changes from XEC price to fiat price
         expect(priceInput).toHaveValue(null);
 
         // We list for $5 per token
         await userEvent.type(priceInput, '5');
 
         // The fiat price is previewed correctly
         expect(
             screen.getByText('$5 USD (166,666.67 XEC) per token'),
         ).toBeInTheDocument();
 
         // We enter a low price in fiat
         await userEvent.clear(priceInput);
         await userEvent.type(priceInput, '0.0005');
 
         // The fiat price is previewed correctly
         expect(
             await screen.findByText('$0.0005 USD (16.67 XEC) per token'),
         ).toBeInTheDocument();
 
         // Click the now-enabled list button
         expect(listButton).toBeEnabled();
         await userEvent.click(listButton);
 
         // We see expected confirmation modal to list the Token
         expect(screen.getByText('List tCRD?')).toBeInTheDocument();
         expect(
             screen.getByText('Create the following sell offer?'),
         ).toBeInTheDocument();
         // Offered qty (actual, calculated from AgoraOffer)
         const actualOfferedQty = '99.9936';
         expect(screen.getByText(actualOfferedQty)).toBeInTheDocument();
         // Min by (actual, calculated from AgoraOffer)
         expect(screen.getByText('1.0240')).toBeInTheDocument();
         // Actual price calculated from AgoraOffer
         const actualPricePerTokenForMinBuy = '16.67 XEC';
         expect(
             screen.getAllByText(actualPricePerTokenForMinBuy)[0],
         ).toBeInTheDocument();
         // User input price
         expect(screen.getAllByText('16.67 XEC')[1]).toBeInTheDocument();
 
         // We can cancel and not create this listing
         await userEvent.click(screen.getByText('Cancel'));
 
         // The confirmation modal is gone
         expect(screen.queryByText('List tCRD?')).not.toBeInTheDocument();
 
         // We change our mind and list it
         await userEvent.click(listButton);
         // We wait for the preview to be calculated again
 
         expect(await screen.findByText('List tCRD?')).toBeInTheDocument();
         await userEvent.click(screen.getByText('OK'));
 
         // We see the expected toast notification for the successful listing tx
         expect(
             await screen.findByText(
                 `${actualOfferedQty} Test CRD listed for ${actualPricePerTokenForMinBuy} per token`,
             ),
         ).toBeInTheDocument();
     });
 });
diff --git a/modules/mock-chronik-client/README.md b/modules/mock-chronik-client/README.md
index 6e0b4d2ff..4260cc841 100644
--- a/modules/mock-chronik-client/README.md
+++ b/modules/mock-chronik-client/README.md
@@ -1,166 +1,170 @@
 # mock-chronik-client
 
 Testing utility to mock the Chronik indexer client and support unit tests that need to mock chronik related API calls.
 
 ## Usage
 
 Import the MockChronikClient module via relative path along with any desired mock objects from `/mocks/mockChronikResponses`.
 
 ```
 const { MockChronikClient } = require('/index');
 // Import any mock responses from '/mocks/mockChronikResponses'
 const ecashaddr = require('ecashaddrjs');
 const mockedChronik = new MockChronikClient();
 ```
 
 **_Mocking API Responses_**
 
 Chronik-client APIs which **don't** rely on a preceding `.script()` call can use the `.setMock()` function to inject the mock API response.
 
 This includes:
 
 -   `.block()`
 -   `.tx()`
 -   `.token()`
 -   `.blockchainInfo()`
 -   `.broadcastTx()`
 -   `.ws()`
 
 Example: mocking the chronik.token() call
 
 ```
 const { mockTokenInfo } = require('/mocks/mockChronikResponses');
 // Initialize chronik mock with token info
 mockedChronik.setMock('token', {
 	input: 'some token ID',
 	output: mockTokenInfo,
 });
 
 // Execute the API call
 const result = await mockedChronik.token('some token ID');
 assert.deepEqual(result, mockTokenInfo);
 ```
 
 Chronik-client APIs which **do** rely on a preceding `.script()` call will need to firstly set the intended script (address type and hash) before setting the specific mock function.
 
 This includes:
 
 -   `.script().utxos()`
 -   `.script().history()`
 
 Example: mocking the chronik.script(type, hash).utxos() call
 
 ```
 const { mockP2pkhUtxos } = require('/mocks/mockChronikResponses');
 // Initialize chronik mock with script and utxo info
 const P2PKH_ADDRESS = 'ecash:qzth8qvakhr6y8zcefdrvx30zrdmt2z2gvp7zc5vj8';
 const { type, hash } = ecashaddr.decode(P2PKH_ADDRESS, true);
 mockedChronik.setScript(type, hash);
 mockedChronik.setUtxos(type, hash, mockP2pkhUtxos);
 
 // Execute the API call
 const result = await mockedChronik.script(type, hash).utxos();
 assert.deepEqual(result, mockP2pkhUtxos);
 ```
 
 **_Mocking API Errors_**
 
 To test your app's behavior in handling an API error from Chronik, simply set an Error object as the mock output.
 
 Example: mocking an error from the chronik.broadcastTx() call
 
 ```
 const mockInvalidRawTxHex = 'not a valid raw tx hex';
 const expectedError = new Error('Bad response from Chronik');
 mockedChronik.setMock('broadcastTx', {
 	input: mockInvalidRawTxHex,
 	output: expectedError,
 });
 
 // Execute the API call
 await assert.rejects(
 	async () => {
 		await mockedChronik.broadcastTx(mockInvalidRawTxHex);
 	},
 	expectedError,
 );
 ```
 
 ## Questions?
 
 If you have any implementation questions regarding this mock tool please check the test suite in `/test/index.test.js` or feel free to reach out to the development team via the [eCash Development Telegram](https://t.me/eCashDevelopment).
 
 ### Change Log
 
 1.1.0
 
 -   Add support to in-node subscribeToBlocks method and check flag, isSubscribedBlocks
 
 1.1.1
 
 -   Patch error tests
 
 1.2.0
 
 -   Add support to calls by `address(address)` returning same as `script(type, hash)`
 
 1.3.0
 
 -   Add support for `subscribeToAddress` and `unsubscribeFromAddress` websocket methods
 
 1.4.0
 
 -   Add support for `ws.unsubscribe` method and fix errors in `ws` tests
 
 1.4.1
 
 -   Patch repo path in package.json
 
 1.5.0
 
 -   Add support for ws subscribe methods and shape found in in-node chronik-client
 
 1.6.0
 
 -   Match shape of `subs` object in `ChronikClientNode` for `ChronikClientNode` ws methods and support unsubscribe from blocks
 
 1.7.0
 
 -   Allow getting and setting utxos() and history() by tokenId
 
 1.8.0
 
 -   Allow getting history without specifying pageNumber or pageSize
 
 1.9.0
 
 -   Support `blockTxs` endpoint
 -   Update websocket subs shape to match ChronikClientNode
 
 1.9.1
 
 -   Upgrading npm dependencies [D16380](https://reviews.bitcoinabc.org/D16380)
 
 1.10.0
 
 -   Allow getting and setting `history()` by `lokadId` [D16382](https://reviews.bitcoinabc.org/D16382)
 
 1.10.1
 
 -   Return missing `numTxs` key from `history()` calls [D16617](https://reviews.bitcoinabc.org/D16617)
 
 1.11.0
 
 -   Add support for `MockAgora`, a simple set-and-return mock for some `ecash-agora` class methods [D16737](https://reviews.bitcoinabc.org/D16737)
 
 1.12.0
 
 -   Extend `MockAgora` support to cover `offeredFungibleTokenIds()` and `activeOffersByTokenId()` methods [D16929](https://reviews.bitcoinabc.org/D16929)
 
 1.12.1
 
 -   Build published version with dependencies from `npm` [D17227](https://reviews.bitcoinabc.org/D17227)
 
 1.12.2
 
 -   Add `MockAgora` to stub ts declarations [D17274](https://reviews.bitcoinabc.org/D17274)
+
+1.12.3
+
+-   Add dummy `plugin` method to allow construction of `new Agora()` from `ecash-agora` with a `MockChronikClient` [D17279](https://reviews.bitcoinabc.org/D17279)
diff --git a/modules/mock-chronik-client/index.js b/modules/mock-chronik-client/index.js
index 1701340ab..abcc09306 100644
--- a/modules/mock-chronik-client/index.js
+++ b/modules/mock-chronik-client/index.js
@@ -1,492 +1,496 @@
 // Copyright (c) 2023 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 'use strict';
 const cashaddr = require('ecashaddrjs');
 
 const CHRONIK_DEFAULT_PAGESIZE = 25;
 
 module.exports = {
     MockAgora: class {
         // Agora can make specialized chronik-client calls to a chronik-client instance
         // running the agora plugin
         // For the purposes of unit testing, we only need to re-create how this object
         // is initialized and support getting and setting of expected responses
         constructor() {
             // Use self since it is not a reserved term in js
             // Can access self from inside a method and still get the class
             const self = this;
             // API call mock return objects
             // Can be set with self.setMock
             self.mockedResponses = {
                 offeredGroupTokenIds: {},
                 offeredFungibleTokenIds: {},
                 activeOffersByPubKey: {},
                 activeOffersByGroupTokenId: {},
                 activeOffersByTokenId: {},
             };
 
             // Allow user to set supported agora query responses
             self.setOfferedGroupTokenIds = function (response) {
                 self.mockedResponses.offeredGroupTokenIds = response;
             };
             self.setOfferedFungibleTokenIds = function (response) {
                 self.mockedResponses.offeredFungibleTokenIds = response;
             };
             self.setActiveOffersByPubKey = function (pubKey, response) {
                 self.mockedResponses.activeOffersByPubKey[pubKey] = response;
             };
             self.setActiveOffersByGroupTokenId = function (
                 groupTokenId,
                 response,
             ) {
                 self.mockedResponses.activeOffersByGroupTokenId[groupTokenId] =
                     response;
             };
             self.setActiveOffersByTokenId = function (tokenId, response) {
                 self.mockedResponses.activeOffersByTokenId[tokenId] = response;
             };
 
             // Checks whether the user set this mock response to be an error.
             // If so, throw it to simulate an API error response.
             function throwOrReturnValue(mockResponse) {
                 if (mockResponse instanceof Error) {
                     throw mockResponse;
                 }
                 return mockResponse;
             }
 
             self.offeredGroupTokenIds = async function () {
                 return throwOrReturnValue(
                     self.mockedResponses.offeredGroupTokenIds,
                 );
             };
             self.offeredFungibleTokenIds = async function () {
                 return throwOrReturnValue(
                     self.mockedResponses.offeredFungibleTokenIds,
                 );
             };
             self.activeOffersByPubKey = async function (pubKey) {
                 return throwOrReturnValue(
                     self.mockedResponses.activeOffersByPubKey[pubKey],
                 );
             };
             self.activeOffersByGroupTokenId = async function (groupTokenId) {
                 return throwOrReturnValue(
                     self.mockedResponses.activeOffersByGroupTokenId[
                         groupTokenId
                     ],
                 );
             };
             self.activeOffersByTokenId = async function (tokenId) {
                 return throwOrReturnValue(
                     self.mockedResponses.activeOffersByTokenId[tokenId],
                 );
             };
         }
     },
     MockChronikClient: class {
         constructor() {
             // Use self since it is not a reserved term in js
             // Can access self from inside a method and still get the class
             const self = this;
 
+            // We need to give mockedChronik a plugin function
+            // This is required for creating a new Agora(mockedChronik)
+            self.plugin = () => 'dummy plugin';
+
             // API call mock return objects
             // Can be set with self.setMock
             self.mockedResponses = {
                 block: {},
                 blockTxs: {},
                 blockchainInfo: {},
                 txHistory: [],
                 tx: {},
                 token: {},
                 p2sh: {},
                 p2pkh: {},
                 broadcastTx: {},
             };
             self.mockedMethods = { p2pkh: {}, p2sh: {} };
             self.manuallyClosed = false;
 
             // API call mock functions
             self.block = async function (blockHashOrHeight) {
                 return throwOrReturnValue(
                     self.mockedResponses.block[blockHashOrHeight],
                 );
             };
             self.blockTxs = async function (
                 hashOrHeight,
                 pageNumber = 0,
                 pageSize = CHRONIK_DEFAULT_PAGESIZE,
             ) {
                 if (
                     self.mockedResponses[hashOrHeight].txHistory instanceof
                     Error
                 ) {
                     throw self.mockedResponses[hashOrHeight].txHistory;
                 }
                 return self.getTxHistory(
                     pageNumber,
                     pageSize,
                     self.mockedResponses[hashOrHeight].txHistory,
                 );
             };
             self.tx = async function (txid) {
                 return throwOrReturnValue(self.mockedResponses.tx[txid]);
             };
             self.token = async function (tokenId) {
                 return throwOrReturnValue(self.mockedResponses.token[tokenId]);
             };
             self.broadcastTx = async function (txHex) {
                 return throwOrReturnValue(
                     self.mockedResponses.broadcastTx[txHex],
                 );
             };
             self.blockchainInfo = async function () {
                 return throwOrReturnValue(self.mockedResponses.blockchainInfo);
             };
 
             // Return assigned script mocks
             self.script = function (type, hash) {
                 return self.mockedMethods[type][hash];
             };
 
             // Return assigned address mocks
             self.address = function (address) {
                 return self.mockedMethods[address];
             };
 
             // Return assigned tokenId mocks
             self.tokenId = function (tokenId) {
                 return self.mockedMethods[tokenId];
             };
 
             // Return assigned lokadId mocks
             self.lokadId = function (lokadId) {
                 return self.mockedMethods[lokadId];
             };
 
             // Checks whether the user set this mock response to be an error.
             // If so, throw it to simulate an API error response.
             function throwOrReturnValue(mockResponse) {
                 if (mockResponse instanceof Error) {
                     throw mockResponse;
                 }
                 return mockResponse;
             }
 
             // Flags to check if ws methods have been called
             self.wsSubscribeCalled = false;
             self.wsWaitForOpenCalled = false;
 
             // Websocket mocks
             self.ws = function (wsObj) {
                 if (wsObj !== null) {
                     const returnedWs = {
                         onMessage: wsObj.onMessage, // may be undefined
                         onConnect: wsObj.onConnect, // may be undefined
                         onReconnect: wsObj.onReconnect, // may be undefined
                         onEnd: wsObj.onEnd, // may be undefined
                         autoReconnect: wsObj.autoReconnect || true, // default to true if unset
                         manuallyClosed: false,
                         subs: {
                             blocks: false,
                             tokens: [],
                             lokadIds: [],
                             scripts: [],
                         },
                         isSubscribedBlocks: false,
                         waitForOpen: async function () {
                             self.wsWaitForOpenCalled = true;
                         },
                         // Note: subscribe is a legacy NNG method
                         subscribe: function (type, hash) {
                             this.subs.scripts.push({
                                 scriptType: type,
                                 scriptPayload: hash,
                             });
                             self.wsSubscribeCalled = true;
                         },
                         // Note: unsubscribe is a legacy NNG method
                         unsubscribe: function (type, hash) {
                             const thisSubInSubsIndex =
                                 this.subs.scripts.findIndex(
                                     sub =>
                                         sub.scriptType === type &&
                                         sub.scriptPayload === hash,
                                 );
 
                             if (typeof thisSubInSubsIndex !== 'undefined') {
                                 // Remove from subs
                                 this.subs.scripts.splice(thisSubInSubsIndex, 1);
                             }
                             // Otherwise do nothing
                         },
                         subscribeToScript: function (type, hash) {
                             // in-node only
                             if (Array.isArray(this.subs)) {
                                 this.subs = { scripts: [] };
                             }
                             this.subs.scripts.push({
                                 scriptType: type,
                                 payload: hash,
                             });
                             self.wsSubscribeCalled = true;
                         },
                         unsubscribeFromScript: function (type, hash) {
                             const thisSubInSubsIndex =
                                 this.subs.scripts.findIndex(
                                     sub =>
                                         sub.scriptType === type &&
                                         sub.payload === hash,
                                 );
 
                             if (typeof thisSubInSubsIndex !== 'undefined') {
                                 // Remove from subs
                                 this.subs.scripts.splice(thisSubInSubsIndex, 1);
                             }
                             // Otherwise do nothing
                         },
                         subscribeToAddress: function (address) {
                             // in-node only
                             if (Array.isArray(this.subs)) {
                                 this.subs = { scripts: [] };
                             }
                             const { type, hash } = cashaddr.decode(
                                 address,
                                 true,
                             );
                             this.subs.scripts.push({
                                 scriptType: type,
                                 payload: hash,
                             });
                         },
                         unsubscribeFromAddress: function (address) {
                             const { type, hash } = cashaddr.decode(
                                 address,
                                 true,
                             );
                             // Find the requested unsub script and remove it
                             const unsubIndex = this.subs.scripts.findIndex(
                                 sub =>
                                     sub.scriptType === type &&
                                     sub.payload === hash,
                             );
                             if (unsubIndex === -1) {
                                 // If we cannot find this subscription in this.subs, throw an error
                                 // We do not want an app developer thinking they have unsubscribed from something
                                 throw new Error(
                                     `No existing sub at ${type}, ${hash}`,
                                 );
                             }
 
                             // Remove the requested subscription from this.subs
                             this.subs.scripts.splice(unsubIndex, 1);
                         },
                         subscribeToBlocks: function () {
                             this.subs.blocks = true;
                         },
                         unsubscribeFromBlocks: function () {
                             this.subs.blocks = false;
                         },
                     };
                     return returnedWs;
                 }
             };
             self.wsClose = function () {
                 self.manuallyClosed = true;
             };
 
             // Allow user to set expected chronik call response
             self.setMock = function (call, options) {
                 // e.g. ('block', {input: '', output: ''})
                 const { input, output } = options;
                 if (input) {
                     self.mockedResponses[call][input] = output;
                 } else {
                     self.mockedResponses[call] = output;
                 }
             };
 
             // script calls need to be set differently
             self.setTxHistory = function (type, hash, txHistory) {
                 self.mockedResponses[type][hash].txHistory = txHistory;
             };
 
             self.setTxHistoryByAddress = function (address, txHistory) {
                 self.mockedResponses[address].txHistory = txHistory;
             };
 
             self.setTxHistoryByTokenId = function (tokenId, txHistory) {
                 self.mockedResponses[tokenId].txHistory = txHistory;
             };
 
             self.setTxHistoryByLokadId = function (lokadId, txHistory) {
                 self.mockedResponses[lokadId].txHistory = txHistory;
             };
 
             self.setTxHistoryByBlock = function (hashOrHeight, txHistory) {
                 // Set all expected tx history as array where it can be accessed by mock method
                 self.mockedResponses[hashOrHeight] = { txHistory };
             };
 
             /**
              * Set utxos to custom response; must be called after setScript
              * @param {string} type 'p2sh' or 'p2pkh'
              * @param {string} hash hash of an eCash address
              * @param {array} utxos mocked response of chronik.script(type,hash).utxos()
              */
             self.setUtxos = function (type, hash, utxos) {
                 self.mockedResponses[type][hash].utxos = utxos;
             };
 
             /**
              * Set utxos to custom response; must be called after setAddress
              * @param {string} address 'p2sh' or 'p2pkh' address
              * @param {array} utxos mocked response of chronik.address(address).utxos()
              */
             self.setUtxosByAddress = function (address, utxos) {
                 self.mockedResponses[address].utxos = utxos;
             };
 
             /**
              * Set utxos to custom response; must be called after setTokenId
              * @param {string} tokenId a tokenId
              * @param {array} utxos mocked response of chronik.tokenId(tokenId).utxos()
              */
             self.setUtxosByTokenId = function (tokenId, utxos) {
                 self.mockedResponses[tokenId].utxos = utxos;
             };
 
             // Allow users to set expected chronik script call responses
             self.setScript = function (type, hash) {
                 // Initialize object that will hold utxos if set
                 self.mockedResponses[type][hash] = {};
 
                 self.mockedMethods[type][hash] = {
                     history: async function (
                         pageNumber = 0,
                         pageSize = CHRONIK_DEFAULT_PAGESIZE,
                     ) {
                         if (
                             self.mockedResponses[type][hash]
                                 .txHistory instanceof Error
                         ) {
                             throw self.mockedResponses[type][hash].txHistory;
                         }
                         return self.getTxHistory(
                             pageNumber,
                             pageSize,
                             self.mockedResponses[type][hash].txHistory,
                         );
                     },
                     utxos: async function () {
                         return throwOrReturnValue(
                             self.mockedResponses[type][hash].utxos,
                         );
                     },
                 };
             };
 
             // Allow users to set expected chronik address call responses
             self.setAddress = function (address) {
                 // Initialize object that will hold utxos if set
                 self.mockedResponses[address] = {};
 
                 self.mockedMethods[address] = {
                     history: async function (
                         pageNumber = 0,
                         pageSize = CHRONIK_DEFAULT_PAGESIZE,
                     ) {
                         if (
                             self.mockedResponses[address].txHistory instanceof
                             Error
                         ) {
                             throw self.mockedResponses[address].txHistory;
                         }
                         return self.getTxHistory(
                             pageNumber,
                             pageSize,
                             self.mockedResponses[address].txHistory,
                         );
                     },
                     utxos: async function () {
                         return throwOrReturnValue(
                             self.mockedResponses[address].utxos,
                         );
                     },
                 };
             };
 
             // Allow users to set expected chronik tokenId call responses
             self.setTokenId = function (tokenId) {
                 // Initialize object that will hold utxos if set
                 self.mockedResponses[tokenId] = {};
 
                 self.mockedMethods[tokenId] = {
                     history: async function (
                         pageNumber = 0,
                         pageSize = CHRONIK_DEFAULT_PAGESIZE,
                     ) {
                         if (
                             self.mockedResponses[tokenId].txHistory instanceof
                             Error
                         ) {
                             throw self.mockedResponses[tokenId].txHistory;
                         }
                         return self.getTxHistory(
                             pageNumber,
                             pageSize,
                             self.mockedResponses[tokenId].txHistory,
                         );
                     },
                     utxos: async function () {
                         return throwOrReturnValue(
                             self.mockedResponses[tokenId].utxos,
                         );
                     },
                 };
             };
 
             // Allow users to set expected chronik lokadId call responses
             self.setLokadId = function (lokadId) {
                 // Initialize object that will hold utxos if set
                 self.mockedResponses[lokadId] = {};
 
                 self.mockedMethods[lokadId] = {
                     history: async function (
                         pageNumber = 0,
                         pageSize = CHRONIK_DEFAULT_PAGESIZE,
                     ) {
                         if (
                             self.mockedResponses[lokadId].txHistory instanceof
                             Error
                         ) {
                             throw self.mockedResponses[lokadId].txHistory;
                         }
                         return self.getTxHistory(
                             pageNumber,
                             pageSize,
                             self.mockedResponses[lokadId].txHistory,
                         );
                     },
                 };
             };
         }
         // Method to get paginated tx history with same variables as chronik
         getTxHistory(pageNumber = 0, pageSize, txHistory) {
             // Return chronik shaped responses
             const startSliceOnePage = pageNumber * pageSize;
             const endSliceOnePage = startSliceOnePage + pageSize;
             const thisPage = txHistory.slice(
                 startSliceOnePage,
                 endSliceOnePage,
             );
             const response = {};
 
             response.txs = thisPage;
             response.numPages = Math.ceil(txHistory.length / pageSize);
             response.numTxs = txHistory.length;
             return response;
         }
     },
 };
diff --git a/modules/mock-chronik-client/package-lock.json b/modules/mock-chronik-client/package-lock.json
index 6613656ba..923a300a5 100644
--- a/modules/mock-chronik-client/package-lock.json
+++ b/modules/mock-chronik-client/package-lock.json
@@ -1,4749 +1,4749 @@
 {
     "name": "mock-chronik-client",
-    "version": "1.12.2",
+    "version": "1.12.3",
     "lockfileVersion": 2,
     "requires": true,
     "packages": {
         "": {
             "name": "mock-chronik-client",
-            "version": "1.12.2",
+            "version": "1.12.3",
             "license": "MIT",
             "dependencies": {
                 "ecashaddrjs": "file:../ecashaddrjs"
             },
             "devDependencies": {
                 "mocha": "^10.2.0",
                 "mocha-junit-reporter": "^2.2.1",
                 "nyc": "^15.1.0"
             }
         },
         "../ecashaddrjs": {
             "version": "1.5.8",
             "license": "MIT",
             "dependencies": {
                 "big-integer": "1.6.36",
                 "bs58check": "^3.0.1"
             },
             "devDependencies": {
                 "@babel/cli": "^7.21.0",
                 "@babel/core": "^7.21.3",
                 "@babel/preset-env": "^7.20.2",
                 "babel-loader": "^9.1.2",
                 "buffer": "^6.0.3",
                 "chai": "^4.3.7",
                 "debug": "^4.3.4",
                 "eslint": "^8.37.0",
                 "jsdoc": "^4.0.2",
                 "mocha": "^10.2.0",
                 "mocha-junit-reporter": "^2.2.0",
                 "mocha-suppress-logs": "^0.3.1",
                 "nyc": "^15.1.0",
                 "random-js": "^2.1.0",
                 "webpack": "^5.76.2",
                 "webpack-cli": "^5.0.1"
             }
         },
         "node_modules/@ampproject/remapping": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
             "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
             "dev": true,
             "dependencies": {
                 "@jridgewell/gen-mapping": "^0.3.0",
                 "@jridgewell/trace-mapping": "^0.3.9"
             },
             "engines": {
                 "node": ">=6.0.0"
             }
         },
         "node_modules/@babel/code-frame": {
             "version": "7.22.13",
             "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
             "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
             "dev": true,
             "dependencies": {
                 "@babel/highlight": "^7.22.13",
                 "chalk": "^2.4.2"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/code-frame/node_modules/ansi-styles": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
             "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
             "dev": true,
             "dependencies": {
                 "color-convert": "^1.9.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/code-frame/node_modules/chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
             "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
             "dev": true,
             "dependencies": {
                 "ansi-styles": "^3.2.1",
                 "escape-string-regexp": "^1.0.5",
                 "supports-color": "^5.3.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/code-frame/node_modules/color-convert": {
             "version": "1.9.3",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
             "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
             "dev": true,
             "dependencies": {
                 "color-name": "1.1.3"
             }
         },
         "node_modules/@babel/code-frame/node_modules/color-name": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
             "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
             "dev": true
         },
         "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
             "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
             "dev": true,
             "engines": {
                 "node": ">=0.8.0"
             }
         },
         "node_modules/@babel/code-frame/node_modules/has-flag": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
             "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
             "dev": true,
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/code-frame/node_modules/supports-color": {
             "version": "5.5.0",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
             "dev": true,
             "dependencies": {
                 "has-flag": "^3.0.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/compat-data": {
             "version": "7.22.9",
             "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
             "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/core": {
             "version": "7.22.11",
             "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz",
             "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==",
             "dev": true,
             "dependencies": {
                 "@ampproject/remapping": "^2.2.0",
                 "@babel/code-frame": "^7.22.10",
                 "@babel/generator": "^7.22.10",
                 "@babel/helper-compilation-targets": "^7.22.10",
                 "@babel/helper-module-transforms": "^7.22.9",
                 "@babel/helpers": "^7.22.11",
                 "@babel/parser": "^7.22.11",
                 "@babel/template": "^7.22.5",
                 "@babel/traverse": "^7.22.11",
                 "@babel/types": "^7.22.11",
                 "convert-source-map": "^1.7.0",
                 "debug": "^4.1.0",
                 "gensync": "^1.0.0-beta.2",
                 "json5": "^2.2.3",
                 "semver": "^6.3.1"
             },
             "engines": {
                 "node": ">=6.9.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/babel"
             }
         },
         "node_modules/@babel/generator": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
             "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
             "dev": true,
             "dependencies": {
                 "@babel/types": "^7.23.0",
                 "@jridgewell/gen-mapping": "^0.3.2",
                 "@jridgewell/trace-mapping": "^0.3.17",
                 "jsesc": "^2.5.1"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-compilation-targets": {
             "version": "7.22.10",
             "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz",
             "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==",
             "dev": true,
             "dependencies": {
                 "@babel/compat-data": "^7.22.9",
                 "@babel/helper-validator-option": "^7.22.5",
                 "browserslist": "^4.21.9",
                 "lru-cache": "^5.1.1",
                 "semver": "^6.3.1"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-environment-visitor": {
             "version": "7.22.20",
             "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
             "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-function-name": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
             "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
             "dev": true,
             "dependencies": {
                 "@babel/template": "^7.22.15",
                 "@babel/types": "^7.23.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-hoist-variables": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
             "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
             "dev": true,
             "dependencies": {
                 "@babel/types": "^7.22.5"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-module-imports": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
             "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
             "dev": true,
             "dependencies": {
                 "@babel/types": "^7.22.5"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-module-transforms": {
             "version": "7.22.9",
             "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
             "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
             "dev": true,
             "dependencies": {
                 "@babel/helper-environment-visitor": "^7.22.5",
                 "@babel/helper-module-imports": "^7.22.5",
                 "@babel/helper-simple-access": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
                 "@babel/helper-validator-identifier": "^7.22.5"
             },
             "engines": {
                 "node": ">=6.9.0"
             },
             "peerDependencies": {
                 "@babel/core": "^7.0.0"
             }
         },
         "node_modules/@babel/helper-simple-access": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
             "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
             "dev": true,
             "dependencies": {
                 "@babel/types": "^7.22.5"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-split-export-declaration": {
             "version": "7.22.6",
             "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
             "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
             "dev": true,
             "dependencies": {
                 "@babel/types": "^7.22.5"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-string-parser": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
             "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-validator-identifier": {
             "version": "7.22.20",
             "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
             "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helper-validator-option": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz",
             "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helpers": {
             "version": "7.22.11",
             "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz",
             "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==",
             "dev": true,
             "dependencies": {
                 "@babel/template": "^7.22.5",
                 "@babel/traverse": "^7.22.11",
                 "@babel/types": "^7.22.11"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/highlight": {
             "version": "7.22.13",
             "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz",
             "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==",
             "dev": true,
             "dependencies": {
                 "@babel/helper-validator-identifier": "^7.22.5",
                 "chalk": "^2.4.2",
                 "js-tokens": "^4.0.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/highlight/node_modules/ansi-styles": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
             "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
             "dev": true,
             "dependencies": {
                 "color-convert": "^1.9.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/highlight/node_modules/chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
             "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
             "dev": true,
             "dependencies": {
                 "ansi-styles": "^3.2.1",
                 "escape-string-regexp": "^1.0.5",
                 "supports-color": "^5.3.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/highlight/node_modules/color-convert": {
             "version": "1.9.3",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
             "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
             "dev": true,
             "dependencies": {
                 "color-name": "1.1.3"
             }
         },
         "node_modules/@babel/highlight/node_modules/color-name": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
             "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
             "dev": true
         },
         "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
             "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
             "dev": true,
             "engines": {
                 "node": ">=0.8.0"
             }
         },
         "node_modules/@babel/highlight/node_modules/has-flag": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
             "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
             "dev": true,
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/highlight/node_modules/supports-color": {
             "version": "5.5.0",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
             "dev": true,
             "dependencies": {
                 "has-flag": "^3.0.0"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/@babel/parser": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
             "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
             "dev": true,
             "bin": {
                 "parser": "bin/babel-parser.js"
             },
             "engines": {
                 "node": ">=6.0.0"
             }
         },
         "node_modules/@babel/template": {
             "version": "7.22.15",
             "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
             "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
             "dev": true,
             "dependencies": {
                 "@babel/code-frame": "^7.22.13",
                 "@babel/parser": "^7.22.15",
                 "@babel/types": "^7.22.15"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/traverse": {
             "version": "7.23.2",
             "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
             "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
             "dev": true,
             "dependencies": {
                 "@babel/code-frame": "^7.22.13",
                 "@babel/generator": "^7.23.0",
                 "@babel/helper-environment-visitor": "^7.22.20",
                 "@babel/helper-function-name": "^7.23.0",
                 "@babel/helper-hoist-variables": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
                 "@babel/parser": "^7.23.0",
                 "@babel/types": "^7.23.0",
                 "debug": "^4.1.0",
                 "globals": "^11.1.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/types": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
             "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
             "dev": true,
             "dependencies": {
                 "@babel/helper-string-parser": "^7.22.5",
                 "@babel/helper-validator-identifier": "^7.22.20",
                 "to-fast-properties": "^2.0.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
             "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
             "dev": true,
             "dependencies": {
                 "camelcase": "^5.3.1",
                 "find-up": "^4.1.0",
                 "get-package-type": "^0.1.0",
                 "js-yaml": "^3.13.1",
                 "resolve-from": "^5.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
             "version": "1.0.10",
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
             "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
             "dev": true,
             "dependencies": {
                 "sprintf-js": "~1.0.2"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
             "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
             "dev": true,
             "dependencies": {
                 "locate-path": "^5.0.0",
                 "path-exists": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
             "version": "3.14.1",
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
             "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
             "dev": true,
             "dependencies": {
                 "argparse": "^1.0.7",
                 "esprima": "^4.0.0"
             },
             "bin": {
                 "js-yaml": "bin/js-yaml.js"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
             "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
             "dev": true,
             "dependencies": {
                 "p-locate": "^4.1.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
             "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
             "dev": true,
             "dependencies": {
                 "p-try": "^2.0.0"
             },
             "engines": {
                 "node": ">=6"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
             "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
             "dev": true,
             "dependencies": {
                 "p-limit": "^2.2.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/@istanbuljs/schema": {
             "version": "0.1.3",
             "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
             "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/@jridgewell/gen-mapping": {
             "version": "0.3.3",
             "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
             "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
             "dev": true,
             "dependencies": {
                 "@jridgewell/set-array": "^1.0.1",
                 "@jridgewell/sourcemap-codec": "^1.4.10",
                 "@jridgewell/trace-mapping": "^0.3.9"
             },
             "engines": {
                 "node": ">=6.0.0"
             }
         },
         "node_modules/@jridgewell/resolve-uri": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
             "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
             "dev": true,
             "engines": {
                 "node": ">=6.0.0"
             }
         },
         "node_modules/@jridgewell/set-array": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
             "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
             "dev": true,
             "engines": {
                 "node": ">=6.0.0"
             }
         },
         "node_modules/@jridgewell/sourcemap-codec": {
             "version": "1.4.15",
             "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
             "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
             "dev": true
         },
         "node_modules/@jridgewell/trace-mapping": {
             "version": "0.3.19",
             "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
             "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
             "dev": true,
             "dependencies": {
                 "@jridgewell/resolve-uri": "^3.1.0",
                 "@jridgewell/sourcemap-codec": "^1.4.14"
             }
         },
         "node_modules/aggregate-error": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
             "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
             "dev": true,
             "dependencies": {
                 "clean-stack": "^2.0.0",
                 "indent-string": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/ansi-colors": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
             "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
             "dev": true,
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/ansi-regex": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
             "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/ansi-styles": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
             "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
             "dev": true,
             "dependencies": {
                 "color-convert": "^2.0.1"
             },
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/chalk/ansi-styles?sponsor=1"
             }
         },
         "node_modules/anymatch": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
             "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
             "dev": true,
             "dependencies": {
                 "normalize-path": "^3.0.0",
                 "picomatch": "^2.0.4"
             },
             "engines": {
                 "node": ">= 8"
             }
         },
         "node_modules/append-transform": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
             "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
             "dev": true,
             "dependencies": {
                 "default-require-extensions": "^3.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/archy": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
             "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
             "dev": true
         },
         "node_modules/argparse": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
             "dev": true
         },
         "node_modules/balanced-match": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
             "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
             "dev": true
         },
         "node_modules/binary-extensions": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
             "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/brace-expansion": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
             "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
             "dev": true,
             "dependencies": {
                 "balanced-match": "^1.0.0"
             }
         },
         "node_modules/braces": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
             "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "fill-range": "^7.1.1"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/browser-stdout": {
             "version": "1.3.1",
             "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
             "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
             "dev": true
         },
         "node_modules/browserslist": {
             "version": "4.21.10",
             "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
             "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
             "dev": true,
             "funding": [
                 {
                     "type": "opencollective",
                     "url": "https://opencollective.com/browserslist"
                 },
                 {
                     "type": "tidelift",
                     "url": "https://tidelift.com/funding/github/npm/browserslist"
                 },
                 {
                     "type": "github",
                     "url": "https://github.com/sponsors/ai"
                 }
             ],
             "dependencies": {
                 "caniuse-lite": "^1.0.30001517",
                 "electron-to-chromium": "^1.4.477",
                 "node-releases": "^2.0.13",
                 "update-browserslist-db": "^1.0.11"
             },
             "bin": {
                 "browserslist": "cli.js"
             },
             "engines": {
                 "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
             }
         },
         "node_modules/caching-transform": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
             "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
             "dev": true,
             "dependencies": {
                 "hasha": "^5.0.0",
                 "make-dir": "^3.0.0",
                 "package-hash": "^4.0.0",
                 "write-file-atomic": "^3.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/camelcase": {
             "version": "5.3.1",
             "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
             "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
             "dev": true,
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/caniuse-lite": {
             "version": "1.0.30001524",
             "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
             "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
             "dev": true,
             "funding": [
                 {
                     "type": "opencollective",
                     "url": "https://opencollective.com/browserslist"
                 },
                 {
                     "type": "tidelift",
                     "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
                 },
                 {
                     "type": "github",
                     "url": "https://github.com/sponsors/ai"
                 }
             ]
         },
         "node_modules/chalk": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
             "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
             "dev": true,
             "dependencies": {
                 "ansi-styles": "^4.1.0",
                 "supports-color": "^7.1.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/chalk/chalk?sponsor=1"
             }
         },
         "node_modules/chalk/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/charenc": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
             "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
             "dev": true,
             "engines": {
                 "node": "*"
             }
         },
         "node_modules/chokidar": {
             "version": "3.5.3",
             "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
             "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
             "dev": true,
             "funding": [
                 {
                     "type": "individual",
                     "url": "https://paulmillr.com/funding/"
                 }
             ],
             "dependencies": {
                 "anymatch": "~3.1.2",
                 "braces": "~3.0.2",
                 "glob-parent": "~5.1.2",
                 "is-binary-path": "~2.1.0",
                 "is-glob": "~4.0.1",
                 "normalize-path": "~3.0.0",
                 "readdirp": "~3.6.0"
             },
             "engines": {
                 "node": ">= 8.10.0"
             },
             "optionalDependencies": {
                 "fsevents": "~2.3.2"
             }
         },
         "node_modules/clean-stack": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
             "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
             "dev": true,
             "engines": {
                 "node": ">=6"
             }
         },
         "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==",
             "dev": true,
             "dependencies": {
                 "string-width": "^4.2.0",
                 "strip-ansi": "^6.0.0",
                 "wrap-ansi": "^7.0.0"
             }
         },
         "node_modules/color-convert": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
             "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
             "dev": true,
             "dependencies": {
                 "color-name": "~1.1.4"
             },
             "engines": {
                 "node": ">=7.0.0"
             }
         },
         "node_modules/color-name": {
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
             "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
             "dev": true
         },
         "node_modules/commondir": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
             "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
             "dev": true
         },
         "node_modules/concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
             "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
             "dev": true
         },
         "node_modules/convert-source-map": {
             "version": "1.9.0",
             "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
             "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
             "dev": true
         },
         "node_modules/cross-spawn": {
             "version": "7.0.3",
             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
             "dev": true,
             "dependencies": {
                 "path-key": "^3.1.0",
                 "shebang-command": "^2.0.0",
                 "which": "^2.0.1"
             },
             "engines": {
                 "node": ">= 8"
             }
         },
         "node_modules/crypt": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
             "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
             "dev": true,
             "engines": {
                 "node": "*"
             }
         },
         "node_modules/debug": {
             "version": "4.3.4",
             "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
             "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
             "dev": true,
             "dependencies": {
                 "ms": "2.1.2"
             },
             "engines": {
                 "node": ">=6.0"
             },
             "peerDependenciesMeta": {
                 "supports-color": {
                     "optional": true
                 }
             }
         },
         "node_modules/debug/node_modules/ms": {
             "version": "2.1.2",
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
             "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
             "dev": true
         },
         "node_modules/decamelize": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
             "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/default-require-extensions": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
             "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==",
             "dev": true,
             "dependencies": {
                 "strip-bom": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "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==",
             "dev": true,
             "engines": {
                 "node": ">=0.3.1"
             }
         },
         "node_modules/ecashaddrjs": {
             "resolved": "../ecashaddrjs",
             "link": true
         },
         "node_modules/electron-to-chromium": {
             "version": "1.4.504",
             "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.504.tgz",
             "integrity": "sha512-cSMwIAd8yUh54VwitVRVvHK66QqHWE39C3DRj8SWiXitEpVSY3wNPD9y1pxQtLIi4w3UdzF9klLsmuPshz09DQ==",
             "dev": true
         },
         "node_modules/emoji-regex": {
             "version": "8.0.0",
             "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
             "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
             "dev": true
         },
         "node_modules/es6-error": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
             "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
             "dev": true
         },
         "node_modules/escalade": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
             "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
             "dev": true,
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/escape-string-regexp": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
             "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/esprima": {
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
             "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
             "dev": true,
             "bin": {
                 "esparse": "bin/esparse.js",
                 "esvalidate": "bin/esvalidate.js"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/fill-range": {
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
             "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "to-regex-range": "^5.0.1"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/find-cache-dir": {
             "version": "3.3.2",
             "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
             "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
             "dev": true,
             "dependencies": {
                 "commondir": "^1.0.1",
                 "make-dir": "^3.0.2",
                 "pkg-dir": "^4.1.0"
             },
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
             }
         },
         "node_modules/find-up": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
             "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
             "dev": true,
             "dependencies": {
                 "locate-path": "^6.0.0",
                 "path-exists": "^4.0.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/flat": {
             "version": "5.0.2",
             "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
             "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
             "dev": true,
             "bin": {
                 "flat": "cli.js"
             }
         },
         "node_modules/foreground-child": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
             "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
             "dev": true,
             "dependencies": {
                 "cross-spawn": "^7.0.0",
                 "signal-exit": "^3.0.2"
             },
             "engines": {
                 "node": ">=8.0.0"
             }
         },
         "node_modules/fromentries": {
             "version": "1.3.2",
             "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
             "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
             "dev": true,
             "funding": [
                 {
                     "type": "github",
                     "url": "https://github.com/sponsors/feross"
                 },
                 {
                     "type": "patreon",
                     "url": "https://www.patreon.com/feross"
                 },
                 {
                     "type": "consulting",
                     "url": "https://feross.org/support"
                 }
             ]
         },
         "node_modules/fs.realpath": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
             "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
             "dev": true
         },
         "node_modules/fsevents": {
             "version": "2.3.3",
             "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
             "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
             "dev": true,
             "hasInstallScript": true,
             "optional": true,
             "os": [
                 "darwin"
             ],
             "engines": {
                 "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
             }
         },
         "node_modules/gensync": {
             "version": "1.0.0-beta.2",
             "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
             "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
             "dev": true,
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/get-caller-file": {
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
             "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
             "dev": true,
             "engines": {
                 "node": "6.* || 8.* || >= 10.*"
             }
         },
         "node_modules/get-package-type": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
             "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
             "dev": true,
             "engines": {
                 "node": ">=8.0.0"
             }
         },
         "node_modules/glob": {
             "version": "7.2.0",
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
             "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
             "dev": true,
             "dependencies": {
                 "fs.realpath": "^1.0.0",
                 "inflight": "^1.0.4",
                 "inherits": "2",
                 "minimatch": "^3.0.4",
                 "once": "^1.3.0",
                 "path-is-absolute": "^1.0.0"
             },
             "engines": {
                 "node": "*"
             },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
             }
         },
         "node_modules/glob-parent": {
             "version": "5.1.2",
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
             "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
             "dev": true,
             "dependencies": {
                 "is-glob": "^4.0.1"
             },
             "engines": {
                 "node": ">= 6"
             }
         },
         "node_modules/glob/node_modules/brace-expansion": {
             "version": "1.1.11",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "dev": true,
             "dependencies": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
             }
         },
         "node_modules/glob/node_modules/minimatch": {
             "version": "3.1.2",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
             "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
             "dev": true,
             "dependencies": {
                 "brace-expansion": "^1.1.7"
             },
             "engines": {
                 "node": "*"
             }
         },
         "node_modules/globals": {
             "version": "11.12.0",
             "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
             "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
             "dev": true,
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/graceful-fs": {
             "version": "4.2.11",
             "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
             "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
             "dev": true
         },
         "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/hasha": {
             "version": "5.2.2",
             "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
             "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
             "dev": true,
             "dependencies": {
                 "is-stream": "^2.0.0",
                 "type-fest": "^0.8.0"
             },
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/he": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
             "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
             "dev": true,
             "bin": {
                 "he": "bin/he"
             }
         },
         "node_modules/html-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/imurmurhash": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
             "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
             "dev": true,
             "engines": {
                 "node": ">=0.8.19"
             }
         },
         "node_modules/indent-string": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
             "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/inflight": {
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
             "dev": true,
             "dependencies": {
                 "once": "^1.3.0",
                 "wrappy": "1"
             }
         },
         "node_modules/inherits": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
             "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
             "dev": true
         },
         "node_modules/is-binary-path": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
             "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
             "dev": true,
             "dependencies": {
                 "binary-extensions": "^2.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/is-buffer": {
             "version": "1.1.6",
             "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
             "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
             "dev": true
         },
         "node_modules/is-extglob": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
             "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/is-fullwidth-code-point": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
             "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/is-glob": {
             "version": "4.0.3",
             "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
             "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
             "dev": true,
             "dependencies": {
                 "is-extglob": "^2.1.1"
             },
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/is-number": {
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
             "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
             "dev": true,
             "license": "MIT",
             "engines": {
                 "node": ">=0.12.0"
             }
         },
         "node_modules/is-plain-obj": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
             "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/is-stream": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
             "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/is-typedarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
             "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
             "dev": true
         },
         "node_modules/is-unicode-supported": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
             "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/is-windows": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
             "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/isexe": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
             "dev": true
         },
         "node_modules/istanbul-lib-coverage": {
             "version": "3.2.0",
             "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
             "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/istanbul-lib-hook": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
             "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
             "dev": true,
             "dependencies": {
                 "append-transform": "^2.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "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,
             "dependencies": {
                 "@babel/core": "^7.7.5",
                 "@istanbuljs/schema": "^0.1.2",
                 "istanbul-lib-coverage": "^3.0.0",
                 "semver": "^6.3.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/istanbul-lib-processinfo": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz",
             "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==",
             "dev": true,
             "dependencies": {
                 "archy": "^1.0.0",
                 "cross-spawn": "^7.0.3",
                 "istanbul-lib-coverage": "^3.2.0",
                 "p-map": "^3.0.0",
                 "rimraf": "^3.0.0",
                 "uuid": "^8.3.2"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/istanbul-lib-report": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
             "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
             "dev": true,
             "dependencies": {
                 "istanbul-lib-coverage": "^3.0.0",
                 "make-dir": "^4.0.0",
                 "supports-color": "^7.1.0"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/istanbul-lib-report/node_modules/lru-cache": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
             "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
             "dev": true,
             "dependencies": {
                 "yallist": "^4.0.0"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/istanbul-lib-report/node_modules/make-dir": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
             "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
             "dev": true,
             "dependencies": {
                 "semver": "^7.5.3"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/istanbul-lib-report/node_modules/semver": {
             "version": "7.5.4",
             "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
             "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
             "dev": true,
             "dependencies": {
                 "lru-cache": "^6.0.0"
             },
             "bin": {
                 "semver": "bin/semver.js"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "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-lib-report/node_modules/yallist": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
             "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
             "dev": true
         },
         "node_modules/istanbul-lib-source-maps": {
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
             "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
             "dev": true,
             "dependencies": {
                 "debug": "^4.1.1",
                 "istanbul-lib-coverage": "^3.0.0",
                 "source-map": "^0.6.1"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/istanbul-reports": {
             "version": "3.1.6",
             "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
             "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
             "dev": true,
             "dependencies": {
                 "html-escaper": "^2.0.0",
                 "istanbul-lib-report": "^3.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
             "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
             "dev": true
         },
         "node_modules/js-yaml": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
             "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
             "dev": true,
             "dependencies": {
                 "argparse": "^2.0.1"
             },
             "bin": {
                 "js-yaml": "bin/js-yaml.js"
             }
         },
         "node_modules/jsesc": {
             "version": "2.5.2",
             "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
             "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
             "dev": true,
             "bin": {
                 "jsesc": "bin/jsesc"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/json5": {
             "version": "2.2.3",
             "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
             "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
             "dev": true,
             "bin": {
                 "json5": "lib/cli.js"
             },
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/locate-path": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
             "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
             "dev": true,
             "dependencies": {
                 "p-locate": "^5.0.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/lodash.flattendeep": {
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
             "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
             "dev": true
         },
         "node_modules/log-symbols": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
             "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
             "dev": true,
             "dependencies": {
                 "chalk": "^4.1.0",
                 "is-unicode-supported": "^0.1.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/lru-cache": {
             "version": "5.1.1",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
             "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
             "dev": true,
             "dependencies": {
                 "yallist": "^3.0.2"
             }
         },
         "node_modules/make-dir": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
             "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
             "dev": true,
             "dependencies": {
                 "semver": "^6.0.0"
             },
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/md5": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
             "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
             "dev": true,
             "dependencies": {
                 "charenc": "0.0.2",
                 "crypt": "0.0.2",
                 "is-buffer": "~1.1.6"
             }
         },
         "node_modules/minimatch": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
             "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
             "dev": true,
             "dependencies": {
                 "brace-expansion": "^2.0.1"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/mkdirp": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
             "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
             "dev": true,
             "bin": {
                 "mkdirp": "dist/cjs/src/bin.js"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
             }
         },
         "node_modules/mocha": {
             "version": "10.2.0",
             "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
             "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
             "dev": true,
             "dependencies": {
                 "ansi-colors": "4.1.1",
                 "browser-stdout": "1.3.1",
                 "chokidar": "3.5.3",
                 "debug": "4.3.4",
                 "diff": "5.0.0",
                 "escape-string-regexp": "4.0.0",
                 "find-up": "5.0.0",
                 "glob": "7.2.0",
                 "he": "1.2.0",
                 "js-yaml": "4.1.0",
                 "log-symbols": "4.1.0",
                 "minimatch": "5.0.1",
                 "ms": "2.1.3",
                 "nanoid": "3.3.3",
                 "serialize-javascript": "6.0.0",
                 "strip-json-comments": "3.1.1",
                 "supports-color": "8.1.1",
                 "workerpool": "6.2.1",
                 "yargs": "16.2.0",
                 "yargs-parser": "20.2.4",
                 "yargs-unparser": "2.0.0"
             },
             "bin": {
                 "_mocha": "bin/_mocha",
                 "mocha": "bin/mocha.js"
             },
             "engines": {
                 "node": ">= 14.0.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/mochajs"
             }
         },
         "node_modules/mocha-junit-reporter": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.2.1.tgz",
             "integrity": "sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw==",
             "dev": true,
             "dependencies": {
                 "debug": "^4.3.4",
                 "md5": "^2.3.0",
                 "mkdirp": "^3.0.0",
                 "strip-ansi": "^6.0.1",
                 "xml": "^1.0.1"
             },
             "peerDependencies": {
                 "mocha": ">=2.2.5"
             }
         },
         "node_modules/ms": {
             "version": "2.1.3",
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
             "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
             "dev": true
         },
         "node_modules/nanoid": {
             "version": "3.3.3",
             "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
             "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
             "dev": true,
             "bin": {
                 "nanoid": "bin/nanoid.cjs"
             },
             "engines": {
                 "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
             }
         },
         "node_modules/node-preload": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
             "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
             "dev": true,
             "dependencies": {
                 "process-on-spawn": "^1.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/node-releases": {
             "version": "2.0.13",
             "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
             "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
             "dev": true
         },
         "node_modules/normalize-path": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
             "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/nyc": {
             "version": "15.1.0",
             "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
             "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
             "dev": true,
             "dependencies": {
                 "@istanbuljs/load-nyc-config": "^1.0.0",
                 "@istanbuljs/schema": "^0.1.2",
                 "caching-transform": "^4.0.0",
                 "convert-source-map": "^1.7.0",
                 "decamelize": "^1.2.0",
                 "find-cache-dir": "^3.2.0",
                 "find-up": "^4.1.0",
                 "foreground-child": "^2.0.0",
                 "get-package-type": "^0.1.0",
                 "glob": "^7.1.6",
                 "istanbul-lib-coverage": "^3.0.0",
                 "istanbul-lib-hook": "^3.0.0",
                 "istanbul-lib-instrument": "^4.0.0",
                 "istanbul-lib-processinfo": "^2.0.2",
                 "istanbul-lib-report": "^3.0.0",
                 "istanbul-lib-source-maps": "^4.0.0",
                 "istanbul-reports": "^3.0.2",
                 "make-dir": "^3.0.0",
                 "node-preload": "^0.2.1",
                 "p-map": "^3.0.0",
                 "process-on-spawn": "^1.0.0",
                 "resolve-from": "^5.0.0",
                 "rimraf": "^3.0.0",
                 "signal-exit": "^3.0.2",
                 "spawn-wrap": "^2.0.0",
                 "test-exclude": "^6.0.0",
                 "yargs": "^15.0.2"
             },
             "bin": {
                 "nyc": "bin/nyc.js"
             },
             "engines": {
                 "node": ">=8.9"
             }
         },
         "node_modules/nyc/node_modules/cliui": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
             "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
             "dev": true,
             "dependencies": {
                 "string-width": "^4.2.0",
                 "strip-ansi": "^6.0.0",
                 "wrap-ansi": "^6.2.0"
             }
         },
         "node_modules/nyc/node_modules/find-up": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
             "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
             "dev": true,
             "dependencies": {
                 "locate-path": "^5.0.0",
                 "path-exists": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/nyc/node_modules/locate-path": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
             "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
             "dev": true,
             "dependencies": {
                 "p-locate": "^4.1.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/nyc/node_modules/p-limit": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
             "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
             "dev": true,
             "dependencies": {
                 "p-try": "^2.0.0"
             },
             "engines": {
                 "node": ">=6"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/nyc/node_modules/p-locate": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
             "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
             "dev": true,
             "dependencies": {
                 "p-limit": "^2.2.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/nyc/node_modules/wrap-ansi": {
             "version": "6.2.0",
             "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
             "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
             "dev": true,
             "dependencies": {
                 "ansi-styles": "^4.0.0",
                 "string-width": "^4.1.0",
                 "strip-ansi": "^6.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/nyc/node_modules/y18n": {
             "version": "4.0.3",
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
             "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
             "dev": true
         },
         "node_modules/nyc/node_modules/yargs": {
             "version": "15.4.1",
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
             "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
             "dev": true,
             "dependencies": {
                 "cliui": "^6.0.0",
                 "decamelize": "^1.2.0",
                 "find-up": "^4.1.0",
                 "get-caller-file": "^2.0.1",
                 "require-directory": "^2.1.1",
                 "require-main-filename": "^2.0.0",
                 "set-blocking": "^2.0.0",
                 "string-width": "^4.2.0",
                 "which-module": "^2.0.0",
                 "y18n": "^4.0.0",
                 "yargs-parser": "^18.1.2"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/nyc/node_modules/yargs-parser": {
             "version": "18.1.3",
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
             "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
             "dev": true,
             "dependencies": {
                 "camelcase": "^5.0.0",
                 "decamelize": "^1.2.0"
             },
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/once": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
             "dev": true,
             "dependencies": {
                 "wrappy": "1"
             }
         },
         "node_modules/p-limit": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
             "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
             "dev": true,
             "dependencies": {
                 "yocto-queue": "^0.1.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/p-locate": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
             "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
             "dev": true,
             "dependencies": {
                 "p-limit": "^3.0.2"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/p-map": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
             "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
             "dev": true,
             "dependencies": {
                 "aggregate-error": "^3.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/p-try": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
             "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
             "dev": true,
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/package-hash": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
             "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
             "dev": true,
             "dependencies": {
                 "graceful-fs": "^4.1.15",
                 "hasha": "^5.0.0",
                 "lodash.flattendeep": "^4.4.0",
                 "release-zalgo": "^1.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/path-exists": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
             "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/path-is-absolute": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
             "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/path-key": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/picocolors": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
             "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
             "dev": true
         },
         "node_modules/picomatch": {
             "version": "2.3.1",
             "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
             "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
             "dev": true,
             "engines": {
                 "node": ">=8.6"
             },
             "funding": {
                 "url": "https://github.com/sponsors/jonschlinkert"
             }
         },
         "node_modules/pkg-dir": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
             "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
             "dev": true,
             "dependencies": {
                 "find-up": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/pkg-dir/node_modules/find-up": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
             "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
             "dev": true,
             "dependencies": {
                 "locate-path": "^5.0.0",
                 "path-exists": "^4.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/pkg-dir/node_modules/locate-path": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
             "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
             "dev": true,
             "dependencies": {
                 "p-locate": "^4.1.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/pkg-dir/node_modules/p-limit": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
             "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
             "dev": true,
             "dependencies": {
                 "p-try": "^2.0.0"
             },
             "engines": {
                 "node": ">=6"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/pkg-dir/node_modules/p-locate": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
             "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
             "dev": true,
             "dependencies": {
                 "p-limit": "^2.2.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/process-on-spawn": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
             "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
             "dev": true,
             "dependencies": {
                 "fromentries": "^1.2.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/randombytes": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
             "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
             "dev": true,
             "dependencies": {
                 "safe-buffer": "^5.1.0"
             }
         },
         "node_modules/readdirp": {
             "version": "3.6.0",
             "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
             "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
             "dev": true,
             "dependencies": {
                 "picomatch": "^2.2.1"
             },
             "engines": {
                 "node": ">=8.10.0"
             }
         },
         "node_modules/release-zalgo": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
             "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==",
             "dev": true,
             "dependencies": {
                 "es6-error": "^4.0.1"
             },
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/require-directory": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
             "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
             }
         },
         "node_modules/require-main-filename": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
             "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
             "dev": true
         },
         "node_modules/resolve-from": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
             "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/rimraf": {
             "version": "3.0.2",
             "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
             "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
             "dev": true,
             "dependencies": {
                 "glob": "^7.1.3"
             },
             "bin": {
                 "rimraf": "bin.js"
             },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
             }
         },
         "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==",
             "dev": true,
             "funding": [
                 {
                     "type": "github",
                     "url": "https://github.com/sponsors/feross"
                 },
                 {
                     "type": "patreon",
                     "url": "https://www.patreon.com/feross"
                 },
                 {
                     "type": "consulting",
                     "url": "https://feross.org/support"
                 }
             ]
         },
         "node_modules/semver": {
             "version": "6.3.1",
             "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
             "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
             }
         },
         "node_modules/serialize-javascript": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
             "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
             "dev": true,
             "dependencies": {
                 "randombytes": "^2.1.0"
             }
         },
         "node_modules/set-blocking": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
             "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
             "dev": true
         },
         "node_modules/shebang-command": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
             "dev": true,
             "dependencies": {
                 "shebang-regex": "^3.0.0"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/shebang-regex": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/signal-exit": {
             "version": "3.0.7",
             "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
             "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
             "dev": true
         },
         "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/spawn-wrap": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
             "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
             "dev": true,
             "dependencies": {
                 "foreground-child": "^2.0.0",
                 "is-windows": "^1.0.2",
                 "make-dir": "^3.0.0",
                 "rimraf": "^3.0.0",
                 "signal-exit": "^3.0.2",
                 "which": "^2.0.1"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/sprintf-js": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
             "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
             "dev": true
         },
         "node_modules/string-width": {
             "version": "4.2.3",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
             "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
             "dev": true,
             "dependencies": {
                 "emoji-regex": "^8.0.0",
                 "is-fullwidth-code-point": "^3.0.0",
                 "strip-ansi": "^6.0.1"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
             "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
             "dev": true,
             "dependencies": {
                 "ansi-regex": "^5.0.1"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/strip-bom": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
             "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/strip-json-comments": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
             "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/supports-color": {
             "version": "8.1.1",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
             "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
             "dev": true,
             "dependencies": {
                 "has-flag": "^4.0.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/chalk/supports-color?sponsor=1"
             }
         },
         "node_modules/test-exclude": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
             "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
             "dev": true,
             "dependencies": {
                 "@istanbuljs/schema": "^0.1.2",
                 "glob": "^7.1.4",
                 "minimatch": "^3.0.4"
             },
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/test-exclude/node_modules/brace-expansion": {
             "version": "1.1.11",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "dev": true,
             "dependencies": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
             }
         },
         "node_modules/test-exclude/node_modules/minimatch": {
             "version": "3.1.2",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
             "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
             "dev": true,
             "dependencies": {
                 "brace-expansion": "^1.1.7"
             },
             "engines": {
                 "node": "*"
             }
         },
         "node_modules/to-fast-properties": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
             "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
             "dev": true,
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/to-regex-range": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
             "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "is-number": "^7.0.0"
             },
             "engines": {
                 "node": ">=8.0"
             }
         },
         "node_modules/type-fest": {
             "version": "0.8.1",
             "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
             "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
             "dev": true,
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/typedarray-to-buffer": {
             "version": "3.1.5",
             "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
             "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
             "dev": true,
             "dependencies": {
                 "is-typedarray": "^1.0.0"
             }
         },
         "node_modules/update-browserslist-db": {
             "version": "1.0.11",
             "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
             "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
             "dev": true,
             "funding": [
                 {
                     "type": "opencollective",
                     "url": "https://opencollective.com/browserslist"
                 },
                 {
                     "type": "tidelift",
                     "url": "https://tidelift.com/funding/github/npm/browserslist"
                 },
                 {
                     "type": "github",
                     "url": "https://github.com/sponsors/ai"
                 }
             ],
             "dependencies": {
                 "escalade": "^3.1.1",
                 "picocolors": "^1.0.0"
             },
             "bin": {
                 "update-browserslist-db": "cli.js"
             },
             "peerDependencies": {
                 "browserslist": ">= 4.21.0"
             }
         },
         "node_modules/uuid": {
             "version": "8.3.2",
             "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
             "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
             "dev": true,
             "bin": {
                 "uuid": "dist/bin/uuid"
             }
         },
         "node_modules/which": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
             "dev": true,
             "dependencies": {
                 "isexe": "^2.0.0"
             },
             "bin": {
                 "node-which": "bin/node-which"
             },
             "engines": {
                 "node": ">= 8"
             }
         },
         "node_modules/which-module": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
             "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
             "dev": true
         },
         "node_modules/workerpool": {
             "version": "6.2.1",
             "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
             "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
             "dev": true
         },
         "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==",
             "dev": true,
             "dependencies": {
                 "ansi-styles": "^4.0.0",
                 "string-width": "^4.1.0",
                 "strip-ansi": "^6.0.0"
             },
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
             }
         },
         "node_modules/wrappy": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
             "dev": true
         },
         "node_modules/write-file-atomic": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
             "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
             "dev": true,
             "dependencies": {
                 "imurmurhash": "^0.1.4",
                 "is-typedarray": "^1.0.0",
                 "signal-exit": "^3.0.2",
                 "typedarray-to-buffer": "^3.1.5"
             }
         },
         "node_modules/xml": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
             "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
             "dev": true
         },
         "node_modules/y18n": {
             "version": "5.0.8",
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
             "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/yallist": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
             "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
             "dev": true
         },
         "node_modules/yargs": {
             "version": "16.2.0",
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
             "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
             "dev": true,
             "dependencies": {
                 "cliui": "^7.0.2",
                 "escalade": "^3.1.1",
                 "get-caller-file": "^2.0.5",
                 "require-directory": "^2.1.1",
                 "string-width": "^4.2.0",
                 "y18n": "^5.0.5",
                 "yargs-parser": "^20.2.2"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/yargs-parser": {
             "version": "20.2.4",
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
             "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/yargs-unparser": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
             "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
             "dev": true,
             "dependencies": {
                 "camelcase": "^6.0.0",
                 "decamelize": "^4.0.0",
                 "flat": "^5.0.2",
                 "is-plain-obj": "^2.1.0"
             },
             "engines": {
                 "node": ">=10"
             }
         },
         "node_modules/yargs-unparser/node_modules/camelcase": {
             "version": "6.3.0",
             "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
             "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/yargs-unparser/node_modules/decamelize": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
             "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/yocto-queue": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
             "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
             "dev": true,
             "engines": {
                 "node": ">=10"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         }
     },
     "dependencies": {
         "@ampproject/remapping": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
             "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
             "dev": true,
             "requires": {
                 "@jridgewell/gen-mapping": "^0.3.0",
                 "@jridgewell/trace-mapping": "^0.3.9"
             }
         },
         "@babel/code-frame": {
             "version": "7.22.13",
             "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
             "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
             "dev": true,
             "requires": {
                 "@babel/highlight": "^7.22.13",
                 "chalk": "^2.4.2"
             },
             "dependencies": {
                 "ansi-styles": {
                     "version": "3.2.1",
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
                         "color-convert": "^1.9.0"
                     }
                 },
                 "chalk": {
                     "version": "2.4.2",
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
                         "ansi-styles": "^3.2.1",
                         "escape-string-regexp": "^1.0.5",
                         "supports-color": "^5.3.0"
                     }
                 },
                 "color-convert": {
                     "version": "1.9.3",
                     "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
                     "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
                     "dev": true,
                     "requires": {
                         "color-name": "1.1.3"
                     }
                 },
                 "color-name": {
                     "version": "1.1.3",
                     "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
                     "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
                     "dev": true
                 },
                 "escape-string-regexp": {
                     "version": "1.0.5",
                     "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
                     "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
                     "dev": true
                 },
                 "has-flag": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
                     "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
                     "dev": true
                 },
                 "supports-color": {
                     "version": "5.5.0",
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
                         "has-flag": "^3.0.0"
                     }
                 }
             }
         },
         "@babel/compat-data": {
             "version": "7.22.9",
             "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
             "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
             "dev": true
         },
         "@babel/core": {
             "version": "7.22.11",
             "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz",
             "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==",
             "dev": true,
             "requires": {
                 "@ampproject/remapping": "^2.2.0",
                 "@babel/code-frame": "^7.22.10",
                 "@babel/generator": "^7.22.10",
                 "@babel/helper-compilation-targets": "^7.22.10",
                 "@babel/helper-module-transforms": "^7.22.9",
                 "@babel/helpers": "^7.22.11",
                 "@babel/parser": "^7.22.11",
                 "@babel/template": "^7.22.5",
                 "@babel/traverse": "^7.22.11",
                 "@babel/types": "^7.22.11",
                 "convert-source-map": "^1.7.0",
                 "debug": "^4.1.0",
                 "gensync": "^1.0.0-beta.2",
                 "json5": "^2.2.3",
                 "semver": "^6.3.1"
             }
         },
         "@babel/generator": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
             "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
             "dev": true,
             "requires": {
                 "@babel/types": "^7.23.0",
                 "@jridgewell/gen-mapping": "^0.3.2",
                 "@jridgewell/trace-mapping": "^0.3.17",
                 "jsesc": "^2.5.1"
             }
         },
         "@babel/helper-compilation-targets": {
             "version": "7.22.10",
             "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz",
             "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==",
             "dev": true,
             "requires": {
                 "@babel/compat-data": "^7.22.9",
                 "@babel/helper-validator-option": "^7.22.5",
                 "browserslist": "^4.21.9",
                 "lru-cache": "^5.1.1",
                 "semver": "^6.3.1"
             }
         },
         "@babel/helper-environment-visitor": {
             "version": "7.22.20",
             "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
             "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
             "dev": true
         },
         "@babel/helper-function-name": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
             "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
             "dev": true,
             "requires": {
                 "@babel/template": "^7.22.15",
                 "@babel/types": "^7.23.0"
             }
         },
         "@babel/helper-hoist-variables": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
             "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
             "dev": true,
             "requires": {
                 "@babel/types": "^7.22.5"
             }
         },
         "@babel/helper-module-imports": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
             "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
             "dev": true,
             "requires": {
                 "@babel/types": "^7.22.5"
             }
         },
         "@babel/helper-module-transforms": {
             "version": "7.22.9",
             "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
             "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
             "dev": true,
             "requires": {
                 "@babel/helper-environment-visitor": "^7.22.5",
                 "@babel/helper-module-imports": "^7.22.5",
                 "@babel/helper-simple-access": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
                 "@babel/helper-validator-identifier": "^7.22.5"
             }
         },
         "@babel/helper-simple-access": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
             "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
             "dev": true,
             "requires": {
                 "@babel/types": "^7.22.5"
             }
         },
         "@babel/helper-split-export-declaration": {
             "version": "7.22.6",
             "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
             "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
             "dev": true,
             "requires": {
                 "@babel/types": "^7.22.5"
             }
         },
         "@babel/helper-string-parser": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
             "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
             "dev": true
         },
         "@babel/helper-validator-identifier": {
             "version": "7.22.20",
             "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
             "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
             "dev": true
         },
         "@babel/helper-validator-option": {
             "version": "7.22.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz",
             "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==",
             "dev": true
         },
         "@babel/helpers": {
             "version": "7.22.11",
             "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz",
             "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==",
             "dev": true,
             "requires": {
                 "@babel/template": "^7.22.5",
                 "@babel/traverse": "^7.22.11",
                 "@babel/types": "^7.22.11"
             }
         },
         "@babel/highlight": {
             "version": "7.22.13",
             "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz",
             "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==",
             "dev": true,
             "requires": {
                 "@babel/helper-validator-identifier": "^7.22.5",
                 "chalk": "^2.4.2",
                 "js-tokens": "^4.0.0"
             },
             "dependencies": {
                 "ansi-styles": {
                     "version": "3.2.1",
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
                         "color-convert": "^1.9.0"
                     }
                 },
                 "chalk": {
                     "version": "2.4.2",
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
                         "ansi-styles": "^3.2.1",
                         "escape-string-regexp": "^1.0.5",
                         "supports-color": "^5.3.0"
                     }
                 },
                 "color-convert": {
                     "version": "1.9.3",
                     "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
                     "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
                     "dev": true,
                     "requires": {
                         "color-name": "1.1.3"
                     }
                 },
                 "color-name": {
                     "version": "1.1.3",
                     "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
                     "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
                     "dev": true
                 },
                 "escape-string-regexp": {
                     "version": "1.0.5",
                     "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
                     "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
                     "dev": true
                 },
                 "has-flag": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
                     "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
                     "dev": true
                 },
                 "supports-color": {
                     "version": "5.5.0",
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
                         "has-flag": "^3.0.0"
                     }
                 }
             }
         },
         "@babel/parser": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
             "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
             "dev": true
         },
         "@babel/template": {
             "version": "7.22.15",
             "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
             "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
             "dev": true,
             "requires": {
                 "@babel/code-frame": "^7.22.13",
                 "@babel/parser": "^7.22.15",
                 "@babel/types": "^7.22.15"
             }
         },
         "@babel/traverse": {
             "version": "7.23.2",
             "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
             "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
             "dev": true,
             "requires": {
                 "@babel/code-frame": "^7.22.13",
                 "@babel/generator": "^7.23.0",
                 "@babel/helper-environment-visitor": "^7.22.20",
                 "@babel/helper-function-name": "^7.23.0",
                 "@babel/helper-hoist-variables": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
                 "@babel/parser": "^7.23.0",
                 "@babel/types": "^7.23.0",
                 "debug": "^4.1.0",
                 "globals": "^11.1.0"
             }
         },
         "@babel/types": {
             "version": "7.23.0",
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
             "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
             "dev": true,
             "requires": {
                 "@babel/helper-string-parser": "^7.22.5",
                 "@babel/helper-validator-identifier": "^7.22.20",
                 "to-fast-properties": "^2.0.0"
             }
         },
         "@istanbuljs/load-nyc-config": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
             "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
             "dev": true,
             "requires": {
                 "camelcase": "^5.3.1",
                 "find-up": "^4.1.0",
                 "get-package-type": "^0.1.0",
                 "js-yaml": "^3.13.1",
                 "resolve-from": "^5.0.0"
             },
             "dependencies": {
                 "argparse": {
                     "version": "1.0.10",
                     "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
                     "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
                     "dev": true,
                     "requires": {
                         "sprintf-js": "~1.0.2"
                     }
                 },
                 "find-up": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
                     "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
                     "dev": true,
                     "requires": {
                         "locate-path": "^5.0.0",
                         "path-exists": "^4.0.0"
                     }
                 },
                 "js-yaml": {
                     "version": "3.14.1",
                     "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
                     "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
                     "dev": true,
                     "requires": {
                         "argparse": "^1.0.7",
                         "esprima": "^4.0.0"
                     }
                 },
                 "locate-path": {
                     "version": "5.0.0",
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
                     "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
                     "dev": true,
                     "requires": {
                         "p-locate": "^4.1.0"
                     }
                 },
                 "p-limit": {
                     "version": "2.3.0",
                     "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
                     "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
                     "dev": true,
                     "requires": {
                         "p-try": "^2.0.0"
                     }
                 },
                 "p-locate": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
                     "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
                     "dev": true,
                     "requires": {
                         "p-limit": "^2.2.0"
                     }
                 }
             }
         },
         "@istanbuljs/schema": {
             "version": "0.1.3",
             "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
             "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
             "dev": true
         },
         "@jridgewell/gen-mapping": {
             "version": "0.3.3",
             "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
             "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
             "dev": true,
             "requires": {
                 "@jridgewell/set-array": "^1.0.1",
                 "@jridgewell/sourcemap-codec": "^1.4.10",
                 "@jridgewell/trace-mapping": "^0.3.9"
             }
         },
         "@jridgewell/resolve-uri": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
             "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
             "dev": true
         },
         "@jridgewell/set-array": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
             "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
             "dev": true
         },
         "@jridgewell/sourcemap-codec": {
             "version": "1.4.15",
             "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
             "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
             "dev": true
         },
         "@jridgewell/trace-mapping": {
             "version": "0.3.19",
             "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
             "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
             "dev": true,
             "requires": {
                 "@jridgewell/resolve-uri": "^3.1.0",
                 "@jridgewell/sourcemap-codec": "^1.4.14"
             }
         },
         "aggregate-error": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
             "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
             "dev": true,
             "requires": {
                 "clean-stack": "^2.0.0",
                 "indent-string": "^4.0.0"
             }
         },
         "ansi-colors": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
             "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
             "dev": true
         },
         "ansi-regex": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
             "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
             "dev": true
         },
         "ansi-styles": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
             "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
             "dev": true,
             "requires": {
                 "color-convert": "^2.0.1"
             }
         },
         "anymatch": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
             "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
             "dev": true,
             "requires": {
                 "normalize-path": "^3.0.0",
                 "picomatch": "^2.0.4"
             }
         },
         "append-transform": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
             "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
             "dev": true,
             "requires": {
                 "default-require-extensions": "^3.0.0"
             }
         },
         "archy": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
             "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
             "dev": true
         },
         "argparse": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
             "dev": true
         },
         "balanced-match": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
             "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
             "dev": true
         },
         "binary-extensions": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
             "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
             "dev": true
         },
         "brace-expansion": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
             "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
             "dev": true,
             "requires": {
                 "balanced-match": "^1.0.0"
             }
         },
         "braces": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
             "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
             "dev": true,
             "requires": {
                 "fill-range": "^7.1.1"
             }
         },
         "browser-stdout": {
             "version": "1.3.1",
             "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
             "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
             "dev": true
         },
         "browserslist": {
             "version": "4.21.10",
             "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
             "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
             "dev": true,
             "requires": {
                 "caniuse-lite": "^1.0.30001517",
                 "electron-to-chromium": "^1.4.477",
                 "node-releases": "^2.0.13",
                 "update-browserslist-db": "^1.0.11"
             }
         },
         "caching-transform": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
             "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
             "dev": true,
             "requires": {
                 "hasha": "^5.0.0",
                 "make-dir": "^3.0.0",
                 "package-hash": "^4.0.0",
                 "write-file-atomic": "^3.0.0"
             }
         },
         "camelcase": {
             "version": "5.3.1",
             "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
             "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
             "dev": true
         },
         "caniuse-lite": {
             "version": "1.0.30001524",
             "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
             "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
             "dev": true
         },
         "chalk": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
             "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
             "dev": true,
             "requires": {
                 "ansi-styles": "^4.1.0",
                 "supports-color": "^7.1.0"
             },
             "dependencies": {
                 "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"
                     }
                 }
             }
         },
         "charenc": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
             "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
             "dev": true
         },
         "chokidar": {
             "version": "3.5.3",
             "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
             "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
             "dev": true,
             "requires": {
                 "anymatch": "~3.1.2",
                 "braces": "~3.0.2",
                 "fsevents": "~2.3.2",
                 "glob-parent": "~5.1.2",
                 "is-binary-path": "~2.1.0",
                 "is-glob": "~4.0.1",
                 "normalize-path": "~3.0.0",
                 "readdirp": "~3.6.0"
             }
         },
         "clean-stack": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
             "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
             "dev": true
         },
         "cliui": {
             "version": "7.0.4",
             "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
             "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
             "dev": true,
             "requires": {
                 "string-width": "^4.2.0",
                 "strip-ansi": "^6.0.0",
                 "wrap-ansi": "^7.0.0"
             }
         },
         "color-convert": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
             "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
             "dev": true,
             "requires": {
                 "color-name": "~1.1.4"
             }
         },
         "color-name": {
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
             "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
             "dev": true
         },
         "commondir": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
             "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
             "dev": true
         },
         "concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
             "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
             "dev": true
         },
         "convert-source-map": {
             "version": "1.9.0",
             "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
             "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
             "dev": true
         },
         "cross-spawn": {
             "version": "7.0.3",
             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
             "dev": true,
             "requires": {
                 "path-key": "^3.1.0",
                 "shebang-command": "^2.0.0",
                 "which": "^2.0.1"
             }
         },
         "crypt": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
             "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
             "dev": true
         },
         "debug": {
             "version": "4.3.4",
             "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
             "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
             "dev": true,
             "requires": {
                 "ms": "2.1.2"
             },
             "dependencies": {
                 "ms": {
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
                     "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
                     "dev": true
                 }
             }
         },
         "decamelize": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
             "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
             "dev": true
         },
         "default-require-extensions": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
             "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==",
             "dev": true,
             "requires": {
                 "strip-bom": "^4.0.0"
             }
         },
         "diff": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
             "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
             "dev": true
         },
         "ecashaddrjs": {
             "version": "file:../ecashaddrjs",
             "requires": {
                 "@babel/cli": "^7.21.0",
                 "@babel/core": "^7.21.3",
                 "@babel/preset-env": "^7.20.2",
                 "babel-loader": "^9.1.2",
                 "big-integer": "1.6.36",
                 "bs58check": "^3.0.1",
                 "buffer": "^6.0.3",
                 "chai": "^4.3.7",
                 "debug": "^4.3.4",
                 "eslint": "^8.37.0",
                 "jsdoc": "^4.0.2",
                 "mocha": "^10.2.0",
                 "mocha-junit-reporter": "^2.2.0",
                 "mocha-suppress-logs": "^0.3.1",
                 "nyc": "^15.1.0",
                 "random-js": "^2.1.0",
                 "webpack": "^5.76.2",
                 "webpack-cli": "^5.0.1"
             }
         },
         "electron-to-chromium": {
             "version": "1.4.504",
             "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.504.tgz",
             "integrity": "sha512-cSMwIAd8yUh54VwitVRVvHK66QqHWE39C3DRj8SWiXitEpVSY3wNPD9y1pxQtLIi4w3UdzF9klLsmuPshz09DQ==",
             "dev": true
         },
         "emoji-regex": {
             "version": "8.0.0",
             "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
             "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
             "dev": true
         },
         "es6-error": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
             "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
             "dev": true
         },
         "escalade": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
             "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
             "dev": true
         },
         "escape-string-regexp": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
             "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
             "dev": true
         },
         "esprima": {
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
             "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
             "dev": true
         },
         "fill-range": {
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
             "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
             "dev": true,
             "requires": {
                 "to-regex-range": "^5.0.1"
             }
         },
         "find-cache-dir": {
             "version": "3.3.2",
             "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
             "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
             "dev": true,
             "requires": {
                 "commondir": "^1.0.1",
                 "make-dir": "^3.0.2",
                 "pkg-dir": "^4.1.0"
             }
         },
         "find-up": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
             "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
             "dev": true,
             "requires": {
                 "locate-path": "^6.0.0",
                 "path-exists": "^4.0.0"
             }
         },
         "flat": {
             "version": "5.0.2",
             "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
             "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
             "dev": true
         },
         "foreground-child": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
             "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
             "dev": true,
             "requires": {
                 "cross-spawn": "^7.0.0",
                 "signal-exit": "^3.0.2"
             }
         },
         "fromentries": {
             "version": "1.3.2",
             "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
             "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
             "dev": true
         },
         "fs.realpath": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
             "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
             "dev": true
         },
         "fsevents": {
             "version": "2.3.3",
             "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
             "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
             "dev": true,
             "optional": true
         },
         "gensync": {
             "version": "1.0.0-beta.2",
             "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
             "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
             "dev": true
         },
         "get-caller-file": {
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
             "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
             "dev": true
         },
         "get-package-type": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
             "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
             "dev": true
         },
         "glob": {
             "version": "7.2.0",
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
             "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
             "dev": true,
             "requires": {
                 "fs.realpath": "^1.0.0",
                 "inflight": "^1.0.4",
                 "inherits": "2",
                 "minimatch": "^3.0.4",
                 "once": "^1.3.0",
                 "path-is-absolute": "^1.0.0"
             },
             "dependencies": {
                 "brace-expansion": {
                     "version": "1.1.11",
                     "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
                     "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
                     "dev": true,
                     "requires": {
                         "balanced-match": "^1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
                 "minimatch": {
                     "version": "3.1.2",
                     "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
                     "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
                     "dev": true,
                     "requires": {
                         "brace-expansion": "^1.1.7"
                     }
                 }
             }
         },
         "glob-parent": {
             "version": "5.1.2",
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
             "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
             "dev": true,
             "requires": {
                 "is-glob": "^4.0.1"
             }
         },
         "globals": {
             "version": "11.12.0",
             "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
             "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
             "dev": true
         },
         "graceful-fs": {
             "version": "4.2.11",
             "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
             "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
             "dev": true
         },
         "has-flag": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
             "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
             "dev": true
         },
         "hasha": {
             "version": "5.2.2",
             "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
             "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
             "dev": true,
             "requires": {
                 "is-stream": "^2.0.0",
                 "type-fest": "^0.8.0"
             }
         },
         "he": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
             "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
             "dev": true
         },
         "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
         },
         "imurmurhash": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
             "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
             "dev": true
         },
         "indent-string": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
             "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
             "dev": true
         },
         "inflight": {
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
             "dev": true,
             "requires": {
                 "once": "^1.3.0",
                 "wrappy": "1"
             }
         },
         "inherits": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
             "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
             "dev": true
         },
         "is-binary-path": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
             "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
             "dev": true,
             "requires": {
                 "binary-extensions": "^2.0.0"
             }
         },
         "is-buffer": {
             "version": "1.1.6",
             "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
             "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
             "dev": true
         },
         "is-extglob": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
             "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
             "dev": true
         },
         "is-fullwidth-code-point": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
             "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
             "dev": true
         },
         "is-glob": {
             "version": "4.0.3",
             "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
             "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
             "dev": true,
             "requires": {
                 "is-extglob": "^2.1.1"
             }
         },
         "is-number": {
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
             "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
             "dev": true
         },
         "is-plain-obj": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
             "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
             "dev": true
         },
         "is-stream": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
             "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
             "dev": true
         },
         "is-typedarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
             "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
             "dev": true
         },
         "is-unicode-supported": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
             "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
             "dev": true
         },
         "is-windows": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
             "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
             "dev": true
         },
         "isexe": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
             "dev": true
         },
         "istanbul-lib-coverage": {
             "version": "3.2.0",
             "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
             "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
             "dev": true
         },
         "istanbul-lib-hook": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
             "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
             "dev": true,
             "requires": {
                 "append-transform": "^2.0.0"
             }
         },
         "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,
             "requires": {
                 "@babel/core": "^7.7.5",
                 "@istanbuljs/schema": "^0.1.2",
                 "istanbul-lib-coverage": "^3.0.0",
                 "semver": "^6.3.0"
             }
         },
         "istanbul-lib-processinfo": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz",
             "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==",
             "dev": true,
             "requires": {
                 "archy": "^1.0.0",
                 "cross-spawn": "^7.0.3",
                 "istanbul-lib-coverage": "^3.2.0",
                 "p-map": "^3.0.0",
                 "rimraf": "^3.0.0",
                 "uuid": "^8.3.2"
             }
         },
         "istanbul-lib-report": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
             "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
             "dev": true,
             "requires": {
                 "istanbul-lib-coverage": "^3.0.0",
                 "make-dir": "^4.0.0",
                 "supports-color": "^7.1.0"
             },
             "dependencies": {
                 "lru-cache": {
                     "version": "6.0.0",
                     "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
                     "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
                     "dev": true,
                     "requires": {
                         "yallist": "^4.0.0"
                     }
                 },
                 "make-dir": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
                     "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
                     "dev": true,
                     "requires": {
                         "semver": "^7.5.3"
                     }
                 },
                 "semver": {
                     "version": "7.5.4",
                     "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
                     "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
                     "dev": true,
                     "requires": {
                         "lru-cache": "^6.0.0"
                     }
                 },
                 "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"
                     }
                 },
                 "yallist": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
                     "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
                     "dev": true
                 }
             }
         },
         "istanbul-lib-source-maps": {
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
             "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
             "dev": true,
             "requires": {
                 "debug": "^4.1.1",
                 "istanbul-lib-coverage": "^3.0.0",
                 "source-map": "^0.6.1"
             }
         },
         "istanbul-reports": {
             "version": "3.1.6",
             "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
             "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
             "dev": true,
             "requires": {
                 "html-escaper": "^2.0.0",
                 "istanbul-lib-report": "^3.0.0"
             }
         },
         "js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
             "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
             "dev": true
         },
         "js-yaml": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
             "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
             "dev": true,
             "requires": {
                 "argparse": "^2.0.1"
             }
         },
         "jsesc": {
             "version": "2.5.2",
             "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
             "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
             "dev": true
         },
         "json5": {
             "version": "2.2.3",
             "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
             "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
             "dev": true
         },
         "locate-path": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
             "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
             "dev": true,
             "requires": {
                 "p-locate": "^5.0.0"
             }
         },
         "lodash.flattendeep": {
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
             "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
             "dev": true
         },
         "log-symbols": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
             "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
             "dev": true,
             "requires": {
                 "chalk": "^4.1.0",
                 "is-unicode-supported": "^0.1.0"
             }
         },
         "lru-cache": {
             "version": "5.1.1",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
             "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
             "dev": true,
             "requires": {
                 "yallist": "^3.0.2"
             }
         },
         "make-dir": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
             "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
             "dev": true,
             "requires": {
                 "semver": "^6.0.0"
             }
         },
         "md5": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
             "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
             "dev": true,
             "requires": {
                 "charenc": "0.0.2",
                 "crypt": "0.0.2",
                 "is-buffer": "~1.1.6"
             }
         },
         "minimatch": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
             "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
             "dev": true,
             "requires": {
                 "brace-expansion": "^2.0.1"
             }
         },
         "mkdirp": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
             "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
             "dev": true
         },
         "mocha": {
             "version": "10.2.0",
             "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
             "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
             "dev": true,
             "requires": {
                 "ansi-colors": "4.1.1",
                 "browser-stdout": "1.3.1",
                 "chokidar": "3.5.3",
                 "debug": "4.3.4",
                 "diff": "5.0.0",
                 "escape-string-regexp": "4.0.0",
                 "find-up": "5.0.0",
                 "glob": "7.2.0",
                 "he": "1.2.0",
                 "js-yaml": "4.1.0",
                 "log-symbols": "4.1.0",
                 "minimatch": "5.0.1",
                 "ms": "2.1.3",
                 "nanoid": "3.3.3",
                 "serialize-javascript": "6.0.0",
                 "strip-json-comments": "3.1.1",
                 "supports-color": "8.1.1",
                 "workerpool": "6.2.1",
                 "yargs": "16.2.0",
                 "yargs-parser": "20.2.4",
                 "yargs-unparser": "2.0.0"
             }
         },
         "mocha-junit-reporter": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.2.1.tgz",
             "integrity": "sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw==",
             "dev": true,
             "requires": {
                 "debug": "^4.3.4",
                 "md5": "^2.3.0",
                 "mkdirp": "^3.0.0",
                 "strip-ansi": "^6.0.1",
                 "xml": "^1.0.1"
             }
         },
         "ms": {
             "version": "2.1.3",
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
             "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
             "dev": true
         },
         "nanoid": {
             "version": "3.3.3",
             "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
             "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
             "dev": true
         },
         "node-preload": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
             "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
             "dev": true,
             "requires": {
                 "process-on-spawn": "^1.0.0"
             }
         },
         "node-releases": {
             "version": "2.0.13",
             "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
             "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
             "dev": true
         },
         "normalize-path": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
             "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
             "dev": true
         },
         "nyc": {
             "version": "15.1.0",
             "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
             "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
             "dev": true,
             "requires": {
                 "@istanbuljs/load-nyc-config": "^1.0.0",
                 "@istanbuljs/schema": "^0.1.2",
                 "caching-transform": "^4.0.0",
                 "convert-source-map": "^1.7.0",
                 "decamelize": "^1.2.0",
                 "find-cache-dir": "^3.2.0",
                 "find-up": "^4.1.0",
                 "foreground-child": "^2.0.0",
                 "get-package-type": "^0.1.0",
                 "glob": "^7.1.6",
                 "istanbul-lib-coverage": "^3.0.0",
                 "istanbul-lib-hook": "^3.0.0",
                 "istanbul-lib-instrument": "^4.0.0",
                 "istanbul-lib-processinfo": "^2.0.2",
                 "istanbul-lib-report": "^3.0.0",
                 "istanbul-lib-source-maps": "^4.0.0",
                 "istanbul-reports": "^3.0.2",
                 "make-dir": "^3.0.0",
                 "node-preload": "^0.2.1",
                 "p-map": "^3.0.0",
                 "process-on-spawn": "^1.0.0",
                 "resolve-from": "^5.0.0",
                 "rimraf": "^3.0.0",
                 "signal-exit": "^3.0.2",
                 "spawn-wrap": "^2.0.0",
                 "test-exclude": "^6.0.0",
                 "yargs": "^15.0.2"
             },
             "dependencies": {
                 "cliui": {
                     "version": "6.0.0",
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
                     "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
                     "dev": true,
                     "requires": {
                         "string-width": "^4.2.0",
                         "strip-ansi": "^6.0.0",
                         "wrap-ansi": "^6.2.0"
                     }
                 },
                 "find-up": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
                     "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
                     "dev": true,
                     "requires": {
                         "locate-path": "^5.0.0",
                         "path-exists": "^4.0.0"
                     }
                 },
                 "locate-path": {
                     "version": "5.0.0",
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
                     "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
                     "dev": true,
                     "requires": {
                         "p-locate": "^4.1.0"
                     }
                 },
                 "p-limit": {
                     "version": "2.3.0",
                     "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
                     "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
                     "dev": true,
                     "requires": {
                         "p-try": "^2.0.0"
                     }
                 },
                 "p-locate": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
                     "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
                     "dev": true,
                     "requires": {
                         "p-limit": "^2.2.0"
                     }
                 },
                 "wrap-ansi": {
                     "version": "6.2.0",
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
                     "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
                     "dev": true,
                     "requires": {
                         "ansi-styles": "^4.0.0",
                         "string-width": "^4.1.0",
                         "strip-ansi": "^6.0.0"
                     }
                 },
                 "y18n": {
                     "version": "4.0.3",
                     "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
                     "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
                     "dev": true
                 },
                 "yargs": {
                     "version": "15.4.1",
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
                     "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
                     "dev": true,
                     "requires": {
                         "cliui": "^6.0.0",
                         "decamelize": "^1.2.0",
                         "find-up": "^4.1.0",
                         "get-caller-file": "^2.0.1",
                         "require-directory": "^2.1.1",
                         "require-main-filename": "^2.0.0",
                         "set-blocking": "^2.0.0",
                         "string-width": "^4.2.0",
                         "which-module": "^2.0.0",
                         "y18n": "^4.0.0",
                         "yargs-parser": "^18.1.2"
                     }
                 },
                 "yargs-parser": {
                     "version": "18.1.3",
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
                     "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
                     "dev": true,
                     "requires": {
                         "camelcase": "^5.0.0",
                         "decamelize": "^1.2.0"
                     }
                 }
             }
         },
         "once": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
             "dev": true,
             "requires": {
                 "wrappy": "1"
             }
         },
         "p-limit": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
             "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
             "dev": true,
             "requires": {
                 "yocto-queue": "^0.1.0"
             }
         },
         "p-locate": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
             "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
             "dev": true,
             "requires": {
                 "p-limit": "^3.0.2"
             }
         },
         "p-map": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
             "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
             "dev": true,
             "requires": {
                 "aggregate-error": "^3.0.0"
             }
         },
         "p-try": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
             "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
             "dev": true
         },
         "package-hash": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
             "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
             "dev": true,
             "requires": {
                 "graceful-fs": "^4.1.15",
                 "hasha": "^5.0.0",
                 "lodash.flattendeep": "^4.4.0",
                 "release-zalgo": "^1.0.0"
             }
         },
         "path-exists": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
             "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
             "dev": true
         },
         "path-is-absolute": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
             "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
             "dev": true
         },
         "path-key": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
             "dev": true
         },
         "picocolors": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
             "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
             "dev": true
         },
         "picomatch": {
             "version": "2.3.1",
             "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
             "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
             "dev": true
         },
         "pkg-dir": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
             "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
             "dev": true,
             "requires": {
                 "find-up": "^4.0.0"
             },
             "dependencies": {
                 "find-up": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
                     "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
                     "dev": true,
                     "requires": {
                         "locate-path": "^5.0.0",
                         "path-exists": "^4.0.0"
                     }
                 },
                 "locate-path": {
                     "version": "5.0.0",
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
                     "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
                     "dev": true,
                     "requires": {
                         "p-locate": "^4.1.0"
                     }
                 },
                 "p-limit": {
                     "version": "2.3.0",
                     "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
                     "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
                     "dev": true,
                     "requires": {
                         "p-try": "^2.0.0"
                     }
                 },
                 "p-locate": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
                     "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
                     "dev": true,
                     "requires": {
                         "p-limit": "^2.2.0"
                     }
                 }
             }
         },
         "process-on-spawn": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
             "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
             "dev": true,
             "requires": {
                 "fromentries": "^1.2.0"
             }
         },
         "randombytes": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
             "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
             "dev": true,
             "requires": {
                 "safe-buffer": "^5.1.0"
             }
         },
         "readdirp": {
             "version": "3.6.0",
             "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
             "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
             "dev": true,
             "requires": {
                 "picomatch": "^2.2.1"
             }
         },
         "release-zalgo": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
             "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==",
             "dev": true,
             "requires": {
                 "es6-error": "^4.0.1"
             }
         },
         "require-directory": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
             "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
             "dev": true
         },
         "require-main-filename": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
             "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
             "dev": true
         },
         "resolve-from": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
             "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
             "dev": true
         },
         "rimraf": {
             "version": "3.0.2",
             "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
             "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
             "dev": true,
             "requires": {
                 "glob": "^7.1.3"
             }
         },
         "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==",
             "dev": true
         },
         "semver": {
             "version": "6.3.1",
             "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
             "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true
         },
         "serialize-javascript": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
             "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
             "dev": true,
             "requires": {
                 "randombytes": "^2.1.0"
             }
         },
         "set-blocking": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
             "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
             "dev": true
         },
         "shebang-command": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
             "dev": true,
             "requires": {
                 "shebang-regex": "^3.0.0"
             }
         },
         "shebang-regex": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
             "dev": true
         },
         "signal-exit": {
             "version": "3.0.7",
             "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
             "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
             "dev": true
         },
         "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
         },
         "spawn-wrap": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
             "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
             "dev": true,
             "requires": {
                 "foreground-child": "^2.0.0",
                 "is-windows": "^1.0.2",
                 "make-dir": "^3.0.0",
                 "rimraf": "^3.0.0",
                 "signal-exit": "^3.0.2",
                 "which": "^2.0.1"
             }
         },
         "sprintf-js": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
             "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
             "dev": true
         },
         "string-width": {
             "version": "4.2.3",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
             "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
             "dev": true,
             "requires": {
                 "emoji-regex": "^8.0.0",
                 "is-fullwidth-code-point": "^3.0.0",
                 "strip-ansi": "^6.0.1"
             }
         },
         "strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
             "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
             "dev": true,
             "requires": {
                 "ansi-regex": "^5.0.1"
             }
         },
         "strip-bom": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
             "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
             "dev": true
         },
         "strip-json-comments": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
             "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
             "dev": true
         },
         "supports-color": {
             "version": "8.1.1",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
             "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
             "dev": true,
             "requires": {
                 "has-flag": "^4.0.0"
             }
         },
         "test-exclude": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
             "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
             "dev": true,
             "requires": {
                 "@istanbuljs/schema": "^0.1.2",
                 "glob": "^7.1.4",
                 "minimatch": "^3.0.4"
             },
             "dependencies": {
                 "brace-expansion": {
                     "version": "1.1.11",
                     "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
                     "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
                     "dev": true,
                     "requires": {
                         "balanced-match": "^1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
                 "minimatch": {
                     "version": "3.1.2",
                     "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
                     "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
                     "dev": true,
                     "requires": {
                         "brace-expansion": "^1.1.7"
                     }
                 }
             }
         },
         "to-fast-properties": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
             "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
             "dev": true
         },
         "to-regex-range": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
             "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
             "dev": true,
             "requires": {
                 "is-number": "^7.0.0"
             }
         },
         "type-fest": {
             "version": "0.8.1",
             "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
             "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
             "dev": true
         },
         "typedarray-to-buffer": {
             "version": "3.1.5",
             "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
             "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
             "dev": true,
             "requires": {
                 "is-typedarray": "^1.0.0"
             }
         },
         "update-browserslist-db": {
             "version": "1.0.11",
             "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
             "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
             "dev": true,
             "requires": {
                 "escalade": "^3.1.1",
                 "picocolors": "^1.0.0"
             }
         },
         "uuid": {
             "version": "8.3.2",
             "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
             "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
             "dev": true
         },
         "which": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
             "dev": true,
             "requires": {
                 "isexe": "^2.0.0"
             }
         },
         "which-module": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
             "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
             "dev": true
         },
         "workerpool": {
             "version": "6.2.1",
             "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
             "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
             "dev": 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==",
             "dev": true,
             "requires": {
                 "ansi-styles": "^4.0.0",
                 "string-width": "^4.1.0",
                 "strip-ansi": "^6.0.0"
             }
         },
         "wrappy": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
             "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
             "dev": true
         },
         "write-file-atomic": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
             "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
             "dev": true,
             "requires": {
                 "imurmurhash": "^0.1.4",
                 "is-typedarray": "^1.0.0",
                 "signal-exit": "^3.0.2",
                 "typedarray-to-buffer": "^3.1.5"
             }
         },
         "xml": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
             "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
             "dev": true
         },
         "y18n": {
             "version": "5.0.8",
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
             "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
             "dev": true
         },
         "yallist": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
             "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
             "dev": true
         },
         "yargs": {
             "version": "16.2.0",
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
             "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
             "dev": true,
             "requires": {
                 "cliui": "^7.0.2",
                 "escalade": "^3.1.1",
                 "get-caller-file": "^2.0.5",
                 "require-directory": "^2.1.1",
                 "string-width": "^4.2.0",
                 "y18n": "^5.0.5",
                 "yargs-parser": "^20.2.2"
             }
         },
         "yargs-parser": {
             "version": "20.2.4",
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
             "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
             "dev": true
         },
         "yargs-unparser": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
             "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
             "dev": true,
             "requires": {
                 "camelcase": "^6.0.0",
                 "decamelize": "^4.0.0",
                 "flat": "^5.0.2",
                 "is-plain-obj": "^2.1.0"
             },
             "dependencies": {
                 "camelcase": {
                     "version": "6.3.0",
                     "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
                     "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
                     "dev": true
                 },
                 "decamelize": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
                     "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
                     "dev": true
                 }
             }
         },
         "yocto-queue": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
             "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
             "dev": true
         }
     }
 }
diff --git a/modules/mock-chronik-client/package.json b/modules/mock-chronik-client/package.json
index d48c4d2f8..49224ec4f 100644
--- a/modules/mock-chronik-client/package.json
+++ b/modules/mock-chronik-client/package.json
@@ -1,32 +1,32 @@
 {
     "dependencies": {
         "ecashaddrjs": "file:../ecashaddrjs"
     },
     "name": "mock-chronik-client",
     "description": "Testing utility to mock the Chronik indexer client and support unit tests that need to mock chronik related API calls.",
-    "version": "1.12.2",
+    "version": "1.12.3",
     "main": "index.js",
     "devDependencies": {
         "mocha": "^10.2.0",
         "mocha-junit-reporter": "^2.2.1",
         "nyc": "^15.1.0"
     },
     "scripts": {
         "test": "mocha",
         "coverage": "nyc mocha",
         "junit": "mocha test --reporter mocha-junit-reporter"
     },
     "repository": {
         "type": "git",
         "url": "git+https://github.com/Bitcoin-ABC/bitcoin-abc.git",
         "directory": "modules/mock-chronik-client"
     },
     "keywords": [
         "chronik-client",
         "chronik",
         "mock"
     ],
     "author": "Bitcoin ABC",
     "license": "MIT",
     "homepage": "https://github.com/Bitcoin-ABC/bitcoin-abc#readme"
 }