diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cfa0d5e2..61ad49d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,7 +57,7 @@ jobs: strategy: matrix: os: ['ubuntu-latest'] - keria-version: ['0.1.3'] + keria-version: ['0.2.0-dev3'] node-version: ['20'] env: KERIA_IMAGE_TAG: ${{ matrix.keria-version }} diff --git a/docker-compose.yaml b/docker-compose.yaml index 50607343..25d0dd40 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,7 +26,7 @@ services: - 7723:7723 keria: - image: ${KERIA_IMAGE:-weboftrust/keria}:${KERIA_IMAGE_TAG:-0.1.3} + image: ${KERIA_IMAGE:-weboftrust/keria}:${KERIA_IMAGE_TAG:-0.2.0-dev3} environment: - KERI_AGENT_CORS=1 - KERI_URL=http://keria:3902 @@ -34,17 +34,19 @@ services: - PYTHONIOENCODING=UTF-8 volumes: - ./config/keria.json:/keria/config/keri/cf/keria.json - entrypoint: keria - command: - - start - - --config-dir - - /keria/config - - --config-file - - keria - - --name - - agent + entrypoint: + [ + 'keria', + 'start', + '--config-dir', + '/keria/config', + '--config-file', + 'keria', + '--name', + 'agent', + ] healthcheck: - test: ['CMD', 'curl', '-f', 'http://localhost:3902/spec.yaml'] + test: ['CMD', 'wget', '--spider', 'http://keria:3902/spec.yaml'] interval: 2s timeout: 3s retries: 5 diff --git a/examples/integration-scripts/challenge.test.ts b/examples/integration-scripts/challenge.test.ts index 94c57f5e..0f8d1217 100644 --- a/examples/integration-scripts/challenge.test.ts +++ b/examples/integration-scripts/challenge.test.ts @@ -63,7 +63,7 @@ test('challenge', async () => { client1, await icpResult1.op() ); - let rpyResult1 = await client1 + const rpyResult1 = await client1 .identifiers() .addEndRole('alice', 'agent', client1!.agent!.pre); await waitOperation(client1, await rpyResult1.op()); @@ -81,7 +81,7 @@ test('challenge', async () => { client2, await icpResult2.op() ); - let rpyResult2 = await client2 + const rpyResult2 = await client2 .identifiers() .addEndRole('bob', 'agent', client2!.agent!.pre); await waitOperation(client2, await rpyResult2.op()); diff --git a/examples/integration-scripts/credentials.test.ts b/examples/integration-scripts/credentials.test.ts index 0bdbacfe..4f87c6ce 100644 --- a/examples/integration-scripts/credentials.test.ts +++ b/examples/integration-scripts/credentials.test.ts @@ -4,17 +4,15 @@ import { resolveEnvironment } from './utils/resolve-env'; import { assertNotifications, assertOperations, + createAid, + getOrCreateClients, + getOrCreateContact, markAndRemoveNotification, resolveOobi, waitForNotifications, waitOperation, } from './utils/test-util'; import { retry } from './utils/retry'; -import { - getOrCreateClients, - getOrCreateContact, - getOrCreateIdentifier, -} from './utils/test-setup'; import { randomUUID } from 'crypto'; import { step } from './utils/test-step'; @@ -36,11 +34,6 @@ function createTimestamp() { return new Date().toISOString().replace('Z', '000+00:00'); } -async function createAid(client: SignifyClient, name: string): Promise { - const [prefix, oobi] = await getOrCreateIdentifier(client, name); - return { prefix, oobi, name }; -} - let issuerClient: SignifyClient; let holderClient: SignifyClient; let verifierClient: SignifyClient; @@ -125,7 +118,7 @@ test('single signature credentials', async () => { .rename(issuerAid.name, registryName, updatedRegistryName); registries = await issuerClient.registries().list(issuerAid.name); - let updateRegistry: { name: string; regk: string } = registries[0]; + const updateRegistry: { name: string; regk: string } = registries[0]; assert.equal(registries.length, 1); assert.equal(updateRegistry.name, updatedRegistryName); @@ -243,7 +236,7 @@ test('single signature credentials', async () => { datetime: dt, }); - let op = await issuerClient + const op = await issuerClient .ipex() .submitGrant(issuerAid.name, grant, gsigs, gend, [ holderAid.prefix, @@ -266,7 +259,7 @@ test('single signature credentials', async () => { grantNotification.a.d!, createTimestamp() ); - let op = await holderClient + const op = await holderClient .ipex() .submitAdmit(holderAid.name, admit, sigs, aend, [issuerAid.prefix]); await waitOperation(holderClient, op); @@ -313,7 +306,7 @@ test('single signature credentials', async () => { datetime: createTimestamp(), }); - let op = await holderClient + const op = await holderClient .ipex() .submitGrant(holderAid.name, grant2, gsigs2, gend2, [ verifierAid.prefix, @@ -338,7 +331,7 @@ test('single signature credentials', async () => { createTimestamp() ); - let op = await verifierClient + const op = await verifierClient .ipex() .submitAdmit(verifierAid.name, admit3, sigs3, aend3, [ holderAid.prefix, @@ -437,7 +430,7 @@ test('single signature credentials', async () => { datetime: dt, }); - let op = await holderClient + const op = await holderClient .ipex() .submitGrant(holderAid.name, grant, gsigs, gend, [ legalEntityAid.prefix, @@ -461,7 +454,7 @@ test('single signature credentials', async () => { createTimestamp() ); - let op = await legalEntityClient + const op = await legalEntityClient .ipex() .submitAdmit(legalEntityAid.name, admit, sigs, aend, [ holderAid.prefix, diff --git a/examples/integration-scripts/delegation-multisig.test.ts b/examples/integration-scripts/delegation-multisig.test.ts index 103aacfa..60d89445 100644 --- a/examples/integration-scripts/delegation-multisig.test.ts +++ b/examples/integration-scripts/delegation-multisig.test.ts @@ -3,115 +3,337 @@ import signify from 'signify-ts'; import { assertNotifications, assertOperations, + createAID, + createTimestamp, + getOrCreateClient, + getOrCreateContact, markAndRemoveNotification, resolveOobi, + waitAndMarkNotification, waitForNotifications, waitOperation, - warnNotifications, } from './utils/test-util'; -import { getOrCreateClient, getOrCreateIdentifier } from './utils/test-setup'; import { acceptMultisigIncept, + addEndRoleMultisig, + delegateMultisig, startMultisigIncept, } from './utils/multisig-utils'; +import { step } from './utils/test-step'; + +const delegatorGroupName = 'delegator_group'; +const delegateeGroupName = 'delegatee_group'; +const delegator1Name = 'delegator1'; +const delegator2Name = 'delegator2'; +const delegatee1Name = 'delegatee1'; +const delegatee2Name = 'delegatee2'; test('delegation-multisig', async () => { await signify.ready(); // Boot three clients - const [client0, client1, client2] = await Promise.all([ - getOrCreateClient(), - getOrCreateClient(), - getOrCreateClient(), - ]); + const [ + delegator1Client, + delegator2Client, + delegatee1Client, + delegatee2Client, + ] = await step('Creating single sig clients', async () => { + return await Promise.all([ + getOrCreateClient(), + getOrCreateClient(), + getOrCreateClient(), + getOrCreateClient(), + ]); + }); - // Create four identifiers, one for each client - const [aid0, aid1, aid2] = await Promise.all([ - createAID(client0, 'delegator'), - createAID(client1, 'member1'), - createAID(client2, 'member2'), - ]); + // Create delegator and delegatee identifiers clients + const [delegator1Aid, delegator2Aid, delegatee1Aid, delegatee2Aid] = + await step('Creating single sig aids', async () => { + return await Promise.all([ + createAID(delegator1Client, delegator1Name), + createAID(delegator2Client, delegator2Name), + createAID(delegatee1Client, delegatee1Name), + createAID(delegatee2Client, delegatee2Name), + ]); + }); // Exchange OOBIs - console.log('Resolving OOBIs'); - const oobi0 = await client0.oobis().get('delegator', 'agent'); - const oobi1 = await client1.oobis().get('member1', 'agent'); - const oobi2 = await client2.oobis().get('member2', 'agent'); + const [delegator1Oobi, delegator2Oobi, delegatee1Oobi, delegatee2Oobi] = + await step('Getting OOBIs before resolving...', async () => { + return await Promise.all([ + await delegator1Client.oobis().get(delegator1Name, 'agent'), + await delegator2Client.oobis().get(delegator2Name, 'agent'), + await delegatee1Client.oobis().get(delegatee1Name, 'agent'), + await delegatee2Client.oobis().get(delegatee2Name, 'agent'), + ]); + }); + + await step('Resolving OOBIs', async () => { + await Promise.all([ + resolveOobi( + delegator1Client, + delegator2Oobi.oobis[0], + delegator2Name + ), + resolveOobi( + delegator2Client, + delegator1Oobi.oobis[0], + delegator1Name + ), + resolveOobi( + delegatee1Client, + delegatee2Oobi.oobis[0], + delegatee2Name + ), + resolveOobi( + delegatee2Client, + delegatee1Oobi.oobis[0], + delegatee1Name + ), + ]); + }); + console.log( + `${delegator1Name}(${delegator1Aid.prefix}) and ${delegatee1Name}(${delegatee1Aid.prefix}) resolved ${delegator2Name}(${delegator2Aid.prefix}) and ${delegatee2Name}(${delegatee2Aid.prefix}) OOBIs and vice versa` + ); + + // First member start the creation of a multisig identifier + // Create a multisig AID for the GEDA. + // Skip if a GEDA AID has already been incepted. + const otor1 = await step( + `${delegator1Name}(${delegator1Aid.prefix}) initiated delegator multisig, waiting for ${delegator2Name}(${delegator2Aid.prefix}) to join...`, + async () => { + return await startMultisigIncept(delegator1Client, { + groupName: delegatorGroupName, + localMemberName: delegator1Aid.name, + participants: [delegator1Aid.prefix, delegator2Aid.prefix], + isith: 2, + nsith: 2, + toad: 2, + wits: [ + 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', + 'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM', + 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', + ], + }); + } + ); + const [ntor] = await waitForNotifications( + delegator2Client, + '/multisig/icp', + { + maxSleep: 10000, + minSleep: 1000, + maxRetries: undefined, + timeout: 30000, + } + ); + await markAndRemoveNotification(delegator2Client, ntor); + assert(ntor.a.d); + const otor2 = await acceptMultisigIncept(delegator2Client, { + localMemberName: delegator2Aid.name, + groupName: delegatorGroupName, + msgSaid: ntor.a.d, + }); + + const torpre = otor1.name.split('.')[1]; await Promise.all([ - resolveOobi(client1, oobi0.oobis[0], 'delegator'), - resolveOobi(client1, oobi2.oobis[0], 'member2'), - resolveOobi(client2, oobi0.oobis[0], 'delegator'), - resolveOobi(client2, oobi1.oobis[0], 'member1'), + waitOperation(delegator1Client, otor1), + waitOperation(delegator2Client, otor2), ]); - console.log('Member1 and Member2 resolved 2 OOBIs'); + const adelegatorGroupName1 = await delegator1Client + .identifiers() + .get(delegatorGroupName); + const adelegatorGroupName2 = await delegator2Client + .identifiers() + .get(delegatorGroupName); - // First member start the creation of a multisig identifier - const op1 = await startMultisigIncept(client1, { - groupName: 'multisig', - localMemberName: aid1.name, - participants: [aid1.prefix, aid2.prefix], - isith: 2, - nsith: 2, - toad: 2, - delpre: aid0.prefix, - wits: [ - 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', - 'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM', - 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', - ], - }); - console.log('Member1 initiated multisig, waiting for others to join...'); - - // Second member check notifications and join the multisig - const [notification] = await waitForNotifications(client2, '/multisig/icp'); - await markAndRemoveNotification(client2, notification); - assert(notification.a.d); - const op2 = await acceptMultisigIncept(client2, { - localMemberName: aid2.name, - groupName: 'multisig', - msgSaid: notification.a.d, - }); + assert.equal(adelegatorGroupName1.prefix, adelegatorGroupName2.prefix); + assert.equal(adelegatorGroupName1.name, adelegatorGroupName2.name); + const adelegatorGroupName = adelegatorGroupName1; + + //Resolve delegator OOBI + const delegatorGroupNameOobi = await step( + `Add and resolve delegator OOBI ${delegatorGroupName}(${adelegatorGroupName.prefix})`, + async () => { + const timestamp = createTimestamp(); + const opList1 = await addEndRoleMultisig( + delegator1Client, + delegatorGroupName, + delegator1Aid, + [delegator2Aid], + adelegatorGroupName, + timestamp, + true + ); + const opList2 = await addEndRoleMultisig( + delegator2Client, + delegatorGroupName, + delegator2Aid, + [delegator1Aid], + adelegatorGroupName, + timestamp + ); - console.log('Member2 joined multisig, waiting for delegator...'); + await Promise.all( + opList1.map((op) => waitOperation(delegator1Client, op)) + ); + await Promise.all( + opList2.map((op) => waitOperation(delegator2Client, op)) + ); - const delegatePrefix = op1.name.split('.')[1]; - assert.equal(op2.name.split('.')[1], delegatePrefix); - console.log("Delegate's prefix:", delegatePrefix); - console.log('Delegate waiting for approval...'); + await waitAndMarkNotification(delegator1Client, '/multisig/rpy'); + await waitAndMarkNotification(delegator2Client, '/multisig/rpy'); - // Client 0 approves delegation - const anchor = { - i: delegatePrefix, - s: '0', - d: delegatePrefix, - }; - const ixnResult = await client0.identifiers().interact('delegator', anchor); - await waitOperation(client0, await ixnResult.op()); - console.log('Delegator approved delegation'); + const [odelegatorGroupName1, odelegatorGroupName2] = + await Promise.all([ + delegator1Client + .oobis() + .get(adelegatorGroupName.name, 'agent'), + delegator2Client + .oobis() + .get(adelegatorGroupName.name, 'agent'), + ]); - const op3 = await client1.keyStates().query(aid0.prefix, '1'); - const op4 = await client2.keyStates().query(aid0.prefix, '1'); + assert.equal(odelegatorGroupName1.role, odelegatorGroupName2.role); + assert.equal( + odelegatorGroupName1.oobis[0], + odelegatorGroupName2.oobis[0] + ); - // Check for completion + return odelegatorGroupName1.oobis[0]; + } + ); + + const oobiGtor = delegatorGroupNameOobi.split('/agent/')[0]; await Promise.all([ - waitOperation(client1, op1), - waitOperation(client2, op2), - waitOperation(client1, op3), - waitOperation(client2, op4), + getOrCreateContact( + delegatee1Client, + adelegatorGroupName.name, + oobiGtor + ), + getOrCreateContact( + delegatee2Client, + adelegatorGroupName.name, + oobiGtor + ), ]); - console.log('Delegated multisig created!'); - const aid_delegate = await client1.identifiers().get('multisig'); - assert.equal(aid_delegate.prefix, delegatePrefix); + const opDelegatee1 = await step( + `${delegatee1Name}(${delegatee1Aid.prefix}) initiated delegatee multisig, waiting for ${delegatee2Name}(${delegatee2Aid.prefix}) to join...`, + async () => { + return await startMultisigIncept(delegatee1Client, { + groupName: delegateeGroupName, + localMemberName: delegatee1Aid.name, + participants: [delegatee1Aid.prefix, delegatee2Aid.prefix], + isith: 2, + nsith: 2, + toad: 2, + delpre: torpre, + wits: [ + 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', + 'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM', + 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', + ], + }); + } + ); + + // Second member of delegatee check notifications and join the multisig + const [ntee] = await waitForNotifications( + delegatee2Client, + '/multisig/icp' + ); + await markAndRemoveNotification(delegatee2Client, ntee); + assert(ntee.a.d); + + const opDelegatee2 = await acceptMultisigIncept(delegatee2Client, { + localMemberName: delegatee2Aid.name, + groupName: delegateeGroupName, + msgSaid: ntee.a.d, + }); + + console.log(`${delegatee2Name} joined multisig, waiting for delegator...`); + + const agtee1 = await delegatee1Client.identifiers().get(delegateeGroupName); + const agtee2 = await delegatee2Client.identifiers().get(delegateeGroupName); + + assert.equal(agtee1.prefix, agtee2.prefix); + assert.equal(agtee1.name, agtee2.name); + + const teepre = opDelegatee1.name.split('.')[1]; + assert.equal(opDelegatee2.name.split('.')[1], teepre); + console.log('Delegatee prefix:', teepre); + + await step('delegator anchors/approves delegation', async () => { + // GEDA anchors delegation with an interaction event. + const anchor = { + i: teepre, + s: '0', + d: teepre, + }; + const delApprOp1 = await delegateMultisig( + delegator1Client, + delegator1Aid, + [delegator2Aid], + adelegatorGroupName, + anchor, + true + ); + const delApprOp2 = await delegateMultisig( + delegator2Client, + delegator2Aid, + [delegator1Aid], + adelegatorGroupName, + anchor + ); + const [dresult1, dresult2] = await Promise.all([ + waitOperation(delegator1Client, delApprOp1), + waitOperation(delegator2Client, delApprOp2), + ]); + + assert.equal(dresult1.response, dresult2.response); + + await waitAndMarkNotification(delegator1Client, '/multisig/ixn'); + }); + + const queryOp1 = await delegator1Client + .keyStates() + .query(adelegatorGroupName.prefix, '1'); + const queryOp2 = await delegator2Client + .keyStates() + .query(adelegatorGroupName.prefix, '1'); + + const kstor1 = await waitOperation(delegator1Client, queryOp1); + const kstor2 = await waitOperation(delegator2Client, queryOp2); + + // QARs query the GEDA's key state + const ksteetor1 = await delegatee1Client + .keyStates() + .query(adelegatorGroupName.prefix, '1'); + const ksteetor2 = await delegatee2Client + .keyStates() + .query(adelegatorGroupName.prefix, '1'); + const teeTor1 = await waitOperation(delegatee1Client, ksteetor1); + const teeTor2 = await waitOperation(delegatee2Client, ksteetor2); + + const teeDone1 = await waitOperation(delegatee1Client, opDelegatee1); + const teeDone2 = await waitOperation(delegatee2Client, opDelegatee2); + console.log('Delegated multisig created!'); - await assertOperations(client0, client1, client2); - await assertNotifications(client0, client1, client2); -}, 30000); + const agtee = await delegatee1Client.identifiers().get(delegateeGroupName); + assert.equal(agtee.prefix, teepre); -async function createAID(client: signify.SignifyClient, name: string) { - await getOrCreateIdentifier(client, name); - const aid = await client.identifiers().get(name); - console.log(name, 'AID:', aid.prefix); - return aid; -} + await assertOperations( + delegator1Client, + delegator2Client, + delegatee1Client, + delegatee2Client + ); + await assertNotifications( + delegator1Client, + delegator2Client, + delegatee1Client, + delegatee2Client + ); +}, 600000); diff --git a/examples/integration-scripts/delegation.test.ts b/examples/integration-scripts/delegation.test.ts index d07b59f5..529b82c5 100644 --- a/examples/integration-scripts/delegation.test.ts +++ b/examples/integration-scripts/delegation.test.ts @@ -3,9 +3,12 @@ import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env'; import { assertOperations, + getOrCreateContact, resolveOobi, waitOperation, } from './utils/test-util'; +import { retry } from './utils/retry'; +import { step } from './utils/test-step'; const { url, bootUrl } = resolveEnvironment(); @@ -55,12 +58,12 @@ test('delegation', async () => { ], }); await waitOperation(client1, await icpResult1.op()); - const aid1 = await client1.identifiers().get('delegator'); + const ator = await client1.identifiers().get('delegator'); const rpyResult1 = await client1 .identifiers() .addEndRole('delegator', 'agent', client1!.agent!.pre); await waitOperation(client1, await rpyResult1.op()); - console.log("Delegator's AID:", aid1.prefix); + console.log("Delegator's AID:", ator.prefix); // Client 2 resolves delegator OOBI console.log('Client 2 resolving delegator OOBI'); @@ -71,25 +74,35 @@ test('delegation', async () => { // Client 2 creates delegate AID const icpResult2 = await client2 .identifiers() - .create('delegate', { delpre: aid1.prefix }); + .create('delegate', { delpre: ator.prefix }); const op2 = await icpResult2.op(); const delegatePrefix = op2.name.split('.')[1]; console.log("Delegate's prefix:", delegatePrefix); console.log('Delegate waiting for approval...'); - // Client 1 approves deletation + // Client 1 approves delegation const anchor = { i: delegatePrefix, s: '0', d: delegatePrefix, }; - const ixnResult1 = await client1 - .identifiers() - .interact('delegator', anchor); - await waitOperation(client1, await ixnResult1.op()); - console.log('Delegator approved delegation'); - let op3 = await client2.keyStates().query(aid1.prefix, '1'); + await step('delegator approves delegation', async () => { + const result = await retry(async () => { + const apprDelRes = await client1 + .delegations() + .approve('delegator', anchor); + await waitOperation(client1, await apprDelRes.op()); + console.log('Delegator approve delegation submitted'); + return apprDelRes; + }); + assert.equal( + JSON.stringify(result.serder.ked.a[0]), + JSON.stringify(anchor) + ); + }); + + const op3 = await client2.keyStates().query(ator.prefix, '1'); await waitOperation(client2, op3); // Client 2 check approval @@ -99,4 +112,17 @@ test('delegation', async () => { console.log('Delegation approved for aid:', aid2.prefix); await assertOperations(client1, client2); -}, 60000); + const rpyResult2 = await client2 + .identifiers() + .addEndRole('delegate', 'agent', client2!.agent!.pre); + await waitOperation(client2, await rpyResult2.op()); + const oobis = await client2.oobis().get('delegate'); + + console.log(oobis); + await getOrCreateContact( + client1, + 'delegate', + oobis.oobis[0].split('/agent/')[0] + ); + // console.log(res); +}, 600000); diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts index b5e26879..93162e54 100644 --- a/examples/integration-scripts/multisig-holder.test.ts +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -3,12 +3,12 @@ import signify, { SignifyClient, Operation, CredentialData } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env'; import { assertOperations, - markNotification, - waitForNotifications, + getOrCreateClient, + getOrCreateIdentifier, + waitAndMarkNotification, waitOperation, warnNotifications, } from './utils/test-util'; -import { getOrCreateClient, getOrCreateIdentifier } from './utils/test-setup'; import { acceptMultisigIncept, startMultisigIncept, @@ -136,7 +136,7 @@ test('multisig', async function run() { console.log(`Starting multisig end role authorization for agent ${eid1}`); - let stamp = createTimestamp(); + const stamp = createTimestamp(); let endRoleRes = await client1 .identifiers() @@ -434,18 +434,6 @@ test('multisig', async function run() { await warnNotifications(client1, client2, client3); }, 360000); -async function waitAndMarkNotification(client: SignifyClient, route: string) { - const notes = await waitForNotifications(client, route); - - await Promise.all( - notes.map(async (note) => { - await markNotification(client, note); - }) - ); - - return notes[notes.length - 1]?.a.d ?? ''; -} - async function createAID(client: SignifyClient, name: string, wits: string[]) { await getOrCreateIdentifier(client, name); const aid = await client.identifiers().get(name); diff --git a/examples/integration-scripts/multisig-inception.test.ts b/examples/integration-scripts/multisig-inception.test.ts index 16aa72c9..d4b4b312 100644 --- a/examples/integration-scripts/multisig-inception.test.ts +++ b/examples/integration-scripts/multisig-inception.test.ts @@ -1,10 +1,11 @@ import signify from 'signify-ts'; import { + getOrCreateClient, + getOrCreateIdentifier, resolveOobi, waitForNotifications, waitOperation, } from './utils/test-util'; -import { getOrCreateClient, getOrCreateIdentifier } from './utils/test-setup'; import { acceptMultisigIncept, startMultisigIncept, diff --git a/examples/integration-scripts/multisig-vlei-issuance.test.ts b/examples/integration-scripts/multisig-vlei-issuance.test.ts index 3e1daeb7..7a72aadd 100644 --- a/examples/integration-scripts/multisig-vlei-issuance.test.ts +++ b/examples/integration-scripts/multisig-vlei-issuance.test.ts @@ -1,12 +1,9 @@ import { strict as assert } from 'assert'; import signify, { - SignifyClient, Saider, - Serder, CredentialSubject, CredentialData, CreateIdentiferArgs, - EventResult, randomNonce, Salter, HabState, @@ -15,9 +12,25 @@ import { resolveEnvironment } from './utils/resolve-env'; import { resolveOobi, waitOperation, - waitForNotifications, + getOrCreateAID, + getOrCreateClients, + getOrCreateContact, + createTimestamp, + getIssuedCredential, + getReceivedCredential, + waitForCredential, + admitSinglesig, + waitAndMarkNotification, } from './utils/test-util'; -import { getOrCreateClients, getOrCreateContact } from './utils/test-setup'; +import { + addEndRoleMultisig, + admitMultisig, + createAIDMultisig, + createRegistryMultisig, + delegateMultisig, + grantMultisig, + issueCredentialMultisig, +} from './utils/multisig-utils'; const { vleiServerUrl, witnessIds } = resolveEnvironment(); @@ -245,6 +258,7 @@ test('multisig-vlei-issuance', async function run() { const timestamp = createTimestamp(); const opList1 = await addEndRoleMultisig( clientGAR1, + aidGEDA.name, aidGAR1, [aidGAR2], aidGEDA, @@ -253,6 +267,7 @@ test('multisig-vlei-issuance', async function run() { ); const opList2 = await addEndRoleMultisig( clientGAR2, + aidGEDA.name, aidGAR2, [aidGAR1], aidGEDA, @@ -342,7 +357,7 @@ test('multisig-vlei-issuance', async function run() { s: '0', d: aidQVIPrefix, }; - const ixnOp1 = await interactMultisig( + const ixnOp1 = await delegateMultisig( clientGAR1, aidGAR1, [aidGAR2], @@ -350,7 +365,7 @@ test('multisig-vlei-issuance', async function run() { anchor, true ); - const ixnOp2 = await interactMultisig( + const ixnOp2 = await delegateMultisig( clientGAR2, aidGAR2, [aidGAR1], @@ -411,6 +426,7 @@ test('multisig-vlei-issuance', async function run() { const timestamp = createTimestamp(); const opList1 = await addEndRoleMultisig( clientQAR1, + aidQVI.name, aidQAR1, [aidQAR2, aidQAR3], aidQVI, @@ -419,6 +435,7 @@ test('multisig-vlei-issuance', async function run() { ); const opList2 = await addEndRoleMultisig( clientQAR2, + aidQVI.name, aidQAR2, [aidQAR1, aidQAR3], aidQVI, @@ -426,6 +443,7 @@ test('multisig-vlei-issuance', async function run() { ); const opList3 = await addEndRoleMultisig( clientQAR3, + aidQVI.name, aidQAR3, [aidQAR1, aidQAR2], aidQVI, @@ -728,6 +746,7 @@ test('multisig-vlei-issuance', async function run() { const timestamp = createTimestamp(); const opList1 = await addEndRoleMultisig( clientLAR1, + aidLE.name, aidLAR1, [aidLAR2, aidLAR3], aidLE, @@ -736,6 +755,7 @@ test('multisig-vlei-issuance', async function run() { ); const opList2 = await addEndRoleMultisig( clientLAR2, + aidLE.name, aidLAR2, [aidLAR1, aidLAR3], aidLE, @@ -743,6 +763,7 @@ test('multisig-vlei-issuance', async function run() { ); const opList3 = await addEndRoleMultisig( clientLAR3, + aidLE.name, aidLAR3, [aidLAR1, aidLAR2], aidLE, @@ -1226,7 +1247,7 @@ test('multisig-vlei-issuance', async function run() { // Skip if ECR Person has already received the credential. let ecrCredbyECR = await getReceivedCredential(clientECR, ecrCred.sad.d); if (!ecrCredbyECR) { - await admitSinglesig(clientECR, aidECR, aidLE); + await admitSinglesig(clientECR, aidECR.name, aidLE); await waitAndMarkNotification(clientLAR1, '/exn/ipex/admit'); await waitAndMarkNotification(clientLAR2, '/exn/ipex/admit'); await waitAndMarkNotification(clientLAR3, '/exn/ipex/admit'); @@ -1235,436 +1256,3 @@ test('multisig-vlei-issuance', async function run() { } assert.equal(ecrCred.sad.d, ecrCredbyECR.sad.d); }, 360000); - -function createTimestamp() { - return new Date().toISOString().replace('Z', '000+00:00'); -} - -async function getOrCreateAID( - client: SignifyClient, - name: string, - kargs: CreateIdentiferArgs -): Promise { - try { - return await client.identifiers().get(name); - } catch { - const result: EventResult = await client - .identifiers() - .create(name, kargs); - - await waitOperation(client, await result.op()); - const aid = await client.identifiers().get(name); - - const op = await client - .identifiers() - .addEndRole(name, 'agent', client!.agent!.pre); - await waitOperation(client, await op.op()); - console.log(name, 'AID:', aid.prefix); - return aid; - } -} - -async function createAIDMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - groupName: string, - kargs: CreateIdentiferArgs, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/icp'); - - const icpResult = await client.identifiers().create(groupName, kargs); - const op = await icpResult.op(); - - const serder = icpResult.serder; - const sigs = icpResult.sigs; - const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(serder, sigers)); - const atc = ims.substring(serder.size); - const embeds = { - icp: [serder, atc], - }; - const smids = kargs.states?.map((state) => state['i']); - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/icp', - { gid: serder.pre, smids: smids, rmids: smids }, - embeds, - recp - ); - - return op; -} - -async function interactMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAID: HabState, - anchor: { i: string; s: string; d: string }, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/ixn'); - - const ixnResult = await client - .identifiers() - .interact(multisigAID.name, anchor); - const op = await ixnResult.op(); - const serder = ixnResult.serder; - const sigs = ixnResult.sigs; - const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(serder, sigers)); - const atc = ims.substring(serder.size); - const xembeds = { - ixn: [serder, atc], - }; - const smids = [aid.prefix, ...otherMembersAIDs.map((aid) => aid.prefix)]; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/ixn', - { gid: serder.pre, smids: smids, rmids: smids }, - xembeds, - recp - ); - - return op; -} - -async function addEndRoleMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAID: HabState, - timestamp: string, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/rpy'); - - const opList: any[] = []; - const members = await client.identifiers().members(multisigAID.name); - const signings = members['signing']; - - for (const signing of signings) { - const eid = Object.keys(signing.ends.agent)[0]; - const endRoleResult = await client - .identifiers() - .addEndRole(multisigAID.name, 'agent', eid, timestamp); - const op = await endRoleResult.op(); - opList.push(op); - - const rpy = endRoleResult.serder; - const sigs = endRoleResult.sigs; - const ghabState1 = multisigAID.state; - const seal = [ - 'SealEvent', - { - i: multisigAID.prefix, - s: ghabState1['ee']['s'], - d: ghabState1['ee']['d'], - }, - ]; - const sigers = sigs.map( - (sig: string) => new signify.Siger({ qb64: sig }) - ); - const roleims = signify.d( - signify.messagize(rpy, sigers, seal, undefined, undefined, false) - ); - const atc = roleims.substring(rpy.size); - const roleembeds = { - rpy: [rpy, atc], - }; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/rpy', - { gid: multisigAID.prefix }, - roleembeds, - recp - ); - } - - return opList; -} - -async function createRegistryMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAID: HabState, - registryName: string, - nonce: string, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/vcp'); - - const vcpResult = await client.registries().create({ - name: multisigAID.name, - registryName: registryName, - nonce: nonce, - }); - const op = await vcpResult.op(); - - const serder = vcpResult.regser; - const anc = vcpResult.serder; - const sigs = vcpResult.sigs; - const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(anc, sigers)); - const atc = ims.substring(anc.size); - const regbeds = { - vcp: [serder, ''], - anc: [anc, atc], - }; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'registry', - aid, - '/multisig/vcp', - { gid: multisigAID.prefix }, - regbeds, - recp - ); - - return op; -} - -async function getIssuedCredential( - issuerClient: SignifyClient, - issuerAID: HabState, - recipientAID: HabState, - schemaSAID: string -) { - const credentialList = await issuerClient.credentials().list({ - filter: { - '-i': issuerAID.prefix, - '-s': schemaSAID, - '-a-i': recipientAID.prefix, - }, - }); - assert(credentialList.length <= 1); - return credentialList[0]; -} - -async function issueCredentialMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAIDName: string, - kargsIss: CredentialData, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/iss'); - - const credResult = await client - .credentials() - .issue(multisigAIDName, kargsIss); - const op = credResult.op; - - const multisigAID = await client.identifiers().get(multisigAIDName); - const keeper = client.manager!.get(multisigAID); - const sigs = await keeper.sign(signify.b(credResult.anc.raw)); - const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(credResult.anc, sigers)); - const atc = ims.substring(credResult.anc.size); - const embeds = { - acdc: [credResult.acdc, ''], - iss: [credResult.iss, ''], - anc: [credResult.anc, atc], - }; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/iss', - { gid: multisigAID.prefix }, - embeds, - recp - ); - - return op; -} - -async function grantMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAID: HabState, - recipientAID: HabState, - credential: any, - timestamp: string, - isInitiator: boolean = false -) { - if (!isInitiator) await waitAndMarkNotification(client, '/multisig/exn'); - - const [grant, sigs, end] = await client.ipex().grant({ - senderName: multisigAID.name, - acdc: new Serder(credential.sad), - anc: new Serder(credential.anc), - iss: new Serder(credential.iss), - recipient: recipientAID.prefix, - datetime: timestamp, - }); - - await client - .ipex() - .submitGrant(multisigAID.name, grant, sigs, end, [recipientAID.prefix]); - - const mstate = multisigAID.state; - const seal = [ - 'SealEvent', - { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, - ]; - const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); - const gims = signify.d(signify.messagize(grant, sigers, seal)); - let atc = gims.substring(grant.size); - atc += end; - const gembeds = { - exn: [grant, atc], - }; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/exn', - { gid: multisigAID.prefix }, - gembeds, - recp - ); -} - -async function admitMultisig( - client: SignifyClient, - aid: HabState, - otherMembersAIDs: HabState[], - multisigAID: HabState, - recipientAID: HabState, - timestamp: string - // numGrantMsgs: number -) { - const grantMsgSaid = await waitAndMarkNotification( - client, - '/exn/ipex/grant' - ); - - const [admit, sigs, end] = await client - .ipex() - .admit(multisigAID.name, '', grantMsgSaid, timestamp); - - await client - .ipex() - .submitAdmit(multisigAID.name, admit, sigs, end, [recipientAID.prefix]); - - const mstate = multisigAID.state; - const seal = [ - 'SealEvent', - { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, - ]; - const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(admit, sigers, seal)); - let atc = ims.substring(admit.size); - atc += end; - const gembeds = { - exn: [admit, atc], - }; - const recp = otherMembersAIDs.map((aid) => aid.prefix); - - await client - .exchanges() - .send( - aid.name, - 'multisig', - aid, - '/multisig/exn', - { gid: multisigAID.prefix }, - gembeds, - recp - ); -} - -async function admitSinglesig( - client: SignifyClient, - aid: HabState, - recipientAid: HabState -) { - const grantMsgSaid = await waitAndMarkNotification( - client, - '/exn/ipex/grant' - ); - - const [admit, sigs, aend] = await client - .ipex() - .admit(aid.name, '', grantMsgSaid); - - await client - .ipex() - .submitAdmit(aid.name, admit, sigs, aend, [recipientAid.prefix]); -} - -async function waitAndMarkNotification(client: SignifyClient, route: string) { - const notes = await waitForNotifications(client, route); - - await Promise.all( - notes.map(async (note) => { - await client.notifications().mark(note.i); - }) - ); - - return notes[notes.length - 1]?.a.d ?? ''; -} - -async function getReceivedCredential( - client: SignifyClient, - credId: string -): Promise { - const credentialList = await client.credentials().list({ - filter: { - '-d': credId, - }, - }); - return credentialList[0]; -} - -async function waitForCredential( - client: SignifyClient, - credSAID: string, - MAX_RETRIES: number = 10 -) { - let retryCount = 0; - while (retryCount < MAX_RETRIES) { - const cred = await getReceivedCredential(client, credSAID); - if (cred) return cred; - - await new Promise((resolve) => setTimeout(resolve, 1000)); - console.log(` retry-${retryCount}: No credentials yet...`); - retryCount = retryCount + 1; - } - throw Error('Credential SAID: ' + credSAID + ' has not been received'); -} diff --git a/examples/integration-scripts/multisig.test.ts b/examples/integration-scripts/multisig.test.ts index 79f9d789..2b5dd14c 100644 --- a/examples/integration-scripts/multisig.test.ts +++ b/examples/integration-scripts/multisig.test.ts @@ -7,12 +7,14 @@ import signify, { import { resolveEnvironment } from './utils/resolve-env'; import { assertOperations, + getOrCreateClient, + getOrCreateIdentifier, markNotification, + waitAndMarkNotification, waitForNotifications, waitOperation, warnNotifications, } from './utils/test-util'; -import { getOrCreateClient, getOrCreateIdentifier } from './utils/test-setup'; const { vleiServerUrl } = resolveEnvironment(); const WITNESS_AIDS = [ @@ -1171,18 +1173,6 @@ test('multisig', async function run() { console.log('Multisig credential revocation completed!'); }, 400000); -async function waitAndMarkNotification(client: SignifyClient, route: string) { - const notes = await waitForNotifications(client, route); - - await Promise.all( - notes.map(async (note) => { - await markNotification(client, note); - }) - ); - - return notes[notes.length - 1]?.a.d ?? ''; -} - async function createAID(client: SignifyClient, name: string, wits: string[]) { await getOrCreateIdentifier(client, name, { wits: wits, diff --git a/examples/integration-scripts/salty.test.ts b/examples/integration-scripts/salty.test.ts index 95b88d19..5c460796 100644 --- a/examples/integration-scripts/salty.test.ts +++ b/examples/integration-scripts/salty.test.ts @@ -156,13 +156,13 @@ test('salty', async () => { const events = client1.keyEvents(); const log = await events.get(aid['prefix']); assert.equal(log.length, 3); - let serder = new signify.Serder(log[0]); + let serder = new signify.Serder(log[0]['ked']); assert.equal(serder.pre, icp.pre); assert.equal(serder.ked['d'], icp.ked['d']); - serder = new signify.Serder(log[1]); + serder = new signify.Serder(log[1]['ked']); assert.equal(serder.pre, rot.pre); assert.equal(serder.ked['d'], rot.ked['d']); - serder = new signify.Serder(log[2]); + serder = new signify.Serder(log[2]['ked']); assert.equal(serder.pre, ixn.pre); assert.equal(serder.ked['d'], ixn.ked['d']); diff --git a/examples/integration-scripts/singlesig-dip.test.ts b/examples/integration-scripts/singlesig-dip.test.ts index dc154fc9..8627d376 100644 --- a/examples/integration-scripts/singlesig-dip.test.ts +++ b/examples/integration-scripts/singlesig-dip.test.ts @@ -1,10 +1,11 @@ import { CreateIdentiferArgs, SignifyClient } from 'signify-ts'; import { + assertOperations, getOrCreateClients, getOrCreateContact, getOrCreateIdentifier, -} from './utils/test-setup'; -import { assertOperations, waitOperation } from './utils/test-util'; + waitOperation, +} from './utils/test-util'; import { resolveEnvironment } from './utils/resolve-env'; let client1: SignifyClient, client2: SignifyClient; diff --git a/examples/integration-scripts/singlesig-drt.test.ts b/examples/integration-scripts/singlesig-drt.test.ts index c30e5e29..bb1c714f 100644 --- a/examples/integration-scripts/singlesig-drt.test.ts +++ b/examples/integration-scripts/singlesig-drt.test.ts @@ -1,10 +1,11 @@ import { CreateIdentiferArgs, SignifyClient } from 'signify-ts'; import { + assertOperations, getOrCreateClients, getOrCreateContact, getOrCreateIdentifier, -} from './utils/test-setup'; -import { assertOperations, waitOperation } from './utils/test-util'; + waitOperation, +} from './utils/test-util'; let delegator: SignifyClient, delegate: SignifyClient; let name1_id: string, name1_oobi: string; diff --git a/examples/integration-scripts/singlesig-ixn.test.ts b/examples/integration-scripts/singlesig-ixn.test.ts index 73fe67e1..cde5729b 100644 --- a/examples/integration-scripts/singlesig-ixn.test.ts +++ b/examples/integration-scripts/singlesig-ixn.test.ts @@ -1,10 +1,11 @@ import { EventResult, SignifyClient } from 'signify-ts'; import { + assertOperations, getOrCreateClients, getOrCreateContact, getOrCreateIdentifier, -} from './utils/test-setup'; -import { assertOperations, waitOperation } from './utils/test-util'; + waitOperation, +} from './utils/test-util'; let client1: SignifyClient, client2: SignifyClient; let name1_id: string, name1_oobi: string; diff --git a/examples/integration-scripts/singlesig-rot.test.ts b/examples/integration-scripts/singlesig-rot.test.ts index 89a3bf40..acc90496 100644 --- a/examples/integration-scripts/singlesig-rot.test.ts +++ b/examples/integration-scripts/singlesig-rot.test.ts @@ -1,10 +1,11 @@ import { EventResult, RotateIdentifierArgs, SignifyClient } from 'signify-ts'; import { + assertOperations, getOrCreateClients, getOrCreateContact, getOrCreateIdentifier, -} from './utils/test-setup'; -import { assertOperations, waitOperation } from './utils/test-util'; + waitOperation, +} from './utils/test-util'; let client1: SignifyClient, client2: SignifyClient; let name1_id: string, name1_oobi: string; diff --git a/examples/integration-scripts/singlesig-vlei-issuance.test.ts b/examples/integration-scripts/singlesig-vlei-issuance.test.ts index 4d807860..1d87d522 100644 --- a/examples/integration-scripts/singlesig-vlei-issuance.test.ts +++ b/examples/integration-scripts/singlesig-vlei-issuance.test.ts @@ -2,7 +2,14 @@ import { strict as assert } from 'assert'; import { Saider, Salter, Serder, SignifyClient } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env'; import { + Aid, assertOperations, + createAid, + getOrCreateClients, + getOrCreateContact, + getOrCreateIdentifier, + getOrIssueCredential, + getReceivedCredential, markAndRemoveNotification, resolveOobi, waitForNotifications, @@ -10,11 +17,6 @@ import { warnNotifications, } from './utils/test-util'; import { retry } from './utils/retry'; -import { - getOrCreateClients, - getOrCreateContact, - getOrCreateIdentifier, -} from './utils/test-setup'; const { vleiServerUrl } = resolveEnvironment(); @@ -107,27 +109,16 @@ const OOR_RULES = LE_RULES; const OOR_AUTH_RULES = LE_RULES; const CRED_RETRY_DEFAULTS = { - maxSleep: 1000, - minSleep: 100, + maxSleep: 10000, + minSleep: 1000, maxRetries: undefined, timeout: 30000, }; -interface Aid { - name: string; - prefix: string; - oobi: string; -} - function createTimestamp() { return new Date().toISOString().replace('Z', '000+00:00'); } -async function createAid(client: SignifyClient, name: string): Promise { - const [prefix, oobi] = await getOrCreateIdentifier(client, name); - return { name, prefix, oobi }; -} - test('singlesig-vlei-issuance', async function run() { const [gleifClient, qviClient, leClient, roleClient] = await getOrCreateClients(4); @@ -190,14 +181,14 @@ test('singlesig-vlei-issuance', async function run() { QVI_SCHEMA_SAID ); - let qviCredHolder = await getGrantedCredential(qviClient, qviCred.sad.d); + let qviCredHolder = await getReceivedCredential(qviClient, qviCred.sad.d); if (!qviCredHolder) { await sendGrantMessage(gleifClient, gleifAid, qviAid, qviCred); await sendAdmitMessage(qviClient, qviAid, gleifAid); qviCredHolder = await retry(async () => { - const cred = await getGrantedCredential(qviClient, qviCred.sad.d); + const cred = await getReceivedCredential(qviClient, qviCred.sad.d); assert(cred !== undefined); return cred; }, CRED_RETRY_DEFAULTS); @@ -230,14 +221,14 @@ test('singlesig-vlei-issuance', async function run() { leCredSource ); - let leCredHolder = await getGrantedCredential(leClient, leCred.sad.d); + let leCredHolder = await getReceivedCredential(leClient, leCred.sad.d); if (!leCredHolder) { await sendGrantMessage(qviClient, qviAid, leAid, leCred); await sendAdmitMessage(leClient, leAid, qviAid); leCredHolder = await retry(async () => { - const cred = await getGrantedCredential(leClient, leCred.sad.d); + const cred = await getReceivedCredential(leClient, leCred.sad.d); assert(cred !== undefined); return cred; }, CRED_RETRY_DEFAULTS); @@ -272,14 +263,14 @@ test('singlesig-vlei-issuance', async function run() { true ); - let ecrCredHolder = await getGrantedCredential(roleClient, ecrCred.sad.d); + let ecrCredHolder = await getReceivedCredential(roleClient, ecrCred.sad.d); if (!ecrCredHolder) { await sendGrantMessage(leClient, leAid, roleAid, ecrCred); await sendAdmitMessage(roleClient, roleAid, leAid); ecrCredHolder = await retry(async () => { - const cred = await getGrantedCredential(roleClient, ecrCred.sad.d); + const cred = await getReceivedCredential(roleClient, ecrCred.sad.d); assert(cred !== undefined); return cred; }, CRED_RETRY_DEFAULTS); @@ -314,7 +305,7 @@ test('singlesig-vlei-issuance', async function run() { ecrAuthCredSource ); - let ecrAuthCredHolder = await getGrantedCredential( + let ecrAuthCredHolder = await getReceivedCredential( qviClient, ecrAuthCred.sad.d ); @@ -324,7 +315,7 @@ test('singlesig-vlei-issuance', async function run() { await sendAdmitMessage(qviClient, qviAid, leAid); ecrAuthCredHolder = await retry(async () => { - const cred = await getGrantedCredential( + const cred = await getReceivedCredential( qviClient, ecrAuthCred.sad.d ); @@ -364,14 +355,20 @@ test('singlesig-vlei-issuance', async function run() { true ); - let ecrCredHolder2 = await getGrantedCredential(roleClient, ecrCred2.sad.d); + let ecrCredHolder2 = await getReceivedCredential( + roleClient, + ecrCred2.sad.d + ); if (!ecrCredHolder2) { await sendGrantMessage(qviClient, qviAid, roleAid, ecrCred2); await sendAdmitMessage(roleClient, roleAid, qviAid); ecrCredHolder2 = await retry(async () => { - const cred = await getGrantedCredential(roleClient, ecrCred2.sad.d); + const cred = await getReceivedCredential( + roleClient, + ecrCred2.sad.d + ); assert(cred !== undefined); return cred; }, CRED_RETRY_DEFAULTS); @@ -405,7 +402,7 @@ test('singlesig-vlei-issuance', async function run() { oorAuthCredSource ); - let oorAuthCredHolder = await getGrantedCredential( + let oorAuthCredHolder = await getReceivedCredential( qviClient, oorAuthCred.sad.d ); @@ -415,7 +412,7 @@ test('singlesig-vlei-issuance', async function run() { await sendAdmitMessage(qviClient, qviAid, leAid); oorAuthCredHolder = await retry(async () => { - const cred = await getGrantedCredential( + const cred = await getReceivedCredential( qviClient, oorAuthCred.sad.d ); @@ -454,14 +451,14 @@ test('singlesig-vlei-issuance', async function run() { oorCredSource ); - let oorCredHolder = await getGrantedCredential(roleClient, oorCred.sad.d); + let oorCredHolder = await getReceivedCredential(roleClient, oorCred.sad.d); if (!oorCredHolder) { await sendGrantMessage(qviClient, qviAid, roleAid, oorCred); await sendAdmitMessage(roleClient, roleAid, qviAid); oorCredHolder = await retry(async () => { - const cred = await getGrantedCredential(roleClient, oorCred.sad.d); + const cred = await getReceivedCredential(roleClient, oorCred.sad.d); assert(cred !== undefined); return cred; }, CRED_RETRY_DEFAULTS); @@ -496,65 +493,6 @@ async function getOrCreateRegistry( return registries[0]; } -async function getOrIssueCredential( - issuerClient: SignifyClient, - issuerAid: Aid, - recipientAid: Aid, - issuerRegistry: { regk: string }, - credData: any, - schema: string, - rules?: any, - source?: any, - privacy = false -): Promise { - const credentialList = await issuerClient.credentials().list(); - - if (credentialList.length > 0) { - const credential = credentialList.find( - (cred: any) => - cred.sad.s === schema && - cred.sad.i === issuerAid.prefix && - cred.sad.a.i === recipientAid.prefix - ); - if (credential) return credential; - } - - const issResult = await issuerClient.credentials().issue(issuerAid.name, { - ri: issuerRegistry.regk, - s: schema, - u: privacy ? new Salter({}).qb64 : undefined, - a: { - i: recipientAid.prefix, - u: privacy ? new Salter({}).qb64 : undefined, - ...credData, - }, - r: rules, - e: source, - }); - - await waitOperation(issuerClient, issResult.op); - const credential = await issuerClient - .credentials() - .get(issResult.acdc.ked.d); - - return credential; -} - -async function getGrantedCredential( - client: SignifyClient, - credId: string -): Promise { - const credentialList = await client.credentials().list({ - filter: { '-d': credId }, - }); - let credential: any; - if (credentialList.length > 0) { - assert.equal(credentialList.length, 1); - credential = credentialList[0]; - } - return credential; -} - async function sendGrantMessage( senderClient: SignifyClient, senderAid: Aid, diff --git a/examples/integration-scripts/test-setup-clients.test.ts b/examples/integration-scripts/test-setup-clients.test.ts index dd06adc1..9e822e16 100644 --- a/examples/integration-scripts/test-setup-clients.test.ts +++ b/examples/integration-scripts/test-setup-clients.test.ts @@ -1,10 +1,10 @@ import { SignifyClient } from 'signify-ts'; import { + assertOperations, getOrCreateClients, getOrCreateContact, getOrCreateIdentifier, -} from './utils/test-setup'; -import { assertOperations } from './utils/test-util'; +} from './utils/test-util'; let client1: SignifyClient, client2: SignifyClient; let name1_id: string, name1_oobi: string; diff --git a/examples/integration-scripts/test-setup-single-client.test.ts b/examples/integration-scripts/test-setup-single-client.test.ts index cf2f941b..fecf61c7 100644 --- a/examples/integration-scripts/test-setup-single-client.test.ts +++ b/examples/integration-scripts/test-setup-single-client.test.ts @@ -1,7 +1,10 @@ import { SignifyClient } from 'signify-ts'; -import { getOrCreateClients, getOrCreateIdentifier } from './utils/test-setup'; import { resolveEnvironment } from './utils/resolve-env'; -import { assertOperations } from './utils/test-util'; +import { + assertOperations, + getOrCreateClients, + getOrCreateIdentifier, +} from './utils/test-util'; let client: SignifyClient; let name1_id: string, name1_oobi: string; @@ -19,9 +22,7 @@ afterAll(async () => { describe('test-setup-single-client', () => { test('step1', async () => { - expect(client.agent?.pre).toEqual( - 'EC60ue9GOpQGrLBlS9T0dO6JkBTbv3V05Y4O730QBBoc' - ); + const env = resolveEnvironment(); expect(client.controller?.pre).toEqual( 'EB3UGWwIMq7ppzcQ697ImQIuXlBG5jzh-baSx-YG3-tY' ); @@ -33,7 +34,7 @@ describe('test-setup-single-client', () => { switch (env.preset) { case 'local': expect(name1_oobi).toEqual( - `http://127.0.0.1:3902/oobi/${name1_id}/agent/EC60ue9GOpQGrLBlS9T0dO6JkBTbv3V05Y4O730QBBoc` + `http://127.0.0.1:3902/oobi/${name1_id}/agent/${client.agent?.pre}` ); expect(oobi.oobis[0]).toEqual( `http://127.0.0.1:5642/oobi/${name1_id}/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha` @@ -47,7 +48,7 @@ describe('test-setup-single-client', () => { break; case 'docker': expect(name1_oobi).toEqual( - `http://keria:3902/oobi/${name1_id}/agent/EC60ue9GOpQGrLBlS9T0dO6JkBTbv3V05Y4O730QBBoc` + `http://keria:3902/oobi/${name1_id}/agent/${client.agent?.pre}` ); expect(oobi.oobis[0]).toEqual( `http://witness-demo:5642/oobi/${name1_id}/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha` diff --git a/examples/integration-scripts/utils/multisig-utils.ts b/examples/integration-scripts/utils/multisig-utils.ts index 417dedab..6cc876ae 100644 --- a/examples/integration-scripts/utils/multisig-utils.ts +++ b/examples/integration-scripts/utils/multisig-utils.ts @@ -1,4 +1,16 @@ -import { Algos, Siger, SignifyClient, d, messagize } from 'signify-ts'; +import signify, { + Algos, + CreateIdentiferArgs, + CredentialData, + Serder, + Siger, + SignifyClient, + d, + messagize, +} from 'signify-ts'; +import { getStates, waitAndMarkNotification } from './test-util'; +import { HabState } from '../../../src/keri/core/state'; +import assert from 'assert'; export interface AcceptMultisigInceptArgs { groupName: string; @@ -6,6 +18,17 @@ export interface AcceptMultisigInceptArgs { msgSaid: string; } +export interface StartMultisigInceptArgs { + groupName: string; + localMemberName: string; + participants: string[]; + isith?: number | string | string[]; + nsith?: number | string | string[]; + toad?: number; + wits?: string[]; + delpre?: string; +} + export async function acceptMultisigIncept( client2: SignifyClient, { groupName, localMemberName, msgSaid }: AcceptMultisigInceptArgs @@ -44,11 +67,11 @@ export async function acceptMultisigIncept( const recipients = smids.filter((id: string) => memberHab.prefix !== id); - await client2 + client2 .exchanges() .send( localMemberName, - 'multisig', + groupName, memberHab, '/multisig/icp', { gid: serder.pre, smids: smids, rmids: smids }, @@ -59,15 +82,362 @@ export async function acceptMultisigIncept( return op2; } -export interface StartMultisigInceptArgs { - groupName: string; - localMemberName: string; - participants: string[]; - isith?: number | string | string[]; - nsith?: number | string | string[]; - toad?: number; - wits?: string[]; - delpre?: string; +export async function addEndRoleMultisig( + client: SignifyClient, + groupName: string, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAID: HabState, + timestamp: string, + isInitiator: boolean = false +) { + if (!isInitiator) await waitAndMarkNotification(client, '/multisig/rpy'); + + const opList: any[] = []; + const members = await client.identifiers().members(multisigAID.name); + const signings = members['signing']; + + for (const signing of signings) { + const eid = Object.keys(signing.ends.agent)[0]; + const endRoleResult = await client + .identifiers() + .addEndRole(multisigAID.name, 'agent', eid, timestamp); + const op = await endRoleResult.op(); + opList.push(op); + + const rpy = endRoleResult.serder; + const sigs = endRoleResult.sigs; + const ghabState1 = multisigAID.state; + const seal = [ + 'SealEvent', + { + i: multisigAID.prefix, + s: ghabState1['ee']['s'], + d: ghabState1['ee']['d'], + }, + ]; + const sigers = sigs.map( + (sig: string) => new signify.Siger({ qb64: sig }) + ); + const roleims = signify.d( + signify.messagize(rpy, sigers, seal, undefined, undefined, false) + ); + const atc = roleims.substring(rpy.size); + const roleembeds = { + rpy: [rpy, atc], + }; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + await client + .exchanges() + .send( + aid.name, + groupName, + aid, + '/multisig/rpy', + { gid: multisigAID.prefix }, + roleembeds, + recp + ); + } + + return opList; +} + +export async function admitMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAID: HabState, + recipientAID: HabState, + timestamp: string + // numGrantMsgs: number +) { + const grantMsgSaid = await waitAndMarkNotification( + client, + '/exn/ipex/grant' + ); + + const [admit, sigs, end] = await client + .ipex() + .admit(multisigAID.name, '', grantMsgSaid, timestamp); + + await client + .ipex() + .submitAdmit(multisigAID.name, admit, sigs, end, [recipientAID.prefix]); + + const mstate = multisigAID.state; + const seal = [ + 'SealEvent', + { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, + ]; + const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(admit, sigers, seal)); + let atc = ims.substring(admit.size); + atc += end; + const gembeds = { + exn: [admit, atc], + }; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + 'multisig', + aid, + '/multisig/exn', + { gid: multisigAID.prefix }, + gembeds, + recp + ); +} + +export async function createAIDMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + groupName: string, + kargs: CreateIdentiferArgs, + isInitiator: boolean = false +) { + if (!isInitiator) await waitAndMarkNotification(client, '/multisig/icp'); + + const icpResult = await client.identifiers().create(groupName, kargs); + const op = await icpResult.op(); + + const serder = icpResult.serder; + const sigs = icpResult.sigs; + const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(serder, sigers)); + const atc = ims.substring(serder.size); + const embeds = { + icp: [serder, atc], + }; + const smids = kargs.states?.map((state) => state['i']); + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + 'multisig', + aid, + '/multisig/icp', + { gid: serder.pre, smids: smids, rmids: smids }, + embeds, + recp + ); + + return op; +} + +export async function createRegistryMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAID: HabState, + registryName: string, + nonce: string, + isInitiator: boolean = false +) { + if (!isInitiator) await waitAndMarkNotification(client, '/multisig/vcp'); + + const vcpResult = await client.registries().create({ + name: multisigAID.name, + registryName: registryName, + nonce: nonce, + }); + const op = await vcpResult.op(); + + const serder = vcpResult.regser; + const anc = vcpResult.serder; + const sigs = vcpResult.sigs; + const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(anc, sigers)); + const atc = ims.substring(anc.size); + const regbeds = { + vcp: [serder, ''], + anc: [anc, atc], + }; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + 'registry', + aid, + '/multisig/vcp', + { gid: multisigAID.prefix }, + regbeds, + recp + ); + + return op; +} + +export async function delegateMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAID: HabState, + anchor: { i: string; s: string; d: string }, + isInitiator: boolean = false +) { + if (!isInitiator) { + const msgSaid = await waitAndMarkNotification(client, '/multisig/ixn'); + console.log( + `${aid.name}(${aid.prefix}) received exchange message to join the interaction event` + ); + const res = await client.groups().getRequest(msgSaid); + const exn = res[0].exn; + const ixn = exn.e.ixn; + anchor = ixn.a[0]; + } + + // const {delResult, delOp} = await retry(async () => { + const delResult = await client + .delegations() + .approve(multisigAID.name, anchor); + const appOp = await delResult.op(); + console.log( + `Delegator ${aid.name}(${aid.prefix}) approved delegation for ${ + multisigAID.name + } with anchor ${JSON.stringify(anchor)}` + ); + + assert.equal( + JSON.stringify(delResult.serder.ked.a[0]), + JSON.stringify(anchor) + ); + + const serder = delResult.serder; + const sigs = delResult.sigs; + const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(serder, sigers)); + const atc = ims.substring(serder.size); + const xembeds = { + ixn: [serder, atc], + }; + const smids = [aid.prefix, ...otherMembersAIDs.map((aid) => aid.prefix)]; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + multisigAID.name, + aid, + '/multisig/ixn', + { gid: serder.pre, smids: smids, rmids: smids }, + xembeds, + recp + ); + + if (isInitiator) { + console.log( + `${aid.name}(${aid.prefix}) initiates delegation interaction event, waiting for others to join...` + ); + } else { + console.log(`${aid.name}(${aid.prefix}) joins interaction event`); + } + + return appOp; +} + +export async function grantMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAID: HabState, + recipientAID: HabState, + credential: any, + timestamp: string, + isInitiator: boolean = false +) { + if (!isInitiator) await waitAndMarkNotification(client, '/multisig/exn'); + + const [grant, sigs, end] = await client.ipex().grant({ + senderName: multisigAID.name, + acdc: new Serder(credential.sad), + anc: new Serder(credential.anc), + iss: new Serder(credential.iss), + recipient: recipientAID.prefix, + datetime: timestamp, + }); + + await client + .ipex() + .submitGrant(multisigAID.name, grant, sigs, end, [recipientAID.prefix]); + + const mstate = multisigAID.state; + const seal = [ + 'SealEvent', + { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, + ]; + const sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + const gims = signify.d(signify.messagize(grant, sigers, seal)); + let atc = gims.substring(grant.size); + atc += end; + const gembeds = { + exn: [grant, atc], + }; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + 'multisig', + aid, + '/multisig/exn', + { gid: multisigAID.prefix }, + gembeds, + recp + ); +} + +export async function issueCredentialMultisig( + client: SignifyClient, + aid: HabState, + otherMembersAIDs: HabState[], + multisigAIDName: string, + kargsIss: CredentialData, + isInitiator: boolean = false +) { + if (!isInitiator) await waitAndMarkNotification(client, '/multisig/iss'); + + const credResult = await client + .credentials() + .issue(multisigAIDName, kargsIss); + const op = credResult.op; + + const multisigAID = await client.identifiers().get(multisigAIDName); + const keeper = client.manager!.get(multisigAID); + const sigs = await keeper.sign(signify.b(credResult.anc.raw)); + const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(credResult.anc, sigers)); + const atc = ims.substring(credResult.anc.size); + const embeds = { + acdc: [credResult.acdc, ''], + iss: [credResult.iss, ''], + anc: [credResult.anc, atc], + }; + const recp = otherMembersAIDs.map((aid) => aid.prefix); + + await client + .exchanges() + .send( + aid.name, + 'multisig', + aid, + '/multisig/iss', + { gid: multisigAID.prefix }, + embeds, + recp + ); + + return op; } export async function startMultisigIncept( @@ -108,8 +478,8 @@ export async function startMultisigIncept( await client .exchanges() .send( - 'member1', - 'multisig', + localMemberName, + groupName, aid1, '/multisig/icp', { gid: serder.pre, smids: smids, rmids: smids }, @@ -118,10 +488,3 @@ export async function startMultisigIncept( ); return op1; } - -async function getStates(client: SignifyClient, prefixes: string[]) { - const participantStates = await Promise.all( - prefixes.map((p) => client.keyStates().get(p)) - ); - return participantStates.map((s) => s[0]); -} diff --git a/examples/integration-scripts/utils/test-util.ts b/examples/integration-scripts/utils/test-util.ts index 95feb44f..d2485296 100644 --- a/examples/integration-scripts/utils/test-util.ts +++ b/examples/integration-scripts/utils/test-util.ts @@ -1,5 +1,30 @@ -import { Operation, SignifyClient } from 'signify-ts'; +import signify, { + CreateIdentiferArgs, + EventResult, + Operation, + randomPasscode, + ready, + Salter, + SignifyClient, + Tier, +} from 'signify-ts'; import { RetryOptions, retry } from './retry'; +import { HabState } from '../../../src/keri/core/state'; +import assert from 'assert'; +import { resolveEnvironment } from './resolve-env'; + +export interface Aid { + name: string; + prefix: string; + oobi: string; +} + +export interface Notification { + i: string; + dt: string; + r: boolean; + a: { r: string; d?: string; m?: string }; +} export function sleep(ms: number): Promise { return new Promise((resolve) => { @@ -7,6 +32,25 @@ export function sleep(ms: number): Promise { }); } +export async function admitSinglesig( + client: SignifyClient, + aidName: string, + recipientAid: HabState +) { + const grantMsgSaid = await waitAndMarkNotification( + client, + '/exn/ipex/grant' + ); + + const [admit, sigs, aend] = await client + .ipex() + .admit(aidName, '', grantMsgSaid); + + await client + .ipex() + .submitAdmit(aidName, admit, sigs, aend, [recipientAid.prefix]); +} + /** * Assert that all operations were waited for. *

