qa360 1.0.3 → 1.1.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.
Files changed (108) hide show
  1. package/dist/commands/history.js +1 -1
  2. package/dist/commands/pack.js +1 -1
  3. package/dist/commands/run.d.ts +1 -1
  4. package/dist/commands/run.d.ts.map +1 -1
  5. package/dist/commands/run.js +1 -1
  6. package/dist/commands/secrets.js +1 -1
  7. package/dist/commands/serve.js +1 -1
  8. package/dist/commands/verify.js +1 -1
  9. package/dist/core/adapters/gitleaks-secrets.d.ts +115 -0
  10. package/dist/core/adapters/gitleaks-secrets.d.ts.map +1 -0
  11. package/dist/core/adapters/gitleaks-secrets.js +410 -0
  12. package/dist/core/adapters/k6-perf.d.ts +86 -0
  13. package/dist/core/adapters/k6-perf.d.ts.map +1 -0
  14. package/dist/core/adapters/k6-perf.js +398 -0
  15. package/dist/core/adapters/osv-deps.d.ts +124 -0
  16. package/dist/core/adapters/osv-deps.d.ts.map +1 -0
  17. package/dist/core/adapters/osv-deps.js +372 -0
  18. package/dist/core/adapters/playwright-api.d.ts +82 -0
  19. package/dist/core/adapters/playwright-api.d.ts.map +1 -0
  20. package/dist/core/adapters/playwright-api.js +252 -0
  21. package/dist/core/adapters/playwright-ui.d.ts +115 -0
  22. package/dist/core/adapters/playwright-ui.d.ts.map +1 -0
  23. package/dist/core/adapters/playwright-ui.js +346 -0
  24. package/dist/core/adapters/semgrep-sast.d.ts +100 -0
  25. package/dist/core/adapters/semgrep-sast.d.ts.map +1 -0
  26. package/dist/core/adapters/semgrep-sast.js +322 -0
  27. package/dist/core/adapters/zap-dast.d.ts +134 -0
  28. package/dist/core/adapters/zap-dast.d.ts.map +1 -0
  29. package/dist/core/adapters/zap-dast.js +424 -0
  30. package/dist/core/hooks/compose.d.ts +62 -0
  31. package/dist/core/hooks/compose.d.ts.map +1 -0
  32. package/dist/core/hooks/compose.js +225 -0
  33. package/dist/core/hooks/runner.d.ts +69 -0
  34. package/dist/core/hooks/runner.d.ts.map +1 -0
  35. package/dist/core/hooks/runner.js +303 -0
  36. package/dist/core/index.d.ts +74 -0
  37. package/dist/core/index.d.ts.map +1 -0
  38. package/dist/core/index.js +39 -0
  39. package/dist/core/pack/migrator.d.ts +52 -0
  40. package/dist/core/pack/migrator.d.ts.map +1 -0
  41. package/dist/core/pack/migrator.js +304 -0
  42. package/dist/core/pack/validator.d.ts +43 -0
  43. package/dist/core/pack/validator.d.ts.map +1 -0
  44. package/dist/core/pack/validator.js +292 -0
  45. package/dist/core/proof/bundle.d.ts +138 -0
  46. package/dist/core/proof/bundle.d.ts.map +1 -0
  47. package/dist/core/proof/bundle.js +160 -0
  48. package/dist/core/proof/canonicalize.d.ts +48 -0
  49. package/dist/core/proof/canonicalize.d.ts.map +1 -0
  50. package/dist/core/proof/canonicalize.js +105 -0
  51. package/dist/core/proof/index.d.ts +14 -0
  52. package/dist/core/proof/index.d.ts.map +1 -0
  53. package/dist/core/proof/index.js +18 -0
  54. package/dist/core/proof/schema.d.ts +218 -0
  55. package/dist/core/proof/schema.d.ts.map +1 -0
  56. package/dist/core/proof/schema.js +263 -0
  57. package/dist/core/proof/signer.d.ts +112 -0
  58. package/dist/core/proof/signer.d.ts.map +1 -0
  59. package/dist/core/proof/signer.js +226 -0
  60. package/dist/core/proof/verifier.d.ts +98 -0
  61. package/dist/core/proof/verifier.d.ts.map +1 -0
  62. package/dist/core/proof/verifier.js +302 -0
  63. package/dist/core/runner/phase3-runner.d.ts +102 -0
  64. package/dist/core/runner/phase3-runner.d.ts.map +1 -0
  65. package/dist/core/runner/phase3-runner.js +471 -0
  66. package/dist/core/secrets/crypto.d.ts +76 -0
  67. package/dist/core/secrets/crypto.d.ts.map +1 -0
  68. package/dist/core/secrets/crypto.js +225 -0
  69. package/dist/core/secrets/manager.d.ts +77 -0
  70. package/dist/core/secrets/manager.d.ts.map +1 -0
  71. package/dist/core/secrets/manager.js +219 -0
  72. package/dist/core/security/redaction-patterns-extended.d.ts +28 -0
  73. package/dist/core/security/redaction-patterns-extended.d.ts.map +1 -0
  74. package/dist/core/security/redaction-patterns-extended.js +247 -0
  75. package/dist/core/security/redactor.d.ts +72 -0
  76. package/dist/core/security/redactor.d.ts.map +1 -0
  77. package/dist/core/security/redactor.js +279 -0
  78. package/dist/core/serve/diagnostics-collector.d.ts +33 -0
  79. package/dist/core/serve/diagnostics-collector.d.ts.map +1 -0
  80. package/dist/core/serve/diagnostics-collector.js +149 -0
  81. package/dist/core/serve/health-checker.d.ts +45 -0
  82. package/dist/core/serve/health-checker.d.ts.map +1 -0
  83. package/dist/core/serve/health-checker.js +219 -0
  84. package/dist/core/serve/index.d.ts +9 -0
  85. package/dist/core/serve/index.d.ts.map +1 -0
  86. package/dist/core/serve/index.js +8 -0
  87. package/dist/core/serve/metrics-collector.d.ts +25 -0
  88. package/dist/core/serve/metrics-collector.d.ts.map +1 -0
  89. package/dist/core/serve/metrics-collector.js +322 -0
  90. package/dist/core/serve/process-manager.d.ts +37 -0
  91. package/dist/core/serve/process-manager.d.ts.map +1 -0
  92. package/dist/core/serve/process-manager.js +213 -0
  93. package/dist/core/serve/server.d.ts +37 -0
  94. package/dist/core/serve/server.d.ts.map +1 -0
  95. package/dist/core/serve/server.js +191 -0
  96. package/dist/core/types/pack-v1.d.ts +162 -0
  97. package/dist/core/types/pack-v1.d.ts.map +1 -0
  98. package/dist/core/types/pack-v1.js +5 -0
  99. package/dist/core/types/trust-score.d.ts +70 -0
  100. package/dist/core/types/trust-score.d.ts.map +1 -0
  101. package/dist/core/types/trust-score.js +191 -0
  102. package/dist/core/vault/cas.d.ts +87 -0
  103. package/dist/core/vault/cas.d.ts.map +1 -0
  104. package/dist/core/vault/cas.js +255 -0
  105. package/dist/core/vault/index.d.ts +205 -0
  106. package/dist/core/vault/index.d.ts.map +1 -0
  107. package/dist/core/vault/index.js +631 -0
  108. package/package.json +12 -6
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Proof Bundle Verification
3
+ *
4
+ * Verifies cryptographic signatures and integrity of proof bundles.
5
+ *
6
+ * @see docs/rfc/proof-bundle-v1.md#6-verification-procedure
7
+ */
8
+ import { promises as fs } from 'fs';
9
+ import { createHash } from 'crypto';
10
+ import { canonicalizeForSigning } from './canonicalize.js';
11
+ import { verify, loadKeys } from './signer.js';
12
+ import { validateProofBundle } from './schema.js';
13
+ /**
14
+ * Verification error codes (matches RFC)
15
+ */
16
+ export var VerificationCode;
17
+ (function (VerificationCode) {
18
+ VerificationCode[VerificationCode["PROOF_OK"] = 0] = "PROOF_OK";
19
+ VerificationCode[VerificationCode["PROOF_INVALID_SIG"] = 1] = "PROOF_INVALID_SIG";
20
+ VerificationCode[VerificationCode["PROOF_INVALID_SCHEMA"] = 2] = "PROOF_INVALID_SCHEMA";
21
+ VerificationCode[VerificationCode["PROOF_ARTIFACT_MISMATCH"] = 3] = "PROOF_ARTIFACT_MISMATCH";
22
+ VerificationCode[VerificationCode["PROOF_MISSING_KEY"] = 4] = "PROOF_MISSING_KEY";
23
+ VerificationCode[VerificationCode["PROOF_MALFORMED"] = 5] = "PROOF_MALFORMED";
24
+ })(VerificationCode || (VerificationCode = {}));
25
+ /**
26
+ * Verify proof bundle signature
27
+ *
28
+ * @param bundle - Proof bundle to verify
29
+ * @param publicKey - Optional public key (loads from ~/.qa360/keys if not provided)
30
+ * @returns Verification result
31
+ */
32
+ export async function verifyProofBundle(bundle, publicKey) {
33
+ // Step 1: Validate JSON structure
34
+ try {
35
+ JSON.stringify(bundle);
36
+ }
37
+ catch {
38
+ return {
39
+ valid: false,
40
+ code: VerificationCode.PROOF_MALFORMED,
41
+ message: 'Malformed JSON structure',
42
+ };
43
+ }
44
+ // Step 2: Extract signature
45
+ const signatureB64 = bundle.signature;
46
+ if (!signatureB64) {
47
+ return {
48
+ valid: false,
49
+ code: VerificationCode.PROOF_INVALID_SIG,
50
+ message: 'Missing signature field',
51
+ };
52
+ }
53
+ // Step 3: Validate schema
54
+ const schemaValidation = validateProofBundle(bundle);
55
+ if (!schemaValidation.valid) {
56
+ return {
57
+ valid: false,
58
+ code: VerificationCode.PROOF_INVALID_SCHEMA,
59
+ message: `Schema validation failed: ${schemaValidation.errors?.join(', ')}`,
60
+ };
61
+ }
62
+ // Step 4: Load public key if not provided
63
+ let pubKey = publicKey;
64
+ if (!pubKey) {
65
+ try {
66
+ const keyPair = await loadKeys();
67
+ pubKey = keyPair.publicKey;
68
+ }
69
+ catch (error) {
70
+ return {
71
+ valid: false,
72
+ code: VerificationCode.PROOF_MISSING_KEY,
73
+ message: `Public key not found: ${error instanceof Error ? error.message : 'Unknown error'}`,
74
+ };
75
+ }
76
+ }
77
+ // Step 5: Re-canonicalize (without signature)
78
+ const canonical = canonicalizeForSigning(bundle);
79
+ // Step 6: Compute hash for verification details
80
+ const hash = createHash('sha256').update(canonical, 'utf-8').digest('hex');
81
+ // Step 7: Verify signature
82
+ const signatureValid = verify(canonical, signatureB64, pubKey);
83
+ if (!signatureValid) {
84
+ return {
85
+ valid: false,
86
+ code: VerificationCode.PROOF_INVALID_SIG,
87
+ message: 'Invalid signature',
88
+ details: {
89
+ signerId: bundle.signing.signerId,
90
+ hash: `sha256-${hash}`,
91
+ },
92
+ };
93
+ }
94
+ // Step 8: Success
95
+ return {
96
+ valid: true,
97
+ code: VerificationCode.PROOF_OK,
98
+ message: 'Proof verified successfully',
99
+ details: {
100
+ signerId: bundle.signing.signerId,
101
+ hash: `sha256-${hash}`,
102
+ artifactsTotal: bundle.artifacts.length,
103
+ trustScore: bundle.results.trustScore,
104
+ runId: bundle.run.id,
105
+ startedAt: bundle.run.startedAt,
106
+ finishedAt: bundle.run.finishedAt,
107
+ },
108
+ };
109
+ }
110
+ /**
111
+ * Verify artifact integrity
112
+ *
113
+ * @param artifact - Artifact metadata
114
+ * @param filePath - Path to artifact file
115
+ * @returns true if hash matches
116
+ */
117
+ export async function verifyArtifact(artifact, filePath) {
118
+ try {
119
+ const content = await fs.readFile(filePath);
120
+ const hash = createHash('sha256').update(content).digest('hex');
121
+ const expectedHash = artifact.sha256.replace('sha256-', '');
122
+ return hash === expectedHash;
123
+ }
124
+ catch {
125
+ return false;
126
+ }
127
+ }
128
+ /**
129
+ * Verify all artifacts in proof bundle
130
+ *
131
+ * @param bundle - Proof bundle
132
+ * @param options - Verification options
133
+ * @returns Verification result with artifact details
134
+ */
135
+ export async function verifyArtifacts(bundle, options = {}) {
136
+ const { basePath = '.', skipMissing = false } = options;
137
+ let verified = 0;
138
+ const total = bundle.artifacts.length;
139
+ for (const artifact of bundle.artifacts) {
140
+ const filePath = artifact.path
141
+ ? `${basePath}/${artifact.path}`
142
+ : `${basePath}/${artifact.name}`;
143
+ try {
144
+ const valid = await verifyArtifact(artifact, filePath);
145
+ if (valid) {
146
+ verified++;
147
+ }
148
+ else if (!skipMissing) {
149
+ return {
150
+ valid: false,
151
+ code: VerificationCode.PROOF_ARTIFACT_MISMATCH,
152
+ message: `Artifact hash mismatch: ${artifact.name}`,
153
+ details: {
154
+ artifactsVerified: verified,
155
+ artifactsTotal: total,
156
+ },
157
+ };
158
+ }
159
+ }
160
+ catch {
161
+ if (!skipMissing) {
162
+ return {
163
+ valid: false,
164
+ code: VerificationCode.PROOF_ARTIFACT_MISMATCH,
165
+ message: `Artifact not found: ${artifact.name}`,
166
+ details: {
167
+ artifactsVerified: verified,
168
+ artifactsTotal: total,
169
+ },
170
+ };
171
+ }
172
+ }
173
+ }
174
+ return {
175
+ valid: true,
176
+ code: VerificationCode.PROOF_OK,
177
+ message: `All artifacts verified (${verified}/${total})`,
178
+ details: {
179
+ artifactsVerified: verified,
180
+ artifactsTotal: total,
181
+ },
182
+ };
183
+ }
184
+ /**
185
+ * Verify proof bundle and artifacts (complete verification)
186
+ *
187
+ * @param bundle - Proof bundle
188
+ * @param options - Artifact verification options
189
+ * @param publicKey - Optional public key
190
+ * @returns Complete verification result
191
+ */
192
+ export async function verifyComplete(bundle, options = {}, publicKey) {
193
+ // Step 1: Verify signature
194
+ const sigResult = await verifyProofBundle(bundle, publicKey);
195
+ if (!sigResult.valid) {
196
+ return sigResult;
197
+ }
198
+ // Step 2: Verify artifacts (if any)
199
+ if (bundle.artifacts.length > 0) {
200
+ const artifactResult = await verifyArtifacts(bundle, options);
201
+ if (!artifactResult.valid) {
202
+ return artifactResult;
203
+ }
204
+ // Merge details
205
+ return {
206
+ ...sigResult,
207
+ details: {
208
+ ...sigResult.details,
209
+ ...artifactResult.details,
210
+ },
211
+ };
212
+ }
213
+ return sigResult;
214
+ }
215
+ /**
216
+ * Load and verify proof bundle from file
217
+ *
218
+ * @param filePath - Path to proof bundle JSON file
219
+ * @param options - Artifact verification options
220
+ * @param publicKey - Optional public key
221
+ * @returns Verification result
222
+ */
223
+ export async function verifyProofFile(filePath, options = {}, publicKey) {
224
+ try {
225
+ const content = await fs.readFile(filePath, 'utf-8');
226
+ const bundle = JSON.parse(content);
227
+ return verifyComplete(bundle, options, publicKey);
228
+ }
229
+ catch (error) {
230
+ return {
231
+ valid: false,
232
+ code: VerificationCode.PROOF_MALFORMED,
233
+ message: `Failed to load proof: ${error instanceof Error ? error.message : 'Unknown error'}`,
234
+ };
235
+ }
236
+ }
237
+ /**
238
+ * Verify Phase3 proof format (simplified)
239
+ *
240
+ * @param filePath - Path to Phase3 proof JSON
241
+ * @returns Verification result
242
+ */
243
+ export async function verifyPhase3Proof(filePath) {
244
+ try {
245
+ const content = await fs.readFile(filePath, 'utf-8');
246
+ const proof = JSON.parse(content);
247
+ // Check if it's Phase3 format
248
+ if (!proof.version || !proof.signature || !proof.runId) {
249
+ return {
250
+ valid: false,
251
+ code: VerificationCode.PROOF_MALFORMED,
252
+ message: 'Not a valid Phase3 proof format',
253
+ };
254
+ }
255
+ // Extract signature info
256
+ const { signature, ...payload } = proof;
257
+ if (signature.algorithm === 'none' || !signature.publicKey) {
258
+ return {
259
+ valid: false,
260
+ code: VerificationCode.PROOF_INVALID_SIG,
261
+ message: 'Proof is unsigned',
262
+ };
263
+ }
264
+ // Decode public key from proof
265
+ const publicKey = new Uint8Array(Buffer.from(signature.publicKey, 'base64'));
266
+ // Canonicalize payload
267
+ const { canonicalize } = await import('./canonicalize.js');
268
+ const canonical = canonicalize(payload);
269
+ // Verify signature
270
+ const isValid = verify(canonical, signature.value, publicKey);
271
+ if (!isValid) {
272
+ return {
273
+ valid: false,
274
+ code: VerificationCode.PROOF_INVALID_SIG,
275
+ message: 'Invalid signature - proof may have been tampered with',
276
+ details: {
277
+ runId: proof.runId,
278
+ trustScore: proof.execution?.trustScore,
279
+ },
280
+ };
281
+ }
282
+ // Success
283
+ return {
284
+ valid: true,
285
+ code: VerificationCode.PROOF_OK,
286
+ message: 'Proof verified successfully',
287
+ details: {
288
+ runId: proof.runId,
289
+ trustScore: proof.execution?.trustScore,
290
+ startedAt: proof.timestamp,
291
+ artifactsTotal: proof.gates?.length || 0,
292
+ },
293
+ };
294
+ }
295
+ catch (error) {
296
+ return {
297
+ valid: false,
298
+ code: VerificationCode.PROOF_MALFORMED,
299
+ message: `Failed to verify proof: ${error instanceof Error ? error.message : 'Unknown error'}`,
300
+ };
301
+ }
302
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * QA360 Phase 3 Runner
3
+ * Orchestrates hooks, adapters, and proof generation
4
+ */
5
+ import { PackConfigV1 } from '../types/pack-v1.js';
6
+ export interface Phase3RunnerOptions {
7
+ workingDir: string;
8
+ pack: PackConfigV1;
9
+ outputDir?: string;
10
+ }
11
+ export interface GateResult {
12
+ gate: string;
13
+ success: boolean;
14
+ duration: number;
15
+ adapter: string;
16
+ results: any;
17
+ junit?: string;
18
+ error?: string;
19
+ }
20
+ export interface Phase3RunResult {
21
+ success: boolean;
22
+ pack: PackConfigV1;
23
+ duration: number;
24
+ gates: GateResult[];
25
+ hooks: {
26
+ beforeAll: any[];
27
+ beforeEach: any[];
28
+ afterEach: any[];
29
+ afterAll: any[];
30
+ };
31
+ summary: {
32
+ total: number;
33
+ passed: number;
34
+ failed: number;
35
+ trustScore: number;
36
+ };
37
+ proofPath?: string;
38
+ error?: string;
39
+ }
40
+ export declare class Phase3Runner {
41
+ private workingDir;
42
+ private pack;
43
+ private outputDir;
44
+ private redactor;
45
+ private hooksRunner;
46
+ private keyPair?;
47
+ private vault?;
48
+ constructor(options: Phase3RunnerOptions);
49
+ /**
50
+ * Execute complete Phase 3 workflow
51
+ */
52
+ run(): Promise<Phase3RunResult>;
53
+ /**
54
+ * Execute a single quality gate
55
+ */
56
+ private executeGate;
57
+ /**
58
+ * Run API smoke gate
59
+ */
60
+ private runApiSmokeGate;
61
+ /**
62
+ * Run UI gate (includes basic accessibility)
63
+ */
64
+ private runUiGate;
65
+ /**
66
+ * Run A11y gate (focused accessibility testing)
67
+ */
68
+ private runA11yGate;
69
+ /**
70
+ * Run performance gate
71
+ */
72
+ private runPerfGate;
73
+ /**
74
+ * Run SAST gate
75
+ */
76
+ private runSastGate;
77
+ /**
78
+ * Run DAST gate (mock implementation)
79
+ */
80
+ private runDastGate;
81
+ /**
82
+ * Calculate execution summary
83
+ */
84
+ private calculateSummary;
85
+ /**
86
+ * Generate cryptographically signed proof document
87
+ */
88
+ private generateProof;
89
+ /**
90
+ * Save run results to Evidence Vault
91
+ */
92
+ private saveToVault;
93
+ /**
94
+ * Generate hash of pack configuration
95
+ */
96
+ private hashPack;
97
+ /**
98
+ * Ensure output directory exists
99
+ */
100
+ private ensureOutputDir;
101
+ }
102
+ //# sourceMappingURL=phase3-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase3-runner.d.ts","sourceRoot":"","sources":["../../../src/core/runner/phase3-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAWnD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,SAAS,EAAE,GAAG,EAAE,CAAC;QACjB,UAAU,EAAE,GAAG,EAAE,CAAC;QAClB,SAAS,EAAE,GAAG,EAAE,CAAC;QACjB,QAAQ,EAAE,GAAG,EAAE,CAAC;KACjB,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAgB;gBAElB,OAAO,EAAE,mBAAmB;IAcxC;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC;IA2IrC;;OAEG;YACW,WAAW;IAkFzB;;OAEG;YACW,eAAe;IAc7B;;OAEG;YACW,SAAS;IAavB;;OAEG;YACW,WAAW;IAKzB;;OAEG;YACW,WAAW;IAgBzB;;OAEG;YACW,WAAW;IAWzB;;OAEG;YACW,WAAW;IAezB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;OAEG;YACW,aAAa;IAsE3B;;OAEG;YACW,WAAW;IAmDzB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;OAEG;IACH,OAAO,CAAC,eAAe;CAKxB"}