@prosopo/provider 0.2.40 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,151 +0,0 @@
1
- import { AccountKey } from '../dataUtils/DatabaseAccounts.js';
2
- import { BN, BN_THOUSAND, BN_TWO, bnMin } from '@polkadot/util/bn';
3
- import { BatchCommitmentsTask } from '../../batch/commitments.js';
4
- import { ScheduledTaskNames } from '@prosopo/types';
5
- import { CaptchaStatus } from '@prosopo/captcha-contract/types-returns';
6
- import { MockEnvironment } from '@prosopo/env';
7
- import { ProsopoEnvError } from '@prosopo/common';
8
- import { accountAddress, accountContract, accountMnemonic, getSignedTasks } from '../accounts.js';
9
- import { afterEach, beforeEach, describe, expect, test } from 'vitest';
10
- import { at } from '@prosopo/util';
11
- import { getPairAsync, wrapQuery } from '@prosopo/contract';
12
- import { getTestConfig } from '@prosopo/config';
13
- import { getUser } from '../getUser.js';
14
- import { randomAsHex } from '@polkadot/util-crypto/random';
15
- import { sleep } from '../tasks/tasks.test.js';
16
- import { stringToHex } from '@polkadot/util/string';
17
- const THRESHOLD = BN_THOUSAND.div(BN_TWO);
18
- const DEFAULT_TIME = new BN(6000);
19
- const A_DAY = new BN(24 * 60 * 60 * 1000);
20
- function calcInterval(api) {
21
- return bnMin(A_DAY, api.consts.babe?.expectedBlockTime ||
22
- api.consts.difficulty?.targetBlockTime ||
23
- api.consts.subspace?.expectedBlockTime ||
24
- (api.consts.timestamp?.minimumPeriod.gte(THRESHOLD)
25
- ?
26
- api.consts.timestamp.minimumPeriod.mul(BN_TWO)
27
- : api.query.parachainSystem
28
- ?
29
- DEFAULT_TIME.mul(BN_TWO)
30
- :
31
- DEFAULT_TIME));
32
- }
33
- describe('BATCH TESTS', function () {
34
- beforeEach(async function (context) {
35
- const config = getTestConfig();
36
- const network = config.networks[config.defaultNetwork];
37
- const alicePair = await getPairAsync(network, '//Alice');
38
- context.env = new MockEnvironment(getTestConfig(), alicePair);
39
- try {
40
- await context.env.isReady();
41
- }
42
- catch (e) {
43
- throw new ProsopoEnvError(e);
44
- }
45
- const promiseStakeDefault = wrapQuery(context.env.getContractInterface().query.getProviderStakeThreshold, context.env.getContractInterface().query)();
46
- context.providerStakeThreshold = new BN((await promiseStakeDefault).toNumber());
47
- });
48
- afterEach(async ({ env }) => {
49
- if (env && 'db' in env)
50
- await env.db?.close();
51
- });
52
- const commitmentCount = 50;
53
- test(`Batches ~${commitmentCount} commitments on-chain`, async ({ env }) => {
54
- if (env.db) {
55
- const providerAccount = await getUser(env, AccountKey.providersWithStakeAndDataset);
56
- await env.changeSigner(await getPairAsync(env.config.networks[env.config.defaultNetwork], accountMnemonic(providerAccount), ''));
57
- const contractApi = await env.getContractApi();
58
- await env.db.tables?.commitment.deleteMany({});
59
- await env.db.tables?.usersolution.deleteMany({});
60
- const startNonce = await contractApi.api.call.accountNonceApi.accountNonce(accountAddress(providerAccount));
61
- const batcher = new BatchCommitmentsTask(env.config.batchCommit, await env.getContractApi(), env.db, BigInt(startNonce.toNumber()), env.logger);
62
- const providerTasks = await getSignedTasks(env, providerAccount);
63
- const providerDetails = (await providerTasks.contract.query.getProvider(accountAddress(providerAccount))).value
64
- .unwrap()
65
- .unwrap();
66
- const dappAccount = await getUser(env, AccountKey.dappsWithStake);
67
- const randomCaptchasResult = await providerTasks.db.getRandomCaptcha(true, providerDetails.datasetId);
68
- if (randomCaptchasResult) {
69
- const solutions = await providerTasks.db.getSolutions(providerDetails.datasetId.toString());
70
- const solutionIndex = solutions.findIndex((s) => s.captchaContentId === at(randomCaptchasResult, 0).captchaContentId);
71
- const solution = at(solutions, solutionIndex).solution;
72
- const unsolvedCaptcha = at(randomCaptchasResult, 0);
73
- const captchaSolution = { ...unsolvedCaptcha, solution, salt: randomAsHex() };
74
- const commitmentIds = [];
75
- const completedAt = (await env.getApi().rpc.chain.getBlock()).block.header.number.toNumber();
76
- const requestedAt = completedAt - 1;
77
- const requestHash = 'requestHash';
78
- for (let count = 0; count < commitmentCount; count++) {
79
- const dappUser = await getUser(env, AccountKey.dappUsers, false);
80
- const commitmentId = randomAsHex();
81
- commitmentIds.push(commitmentId);
82
- const status = count % 2 === 0 ? CaptchaStatus.approved : CaptchaStatus.disapproved;
83
- const signer = env.keyring.addFromMnemonic(accountMnemonic(dappUser));
84
- const userSignature = signer.sign(stringToHex(requestHash));
85
- const commit = {
86
- id: commitmentId,
87
- userAccount: accountAddress(dappUser),
88
- providerAccount: accountAddress(providerAccount),
89
- datasetId: providerDetails.datasetId.toString(),
90
- dappContract: accountContract(dappAccount),
91
- status,
92
- requestedAt,
93
- completedAt,
94
- userSignature: Array.from(userSignature),
95
- processed: false,
96
- batched: false,
97
- };
98
- await providerTasks.db.storeDappUserSolution([captchaSolution], commit);
99
- if (status === CaptchaStatus.approved) {
100
- await providerTasks.db.approveDappUserCommitment(commitmentId);
101
- }
102
- await sleep(10);
103
- const userSolutions = await providerTasks.db.getDappUserSolutionById(commitmentId);
104
- expect(userSolutions).to.be.not.empty;
105
- const commitRecord = await providerTasks.db.getDappUserCommitmentById(commitmentId);
106
- expect(commitRecord).to.be.not.empty;
107
- }
108
- const commitmentsBeforeBatching = await batcher.getCommitments();
109
- expect(commitmentsBeforeBatching.length).to.be.equal(commitmentCount);
110
- expect(commitmentsBeforeBatching
111
- .map((c) => +(c.status === CaptchaStatus.approved))
112
- .reduce((prev, next) => prev + next)).to.equal(Math.round(commitmentCount / 2));
113
- await batcher.run();
114
- const batcherResult = await env.db.getLastScheduledTaskStatus(ScheduledTaskNames.BatchCommitment);
115
- console.log('batcherResult', batcherResult);
116
- if (!batcherResult ||
117
- (batcherResult && !batcherResult.result) ||
118
- (batcherResult && batcherResult.result && !batcherResult.result.data)) {
119
- expect(true).to.be.false;
120
- }
121
- if (batcherResult && batcherResult.result && batcherResult.result.data) {
122
- const processedCommitmentIds = batcherResult.result.data.commitmentIds;
123
- const processedCommitments = commitmentsBeforeBatching.filter((commitment) => processedCommitmentIds.indexOf(commitment.id.toString()) > -1);
124
- const commitmentsFromDbAfter = await env.db.getUnbatchedDappUserCommitments();
125
- expect(commitmentsBeforeBatching.length - processedCommitments.length).to.equal(commitmentsFromDbAfter.length);
126
- const waitTime = calcInterval(contractApi.api).toNumber() * 2;
127
- env.logger.debug(`waiting ${waitTime}ms for commitments to be available on-chain`);
128
- await sleep(waitTime);
129
- let count = 0;
130
- for (const commitment of processedCommitments) {
131
- const approved = count % 2 === 0 ? 'Approved' : 'Disapproved';
132
- env.logger.debug(`Getting commitmentId ${commitment.id} from contract`);
133
- const contractCommitment = (await contractApi.query.getCommit(commitment.id)).value
134
- .unwrap()
135
- .unwrap();
136
- expect(contractCommitment).to.be.not.empty;
137
- expect(contractCommitment.status).to.be.equal(approved);
138
- count++;
139
- }
140
- const lastBatchCommit = await providerTasks.db.getLastScheduledTaskStatus(ScheduledTaskNames.BatchCommitment);
141
- expect(lastBatchCommit).to.be.not.empty;
142
- expect(lastBatchCommit.status).to.be.equal('Completed');
143
- if (lastBatchCommit !== undefined) {
144
- expect(+Date.now() - +lastBatchCommit?.datetime).to.be.lessThan(waitTime * 2);
145
- }
146
- }
147
- }
148
- }
149
- }, 24000);
150
- });
151
- //# sourceMappingURL=commitments.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"commitments.test.js","sourceRoot":"","sources":["../../../src/tests/batch/commitments.test.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAE7D,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,EAAmB,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAIjD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACjG,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAInD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC,IAAK,CAAC,CAAA;AAClC,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAEzC,SAAS,YAAY,CAAC,GAAe;IACjC,OAAO,KAAK,CACR,KAAK,EAEL,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB;QAE9B,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe;QAEtC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,iBAAiB;QAEtC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;YAC/C,CAAC;gBACC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;YAChD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe;gBAC3B,CAAC;oBACC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;gBAC1B,CAAC;oBACC,YAAY,CAAC,CAC1B,CAAA;AACL,CAAC;AAMD,QAAQ,CAAC,aAAa,EAAE;IACpB,UAAU,CAAC,KAAK,WAAW,OAAwB;QAC/C,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;QAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QACtD,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,GAAG,IAAI,eAAe,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC,CAAA;QAC7D,IAAI;YACA,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;SAC9B;QAAC,OAAO,CAAC,EAAE;YACR,MAAM,IAAI,eAAe,CAAC,CAAU,CAAC,CAAA;SACxC;QACD,MAAM,mBAAmB,GAA0B,SAAS,CACxD,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,KAAK,CAAC,yBAAyB,EAClE,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,KAAK,CAC3C,EAAE,CAAA;QACH,OAAO,CAAC,sBAAsB,GAAG,IAAI,EAAE,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;IACnF,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,EAAiB,EAAE;QACvC,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG;YAAE,MAAM,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,MAAM,eAAe,GAAG,EAAE,CAAA;IAE1B,IAAI,CAAC,YAAY,eAAe,uBAAuB,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;QACvE,IAAI,GAAG,CAAC,EAAE,EAAE;YACR,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,4BAA4B,CAAC,CAAA;YAEnF,MAAM,GAAG,CAAC,YAAY,CAClB,MAAM,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,CAC3G,CAAA;YAGD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,cAAc,EAAE,CAAA;YAI9C,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;YAC9C,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;YAGhD,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAA;YAI3G,MAAM,OAAO,GAAG,IAAI,oBAAoB,CACpC,GAAG,CAAC,MAAM,CAAC,WAAW,EACtB,MAAM,GAAG,CAAC,cAAc,EAAE,EAC1B,GAAG,CAAC,EAAE,EACN,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,EAC7B,GAAG,CAAC,MAAM,CACb,CAAA;YAED,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;YAChE,MAAM,eAAe,GAAG,CACpB,MAAM,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAClF,CAAC,KAAK;iBACF,MAAM,EAAE;iBACR,MAAM,EAAE,CAAA;YACb,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,cAAc,CAAC,CAAA;YACjE,MAAM,oBAAoB,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAA;YAErG,IAAI,oBAAoB,EAAE;gBACtB,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAC3F,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAAK,EAAE,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAC7E,CAAA;gBACD,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAA;gBACtD,MAAM,eAAe,GAAG,EAAE,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAA;gBACnD,MAAM,eAAe,GAAoB,EAAE,GAAG,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAA;gBAC9F,MAAM,aAAa,GAAa,EAAE,CAAA;gBAGlC,MAAM,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;gBAC5F,MAAM,WAAW,GAAG,WAAW,GAAG,CAAC,CAAA;gBACnC,MAAM,WAAW,GAAG,aAAa,CAAA;gBACjC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,eAAe,EAAE,KAAK,EAAE,EAAE;oBAGlD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;oBAEhE,MAAM,YAAY,GAAG,WAAW,EAAE,CAAA;oBAClC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBAChC,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,CAAA;oBACnF,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAA;oBACrE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAA;oBAC3D,MAAM,MAAM,GAAyB;wBACjC,EAAE,EAAE,YAAY;wBAChB,WAAW,EAAE,cAAc,CAAC,QAAQ,CAAC;wBACrC,eAAe,EAAE,cAAc,CAAC,eAAe,CAAC;wBAChD,SAAS,EAAE,eAAe,CAAC,SAAS,CAAC,QAAQ,EAAE;wBAC/C,YAAY,EAAE,eAAe,CAAC,WAAW,CAAC;wBAC1C,MAAM;wBACN,WAAW;wBACX,WAAW;wBACX,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC;wBACxC,SAAS,EAAE,KAAK;wBAChB,OAAO,EAAE,KAAK;qBACjB,CAAA;oBACD,MAAM,aAAa,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,CAAA;oBACvE,IAAI,MAAM,KAAK,aAAa,CAAC,QAAQ,EAAE;wBACnC,MAAM,aAAa,CAAC,EAAE,CAAC,yBAAyB,CAAC,YAAY,CAAC,CAAA;qBACjE;oBACD,MAAM,KAAK,CAAC,EAAE,CAAC,CAAA;oBACf,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAA;oBAClF,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAA;oBACrC,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,yBAAyB,CAAC,YAAY,CAAC,CAAA;oBACnF,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAA;iBACvC;gBAED,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAA;gBAEhE,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;gBAGrE,MAAM,CACF,yBAAyB;qBACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC;qBAClD,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAC3C,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAA;gBAG3C,MAAM,OAAO,CAAC,GAAG,EAAE,CAAA;gBAyBnB,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAA;gBACjG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;gBAC3C,IACI,CAAC,aAAa;oBACd,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;oBACxC,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EACvE;oBACE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAA;iBAC3B;gBAED,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE;oBACpE,MAAM,sBAAsB,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAA;oBACtE,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,MAAM,CACzD,CAAC,UAAU,EAAE,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAChF,CAAA;oBAGD,MAAM,sBAAsB,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,+BAA+B,EAAE,CAAA;oBAI7E,MAAM,CAAC,yBAAyB,CAAC,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAC3E,sBAAsB,CAAC,MAAM,CAChC,CAAA;oBAGD,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC,GAAiB,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;oBAC3E,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,QAAQ,6CAA6C,CAAC,CAAA;oBAClF,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAA;oBAIrB,IAAI,KAAK,GAAG,CAAC,CAAA;oBACb,KAAK,MAAM,UAAU,IAAI,oBAAoB,EAAE;wBAC3C,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAA;wBAC7D,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAA;wBACvE,MAAM,kBAAkB,GAAG,CAAC,MAAM,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;6BAC9E,MAAM,EAAE;6BACR,MAAM,EAAE,CAAA;wBACb,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAA;wBAC1C,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;wBACvD,KAAK,EAAE,CAAA;qBACV;oBAED,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,0BAA0B,CACrE,kBAAkB,CAAC,eAAe,CACrC,CAAA;oBACD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAA;oBACvC,MAAM,CAAC,eAAgB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;oBAGxD,IAAI,eAAe,KAAK,SAAS,EAAE;wBAC/B,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAA;qBAChF;iBACJ;aACJ;SACJ;IACL,CAAC,EAAE,KAAK,CAAC,CAAA;AACb,CAAC,CAAC,CAAA"}