@runflow-ai/sdk 1.0.94 → 1.0.96
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/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +11 -3
- package/dist/core/agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -10
- package/dist/index.js.map +1 -1
- package/dist/llm/llm-manager.d.ts +21 -1
- package/dist/llm/llm-manager.d.ts.map +1 -1
- package/dist/llm/llm-manager.js +39 -0
- package/dist/llm/llm-manager.js.map +1 -1
- package/dist/privacy/index.d.ts +31 -0
- package/dist/privacy/index.d.ts.map +1 -0
- package/dist/privacy/index.js +45 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/privacy/patterns.d.ts +38 -0
- package/dist/privacy/patterns.d.ts.map +1 -0
- package/dist/privacy/patterns.js +388 -0
- package/dist/privacy/patterns.js.map +1 -0
- package/dist/privacy/pii-sanitizer.d.ts +122 -0
- package/dist/privacy/pii-sanitizer.d.ts.map +1 -0
- package/dist/privacy/pii-sanitizer.js +574 -0
- package/dist/privacy/pii-sanitizer.js.map +1 -0
- package/dist/privacy/types.d.ts +158 -0
- package/dist/privacy/types.d.ts.map +1 -0
- package/dist/privacy/types.js +11 -0
- package/dist/privacy/types.js.map +1 -0
- package/dist/types/all-types.d.ts +17 -0
- package/dist/types/all-types.d.ts.map +1 -1
- package/dist/workflows/workflow.d.ts +4 -0
- package/dist/workflows/workflow.d.ts.map +1 -1
- package/dist/workflows/workflow.js +15 -2
- package/dist/workflows/workflow.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* RUNFLOW SDK - PII SANITIZER
|
|
5
|
+
* ============================================================================
|
|
6
|
+
*
|
|
7
|
+
* High-performance, configurable PII sanitization engine.
|
|
8
|
+
* Integrates with the observability pipeline via onTrace callback.
|
|
9
|
+
*
|
|
10
|
+
* Safety guarantees:
|
|
11
|
+
* - Never crashes on unexpected input (circular refs, Dates, Buffers, etc.)
|
|
12
|
+
* - Never loses non-PII data (preserves structure and special types)
|
|
13
|
+
* - Never leaks PII on internal error (fails closed)
|
|
14
|
+
* - Handles any input type: string, JSON, nested objects, arrays, mixed
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* const agent = new Agent({
|
|
18
|
+
* privacy: { locales: ['br'], strategy: 'redact' },
|
|
19
|
+
* ...
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* Or standalone:
|
|
23
|
+
* const sanitizer = new PIISanitizer({ locales: ['br'] });
|
|
24
|
+
* const clean = sanitizer.sanitize("Meu CPF 123.456.789-09");
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.PIISanitizer = void 0;
|
|
28
|
+
exports.createPIISanitizer = createPIISanitizer;
|
|
29
|
+
exports.normalizePrivacyConfig = normalizePrivacyConfig;
|
|
30
|
+
exports.buildPrivacyInterceptor = buildPrivacyInterceptor;
|
|
31
|
+
exports.composeTraceInterceptors = composeTraceInterceptors;
|
|
32
|
+
const crypto_1 = require("crypto");
|
|
33
|
+
const patterns_1 = require("./patterns");
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// INTERNAL HELPERS
|
|
36
|
+
// ============================================================================
|
|
37
|
+
const MAX_DEPTH = 20;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a value is a plain object (not Date, Buffer, RegExp, Map, etc.)
|
|
40
|
+
*/
|
|
41
|
+
function isPlainObject(value) {
|
|
42
|
+
if (value === null || typeof value !== 'object')
|
|
43
|
+
return false;
|
|
44
|
+
if (Array.isArray(value))
|
|
45
|
+
return false;
|
|
46
|
+
const proto = Object.getPrototypeOf(value);
|
|
47
|
+
return proto === Object.prototype || proto === null;
|
|
48
|
+
}
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// PII SANITIZER
|
|
51
|
+
// ============================================================================
|
|
52
|
+
class PIISanitizer {
|
|
53
|
+
constructor(config = {}) {
|
|
54
|
+
this.redactionCount = 0;
|
|
55
|
+
// Build config with explicit defaults - no spread overwrite risk
|
|
56
|
+
this.config = {
|
|
57
|
+
enabled: config.enabled ?? true,
|
|
58
|
+
strategy: config.strategy ?? 'redact',
|
|
59
|
+
detectFields: config.detectFields ?? true,
|
|
60
|
+
audit: config.audit ?? false,
|
|
61
|
+
scope: {
|
|
62
|
+
input: config.scope?.input ?? true,
|
|
63
|
+
output: config.scope?.output ?? true,
|
|
64
|
+
metadata: config.scope?.metadata ?? false,
|
|
65
|
+
},
|
|
66
|
+
onRedaction: config.onRedaction,
|
|
67
|
+
onSanitize: config.onSanitize,
|
|
68
|
+
sensitiveFields: config.sensitiveFields,
|
|
69
|
+
};
|
|
70
|
+
// Build pattern list
|
|
71
|
+
const localePatterns = (0, patterns_1.getPatterns)(config.locales ?? ['common']);
|
|
72
|
+
this.patterns = [...localePatterns, ...(config.customPatterns ?? [])];
|
|
73
|
+
// Apply category filters
|
|
74
|
+
this.activeCategories = null;
|
|
75
|
+
if (config.includeCategories?.length) {
|
|
76
|
+
this.activeCategories = new Set(config.includeCategories);
|
|
77
|
+
}
|
|
78
|
+
if (config.excludeCategories?.length) {
|
|
79
|
+
const excludeSet = new Set(config.excludeCategories);
|
|
80
|
+
if (this.activeCategories) {
|
|
81
|
+
for (const cat of excludeSet) {
|
|
82
|
+
this.activeCategories.delete(cat);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const allCategories = [
|
|
87
|
+
'document', 'contact', 'financial', 'location',
|
|
88
|
+
'personal', 'network', 'credential', 'health', 'custom',
|
|
89
|
+
];
|
|
90
|
+
this.activeCategories = new Set(allCategories.filter(c => !excludeSet.has(c)));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Filter patterns by active categories
|
|
94
|
+
if (this.activeCategories) {
|
|
95
|
+
this.patterns = this.patterns.filter(p => this.activeCategories.has(p.category));
|
|
96
|
+
}
|
|
97
|
+
// Build field name sets
|
|
98
|
+
const baseFields = this.config.detectFields ? patterns_1.DEFAULT_SENSITIVE_FIELDS : [];
|
|
99
|
+
this.sensitiveFields = new Set([...baseFields, ...(config.sensitiveFields ?? [])].map(f => f.toLowerCase()));
|
|
100
|
+
this.allowFields = new Set((config.allowFields ?? []).map(f => f.toLowerCase()));
|
|
101
|
+
}
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// PUBLIC API
|
|
104
|
+
// ============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Sanitize a string value by applying all active PII patterns.
|
|
107
|
+
*/
|
|
108
|
+
sanitize(value, path = '', field = '') {
|
|
109
|
+
if (!this.config.enabled || !value)
|
|
110
|
+
return value;
|
|
111
|
+
let result = value;
|
|
112
|
+
for (const pattern of this.patterns) {
|
|
113
|
+
// Reset regex lastIndex for global patterns
|
|
114
|
+
pattern.pattern.lastIndex = 0;
|
|
115
|
+
result = result.replace(pattern.pattern, (match) => {
|
|
116
|
+
// Run optional validation
|
|
117
|
+
if (pattern.validate && !pattern.validate(match)) {
|
|
118
|
+
return match;
|
|
119
|
+
}
|
|
120
|
+
this.recordRedaction(pattern, path, field, match.length);
|
|
121
|
+
return this.applyReplacement(match, pattern);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Deep-sanitize any value (string, object, array).
|
|
128
|
+
* Traverses nested structures and applies both pattern and field-name detection.
|
|
129
|
+
*
|
|
130
|
+
* Safety:
|
|
131
|
+
* - Handles circular references (via seen set)
|
|
132
|
+
* - Preserves Date, Buffer, RegExp, Map, Set, Error (converts to safe representation)
|
|
133
|
+
* - Caps recursion depth to prevent stack overflow
|
|
134
|
+
* - Never throws - returns data as-is on unexpected types
|
|
135
|
+
*/
|
|
136
|
+
sanitizeDeep(data, path = '', field = '') {
|
|
137
|
+
return this._sanitizeDeep(data, path, field, new WeakSet(), 0);
|
|
138
|
+
}
|
|
139
|
+
_sanitizeDeep(data, path, field, seen, depth) {
|
|
140
|
+
if (!this.config.enabled)
|
|
141
|
+
return data;
|
|
142
|
+
if (data === null || data === undefined)
|
|
143
|
+
return data;
|
|
144
|
+
// Primitives: string, number, boolean, bigint, symbol
|
|
145
|
+
if (typeof data === 'string') {
|
|
146
|
+
return this.sanitize(data, path, field);
|
|
147
|
+
}
|
|
148
|
+
if (typeof data !== 'object' && typeof data !== 'function') {
|
|
149
|
+
return data;
|
|
150
|
+
}
|
|
151
|
+
// Depth guard
|
|
152
|
+
if (depth >= MAX_DEPTH) {
|
|
153
|
+
return data;
|
|
154
|
+
}
|
|
155
|
+
// Circular reference guard
|
|
156
|
+
if (seen.has(data)) {
|
|
157
|
+
return '[Circular]';
|
|
158
|
+
}
|
|
159
|
+
seen.add(data);
|
|
160
|
+
// Array: recurse into elements
|
|
161
|
+
if (Array.isArray(data)) {
|
|
162
|
+
return data.map((item, i) => this._sanitizeDeep(item, `${path}[${i}]`, field, seen, depth + 1));
|
|
163
|
+
}
|
|
164
|
+
// Special object types: preserve as-is or convert to safe string
|
|
165
|
+
if (data instanceof Date)
|
|
166
|
+
return data;
|
|
167
|
+
if (data instanceof RegExp)
|
|
168
|
+
return data;
|
|
169
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data))
|
|
170
|
+
return data;
|
|
171
|
+
if (data instanceof Error) {
|
|
172
|
+
// Sanitize error message (may contain PII), preserve structure
|
|
173
|
+
const sanitizedError = new Error(this.sanitize(data.message, `${path}.message`, field));
|
|
174
|
+
sanitizedError.name = data.name;
|
|
175
|
+
if (data.stack) {
|
|
176
|
+
sanitizedError.stack = this.sanitize(data.stack, `${path}.stack`, field);
|
|
177
|
+
}
|
|
178
|
+
return sanitizedError;
|
|
179
|
+
}
|
|
180
|
+
if (data instanceof Map) {
|
|
181
|
+
const result = new Map();
|
|
182
|
+
for (const [key, value] of data) {
|
|
183
|
+
const keyStr = typeof key === 'string' ? key : String(key);
|
|
184
|
+
result.set(key, this._sanitizeDeep(value, `${path}.Map(${keyStr})`, field, seen, depth + 1));
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
if (data instanceof Set) {
|
|
189
|
+
const result = new Set();
|
|
190
|
+
let i = 0;
|
|
191
|
+
for (const value of data) {
|
|
192
|
+
result.add(this._sanitizeDeep(value, `${path}.Set[${i}]`, field, seen, depth + 1));
|
|
193
|
+
i++;
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
// Plain objects only - don't iterate custom class instances with Object.entries
|
|
198
|
+
if (!isPlainObject(data)) {
|
|
199
|
+
// Non-plain objects: try to sanitize via toString if it looks like a string container
|
|
200
|
+
if (typeof data.toString === 'function' && data.toString !== Object.prototype.toString) {
|
|
201
|
+
const str = data.toString();
|
|
202
|
+
if (typeof str === 'string' && str !== '[object Object]') {
|
|
203
|
+
const sanitized = this.sanitize(str, path, field);
|
|
204
|
+
if (sanitized !== str) {
|
|
205
|
+
// PII was found in the string representation - return sanitized string
|
|
206
|
+
return sanitized;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return data;
|
|
211
|
+
}
|
|
212
|
+
// Plain object: check field names + recurse
|
|
213
|
+
const result = {};
|
|
214
|
+
for (const [key, value] of Object.entries(data)) {
|
|
215
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
216
|
+
const keyLower = key.toLowerCase();
|
|
217
|
+
// Check if this field is in the allow list
|
|
218
|
+
if (this.allowFields.has(keyLower)) {
|
|
219
|
+
result[key] = value;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// Check if this field name indicates sensitive data
|
|
223
|
+
// Pass original key for camelCase boundary detection
|
|
224
|
+
if (this.isSensitiveField(key)) {
|
|
225
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
226
|
+
// String value on sensitive field: redact the whole value
|
|
227
|
+
this.recordRedaction({ id: `field:${key}`, label: key, category: 'personal', pattern: /(?:)/ }, currentPath, field || 'input', value.length);
|
|
228
|
+
result[key] = this.applyFieldRedaction(value, key);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (value != null && typeof value === 'object') {
|
|
232
|
+
// Object/array value on sensitive field: sanitize everything inside deeply
|
|
233
|
+
result[key] = this._redactDeep(value, currentPath, field, seen, depth + 1);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
// Number/boolean on sensitive field: keep as-is (ambiguous - could be age, could be ID)
|
|
237
|
+
// If user wants these redacted, they should use onSanitize hook
|
|
238
|
+
}
|
|
239
|
+
// Recurse into value
|
|
240
|
+
result[key] = this._sanitizeDeep(value, currentPath, field, seen, depth + 1);
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Redact all string values in a structure (used for sensitive field objects).
|
|
246
|
+
* When a sensitive field name contains an object, ALL nested strings get redacted.
|
|
247
|
+
*/
|
|
248
|
+
_redactDeep(data, path, field, seen, depth) {
|
|
249
|
+
if (data === null || data === undefined)
|
|
250
|
+
return data;
|
|
251
|
+
if (depth >= MAX_DEPTH)
|
|
252
|
+
return data;
|
|
253
|
+
if (typeof data === 'string') {
|
|
254
|
+
if (data.length > 0) {
|
|
255
|
+
this.recordRedaction({ id: `field:${path}`, label: path, category: 'personal', pattern: /(?:)/ }, path, field || 'input', data.length);
|
|
256
|
+
return this.applyFieldRedaction(data, path.split('.').pop() || path);
|
|
257
|
+
}
|
|
258
|
+
return data;
|
|
259
|
+
}
|
|
260
|
+
if (typeof data !== 'object')
|
|
261
|
+
return data;
|
|
262
|
+
if (seen.has(data))
|
|
263
|
+
return '[Circular]';
|
|
264
|
+
seen.add(data);
|
|
265
|
+
if (Array.isArray(data)) {
|
|
266
|
+
return data.map((item, i) => this._redactDeep(item, `${path}[${i}]`, field, seen, depth + 1));
|
|
267
|
+
}
|
|
268
|
+
if (!isPlainObject(data))
|
|
269
|
+
return data;
|
|
270
|
+
const result = {};
|
|
271
|
+
for (const [key, value] of Object.entries(data)) {
|
|
272
|
+
result[key] = this._redactDeep(value, `${path}.${key}`, field, seen, depth + 1);
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Create an onTrace callback for use with ObservabilityConfig.
|
|
278
|
+
* This is the primary integration point with the RunFlow trace system.
|
|
279
|
+
*
|
|
280
|
+
* Safety: wraps everything in try/catch. On any error, returns null
|
|
281
|
+
* (cancels the trace) to prevent PII leakage. Privacy fails closed.
|
|
282
|
+
*/
|
|
283
|
+
createTraceInterceptor() {
|
|
284
|
+
return (trace) => {
|
|
285
|
+
if (!this.config.enabled)
|
|
286
|
+
return trace;
|
|
287
|
+
try {
|
|
288
|
+
const sanitized = { ...trace };
|
|
289
|
+
// Sanitize input
|
|
290
|
+
if (this.config.scope.input && sanitized.input != null) {
|
|
291
|
+
sanitized.input = this.sanitizeDeep(sanitized.input, 'input', 'input');
|
|
292
|
+
}
|
|
293
|
+
// Sanitize output
|
|
294
|
+
if (this.config.scope.output && sanitized.output != null) {
|
|
295
|
+
sanitized.output = this.sanitizeDeep(sanitized.output, 'output', 'output');
|
|
296
|
+
}
|
|
297
|
+
// Sanitize metadata (custom fields only, preserve system fields)
|
|
298
|
+
if (this.config.scope.metadata && sanitized.metadata) {
|
|
299
|
+
const meta = { ...sanitized.metadata };
|
|
300
|
+
if (meta.custom) {
|
|
301
|
+
meta.custom = this.sanitizeDeep(meta.custom, 'metadata.custom', 'metadata');
|
|
302
|
+
}
|
|
303
|
+
if (meta.entityValue && typeof meta.entityValue === 'string') {
|
|
304
|
+
meta.entityValue = this.sanitize(meta.entityValue, 'metadata.entityValue', 'metadata');
|
|
305
|
+
}
|
|
306
|
+
sanitized.metadata = meta;
|
|
307
|
+
}
|
|
308
|
+
// Call custom onSanitize hook if provided
|
|
309
|
+
if (this.config.onSanitize) {
|
|
310
|
+
const ctx = {
|
|
311
|
+
field: 'input',
|
|
312
|
+
traceType: sanitized.type,
|
|
313
|
+
operation: sanitized.operation,
|
|
314
|
+
path: '',
|
|
315
|
+
};
|
|
316
|
+
if (sanitized.input != null) {
|
|
317
|
+
sanitized.input = this.config.onSanitize(sanitized.input, { ...ctx, field: 'input' });
|
|
318
|
+
}
|
|
319
|
+
if (sanitized.output != null) {
|
|
320
|
+
sanitized.output = this.config.onSanitize(sanitized.output, { ...ctx, field: 'output' });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return sanitized;
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
// Privacy fails closed: if sanitization crashes, drop the trace
|
|
327
|
+
// to prevent PII from leaking into logs/storage.
|
|
328
|
+
console.error('[RunFlow Privacy] Sanitization failed, dropping trace to prevent PII leakage:', error instanceof Error ? error.message : 'unknown error');
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Get the total number of redactions performed.
|
|
335
|
+
*/
|
|
336
|
+
getRedactionCount() {
|
|
337
|
+
return this.redactionCount;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Reset the redaction counter.
|
|
341
|
+
*/
|
|
342
|
+
resetStats() {
|
|
343
|
+
this.redactionCount = 0;
|
|
344
|
+
}
|
|
345
|
+
// ============================================================================
|
|
346
|
+
// REPLACEMENT STRATEGIES
|
|
347
|
+
// ============================================================================
|
|
348
|
+
applyReplacement(match, pattern) {
|
|
349
|
+
// Pattern-specific replacement takes priority
|
|
350
|
+
if (pattern.replacement) {
|
|
351
|
+
if (typeof pattern.replacement === 'function') {
|
|
352
|
+
return pattern.replacement(match);
|
|
353
|
+
}
|
|
354
|
+
return pattern.replacement;
|
|
355
|
+
}
|
|
356
|
+
const strategy = this.config.strategy;
|
|
357
|
+
if (typeof strategy === 'function') {
|
|
358
|
+
return strategy(match, pattern);
|
|
359
|
+
}
|
|
360
|
+
switch (strategy) {
|
|
361
|
+
case 'redact':
|
|
362
|
+
return '[REDACTED]';
|
|
363
|
+
case 'category':
|
|
364
|
+
return `[${pattern.label.toUpperCase()}]`;
|
|
365
|
+
case 'mask':
|
|
366
|
+
return this.maskValue(match, pattern);
|
|
367
|
+
case 'hash':
|
|
368
|
+
return this.hashValue(match);
|
|
369
|
+
default:
|
|
370
|
+
return '[REDACTED]';
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
applyFieldRedaction(value, fieldName) {
|
|
374
|
+
const strategy = this.config.strategy;
|
|
375
|
+
if (typeof strategy === 'function') {
|
|
376
|
+
return strategy(value, {
|
|
377
|
+
id: `field:${fieldName}`,
|
|
378
|
+
label: fieldName,
|
|
379
|
+
category: 'personal',
|
|
380
|
+
pattern: /(?:)/,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
switch (strategy) {
|
|
384
|
+
case 'redact':
|
|
385
|
+
return '[REDACTED]';
|
|
386
|
+
case 'category':
|
|
387
|
+
return `[${fieldName.toUpperCase()}]`;
|
|
388
|
+
case 'mask':
|
|
389
|
+
return this.maskGeneric(value);
|
|
390
|
+
case 'hash':
|
|
391
|
+
return this.hashValue(value);
|
|
392
|
+
default:
|
|
393
|
+
return '[REDACTED]';
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Mask a value based on its pattern type.
|
|
398
|
+
* Shows partial data for usability while hiding the full value.
|
|
399
|
+
*/
|
|
400
|
+
maskValue(match, pattern) {
|
|
401
|
+
const digits = match.replace(/\D/g, '');
|
|
402
|
+
switch (pattern.id) {
|
|
403
|
+
case 'br_cpf':
|
|
404
|
+
return `***.***${match.slice(-6)}`;
|
|
405
|
+
case 'br_cnpj':
|
|
406
|
+
return `**.***.***/${match.slice(-5)}`;
|
|
407
|
+
case 'us_ssn':
|
|
408
|
+
return `***-**-${digits.slice(-4)}`;
|
|
409
|
+
case 'email': {
|
|
410
|
+
const atIndex = match.indexOf('@');
|
|
411
|
+
if (atIndex <= 0)
|
|
412
|
+
return this.maskGeneric(match);
|
|
413
|
+
const local = match.substring(0, atIndex);
|
|
414
|
+
const domain = match.substring(atIndex + 1);
|
|
415
|
+
return `${local[0]}***@${domain}`;
|
|
416
|
+
}
|
|
417
|
+
case 'credit_card':
|
|
418
|
+
return `**** **** **** ${digits.slice(-4)}`;
|
|
419
|
+
case 'br_phone':
|
|
420
|
+
case 'us_phone':
|
|
421
|
+
case 'eu_phone':
|
|
422
|
+
return `****${match.slice(-4)}`;
|
|
423
|
+
default:
|
|
424
|
+
return this.maskGeneric(match);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Generic masking: show first and last char, mask the rest.
|
|
429
|
+
*/
|
|
430
|
+
maskGeneric(value) {
|
|
431
|
+
if (value.length <= 4)
|
|
432
|
+
return '****';
|
|
433
|
+
return value[0] + '*'.repeat(value.length - 2) + value[value.length - 1];
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Hash a value using SHA-256 (truncated).
|
|
437
|
+
* Same input always produces same output, enabling correlation without exposing data.
|
|
438
|
+
*/
|
|
439
|
+
hashValue(value) {
|
|
440
|
+
const hash = (0, crypto_1.createHash)('sha256').update(value).digest('hex').substring(0, 12);
|
|
441
|
+
return `[HASH:${hash}]`;
|
|
442
|
+
}
|
|
443
|
+
// ============================================================================
|
|
444
|
+
// FIELD DETECTION
|
|
445
|
+
// ============================================================================
|
|
446
|
+
isSensitiveField(fieldName) {
|
|
447
|
+
if (!this.config.detectFields && !this.config.sensitiveFields?.length) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
const normalized = fieldName
|
|
451
|
+
.toLowerCase()
|
|
452
|
+
.replace(/[-\s]/g, '_');
|
|
453
|
+
// Exact match first (fastest path)
|
|
454
|
+
if (this.sensitiveFields.has(normalized) || this.sensitiveFields.has(fieldName)) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
// Token-based match for compound field names
|
|
458
|
+
// Split by underscore and camelCase boundaries:
|
|
459
|
+
// 'nome_contato' → ['nome', 'contato']
|
|
460
|
+
// 'contactName' → ['contact', 'name']
|
|
461
|
+
// 'emailAddress' → ['email', 'address']
|
|
462
|
+
// Note: apply camelCase split on original casing, THEN lowercase
|
|
463
|
+
const tokens = fieldName
|
|
464
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2') // camelCase → snake_case
|
|
465
|
+
.toLowerCase()
|
|
466
|
+
.replace(/[-\s]/g, '_')
|
|
467
|
+
.split('_')
|
|
468
|
+
.filter(t => t.length > 0);
|
|
469
|
+
const isCompound = tokens.length > 1;
|
|
470
|
+
for (const token of tokens) {
|
|
471
|
+
// Always-sensitive tokens match regardless
|
|
472
|
+
if (patterns_1.SENSITIVE_TOKENS_ALWAYS.has(token)) {
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
// Compound-only tokens match only in multi-token field names
|
|
476
|
+
// e.g., 'name' alone = not PII, but 'contactName' = PII
|
|
477
|
+
if (isCompound && patterns_1.SENSITIVE_TOKENS_COMPOUND.has(token)) {
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
// ============================================================================
|
|
484
|
+
// AUDIT TRAIL
|
|
485
|
+
// ============================================================================
|
|
486
|
+
recordRedaction(pattern, path, field, originalLength) {
|
|
487
|
+
this.redactionCount++;
|
|
488
|
+
if (!this.config.audit || !this.config.onRedaction)
|
|
489
|
+
return;
|
|
490
|
+
const event = {
|
|
491
|
+
patternId: pattern.id,
|
|
492
|
+
category: pattern.category,
|
|
493
|
+
path,
|
|
494
|
+
field,
|
|
495
|
+
originalLength,
|
|
496
|
+
timestamp: new Date(),
|
|
497
|
+
};
|
|
498
|
+
try {
|
|
499
|
+
this.config.onRedaction(event);
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
// Audit callback failure should never break sanitization
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
exports.PIISanitizer = PIISanitizer;
|
|
507
|
+
// ============================================================================
|
|
508
|
+
// FACTORY FUNCTIONS
|
|
509
|
+
// ============================================================================
|
|
510
|
+
/**
|
|
511
|
+
* Create a PII sanitizer instance with the given configuration.
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* const sanitizer = createPIISanitizer({
|
|
515
|
+
* locales: ['br'],
|
|
516
|
+
* strategy: 'mask',
|
|
517
|
+
* audit: true,
|
|
518
|
+
* onRedaction: (event) => console.log('PII found:', event.patternId),
|
|
519
|
+
* });
|
|
520
|
+
*/
|
|
521
|
+
function createPIISanitizer(config = {}) {
|
|
522
|
+
return new PIISanitizer(config);
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Normalize shorthand privacy config into full PrivacyConfig.
|
|
526
|
+
*
|
|
527
|
+
* true → { enabled: true } (all locales)
|
|
528
|
+
* 'br' → { locales: ['br'] }
|
|
529
|
+
* ['br', 'us'] → { locales: ['br', 'us'] }
|
|
530
|
+
* { ... } → passthrough
|
|
531
|
+
*/
|
|
532
|
+
function normalizePrivacyConfig(config) {
|
|
533
|
+
if (config === false)
|
|
534
|
+
return null;
|
|
535
|
+
if (config === true)
|
|
536
|
+
return { enabled: true };
|
|
537
|
+
if (typeof config === 'string')
|
|
538
|
+
return { locales: [config] };
|
|
539
|
+
if (Array.isArray(config))
|
|
540
|
+
return { locales: config };
|
|
541
|
+
return config;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Build the onTrace callback from a PrivacyConfig.
|
|
545
|
+
* Used internally by Agent to wire privacy into the observability pipeline.
|
|
546
|
+
*/
|
|
547
|
+
function buildPrivacyInterceptor(config) {
|
|
548
|
+
const sanitizer = new PIISanitizer(config);
|
|
549
|
+
return sanitizer.createTraceInterceptor();
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Compose multiple onTrace callbacks into a single callback.
|
|
553
|
+
* Handles the full onTrace contract: TraceData → continue, null → cancel, void → use original.
|
|
554
|
+
*/
|
|
555
|
+
function composeTraceInterceptors(...interceptors) {
|
|
556
|
+
const validInterceptors = interceptors.filter((fn) => fn != null);
|
|
557
|
+
if (validInterceptors.length === 0)
|
|
558
|
+
return (trace) => trace;
|
|
559
|
+
if (validInterceptors.length === 1)
|
|
560
|
+
return validInterceptors[0];
|
|
561
|
+
return (trace) => {
|
|
562
|
+
let current = trace;
|
|
563
|
+
for (const interceptor of validInterceptors) {
|
|
564
|
+
const result = interceptor(current);
|
|
565
|
+
if (result === null)
|
|
566
|
+
return null; // Trace cancelled
|
|
567
|
+
if (result === undefined)
|
|
568
|
+
continue; // void = use current unchanged
|
|
569
|
+
current = result; // Use modified trace
|
|
570
|
+
}
|
|
571
|
+
return current;
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=pii-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii-sanitizer.js","sourceRoot":"","sources":["../../src/privacy/pii-sanitizer.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;;AA8mBH,gDAEC;AAUD,wDAQC;AAMD,0DAKC;AAMD,4DAuBC;AAxqBD,mCAAoC;AAUpC,yCAAuH;AAEvH,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;GAEG;AACH,SAAS,aAAa,CAAC,KAAU;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AACtD,CAAC;AAED,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAa,YAAY;IAiBvB,YAAY,SAAwB,EAAE;QAF9B,mBAAc,GAAG,CAAC,CAAC;QAGzB,iEAAiE;QACjE,IAAI,CAAC,MAAM,GAAG;YACZ,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,QAAQ;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;YACzC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK;YAC5B,KAAK,EAAE;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI;gBAClC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,IAAI;gBACpC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,IAAI,KAAK;aAC1C;YACD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC;QAEF,qBAAqB;QACrB,MAAM,cAAc,GAAG,IAAA,sBAAW,EAAC,MAAM,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC;QAEtE,yBAAyB;QACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;YACrC,IAAI,CAAC,gBAAgB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACrD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;oBAC7B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,GAAkB;oBACnC,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU;oBAC9C,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ;iBACxD,CAAC;gBACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,GAAG,CAC7B,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC9C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpF,CAAC;QAED,wBAAwB;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,mCAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,CAC5B,CAAC,GAAG,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAC7E,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CACxB,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CACrD,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,aAAa;IACb,+EAA+E;IAE/E;;OAEG;IACH,QAAQ,CAAC,KAAa,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEjD,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,4CAA4C;YAC5C,OAAO,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;YAE9B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjD,0BAA0B;gBAC1B,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjD,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;OASG;IACH,YAAY,CAAC,IAAS,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE;QAC3C,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAEO,aAAa,CACnB,IAAS,EACT,IAAY,EACZ,KAAa,EACb,IAAqB,EACrB,KAAa;QAEb,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAErD,sDAAsD;QACtD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,cAAc;QACd,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEf,+BAA+B;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAClE,CAAC;QACJ,CAAC;QAED,iEAAiE;QACjE,IAAI,IAAI,YAAY,IAAI;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,IAAI,YAAY,MAAM;YAAE,OAAO,IAAI,CAAC;QACxC,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACxE,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;YAC1B,+DAA+D;YAC/D,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;YACxF,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YAChC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,cAAc,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,cAAc,CAAC;QACxB,CAAC;QACD,IAAI,IAAI,YAAY,GAAG,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;gBAChC,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/F,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,IAAI,YAAY,GAAG,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;gBACnF,CAAC,EAAE,CAAC;YACN,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,gFAAgF;QAChF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,sFAAsF;YACtF,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBACvF,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;oBACzD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;oBAClD,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;wBACtB,uEAAuE;wBACvE,OAAO,SAAS,CAAC;oBACnB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,4CAA4C;QAC5C,MAAM,MAAM,GAAwB,EAAE,CAAC;QAEvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAEnC,2CAA2C;YAC3C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACpB,SAAS;YACX,CAAC;YAED,oDAAoD;YACpD,qDAAqD;YACrD,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClD,0DAA0D;oBAC1D,IAAI,CAAC,eAAe,CAClB,EAAE,EAAE,EAAE,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAa,EAAE,EAChF,WAAW,EACX,KAAK,IAAI,OAAO,EAChB,KAAK,CAAC,MAAM,CACb,CAAC;oBACF,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBACnD,SAAS;gBACX,CAAC;gBACD,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC/C,2EAA2E;oBAC3E,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC3E,SAAS;gBACX,CAAC;gBACD,wFAAwF;gBACxF,gEAAgE;YAClE,CAAC;YAED,qBAAqB;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC/E,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,WAAW,CACjB,IAAS,EACT,IAAY,EACZ,KAAa,EACb,IAAqB,EACrB,KAAa;QAEb,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrD,IAAI,KAAK,IAAI,SAAS;YAAE,OAAO,IAAI,CAAC;QAEpC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,eAAe,CAClB,EAAE,EAAE,EAAE,SAAS,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAa,EAAE,EAClF,IAAI,EACJ,KAAK,IAAI,OAAO,EAChB,IAAI,CAAC,MAAM,CACZ,CAAC;gBACF,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,CAAC;YACvE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE1C,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,YAAY,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAChG,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;OAMG;IACH,sBAAsB;QACpB,OAAO,CAAC,KAAgB,EAAoB,EAAE;YAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC;YAEvC,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;gBAE/B,iBAAiB;gBACjB,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;oBACvD,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBACzE,CAAC;gBAED,kBAAkB;gBAClB,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;oBACzD,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAC7E,CAAC;gBAED,iEAAiE;gBACjE,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACrD,MAAM,IAAI,GAAG,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;oBAEvC,IAAK,IAAY,CAAC,MAAM,EAAE,CAAC;wBACxB,IAAY,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CACrC,IAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,UAAU,CACpD,CAAC;oBACJ,CAAC;oBAED,IAAK,IAAY,CAAC,WAAW,IAAI,OAAQ,IAAY,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;wBAC9E,IAAY,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CACtC,IAAY,CAAC,WAAW,EAAE,sBAAsB,EAAE,UAAU,CAC9D,CAAC;oBACJ,CAAC;oBAED,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAC5B,CAAC;gBAED,0CAA0C;gBAC1C,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;oBAC3B,MAAM,GAAG,GAAoB;wBAC3B,KAAK,EAAE,OAAO;wBACd,SAAS,EAAE,SAAS,CAAC,IAAc;wBACnC,SAAS,EAAE,SAAS,CAAC,SAAS;wBAC9B,IAAI,EAAE,EAAE;qBACT,CAAC;oBAEF,IAAI,SAAS,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;wBAC5B,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;oBACxF,CAAC;oBACD,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;wBAC7B,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC3F,CAAC;gBACH,CAAC;gBAED,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,gEAAgE;gBAChE,iDAAiD;gBACjD,OAAO,CAAC,KAAK,CACX,+EAA+E,EAC/E,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,+EAA+E;IAC/E,yBAAyB;IACzB,+EAA+E;IAEvE,gBAAgB,CAAC,KAAa,EAAE,OAAmB;QACzD,8CAA8C;QAC9C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;gBAC9C,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,OAAO,OAAO,CAAC,WAAW,CAAC;QAC7B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAEtC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAClC,CAAC;QAED,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,YAAY,CAAC;YAEtB,KAAK,UAAU;gBACb,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;YAE5C,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAExC,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAE/B;gBACE,OAAO,YAAY,CAAC;QACxB,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,KAAa,EAAE,SAAiB;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAEtC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAC,KAAK,EAAE;gBACrB,EAAE,EAAE,SAAS,SAAS,EAAE;gBACxB,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,MAAa;aACvB,CAAC,CAAC;QACL,CAAC;QAED,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,YAAY,CAAC;YACtB,KAAK,UAAU;gBACb,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC;YACxC,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACjC,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC/B;gBACE,OAAO,YAAY,CAAC;QACxB,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,SAAS,CAAC,KAAa,EAAE,OAAmB;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAExC,QAAQ,OAAO,CAAC,EAAE,EAAE,CAAC;YACnB,KAAK,QAAQ;gBACX,OAAO,UAAU,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAErC,KAAK,SAAS;gBACZ,OAAO,cAAc,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEzC,KAAK,QAAQ;gBACX,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEtC,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACnC,IAAI,OAAO,IAAI,CAAC;oBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;gBAC5C,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC;YACpC,CAAC;YAED,KAAK,aAAa;gBAChB,OAAO,kBAAkB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAE9C,KAAK,UAAU,CAAC;YAChB,KAAK,UAAU,CAAC;YAChB,KAAK,UAAU;gBACb,OAAO,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAElC;gBACE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAa;QAC/B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC;QACrC,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACK,SAAS,CAAC,KAAa;QAC7B,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/E,OAAO,SAAS,IAAI,GAAG,CAAC;IAC1B,CAAC;IAED,+EAA+E;IAC/E,kBAAkB;IAClB,+EAA+E;IAEvE,gBAAgB,CAAC,SAAiB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;YACtE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,UAAU,GAAG,SAAS;aACzB,WAAW,EAAE;aACb,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAE1B,mCAAmC;QACnC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6CAA6C;QAC7C,gDAAgD;QAChD,0CAA0C;QAC1C,0CAA0C;QAC1C,2CAA2C;QAC3C,iEAAiE;QACjE,MAAM,MAAM,GAAG,SAAS;aACrB,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAE,yBAAyB;aAC9D,WAAW,EAAE;aACb,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE7B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,2CAA2C;YAC3C,IAAI,kCAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,6DAA6D;YAC7D,wDAAwD;YACxD,IAAI,UAAU,IAAI,oCAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+EAA+E;IAC/E,cAAc;IACd,+EAA+E;IAEvE,eAAe,CACrB,OAAmB,EACnB,IAAY,EACZ,KAAa,EACb,cAAsB;QAEtB,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,OAAO;QAE3D,MAAM,KAAK,GAAmB;YAC5B,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI;YACJ,KAAK;YACL,cAAc;YACd,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;QAEF,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;IACH,CAAC;CACF;AA3jBD,oCA2jBC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAAC,SAAwB,EAAE;IAC3D,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CACpC,MAAmD;IAEnD,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,MAAa,CAAC,EAAE,CAAC;IACpE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,MAAa,EAAE,CAAC;IAC7D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CACrC,MAAqB;IAErB,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,SAAS,CAAC,sBAAsB,EAAE,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,GAAG,YAAgF;IAEnF,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAC3C,CAAC,EAAE,EAAuD,EAAE,CAAC,EAAE,IAAI,IAAI,CACxE,CAAC;IAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;IAC5D,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,KAAgB,EAA2B,EAAE;QACnD,IAAI,OAAO,GAAc,KAAK,CAAC;QAE/B,KAAK,MAAM,WAAW,IAAI,iBAAiB,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAEpC,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,CAAM,kBAAkB;YACzD,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS,CAAI,+BAA+B;YACtE,OAAO,GAAG,MAAM,CAAC,CAAuB,qBAAqB;QAC/D,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC"}
|