This is a postcondition check to make sure all long-running operations have been waited for @@ -37,6 +81,285 @@ export async function assertNotifications( } } +export async function createAid( + client: SignifyClient, + name: string +): Promise { + const [prefix, oobi] = await getOrCreateIdentifier(client, name); + return { prefix, oobi, name }; +} + +export async function createAID(client: signify.SignifyClient, name: string) { + await getOrCreateIdentifier(client, name); + const aid = await client.identifiers().get(name); + console.log(name, 'AID:', aid.prefix); + return aid; +} + +export function createTimestamp() { + return new Date().toISOString().replace('Z', '000+00:00'); +} + +/** + * Get list of end role authorizations for a Keri idenfitier + */ +export async function getEndRoles( + client: SignifyClient, + alias: string, + role?: string +): Promise { + const path = + role !== undefined + ? `/identifiers/${alias}/endroles/${role}` + : `/identifiers/${alias}/endroles`; + const response: Response = await client.fetch(path, 'GET', null); + if (!response.ok) throw new Error(await response.text()); + const result = await response.json(); + // console.log("getEndRoles", result); + return result; +} + +export async function getIssuedCredential( + issuerClient: SignifyClient, + issuerAID: HabState, + recipientAID: HabState, + schemaSAID: string +) { + const credentialList = await issuerClient.credentials().list({ + filter: { + '-i': issuerAID.prefix, + '-s': schemaSAID, + '-a-i': recipientAID.prefix, + }, + }); + assert(credentialList.length <= 1); + return credentialList[0]; +} + +export async function getOrCreateAID( + client: SignifyClient, + name: string, + kargs: CreateIdentiferArgs +): Promise { + try { + return await client.identifiers().get(name); + } catch { + const result: EventResult = await client + .identifiers() + .create(name, kargs); + + await waitOperation(client, await result.op()); + const aid = await client.identifiers().get(name); + + const op = await client + .identifiers() + .addEndRole(name, 'agent', client!.agent!.pre); + await waitOperation(client, await op.op()); + console.log(name, 'AID:', aid.prefix); + return aid; + } +} + +/** + * Connect or boot a SignifyClient instance + */ +export async function getOrCreateClient( + bran: string | undefined = undefined +): Promise { + const env = resolveEnvironment(); + await ready(); + bran ??= randomPasscode(); + bran = bran.padEnd(21, '_'); + const client = new SignifyClient(env.url, bran, Tier.low, env.bootUrl); + try { + await client.connect(); + } catch { + const res = await client.boot(); + if (!res.ok) throw new Error(); + await client.connect(); + } + console.log('client', { + agent: client.agent?.pre, + controller: client.controller.pre, + }); + return client; +} + +/** + * Connect or boot a number of SignifyClient instances + * @example + * Create two clients with random secrets + * let client1: SignifyClient, client2: SignifyClient; + * beforeAll(async () => { + * [client1, client2] = await getOrCreateClients(2); + * }); + * @example + * Launch jest from shell with pre-defined secrets + * $ SIGNIFY_SECRETS="0ACqshJKkJ7DDXcaDuwnmI8s,0ABqicvyicXGvIVg6Ih-dngE" npx jest ./tests + */ +export async function getOrCreateClients( + count: number, + brans: string[] | undefined = undefined +): Promise { + const tasks: Promise[] = []; + const secrets = process.env['SIGNIFY_SECRETS']?.split(','); + for (let i = 0; i < count; i++) { + tasks.push( + getOrCreateClient(brans?.at(i) ?? secrets?.at(i) ?? undefined) + ); + } + const clients: SignifyClient[] = await Promise.all(tasks); + console.log(`SIGNIFY_SECRETS="${clients.map((i) => i.bran).join(',')}"`); + return clients; +} + +/** + * Get or resolve a Keri contact + * @example + * Create a Keri contact before running tests + * let contact1_id: string; + * beforeAll(async () => { + * contact1_id = await getOrCreateContact(client2, "contact1", name1_oobi); + * }); + */ +export async function getOrCreateContact( + client: SignifyClient, + name: string, + oobi: string +): Promise { + const list = await client.contacts().list(undefined, 'alias', `^${name}$`); + // console.log("contacts.list", list); + if (list.length > 0) { + const contact = list[0]; + if (contact.oobi === oobi) { + // console.log("contacts.id", contact.id); + return contact.id; + } + } + let op = await client.oobis().resolve(oobi, name); + op = await waitOperation(client, op); + return op.response.i; +} + +/** + * Get or create a Keri identifier. Uses default witness config from `resolveEnvironment` + * @example + * Create a Keri identifier before running tests + * let name1_id: string, name1_oobi: string; + * beforeAll(async () => { + * [name1_id, name1_oobi] = await getOrCreateIdentifier(client1, "name1"); + * }); + * @see resolveEnvironment + */ +export async function getOrCreateIdentifier( + client: SignifyClient, + name: string, + kargs: CreateIdentiferArgs | undefined = undefined +): Promise<[string, string]> { + let id: any = undefined; + try { + const identfier = await client.identifiers().get(name); + // console.log("identifiers.get", identfier); + id = identfier.prefix; + } catch { + const env = resolveEnvironment(); + kargs ??= { + toad: env.witnessIds.length, + wits: env.witnessIds, + }; + const result: EventResult = await client + .identifiers() + .create(name, kargs); + let op = await result.op(); + op = await waitOperation(client, op); + // console.log("identifiers.create", op); + id = op.response.i; + } + const eid = client.agent?.pre!; + if (!(await hasEndRole(client, name, 'agent', eid))) { + const result: EventResult = await client + .identifiers() + .addEndRole(name, 'agent', eid); + let op = await result.op(); + op = await waitOperation(client, op); + console.log('identifiers.addEndRole', op); + } + + const oobi = await client.oobis().get(name, 'agent'); + const result: [string, string] = [id, oobi.oobis[0]]; + console.log(name, result); + return result; +} + +export async function getOrIssueCredential( + issuerClient: SignifyClient, + issuerAid: Aid, + recipientAid: Aid, + issuerRegistry: { regk: string }, + credData: any, + schema: string, + rules?: any, + source?: any, + privacy = false +): Promise { + const credentialList = await issuerClient.credentials().list(); + + if (credentialList.length > 0) { + const credential = credentialList.find( + (cred: any) => + cred.sad.s === schema && + cred.sad.i === issuerAid.prefix && + cred.sad.a.i === recipientAid.prefix + ); + if (credential) return credential; + } + + const issResult = await issuerClient.credentials().issue(issuerAid.name, { + ri: issuerRegistry.regk, + s: schema, + u: privacy ? new Salter({}).qb64 : undefined, + a: { + i: recipientAid.prefix, + u: privacy ? new Salter({}).qb64 : undefined, + ...credData, + }, + r: rules, + e: source, + }); + + await waitOperation(issuerClient, issResult.op); + const credential = await issuerClient + .credentials() + .get(issResult.acdc.ked.d); + + return credential; +} + +export async function getStates(client: SignifyClient, prefixes: string[]) { + const participantStates = await Promise.all( + prefixes.map((p) => client.keyStates().get(p)) + ); + return participantStates.map((s) => s[0]); +} + +/** + * Test if end role is authorized for a Keri identifier + */ +export async function hasEndRole( + client: SignifyClient, + alias: string, + role: string, + eid: string +): Promise { + const list = await getEndRoles(client, alias, role); + for (const i of list) { + if (i.role === role && i.eid === eid) { + return true; + } + } + return false; +} + /** * Logs a warning for each un-handled notification. *

Replace warnNotifications with assertNotifications when test handles all notifications @@ -57,27 +380,6 @@ export async function warnNotifications( expect(count).toBeGreaterThan(0); // replace warnNotifications with assertNotifications } -/** - * Poll for operation to become completed. - * Removes completed operation - */ -export async function waitOperation( - client: SignifyClient, - op: Operation | string, - signal?: AbortSignal -): Promise> { - if (typeof op === 'string') { - op = await client.operations().get(op); - } - - op = await client - .operations() - .wait(op, { signal: signal ?? AbortSignal.timeout(30000) }); - await deleteOperations(client, op); - - return op; -} - async function deleteOperations( client: SignifyClient, op: Operation @@ -89,6 +391,47 @@ async function deleteOperations( await client.operations().delete(op.name); } +export async function getReceivedCredential( + client: SignifyClient, + credId: string +): Promise { + const credentialList = await client.credentials().list({ + filter: { + '-d': credId, + }, + }); + let credential: any; + if (credentialList.length > 0) { + assert.equal(credentialList.length, 1); + credential = credentialList[0]; + } + return credential; +} + +/** + * Mark and remove notification. + */ +export async function markAndRemoveNotification( + client: SignifyClient, + note: Notification +): Promise { + try { + await client.notifications().mark(note.i); + } finally { + await client.notifications().delete(note.i); + } +} + +/** + * Mark notification as read. + */ +export async function markNotification( + client: SignifyClient, + note: Notification +): Promise { + await client.notifications().mark(note.i); +} + export async function resolveOobi( client: SignifyClient, oobi: string, @@ -98,11 +441,36 @@ export async function resolveOobi( await waitOperation(client, op); } -export interface Notification { - i: string; - dt: string; - r: boolean; - a: { r: string; d?: string; m?: string }; +export async function waitForCredential( + client: SignifyClient, + credSAID: string, + MAX_RETRIES: number = 10 +) { + let retryCount = 0; + while (retryCount < MAX_RETRIES) { + const cred = await getReceivedCredential(client, credSAID); + if (cred) return cred; + + await new Promise((resolve) => setTimeout(resolve, 1000)); + console.log(` retry-${retryCount}: No credentials yet...`); + retryCount = retryCount + 1; + } + throw Error('Credential SAID: ' + credSAID + ' has not been received'); +} + +export async function waitAndMarkNotification( + client: SignifyClient, + route: string +) { + const notes = await waitForNotifications(client, route); + + await Promise.all( + notes.map(async (note) => { + await markNotification(client, note); + }) + ); + + return notes[notes.length - 1]?.a.d ?? ''; } export async function waitForNotifications( @@ -128,25 +496,22 @@ export async function waitForNotifications( } /** - * Mark notification as read. - */ -export async function markNotification( - client: SignifyClient, - note: Notification -): Promise { - await client.notifications().mark(note.i); -} - -/** - * Mark and remove notification. + * Poll for operation to become completed. + * Removes completed operation */ -export async function markAndRemoveNotification( +export async function waitOperation( client: SignifyClient, - note: Notification -): Promise { - try { - await client.notifications().mark(note.i); - } finally { - await client.notifications().delete(note.i); + op: Operation | string, + signal?: AbortSignal +): Promise> { + if (typeof op === 'string') { + op = await client.operations().get(op); } + + op = await client + .operations() + .wait(op, { signal: signal ?? AbortSignal.timeout(30000) }); + await deleteOperations(client, op); + + return op; } diff --git a/examples/integration-scripts/witness.test.ts b/examples/integration-scripts/witness.test.ts index b7b39a3e..c5d45234 100644 --- a/examples/integration-scripts/witness.test.ts +++ b/examples/integration-scripts/witness.test.ts @@ -67,4 +67,4 @@ test('test witness', async () => { assert.equal(aid1.state.b.length, 1); assert.equal(aid1.state.b.length, 1); assert.equal(aid1.state.b[0], WITNESS_AID); -}); +}, 60000); diff --git a/package-lock.json b/package-lock.json index e4f9dcd9..183e2dda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "signify-ts", - "version": "0.2.1", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "signify-ts", - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "workspaces": [ "examples/*" @@ -20,7 +20,7 @@ "structured-headers": "^0.5.0" }, "devDependencies": { - "@mermaid-js/mermaid-cli": "^10.3.0", + "@mermaid-js/mermaid-cli": "^10.6.1", "@types/jest": "^29.5.8", "@types/libsodium-wrappers-sumo": "^0.7.5", "@types/node": "^18.11.18", @@ -108,99 +108,43 @@ } }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "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/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==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -215,24 +159,15 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/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/@babel/generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", - "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", "dev": true, "dependencies": { - "@babel/types": "^7.23.3", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -240,14 +175,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -255,72 +190,67 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/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/@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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -330,88 +260,89 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "engines": { "node": ">=6.9.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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "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==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", - "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -474,9 +405,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -674,34 +605,34 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", - "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@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.3", - "@babel/types": "^7.23.3", - "debug": "^4.1.0", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -709,13 +640,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", - "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -728,6 +659,12 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==", + "dev": true + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -1785,14 +1722,14 @@ "dev": true }, "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==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -1808,9 +1745,9 @@ } }, "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==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1823,9 +1760,9 @@ "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==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1845,13 +1782,14 @@ } }, "node_modules/@mermaid-js/mermaid-cli": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-cli/-/mermaid-cli-10.4.0.tgz", - "integrity": "sha512-sXohfGD6xgR8VEKvLdvSCndFaFNVTlyXjgZlJ3x8U3/J0V2VTfLIZO94Gt8KUPUccFWci8dRYDGG0fQerB+aIA==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-cli/-/mermaid-cli-10.9.1.tgz", + "integrity": "sha512-ajpGUKmB5YbRRzrFR+0dbykF9mTvce4FpHWGYPYTry8ZsOgP6h7SUnojyCJDGgbReCnArODCM8L212qIcxshIw==", "dev": true, "dependencies": { "chalk": "^5.0.1", "commander": "^10.0.0", + "mermaid": "^10.8.0", "puppeteer": "^19.0.0" }, "bin": { @@ -1907,63 +1845,6 @@ "node": ">= 8" } }, - "node_modules/@puppeteer/browsers": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-0.5.0.tgz", - "integrity": "sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==", - "dev": true, - "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=14.1.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@puppeteer/browsers/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/@puppeteer/browsers/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1988,6 +1869,12 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2013,9 +1900,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", - "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -2053,6 +1940,36 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dev": true, + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==", + "dev": true + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "dev": true + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -2133,12 +2050,27 @@ "@types/mdurl": "*" } }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/mdurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, "node_modules/@types/node": { "version": "18.17.15", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.15.tgz", @@ -2165,6 +2097,12 @@ "integrity": "sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "node_modules/@types/urlsafe-base64": { "version": "1.0.29", "resolved": "https://registry.npmjs.org/@types/urlsafe-base64/-/urlsafe-base64-1.0.29.tgz", @@ -2190,9 +2128,9 @@ "dev": true }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "dependencies": { @@ -2524,15 +2462,15 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -2646,6 +2584,24 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -2748,15 +2704,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/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/babel-plugin-jest-hoist": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", @@ -2852,6 +2799,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", + "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2871,6 +2864,15 @@ } ] }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bip39": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", @@ -2888,41 +2890,6 @@ "pbkdf2": "^3.0.9" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2940,21 +2907,21 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "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==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "dev": true, "funding": [ { @@ -2971,10 +2938,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -3061,9 +3028,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001532", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001532.tgz", - "integrity": "sha512-FbDFnNat3nMnrROzqrsg314zhqN5LGQ1kyyMk2opcrwGbVGpHRhgCWtAgD5YJUqNAiQ+dklreil/c3Qf1dfCTw==", + "version": "1.0.30001642", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", + "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", "dev": true, "funding": [ { @@ -3113,22 +3080,14 @@ "node": ">=10" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/chromium-bidi": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz", - "integrity": "sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==", + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "dev": true, - "dependencies": { - "mitt": "3.0.0" - }, - "peerDependencies": { - "devtools-protocol": "*" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/ci-info": { @@ -3289,40 +3248,13 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/cosmiconfig": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", - "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", "dev": true, "dependencies": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - } - }, - "node_modules/cosmiconfig/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/cosmiconfig/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" + "layout-base": "^1.0.0" } }, "node_modules/create-hash": { @@ -3449,6 +3381,502 @@ "node": ">= 8" } }, + "node_modules/cytoscape": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.0.tgz", + "integrity": "sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dev": true, + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dev": true, + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dev": true, + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dev": true, + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dev": true, + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dev": true, + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dev": true, + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dev": true, + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dev": true, + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dev": true, + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dev": true, + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "dev": true + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dev": true, + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "dev": true + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dev": true, + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dev": true, + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dev": true, + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dev": true, + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dev": true, + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dev": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "dev": true, + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3471,6 +3899,19 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", @@ -3500,6 +3941,38 @@ "node": ">=0.10.0" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dev": true, + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3510,9 +3983,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1107588", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz", - "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==", + "version": "0.0.1299070", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1299070.tgz", + "integrity": "sha512-+qtL3eX50qsJ7c+qVyagqi7AWMoQCBGNfoyJZMwm/NSXVqLYbuitrWEEIzxfUmTNy7//Xe8yhMmQ+elj3uAqSg==", "dev": true }, "node_modules/diff": { @@ -3557,6 +4030,12 @@ "node": ">=6.0.0" } }, + "node_modules/dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", + "dev": true + }, "node_modules/ecdsa-secp256r1": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/ecdsa-secp256r1/-/ecdsa-secp256r1-1.3.3.tgz", @@ -3572,9 +4051,15 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.513", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.513.tgz", - "integrity": "sha512-cOB0xcInjm+E5qIssHeXJ29BaUyWpMyFKT5RB3bsLENDheCja0wMkHJyiPl0NBE/VzDI7JDuNEQWhe6RitEUcw==", + "version": "1.4.829", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.829.tgz", + "integrity": "sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw==", + "dev": true + }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==", "dev": true }, "node_modules/emittery": { @@ -3613,6 +4098,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3660,9 +4154,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -3685,6 +4179,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "8.53.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", @@ -3835,15 +4350,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3983,15 +4489,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -4004,7 +4501,7 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -4111,6 +4608,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -4179,9 +4682,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -4217,21 +4720,6 @@ "node": ">=12.0.0" } }, - "node_modules/flat-cache/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/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", @@ -4250,11 +4738,19 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -4321,6 +4817,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -4434,17 +4945,30 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -4456,6 +4980,18 @@ "node": ">=10.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -4556,6 +5092,34 @@ "resolved": "examples/integration-scripts", "link": true }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6065,6 +6629,12 @@ "xmlcreate": "^2.0.4" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "node_modules/jsdoc": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", @@ -6139,24 +6709,61 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "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/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, - "bin": { - "json5": "lib/cli.js" - }, "engines": { - "node": ">=6" + "node": ">= 12" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -6166,6 +6773,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==", + "dev": true + }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", @@ -6184,6 +6797,12 @@ "node": ">=6" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "dev": true + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -6252,6 +6871,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -6386,58 +7011,565 @@ "node": ">= 12" } }, - "node_modules/mathjs": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.0.tgz", - "integrity": "sha512-4Moy0RNjwMSajEkGGxNUyMMC/CZAcl87WBopvNsJWB4E4EFebpTedr+0/rhqmnOSTH3Wu/3WfiWiw6mqiaHxVw==", + "node_modules/mathjs": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.0.tgz", + "integrity": "sha512-4Moy0RNjwMSajEkGGxNUyMMC/CZAcl87WBopvNsJWB4E4EFebpTedr+0/rhqmnOSTH3Wu/3WfiWiw6mqiaHxVw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.1.tgz", + "integrity": "sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==", + "dev": true, + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.28.1", + "cytoscape-cose-bilkent": "^4.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5", + "elkjs": "^0.9.0", + "katex": "^0.16.9", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "@babel/runtime": "^7.23.9", - "complex.js": "^2.1.1", - "decimal.js": "^10.4.3", - "escape-latex": "^1.2.0", - "fraction.js": "4.3.4", - "javascript-natural-sort": "^0.7.1", - "seedrandom": "^3.0.5", - "tiny-emitter": "^2.1.0", - "typed-function": "^4.1.1" - }, - "bin": { - "mathjs": "bin/cli.js" - }, - "engines": { - "node": ">= 18" + "micromark-util-types": "^1.0.0" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "dev": true, - "engines": { - "node": ">= 8" - } + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, "node_modules/micromatch": { "version": "4.0.5", @@ -6484,12 +7616,6 @@ "node": "*" } }, - "node_modules/mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", - "dev": true - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6502,11 +7628,14 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } }, "node_modules/ms": { "version": "2.1.2", @@ -6520,6 +7649,15 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -6547,9 +7685,15 @@ "dev": true }, "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==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.17.tgz", + "integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==", + "dev": true + }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==", "dev": true }, "node_modules/normalize-path": { @@ -6665,6 +7809,38 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6759,9 +7935,9 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -6827,137 +8003,276 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-polyfill": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", + "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", + "dev": true + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.13.1.tgz", + "integrity": "sha512-PwXLDQK5u83Fm5A7TGMq+9BR7iHDJ8a3h21PSsh/E6VfhxiKYkU7+tvGZNSCap6k3pCNDd9oNteVBEctcBalmQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.2.4", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1299070", + "puppeteer-core": "22.13.1" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer/node_modules/@puppeteer/browsers": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.4.tgz", + "integrity": "sha512-BdG2qiI1dn89OTUUsx2GZSpUzW+DRffR1wlMJyKxVHYrhnKoELSDxDd+2XImUkuWPEKk76H5FcM/gPFrEK1Tfw==", + "dev": true, + "dependencies": { + "debug": "^4.3.5", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.2", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer/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/puppeteer/node_modules/chromium-bidi": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.1.tgz", + "integrity": "sha512-kSxJRj0VgtUKz6nmzc2JPfyfJGzwzt65u7PqhPHtgGQUZLF5oG+ST6l6e5ONfStUMAlhSutFCjaGKllXZa16jA==", + "dev": true, + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/puppeteer/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/puppeteer/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/puppeteer/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" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/puppeteer/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/promise-polyfill": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", - "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", + "node_modules/puppeteer/node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/puppeteer/node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "node_modules/puppeteer/node_modules/puppeteer-core": { + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.13.1.tgz", + "integrity": "sha512-NmhnASYp51QPRCAf9n0OPxuPMmzkKd8+2sB9Q+BjwwCG25gz6iuNc3LQDWa+cH2tyivmJppLhNNFt6Q3HmoOpw==", "dev": true, "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, + "@puppeteer/browsers": "2.2.4", + "chromium-bidi": "0.6.1", + "debug": "^4.3.5", + "devtools-protocol": "0.0.1299070", + "ws": "^8.18.0" + }, "engines": { - "node": ">=6" - } - }, - "node_modules/puppeteer": { - "version": "19.11.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.11.1.tgz", - "integrity": "sha512-39olGaX2djYUdhaQQHDZ0T0GwEp+5f9UB9HmEP0qHfdQHIq0xGQZuAZ5TLnJIc/88SrPLpEflPC+xUqOTv3c5g==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@puppeteer/browsers": "0.5.0", - "cosmiconfig": "8.1.3", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "puppeteer-core": "19.11.1" + "node": ">=18" } }, - "node_modules/puppeteer-core": { - "version": "19.11.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.11.1.tgz", - "integrity": "sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==", + "node_modules/puppeteer/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "@puppeteer/browsers": "0.5.0", - "chromium-bidi": "0.4.7", - "cross-fetch": "3.1.5", - "debug": "4.3.4", - "devtools-protocol": "0.0.1107588", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.1", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.13.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=14.14.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=10" } }, - "node_modules/puppeteer-core/node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "node_modules/puppeteer/node_modules/tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "dependencies": { - "node-fetch": "2.6.7" + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, - "node_modules/puppeteer-core/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "node_modules/puppeteer/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, "engines": { - "node": "4.x || >=6.0.0" + "node": ">=10.0.0" }, "peerDependencies": { - "encoding": "^0.1.0" + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { - "encoding": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { "optional": true } } @@ -6998,6 +8313,12 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -7097,6 +8418,22 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -7106,6 +8443,12 @@ "inherits": "^2.0.1" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "dev": true + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7129,6 +8472,24 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "dev": true + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7158,6 +8519,15 @@ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, + "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/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -7228,6 +8598,44 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7274,6 +8682,20 @@ "node": ">=8" } }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -7356,6 +8778,12 @@ "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.5.0.tgz", "integrity": "sha512-oLnmXSsjhud+LxRJpvokwP8ImEB2wTg8sg30buwfVViKMuluTv3BlOJHUX9VW9pJ2nQOxmx87Z0kB86O4cphag==" }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "dev": true + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7380,32 +8808,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/test-exclude": { @@ -7422,6 +8833,15 @@ "node": ">=8" } }, + "node_modules/text-decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7484,6 +8904,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-jest": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", @@ -7612,6 +9041,12 @@ } } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7757,10 +9192,32 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -7777,8 +9234,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -7796,11 +9253,66 @@ "punycode": "^2.1.0" } }, + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -7842,6 +9354,12 @@ "makeerror": "1.0.12" } }, + "node_modules/web-worker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", + "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==", + "dev": true + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -7898,33 +9416,21 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "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", @@ -7969,15 +9475,6 @@ "node": ">=12" } }, - "node_modules/yargs/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/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -8008,6 +9505,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index f77b7299..bf881b81 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "exports": { ".": { @@ -31,7 +31,7 @@ "name": "signify-ts", "author": "Phil Feairheller", "devDependencies": { - "@mermaid-js/mermaid-cli": "^10.3.0", + "@mermaid-js/mermaid-cli": "^10.6.1", "@types/jest": "^29.5.8", "@types/libsodium-wrappers-sumo": "^0.7.5", "@types/node": "^18.11.18", @@ -61,6 +61,11 @@ "mathjs": "^12.4.0", "structured-headers": "^0.5.0" }, + "overrides": { + "@mermaid-js/mermaid-cli@^10.6.1": { + "puppeteer": "^22" + } + }, "workspaces": [ "examples/*" ] diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index 290acd2c..7bab1c48 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -7,6 +7,7 @@ import { MtrDex } from '../core/matter'; import { Serder } from '../core/serder'; import { parseRangeHeaders } from '../core/httping'; import { KeyManager } from '../core/keeping'; +import { Operation } from './coring'; import { HabState } from '../core/state'; /** Arguments required to create an identfier */ @@ -257,6 +258,20 @@ export class Identifier { * @returns {Promise} A promise to the interaction event result */ async interact(name: string, data?: any): Promise { + let { serder, sigs, jsondata } = await this.createInteract(name, data); + + const res = await this.client.fetch( + '/identifiers/' + name + '/events', + 'POST', + jsondata + ); + return new EventResult(serder, sigs, res); + } + + async createInteract( + name: string, + data?: any + ): Promise<{ serder: any; sigs: any; jsondata: any }> { const hab = await this.get(name); const pre: string = hab.prefix; @@ -282,13 +297,7 @@ export class Identifier { sigs: sigs, }; jsondata[keeper.algo] = keeper.params(); - - const res = await this.client.fetch( - '/identifiers/' + name + '?type=ixn', - 'PUT', - jsondata - ); - return new EventResult(serder, sigs, res); + return { serder, sigs, jsondata }; } /** @@ -382,8 +391,8 @@ export class Identifier { jsondata[keeper.algo] = keeper.params(); const res = await this.client.fetch( - '/identifiers/' + name, - 'PUT', + '/identifiers/' + name + '/events', + 'POST', jsondata ); return new EventResult(serder, sigs, res); diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index 4c7d5c0f..9da24ecd 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -8,6 +8,7 @@ import { Contacts, Challenges } from './contacting'; import { Agent, Controller } from './controller'; import { Oobis, Operations, KeyEvents, KeyStates } from './coring'; import { Credentials, Ipex, Registries, Schemas } from './credentialing'; +import { Delegations } from './delegating'; import { Escrows } from './escrowing'; import { Exchanges } from './exchanging'; import { Groups } from './grouping'; @@ -469,4 +470,12 @@ export class SignifyClient { exchanges(): Exchanges { return new Exchanges(this); } + + /** + * Get delegations resource + * @returns {Delegations} + */ + delegations(): Delegations { + return new Delegations(this); + } } diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index f6a4e4f3..36ce5eb0 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -776,7 +776,7 @@ export class Ipex { '/ipex/grant', data, embeds, - undefined, + args.recipient, args.datetime, args.agree ); @@ -832,7 +832,7 @@ export class Ipex { '/ipex/admit', data, {}, - undefined, + '', datetime, grant ); diff --git a/src/keri/app/delegating.ts b/src/keri/app/delegating.ts new file mode 100644 index 00000000..b145a843 --- /dev/null +++ b/src/keri/app/delegating.ts @@ -0,0 +1,33 @@ +import { EventResult } from './aiding'; +import { SignifyClient } from './clienting'; + +export class Delegations { + public client: SignifyClient; + /** + * Delegations + * @param {SignifyClient} client + */ + constructor(client: SignifyClient) { + this.client = client; + } + + /** + * Approve the delegation via interaction event + * @async + * @param {string} name Name or alias of the identifier + * @param {any} [data] The anchoring interaction event + * @returns {Promise} A promise to the delegated approval result + */ + async approve(name: string, data?: any): Promise { + let { serder, sigs, jsondata } = await this.client + .identifiers() + .createInteract(name, data); + + const res = await this.client.fetch( + '/identifiers/' + name + '/delegation', + 'POST', + jsondata + ); + return new EventResult(serder, sigs, res); + } +} diff --git a/src/keri/app/exchanging.ts b/src/keri/app/exchanging.ts index 00dd0809..cb9f9e4b 100644 --- a/src/keri/app/exchanging.ts +++ b/src/keri/app/exchanging.ts @@ -38,7 +38,7 @@ export class Exchanges { route: string, payload: Dict, embeds: Dict, - recipient?: string, + recipient: string, datetime?: string, dig?: string ): Promise<[Serder, string[], string]> { @@ -79,20 +79,23 @@ export class Exchanges { embeds: Dict, recipients: string[] ): Promise { - const [exn, sigs, atc] = await this.createExchangeMessage( - sender, - route, - payload, - embeds - ); - return await this.sendFromEvents( - name, - topic, - exn, - sigs, - atc, - recipients - ); + for (const recipient of recipients) { + const [exn, sigs, atc] = await this.createExchangeMessage( + sender, + route, + payload, + embeds, + recipient + ); + return await this.sendFromEvents( + name, + topic, + exn, + sigs, + atc, + recipients + ); + } } /** @@ -146,7 +149,7 @@ export function exchange( route: string, payload: Dict, sender: string, - recipient?: string, + recipient: string, date?: string, dig?: string, modifiers?: Dict, @@ -192,9 +195,7 @@ export function exchange( const attrs = {} as Dict; - if (recipient !== undefined) { - attrs['i'] = recipient; - } + attrs['i'] = recipient; const a = { ...attrs, @@ -206,6 +207,7 @@ export function exchange( t: ilk, d: '', i: sender, + rp: recipient, p: p, dt: dt, r: route, diff --git a/test/app/aiding.test.ts b/test/app/aiding.test.ts index 8a5c95f1..84dfe205 100644 --- a/test/app/aiding.test.ts +++ b/test/app/aiding.test.ts @@ -208,8 +208,8 @@ describe('Aiding', () => { await client.identifiers().rotate('aid1'); const lastCall = client.getLastMockRequest(); - assert.equal(lastCall.path, '/identifiers/aid1'); - assert.equal(lastCall.method, 'PUT'); + assert.equal(lastCall.path, '/identifiers/aid1/events'); + assert.equal(lastCall.method, 'POST'); assert.deepEqual(lastCall.body.rot, { v: 'KERI10JSON000160_', t: 'rot', @@ -254,8 +254,8 @@ describe('Aiding', () => { await client.identifiers().rotate('aid1'); const lastCall = client.getLastMockRequest(); - assert.equal(lastCall.path, '/identifiers/aid1'); - assert.equal(lastCall.method, 'PUT'); + assert.equal(lastCall.path, '/identifiers/aid1/events'); + assert.equal(lastCall.method, 'POST'); expect(lastCall.body.rot).toMatchObject({ v: 'KERI10JSON000160_', t: 'rot', @@ -280,8 +280,8 @@ describe('Aiding', () => { const lastCall = client.getLastMockRequest(); - expect(lastCall.path).toEqual('/identifiers/aid1?type=ixn'); - expect(lastCall.method).toEqual('PUT'); + expect(lastCall.path).toEqual('/identifiers/aid1/events'); + expect(lastCall.method).toEqual('POST'); expect(lastCall.body.ixn).toMatchObject({ v: 'KERI10JSON000138_', t: 'ixn', @@ -322,8 +322,8 @@ describe('Aiding', () => { const lastCall = client.getLastMockRequest(); - expect(lastCall.path).toEqual('/identifiers/aid1?type=ixn'); - expect(lastCall.method).toEqual('PUT'); + expect(lastCall.path).toEqual('/identifiers/aid1/events'); + expect(lastCall.method).toEqual('POST'); expect(lastCall.body.ixn).toMatchObject({ s: 'b', a: data, diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index dfefeaca..53d64243 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -419,13 +419,14 @@ describe('Ipex', () => { }); assert.deepStrictEqual(grant.ked, { - v: 'KERI10JSON0004b1_', + v: 'KERI10JSON0004e5_', t: 'exn', - d: 'ECO262mMZcwP94aY0cUl5IL6LOK_R_Md1irVDdQEwtHl', + d: 'EPVuNFwXTG56BvNtGjeyxncY-MfZMXOAgEtsmIvktkdb', i: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', p: '', dt: '2023-08-23T15:16:07.553000+00:00', r: '/ipex/grant', + rp: 'ELjSFdrTdCebJlmvbFNX9-TLhR2PO0_60al1kQp5_e6k', q: {}, a: { m: '', i: 'ELjSFdrTdCebJlmvbFNX9-TLhR2PO0_60al1kQp5_e6k' }, e: { @@ -465,7 +466,7 @@ describe('Ipex', () => { }); assert.deepStrictEqual(gsigs, [ - 'AAAebNnWRghQuqDS0nXjy1MYht4D1_Sk_tozU0dikS-bOmmGV4AB3Ekt_sl04D7fIgkFGPQJ9gNhqNNS_uxsjNQE', + 'AADGVl57V4gcKYPO_Dn4UuYIdHI62vEQP--U3pnsl8oCqiqQbRqjw2E_7PHBy5-U78de5rhfF4UZQBFeub5evO8M', ]); assert.equal( end, @@ -508,20 +509,21 @@ describe('Ipex', () => { ); assert.deepStrictEqual(admit.ked, { - v: 'KERI10JSON000111_', + v: 'KERI10JSON000120_', t: 'exn', - d: 'EB7FkJBteJSZVV_dsjd0dmx6ORoRO6hJY91HR0z-x9tF', + d: 'EHMPkdV7QJ3a4RoDg43ffa7ytO6VbvEE4WiIbfcYvZNe', i: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', - p: 'ECO262mMZcwP94aY0cUl5IL6LOK_R_Md1irVDdQEwtHl', + p: 'EPVuNFwXTG56BvNtGjeyxncY-MfZMXOAgEtsmIvktkdb', dt: '2023-08-23T15:16:07.553000+00:00', r: '/ipex/admit', + rp: '', q: {}, - a: { m: '' }, + a: { m: '', i: '' }, e: {}, }); assert.deepStrictEqual(asigs, [ - 'AAD6NAWzEr_KonMJhKL32JLTVZ2_xwVNMqlr-ovAwoIQS5IEWZ8POd4rbWO49-8NqK8GedjUyii3y9o1b0QkYzQJ', + 'AADpPFED69bio-P5KtvUO46hkGzN-gGr2ob83jq_AGrmRcwUWIy71iClQ0YggT75T-ORwEIN4dIvIABv7z1r6UIH', ]); await ipex.submitAdmit('multisig', admit, asigs, aend, [holder]); diff --git a/test/app/delegating.test.ts b/test/app/delegating.test.ts new file mode 100644 index 00000000..a1b45caf --- /dev/null +++ b/test/app/delegating.test.ts @@ -0,0 +1,165 @@ +import { strict as assert } from 'assert'; +import { Salter, Tier } from '../../src'; +import libsodium from 'libsodium-wrappers-sumo'; +import { SignifyClient } from '../../src/keri/app/clienting'; +import { Authenticater } from '../../src/keri/core/authing'; +import fetchMock from 'jest-fetch-mock'; +import 'whatwg-fetch'; + +fetchMock.enableMocks(); + +const url = 'http://127.0.0.1:3901'; +const boot_url = 'http://127.0.0.1:3903'; + +const mockConnect = + '{"agent":{"vn":[1,0],"i":"EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei",' + + '"s":"0","p":"","d":"EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei","f":"0",' + + '"dt":"2023-08-19T21:04:57.948863+00:00","et":"dip","kt":"1",' + + '"k":["DMZh_y-H5C3cSbZZST-fqnsmdNTReZxIh0t2xSTOJQ8a"],"nt":"1",' + + '"n":["EM9M2EQNCBK0MyAhVYBvR98Q0tefpvHgE-lHLs82XgqC"],"bt":"0","b":[],' + + '"c":[],"ee":{"s":"0","d":"EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei","br":[],"ba":[]},' + + '"di":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose"},"controller":{"state":{"vn":[1,0],' + + '"i":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose","s":"0","p":"",' + + '"d":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose","f":"0","dt":"2023-08-19T21:04:57.959047+00:00",' + + '"et":"icp","kt":"1","k":["DAbWjobbaLqRB94KiAutAHb_qzPpOHm3LURA_ksxetVc"],"nt":"1",' + + '"n":["EIFG_uqfr1yN560LoHYHfvPAhxQ5sN6xZZT_E3h7d2tL"],"bt":"0","b":[],"c":[],"ee":{"s":"0",' + + '"d":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose","br":[],"ba":[]},"di":""},' + + '"ee":{"v":"KERI10JSON00012b_","t":"icp","d":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose",' + + '"i":"ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose","s":"0","kt":"1",' + + '"k":["DAbWjobbaLqRB94KiAutAHb_qzPpOHm3LURA_ksxetVc"],"nt":"1",' + + '"n":["EIFG_uqfr1yN560LoHYHfvPAhxQ5sN6xZZT_E3h7d2tL"],"bt":"0","b":[],"c":[],"a":[]}},"ridx":0,' + + '"pidx":0}'; +const mockGetAID = { + name: 'aid1', + prefix: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + salty: { + sxlt: '1AAHnNQTkD0yxOC9tSz_ukbB2e-qhDTStH18uCsi5PCwOyXLONDR3MeKwWv_AVJKGKGi6xiBQH25_R1RXLS2OuK3TN3ovoUKH7-A', + pidx: 0, + kidx: 0, + stem: 'signify:aid', + tier: 'low', + dcode: 'E', + icodes: ['A'], + ncodes: ['A'], + transferable: true, + }, + transferable: true, + state: { + vn: [1, 0], + i: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + s: '0', + p: '', + d: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + f: '0', + dt: '2023-08-21T22:30:46.473545+00:00', + et: 'icp', + kt: '1', + k: ['DPmhSfdhCPxr3EqjxzEtF8TVy0YX7ATo0Uc8oo2cnmY9'], + nt: '1', + n: ['EAORnRtObOgNiOlMolji-KijC_isa3lRDpHCsol79cOc'], + bt: '0', + b: [], + c: [], + ee: { + s: '0', + d: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + br: [], + ba: [], + }, + di: '', + }, + windexes: [], +}; + +fetchMock.mockResponse((req) => { + if (req.url.startsWith(url + '/agent')) { + return Promise.resolve({ body: mockConnect, init: { status: 202 } }); + } else if (req.url == boot_url + '/boot') { + return Promise.resolve({ body: '', init: { status: 202 } }); + } else { + const headers = new Headers(); + let signed_headers = new Headers(); + + headers.set( + 'Signify-Resource', + 'EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei' + ); + headers.set( + 'Signify-Timestamp', + new Date().toISOString().replace('Z', '000+00:00') + ); + headers.set('Content-Type', 'application/json'); + + const requrl = new URL(req.url); + const salter = new Salter({ qb64: '0AAwMTIzNDU2Nzg5YWJjZGVm' }); + const signer = salter.signer( + 'A', + true, + 'agentagent-ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose00', + Tier.low + ); + + const authn = new Authenticater(signer!, signer!.verfer); + signed_headers = authn.sign( + headers, + req.method, + requrl.pathname.split('?')[0] + ); + const body = mockGetAID; + + return Promise.resolve({ + body: JSON.stringify(body), + init: { status: 202, headers: signed_headers }, + }); + } +}); + +describe('delegate', () => { + it('approve delegation', async () => { + await libsodium.ready; + const bran = '0123456789abcdefghijk'; + const client = new SignifyClient(url, bran, Tier.low, boot_url); + await client.boot(); + await client.connect(); + const delegations = client.delegations(); + await delegations.approve( + 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao' + ); + const lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1]!; + assert.equal( + lastCall[0]!, + url + + '/identifiers/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao/delegation' + ); + assert.equal(lastCall[1]!.method, 'POST'); + const expectedBody = { + ixn: { + v: 'KERI10JSON0000cf_', + t: 'ixn', + d: 'EBPt7hivibUQN-dlRyE9x_Y5LgFCGJ8QoNLSJrIkBYIg', + i: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + s: '1', + p: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', + a: [null], + }, + sigs: [ + 'AAC4StAw-0IiV_LujceAXB3tnkaK011rPYPBKLgz-u6jI7hwfWGTCu5LDvBUsON4CqXbZAwPgIv6JqYjIusWKv0G', + ], + salty: { + sxlt: '1AAHnNQTkD0yxOC9tSz_ukbB2e-qhDTStH18uCsi5PCwOyXLONDR3MeKwWv_AVJKGKGi6xiBQH25_R1RXLS2OuK3TN3ovoUKH7-A', + pidx: 0, + kidx: 0, + stem: 'signify:aid', + tier: 'low', + icodes: ['A'], + ncodes: ['A'], + dcode: 'E', + transferable: false, + }, + }; + assert.equal( + lastCall[1]!.body?.toString()!, + JSON.stringify(expectedBody) + ); + }); +}); diff --git a/test/app/exchanging.test.ts b/test/app/exchanging.test.ts index d9b4abb4..33ba5b96 100644 --- a/test/app/exchanging.test.ts +++ b/test/app/exchanging.test.ts @@ -170,18 +170,21 @@ describe('exchange', () => { await libsodium.ready; const dt = '2023-08-30T17:22:54.183Z'; - let [exn, end] = exchange('/multisig/vcp', {}, 'test', undefined, dt); + let [exn, end] = exchange('/multisig/vcp', {}, 'test', '', dt); assert.deepStrictEqual(exn.ked, { - a: {}, - d: 'EMhxioc6Ud9b3JZ4X9o79uytSRIXXNDUf27ruwiOmNdQ', + a: { + i: '', + }, + d: 'EPWm8LWxxQXmXlB8gbTZKDy7NIwXxpx49N_ZYTa5QkJV', dt: '2023-08-30T17:22:54.183Z', e: {}, i: 'test', p: '', q: {}, r: '/multisig/vcp', + rp: '', t: 'exn', - v: 'KERI10JSON0000b1_', + v: 'KERI10JSON0000bf_', }); assert.deepStrictEqual(end, new Uint8Array()); @@ -260,7 +263,7 @@ describe('exchange', () => { '/multisig/vcp', {}, 'test', - undefined, + '', dt, undefined, undefined, @@ -268,8 +271,10 @@ describe('exchange', () => { ); assert.deepStrictEqual(exn.ked, { - a: {}, - d: 'EHDEXQx-i0KlQ8iVnITMLa144dAb7Kjq2KDTufDUyLcm', + a: { + i: '', + }, + d: 'EOK2xNjB5xlSvizCUrkFKbdF4j1nsGpvt6TR1HL0wvaY', dt: '2023-08-30T17:22:54.183Z', e: { d: 'EDPWpKtMoPwro_Of8TQzpNMGdtmfyWzqTcRKQ01fGFRi', @@ -302,8 +307,9 @@ describe('exchange', () => { p: '', q: {}, r: '/multisig/vcp', + rp: '', t: 'exn', - v: 'KERI10JSON00020d_', + v: 'KERI10JSON00021b_', }); assert.equal( d(end),