@brightchain/brightchain-api-lib 0.12.0 → 0.13.0
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.
- package/package.json +4 -4
- package/src/lib/application-base.d.ts +1 -1
- package/src/lib/application-base.d.ts.map +1 -1
- package/src/lib/application.d.ts +52 -0
- package/src/lib/application.d.ts.map +1 -1
- package/src/lib/application.js +104 -0
- package/src/lib/application.js.map +1 -1
- package/src/lib/controllers/api/blocks.d.ts.map +1 -1
- package/src/lib/controllers/api/blocks.js +62 -0
- package/src/lib/controllers/api/blocks.js.map +1 -1
- package/src/lib/controllers/api/docs.d.ts +67 -0
- package/src/lib/controllers/api/docs.d.ts.map +1 -0
- package/src/lib/controllers/api/docs.js +86 -0
- package/src/lib/controllers/api/docs.js.map +1 -0
- package/src/lib/controllers/api/energy.d.ts.map +1 -1
- package/src/lib/controllers/api/energy.js +35 -7
- package/src/lib/controllers/api/energy.js.map +1 -1
- package/src/lib/controllers/api/health.d.ts +95 -0
- package/src/lib/controllers/api/health.d.ts.map +1 -0
- package/src/lib/controllers/api/health.js +319 -0
- package/src/lib/controllers/api/health.js.map +1 -0
- package/src/lib/controllers/api/index.d.ts +6 -0
- package/src/lib/controllers/api/index.d.ts.map +1 -1
- package/src/lib/controllers/api/index.js +6 -0
- package/src/lib/controllers/api/index.js.map +1 -1
- package/src/lib/controllers/api/messages.d.ts +119 -0
- package/src/lib/controllers/api/messages.d.ts.map +1 -0
- package/src/lib/controllers/api/messages.js +269 -0
- package/src/lib/controllers/api/messages.js.map +1 -0
- package/src/lib/controllers/api/nodes.d.ts +152 -0
- package/src/lib/controllers/api/nodes.d.ts.map +1 -0
- package/src/lib/controllers/api/nodes.js +378 -0
- package/src/lib/controllers/api/nodes.js.map +1 -0
- package/src/lib/controllers/api/quorum.d.ts +12 -8
- package/src/lib/controllers/api/quorum.d.ts.map +1 -1
- package/src/lib/controllers/api/quorum.js +83 -17
- package/src/lib/controllers/api/quorum.js.map +1 -1
- package/src/lib/controllers/api/scbl.d.ts +80 -0
- package/src/lib/controllers/api/scbl.d.ts.map +1 -0
- package/src/lib/controllers/api/scbl.js +325 -0
- package/src/lib/controllers/api/scbl.js.map +1 -0
- package/src/lib/controllers/api/sync.d.ts +140 -0
- package/src/lib/controllers/api/sync.d.ts.map +1 -0
- package/src/lib/controllers/api/sync.js +352 -0
- package/src/lib/controllers/api/sync.js.map +1 -0
- package/src/lib/controllers/api/user.d.ts +2 -0
- package/src/lib/controllers/api/user.d.ts.map +1 -1
- package/src/lib/controllers/api/user.js +122 -7
- package/src/lib/controllers/api/user.js.map +1 -1
- package/src/lib/enumerations/brightChainApiStrings.d.ts.map +1 -1
- package/src/lib/enumerations/brightChainApiStrings.js.map +1 -1
- package/src/lib/errors/symmetric.d.ts +2 -2
- package/src/lib/errors/symmetric.d.ts.map +1 -1
- package/src/lib/errors/symmetric.js.map +1 -1
- package/src/lib/errors/typed-error-local.d.ts +3 -3
- package/src/lib/errors/typed-error-local.d.ts.map +1 -1
- package/src/lib/errors/typed-error-local.js.map +1 -1
- package/src/lib/interfaces/application.d.ts +2 -1
- package/src/lib/interfaces/application.d.ts.map +1 -1
- package/src/lib/interfaces/backend-objects/index.d.ts +4 -4
- package/src/lib/interfaces/backend-objects/index.d.ts.map +1 -1
- package/src/lib/interfaces/backend-objects/index.js +0 -5
- package/src/lib/interfaces/backend-objects/index.js.map +1 -1
- package/src/lib/interfaces/bases/index.d.ts +4 -4
- package/src/lib/interfaces/bases/index.d.ts.map +1 -1
- package/src/lib/interfaces/bases/index.js +0 -5
- package/src/lib/interfaces/bases/index.js.map +1 -1
- package/src/lib/interfaces/index.d.ts +32 -32
- package/src/lib/interfaces/index.d.ts.map +1 -1
- package/src/lib/interfaces/index.js +0 -33
- package/src/lib/interfaces/index.js.map +1 -1
- package/src/lib/interfaces/member/index.d.ts +3 -3
- package/src/lib/interfaces/member/index.d.ts.map +1 -1
- package/src/lib/interfaces/member/index.js +0 -4
- package/src/lib/interfaces/member/index.js.map +1 -1
- package/src/lib/interfaces/requests/deleteMessagesRequest.d.ts +12 -0
- package/src/lib/interfaces/requests/deleteMessagesRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/deleteMessagesRequest.js +3 -0
- package/src/lib/interfaces/requests/deleteMessagesRequest.js.map +1 -0
- package/src/lib/interfaces/requests/discoverBlockRequest.d.ts +10 -0
- package/src/lib/interfaces/requests/discoverBlockRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/discoverBlockRequest.js +3 -0
- package/src/lib/interfaces/requests/discoverBlockRequest.js.map +1 -0
- package/src/lib/interfaces/requests/getBlockLocationRequest.d.ts +9 -0
- package/src/lib/interfaces/requests/getBlockLocationRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/getBlockLocationRequest.js +3 -0
- package/src/lib/interfaces/requests/getBlockLocationRequest.js.map +1 -0
- package/src/lib/interfaces/requests/getMessageRequest.d.ts +12 -0
- package/src/lib/interfaces/requests/getMessageRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/getMessageRequest.js +3 -0
- package/src/lib/interfaces/requests/getMessageRequest.js.map +1 -0
- package/src/lib/interfaces/requests/getNodeRequest.d.ts +9 -0
- package/src/lib/interfaces/requests/getNodeRequest.d.ts.map +1 -0
- package/src/lib/interfaces/{membersResponse.js → requests/getNodeRequest.js} +1 -1
- package/src/lib/interfaces/requests/getNodeRequest.js.map +1 -0
- package/src/lib/interfaces/requests/index.d.ts +12 -0
- package/src/lib/interfaces/requests/index.d.ts.map +1 -0
- package/src/lib/interfaces/requests/index.js +3 -0
- package/src/lib/interfaces/requests/index.js.map +1 -0
- package/src/lib/interfaces/requests/messageRequest.d.ts +10 -0
- package/src/lib/interfaces/requests/messageRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/messageRequest.js +3 -0
- package/src/lib/interfaces/requests/messageRequest.js.map +1 -0
- package/src/lib/interfaces/requests/queryMessagesRequest.d.ts +16 -0
- package/src/lib/interfaces/requests/queryMessagesRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/queryMessagesRequest.js +3 -0
- package/src/lib/interfaces/requests/queryMessagesRequest.js.map +1 -0
- package/src/lib/interfaces/requests/registerNodeRequest.d.ts +11 -0
- package/src/lib/interfaces/requests/registerNodeRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/registerNodeRequest.js +3 -0
- package/src/lib/interfaces/requests/registerNodeRequest.js.map +1 -0
- package/src/lib/interfaces/requests/replicateBlockRequest.d.ts +13 -0
- package/src/lib/interfaces/requests/replicateBlockRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/replicateBlockRequest.js +3 -0
- package/src/lib/interfaces/requests/replicateBlockRequest.js.map +1 -0
- package/src/lib/interfaces/requests/sendMessageRequest.d.ts +24 -0
- package/src/lib/interfaces/requests/sendMessageRequest.d.ts.map +1 -0
- package/src/lib/interfaces/requests/sendMessageRequest.js +3 -0
- package/src/lib/interfaces/requests/sendMessageRequest.js.map +1 -0
- package/src/lib/interfaces/requests/storeSCBLRequestBody.d.ts +9 -0
- package/src/lib/interfaces/requests/storeSCBLRequestBody.d.ts.map +1 -0
- package/src/lib/interfaces/requests/storeSCBLRequestBody.js +3 -0
- package/src/lib/interfaces/requests/storeSCBLRequestBody.js.map +1 -0
- package/src/lib/interfaces/requests/syncRequestBody.d.ts +10 -0
- package/src/lib/interfaces/requests/syncRequestBody.d.ts.map +1 -0
- package/src/lib/interfaces/requests/syncRequestBody.js +3 -0
- package/src/lib/interfaces/requests/syncRequestBody.js.map +1 -0
- package/src/lib/interfaces/responses/index.d.ts +7 -7
- package/src/lib/interfaces/responses/index.d.ts.map +1 -1
- package/src/lib/interfaces/responses/index.js +0 -8
- package/src/lib/interfaces/responses/index.js.map +1 -1
- package/src/lib/middlewares/authentication.d.ts +133 -0
- package/src/lib/middlewares/authentication.d.ts.map +1 -0
- package/src/lib/middlewares/authentication.js +224 -0
- package/src/lib/middlewares/authentication.js.map +1 -0
- package/src/lib/middlewares/index.d.ts +2 -0
- package/src/lib/middlewares/index.d.ts.map +1 -1
- package/src/lib/middlewares/index.js +15 -1
- package/src/lib/middlewares/index.js.map +1 -1
- package/src/lib/middlewares/request-id.d.ts +18 -0
- package/src/lib/middlewares/request-id.d.ts.map +1 -0
- package/src/lib/middlewares/request-id.js +30 -0
- package/src/lib/middlewares/request-id.js.map +1 -0
- package/src/lib/openapi/index.d.ts +8 -0
- package/src/lib/openapi/index.d.ts.map +1 -0
- package/src/lib/openapi/index.js +21 -0
- package/src/lib/openapi/index.js.map +1 -0
- package/src/lib/openapi/schemas.d.ts +15 -0
- package/src/lib/openapi/schemas.d.ts.map +1 -0
- package/src/lib/openapi/schemas.js +610 -0
- package/src/lib/openapi/schemas.js.map +1 -0
- package/src/lib/routers/api.d.ts +62 -0
- package/src/lib/routers/api.d.ts.map +1 -1
- package/src/lib/routers/api.js +85 -0
- package/src/lib/routers/api.js.map +1 -1
- package/src/lib/services/diskQuorumService.d.ts +7 -6
- package/src/lib/services/diskQuorumService.d.ts.map +1 -1
- package/src/lib/services/diskQuorumService.js.map +1 -1
- package/src/lib/services/email.d.ts +2 -1
- package/src/lib/services/email.d.ts.map +1 -1
- package/src/lib/services/email.js.map +1 -1
- package/src/lib/services/eventNotificationSystem.d.ts +88 -6
- package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
- package/src/lib/services/eventNotificationSystem.js +132 -17
- package/src/lib/services/eventNotificationSystem.js.map +1 -1
- package/src/lib/services/fec.js +1 -1
- package/src/lib/services/fec.js.map +1 -1
- package/src/lib/types/backend-id.d.ts +2 -1
- package/src/lib/types/backend-id.d.ts.map +1 -1
- package/src/lib/utils/errorResponse.d.ts +227 -2
- package/src/lib/utils/errorResponse.d.ts.map +1 -1
- package/src/lib/utils/errorResponse.js +292 -3
- package/src/lib/utils/errorResponse.js.map +1 -1
- package/src/lib/i18n/index.d.ts +0 -7
- package/src/lib/i18n/index.d.ts.map +0 -1
- package/src/lib/i18n/index.js +0 -29
- package/src/lib/i18n/index.js.map +0 -1
- package/src/lib/i18n/strings/index.d.ts +0 -6
- package/src/lib/i18n/strings/index.d.ts.map +0 -1
- package/src/lib/i18n/strings/index.js +0 -17
- package/src/lib/i18n/strings/index.js.map +0 -1
- package/src/lib/interfaces/membersResponse.d.ts +0 -12
- package/src/lib/interfaces/membersResponse.d.ts.map +0 -1
- package/src/lib/interfaces/membersResponse.js.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { RetrieveSCBLResponse, StoreSCBLResponse } from '@brightchain/brightchain-lib';
|
|
2
|
+
import { CoreLanguageCode } from '@digitaldefiance/i18n-lib';
|
|
3
|
+
import { PlatformID } from '@digitaldefiance/node-ecies-lib';
|
|
4
|
+
import { Request } from 'express';
|
|
5
|
+
import { IBrightChainApplication } from '../../interfaces';
|
|
6
|
+
import { DefaultBackendIdType } from '../../shared-types';
|
|
7
|
+
import { BaseController } from '../base';
|
|
8
|
+
/**
|
|
9
|
+
* Handler keys for the SCBL controller
|
|
10
|
+
*/
|
|
11
|
+
interface SCBLHandlers {
|
|
12
|
+
storeSCBL: string;
|
|
13
|
+
retrieveSCBL: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Controller for Super CBL (Hierarchical Constituent Block List) operations.
|
|
17
|
+
*
|
|
18
|
+
* Super CBLs enable storage of files larger than a single CBL can reference
|
|
19
|
+
* through recursive sub-CBL structures. This controller provides endpoints
|
|
20
|
+
* for storing and retrieving large files using the Super CBL hierarchy.
|
|
21
|
+
*
|
|
22
|
+
* ## Endpoints
|
|
23
|
+
*
|
|
24
|
+
* ### POST /api/scbl/store
|
|
25
|
+
* Store a large file as a Super CBL hierarchy.
|
|
26
|
+
*
|
|
27
|
+
* **Request Body:**
|
|
28
|
+
* - `data` (string, required): Base64 encoded file data
|
|
29
|
+
* - `durabilityLevel` (string, optional): 'ephemeral', 'standard', 'enhanced', 'maximum'
|
|
30
|
+
* - `isEncrypted` (boolean, optional): Flag indicating data is already encrypted
|
|
31
|
+
*
|
|
32
|
+
* **Response:** magnetUrl and metadata (hierarchyDepth, subCblCount)
|
|
33
|
+
*
|
|
34
|
+
* ### GET /api/scbl/retrieve
|
|
35
|
+
* Retrieve and reconstruct a file from its Super CBL hierarchy.
|
|
36
|
+
*
|
|
37
|
+
* **Query Parameters:**
|
|
38
|
+
* - `magnetUrl` (string, required): Full magnet URL from store response
|
|
39
|
+
*
|
|
40
|
+
* **Response:** Reconstructed file data (base64 encoded)
|
|
41
|
+
*
|
|
42
|
+
* @requirements 2.1, 2.2, 2.3, 2.4, 2.5
|
|
43
|
+
*/
|
|
44
|
+
export declare class SCBLController<TID extends PlatformID = DefaultBackendIdType> extends BaseController<TID, any, SCBLHandlers, CoreLanguageCode> {
|
|
45
|
+
private readonly blockStore;
|
|
46
|
+
private readonly cblService;
|
|
47
|
+
private readonly checksumService;
|
|
48
|
+
constructor(application: IBrightChainApplication<TID>);
|
|
49
|
+
/**
|
|
50
|
+
* Initialize route definitions
|
|
51
|
+
*/
|
|
52
|
+
protected initRouteDefinitions(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Calculate the maximum data size that can fit in a single CBL
|
|
55
|
+
* based on the block size and CBL header overhead.
|
|
56
|
+
*/
|
|
57
|
+
private getCblThreshold;
|
|
58
|
+
/**
|
|
59
|
+
* Store a large file as a Super CBL hierarchy.
|
|
60
|
+
* POST /api/scbl/store
|
|
61
|
+
*
|
|
62
|
+
* @requirements 2.1, 2.3, 2.5
|
|
63
|
+
*/
|
|
64
|
+
storeSCBL(_req: Request): Promise<{
|
|
65
|
+
statusCode: number;
|
|
66
|
+
response: StoreSCBLResponse;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Retrieve and reconstruct a file from its Super CBL hierarchy.
|
|
70
|
+
* GET /api/scbl/retrieve
|
|
71
|
+
*
|
|
72
|
+
* @requirements 2.2, 2.4
|
|
73
|
+
*/
|
|
74
|
+
retrieveSCBL(req: Request): Promise<{
|
|
75
|
+
statusCode: number;
|
|
76
|
+
response: RetrieveSCBLResponse;
|
|
77
|
+
}>;
|
|
78
|
+
}
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=scbl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scbl.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/controllers/api/scbl.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,oBAAoB,EAGpB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EACL,uBAAuB,EAExB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAiBzC;;GAEG;AACH,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,cAAc,CACzB,GAAG,SAAS,UAAU,GAAG,oBAAoB,CAC7C,SAAQ,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,gBAAgB,CAAC;IAChE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAEtC,WAAW,EAAE,uBAAuB,CAAC,GAAG,CAAC;IAwBrD;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IA+CtC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;OAKG;IACU,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;QAC7C,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,iBAAiB,CAAC;KAC7B,CAAC;IA4HF;;;;;OAKG;IACU,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAC/C,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,oBAAoB,CAAC;KAChC,CAAC;CAsIH"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCBLController = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
const brightchain_lib_1 = require("@brightchain/brightchain-lib");
|
|
6
|
+
const i18n_lib_1 = require("@digitaldefiance/i18n-lib");
|
|
7
|
+
const express_validator_1 = require("express-validator");
|
|
8
|
+
const stores_1 = require("../../stores");
|
|
9
|
+
const base_1 = require("../base");
|
|
10
|
+
/**
|
|
11
|
+
* Type guard for StoreSCBLRequest
|
|
12
|
+
*/
|
|
13
|
+
function isStoreSCBLRequest(body) {
|
|
14
|
+
return (typeof body['data'] === 'string' &&
|
|
15
|
+
(body['durabilityLevel'] === undefined ||
|
|
16
|
+
typeof body['durabilityLevel'] === 'string') &&
|
|
17
|
+
(body['isEncrypted'] === undefined ||
|
|
18
|
+
typeof body['isEncrypted'] === 'boolean'));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Controller for Super CBL (Hierarchical Constituent Block List) operations.
|
|
22
|
+
*
|
|
23
|
+
* Super CBLs enable storage of files larger than a single CBL can reference
|
|
24
|
+
* through recursive sub-CBL structures. This controller provides endpoints
|
|
25
|
+
* for storing and retrieving large files using the Super CBL hierarchy.
|
|
26
|
+
*
|
|
27
|
+
* ## Endpoints
|
|
28
|
+
*
|
|
29
|
+
* ### POST /api/scbl/store
|
|
30
|
+
* Store a large file as a Super CBL hierarchy.
|
|
31
|
+
*
|
|
32
|
+
* **Request Body:**
|
|
33
|
+
* - `data` (string, required): Base64 encoded file data
|
|
34
|
+
* - `durabilityLevel` (string, optional): 'ephemeral', 'standard', 'enhanced', 'maximum'
|
|
35
|
+
* - `isEncrypted` (boolean, optional): Flag indicating data is already encrypted
|
|
36
|
+
*
|
|
37
|
+
* **Response:** magnetUrl and metadata (hierarchyDepth, subCblCount)
|
|
38
|
+
*
|
|
39
|
+
* ### GET /api/scbl/retrieve
|
|
40
|
+
* Retrieve and reconstruct a file from its Super CBL hierarchy.
|
|
41
|
+
*
|
|
42
|
+
* **Query Parameters:**
|
|
43
|
+
* - `magnetUrl` (string, required): Full magnet URL from store response
|
|
44
|
+
*
|
|
45
|
+
* **Response:** Reconstructed file data (base64 encoded)
|
|
46
|
+
*
|
|
47
|
+
* @requirements 2.1, 2.2, 2.3, 2.4, 2.5
|
|
48
|
+
*/
|
|
49
|
+
class SCBLController extends base_1.BaseController {
|
|
50
|
+
constructor(application) {
|
|
51
|
+
super(application);
|
|
52
|
+
// Initialize block store from application environment
|
|
53
|
+
const storePath = this.application.environment.blockStorePath ?? 'tmp/blockstore';
|
|
54
|
+
const blockSize = (this.application.environment.blockStoreBlockSize
|
|
55
|
+
? this.application.environment.blockStoreBlockSize
|
|
56
|
+
: brightchain_lib_1.BlockSize.Medium);
|
|
57
|
+
this.blockStore = new stores_1.DiskBlockAsyncStore({ storePath, blockSize });
|
|
58
|
+
this.checksumService = new brightchain_lib_1.ChecksumService();
|
|
59
|
+
// Initialize CBL service using ServiceProvider
|
|
60
|
+
const serviceProvider = brightchain_lib_1.ServiceProvider.getInstance();
|
|
61
|
+
this.cblService = new brightchain_lib_1.CBLService(this.checksumService, serviceProvider.eciesService, serviceProvider.idProvider);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Initialize route definitions
|
|
65
|
+
*/
|
|
66
|
+
initRouteDefinitions() {
|
|
67
|
+
// Bind handler methods to this instance
|
|
68
|
+
this.handlers = {
|
|
69
|
+
storeSCBL: this.storeSCBL.bind(this),
|
|
70
|
+
retrieveSCBL: this.retrieveSCBL.bind(this),
|
|
71
|
+
};
|
|
72
|
+
this.routeDefinitions = [
|
|
73
|
+
{
|
|
74
|
+
method: 'post',
|
|
75
|
+
path: '/store',
|
|
76
|
+
handlerKey: 'storeSCBL',
|
|
77
|
+
useAuthentication: false,
|
|
78
|
+
validation: [
|
|
79
|
+
(0, express_validator_1.body)('data')
|
|
80
|
+
.isString()
|
|
81
|
+
.notEmpty()
|
|
82
|
+
.withMessage('data is required and must be a non-empty string'),
|
|
83
|
+
(0, express_validator_1.body)('durabilityLevel')
|
|
84
|
+
.optional()
|
|
85
|
+
.isIn(['ephemeral', 'standard', 'enhanced', 'maximum'])
|
|
86
|
+
.withMessage('durabilityLevel must be one of: ephemeral, standard, enhanced, maximum'),
|
|
87
|
+
(0, express_validator_1.body)('isEncrypted')
|
|
88
|
+
.optional()
|
|
89
|
+
.isBoolean()
|
|
90
|
+
.withMessage('isEncrypted must be a boolean'),
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
method: 'get',
|
|
95
|
+
path: '/retrieve',
|
|
96
|
+
handlerKey: 'retrieveSCBL',
|
|
97
|
+
useAuthentication: false,
|
|
98
|
+
validation: [
|
|
99
|
+
(0, express_validator_1.query)('magnetUrl')
|
|
100
|
+
.isString()
|
|
101
|
+
.notEmpty()
|
|
102
|
+
.withMessage('magnetUrl is required and must be a non-empty string'),
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Calculate the maximum data size that can fit in a single CBL
|
|
109
|
+
* based on the block size and CBL header overhead.
|
|
110
|
+
*/
|
|
111
|
+
getCblThreshold() {
|
|
112
|
+
// A CBL can reference multiple blocks, but the CBL itself must fit in a block
|
|
113
|
+
// The threshold is approximately the block size minus header overhead
|
|
114
|
+
// For simplicity, we use a conservative estimate
|
|
115
|
+
const blockSize = this.blockStore.blockSize;
|
|
116
|
+
// CBL header is approximately 200 bytes, each address is 64 bytes
|
|
117
|
+
// A single CBL can reference (blockSize - 200) / 64 blocks
|
|
118
|
+
// Each block can hold blockSize bytes of data
|
|
119
|
+
const maxAddresses = Math.floor((blockSize - 200) / 64);
|
|
120
|
+
return maxAddresses * blockSize;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Store a large file as a Super CBL hierarchy.
|
|
124
|
+
* POST /api/scbl/store
|
|
125
|
+
*
|
|
126
|
+
* @requirements 2.1, 2.3, 2.5
|
|
127
|
+
*/
|
|
128
|
+
async storeSCBL(_req) {
|
|
129
|
+
const body = this.validatedBody;
|
|
130
|
+
if (!isStoreSCBLRequest(body)) {
|
|
131
|
+
throw new i18n_lib_1.HandleableError(new Error('Invalid request body format'), {
|
|
132
|
+
statusCode: 400,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
// Decode file data from base64
|
|
137
|
+
const fileData = Buffer.from(body.data, 'base64');
|
|
138
|
+
const totalSize = fileData.length;
|
|
139
|
+
// Get durability level
|
|
140
|
+
const durabilityLevel = body.durabilityLevel
|
|
141
|
+
? brightchain_lib_1.DurabilityMap[body.durabilityLevel]
|
|
142
|
+
: brightchain_lib_1.DurabilityLevel.Standard;
|
|
143
|
+
// Calculate CBL threshold to determine if we need Super CBL
|
|
144
|
+
const cblThreshold = this.getCblThreshold();
|
|
145
|
+
// If data fits in a single CBL, store it directly
|
|
146
|
+
if (totalSize <= cblThreshold) {
|
|
147
|
+
// Store as a regular CBL with whitening
|
|
148
|
+
const result = await this.blockStore.storeCBLWithWhitening(new Uint8Array(fileData), {
|
|
149
|
+
durabilityLevel,
|
|
150
|
+
isEncrypted: body.isEncrypted,
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
statusCode: 200,
|
|
154
|
+
response: {
|
|
155
|
+
success: true,
|
|
156
|
+
message: 'File stored successfully as CBL',
|
|
157
|
+
magnetUrl: result.magnetUrl,
|
|
158
|
+
metadata: {
|
|
159
|
+
hierarchyDepth: 0, // No hierarchy, just a single CBL
|
|
160
|
+
subCblCount: 0,
|
|
161
|
+
totalSize,
|
|
162
|
+
rootBlockIds: [result.blockId1, result.blockId2],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// For larger files, we need to create a Super CBL hierarchy
|
|
168
|
+
// Split data into chunks that fit in individual CBLs
|
|
169
|
+
const chunkSize = cblThreshold;
|
|
170
|
+
const chunks = [];
|
|
171
|
+
for (let i = 0; i < totalSize; i += chunkSize) {
|
|
172
|
+
chunks.push(fileData.subarray(i, Math.min(i + chunkSize, totalSize)));
|
|
173
|
+
}
|
|
174
|
+
// Store each chunk as a CBL and collect their magnet URLs
|
|
175
|
+
const subCblResults = [];
|
|
176
|
+
for (const chunk of chunks) {
|
|
177
|
+
const result = await this.blockStore.storeCBLWithWhitening(new Uint8Array(chunk), {
|
|
178
|
+
durabilityLevel, // Propagate durability level to sub-CBLs (Requirement 2.5)
|
|
179
|
+
isEncrypted: body.isEncrypted,
|
|
180
|
+
});
|
|
181
|
+
subCblResults.push(result);
|
|
182
|
+
}
|
|
183
|
+
// Create the Super CBL header data containing references to sub-CBLs
|
|
184
|
+
// For now, we store the sub-CBL references as a JSON structure
|
|
185
|
+
// and whitened like a regular CBL
|
|
186
|
+
const superCblData = {
|
|
187
|
+
type: 'super-cbl',
|
|
188
|
+
version: 1,
|
|
189
|
+
subCblCount: subCblResults.length,
|
|
190
|
+
hierarchyDepth: 1,
|
|
191
|
+
totalSize,
|
|
192
|
+
isEncrypted: body.isEncrypted ?? false,
|
|
193
|
+
subCbls: subCblResults.map((r) => ({
|
|
194
|
+
magnetUrl: r.magnetUrl,
|
|
195
|
+
blockId1: r.blockId1,
|
|
196
|
+
blockId2: r.blockId2,
|
|
197
|
+
})),
|
|
198
|
+
};
|
|
199
|
+
const superCblBytes = new TextEncoder().encode(JSON.stringify(superCblData));
|
|
200
|
+
// Store the Super CBL manifest with the same durability level
|
|
201
|
+
const rootResult = await this.blockStore.storeCBLWithWhitening(superCblBytes, {
|
|
202
|
+
durabilityLevel, // Propagate durability level (Requirement 2.5)
|
|
203
|
+
isEncrypted: false, // The manifest itself is not encrypted
|
|
204
|
+
});
|
|
205
|
+
return {
|
|
206
|
+
statusCode: 200,
|
|
207
|
+
response: {
|
|
208
|
+
success: true,
|
|
209
|
+
message: 'File stored successfully as Super CBL',
|
|
210
|
+
magnetUrl: rootResult.magnetUrl,
|
|
211
|
+
metadata: {
|
|
212
|
+
hierarchyDepth: 1,
|
|
213
|
+
subCblCount: subCblResults.length,
|
|
214
|
+
totalSize,
|
|
215
|
+
rootBlockIds: [rootResult.blockId1, rootResult.blockId2],
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
if (error instanceof brightchain_lib_1.StoreError) {
|
|
222
|
+
throw new i18n_lib_1.HandleableError(error, {
|
|
223
|
+
statusCode: error.message.includes('too large') ? 413 : 500,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Retrieve and reconstruct a file from its Super CBL hierarchy.
|
|
231
|
+
* GET /api/scbl/retrieve
|
|
232
|
+
*
|
|
233
|
+
* @requirements 2.2, 2.4
|
|
234
|
+
*/
|
|
235
|
+
async retrieveSCBL(req) {
|
|
236
|
+
const { magnetUrl } = req.query;
|
|
237
|
+
if (!magnetUrl) {
|
|
238
|
+
throw new i18n_lib_1.HandleableError(new Error('magnetUrl query parameter is required'), { statusCode: 400 });
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
// Parse the magnet URL to get block IDs
|
|
242
|
+
const components = this.blockStore.parseCBLMagnetUrl(magnetUrl);
|
|
243
|
+
// Retrieve the root CBL data
|
|
244
|
+
const rootData = await this.blockStore.retrieveCBL(components.blockId1, components.blockId2, components.block1ParityIds, components.block2ParityIds);
|
|
245
|
+
// Try to parse as Super CBL manifest
|
|
246
|
+
let superCblManifest = null;
|
|
247
|
+
try {
|
|
248
|
+
const decoded = new TextDecoder().decode(rootData);
|
|
249
|
+
const parsed = JSON.parse(decoded);
|
|
250
|
+
if (parsed.type === 'super-cbl') {
|
|
251
|
+
superCblManifest = parsed;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// Not a Super CBL manifest, treat as regular CBL data
|
|
256
|
+
}
|
|
257
|
+
// If it's a regular CBL (not a Super CBL), return the data directly
|
|
258
|
+
if (!superCblManifest) {
|
|
259
|
+
return {
|
|
260
|
+
statusCode: 200,
|
|
261
|
+
response: {
|
|
262
|
+
success: true,
|
|
263
|
+
message: 'File retrieved successfully',
|
|
264
|
+
data: Buffer.from(rootData).toString('base64'),
|
|
265
|
+
isEncrypted: components.isEncrypted,
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// Recursively reconstruct file from sub-CBLs
|
|
270
|
+
const chunks = [];
|
|
271
|
+
for (let i = 0; i < superCblManifest.subCbls.length; i++) {
|
|
272
|
+
const subCbl = superCblManifest.subCbls[i];
|
|
273
|
+
try {
|
|
274
|
+
// Parse sub-CBL magnet URL
|
|
275
|
+
const subComponents = this.blockStore.parseCBLMagnetUrl(subCbl.magnetUrl);
|
|
276
|
+
// Retrieve sub-CBL data
|
|
277
|
+
const chunkData = await this.blockStore.retrieveCBL(subComponents.blockId1, subComponents.blockId2, subComponents.block1ParityIds, subComponents.block2ParityIds);
|
|
278
|
+
chunks.push(chunkData);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
// Handle missing sub-CBL (Requirement 2.4)
|
|
282
|
+
if (error instanceof brightchain_lib_1.StoreError &&
|
|
283
|
+
error.message.includes('not found')) {
|
|
284
|
+
throw new i18n_lib_1.HandleableError(new Error(`Sub-CBL ${i + 1} of ${superCblManifest.subCblCount} not found: ${subCbl.magnetUrl}`), { statusCode: 404 });
|
|
285
|
+
}
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Concatenate all chunks to reconstruct the original file
|
|
290
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
291
|
+
const reconstructedData = new Uint8Array(totalLength);
|
|
292
|
+
let offset = 0;
|
|
293
|
+
for (const chunk of chunks) {
|
|
294
|
+
reconstructedData.set(chunk, offset);
|
|
295
|
+
offset += chunk.length;
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
statusCode: 200,
|
|
299
|
+
response: {
|
|
300
|
+
success: true,
|
|
301
|
+
message: 'File retrieved successfully from Super CBL',
|
|
302
|
+
data: Buffer.from(reconstructedData).toString('base64'),
|
|
303
|
+
isEncrypted: superCblManifest.isEncrypted,
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
if (error instanceof i18n_lib_1.HandleableError) {
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
if (error instanceof brightchain_lib_1.StoreError) {
|
|
312
|
+
throw new i18n_lib_1.HandleableError(error, {
|
|
313
|
+
statusCode: error.message.includes('not found') ? 404 : 500,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (error instanceof Error &&
|
|
317
|
+
error.message.includes('Invalid magnet URL')) {
|
|
318
|
+
throw new i18n_lib_1.HandleableError(error, { statusCode: 400 });
|
|
319
|
+
}
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
exports.SCBLController = SCBLController;
|
|
325
|
+
//# sourceMappingURL=scbl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scbl.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/controllers/api/scbl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { IAvailabilityService, IBlockLocationsResponse, IReconcileResponse, IReconciliationService, IReplicateBlockResponse, ISyncRequestResponse } from '@brightchain/brightchain-lib';
|
|
2
|
+
import { CoreLanguageCode } from '@digitaldefiance/i18n-lib';
|
|
3
|
+
import { PlatformID } from '@digitaldefiance/node-ecies-lib';
|
|
4
|
+
import { ApiErrorResponse, ApiRequestHandler, TypedHandlers } from '@digitaldefiance/node-express-suite';
|
|
5
|
+
import { IBrightChainApplication } from '../../interfaces/application';
|
|
6
|
+
import { EventNotificationSystem } from '../../services/eventNotificationSystem';
|
|
7
|
+
import { DefaultBackendIdType } from '../../shared-types';
|
|
8
|
+
import { BaseController } from '../base';
|
|
9
|
+
type SyncApiResponse = IReplicateBlockResponse | IBlockLocationsResponse | ISyncRequestResponse | IReconcileResponse | ApiErrorResponse;
|
|
10
|
+
interface SyncHandlers extends TypedHandlers {
|
|
11
|
+
replicateBlock: ApiRequestHandler<IReplicateBlockResponse | ApiErrorResponse>;
|
|
12
|
+
getBlockLocations: ApiRequestHandler<IBlockLocationsResponse | ApiErrorResponse>;
|
|
13
|
+
syncRequest: ApiRequestHandler<ISyncRequestResponse | ApiErrorResponse>;
|
|
14
|
+
reconcile: ApiRequestHandler<IReconcileResponse | ApiErrorResponse>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Controller for block replication and synchronization operations.
|
|
18
|
+
*
|
|
19
|
+
* Provides REST API endpoints for replicating blocks to other nodes,
|
|
20
|
+
* querying block locations, checking block availability, and triggering
|
|
21
|
+
* reconciliation with peers.
|
|
22
|
+
*
|
|
23
|
+
* ## Endpoints
|
|
24
|
+
*
|
|
25
|
+
* ### POST /api/blocks/:blockId/replicate
|
|
26
|
+
* Replicate a block to specified target nodes.
|
|
27
|
+
*
|
|
28
|
+
* **Parameters:**
|
|
29
|
+
* - `blockId` (string, required): Block ID to replicate
|
|
30
|
+
*
|
|
31
|
+
* **Request Body:**
|
|
32
|
+
* - `targetNodeIds` (string[], required): Array of node IDs to replicate to
|
|
33
|
+
*
|
|
34
|
+
* **Response:**
|
|
35
|
+
* - `blockId` (string): The block ID that was replicated
|
|
36
|
+
* - `replicationResults` (array): Results for each target node
|
|
37
|
+
*
|
|
38
|
+
* ### GET /api/blocks/:blockId/locations
|
|
39
|
+
* Get all known locations for a block.
|
|
40
|
+
*
|
|
41
|
+
* **Parameters:**
|
|
42
|
+
* - `blockId` (string, required): Block ID to query
|
|
43
|
+
*
|
|
44
|
+
* **Response:**
|
|
45
|
+
* - `blockId` (string): The block ID queried
|
|
46
|
+
* - `locations` (array): Array of location records
|
|
47
|
+
*
|
|
48
|
+
* ### POST /api/sync/request
|
|
49
|
+
* Check which blocks are available locally and which need to be fetched.
|
|
50
|
+
*
|
|
51
|
+
* **Request Body:**
|
|
52
|
+
* - `blockIds` (string[], required): Array of block IDs to check
|
|
53
|
+
*
|
|
54
|
+
* **Response:**
|
|
55
|
+
* - `available` (string[]): Block IDs available locally
|
|
56
|
+
* - `missing` (string[]): Block IDs that need to be fetched
|
|
57
|
+
* - `unknown` (string[]): Block IDs with unknown status
|
|
58
|
+
*
|
|
59
|
+
* ### POST /api/sync/reconcile
|
|
60
|
+
* Initiate reconciliation with connected peers.
|
|
61
|
+
*
|
|
62
|
+
* **Response:**
|
|
63
|
+
* - `result` (object): Reconciliation result with statistics
|
|
64
|
+
*
|
|
65
|
+
* @requirements 4.1, 4.2, 4.3, 4.4
|
|
66
|
+
*/
|
|
67
|
+
export declare class SyncController<TID extends PlatformID = DefaultBackendIdType> extends BaseController<TID, SyncApiResponse, SyncHandlers, CoreLanguageCode> {
|
|
68
|
+
private availabilityService;
|
|
69
|
+
private reconciliationService;
|
|
70
|
+
private eventSystem;
|
|
71
|
+
constructor(application: IBrightChainApplication<TID>);
|
|
72
|
+
/**
|
|
73
|
+
* Set the AvailabilityService instance.
|
|
74
|
+
* This allows for dependency injection and testing.
|
|
75
|
+
*/
|
|
76
|
+
setAvailabilityService(service: IAvailabilityService): void;
|
|
77
|
+
/**
|
|
78
|
+
* Set the ReconciliationService instance.
|
|
79
|
+
* This allows for dependency injection and testing.
|
|
80
|
+
*/
|
|
81
|
+
setReconciliationService(service: IReconciliationService): void;
|
|
82
|
+
/**
|
|
83
|
+
* Set the EventNotificationSystem instance.
|
|
84
|
+
* This allows for dependency injection and testing.
|
|
85
|
+
* @requirements 4.5
|
|
86
|
+
*/
|
|
87
|
+
setEventSystem(eventSystem: EventNotificationSystem): void;
|
|
88
|
+
/**
|
|
89
|
+
* Get the AvailabilityService instance.
|
|
90
|
+
* Throws if the service has not been set.
|
|
91
|
+
*/
|
|
92
|
+
private getAvailabilityService;
|
|
93
|
+
/**
|
|
94
|
+
* Get the ReconciliationService instance.
|
|
95
|
+
* Throws if the service has not been set.
|
|
96
|
+
*/
|
|
97
|
+
private getReconciliationService;
|
|
98
|
+
protected initRouteDefinitions(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Convert ILocationRecord to response format
|
|
101
|
+
*/
|
|
102
|
+
private locationToInfo;
|
|
103
|
+
/**
|
|
104
|
+
* POST /api/sync/blocks/:blockId/replicate
|
|
105
|
+
* Replicate a block to specified target nodes.
|
|
106
|
+
*
|
|
107
|
+
* @param req - Request containing block ID and target node IDs
|
|
108
|
+
* @returns Replication results for each target node
|
|
109
|
+
* @requirements 4.1, 4.5
|
|
110
|
+
*/
|
|
111
|
+
private handleReplicateBlock;
|
|
112
|
+
/**
|
|
113
|
+
* GET /api/sync/blocks/:blockId/locations
|
|
114
|
+
* Get all known locations for a block.
|
|
115
|
+
*
|
|
116
|
+
* @param req - Request containing the block ID parameter
|
|
117
|
+
* @returns Array of location records
|
|
118
|
+
* @requirements 4.2
|
|
119
|
+
*/
|
|
120
|
+
private handleGetBlockLocations;
|
|
121
|
+
/**
|
|
122
|
+
* POST /api/sync/request
|
|
123
|
+
* Check which blocks are available locally and which need to be fetched.
|
|
124
|
+
*
|
|
125
|
+
* @param req - Request containing array of block IDs to check
|
|
126
|
+
* @returns Partitioned lists of available, missing, and unknown blocks
|
|
127
|
+
* @requirements 4.3
|
|
128
|
+
*/
|
|
129
|
+
private handleSyncRequest;
|
|
130
|
+
/**
|
|
131
|
+
* POST /api/sync/reconcile
|
|
132
|
+
* Initiate reconciliation with connected peers.
|
|
133
|
+
*
|
|
134
|
+
* @returns Reconciliation result with statistics
|
|
135
|
+
* @requirements 4.4
|
|
136
|
+
*/
|
|
137
|
+
private handleReconcile;
|
|
138
|
+
}
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/controllers/api/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EAEpB,uBAAuB,EAEvB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EAEvB,oBAAoB,EACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EAEd,MAAM,qCAAqC,CAAC;AAM7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAM1D,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,KAAK,eAAe,GAChB,uBAAuB,GACvB,uBAAuB,GACvB,oBAAoB,GACpB,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,UAAU,YAAa,SAAQ,aAAa;IAC1C,cAAc,EAAE,iBAAiB,CAAC,uBAAuB,GAAG,gBAAgB,CAAC,CAAC;IAC9E,iBAAiB,EAAE,iBAAiB,CAClC,uBAAuB,GAAG,gBAAgB,CAC3C,CAAC;IACF,WAAW,EAAE,iBAAiB,CAAC,oBAAoB,GAAG,gBAAgB,CAAC,CAAC;IACxE,SAAS,EAAE,iBAAiB,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBAAa,cAAc,CACzB,GAAG,SAAS,UAAU,GAAG,oBAAoB,CAC7C,SAAQ,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,CAAC;IAC5E,OAAO,CAAC,mBAAmB,CAAqC;IAChE,OAAO,CAAC,qBAAqB,CAAuC;IACpE,OAAO,CAAC,WAAW,CAAwC;gBAE/C,WAAW,EAAE,uBAAuB,CAAC,GAAG,CAAC;IAIrD;;;OAGG;IACI,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAIlE;;;OAGG;IACI,wBAAwB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAItE;;;;OAIG;IACI,cAAc,CAAC,WAAW,EAAE,uBAAuB,GAAG,IAAI;IAIjE;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAOhC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAgCtC;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;;;;;;OAOG;YACW,oBAAoB;IAiGlC;;;;;;;OAOG;YACW,uBAAuB;IA2BrC;;;;;;;OAOG;YACW,iBAAiB;IA8D/B;;;;;;OAMG;YACW,eAAe;CA8B9B"}
|