@mondaydotcomorg/atp-provenance 0.17.14
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/README.md +417 -0
- package/dist/ast/instrumentor.d.ts +37 -0
- package/dist/ast/instrumentor.d.ts.map +1 -0
- package/dist/ast/instrumentor.js +299 -0
- package/dist/ast/instrumentor.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/policies/engine.d.ts +71 -0
- package/dist/policies/engine.d.ts.map +1 -0
- package/dist/policies/engine.js +433 -0
- package/dist/policies/engine.js.map +1 -0
- package/dist/registry.d.ts +94 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +445 -0
- package/dist/registry.js.map +1 -0
- package/dist/tokens.d.ts +49 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +239 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# @mondaydotcomorg/atp-provenance
|
|
2
|
+
|
|
3
|
+
CAMEL-inspired provenance security for LLM applications - track data origin and enforce security policies to defend against prompt injection attacks.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package implements provenance tracking and security policy enforcement inspired by Google Research's CAMEL paper. It provides three modes with different security/performance trade-offs to protect against prompt injection, data exfiltration, and other LLM security threats.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @mondaydotcomorg/atp-provenance
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
graph TB
|
|
19
|
+
ProvenanceSystem[Provenance System] --> Modes[Three Modes]
|
|
20
|
+
Modes --> None[None Mode<br/>Zero overhead]
|
|
21
|
+
Modes --> Proxy[Proxy Mode<br/>Runtime tracking]
|
|
22
|
+
Modes --> AST[AST Mode<br/>Compile-time]
|
|
23
|
+
|
|
24
|
+
ProvenanceSystem --> Policy[Policy Engine]
|
|
25
|
+
Policy --> BuiltIn[Built-in Policies]
|
|
26
|
+
Policy --> Custom[Custom Policies]
|
|
27
|
+
|
|
28
|
+
Proxy --> ProxyAPI[createProvenanceProxy]
|
|
29
|
+
AST --> Compiler[instrumentCode]
|
|
30
|
+
|
|
31
|
+
Policy --> Actions[Policy Actions]
|
|
32
|
+
Actions --> Log[Log]
|
|
33
|
+
Actions --> Approve[Approve]
|
|
34
|
+
Actions --> Block[Block]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Three Modes
|
|
38
|
+
|
|
39
|
+
### None Mode (Default)
|
|
40
|
+
|
|
41
|
+
No provenance tracking, zero overhead.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// Default mode - no tracking
|
|
45
|
+
const user = { name: 'Alice', ssn: '123-45-6789' };
|
|
46
|
+
// Works normally with no overhead
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Proxy Mode
|
|
50
|
+
|
|
51
|
+
Runtime tracking with 5-10% overhead using JavaScript Proxies.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { createProvenanceProxy, ProvenanceSource } from '@mondaydotcomorg/atp-provenance';
|
|
55
|
+
|
|
56
|
+
const user = createProvenanceProxy(
|
|
57
|
+
{ name: 'Alice', ssn: '123-45-6789' },
|
|
58
|
+
{
|
|
59
|
+
type: ProvenanceSource.TOOL,
|
|
60
|
+
toolName: 'getUser',
|
|
61
|
+
apiGroup: 'users',
|
|
62
|
+
timestamp: Date.now(),
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'restricted',
|
|
66
|
+
readers: ['alice@company.com'],
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Provenance tracked automatically
|
|
71
|
+
console.log(user.name); // Proxy tracks access
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### AST Mode
|
|
75
|
+
|
|
76
|
+
Compile-time instrumentation with 20-30% overhead, tracks primitive tainting.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { instrumentCode, createTrackingRuntime } from '@mondaydotcomorg/atp-provenance';
|
|
80
|
+
|
|
81
|
+
const { code } = instrumentCode(`
|
|
82
|
+
const user = await api.users.getUser({ id: '123' });
|
|
83
|
+
const email = user.email; // Taint propagates to email
|
|
84
|
+
await api.email.send({ to: 'external@company.com', body: email });
|
|
85
|
+
`);
|
|
86
|
+
|
|
87
|
+
const runtime = createTrackingRuntime();
|
|
88
|
+
// Execute instrumented code with runtime
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Security Policy Engine
|
|
92
|
+
|
|
93
|
+
### Quick Start
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import {
|
|
97
|
+
SecurityPolicyEngine,
|
|
98
|
+
preventDataExfiltration,
|
|
99
|
+
requireUserOrigin,
|
|
100
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
101
|
+
|
|
102
|
+
const policyEngine = new SecurityPolicyEngine(
|
|
103
|
+
[preventDataExfiltration, requireUserOrigin],
|
|
104
|
+
console // Logger (pino, winston, or console)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Check before sensitive operations
|
|
108
|
+
try {
|
|
109
|
+
await policyEngine.checkTool('send', 'email', {
|
|
110
|
+
to: 'attacker@evil.com',
|
|
111
|
+
body: user, // Contains provenance metadata
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('Security policy blocked:', error.message);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Built-in Policies
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import {
|
|
122
|
+
preventDataExfiltration, // Block data exfiltration
|
|
123
|
+
preventDataExfiltrationWithApproval, // Require approval for exfiltration
|
|
124
|
+
requireUserOrigin, // Require user-originated data
|
|
125
|
+
requireUserOriginWithApproval, // Require approval for non-user data
|
|
126
|
+
blockLLMRecipients, // Block LLM-extracted recipients
|
|
127
|
+
blockLLMRecipientsWithApproval, // Require approval for LLM recipients
|
|
128
|
+
auditSensitiveAccess, // Log all sensitive access
|
|
129
|
+
getBuiltInPolicies, // All block policies
|
|
130
|
+
getBuiltInPoliciesWithApproval, // All approval policies
|
|
131
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Custom Policies
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { createCustomPolicy, type SecurityPolicy } from '@mondaydotcomorg/atp-provenance';
|
|
138
|
+
|
|
139
|
+
const blockExternalAPIs: SecurityPolicy = createCustomPolicy({
|
|
140
|
+
name: 'blockExternalAPIs',
|
|
141
|
+
description: 'Block calls to external APIs',
|
|
142
|
+
check: async (toolName, apiGroup, args, metadata) => {
|
|
143
|
+
const externalAPIs = ['external-api', 'third-party'];
|
|
144
|
+
|
|
145
|
+
if (externalAPIs.includes(apiGroup)) {
|
|
146
|
+
return {
|
|
147
|
+
action: 'block',
|
|
148
|
+
reason: 'External API calls are not allowed',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { action: 'approve' };
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const engine = new SecurityPolicyEngine([blockExternalAPIs], console);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Policy Actions
|
|
160
|
+
|
|
161
|
+
Policies can return three actions:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
type PolicyAction = 'log' | 'approve' | 'block';
|
|
165
|
+
|
|
166
|
+
interface PolicyResult {
|
|
167
|
+
action: PolicyAction;
|
|
168
|
+
reason?: string;
|
|
169
|
+
metadata?: Record<string, unknown>;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
- **log**: Log the operation but allow it
|
|
174
|
+
- **approve**: Explicitly approve the operation
|
|
175
|
+
- **block**: Block the operation and throw error
|
|
176
|
+
|
|
177
|
+
## Provenance Metadata
|
|
178
|
+
|
|
179
|
+
### Track Data Sources
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { ProvenanceSource } from '@mondaydotcomorg/atp-provenance';
|
|
183
|
+
|
|
184
|
+
enum ProvenanceSource {
|
|
185
|
+
USER = 0, // User-provided data
|
|
186
|
+
LLM = 1, // LLM-generated data
|
|
187
|
+
TOOL = 2, // Tool/API response
|
|
188
|
+
SYSTEM = 3, // System-generated data
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
interface ProvenanceMetadata {
|
|
192
|
+
source: SourceMetadata;
|
|
193
|
+
readers?: ReaderPermissions;
|
|
194
|
+
timestamp: number;
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Get Provenance
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { getProvenance, hasProvenance } from '@mondaydotcomorg/atp-provenance';
|
|
202
|
+
|
|
203
|
+
const user = createProvenanceProxy(userData, source, readers);
|
|
204
|
+
|
|
205
|
+
// Check if object has provenance
|
|
206
|
+
if (hasProvenance(user)) {
|
|
207
|
+
const metadata = getProvenance(user);
|
|
208
|
+
console.log('Source:', metadata.source);
|
|
209
|
+
console.log('Readers:', metadata.readers);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Pause/Resume Support
|
|
214
|
+
|
|
215
|
+
Provenance integrates with ATP's pause/resume mechanism:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import {
|
|
219
|
+
captureProvenanceState,
|
|
220
|
+
restoreProvenanceState,
|
|
221
|
+
setProvenanceExecutionId,
|
|
222
|
+
cleanupProvenanceForExecution,
|
|
223
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
224
|
+
|
|
225
|
+
// Before execution
|
|
226
|
+
setProvenanceExecutionId('exec-123');
|
|
227
|
+
|
|
228
|
+
// Capture state before pause
|
|
229
|
+
const state = captureProvenanceState();
|
|
230
|
+
|
|
231
|
+
// Later, restore state on resume
|
|
232
|
+
restoreProvenanceState(state);
|
|
233
|
+
|
|
234
|
+
// Cleanup after execution
|
|
235
|
+
cleanupProvenanceForExecution('exec-123');
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Integration with ATP Server
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import { createServer, ProvenanceMode } from '@mondaydotcomorg/atp-server';
|
|
242
|
+
import { preventDataExfiltration, requireUserOrigin } from '@mondaydotcomorg/atp-server';
|
|
243
|
+
|
|
244
|
+
const server = createServer({
|
|
245
|
+
execution: {
|
|
246
|
+
provenanceMode: ProvenanceMode.PROXY, // or ProvenanceMode.AST
|
|
247
|
+
securityPolicies: [preventDataExfiltration, requireUserOrigin],
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// All tool calls now enforce provenance policies
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Real-World Examples
|
|
255
|
+
|
|
256
|
+
### Prevent Data Exfiltration
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// User's sensitive data
|
|
260
|
+
const user = createProvenanceProxy(
|
|
261
|
+
{ name: 'Alice', ssn: '123-45-6789' },
|
|
262
|
+
{ type: ProvenanceSource.TOOL, toolName: 'getUser' },
|
|
263
|
+
{ type: 'restricted', readers: ['alice@company.com'] }
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
const engine = new SecurityPolicyEngine([preventDataExfiltration], console);
|
|
267
|
+
|
|
268
|
+
// This will throw - external email with restricted data
|
|
269
|
+
await engine.checkTool('send', 'email', {
|
|
270
|
+
to: 'attacker@evil.com',
|
|
271
|
+
body: user,
|
|
272
|
+
});
|
|
273
|
+
// ❌ Throws: ProvenanceSecurityError
|
|
274
|
+
|
|
275
|
+
// This will succeed - internal email
|
|
276
|
+
await engine.checkTool('send', 'email', {
|
|
277
|
+
to: 'alice@company.com',
|
|
278
|
+
body: user,
|
|
279
|
+
});
|
|
280
|
+
// ✅ Allowed
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Require User Origin
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// LLM-generated email address (untrusted)
|
|
287
|
+
const recipient = createProvenanceProxy(
|
|
288
|
+
'external@untrusted.com',
|
|
289
|
+
{ type: ProvenanceSource.LLM },
|
|
290
|
+
null
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
const engine = new SecurityPolicyEngine([requireUserOrigin], console);
|
|
294
|
+
|
|
295
|
+
// This will throw - LLM-generated recipient
|
|
296
|
+
await engine.checkTool('send', 'email', {
|
|
297
|
+
to: recipient,
|
|
298
|
+
subject: 'Hello',
|
|
299
|
+
});
|
|
300
|
+
// ❌ Throws: Non-user-originated data in sensitive field
|
|
301
|
+
|
|
302
|
+
// User-provided recipient (trusted)
|
|
303
|
+
const userRecipient = createProvenanceProxy(
|
|
304
|
+
'verified@company.com',
|
|
305
|
+
{ type: ProvenanceSource.USER },
|
|
306
|
+
null
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
await engine.checkTool('send', 'email', {
|
|
310
|
+
to: userRecipient,
|
|
311
|
+
subject: 'Hello',
|
|
312
|
+
});
|
|
313
|
+
// ✅ Allowed
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Approval Workflows
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { preventDataExfiltrationWithApproval } from '@mondaydotcomorg/atp-provenance';
|
|
320
|
+
|
|
321
|
+
const engine = new SecurityPolicyEngine([preventDataExfiltrationWithApproval], console);
|
|
322
|
+
|
|
323
|
+
// Set approval callback
|
|
324
|
+
engine.setApprovalCallback(async (request) => {
|
|
325
|
+
console.log(`Approval needed: ${request.reason}`);
|
|
326
|
+
// In production: show UI, send to Slack, etc.
|
|
327
|
+
const approved = await getUserApproval(request);
|
|
328
|
+
return { approved };
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// This will request approval instead of blocking
|
|
332
|
+
await engine.checkTool('send', 'email', {
|
|
333
|
+
to: 'external@company.com',
|
|
334
|
+
body: sensitiveData,
|
|
335
|
+
});
|
|
336
|
+
// → Calls approval callback
|
|
337
|
+
// → Proceeds if approved, blocks if denied
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Performance
|
|
341
|
+
|
|
342
|
+
| Mode | Overhead | Use Case |
|
|
343
|
+
| ----- | -------- | ----------------------------------- |
|
|
344
|
+
| None | 0% | No security requirements |
|
|
345
|
+
| Proxy | 5-10% | Production with moderate security |
|
|
346
|
+
| AST | 20-30% | Maximum security, tracks primitives |
|
|
347
|
+
|
|
348
|
+
## Primitive Taint Tracking (AST Mode)
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import {
|
|
352
|
+
markPrimitiveTainted,
|
|
353
|
+
isPrimitiveTainted,
|
|
354
|
+
getProvenanceForPrimitive,
|
|
355
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
356
|
+
|
|
357
|
+
// Mark primitive as tainted
|
|
358
|
+
markPrimitiveTainted('sensitive-string', metadata);
|
|
359
|
+
|
|
360
|
+
// Check if primitive is tainted
|
|
361
|
+
if (isPrimitiveTainted('sensitive-string')) {
|
|
362
|
+
const provenance = getProvenanceForPrimitive('sensitive-string');
|
|
363
|
+
console.log('String is tainted:', provenance);
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## API Reference
|
|
368
|
+
|
|
369
|
+
### Core Functions
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
createProvenanceProxy<T>(value: T, source: SourceMetadata, readers: ReaderPermissions): Proxied<T>
|
|
373
|
+
getProvenance(value: unknown): ProvenanceMetadata | null
|
|
374
|
+
hasProvenance(value: unknown): boolean
|
|
375
|
+
getAllProvenance(value: unknown): ProvenanceMetadata[]
|
|
376
|
+
canRead(metadata: ProvenanceMetadata, reader: string): boolean
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### AST Mode
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
instrumentCode(code: string): { code: string; metadata: unknown }
|
|
383
|
+
createTrackingRuntime(): Runtime
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Policy Engine
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
new SecurityPolicyEngine(policies: SecurityPolicy[], logger: Logger)
|
|
390
|
+
engine.checkTool(toolName: string, apiGroup: string, args: unknown): Promise<void>
|
|
391
|
+
engine.setApprovalCallback(callback: ApprovalCallback): void
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### State Management
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
setProvenanceExecutionId(executionId: string): void
|
|
398
|
+
clearProvenanceExecutionId(): void
|
|
399
|
+
captureProvenanceState(): ProvenanceState
|
|
400
|
+
restoreProvenanceState(state: ProvenanceState): void
|
|
401
|
+
cleanupProvenanceForExecution(executionId: string): void
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## TypeScript Support
|
|
405
|
+
|
|
406
|
+
Full TypeScript definitions with strict typing.
|
|
407
|
+
|
|
408
|
+
## Credits
|
|
409
|
+
|
|
410
|
+
Inspired by Google Research's CAMEL paper:
|
|
411
|
+
|
|
412
|
+
- Paper: [CAMEL: Capability-Aware Machine Execution Language](https://arxiv.org/abs/2410.02904)
|
|
413
|
+
- GitHub: https://github.com/google-research/camel-prompt-injection
|
|
414
|
+
|
|
415
|
+
## License
|
|
416
|
+
|
|
417
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ProvenanceMetadata, SourceMetadata } from '../types.js';
|
|
2
|
+
import { getProvenance, getProvenanceForPrimitive } from '../registry.js';
|
|
3
|
+
export { getProvenance, getProvenanceForPrimitive };
|
|
4
|
+
/**
|
|
5
|
+
* Instrument code to track provenance at AST level
|
|
6
|
+
*/
|
|
7
|
+
export declare function instrumentCode(code: string): {
|
|
8
|
+
code: string;
|
|
9
|
+
metadata: {
|
|
10
|
+
trackingCalls: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Runtime tracking functions injected into sandbox
|
|
15
|
+
*/
|
|
16
|
+
export declare class ASTProvenanceTracker {
|
|
17
|
+
private metadata;
|
|
18
|
+
private valueToId;
|
|
19
|
+
private nextId;
|
|
20
|
+
private getId;
|
|
21
|
+
track(value: unknown, source: SourceMetadata, dependencies?: string[]): unknown;
|
|
22
|
+
trackBinary(left: unknown, right: unknown, operator: string): unknown;
|
|
23
|
+
trackAssign(name: string, value: unknown): unknown;
|
|
24
|
+
trackMethod(object: unknown, method: string, args: unknown[]): unknown;
|
|
25
|
+
trackTemplate(expressions: unknown[], quasis: string[]): string;
|
|
26
|
+
getMetadata(value: unknown): ProvenanceMetadata | null;
|
|
27
|
+
getAllMetadata(): Map<string, ProvenanceMetadata>;
|
|
28
|
+
restoreMetadata(metadata: Map<string, ProvenanceMetadata>): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create tracking runtime for sandbox injection
|
|
32
|
+
*/
|
|
33
|
+
export declare function createTrackingRuntime(): {
|
|
34
|
+
tracker: ASTProvenanceTracker;
|
|
35
|
+
runtime: Record<string, Function>;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=instrumentor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentor.d.ts","sourceRoot":"","sources":["../../src/ast/instrumentor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,EAEN,aAAa,EACb,yBAAyB,EAEzB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,CAAC;AAOpD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC,CA6CA;AA8GD;;GAEG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAK;IAEnB,OAAO,CAAC,KAAK;IAYb,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,GAAE,MAAM,EAAO,GAAG,OAAO;IAmBnF,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAsErE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAQlD,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO;IActE,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM;IAwB/D,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI;IAUtD,cAAc,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAIjD,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,GAAG,IAAI;CAGhE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI;IACxC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAClC,CAkBA"}
|