openredaction 1.0.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/README.md +74 -0
- package/dist/HealthCheck-A5OD4ATR.mjs +12 -0
- package/dist/HealthCheck-A5OD4ATR.mjs.map +1 -0
- package/dist/chunk-7OGNW2MU.mjs +1701 -0
- package/dist/chunk-7OGNW2MU.mjs.map +1 -0
- package/dist/chunk-MYYLGNXS.mjs +149 -0
- package/dist/chunk-MYYLGNXS.mjs.map +1 -0
- package/dist/chunk-WMJKH4XE.mjs +34 -0
- package/dist/chunk-WMJKH4XE.mjs.map +1 -0
- package/dist/chunk-ZRHGDEPC.mjs +297 -0
- package/dist/chunk-ZRHGDEPC.mjs.map +1 -0
- package/dist/cli/test-pattern.js +430 -0
- package/dist/document-AOMZP7UR.mjs +26 -0
- package/dist/document-AOMZP7UR.mjs.map +1 -0
- package/dist/index.cli.js +15093 -0
- package/dist/index.d.mts +4111 -0
- package/dist/index.d.ts +4111 -0
- package/dist/index.js +18488 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +16134 -0
- package/dist/index.mjs.map +1 -0
- package/dist/workers-RMN5POM6.mjs +10 -0
- package/dist/workers-RMN5POM6.mjs.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/ConfigExporter.ts","../src/audit/AuditLogger.ts","../src/audit/PersistentAuditLogger.ts","../src/metrics/MetricsCollector.ts","../src/metrics/PrometheusServer.ts","../src/rbac/roles.ts","../src/rbac/RBACManager.ts","../src/validators/index.ts","../src/patterns/personal.ts","../src/patterns/financial.ts","../src/patterns/government.ts","../src/patterns/contact.ts","../src/patterns/network.ts","../src/patterns/financial/crypto-extended.ts","../src/patterns/industries/healthcare.ts","../src/patterns/industries/financial.ts","../src/patterns/industries/technology.ts","../src/patterns/industries/legal.ts","../src/patterns/industries/education.ts","../src/patterns/industries/hr.ts","../src/patterns/industries/insurance.ts","../src/patterns/industries/retail.ts","../src/patterns/industries/telecoms.ts","../src/patterns/industries/manufacturing.ts","../src/patterns/industries/transportation.ts","../src/patterns/industries/media.ts","../src/patterns/industries/charitable.ts","../src/patterns/industries/procurement.ts","../src/patterns/industries/emergency-services.ts","../src/patterns/industries/real-estate.ts","../src/patterns/industries/gig-economy.ts","../src/patterns/industries/hospitality.ts","../src/patterns/industries/professional-certifications.ts","../src/patterns/industries/gaming.ts","../src/patterns/industries/vehicles.ts","../src/patterns/industries/logistics.ts","../src/patterns/industries/aviation.ts","../src/patterns/industries/maritime.ts","../src/patterns/industries/environmental.ts","../src/patterns/international/middle-east.ts","../src/patterns/international/africa.ts","../src/patterns/international/southeast-asia.ts","../src/patterns/international/latin-america.ts","../src/patterns/international/eastern-europe.ts","../src/patterns/international/oceania.ts","../src/patterns/international/central-asia.ts","../src/patterns/international.ts","../src/patterns/digital-identity.ts","../src/patterns/index.ts","../src/utils/hash.ts","../src/utils/presets.ts","../src/utils/redaction-strategies.ts","../src/learning/LocalLearningStore.ts","../src/config/ConfigLoader.ts","../src/context/ContextAnalyzer.ts","../src/filters/FalsePositiveFilter.ts","../src/multipass/MultiPassDetector.ts","../src/ml/NERDetector.ts","../src/context/ContextRules.ts","../src/severity/SeverityClassifier.ts","../src/utils/cache.ts","../src/explain/ExplainAPI.ts","../src/reports/ReportGenerator.ts","../src/optimizer/PriorityOptimizer.ts","../src/errors/OpenRedactionError.ts","../src/utils/safe-regex.ts","../src/detector.ts","../src/streaming/StreamingDetector.ts","../src/batch/BatchProcessor.ts","../src/integrations/express.ts","../src/integrations/react.ts","../src/tenancy/TenantManager.ts","../src/webhooks/WebhookManager.ts","../src/api/APIServer.ts","../src/index.ts"],"sourcesContent":["/**\n * Configuration export/import utilities\n * Share configurations between projects and version control\n */\n\nimport type { OpenRedactionOptions, PIIPattern } from '../types';\n\nexport interface ExportedConfig {\n version: string; // Config version for compatibility\n timestamp: string; // When exported\n options: {\n includeNames?: boolean;\n includeAddresses?: boolean;\n includePhones?: boolean;\n includeEmails?: boolean;\n patterns?: string[];\n categories?: string[];\n whitelist?: string[];\n deterministic?: boolean;\n redactionMode?: string;\n preset?: string;\n enableContextAnalysis?: boolean;\n confidenceThreshold?: number;\n enableFalsePositiveFilter?: boolean;\n falsePositiveThreshold?: number;\n enableMultiPass?: boolean;\n multiPassCount?: number;\n enableCache?: boolean;\n cacheSize?: number;\n maxInputSize?: number;\n regexTimeout?: number;\n };\n customPatterns?: Array<{\n type: string;\n regex: string;\n flags: string;\n priority: number;\n placeholder: string;\n description?: string;\n severity?: string;\n }>;\n metadata?: {\n description?: string;\n author?: string;\n tags?: string[];\n };\n}\n\nexport class ConfigExporter {\n private static readonly CONFIG_VERSION = '1.0';\n\n /**\n * Export configuration to JSON\n */\n static exportConfig(\n options: OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n },\n metadata?: {\n description?: string;\n author?: string;\n tags?: string[];\n }\n ): ExportedConfig {\n const exported: ExportedConfig = {\n version: this.CONFIG_VERSION,\n timestamp: new Date().toISOString(),\n options: {\n includeNames: options.includeNames,\n includeAddresses: options.includeAddresses,\n includePhones: options.includePhones,\n includeEmails: options.includeEmails,\n patterns: options.patterns,\n categories: options.categories,\n whitelist: options.whitelist,\n deterministic: options.deterministic,\n redactionMode: options.redactionMode,\n preset: options.preset,\n enableContextAnalysis: options.enableContextAnalysis,\n confidenceThreshold: options.confidenceThreshold,\n enableFalsePositiveFilter: options.enableFalsePositiveFilter,\n falsePositiveThreshold: options.falsePositiveThreshold,\n enableMultiPass: options.enableMultiPass,\n multiPassCount: options.multiPassCount,\n enableCache: options.enableCache,\n cacheSize: options.cacheSize,\n maxInputSize: options.maxInputSize,\n regexTimeout: options.regexTimeout\n },\n metadata\n };\n\n // Export custom patterns if present\n if (options.customPatterns && options.customPatterns.length > 0) {\n exported.customPatterns = options.customPatterns.map(p => ({\n type: p.type,\n regex: p.regex.source,\n flags: p.regex.flags,\n priority: p.priority,\n placeholder: p.placeholder,\n description: p.description,\n severity: p.severity\n }));\n }\n\n // Remove undefined values for cleaner JSON\n return JSON.parse(JSON.stringify(exported));\n }\n\n /**\n * Import configuration from JSON\n */\n static importConfig(\n exported: ExportedConfig,\n _options?: {\n mergeWithDefaults?: boolean;\n validatePatterns?: boolean;\n }\n ): OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n } {\n // Validate version compatibility\n if (!exported.version || exported.version !== this.CONFIG_VERSION) {\n console.warn(\n `[OpenRedaction] Config version mismatch. Expected ${this.CONFIG_VERSION}, got ${exported.version}`\n );\n }\n\n const config: any = { ...exported.options };\n\n // Reconstruct custom patterns\n if (exported.customPatterns) {\n config.customPatterns = exported.customPatterns.map(p => {\n const pattern: PIIPattern = {\n type: p.type,\n regex: new RegExp(p.regex, p.flags),\n priority: p.priority,\n placeholder: p.placeholder,\n description: p.description,\n severity: p.severity as any\n };\n return pattern;\n });\n }\n\n return config;\n }\n\n /**\n * Export configuration to JSON string\n */\n static exportToString(\n options: OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n },\n metadata?: {\n description?: string;\n author?: string;\n tags?: string[];\n },\n pretty?: boolean\n ): string {\n const exported = this.exportConfig(options, metadata);\n return JSON.stringify(exported, null, pretty ? 2 : undefined);\n }\n\n /**\n * Import configuration from JSON string\n */\n static importFromString(json: string): OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n } {\n const exported: ExportedConfig = JSON.parse(json);\n return this.importConfig(exported);\n }\n\n /**\n * Export configuration to file (Node.js only)\n */\n static async exportToFile(\n filePath: string,\n options: OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n },\n metadata?: {\n description?: string;\n author?: string;\n tags?: string[];\n }\n ): Promise<void> {\n const fs = await import('fs/promises');\n const content = this.exportToString(options, metadata, true);\n await fs.writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Import configuration from file (Node.js only)\n */\n static async importFromFile(filePath: string): Promise<OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n }> {\n const fs = await import('fs/promises');\n const content = await fs.readFile(filePath, 'utf-8');\n return this.importFromString(content);\n }\n\n /**\n * Validate exported config structure\n */\n static validateConfig(exported: ExportedConfig): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n if (!exported.version) {\n errors.push('Missing version field');\n }\n\n if (!exported.timestamp) {\n errors.push('Missing timestamp field');\n }\n\n if (!exported.options) {\n errors.push('Missing options field');\n }\n\n // Validate custom patterns if present\n if (exported.customPatterns) {\n for (const pattern of exported.customPatterns) {\n if (!pattern.type || !pattern.regex || !pattern.placeholder) {\n errors.push(`Invalid custom pattern: ${pattern.type}`);\n }\n // Try to compile the regex\n try {\n new RegExp(pattern.regex, pattern.flags);\n } catch (e) {\n errors.push(`Invalid regex in pattern ${pattern.type}: ${(e as Error).message}`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors\n };\n }\n\n /**\n * Merge two configurations (useful for extending base configs)\n */\n static mergeConfigs(\n base: ExportedConfig,\n override: ExportedConfig\n ): ExportedConfig {\n return {\n version: this.CONFIG_VERSION,\n timestamp: new Date().toISOString(),\n options: {\n ...base.options,\n ...override.options,\n // Special handling for arrays\n patterns: override.options.patterns || base.options.patterns,\n categories: override.options.categories || base.options.categories,\n whitelist: [\n ...(base.options.whitelist || []),\n ...(override.options.whitelist || [])\n ]\n },\n customPatterns: [\n ...(base.customPatterns || []),\n ...(override.customPatterns || [])\n ],\n metadata: {\n ...base.metadata,\n ...override.metadata\n }\n };\n }\n}\n\n/**\n * Convenience functions for common use cases\n */\n\n/**\n * Create a shareable config preset\n */\nexport function createConfigPreset(\n name: string,\n description: string,\n options: OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n }\n): string {\n return ConfigExporter.exportToString(options, {\n description: `${name}: ${description}`,\n tags: [name, 'preset']\n }, true);\n}\n\n/**\n * Quick export for version control\n */\nexport function exportForVersionControl(\n options: OpenRedactionOptions & {\n categories?: string[];\n maxInputSize?: number;\n regexTimeout?: number;\n }\n): string {\n return ConfigExporter.exportToString(options, {\n description: 'OpenRedaction configuration',\n author: 'Generated automatically',\n tags: ['version-control']\n }, true);\n}\n","/**\n * Audit logging implementation for tracking redaction operations\n */\n\nimport type { IAuditLogger, AuditLogEntry, AuditStats } from '../types';\n\n/**\n * In-memory audit logger implementation\n * Stores audit logs in memory with support for filtering, export, and statistics\n */\nexport class InMemoryAuditLogger implements IAuditLogger {\n private logs: AuditLogEntry[] = [];\n private maxLogs: number;\n\n constructor(maxLogs: number = 10000) {\n this.maxLogs = maxLogs;\n }\n\n /**\n * Log an audit entry\n */\n log(entry: Omit<AuditLogEntry, 'id' | 'timestamp'>): void {\n const auditEntry: AuditLogEntry = {\n ...entry,\n id: this.generateId(),\n timestamp: new Date().toISOString()\n };\n\n this.logs.push(auditEntry);\n\n // Maintain max log size (FIFO)\n if (this.logs.length > this.maxLogs) {\n this.logs.shift();\n }\n }\n\n /**\n * Get all audit logs\n */\n getLogs(): AuditLogEntry[] {\n return [...this.logs];\n }\n\n /**\n * Get audit logs filtered by operation type\n */\n getLogsByOperation(operation: AuditLogEntry['operation']): AuditLogEntry[] {\n return this.logs.filter(log => log.operation === operation);\n }\n\n /**\n * Get audit logs filtered by date range\n */\n getLogsByDateRange(startDate: Date, endDate: Date): AuditLogEntry[] {\n const startTime = startDate.getTime();\n const endTime = endDate.getTime();\n\n return this.logs.filter(log => {\n const logTime = new Date(log.timestamp).getTime();\n return logTime >= startTime && logTime <= endTime;\n });\n }\n\n /**\n * Export audit logs as JSON\n */\n exportAsJson(): string {\n return JSON.stringify(this.logs, null, 2);\n }\n\n /**\n * Export audit logs as CSV\n */\n exportAsCsv(): string {\n if (this.logs.length === 0) {\n return 'id,timestamp,operation,piiCount,piiTypes,textLength,processingTimeMs,redactionMode,success,error,user,sessionId\\n';\n }\n\n const headers = [\n 'id',\n 'timestamp',\n 'operation',\n 'piiCount',\n 'piiTypes',\n 'textLength',\n 'processingTimeMs',\n 'redactionMode',\n 'success',\n 'error',\n 'user',\n 'sessionId'\n ];\n\n const rows = this.logs.map(log => {\n return [\n this.escapeCsv(log.id),\n this.escapeCsv(log.timestamp),\n this.escapeCsv(log.operation),\n log.piiCount.toString(),\n this.escapeCsv(log.piiTypes.join(';')),\n log.textLength.toString(),\n log.processingTimeMs.toFixed(2),\n this.escapeCsv(log.redactionMode || ''),\n log.success.toString(),\n this.escapeCsv(log.error || ''),\n this.escapeCsv(log.user || ''),\n this.escapeCsv(log.sessionId || '')\n ].join(',');\n });\n\n return headers.join(',') + '\\n' + rows.join('\\n');\n }\n\n /**\n * Clear all audit logs\n */\n clear(): void {\n this.logs = [];\n }\n\n /**\n * Get audit statistics\n */\n getStats(): AuditStats {\n if (this.logs.length === 0) {\n return {\n totalOperations: 0,\n totalPiiDetected: 0,\n averageProcessingTime: 0,\n topPiiTypes: [],\n operationsByType: {},\n successRate: 0\n };\n }\n\n const totalOperations = this.logs.length;\n const totalPiiDetected = this.logs.reduce((sum, log) => sum + log.piiCount, 0);\n const totalProcessingTime = this.logs.reduce((sum, log) => sum + log.processingTimeMs, 0);\n const averageProcessingTime = totalProcessingTime / totalOperations;\n const successCount = this.logs.filter(log => log.success).length;\n const successRate = successCount / totalOperations;\n\n // Count PII types\n const piiTypeCount = new Map<string, number>();\n this.logs.forEach(log => {\n log.piiTypes.forEach(type => {\n piiTypeCount.set(type, (piiTypeCount.get(type) || 0) + 1);\n });\n });\n\n // Sort and get top PII types\n const topPiiTypes = Array.from(piiTypeCount.entries())\n .map(([type, count]) => ({ type, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n // Count operations by type\n const operationsByType: Record<string, number> = {};\n this.logs.forEach(log => {\n operationsByType[log.operation] = (operationsByType[log.operation] || 0) + 1;\n });\n\n return {\n totalOperations,\n totalPiiDetected,\n averageProcessingTime,\n topPiiTypes,\n operationsByType,\n successRate\n };\n }\n\n /**\n * Generate a unique ID for audit entries\n */\n private generateId(): string {\n return `audit_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n }\n\n /**\n * Escape CSV values\n */\n private escapeCsv(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n}\n\n/**\n * Console audit logger implementation\n * Outputs audit logs to console (useful for debugging)\n */\nexport class ConsoleAuditLogger implements IAuditLogger {\n private delegate: InMemoryAuditLogger;\n\n constructor(maxLogs: number = 10000) {\n this.delegate = new InMemoryAuditLogger(maxLogs);\n }\n\n log(entry: Omit<AuditLogEntry, 'id' | 'timestamp'>): void {\n this.delegate.log(entry);\n console.log('[AUDIT]', {\n timestamp: new Date().toISOString(),\n ...entry\n });\n }\n\n getLogs(): AuditLogEntry[] {\n return this.delegate.getLogs();\n }\n\n getLogsByOperation(operation: AuditLogEntry['operation']): AuditLogEntry[] {\n return this.delegate.getLogsByOperation(operation);\n }\n\n getLogsByDateRange(startDate: Date, endDate: Date): AuditLogEntry[] {\n return this.delegate.getLogsByDateRange(startDate, endDate);\n }\n\n exportAsJson(): string {\n return this.delegate.exportAsJson();\n }\n\n exportAsCsv(): string {\n return this.delegate.exportAsCsv();\n }\n\n clear(): void {\n this.delegate.clear();\n }\n\n getStats(): AuditStats {\n return this.delegate.getStats();\n }\n}\n","/**\n * Persistent Audit Logger with multiple backend support\n * Provides tamper-proof, cryptographic audit logging for production environments\n */\n\nimport { createHash } from 'crypto';\nimport type {\n IAuditLogger,\n AuditLogEntry,\n AuditStats\n} from '../types';\n\n/**\n * Supported database backends\n */\nexport type AuditBackend = 'sqlite' | 'postgresql' | 'mongodb' | 's3' | 'file';\n\n/**\n * Database connection configuration\n */\nexport interface AuditDatabaseConfig {\n /** Backend type */\n backend: AuditBackend;\n /** Connection string (for PostgreSQL/MongoDB) */\n connectionString?: string;\n /** Database file path (for SQLite/file backend) */\n filePath?: string;\n /** S3 bucket configuration */\n s3Config?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n prefix?: string;\n };\n /** Table/collection name (default: 'audit_logs') */\n tableName?: string;\n /** Enable compression (default: false) */\n enableCompression?: boolean;\n /** Batch size for bulk inserts (default: 100) */\n batchSize?: number;\n}\n\n/**\n * Retention policy configuration\n */\nexport interface RetentionPolicy {\n /** Maximum age of logs in days (default: 90) */\n maxAgeDays?: number;\n /** Maximum number of logs to keep (default: unlimited) */\n maxLogs?: number;\n /** Enable automatic cleanup (default: false) */\n autoCleanup?: boolean;\n /** Cleanup interval in hours (default: 24) */\n cleanupIntervalHours?: number;\n}\n\n/**\n * Persistent audit logger options\n */\nexport interface PersistentAuditLoggerOptions {\n /** Database configuration */\n database: AuditDatabaseConfig;\n /** Retention policy */\n retention?: RetentionPolicy;\n /** Enable cryptographic hashing for tamper detection (default: true) */\n enableHashing?: boolean;\n /** Hash algorithm (default: 'sha256') */\n hashAlgorithm?: 'sha256' | 'sha512';\n /** Enable write-ahead logging for crash recovery (default: true) */\n enableWAL?: boolean;\n /** Secret key for HMAC hashing (optional, recommended for production) */\n secretKey?: string;\n}\n\n/**\n * Audit log entry with cryptographic hash\n */\nexport interface HashedAuditLogEntry extends AuditLogEntry {\n /** Cryptographic hash of this entry */\n hash: string;\n /** Hash of previous entry for chain verification */\n previousHash?: string;\n /** Sequence number in the log chain */\n sequence: number;\n}\n\n/**\n * Audit database adapter interface\n */\nexport interface IAuditDatabaseAdapter {\n /** Initialize the database/table/collection */\n initialize(): Promise<void>;\n /** Insert a single log entry */\n insert(entry: HashedAuditLogEntry): Promise<void>;\n /** Batch insert multiple entries */\n batchInsert(entries: HashedAuditLogEntry[]): Promise<void>;\n /** Query logs with filters */\n query(filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]>;\n /** Get total count of logs */\n count(filter?: Partial<AuditQueryFilter>): Promise<number>;\n /** Delete logs older than date */\n deleteOlderThan(date: Date): Promise<number>;\n /** Get the last log entry */\n getLastEntry(): Promise<HashedAuditLogEntry | null>;\n /** Verify log chain integrity */\n verifyChain(startSequence?: number, endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }>;\n /** Close connection */\n close(): Promise<void>;\n}\n\n/**\n * Audit query filter\n */\nexport interface AuditQueryFilter {\n /** Filter by operation type */\n operation?: AuditLogEntry['operation'];\n /** Filter by user */\n user?: string;\n /** Filter by session ID */\n sessionId?: string;\n /** Filter by date range (start) */\n startDate?: Date;\n /** Filter by date range (end) */\n endDate?: Date;\n /** Filter by success status */\n success?: boolean;\n /** Limit results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n /** Sort order */\n sort?: 'asc' | 'desc';\n}\n\n/**\n * Persistent Audit Logger with cryptographic chain verification\n */\nexport class PersistentAuditLogger implements IAuditLogger {\n private adapter: IAuditDatabaseAdapter;\n private options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string };\n private batchBuffer: HashedAuditLogEntry[] = [];\n private lastHash: string = '';\n private sequence: number = 0;\n private cleanupTimer?: NodeJS.Timeout;\n private initialized: boolean = false;\n\n constructor(options: PersistentAuditLoggerOptions) {\n this.options = {\n ...options,\n retention: {\n maxAgeDays: options.retention?.maxAgeDays ?? 90,\n maxLogs: options.retention?.maxLogs,\n autoCleanup: options.retention?.autoCleanup ?? false,\n cleanupIntervalHours: options.retention?.cleanupIntervalHours ?? 24\n },\n enableHashing: options.enableHashing ?? true,\n hashAlgorithm: options.hashAlgorithm ?? 'sha256',\n enableWAL: options.enableWAL ?? true,\n secretKey: options.secretKey\n } as Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string };\n\n // Create appropriate database adapter\n this.adapter = this.createAdapter(options.database);\n }\n\n /**\n * Initialize the logger (must be called before use)\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.adapter.initialize();\n\n // Load last hash and sequence from database\n const lastEntry = await this.adapter.getLastEntry();\n if (lastEntry) {\n this.lastHash = lastEntry.hash;\n this.sequence = lastEntry.sequence;\n }\n\n // Start automatic cleanup if enabled\n if (this.options.retention.autoCleanup) {\n this.startCleanupSchedule();\n }\n\n this.initialized = true;\n }\n\n /**\n * Log an audit entry\n */\n log(entry: Omit<AuditLogEntry, 'id' | 'timestamp'>): void {\n // Create full entry with ID and timestamp\n const fullEntry: AuditLogEntry = {\n id: this.generateId(),\n timestamp: new Date().toISOString(),\n ...entry\n };\n\n // Create hashed entry\n const hashedEntry = this.createHashedEntry(fullEntry);\n\n // Add to batch buffer\n this.batchBuffer.push(hashedEntry);\n\n // Flush if batch is full\n const batchSize = this.options.database.batchSize ?? 100;\n if (this.batchBuffer.length >= batchSize) {\n // Async flush (fire and forget for performance)\n this.flushBatch().catch(err => {\n console.error('[PersistentAuditLogger] Failed to flush batch:', err);\n });\n }\n }\n\n /**\n * Get all audit logs\n */\n getLogs(): AuditLogEntry[] {\n throw new Error(\n '[PersistentAuditLogger] getLogs() is not supported for persistent storage. Use queryLogs() instead for filtered queries.'\n );\n }\n\n /**\n * Query logs with filters (async)\n */\n async queryLogs(filter?: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n // Flush any pending logs before querying\n await this.flushBatch();\n\n return this.adapter.query(filter || {});\n }\n\n /**\n * Get logs by operation type\n */\n getLogsByOperation(_operation: AuditLogEntry['operation']): AuditLogEntry[] {\n throw new Error(\n '[PersistentAuditLogger] getLogsByOperation() is not supported for persistent storage. Use queryLogs({ operation }) instead.'\n );\n }\n\n /**\n * Get logs by date range\n */\n getLogsByDateRange(_startDate: Date, _endDate: Date): AuditLogEntry[] {\n throw new Error(\n '[PersistentAuditLogger] getLogsByDateRange() is not supported for persistent storage. Use queryLogs({ startDate, endDate }) instead.'\n );\n }\n\n /**\n * Export logs as JSON\n */\n exportAsJson(): string {\n throw new Error(\n '[PersistentAuditLogger] Synchronous export not supported. Use exportAsJsonAsync() instead.'\n );\n }\n\n /**\n * Export logs as JSON (async)\n */\n async exportAsJsonAsync(filter?: AuditQueryFilter): Promise<string> {\n const logs = await this.queryLogs(filter);\n return JSON.stringify(logs, null, 2);\n }\n\n /**\n * Export logs as CSV\n */\n exportAsCsv(): string {\n throw new Error(\n '[PersistentAuditLogger] Synchronous export not supported. Use exportAsCsvAsync() instead.'\n );\n }\n\n /**\n * Export logs as CSV (async)\n */\n async exportAsCsvAsync(filter?: AuditQueryFilter): Promise<string> {\n const logs = await this.queryLogs(filter);\n\n if (logs.length === 0) {\n return '';\n }\n\n // CSV header\n const headers = [\n 'id',\n 'timestamp',\n 'operation',\n 'piiCount',\n 'piiTypes',\n 'textLength',\n 'processingTimeMs',\n 'redactionMode',\n 'success',\n 'error',\n 'user',\n 'sessionId',\n 'hash',\n 'previousHash',\n 'sequence'\n ];\n\n const rows = logs.map(log => [\n log.id,\n log.timestamp,\n log.operation,\n log.piiCount,\n log.piiTypes.join(';'),\n log.textLength,\n log.processingTimeMs,\n log.redactionMode || '',\n log.success,\n log.error || '',\n log.user || '',\n log.sessionId || '',\n log.hash,\n log.previousHash || '',\n log.sequence\n ]);\n\n return [\n headers.join(','),\n ...rows.map(row => row.map(field => `\"${String(field).replace(/\"/g, '\"\"')}\"`).join(','))\n ].join('\\n');\n }\n\n /**\n * Clear all audit logs (dangerous!)\n */\n clear(): void {\n throw new Error(\n '[PersistentAuditLogger] clear() is not supported for persistent storage. Audit logs are immutable. Use deleteOlderThan() for retention policies.'\n );\n }\n\n /**\n * Delete logs older than specified date\n */\n async deleteOlderThan(date: Date): Promise<number> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n return this.adapter.deleteOlderThan(date);\n }\n\n /**\n * Get audit statistics\n */\n getStats(): AuditStats {\n throw new Error(\n '[PersistentAuditLogger] Synchronous getStats() not supported. Use getStatsAsync() instead.'\n );\n }\n\n /**\n * Get audit statistics (async)\n */\n async getStatsAsync(filter?: AuditQueryFilter): Promise<AuditStats> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n const logs = await this.queryLogs(filter);\n\n if (logs.length === 0) {\n return {\n totalOperations: 0,\n totalPiiDetected: 0,\n averageProcessingTime: 0,\n topPiiTypes: [],\n operationsByType: {},\n successRate: 0\n };\n }\n\n const totalOperations = logs.length;\n const totalPiiDetected = logs.reduce((sum, log) => sum + log.piiCount, 0);\n const totalProcessingTime = logs.reduce((sum, log) => sum + log.processingTimeMs, 0);\n const averageProcessingTime = totalProcessingTime / totalOperations;\n\n // Count PII types\n const piiTypeCounts = new Map<string, number>();\n logs.forEach(log => {\n log.piiTypes.forEach(type => {\n piiTypeCounts.set(type, (piiTypeCounts.get(type) || 0) + 1);\n });\n });\n\n const topPiiTypes = Array.from(piiTypeCounts.entries())\n .map(([type, count]) => ({ type, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n // Count operations by type\n const operationsByType: Record<string, number> = {};\n logs.forEach(log => {\n operationsByType[log.operation] = (operationsByType[log.operation] || 0) + 1;\n });\n\n // Calculate success rate\n const successCount = logs.filter(log => log.success).length;\n const successRate = successCount / totalOperations;\n\n return {\n totalOperations,\n totalPiiDetected,\n averageProcessingTime,\n topPiiTypes,\n operationsByType,\n successRate\n };\n }\n\n /**\n * Verify log chain integrity\n */\n async verifyChainIntegrity(startSequence?: number, endSequence?: number): Promise<{\n valid: boolean;\n brokenAt?: number;\n message: string;\n }> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n if (!this.options.enableHashing) {\n return {\n valid: true,\n message: 'Hashing is disabled, chain verification not available'\n };\n }\n\n const result = await this.adapter.verifyChain(startSequence, endSequence);\n\n if (result.valid) {\n return {\n valid: true,\n message: 'Audit log chain is intact and has not been tampered with'\n };\n } else {\n return {\n valid: false,\n brokenAt: result.brokenAt,\n message: `Audit log chain is broken at sequence ${result.brokenAt}. Possible tampering detected.`\n };\n }\n }\n\n /**\n * Flush batch buffer to database\n */\n async flushBatch(): Promise<void> {\n if (this.batchBuffer.length === 0) {\n return;\n }\n\n if (!this.initialized) {\n await this.initialize();\n }\n\n const batch = [...this.batchBuffer];\n this.batchBuffer = [];\n\n try {\n await this.adapter.batchInsert(batch);\n } catch (error) {\n // On failure, put entries back in buffer\n this.batchBuffer.unshift(...batch);\n throw error;\n }\n }\n\n /**\n * Close the logger and flush any pending logs\n */\n async close(): Promise<void> {\n // Stop cleanup timer\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n\n // Flush any pending logs\n await this.flushBatch();\n\n // Close database connection\n await this.adapter.close();\n\n this.initialized = false;\n }\n\n /**\n * Create hashed entry with chain linking\n */\n private createHashedEntry(entry: AuditLogEntry): HashedAuditLogEntry {\n this.sequence++;\n\n const hashedEntry: HashedAuditLogEntry = {\n ...entry,\n hash: '',\n previousHash: this.lastHash || undefined,\n sequence: this.sequence\n };\n\n // Calculate hash\n if (this.options.enableHashing) {\n hashedEntry.hash = this.calculateHash(hashedEntry);\n this.lastHash = hashedEntry.hash;\n } else {\n hashedEntry.hash = 'disabled';\n }\n\n return hashedEntry;\n }\n\n /**\n * Calculate cryptographic hash of entry\n */\n private calculateHash(entry: Omit<HashedAuditLogEntry, 'hash'>): string {\n const algorithm = this.options.hashAlgorithm;\n\n // Create deterministic string representation\n const data = JSON.stringify({\n id: entry.id,\n timestamp: entry.timestamp,\n operation: entry.operation,\n piiCount: entry.piiCount,\n piiTypes: entry.piiTypes,\n textLength: entry.textLength,\n processingTimeMs: entry.processingTimeMs,\n redactionMode: entry.redactionMode,\n success: entry.success,\n error: entry.error,\n user: entry.user,\n sessionId: entry.sessionId,\n metadata: entry.metadata,\n previousHash: entry.previousHash,\n sequence: entry.sequence\n });\n\n // Use HMAC if secret key provided, otherwise simple hash\n if (this.options.secretKey) {\n return createHash(algorithm)\n .update(this.options.secretKey + data)\n .digest('hex');\n } else {\n return createHash(algorithm)\n .update(data)\n .digest('hex');\n }\n }\n\n /**\n * Generate unique ID\n */\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n /**\n * Create database adapter based on backend\n */\n private createAdapter(config: AuditDatabaseConfig): IAuditDatabaseAdapter {\n switch (config.backend) {\n case 'sqlite':\n return new SQLiteAuditAdapter(config, this.options);\n case 'postgresql':\n return new PostgreSQLAuditAdapter(config, this.options);\n case 'mongodb':\n return new MongoDBuditAdapter(config, this.options);\n case 's3':\n return new S3AuditAdapter(config, this.options);\n case 'file':\n return new FileAuditAdapter(config, this.options);\n default:\n throw new Error(`[PersistentAuditLogger] Unsupported backend: ${config.backend}`);\n }\n }\n\n /**\n * Start automatic cleanup schedule\n */\n private startCleanupSchedule(): void {\n const intervalMs = (this.options.retention?.cleanupIntervalHours ?? 24) * 60 * 60 * 1000;\n\n this.cleanupTimer = setInterval(() => {\n this.runCleanup().catch(err => {\n console.error('[PersistentAuditLogger] Cleanup failed:', err);\n });\n }, intervalMs);\n }\n\n /**\n * Run cleanup based on retention policy\n */\n private async runCleanup(): Promise<void> {\n if (!this.initialized) {\n return;\n }\n\n const { maxAgeDays, maxLogs } = this.options.retention;\n\n // Delete logs older than maxAgeDays\n if (maxAgeDays) {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);\n\n const deleted = await this.deleteOlderThan(cutoffDate);\n if (deleted > 0) {\n console.log(`[PersistentAuditLogger] Cleanup: Deleted ${deleted} logs older than ${maxAgeDays} days`);\n }\n }\n\n // Delete oldest logs if over maxLogs limit\n if (maxLogs) {\n const count = await this.adapter.count();\n if (count > maxLogs) {\n const toDelete = count - maxLogs;\n // Implementation depends on adapter\n console.log(`[PersistentAuditLogger] Cleanup: Need to delete ${toDelete} oldest logs (maxLogs: ${maxLogs})`);\n }\n }\n }\n}\n\n/**\n * SQLite adapter implementation\n */\nclass SQLiteAuditAdapter implements IAuditDatabaseAdapter {\n private db?: any;\n private config: AuditDatabaseConfig;\n private options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string };\n\n constructor(config: AuditDatabaseConfig, options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string }) {\n this.config = config;\n this.options = options;\n }\n\n async initialize(): Promise<void> {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const sqlite3 = require('better-sqlite3');\n const filePath = this.config.filePath || './audit-logs.db';\n\n this.db = sqlite3(filePath);\n\n // Enable WAL mode for better concurrency\n if (this.options.enableWAL) {\n this.db.pragma('journal_mode = WAL');\n }\n\n // Create table\n const tableName = this.config.tableName || 'audit_logs';\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS ${tableName} (\n sequence INTEGER PRIMARY KEY,\n id TEXT NOT NULL UNIQUE,\n timestamp TEXT NOT NULL,\n operation TEXT NOT NULL,\n piiCount INTEGER NOT NULL,\n piiTypes TEXT NOT NULL,\n textLength INTEGER NOT NULL,\n processingTimeMs REAL NOT NULL,\n redactionMode TEXT,\n success INTEGER NOT NULL,\n error TEXT,\n user TEXT,\n sessionId TEXT,\n metadata TEXT,\n hash TEXT NOT NULL,\n previousHash TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes\n this.db.exec(`\n CREATE INDEX IF NOT EXISTS idx_${tableName}_timestamp ON ${tableName}(timestamp);\n CREATE INDEX IF NOT EXISTS idx_${tableName}_operation ON ${tableName}(operation);\n CREATE INDEX IF NOT EXISTS idx_${tableName}_user ON ${tableName}(user);\n CREATE INDEX IF NOT EXISTS idx_${tableName}_sessionId ON ${tableName}(sessionId);\n CREATE INDEX IF NOT EXISTS idx_${tableName}_sequence ON ${tableName}(sequence);\n `);\n } catch (error: any) {\n throw new Error(\n `[SQLiteAuditAdapter] Failed to initialize: ${error.message}. Install with: npm install better-sqlite3`\n );\n }\n }\n\n async insert(entry: HashedAuditLogEntry): Promise<void> {\n const tableName = this.config.tableName || 'audit_logs';\n const stmt = this.db.prepare(`\n INSERT INTO ${tableName} (\n sequence, id, timestamp, operation, piiCount, piiTypes, textLength,\n processingTimeMs, redactionMode, success, error, user, sessionId,\n metadata, hash, previousHash\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n entry.sequence,\n entry.id,\n entry.timestamp,\n entry.operation,\n entry.piiCount,\n JSON.stringify(entry.piiTypes),\n entry.textLength,\n entry.processingTimeMs,\n entry.redactionMode || null,\n entry.success ? 1 : 0,\n entry.error || null,\n entry.user || null,\n entry.sessionId || null,\n entry.metadata ? JSON.stringify(entry.metadata) : null,\n entry.hash,\n entry.previousHash || null\n );\n }\n\n async batchInsert(entries: HashedAuditLogEntry[]): Promise<void> {\n const tableName = this.config.tableName || 'audit_logs';\n const stmt = this.db.prepare(`\n INSERT INTO ${tableName} (\n sequence, id, timestamp, operation, piiCount, piiTypes, textLength,\n processingTimeMs, redactionMode, success, error, user, sessionId,\n metadata, hash, previousHash\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const transaction = this.db.transaction((entries: HashedAuditLogEntry[]) => {\n for (const entry of entries) {\n stmt.run(\n entry.sequence,\n entry.id,\n entry.timestamp,\n entry.operation,\n entry.piiCount,\n JSON.stringify(entry.piiTypes),\n entry.textLength,\n entry.processingTimeMs,\n entry.redactionMode || null,\n entry.success ? 1 : 0,\n entry.error || null,\n entry.user || null,\n entry.sessionId || null,\n entry.metadata ? JSON.stringify(entry.metadata) : null,\n entry.hash,\n entry.previousHash || null\n );\n }\n });\n\n transaction(entries);\n }\n\n async query(filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n const tableName = this.config.tableName || 'audit_logs';\n const conditions: string[] = [];\n const params: any[] = [];\n\n if (filter.operation) {\n conditions.push('operation = ?');\n params.push(filter.operation);\n }\n\n if (filter.user) {\n conditions.push('user = ?');\n params.push(filter.user);\n }\n\n if (filter.sessionId) {\n conditions.push('sessionId = ?');\n params.push(filter.sessionId);\n }\n\n if (filter.startDate) {\n conditions.push('timestamp >= ?');\n params.push(filter.startDate.toISOString());\n }\n\n if (filter.endDate) {\n conditions.push('timestamp <= ?');\n params.push(filter.endDate.toISOString());\n }\n\n if (filter.success !== undefined) {\n conditions.push('success = ?');\n params.push(filter.success ? 1 : 0);\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const sortOrder = filter.sort === 'asc' ? 'ASC' : 'DESC';\n const limit = filter.limit ? `LIMIT ${filter.limit}` : '';\n const offset = filter.offset ? `OFFSET ${filter.offset}` : '';\n\n const query = `\n SELECT * FROM ${tableName}\n ${whereClause}\n ORDER BY sequence ${sortOrder}\n ${limit} ${offset}\n `;\n\n const rows = this.db.prepare(query).all(...params);\n\n return rows.map((row: any) => this.rowToEntry(row));\n }\n\n async count(filter?: Partial<AuditQueryFilter>): Promise<number> {\n const tableName = this.config.tableName || 'audit_logs';\n const conditions: string[] = [];\n const params: any[] = [];\n\n if (filter?.operation) {\n conditions.push('operation = ?');\n params.push(filter.operation);\n }\n\n if (filter?.startDate) {\n conditions.push('timestamp >= ?');\n params.push(filter.startDate.toISOString());\n }\n\n if (filter?.endDate) {\n conditions.push('timestamp <= ?');\n params.push(filter.endDate.toISOString());\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const query = `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`;\n\n const result = this.db.prepare(query).get(...params);\n return result.count;\n }\n\n async deleteOlderThan(date: Date): Promise<number> {\n const tableName = this.config.tableName || 'audit_logs';\n const result = this.db.prepare(`\n DELETE FROM ${tableName} WHERE timestamp < ?\n `).run(date.toISOString());\n\n return result.changes;\n }\n\n async getLastEntry(): Promise<HashedAuditLogEntry | null> {\n const tableName = this.config.tableName || 'audit_logs';\n const row = this.db.prepare(`\n SELECT * FROM ${tableName} ORDER BY sequence DESC LIMIT 1\n `).get();\n\n return row ? this.rowToEntry(row) : null;\n }\n\n async verifyChain(startSequence?: number, endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }> {\n const tableName = this.config.tableName || 'audit_logs';\n const start = startSequence || 1;\n const end = endSequence || (await this.count());\n\n const rows = this.db.prepare(`\n SELECT * FROM ${tableName} WHERE sequence >= ? AND sequence <= ? ORDER BY sequence ASC\n `).all(start, end);\n\n let previousHash: string | undefined;\n\n for (const row of rows) {\n const entry = this.rowToEntry(row);\n\n if (previousHash && entry.previousHash !== previousHash) {\n return { valid: false, brokenAt: entry.sequence };\n }\n\n previousHash = entry.hash;\n }\n\n return { valid: true };\n }\n\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n }\n }\n\n private rowToEntry(row: any): HashedAuditLogEntry {\n return {\n id: row.id,\n timestamp: row.timestamp,\n operation: row.operation,\n piiCount: row.piiCount,\n piiTypes: JSON.parse(row.piiTypes),\n textLength: row.textLength,\n processingTimeMs: row.processingTimeMs,\n redactionMode: row.redactionMode || undefined,\n success: row.success === 1,\n error: row.error || undefined,\n user: row.user || undefined,\n sessionId: row.sessionId || undefined,\n metadata: row.metadata ? JSON.parse(row.metadata) : undefined,\n hash: row.hash,\n previousHash: row.previousHash || undefined,\n sequence: row.sequence\n };\n }\n}\n\n/**\n * PostgreSQL adapter implementation (stub - requires pg package)\n */\nclass PostgreSQLAuditAdapter implements IAuditDatabaseAdapter {\n constructor(_config: AuditDatabaseConfig, _options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string }) {\n // Implementation will be added later\n }\n\n async initialize(): Promise<void> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet. Install with: npm install pg');\n }\n\n async insert(_entry: HashedAuditLogEntry): Promise<void> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async batchInsert(_entries: HashedAuditLogEntry[]): Promise<void> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async query(_filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async count(_filter?: Partial<AuditQueryFilter>): Promise<number> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async deleteOlderThan(_date: Date): Promise<number> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async getLastEntry(): Promise<HashedAuditLogEntry | null> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async verifyChain(_startSequence?: number, _endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }> {\n throw new Error('[PostgreSQLAuditAdapter] Not implemented yet');\n }\n\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * MongoDB adapter implementation (stub - requires mongodb package)\n */\nclass MongoDBuditAdapter implements IAuditDatabaseAdapter {\n constructor(_config: AuditDatabaseConfig, _options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string }) {\n // Implementation will be added later\n }\n\n async initialize(): Promise<void> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet. Install with: npm install mongodb');\n }\n\n async insert(_entry: HashedAuditLogEntry): Promise<void> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async batchInsert(_entries: HashedAuditLogEntry[]): Promise<void> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async query(_filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async count(_filter?: Partial<AuditQueryFilter>): Promise<number> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async deleteOlderThan(_date: Date): Promise<number> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async getLastEntry(): Promise<HashedAuditLogEntry | null> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async verifyChain(_startSequence?: number, _endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }> {\n throw new Error('[MongoDBuditAdapter] Not implemented yet');\n }\n\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * S3 adapter implementation (stub - requires aws-sdk)\n */\nclass S3AuditAdapter implements IAuditDatabaseAdapter {\n constructor(_config: AuditDatabaseConfig, _options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string }) {\n // Implementation will be added later\n }\n\n async initialize(): Promise<void> {\n throw new Error('[S3AuditAdapter] Not implemented yet. Install with: npm install @aws-sdk/client-s3');\n }\n\n async insert(_entry: HashedAuditLogEntry): Promise<void> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async batchInsert(_entries: HashedAuditLogEntry[]): Promise<void> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async query(_filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async count(_filter?: Partial<AuditQueryFilter>): Promise<number> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async deleteOlderThan(_date: Date): Promise<number> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async getLastEntry(): Promise<HashedAuditLogEntry | null> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async verifyChain(_startSequence?: number, _endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }> {\n throw new Error('[S3AuditAdapter] Not implemented yet');\n }\n\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * File-based adapter implementation (append-only log file)\n */\nclass FileAuditAdapter implements IAuditDatabaseAdapter {\n constructor(_config: AuditDatabaseConfig, _options: Required<Omit<PersistentAuditLoggerOptions, 'secretKey'>> & { secretKey?: string }) {\n // Implementation will be added later\n }\n\n async initialize(): Promise<void> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async insert(_entry: HashedAuditLogEntry): Promise<void> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async batchInsert(_entries: HashedAuditLogEntry[]): Promise<void> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async query(_filter: AuditQueryFilter): Promise<HashedAuditLogEntry[]> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async count(_filter?: Partial<AuditQueryFilter>): Promise<number> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async deleteOlderThan(_date: Date): Promise<number> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async getLastEntry(): Promise<HashedAuditLogEntry | null> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async verifyChain(_startSequence?: number, _endSequence?: number): Promise<{ valid: boolean; brokenAt?: number }> {\n throw new Error('[FileAuditAdapter] Not implemented yet');\n }\n\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * Create a persistent audit logger\n */\nexport function createPersistentAuditLogger(options: PersistentAuditLoggerOptions): PersistentAuditLogger {\n return new PersistentAuditLogger(options);\n}\n","/**\n * Metrics collection and export for monitoring redaction operations\n */\n\nimport type { IMetricsCollector, IMetricsExporter, RedactionMetrics, DetectionResult, RedactionMode } from '../types';\n\n/**\n * In-memory metrics collector and exporter\n * Collects metrics and provides Prometheus and StatsD export formats\n */\nexport class InMemoryMetricsCollector implements IMetricsCollector, IMetricsExporter {\n private metrics: RedactionMetrics;\n\n constructor() {\n this.metrics = this.createEmptyMetrics();\n }\n\n /**\n * Create empty metrics object\n */\n private createEmptyMetrics(): RedactionMetrics {\n return {\n totalRedactions: 0,\n totalPiiDetected: 0,\n totalProcessingTime: 0,\n averageProcessingTime: 0,\n totalTextLength: 0,\n piiByType: {},\n byRedactionMode: {},\n totalErrors: 0,\n lastUpdated: new Date().toISOString()\n };\n }\n\n /**\n * Record a redaction operation\n */\n recordRedaction(result: DetectionResult, processingTimeMs: number, redactionMode: RedactionMode): void {\n this.metrics.totalRedactions++;\n this.metrics.totalPiiDetected += result.detections.length;\n this.metrics.totalProcessingTime += processingTimeMs;\n this.metrics.averageProcessingTime = this.metrics.totalProcessingTime / this.metrics.totalRedactions;\n this.metrics.totalTextLength += result.original.length;\n\n // Count PII by type\n for (const detection of result.detections) {\n this.metrics.piiByType[detection.type] = (this.metrics.piiByType[detection.type] || 0) + 1;\n }\n\n // Count by redaction mode\n this.metrics.byRedactionMode[redactionMode] = (this.metrics.byRedactionMode[redactionMode] || 0) + 1;\n\n this.metrics.lastUpdated = new Date().toISOString();\n }\n\n /**\n * Record an error\n */\n recordError(): void {\n this.metrics.totalErrors++;\n this.metrics.lastUpdated = new Date().toISOString();\n }\n\n /**\n * Get metrics exporter\n */\n getExporter(): IMetricsExporter {\n return this;\n }\n\n /**\n * Get current metrics snapshot\n */\n getMetrics(): RedactionMetrics {\n return { ...this.metrics };\n }\n\n /**\n * Reset all metrics\n */\n reset(): void {\n this.metrics = this.createEmptyMetrics();\n }\n\n /**\n * Export metrics in Prometheus format\n */\n exportPrometheus(metrics: RedactionMetrics = this.metrics, prefix: string = 'openredaction'): string {\n const lines: string[] = [];\n const timestamp = Date.now();\n\n // Total redactions\n lines.push(`# HELP ${prefix}_total_redactions Total number of redaction operations`);\n lines.push(`# TYPE ${prefix}_total_redactions counter`);\n lines.push(`${prefix}_total_redactions ${metrics.totalRedactions} ${timestamp}`);\n lines.push('');\n\n // Total PII detected\n lines.push(`# HELP ${prefix}_total_pii_detected Total number of PII items detected`);\n lines.push(`# TYPE ${prefix}_total_pii_detected counter`);\n lines.push(`${prefix}_total_pii_detected ${metrics.totalPiiDetected} ${timestamp}`);\n lines.push('');\n\n // Average processing time\n lines.push(`# HELP ${prefix}_avg_processing_time_ms Average processing time in milliseconds`);\n lines.push(`# TYPE ${prefix}_avg_processing_time_ms gauge`);\n lines.push(`${prefix}_avg_processing_time_ms ${metrics.averageProcessingTime.toFixed(2)} ${timestamp}`);\n lines.push('');\n\n // Total processing time\n lines.push(`# HELP ${prefix}_total_processing_time_ms Total processing time in milliseconds`);\n lines.push(`# TYPE ${prefix}_total_processing_time_ms counter`);\n lines.push(`${prefix}_total_processing_time_ms ${metrics.totalProcessingTime.toFixed(2)} ${timestamp}`);\n lines.push('');\n\n // Total text length\n lines.push(`# HELP ${prefix}_total_text_length Total text length processed in characters`);\n lines.push(`# TYPE ${prefix}_total_text_length counter`);\n lines.push(`${prefix}_total_text_length ${metrics.totalTextLength} ${timestamp}`);\n lines.push('');\n\n // PII by type\n lines.push(`# HELP ${prefix}_pii_by_type PII detection counts by type`);\n lines.push(`# TYPE ${prefix}_pii_by_type counter`);\n for (const [type, count] of Object.entries(metrics.piiByType)) {\n lines.push(`${prefix}_pii_by_type{type=\"${type}\"} ${count} ${timestamp}`);\n }\n lines.push('');\n\n // Operations by redaction mode\n lines.push(`# HELP ${prefix}_by_redaction_mode Operation counts by redaction mode`);\n lines.push(`# TYPE ${prefix}_by_redaction_mode counter`);\n for (const [mode, count] of Object.entries(metrics.byRedactionMode)) {\n lines.push(`${prefix}_by_redaction_mode{mode=\"${mode}\"} ${count} ${timestamp}`);\n }\n lines.push('');\n\n // Total errors\n lines.push(`# HELP ${prefix}_total_errors Total number of errors`);\n lines.push(`# TYPE ${prefix}_total_errors counter`);\n lines.push(`${prefix}_total_errors ${metrics.totalErrors} ${timestamp}`);\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Export metrics in StatsD format\n */\n exportStatsD(metrics: RedactionMetrics = this.metrics, prefix: string = 'openredaction'): string[] {\n const lines: string[] = [];\n\n // Counter metrics\n lines.push(`${prefix}.total_redactions:${metrics.totalRedactions}|c`);\n lines.push(`${prefix}.total_pii_detected:${metrics.totalPiiDetected}|c`);\n lines.push(`${prefix}.total_processing_time_ms:${metrics.totalProcessingTime.toFixed(2)}|c`);\n lines.push(`${prefix}.total_text_length:${metrics.totalTextLength}|c`);\n lines.push(`${prefix}.total_errors:${metrics.totalErrors}|c`);\n\n // Gauge metrics\n lines.push(`${prefix}.avg_processing_time_ms:${metrics.averageProcessingTime.toFixed(2)}|g`);\n\n // PII by type (with tags)\n for (const [type, count] of Object.entries(metrics.piiByType)) {\n lines.push(`${prefix}.pii_by_type:${count}|c|#type:${type}`);\n }\n\n // Operations by redaction mode (with tags)\n for (const [mode, count] of Object.entries(metrics.byRedactionMode)) {\n lines.push(`${prefix}.by_redaction_mode:${count}|c|#mode:${mode}`);\n }\n\n return lines;\n }\n}\n","/**\n * Prometheus metrics HTTP server for monitoring\n * Exposes /metrics endpoint for Prometheus scraping\n */\n\nimport type { IMetricsCollector } from '../types';\n\n/**\n * Prometheus server options\n */\nexport interface PrometheusServerOptions {\n /** Port to listen on (default: 9090) */\n port?: number;\n /** Host to bind to (default: '0.0.0.0') */\n host?: string;\n /** Metrics path (default: '/metrics') */\n metricsPath?: string;\n /** Metrics prefix (default: 'openredaction') */\n prefix?: string;\n /** Health check path (default: '/health') */\n healthPath?: string;\n /** Enable CORS (default: false) */\n enableCors?: boolean;\n /** Basic auth username (optional) */\n username?: string;\n /** Basic auth password (optional) */\n password?: string;\n}\n\n/**\n * Prometheus metrics HTTP server\n * Provides a lightweight HTTP server for exposing metrics to Prometheus\n */\nexport class PrometheusServer {\n private server?: any;\n private metricsCollector: IMetricsCollector;\n private options: Required<Omit<PrometheusServerOptions, 'username' | 'password'>> & Pick<PrometheusServerOptions, 'username' | 'password'>;\n private isRunning: boolean = false;\n private requestCount: number = 0;\n private lastScrapeTime?: Date;\n\n constructor(metricsCollector: IMetricsCollector, options?: PrometheusServerOptions) {\n this.metricsCollector = metricsCollector;\n this.options = {\n port: options?.port ?? 9090,\n host: options?.host ?? '0.0.0.0',\n metricsPath: options?.metricsPath ?? '/metrics',\n prefix: options?.prefix ?? 'openredaction',\n healthPath: options?.healthPath ?? '/health',\n enableCors: options?.enableCors ?? false,\n username: options?.username,\n password: options?.password\n };\n }\n\n /**\n * Start the Prometheus metrics server\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error('[PrometheusServer] Server is already running');\n }\n\n try {\n // Try to use native http module\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const http = require('http');\n\n this.server = http.createServer(this.handleRequest.bind(this));\n\n return new Promise<void>((resolve, reject) => {\n this.server.listen(this.options.port, this.options.host, () => {\n this.isRunning = true;\n console.log(\n `[PrometheusServer] Metrics server started on http://${this.options.host}:${this.options.port}${this.options.metricsPath}`\n );\n resolve();\n });\n\n this.server.on('error', (error: any) => {\n reject(new Error(`[PrometheusServer] Failed to start server: ${error.message}`));\n });\n });\n } catch (error: any) {\n throw new Error(`[PrometheusServer] Failed to initialize HTTP server: ${error.message}`);\n }\n }\n\n /**\n * Stop the server\n */\n async stop(): Promise<void> {\n if (!this.isRunning || !this.server) {\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n this.server.close((error: any) => {\n if (error) {\n reject(new Error(`[PrometheusServer] Failed to stop server: ${error.message}`));\n } else {\n this.isRunning = false;\n console.log('[PrometheusServer] Server stopped');\n resolve();\n }\n });\n });\n }\n\n /**\n * Handle incoming HTTP requests\n */\n private handleRequest(req: any, res: any): void {\n this.requestCount++;\n\n // CORS headers\n if (this.options.enableCors) {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n }\n\n // Only allow GET requests\n if (req.method !== 'GET') {\n res.writeHead(405, { 'Content-Type': 'text/plain' });\n res.end('Method Not Allowed');\n return;\n }\n\n // Basic authentication\n if (this.options.username && this.options.password) {\n const authHeader = req.headers.authorization;\n\n if (!authHeader || !this.validateAuth(authHeader)) {\n res.writeHead(401, {\n 'Content-Type': 'text/plain',\n 'WWW-Authenticate': 'Basic realm=\"Prometheus Metrics\"'\n });\n res.end('Unauthorized');\n return;\n }\n }\n\n // Route handling\n const url = req.url;\n\n if (url === this.options.metricsPath) {\n this.handleMetrics(req, res);\n } else if (url === this.options.healthPath) {\n this.handleHealth(req, res);\n } else if (url === '/') {\n this.handleRoot(req, res);\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n }\n\n /**\n * Handle /metrics endpoint\n */\n private handleMetrics(_req: any, res: any): void {\n try {\n this.lastScrapeTime = new Date();\n\n const exporter = this.metricsCollector.getExporter();\n const metrics = exporter.getMetrics();\n const prometheusFormat = exporter.exportPrometheus(metrics, this.options.prefix);\n\n // Add server-specific metrics\n const serverMetrics = this.getServerMetrics();\n const fullMetrics = prometheusFormat + '\\n' + serverMetrics;\n\n res.writeHead(200, { 'Content-Type': 'text/plain; version=0.0.4' });\n res.end(fullMetrics);\n } catch (error: any) {\n console.error('[PrometheusServer] Error exporting metrics:', error);\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Internal Server Error');\n }\n }\n\n /**\n * Handle /health endpoint\n */\n private handleHealth(_req: any, res: any): void {\n const health = {\n status: 'healthy',\n uptime: process.uptime(),\n timestamp: new Date().toISOString(),\n metrics: {\n requestCount: this.requestCount,\n lastScrapeTime: this.lastScrapeTime?.toISOString()\n }\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(health, null, 2));\n }\n\n /**\n * Handle / root endpoint\n */\n private handleRoot(_req: any, res: any): void {\n const html = `\n<!DOCTYPE html>\n<html>\n<head>\n <title>OpenRedaction Prometheus Exporter</title>\n <style>\n body { font-family: sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }\n h1 { color: #333; }\n a { color: #0066cc; }\n .endpoint { background: #f5f5f5; padding: 10px; margin: 10px 0; border-radius: 4px; }\n </style>\n</head>\n<body>\n <h1>OpenRedaction Prometheus Exporter</h1>\n <p>This server exposes metrics for Prometheus monitoring.</p>\n\n <h2>Endpoints</h2>\n <div class=\"endpoint\">\n <strong>GET <a href=\"${this.options.metricsPath}\">${this.options.metricsPath}</a></strong><br>\n Prometheus metrics in text format\n </div>\n <div class=\"endpoint\">\n <strong>GET <a href=\"${this.options.healthPath}\">${this.options.healthPath}</a></strong><br>\n Health check endpoint (JSON)\n </div>\n\n <h2>Configuration</h2>\n <ul>\n <li>Host: ${this.options.host}</li>\n <li>Port: ${this.options.port}</li>\n <li>Metrics Prefix: ${this.options.prefix}</li>\n <li>CORS Enabled: ${this.options.enableCors}</li>\n <li>Authentication: ${this.options.username ? 'Enabled' : 'Disabled'}</li>\n </ul>\n\n <h2>Prometheus Configuration</h2>\n <p>Add this to your <code>prometheus.yml</code>:</p>\n <pre>\nscrape_configs:\n - job_name: 'openredaction'\n static_configs:\n - targets: ['${this.options.host}:${this.options.port}']\n metrics_path: '${this.options.metricsPath}'\n${this.options.username ? ` basic_auth:\n username: '${this.options.username}'\n password: '${this.options.password}'` : ''}\n </pre>\n</body>\n</html>\n `.trim();\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(html);\n }\n\n /**\n * Validate basic authentication\n */\n private validateAuth(authHeader: string): boolean {\n try {\n const base64Credentials = authHeader.split(' ')[1];\n const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8');\n const [username, password] = credentials.split(':');\n\n return username === this.options.username && password === this.options.password;\n } catch {\n return false;\n }\n }\n\n /**\n * Get server-specific metrics in Prometheus format\n */\n private getServerMetrics(): string {\n const prefix = this.options.prefix;\n const timestamp = Date.now();\n const lines: string[] = [];\n\n // Server uptime\n lines.push(`# HELP ${prefix}_server_uptime_seconds Server uptime in seconds`);\n lines.push(`# TYPE ${prefix}_server_uptime_seconds counter`);\n lines.push(`${prefix}_server_uptime_seconds ${process.uptime().toFixed(2)} ${timestamp}`);\n lines.push('');\n\n // Request count\n lines.push(`# HELP ${prefix}_server_requests_total Total number of requests to metrics server`);\n lines.push(`# TYPE ${prefix}_server_requests_total counter`);\n lines.push(`${prefix}_server_requests_total ${this.requestCount} ${timestamp}`);\n lines.push('');\n\n // Last scrape time\n if (this.lastScrapeTime) {\n const lastScrapeSeconds = Math.floor((Date.now() - this.lastScrapeTime.getTime()) / 1000);\n lines.push(`# HELP ${prefix}_server_last_scrape_seconds Seconds since last metrics scrape`);\n lines.push(`# TYPE ${prefix}_server_last_scrape_seconds gauge`);\n lines.push(`${prefix}_server_last_scrape_seconds ${lastScrapeSeconds} ${timestamp}`);\n lines.push('');\n }\n\n // Memory usage\n const mem = process.memoryUsage();\n lines.push(`# HELP ${prefix}_server_memory_bytes Server memory usage in bytes`);\n lines.push(`# TYPE ${prefix}_server_memory_bytes gauge`);\n lines.push(`${prefix}_server_memory_bytes{type=\"rss\"} ${mem.rss} ${timestamp}`);\n lines.push(`${prefix}_server_memory_bytes{type=\"heapTotal\"} ${mem.heapTotal} ${timestamp}`);\n lines.push(`${prefix}_server_memory_bytes{type=\"heapUsed\"} ${mem.heapUsed} ${timestamp}`);\n lines.push(`${prefix}_server_memory_bytes{type=\"external\"} ${mem.external} ${timestamp}`);\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Get server statistics\n */\n getStats(): {\n isRunning: boolean;\n requestCount: number;\n lastScrapeTime?: Date;\n uptime: number;\n host: string;\n port: number;\n metricsPath: string;\n } {\n return {\n isRunning: this.isRunning,\n requestCount: this.requestCount,\n lastScrapeTime: this.lastScrapeTime,\n uptime: process.uptime(),\n host: this.options.host,\n port: this.options.port,\n metricsPath: this.options.metricsPath\n };\n }\n}\n\n/**\n * Create a Prometheus server instance\n */\nexport function createPrometheusServer(\n metricsCollector: IMetricsCollector,\n options?: PrometheusServerOptions\n): PrometheusServer {\n return new PrometheusServer(metricsCollector, options);\n}\n\n/**\n * Example Grafana dashboard JSON for OpenRedaction metrics\n * Can be imported directly into Grafana\n */\nexport const GRAFANA_DASHBOARD_TEMPLATE = {\n dashboard: {\n title: 'OpenRedaction Metrics',\n tags: ['pii', 'redaction', 'security'],\n timezone: 'browser',\n panels: [\n {\n id: 1,\n title: 'Total Redactions',\n type: 'graph',\n targets: [\n {\n expr: 'rate(openredaction_total_redactions[5m])',\n legendFormat: 'Redactions per second'\n }\n ]\n },\n {\n id: 2,\n title: 'PII Detected by Type',\n type: 'graph',\n targets: [\n {\n expr: 'rate(openredaction_pii_by_type[5m])',\n legendFormat: '{{type}}'\n }\n ]\n },\n {\n id: 3,\n title: 'Average Processing Time',\n type: 'graph',\n targets: [\n {\n expr: 'openredaction_avg_processing_time_ms',\n legendFormat: 'Processing time (ms)'\n }\n ]\n },\n {\n id: 4,\n title: 'Error Rate',\n type: 'graph',\n targets: [\n {\n expr: 'rate(openredaction_total_errors[5m])',\n legendFormat: 'Errors per second'\n }\n ]\n },\n {\n id: 5,\n title: 'Operations by Redaction Mode',\n type: 'piechart',\n targets: [\n {\n expr: 'openredaction_by_redaction_mode',\n legendFormat: '{{mode}}'\n }\n ]\n },\n {\n id: 6,\n title: 'Server Memory Usage',\n type: 'graph',\n targets: [\n {\n expr: 'openredaction_server_memory_bytes',\n legendFormat: '{{type}}'\n }\n ]\n }\n ]\n }\n};\n","/**\n * Predefined RBAC roles with permission sets\n */\n\nimport type { Role, Permission } from '../types';\n\n/**\n * All available permissions\n */\nexport const ALL_PERMISSIONS: Permission[] = [\n 'pattern:read',\n 'pattern:write',\n 'pattern:delete',\n 'detection:detect',\n 'detection:redact',\n 'detection:restore',\n 'audit:read',\n 'audit:export',\n 'audit:delete',\n 'metrics:read',\n 'metrics:export',\n 'metrics:reset',\n 'config:read',\n 'config:write'\n];\n\n/**\n * Admin role - full access to all operations\n */\nexport const ADMIN_ROLE: Role = {\n name: 'admin',\n description: 'Administrator with full access to all operations',\n permissions: ALL_PERMISSIONS\n};\n\n/**\n * Analyst role - can perform analysis and read audit/metrics\n */\nexport const ANALYST_ROLE: Role = {\n name: 'analyst',\n description: 'Data analyst with detection, audit, and metrics access',\n permissions: [\n 'pattern:read',\n 'detection:detect',\n 'detection:redact',\n 'detection:restore',\n 'audit:read',\n 'audit:export',\n 'metrics:read',\n 'metrics:export',\n 'config:read'\n ]\n};\n\n/**\n * Operator role - can perform detections and basic operations\n */\nexport const OPERATOR_ROLE: Role = {\n name: 'operator',\n description: 'Operator with detection and limited audit/metrics access',\n permissions: [\n 'pattern:read',\n 'detection:detect',\n 'detection:redact',\n 'audit:read',\n 'metrics:read'\n ]\n};\n\n/**\n * Viewer role - read-only access to patterns, audit logs, and metrics\n */\nexport const VIEWER_ROLE: Role = {\n name: 'viewer',\n description: 'Read-only viewer with no execution permissions',\n permissions: [\n 'pattern:read',\n 'audit:read',\n 'audit:export',\n 'metrics:read',\n 'metrics:export',\n 'config:read'\n ]\n};\n\n/**\n * Get predefined role by name\n */\nexport function getPredefinedRole(roleName: string): Role | undefined {\n switch (roleName.toLowerCase()) {\n case 'admin':\n return ADMIN_ROLE;\n case 'analyst':\n return ANALYST_ROLE;\n case 'operator':\n return OPERATOR_ROLE;\n case 'viewer':\n return VIEWER_ROLE;\n default:\n return undefined;\n }\n}\n\n/**\n * Create a custom role with specific permissions\n */\nexport function createCustomRole(name: string, permissions: Permission[], description?: string): Role {\n return {\n name,\n description: description || `Custom role: ${name}`,\n permissions\n };\n}\n","/**\n * RBAC Manager for role-based access control\n */\n\nimport type { Role, Permission, IRBACManager, PIIPattern } from '../types';\nimport { ADMIN_ROLE } from './roles';\n\n/**\n * Default RBAC Manager implementation\n * Provides role-based permission checking and pattern filtering\n */\nexport class RBACManager implements IRBACManager {\n private role: Role;\n\n constructor(role: Role = ADMIN_ROLE) {\n this.role = role;\n }\n\n /**\n * Check if current role has a specific permission\n */\n hasPermission(permission: Permission): boolean {\n return this.role.permissions.includes(permission);\n }\n\n /**\n * Check if current role has all specified permissions\n */\n hasAllPermissions(permissions: Permission[]): boolean {\n return permissions.every(permission => this.hasPermission(permission));\n }\n\n /**\n * Check if current role has any of the specified permissions\n */\n hasAnyPermission(permissions: Permission[]): boolean {\n return permissions.some(permission => this.hasPermission(permission));\n }\n\n /**\n * Get current role\n */\n getRole(): Role {\n return { ...this.role };\n }\n\n /**\n * Set role (updates permissions)\n */\n setRole(role: Role): void {\n this.role = role;\n }\n\n /**\n * Get all permissions for current role\n */\n getPermissions(): Permission[] {\n return [...this.role.permissions];\n }\n\n /**\n * Filter patterns based on read permissions\n * Returns empty array if user lacks pattern:read permission\n */\n filterPatterns(patterns: PIIPattern[]): PIIPattern[] {\n if (!this.hasPermission('pattern:read')) {\n return [];\n }\n return patterns;\n }\n}\n\n/**\n * Create RBAC manager with predefined or custom role\n */\nexport function createRBACManager(role: Role): RBACManager {\n return new RBACManager(role);\n}\n","/**\n * Validators for PII pattern matching\n */\n\n/**\n * Luhn algorithm validator for credit cards\n * https://en.wikipedia.org/wiki/Luhn_algorithm\n */\nexport function validateLuhn(cardNumber: string, _context?: string): boolean {\n // Remove any spaces or hyphens\n const cleaned = cardNumber.replace(/[\\s-]/g, '');\n\n // Must be numeric and at least 13 digits\n if (!/^\\d{13,19}$/.test(cleaned)) {\n return false;\n }\n\n let sum = 0;\n let isEven = false;\n\n // Loop through values starting from the right\n for (let i = cleaned.length - 1; i >= 0; i--) {\n let digit = parseInt(cleaned[i], 10);\n\n if (isEven) {\n digit *= 2;\n if (digit > 9) {\n digit -= 9;\n }\n }\n\n sum += digit;\n isEven = !isEven;\n }\n\n return sum % 10 === 0;\n}\n\n/**\n * IBAN validator with checksum verification\n */\nexport function validateIBAN(iban: string, _context?: string): boolean {\n // Remove spaces and convert to uppercase\n const cleaned = iban.replace(/\\s/g, '').toUpperCase();\n\n // Check format: 2 letters, 2 digits, up to 30 alphanumeric\n if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/.test(cleaned)) {\n return false;\n }\n\n // Country-specific length validation\n const lengths: Record<string, number> = {\n AD: 24, AE: 23, AL: 28, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22,\n BH: 22, BR: 29, CH: 21, CR: 21, CY: 28, CZ: 24, DE: 22, DK: 18,\n DO: 28, EE: 20, ES: 24, FI: 18, FO: 18, FR: 27, GB: 22, GE: 22,\n GI: 23, GL: 18, GR: 27, GT: 28, HR: 21, HU: 28, IE: 22, IL: 23,\n IS: 26, IT: 27, JO: 30, KW: 30, KZ: 20, LB: 28, LI: 21, LT: 20,\n LU: 20, LV: 21, MC: 27, MD: 24, ME: 22, MK: 19, MR: 27, MT: 31,\n MU: 30, NL: 18, NO: 15, PK: 24, PL: 28, PS: 29, PT: 25, QA: 29,\n RO: 24, RS: 22, SA: 24, SE: 24, SI: 19, SK: 24, SM: 27, TN: 24,\n TR: 26, UA: 29, VA: 22, VG: 24, XK: 20\n };\n\n const countryCode = cleaned.substring(0, 2);\n const expectedLength = lengths[countryCode];\n\n if (!expectedLength || cleaned.length !== expectedLength) {\n return false;\n }\n\n // Move first 4 characters to end\n const rearranged = cleaned.substring(4) + cleaned.substring(0, 4);\n\n // Replace letters with numbers (A=10, B=11, ..., Z=35)\n const numericString = rearranged.replace(/[A-Z]/g, (char) =>\n (char.charCodeAt(0) - 55).toString()\n );\n\n // Perform mod-97 operation\n return mod97(numericString) === 1;\n}\n\n/**\n * Helper function for mod-97 calculation on large numbers\n */\nfunction mod97(string: string): number {\n let remainder = 0;\n for (let i = 0; i < string.length; i++) {\n remainder = (remainder * 10 + parseInt(string[i], 10)) % 97;\n }\n return remainder;\n}\n\n/**\n * UK National Insurance Number validator\n */\nexport function validateNINO(nino: string, _context?: string): boolean {\n const cleaned = nino.replace(/\\s/g, '').toUpperCase();\n\n // Format: 2 letters, 6 digits, 1 letter (A, B, C, or D)\n if (!/^[A-CEGHJ-PR-TW-Z]{2}[0-9]{6}[A-D]$/.test(cleaned)) {\n return false;\n }\n\n // Invalid prefixes\n const invalidPrefixes = ['BG', 'GB', 'NK', 'KN', 'TN', 'NT', 'ZZ'];\n const prefix = cleaned.substring(0, 2);\n\n return !invalidPrefixes.includes(prefix);\n}\n\n/**\n * UK NHS Number validator with checksum\n */\nexport function validateNHS(nhs: string, _context?: string): boolean {\n const cleaned = nhs.replace(/[\\s-]/g, '');\n\n if (!/^\\d{10}$/.test(cleaned)) {\n return false;\n }\n\n // Calculate check digit using mod 11 algorithm\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += parseInt(cleaned[i], 10) * (10 - i);\n }\n\n const checkDigit = 11 - (sum % 11);\n const expectedCheckDigit = checkDigit === 11 ? 0 : checkDigit;\n\n return expectedCheckDigit === parseInt(cleaned[9], 10) && checkDigit !== 10;\n}\n\n/**\n * UK Passport validator\n */\nexport function validateUKPassport(passport: string, _context?: string): boolean {\n const cleaned = passport.replace(/\\s/g, '').toUpperCase();\n\n // Format: 9 digits or 3 digits + 6 digits\n return /^\\d{9}$/.test(cleaned) || /^\\d{3}\\d{6}$/.test(cleaned);\n}\n\n/**\n * US Social Security Number validator (format check only)\n */\nexport function validateSSN(ssn: string, _context?: string): boolean {\n const cleaned = ssn.replace(/[\\s-]/g, '');\n\n if (!/^\\d{9}$/.test(cleaned)) {\n return false;\n }\n\n // Invalid patterns\n const area = cleaned.substring(0, 3);\n const group = cleaned.substring(3, 5);\n const serial = cleaned.substring(5, 9);\n\n // Area cannot be 000, 666, or 900-999\n if (area === '000' || area === '666' || parseInt(area, 10) >= 900) {\n return false;\n }\n\n // Group and serial cannot be all zeros\n if (group === '00' || serial === '0000') {\n return false;\n }\n\n // Check for known invalid/test SSNs (repeated digits)\n const invalidSSNs = ['111111111', '222222222', '333333333', '444444444',\n '555555555', '666666666', '777777777', '888888888', '999999999'];\n\n return !invalidSSNs.includes(cleaned);\n}\n\n/**\n * UK Sort Code validator (format check)\n */\nexport function validateSortCode(sortCode: string, _context?: string): boolean {\n const cleaned = sortCode.replace(/[\\s-]/g, '');\n return /^\\d{6}$/.test(cleaned);\n}\n\n/**\n * Context-aware name validator to reduce false positives\n */\nexport function validateName(name: string, context: string): boolean {\n // Filter out common false positives\n const businessTerms = [\n 'account', 'company', 'limited', 'ltd', 'inc', 'corp',\n 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday',\n 'january', 'february', 'march', 'april', 'may', 'june',\n 'july', 'august', 'september', 'october', 'november', 'december',\n 'mr', 'mrs', 'ms', 'dr', 'sir', 'madam', 'lord', 'lady'\n ];\n\n const nameLower = name.toLowerCase();\n\n // Skip if it's a business term\n if (businessTerms.some(term => nameLower.includes(term))) {\n return false;\n }\n\n // Skip if it's all caps (likely an acronym)\n if (name === name.toUpperCase() && name.length <= 5) {\n return false;\n }\n\n // Skip single letter names\n if (name.length === 1) {\n return false;\n }\n\n // Check if appears in business context\n const contextLower = context.toLowerCase();\n if (\n contextLower.includes('company ') ||\n contextLower.includes('business ') ||\n contextLower.includes('organization')\n ) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Email validator with DNS check capability\n */\nexport function validateEmail(email: string, _context?: string): boolean {\n // Basic RFC 5322 compliant regex\n const emailRegex = /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n\n if (!emailRegex.test(email)) {\n return false;\n }\n\n // Additional validations\n const [local, domain] = email.split('@');\n\n // Local part checks\n if (local.length > 64 || domain.length > 255) {\n return false;\n }\n\n // Domain must have at least one dot\n if (!domain.includes('.')) {\n return false;\n }\n\n return true;\n}\n","/**\n * Personal PII patterns (emails, names, etc.)\n */\n\nimport { PIIPattern } from '../types';\nimport { validateEmail, validateName } from '../validators';\n\nexport const personalPatterns: PIIPattern[] = [\n {\n type: 'EMAIL',\n regex: /\\b[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\\b/g,\n priority: 100,\n validator: validateEmail,\n placeholder: '[EMAIL_{n}]',\n description: 'Email address',\n severity: 'high'\n },\n {\n type: 'NAME',\n regex: /\\b(?:(?:Mr|Mrs|Ms|Miss|Dr|Prof|Professor|Sir|Madam|Lady|Lord|Rev|Father|Sister|Brother)\\.?\\s+)?([A-Z][a-z]+(?:-[A-Z][a-z]+)? (?:[A-Z][a-z]+(?:-[A-Z][a-z]+)? )?[A-Z][a-z]+(?:-[A-Z][a-z]+)?)(?:\\s+(?:Jr|Sr|II|III|IV|PhD|MD|Esq|DDS|DVM|MBA|CPA)\\.?)?\\b/g,\n priority: 50,\n validator: validateName,\n placeholder: '[NAME_{n}]',\n description: 'Person name with salutations/suffixes',\n severity: 'high'\n },\n {\n type: 'EMPLOYEE_ID',\n regex: /\\b(?:EMP|EMPL|EMPLOYEE)[_\\s-]?(?:ID|NUM(?:BER)?)?[:\\s-]*([A-Z0-9]{4,10})\\b/gi,\n priority: 90,\n placeholder: '[EMPLOYEE_ID_{n}]',\n description: 'Employee ID',\n severity: 'medium'\n },\n {\n type: 'USERNAME',\n regex: /\\b(?:user(?:name)?|login)[:\\s]+([a-zA-Z0-9_-]{3,20})\\b/gi,\n priority: 85,\n placeholder: '[USERNAME_{n}]',\n description: 'Username',\n severity: 'medium'\n },\n {\n type: 'DATE_OF_BIRTH',\n regex: /\\b(?:DOB|date of birth|birth ?date)[:\\s]*(\\d{1,2}[-\\/]\\d{1,2}[-\\/]\\d{2,4})\\b/gi,\n priority: 95,\n placeholder: '[DOB_{n}]',\n description: 'Date of birth',\n severity: 'high'\n }\n];\n","/**\n * Financial PII patterns (credit cards, bank accounts, etc.)\n */\n\nimport { PIIPattern } from '../types';\nimport { validateLuhn, validateIBAN, validateSortCode } from '../validators';\n\nexport const financialPatterns: PIIPattern[] = [\n {\n type: 'CREDIT_CARD',\n regex: /\\b(?:(?:\\d{4}[\\s-]?){3}\\d{4}|\\d{4}[\\s-]?\\d{6}[\\s-]?\\d{5})\\b/g,\n priority: 100,\n validator: (match) => validateLuhn(match),\n placeholder: '[CREDIT_CARD_{n}]',\n description: 'Credit card number',\n severity: 'high'\n },\n {\n type: 'IBAN',\n regex: /\\b[A-Z]{2}\\d{2}[A-Z0-9]{1,30}\\b/g,\n priority: 95,\n validator: (match) => validateIBAN(match),\n placeholder: '[IBAN_{n}]',\n description: 'IBAN bank account',\n severity: 'high'\n },\n {\n type: 'BANK_ACCOUNT_UK',\n regex: /\\b(?:account|acc)[:\\s#]*([0-9]{8})\\b/gi,\n priority: 90,\n placeholder: '[BANK_ACCOUNT_{n}]',\n description: 'UK bank account number',\n severity: 'high'\n },\n {\n type: 'SORT_CODE_UK',\n regex: /\\b(?:sort[:\\s]?code|SC)[:\\s]*(\\d{2}[-\\s]?\\d{2}[-\\s]?\\d{2})\\b/gi,\n priority: 90,\n validator: (match) => validateSortCode(match),\n placeholder: '[SORT_CODE_{n}]',\n description: 'UK sort code',\n severity: 'high'\n },\n {\n type: 'ROUTING_NUMBER_US',\n regex: /\\b(?:routing|RTN|ABA)[:\\s#]*([0-9]{9})\\b/gi,\n priority: 90,\n placeholder: '[ROUTING_NUMBER_{n}]',\n description: 'US routing number',\n severity: 'high'\n },\n {\n type: 'CVV',\n regex: /\\b(?:CVV|CVC|CSC|CVN)[:\\s]*(\\d{3,4})\\b/gi,\n priority: 95,\n placeholder: '[CVV_{n}]',\n description: 'Card security code',\n severity: 'high'\n },\n {\n type: 'IFSC',\n regex: /\\b[A-Z]{4}0[A-Z0-9]{6}\\b/g,\n priority: 90,\n placeholder: '[IFSC_{n}]',\n description: 'Indian Financial System Code',\n severity: 'high'\n },\n {\n type: 'CLABE',\n regex: /\\b\\d{18}\\b/g,\n priority: 85,\n validator: (match) => {\n // CLABE has 18 digits: 3 bank + 3 branch + 11 account + 1 check digit\n if (match.length !== 18) return false;\n\n // Validate check digit using weighted sum\n const weights = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];\n let sum = 0;\n for (let i = 0; i < 17; i++) {\n sum += parseInt(match[i]) * weights[i];\n }\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === parseInt(match[17]);\n },\n placeholder: '[CLABE_{n}]',\n description: 'Mexican CLABE bank account number',\n severity: 'high'\n },\n {\n type: 'BSB_AU',\n regex: /\\b(?:BSB)[:\\s]*(\\d{3}[-\\s]?\\d{3})\\b/gi,\n priority: 90,\n validator: (match) => {\n const digits = match.replace(/\\D/g, '');\n return digits.length === 6;\n },\n placeholder: '[BSB_{n}]',\n description: 'Australian Bank State Branch number',\n severity: 'high'\n },\n {\n type: 'ISIN',\n regex: /\\b[A-Z]{2}[A-Z0-9]{9}\\d\\b/g,\n priority: 85,\n validator: (match) => {\n // ISIN: 2 letter country code + 9 alphanumeric + 1 check digit\n if (match.length !== 12) return false;\n\n // Convert letters to numbers (A=10, B=11, etc.)\n let numStr = '';\n for (let i = 0; i < match.length - 1; i++) {\n const char = match[i];\n if (char >= 'A' && char <= 'Z') {\n numStr += (char.charCodeAt(0) - 55).toString();\n } else {\n numStr += char;\n }\n }\n\n // Luhn check\n let sum = 0;\n let alternate = false;\n for (let i = numStr.length - 1; i >= 0; i--) {\n let digit = parseInt(numStr[i]);\n if (alternate) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n sum += digit;\n alternate = !alternate;\n }\n\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === parseInt(match[11]);\n },\n placeholder: '[ISIN_{n}]',\n description: 'International Securities Identification Number',\n severity: 'medium'\n },\n {\n type: 'CUSIP',\n regex: /\\b[A-Z0-9]{9}\\b/g,\n priority: 80,\n validator: (match) => {\n // CUSIP: 9 characters (8 alphanumeric + 1 check digit)\n if (match.length !== 9) return false;\n\n // Convert to numbers\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n let value: number;\n const char = match[i];\n if (char >= '0' && char <= '9') {\n value = parseInt(char);\n } else if (char >= 'A' && char <= 'Z') {\n value = char.charCodeAt(0) - 55; // A=10, B=11, etc.\n } else {\n return false;\n }\n\n // Double every second digit\n if (i % 2 !== 0) {\n value *= 2;\n }\n\n // Add digits\n sum += Math.floor(value / 10) + (value % 10);\n }\n\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === parseInt(match[8]);\n },\n placeholder: '[CUSIP_{n}]',\n description: 'CUSIP securities identifier',\n severity: 'medium'\n },\n {\n type: 'SEDOL',\n regex: /\\b[B-DF-HJ-NP-TV-Z0-9]{6}\\d\\b/g,\n priority: 80,\n validator: (match) => {\n // SEDOL: 6 alphanumeric + 1 check digit (excludes vowels and I)\n if (match.length !== 7) return false;\n\n const weights = [1, 3, 1, 7, 3, 9];\n let sum = 0;\n\n for (let i = 0; i < 6; i++) {\n const char = match[i];\n let value: number;\n if (char >= '0' && char <= '9') {\n value = parseInt(char);\n } else {\n value = char.charCodeAt(0) - 55; // A=10, B=11, etc.\n }\n sum += value * weights[i];\n }\n\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === parseInt(match[6]);\n },\n placeholder: '[SEDOL_{n}]',\n description: 'Stock Exchange Daily Official List identifier',\n severity: 'medium'\n },\n {\n type: 'LEI',\n regex: /\\b[A-Z0-9]{20}\\b/g,\n priority: 75,\n validator: (match) => {\n // LEI: 20 alphanumeric characters\n if (match.length !== 20) return false;\n\n // Convert to numeric string\n let numStr = '';\n for (const char of match) {\n if (char >= '0' && char <= '9') {\n numStr += char;\n } else if (char >= 'A' && char <= 'Z') {\n numStr += (char.charCodeAt(0) - 55).toString();\n } else {\n return false;\n }\n }\n\n // ISO 17442 check digit validation (mod 97)\n const checkDigits = parseInt(numStr.slice(-2));\n const baseNumber = numStr.slice(0, -2);\n\n // Calculate mod 97\n let remainder = 0;\n for (const digit of baseNumber) {\n remainder = (remainder * 10 + parseInt(digit)) % 97;\n }\n\n const calculated = 98 - remainder;\n return calculated === checkDigits;\n },\n placeholder: '[LEI_{n}]',\n description: 'Legal Entity Identifier',\n severity: 'medium'\n }\n];\n","/**\n * Government ID patterns (passports, SSN, national IDs, etc.)\n */\n\nimport { PIIPattern } from '../types';\nimport {\n validateSSN,\n validateNINO,\n validateNHS,\n validateUKPassport\n} from '../validators';\n\nexport const governmentPatterns: PIIPattern[] = [\n {\n type: 'SSN',\n regex: /\\b(?:SSN|social security)[:\\s#]*(\\d{3}[-\\s]?\\d{2}[-\\s]?\\d{4})\\b/gi,\n priority: 100,\n validator: (match) => validateSSN(match),\n placeholder: '[SSN_{n}]',\n description: 'US Social Security Number',\n severity: 'high'\n },\n {\n type: 'PASSPORT_UK',\n regex: /\\b(?:passport|pass)[:\\s#]*([0-9]{9})\\b/gi,\n priority: 95,\n validator: (match) => validateUKPassport(match),\n placeholder: '[PASSPORT_{n}]',\n description: 'UK Passport number',\n severity: 'high'\n },\n {\n type: 'PASSPORT_US',\n regex: /\\b(?:passport|pass)[:\\s#]*([A-Z0-9]{6,9})\\b/gi,\n priority: 95,\n placeholder: '[PASSPORT_{n}]',\n description: 'US Passport number',\n severity: 'high'\n },\n {\n type: 'NATIONAL_INSURANCE_UK',\n regex: /\\b(?:NI|NINO|national insurance)[:\\s#]*([A-CEGHJ-PR-TW-Z]{2}\\s?\\d{2}\\s?\\d{2}\\s?\\d{2}\\s?[A-D])\\b/gi,\n priority: 100,\n validator: (match) => validateNINO(match),\n placeholder: '[NINO_{n}]',\n description: 'UK National Insurance Number',\n severity: 'high'\n },\n {\n type: 'NHS_NUMBER',\n regex: /\\b(?:NHS|nhs number)[:\\s#]*(\\d{3}[\\s-]?\\d{3}[\\s-]?\\d{4})\\b/gi,\n priority: 95,\n validator: (match) => validateNHS(match),\n placeholder: '[NHS_{n}]',\n description: 'UK NHS Number',\n severity: 'high'\n },\n {\n type: 'DRIVING_LICENSE_UK',\n regex: /\\b([A-Z]{5}\\d{6}[A-Z]{2}\\d[A-Z]{2})\\b/g,\n priority: 90,\n placeholder: '[DRIVING_LICENSE_{n}]',\n description: 'UK Driving License',\n severity: 'high'\n },\n {\n type: 'DRIVING_LICENSE_US',\n regex: /\\b(?:DL|driver(?:'s)?\\slicense)[:\\s#]*([A-Z0-9]{5,20})\\b/gi,\n priority: 90,\n placeholder: '[DRIVING_LICENSE_{n}]',\n description: 'US Driving License',\n severity: 'high'\n },\n {\n type: 'TAX_ID',\n regex: /\\b(?:TIN|tax id|EIN)[:\\s#]*(\\d{2}[-\\s]?\\d{7})\\b/gi,\n priority: 95,\n placeholder: '[TAX_ID_{n}]',\n description: 'Tax identification number',\n severity: 'high'\n },\n {\n type: 'PASSPORT_MRZ_TD3',\n regex: /P<[A-Z]{3}[A-Z<]{39}\\n[A-Z0-9<]{9}[0-9][A-Z]{3}[0-9]{6}[0-9][MF<][0-9]{6}[0-9][A-Z0-9<]{14}[0-9]/g,\n priority: 98,\n placeholder: '[PASSPORT_MRZ_{n}]',\n description: 'Passport Machine Readable Zone (TD3 - 2 lines x 44 chars)',\n severity: 'high'\n },\n {\n type: 'PASSPORT_MRZ_TD1',\n regex: /[A-Z]{1}[A-Z<][A-Z]{3}[A-Z0-9<]{9}[0-9][A-Z0-9<]{15}\\n[0-9]{6}[0-9][MF<][0-9]{6}[0-9][A-Z]{3}[A-Z0-9<]{11}[0-9]\\n[A-Z<]{30}/g,\n priority: 98,\n placeholder: '[ID_MRZ_{n}]',\n description: 'ID Card Machine Readable Zone (TD1 - 3 lines x 30 chars)',\n severity: 'high'\n },\n {\n type: 'VISA_MRZ',\n regex: /V<[A-Z]{3}[A-Z<]{39}\\n[A-Z0-9<]{9}[0-9][A-Z]{3}[0-9]{6}[0-9][MF<][0-9]{6}[0-9][A-Z0-9<]{14}[0-9]/g,\n priority: 98,\n placeholder: '[VISA_MRZ_{n}]',\n description: 'Visa Machine Readable Zone',\n severity: 'high'\n },\n {\n type: 'TRAVEL_DOCUMENT_NUMBER',\n regex: /\\b(?:TRAVEL\\s+DOC(?:UMENT)?|TD)[:\\s#]*([A-Z0-9]{6,15})\\b/gi,\n priority: 92,\n placeholder: '[TRAVEL_DOC_{n}]',\n description: 'Travel document numbers',\n severity: 'high',\n validator: (_value: string, context: string) => {\n return /travel|document|visa|passport|border|immigration/i.test(context);\n }\n },\n {\n type: 'VISA_NUMBER',\n regex: /\\b(?:VISA)[:\\s#]*([A-Z0-9]{8,12})\\b/gi,\n priority: 92,\n placeholder: '[VISA_{n}]',\n description: 'Visa numbers',\n severity: 'high',\n validator: (_value: string, context: string) => {\n return /visa|travel|entry|immigration|consulate|embassy/i.test(context);\n }\n },\n {\n type: 'IMMIGRATION_NUMBER',\n regex: /\\b(?:IMMIGRATION|ALIEN|A-NUMBER|A#)[:\\s#]*([A-Z]?\\d{8,10})\\b/gi,\n priority: 92,\n placeholder: '[IMMIGRATION_{n}]',\n description: 'Immigration and alien registration numbers',\n severity: 'high'\n },\n {\n type: 'BORDER_CROSSING_CARD',\n regex: /\\b(?:BCC|BORDER\\s+CROSSING)[:\\s#]*([A-Z0-9]{10,15})\\b/gi,\n priority: 90,\n placeholder: '[BCC_{n}]',\n description: 'Border crossing card numbers',\n severity: 'high',\n validator: (_value: string, context: string) => {\n return /border|crossing|card|entry|bcc/i.test(context);\n }\n },\n {\n type: 'UTR_UK',\n regex: /\\b(?:UTR|unique taxpayer reference)[:\\s#]*(\\d{10})\\b/gi,\n priority: 95,\n validator: (match) => {\n // UK UTR: 10 digits, typically issued in sequence\n const digits = match.replace(/\\D/g, '');\n return digits.length === 10 && /^\\d{10}$/.test(digits);\n },\n placeholder: '[UTR_{n}]',\n description: 'UK Unique Taxpayer Reference',\n severity: 'high'\n },\n {\n type: 'VAT_NUMBER',\n regex: /\\b(?:VAT|vat number)[:\\s#]*([A-Z]{2}\\s?\\d{9,12})\\b/gi,\n priority: 90,\n validator: (match) => {\n // VAT format varies by country (GB: 9 digits, DE: 9 digits, FR: 11 chars, etc.)\n const cleaned = match.replace(/\\s/g, '');\n\n // Check for valid country codes\n const countryCode = cleaned.substring(0, 2).toUpperCase();\n const validCountries = ['GB', 'DE', 'FR', 'IT', 'ES', 'NL', 'BE', 'AT', 'PL', 'SE', 'DK', 'FI', 'IE', 'PT', 'CZ', 'HU', 'RO', 'BG', 'GR', 'HR', 'SK', 'SI', 'LT', 'LV', 'EE', 'CY', 'LU', 'MT'];\n\n if (!validCountries.includes(countryCode)) {\n return false;\n }\n\n const number = cleaned.substring(2);\n\n // Country-specific validation\n if (countryCode === 'GB') {\n // UK: 9 or 12 digits\n return /^\\d{9}(\\d{3})?$/.test(number);\n } else if (countryCode === 'DE') {\n // Germany: 9 digits\n return /^\\d{9}$/.test(number);\n } else if (countryCode === 'FR') {\n // France: 11 characters (2 letters/digits + 9 digits)\n return /^[A-Z0-9]{2}\\d{9}$/.test(number);\n }\n\n // Generic validation: must have digits\n return /\\d{7,12}/.test(number);\n },\n placeholder: '[VAT_{n}]',\n description: 'VAT registration number',\n severity: 'medium'\n },\n {\n type: 'COMPANY_NUMBER_UK',\n regex: /\\b(?:company number|reg(?:\\.|istration)?\\s+no(?:\\.)?)[:\\s#]*([A-Z]{2}\\d{6}|\\d{8})\\b/gi,\n priority: 85,\n validator: (match) => {\n // UK company number: 8 digits or 2 letters + 6 digits\n const cleaned = match.replace(/\\s/g, '');\n return /^(\\d{8}|[A-Z]{2}\\d{6})$/.test(cleaned);\n },\n placeholder: '[COMPANY_NUMBER_{n}]',\n description: 'UK Company registration number',\n severity: 'low'\n },\n {\n type: 'ITIN',\n regex: /\\b(?:ITIN|individual taxpayer)[:\\s#]*(9\\d{2}[-\\s]?[7-8]\\d[-\\s]?\\d{4})\\b/gi,\n priority: 100,\n validator: (match) => {\n // ITIN: 9XX-7X-XXXX or 9XX-8X-XXXX format\n const digits = match.replace(/\\D/g, '');\n\n if (digits.length !== 9) return false;\n\n // Must start with 9\n if (digits[0] !== '9') return false;\n\n // Fourth and fifth digits must be 7 or 8\n const fourthDigit = parseInt(digits[3]);\n if (fourthDigit !== 7 && fourthDigit !== 8) return false;\n\n // Cannot be all same digit\n if (/^(\\d)\\1{8}$/.test(digits)) return false;\n\n return true;\n },\n placeholder: '[ITIN_{n}]',\n description: 'US Individual Taxpayer Identification Number',\n severity: 'high'\n },\n {\n type: 'SIN_CA',\n regex: /\\b(?:SIN|social insurance)[:\\s#]*(\\d{3}[-\\s]?\\d{3}[-\\s]?\\d{3})\\b/gi,\n priority: 100,\n validator: (match) => {\n // Canadian SIN: 9 digits using Luhn algorithm\n const digits = match.replace(/\\D/g, '');\n\n if (digits.length !== 9) return false;\n\n // Luhn check (mod-10 algorithm)\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n let digit = parseInt(digits[i]);\n\n // Double every second digit\n if (i % 2 === 1) {\n digit *= 2;\n if (digit > 9) {\n digit -= 9;\n }\n }\n\n sum += digit;\n }\n\n return sum % 10 === 0;\n },\n placeholder: '[SIN_{n}]',\n description: 'Canadian Social Insurance Number',\n severity: 'high'\n }\n];\n","/**\n * Contact information patterns (phones, addresses, etc.)\n */\n\nimport { PIIPattern } from '../types';\n\nexport const contactPatterns: PIIPattern[] = [\n {\n type: 'PHONE_UK_MOBILE',\n regex: /\\b07\\d{3}[\\s-]?\\d{3}[\\s-]?\\d{3}\\b/g,\n priority: 90,\n placeholder: '[PHONE_UK_MOBILE_{n}]',\n description: 'UK mobile phone',\n severity: 'medium'\n },\n {\n type: 'PHONE_UK',\n regex: /\\b(?:0[1-9]\\d{1,2}[\\s-]?\\d{3,4}[\\s-]?\\d{4}|\\+44[\\s-]?[1-9]\\d{1,2}[\\s-]?\\d{3,4}[\\s-]?\\d{4})\\b/g,\n priority: 85,\n placeholder: '[PHONE_UK_{n}]',\n description: 'UK phone number',\n severity: 'medium'\n },\n {\n type: 'PHONE_US',\n regex: /(?<=^|[^\\d])(?:\\+1[\\s-]?)?(?:\\(\\d{3}\\)\\s?|\\d{3}[\\s-]?)\\d{3}[\\s-]?\\d{4}(?=[^\\d]|$)/g,\n priority: 85,\n placeholder: '[PHONE_US_{n}]',\n description: 'US phone number',\n severity: 'medium'\n },\n {\n type: 'PHONE_INTERNATIONAL',\n regex: /\\b\\+\\d{1,3}[\\s-]?\\d{1,4}[\\s-]?\\d{1,4}[\\s-]?\\d{1,9}\\b/g,\n priority: 80,\n placeholder: '[PHONE_{n}]',\n description: 'International phone number',\n severity: 'medium'\n },\n {\n type: 'POSTCODE_UK',\n regex: /\\b([A-Z]{1,2}\\d{1,2}[A-Z]?\\s?\\d[A-Z]{2})\\b/g,\n priority: 75,\n placeholder: '[POSTCODE_{n}]',\n description: 'UK postcode',\n severity: 'low'\n },\n {\n type: 'ZIP_CODE_US',\n regex: /\\b(\\d{5}(?:-\\d{4})?)\\b/g,\n priority: 70,\n placeholder: '[ZIP_{n}]',\n description: 'US ZIP code',\n severity: 'low'\n },\n {\n type: 'ADDRESS_STREET',\n regex: /\\b(\\d{1,5}\\s[A-Z][a-z]+(?:\\s[A-Z][a-z]+){0,3}\\s(?:Street|St|Road|Rd|Avenue|Ave|Lane|Ln|Drive|Dr|Court|Ct|Boulevard|Blvd))\\b/g,\n priority: 70,\n placeholder: '[ADDRESS_{n}]',\n description: 'Street address',\n severity: 'medium'\n },\n {\n type: 'ADDRESS_PO_BOX',\n regex: /\\b(P\\.?O\\.?\\s?Box\\s\\d+)\\b/gi,\n priority: 75,\n placeholder: '[PO_BOX_{n}]',\n description: 'PO Box address',\n severity: 'medium'\n }\n];\n","/**\n * Network-related PII patterns (IP addresses, MAC addresses, etc.)\n */\n\nimport { PIIPattern } from '../types';\n\nexport const networkPatterns: PIIPattern[] = [\n {\n type: 'IPV4',\n regex: /\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b/g,\n priority: 80,\n validator: (match) => {\n // Exclude common non-PII IPs\n const excluded = ['0.0.0.0', '127.0.0.1', '255.255.255.255'];\n return !excluded.includes(match) && !match.startsWith('192.168.') && !match.startsWith('10.');\n },\n placeholder: '[IPV4_{n}]',\n description: 'IPv4 address',\n severity: 'medium'\n },\n {\n type: 'IPV6',\n regex: /\\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\b/g,\n priority: 80,\n validator: (match) => {\n // Exclude localhost\n return match !== '::1' && !match.startsWith('fe80:');\n },\n placeholder: '[IPV6_{n}]',\n description: 'IPv6 address',\n severity: 'medium'\n },\n {\n type: 'MAC_ADDRESS',\n regex: /\\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\\b/g,\n priority: 75,\n placeholder: '[MAC_{n}]',\n description: 'MAC address',\n severity: 'low'\n },\n {\n type: 'URL_WITH_AUTH',\n regex: /\\b(?:https?|ftp):\\/\\/[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+@[^\\s]+\\b/g,\n priority: 95,\n placeholder: '[URL_AUTH_{n}]',\n description: 'URL with credentials',\n severity: 'high'\n },\n {\n type: 'IOT_SERIAL_NUMBER',\n regex: /\\bSN:([A-Z0-9]{12})\\b/gi,\n priority: 80,\n placeholder: '[IOT_SERIAL_{n}]',\n description: 'IoT device serial numbers',\n severity: 'medium'\n },\n {\n type: 'DEVICE_UUID',\n regex: /\\b([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\b/gi,\n priority: 75,\n placeholder: '[DEVICE_UUID_{n}]',\n description: 'Device UUID identifiers',\n severity: 'medium',\n validator: (_match: string, context: string) => {\n return /device|uuid|identifier|hardware|iot|sensor/i.test(context);\n }\n }\n];\n","/**\n * Extended Cryptocurrency Address Patterns\n * Additional Layer-1 blockchain addresses beyond BTC, ETH, LTC\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Solana (SOL) Address\n * Format: Base58, 32-44 characters\n * Starts with 1-9 or A-H\n */\nexport const SOLANA_ADDRESS: PIIPattern = {\n type: 'SOLANA_ADDRESS',\n regex: /\\b([1-9A-HJ-NP-Za-km-z]{32,44})\\b/g,\n placeholder: '[SOL_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Solana (SOL) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Length validation\n if (value.length < 32 || value.length > 44) return false;\n\n // Must have crypto/Solana context\n if (!/solana|sol|crypto|wallet|blockchain|address/i.test(context)) {\n return false;\n }\n\n // Exclude other crypto formats\n if (/^(bc1|1|3|0x|L|M|D|X|r|cosmos|tz|addr)/.test(value)) {\n return false;\n }\n\n return true;\n }\n};\n\n/**\n * Polkadot (DOT) Address\n * Format: SS58 format, starts with 1\n * 47-48 characters\n */\nexport const POLKADOT_ADDRESS: PIIPattern = {\n type: 'POLKADOT_ADDRESS',\n regex: /\\b(1[1-9A-HJ-NP-Za-km-z]{46,47})\\b/g,\n placeholder: '[DOT_ADDR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Polkadot (DOT) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Length validation\n if (value.length < 47 || value.length > 48) return false;\n\n // Must start with 1\n if (!value.startsWith('1')) return false;\n\n // Must have crypto/Polkadot context\n return /polkadot|dot|crypto|wallet|blockchain|substrate|address/i.test(context);\n }\n};\n\n/**\n * Avalanche (AVAX) Address\n * Format: 43 characters, prefixed with X-, P-, or C-\n * Example: X-avax1... or P-avax1... or C-0x...\n */\nexport const AVALANCHE_ADDRESS: PIIPattern = {\n type: 'AVALANCHE_ADDRESS',\n regex: /\\b([XPC]-(?:avax)?[a-z0-9]{38,43})\\b/gi,\n placeholder: '[AVAX_ADDR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Avalanche (AVAX) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Must start with X-, P-, or C-\n if (!/^[XPC]-/.test(value)) return false;\n\n // Length validation (with prefix)\n if (value.length < 40 || value.length > 46) return false;\n\n // Must have crypto/Avalanche context\n return /avalanche|avax|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n/**\n * Cosmos (ATOM) Address\n * Format: Bech32 format, starts with \"cosmos1\"\n * 39-45 characters total\n */\nexport const COSMOS_ADDRESS: PIIPattern = {\n type: 'COSMOS_ADDRESS',\n regex: /\\b(cosmos1[a-z0-9]{38,44})\\b/g,\n placeholder: '[ATOM_ADDR_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Cosmos (ATOM) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Must start with cosmos1\n if (!value.startsWith('cosmos1')) return false;\n\n // Length validation\n if (value.length < 39 || value.length > 45) return false;\n\n // Must have crypto/Cosmos context\n return /cosmos|atom|crypto|wallet|blockchain|ibc|address/i.test(context);\n }\n};\n\n/**\n * Algorand (ALGO) Address\n * Format: Base32, 58 characters\n * Uppercase letters and numbers\n */\nexport const ALGORAND_ADDRESS: PIIPattern = {\n type: 'ALGORAND_ADDRESS',\n regex: /\\b([A-Z2-7]{58})\\b/g,\n placeholder: '[ALGO_ADDR_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Algorand (ALGO) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Must be exactly 58 characters\n if (value.length !== 58) return false;\n\n // Must be all uppercase Base32 (A-Z, 2-7)\n if (!/^[A-Z2-7]+$/.test(value)) return false;\n\n // Must have crypto/Algorand context\n return /algorand|algo|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n/**\n * Tezos (XTZ) Address\n * Format: Base58check, starts with \"tz\"\n * 36 characters total (tz1/tz2/tz3 + 33 chars)\n */\nexport const TEZOS_ADDRESS: PIIPattern = {\n type: 'TEZOS_ADDRESS',\n regex: /\\b(tz[123][1-9A-HJ-NP-Za-km-z]{33})\\b/g,\n placeholder: '[XTZ_ADDR_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Tezos (XTZ) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Must start with tz1, tz2, or tz3\n if (!/^tz[123]/.test(value)) return false;\n\n // Must be exactly 36 characters\n if (value.length !== 36) return false;\n\n // Must have crypto/Tezos context\n return /tezos|xtz|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n/**\n * Polygon (MATIC) Address\n * Format: Ethereum-compatible (0x + 40 hex chars)\n * Note: Same format as Ethereum, requires Polygon context\n */\nexport const POLYGON_ADDRESS: PIIPattern = {\n type: 'POLYGON_ADDRESS',\n regex: /\\b(0x[a-fA-F0-9]{40})\\b/g,\n placeholder: '[MATIC_ADDR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Polygon (MATIC) cryptocurrency address',\n validator: (value: string, context: string) => {\n // Must start with 0x and be 42 chars total\n if (!value.startsWith('0x') || value.length !== 42) return false;\n\n // MUST have Polygon/MATIC context to differentiate from ETH\n return /polygon|matic|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n/**\n * Binance Smart Chain (BNB) Address\n * Format: Ethereum-compatible (0x + 40 hex chars)\n * Note: Same format as Ethereum, requires BSC context\n */\nexport const BINANCE_CHAIN_ADDRESS: PIIPattern = {\n type: 'BINANCE_CHAIN_ADDRESS',\n regex: /\\b(0x[a-fA-F0-9]{40})\\b/g,\n placeholder: '[BNB_ADDR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Binance Smart Chain (BNB) address',\n validator: (value: string, context: string) => {\n // Must start with 0x and be 42 chars total\n if (!value.startsWith('0x') || value.length !== 42) return false;\n\n // MUST have Binance/BNB/BSC context to differentiate from ETH\n return /binance|bnb|bsc|smart[- ]?chain|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n/**\n * Near Protocol (NEAR) Address\n * Format: account.near (human-readable) or hex (64 chars)\n * Example: user.near or abc123...\n */\nexport const NEAR_ADDRESS: PIIPattern = {\n type: 'NEAR_ADDRESS',\n regex: /\\b([a-z0-9_-]{2,64}\\.near)\\b/gi,\n placeholder: '[NEAR_ADDR_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Near Protocol (NEAR) address',\n validator: (value: string, context: string) => {\n // Must end with .near\n if (!value.toLowerCase().endsWith('.near')) return false;\n\n // Must have crypto/Near context\n return /near|protocol|crypto|wallet|blockchain|address/i.test(context);\n }\n};\n\n// Export all extended crypto patterns\nexport const cryptoExtendedPatterns: PIIPattern[] = [\n SOLANA_ADDRESS,\n POLKADOT_ADDRESS,\n AVALANCHE_ADDRESS,\n COSMOS_ADDRESS,\n ALGORAND_ADDRESS,\n TEZOS_ADDRESS,\n POLYGON_ADDRESS,\n BINANCE_CHAIN_ADDRESS,\n NEAR_ADDRESS\n];\n","/**\n * Healthcare and Medical PII Patterns\n * For HIPAA compliance and medical data protection\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Medical Record Number (MRN) - Various hospital formats\n */\nexport const MEDICAL_RECORD_NUMBER: PIIPattern = {\n type: 'MEDICAL_RECORD_NUMBER',\n regex: /\\b(?:MR[N]?[-\\s]?|MEDICAL[-\\s]?REC(?:ORD)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*)([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[MRN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Medical Record Numbers in various hospital formats'\n};\n\n/**\n * Patient ID - Generic patient identifier\n */\nexport const PATIENT_ID: PIIPattern = {\n type: 'PATIENT_ID',\n regex: /\\b(?:PATIENT[-\\s]?(?:ID|NUM(?:BER)?|REF(?:ERENCE)?)[-\\s]?[:#]?\\s*)([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PATIENT_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Patient identification numbers'\n};\n\n/**\n * Appointment Reference Numbers\n */\nexport const APPOINTMENT_REF: PIIPattern = {\n type: 'APPOINTMENT_REF',\n regex: /\\b(?:APT|APPT|APPOINTMENT)[-\\s]?(?:REF|ID|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,10})\\b/gi,\n placeholder: '[APT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Medical appointment reference numbers'\n};\n\n/**\n * ICD-10 Diagnosis Codes\n * Format: Letter + 2 digits, optionally followed by decimal and 1-2 more digits\n */\nexport const ICD10_CODE: PIIPattern = {\n type: 'ICD10_CODE',\n regex: /\\b([A-Z]\\d{2}(?:\\.\\d{1,2})?)\\b/g,\n placeholder: '[ICD10_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'ICD-10 diagnosis codes',\n validator: (value: string, context: string) => {\n // Only flag if in medical context\n const medicalContext = /diagnos|condition|disease|disorder|icd|code/i.test(context);\n // First char must be letter, not digit\n const validFormat = /^[A-TV-Z]/.test(value); // Excludes U (unused) except for special cases\n return medicalContext && validFormat;\n }\n};\n\n/**\n * CPT Procedure Codes\n * 5-digit codes (Category I: 00100-99499)\n */\nexport const CPT_CODE: PIIPattern = {\n type: 'CPT_CODE',\n regex: /\\b(?:CPT[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*)?([0-9]{5})\\b/g,\n placeholder: '[CPT_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'CPT medical procedure codes',\n validator: (value: string, context: string) => {\n const code = parseInt(value);\n // Valid CPT range\n const validRange = (code >= 100 && code <= 99499);\n // Only flag in medical context\n const medicalContext = /procedure|cpt|billing|treatment|service/i.test(context);\n return validRange && medicalContext;\n }\n};\n\n/**\n * Prescription/RX Numbers\n */\nexport const PRESCRIPTION_NUMBER: PIIPattern = {\n type: 'PRESCRIPTION_NUMBER',\n regex: /\\b(?:RX|PRESC(?:RIPTION)?|SCRIPT)[-\\s]?(?:NO|NUM(?:BER)?|REF|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RX_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Prescription reference numbers'\n};\n\n/**\n * Health Insurance Claim Numbers\n */\nexport const HEALTH_INSURANCE_CLAIM: PIIPattern = {\n type: 'HEALTH_INSURANCE_CLAIM',\n regex: /\\b(?:CLAIM|CLM)[-\\s]?(?:NO|NUM(?:BER)?|REF|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[CLAIM_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Health insurance claim numbers',\n validator: (_value: string, context: string) => {\n // Only in insurance/medical context\n return /insurance|claim|medical|health|policy/i.test(context);\n }\n};\n\n/**\n * Health Plan Beneficiary Numbers\n */\nexport const HEALTH_PLAN_NUMBER: PIIPattern = {\n type: 'HEALTH_PLAN_NUMBER',\n regex: /\\b(?:HEALTH[-\\s]?PLAN|BENEFICIARY|MEMBER)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,15})\\b/gi,\n placeholder: '[HEALTH_PLAN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Health plan beneficiary/member numbers'\n};\n\n/**\n * Medical Device Serial Numbers\n */\nexport const MEDICAL_DEVICE_SERIAL: PIIPattern = {\n type: 'MEDICAL_DEVICE_SERIAL',\n regex: /\\b(?:DEVICE|IMPLANT|PACEMAKER|DEFIBRILLATOR)[-\\s]?(?:SERIAL|SN|S\\/N)[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[DEVICE_{n}]',\n priority: 75,\n severity: 'high',\n description: 'Medical device serial numbers'\n};\n\n/**\n * Lab Result/Test IDs\n */\nexport const LAB_TEST_ID: PIIPattern = {\n type: 'LAB_TEST_ID',\n regex: /\\b(?:LAB|TEST|SAMPLE)[-\\s]?(?:ID|NUM(?:BER)?|REF)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[LAB_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Laboratory test and sample IDs',\n validator: (_value: string, context: string) => {\n return /lab|test|sample|specimen|pathology/i.test(context);\n }\n};\n\n/**\n * Clinical Trial Participant IDs\n */\nexport const TRIAL_PARTICIPANT_ID: PIIPattern = {\n type: 'TRIAL_PARTICIPANT_ID',\n regex: /\\b(?:PARTICIPANT|SUBJECT|TRIAL)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{1,2}[-]?\\d{4,6})\\b/gi,\n placeholder: '[TRIAL_PART_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Clinical trial participant identifiers'\n};\n\n/**\n * Protocol Numbers (Clinical Trials)\n */\nexport const PROTOCOL_NUMBER: PIIPattern = {\n type: 'PROTOCOL_NUMBER',\n regex: /\\b(?:PROTOCOL|STUDY)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[PROTOCOL_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Clinical trial protocol numbers',\n validator: (_value: string, context: string) => {\n return /trial|study|protocol|research|clinical/i.test(context);\n }\n};\n\n/**\n * Genetic Markers (dbSNP rs numbers)\n */\nexport const GENETIC_MARKER: PIIPattern = {\n type: 'GENETIC_MARKER',\n regex: /\\b(rs\\d{6,10})\\b/gi,\n placeholder: '[SNP_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Genetic markers (dbSNP rs numbers)',\n validator: (_value: string, context: string) => {\n return /genetic|gene|snp|marker|genome|dna|variant|allele/i.test(context);\n }\n};\n\n/**\n * Biobank Sample IDs\n */\nexport const BIOBANK_SAMPLE_ID: PIIPattern = {\n type: 'BIOBANK_SAMPLE_ID',\n regex: /\\b(?:BIOBANK|SAMPLE|SPECIMEN)[-\\s]?(?:ID|NO)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,15})\\b/gi,\n placeholder: '[BIOBANK_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Biobank sample identifiers',\n validator: (_value: string, context: string) => {\n return /biobank|specimen|sample|tissue|blood|genetic/i.test(context);\n }\n};\n\n/**\n * Healthcare Provider License Numbers\n */\nexport const PROVIDER_LICENSE: PIIPattern = {\n type: 'PROVIDER_LICENSE',\n regex: /\\b(?:MEDICAL|PHYSICIAN|DOCTOR|NURSE|PROVIDER)[-\\s]?(?:LICENSE|LICENCE|LIC)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PROVIDER_LIC_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Healthcare provider license numbers'\n};\n\n/**\n * NPI (National Provider Identifier) - US\n * 10-digit number with checksum\n */\nexport const NPI_NUMBER: PIIPattern = {\n type: 'NPI_NUMBER',\n regex: /\\b(?:NPI[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*)?(\\d{10})\\b/g,\n placeholder: '[NPI_{n}]',\n priority: 85,\n severity: 'high',\n description: 'US National Provider Identifier',\n validator: (value: string, context: string) => {\n // Must be in healthcare context\n if (!/provider|npi|physician|doctor|clinic|hospital|practice/i.test(context)) {\n return false;\n }\n\n // Luhn checksum validation\n const digits = value.split('').map(Number);\n let sum = 0;\n for (let i = digits.length - 2; i >= 0; i--) {\n let digit = digits[i];\n if ((digits.length - i) % 2 === 0) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n sum += digit;\n }\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === digits[digits.length - 1];\n }\n};\n\n/**\n * DEA Number (Drug Enforcement Administration) - US\n * Format: 2 letters + 7 digits with checksum\n */\nexport const DEA_NUMBER: PIIPattern = {\n type: 'DEA_NUMBER',\n regex: /\\b(?:DEA[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*)?([A-Z]{2}\\d{7})\\b/gi,\n placeholder: '[DEA_{n}]',\n priority: 90,\n severity: 'high',\n description: 'DEA registration number for controlled substances',\n validator: (value: string, _context: string) => {\n // Must start with valid registrant type\n const validFirstLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'P', 'R', 'S', 'T', 'U'];\n if (!validFirstLetters.includes(value[0].toUpperCase())) {\n return false;\n }\n\n // Checksum validation\n const digits = value.substring(2).split('').map(Number);\n const sum1 = digits[0] + digits[2] + digits[4];\n const sum2 = (digits[1] + digits[3] + digits[5]) * 2;\n const checkDigit = (sum1 + sum2) % 10;\n\n return checkDigit === digits[6];\n }\n};\n\n/**\n * Hospital Account Numbers\n */\nexport const HOSPITAL_ACCOUNT: PIIPattern = {\n type: 'HOSPITAL_ACCOUNT',\n regex: /\\b(?:HOSPITAL|H|HAR)[-\\s]?(?:ACCOUNT|ACCT|A\\/C)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[H_ACCT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Hospital account numbers'\n};\n\n/**\n * Emergency Contact Information Pattern\n * Detects when emergency contact details are mentioned\n */\nexport const EMERGENCY_CONTACT_MARKER: PIIPattern = {\n type: 'EMERGENCY_CONTACT',\n regex: /(?:emergency\\s+contact|next\\s+of\\s+kin|ice|in\\s+case\\s+of\\s+emergency)[:\\s]+([A-Z][a-z]+(?:\\s+[A-Z][a-z]+){1,3})/gi,\n placeholder: '[EMERGENCY_CONTACT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Emergency contact person names'\n};\n\n/**\n * Biometric Identifier References\n * Detects mentions of biometric data (fingerprints, retinal scans, etc.)\n */\nexport const BIOMETRIC_ID: PIIPattern = {\n type: 'BIOMETRIC_ID',\n regex: /\\b(?:FINGERPRINT|RETINAL?[-\\s]?SCAN|IRIS[-\\s]?SCAN|VOICE[-\\s]?PRINT|FACIAL[-\\s]?RECOGNITION|BIOMETRIC)[-\\s]?(?:ID|DATA|TEMPLATE|HASH)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,40})\\b/gi,\n placeholder: '[BIOMETRIC_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Biometric identifier references'\n};\n\n/**\n * DNA/Genetic Sequence Patterns\n * Short nucleotide sequences that might identify individuals\n */\nexport const DNA_SEQUENCE: PIIPattern = {\n type: 'DNA_SEQUENCE',\n regex: /\\b([ATCG]{20,})\\b/g,\n placeholder: '[DNA_{n}]',\n priority: 90,\n severity: 'high',\n description: 'DNA sequence patterns',\n validator: (value: string, context: string) => {\n // Must be in genetic context\n const geneticContext = /dna|genetic|sequence|genome|nucleotide|gene/i.test(context);\n // Must be long enough to be meaningful\n const longEnough = value.length >= 20;\n // Should be mostly ATCG (allow some ambiguity codes)\n const validChars = /^[ATCGRYSWKMBDHVN]+$/i.test(value);\n return geneticContext && longEnough && validChars;\n }\n};\n\n/**\n * Drug Names with Dosages\n * Common pattern: DrugName + dosage + unit\n */\nexport const DRUG_DOSAGE: PIIPattern = {\n type: 'DRUG_DOSAGE',\n regex: /\\b([A-Z][a-z]+(?:ine|ol|azole|mycin|cillin|pril|olol|mab|pam|tab|pine|done|ide|tide|ase|statin))\\s+(\\d+(?:\\.\\d+)?)\\s?(mg|mcg|g|ml|units?|IU)\\b/gi,\n placeholder: '[DRUG_DOSAGE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Drug names with dosages',\n validator: (_value: string, context: string) => {\n return /medication|prescription|drug|dose|treatment|therapy/i.test(context);\n }\n};\n\n/**\n * Medical Image References\n * References to medical imaging files (X-rays, MRIs, etc.)\n */\nexport const MEDICAL_IMAGE_REF: PIIPattern = {\n type: 'MEDICAL_IMAGE_REF',\n regex: /\\b(?:X[-\\s]?RAY|MRI|CT[-\\s]?SCAN|PET[-\\s]?SCAN|ULTRASOUND|MAMMOGRAM)[-\\s]?(?:IMAGE|FILE|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[IMAGE_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Medical imaging file references'\n};\n\n/**\n * Blood Type with Patient Context\n */\nexport const BLOOD_TYPE_PATIENT: PIIPattern = {\n type: 'BLOOD_TYPE',\n regex: /\\b(?:blood\\s+type|blood\\s+group)[:\\s]+(A|B|AB|O)[+-]?\\b/gi,\n placeholder: '[BLOOD_TYPE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Patient blood type information'\n};\n\n/**\n * Allergy Information Pattern\n */\nexport const ALLERGY_INFO: PIIPattern = {\n type: 'ALLERGY_INFO',\n regex: /\\b(?:allergic\\s+to|allergy)[:\\s]+([A-Za-z\\s,]+(?:penicillin|peanuts|latex|aspirin|shellfish|eggs|dairy|soy|wheat))/gi,\n placeholder: '[ALLERGY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Patient allergy information'\n};\n\n/**\n * Vaccination Record IDs\n */\nexport const VACCINATION_ID: PIIPattern = {\n type: 'VACCINATION_ID',\n regex: /\\b(?:VACCINE|VACCINATION|IMMUNIZATION)[-\\s]?(?:ID|RECORD|NO)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[VAX_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Vaccination record identifiers',\n validator: (_value: string, context: string) => {\n return /vaccine|vaccination|immunization|shot|dose/i.test(context);\n }\n};\n\n/**\n * CHI (Community Health Index) Number - Scotland\n * Format: DDMMYY-XXXX (10 digits with hyphen)\n */\nexport const CHI_NUMBER: PIIPattern = {\n type: 'CHI_NUMBER',\n regex: /\\b(?:CHI|community health index)[-\\s]?(?:number|no)?[-\\s]?[:#]?\\s*(\\d{6}[-\\s]?\\d{4})\\b/gi,\n placeholder: '[CHI_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Scottish Community Health Index number',\n validator: (match) => {\n const digits = match.replace(/\\D/g, '');\n\n if (digits.length !== 10) return false;\n\n // First 6 digits should be a valid date (DDMMYY)\n const day = parseInt(digits.substring(0, 2));\n const month = parseInt(digits.substring(2, 4));\n // Year is parsed but not validated (format is DDMMYY)\n\n // Basic date validation\n if (day < 1 || day > 31) return false;\n if (month < 1 || month > 12) return false;\n\n // Check digit validation (simple mod-11)\n let sum = 0;\n const weights = [10, 9, 8, 7, 6, 5, 4, 3, 2];\n\n for (let i = 0; i < 9; i++) {\n sum += parseInt(digits[i]) * weights[i];\n }\n\n const checkDigit = 11 - (sum % 11);\n const expectedCheckDigit = checkDigit === 11 ? 0 : checkDigit === 10 ? 0 : checkDigit;\n\n return expectedCheckDigit === parseInt(digits[9]);\n }\n};\n\n/**\n * EHIC (European Health Insurance Card)\n * Format: Country code + 12-16 digits\n */\nexport const EHIC_NUMBER: PIIPattern = {\n type: 'EHIC_NUMBER',\n regex: /\\b(?:EHIC|european health insurance|health card)[-\\s]?(?:number|no)?[-\\s]?[:#]?\\s*([A-Z]{2}\\s?\\d{12,16})\\b/gi,\n placeholder: '[EHIC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'European Health Insurance Card number',\n validator: (match) => {\n // Remove spaces and extract parts\n const cleaned = match.replace(/\\s/g, '');\n\n // Must start with valid EU country code\n const countryCode = cleaned.substring(0, 2).toUpperCase();\n const validCountries = [\n 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',\n 'DE', 'GR', 'HU', 'IS', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU',\n 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB'\n ];\n\n if (!validCountries.includes(countryCode)) {\n return false;\n }\n\n // Remaining part should be 12-16 digits\n const number = cleaned.substring(2);\n return /^\\d{12,16}$/.test(number);\n }\n};\n\n// Export all healthcare patterns\nexport const healthcarePatterns: PIIPattern[] = [\n MEDICAL_RECORD_NUMBER,\n PATIENT_ID,\n APPOINTMENT_REF,\n ICD10_CODE,\n CPT_CODE,\n PRESCRIPTION_NUMBER,\n HEALTH_INSURANCE_CLAIM,\n HEALTH_PLAN_NUMBER,\n MEDICAL_DEVICE_SERIAL,\n LAB_TEST_ID,\n TRIAL_PARTICIPANT_ID,\n PROTOCOL_NUMBER,\n GENETIC_MARKER,\n BIOBANK_SAMPLE_ID,\n PROVIDER_LICENSE,\n NPI_NUMBER,\n DEA_NUMBER,\n HOSPITAL_ACCOUNT,\n EMERGENCY_CONTACT_MARKER,\n BIOMETRIC_ID,\n DNA_SEQUENCE,\n DRUG_DOSAGE,\n MEDICAL_IMAGE_REF,\n BLOOD_TYPE_PATIENT,\n ALLERGY_INFO,\n VACCINATION_ID,\n CHI_NUMBER,\n EHIC_NUMBER\n];\n","/**\n * Financial Services and Banking PII Patterns\n * For financial data protection and compliance\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * SWIFT/BIC Codes\n * Format: 4 letters (bank) + 2 letters (country) + 2 chars (location) + optional 3 chars (branch)\n */\nexport const SWIFT_BIC: PIIPattern = {\n type: 'SWIFT_BIC',\n regex: /\\b([A-Z]{6}[A-Z0-9]{2}(?:[A-Z0-9]{3})?)\\b/g,\n placeholder: '[SWIFT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'SWIFT/BIC codes for international transfers',\n validator: (value: string, context: string) => {\n // Must be in financial context\n const financialContext = /swift|bic|bank|transfer|wire|international|payment/i.test(context);\n // Validate format\n const validLength = value.length === 8 || value.length === 11;\n return financialContext && validLength;\n }\n};\n\n/**\n * Transaction IDs - Various formats\n */\nexport const TRANSACTION_ID: PIIPattern = {\n type: 'TRANSACTION_ID',\n regex: /\\b(?:TXN|TX|TRANS(?:ACTION)?)[-\\s]?(?:ID|NO|NUM(?:BER)?|REF)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[TXN_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Financial transaction identifiers'\n};\n\n/**\n * Investment Account Numbers\n */\nexport const INVESTMENT_ACCOUNT: PIIPattern = {\n type: 'INVESTMENT_ACCOUNT',\n regex: /\\b(?:ISA|SIPP|INV(?:ESTMENT)?|PENSION|401K|IRA)[-\\s]?(?:ACCOUNT|ACCT|A\\/C)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[INV_ACCT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Investment and pension account numbers'\n};\n\n/**\n * Wire Transfer References\n */\nexport const WIRE_TRANSFER_REF: PIIPattern = {\n type: 'WIRE_TRANSFER_REF',\n regex: /\\b(?:WIRE|TRANSFER|REMITTANCE)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[WIRE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Wire transfer reference numbers'\n};\n\n/**\n * Direct Debit Mandate Numbers (UK)\n */\nexport const DD_MANDATE: PIIPattern = {\n type: 'DD_MANDATE',\n regex: /\\b(?:DD|DIRECT[-\\s]?DEBIT)[-\\s]?(?:MANDATE|REF(?:ERENCE)?|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,18})\\b/gi,\n placeholder: '[DD_MANDATE_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Direct Debit mandate reference numbers'\n};\n\n/**\n * Cheque Numbers\n */\nexport const CHEQUE_NUMBER: PIIPattern = {\n type: 'CHEQUE_NUMBER',\n regex: /\\b(?:CHE(?:QUE|CK))[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{6,10})\\b/gi,\n placeholder: '[CHEQUE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Cheque/check numbers',\n validator: (_value: string, context: string) => {\n return /cheque|check|payment/i.test(context);\n }\n};\n\n/**\n * Stock/Share Trading Account Numbers\n */\nexport const TRADING_ACCOUNT: PIIPattern = {\n type: 'TRADING_ACCOUNT',\n regex: /\\b(?:TRADING|BROKERAGE|STOCK)[-\\s]?(?:ACCOUNT|ACCT|A\\/C)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[TRADE_ACCT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Stock trading and brokerage account numbers'\n};\n\n/**\n * Loan Account Numbers\n */\nexport const LOAN_ACCOUNT: PIIPattern = {\n type: 'LOAN_ACCOUNT',\n regex: /\\b(?:LOAN|MORTGAGE|CREDIT)[-\\s]?(?:ACCOUNT|ACCT|A\\/C)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[LOAN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Loan and mortgage account numbers'\n};\n\n/**\n * Bitcoin Addresses\n * Legacy (P2PKH): 1 + 26-35 base58 chars\n * Script (P2SH): 3 + 26-35 base58 chars\n * SegWit (Bech32): bc1 + 39-59 chars\n */\nexport const BITCOIN_ADDRESS: PIIPattern = {\n type: 'BITCOIN_ADDRESS',\n regex: /\\b([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})\\b/g,\n placeholder: '[BTC_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Bitcoin cryptocurrency addresses',\n validator: (value: string, _context: string) => {\n // Basic format validation\n if (value.startsWith('bc1')) {\n // Bech32 format\n return value.length >= 42 && value.length <= 62;\n } else {\n // Base58 format - exclude common false positives\n const hasLowercase = /[a-km-z]/.test(value);\n const hasUppercase = /[A-HJ-NP-Z]/.test(value);\n // More likely to be real if mixed case\n return hasLowercase || hasUppercase;\n }\n }\n};\n\n/**\n * Ethereum Addresses\n * Format: 0x + 40 hex characters\n */\nexport const ETHEREUM_ADDRESS: PIIPattern = {\n type: 'ETHEREUM_ADDRESS',\n regex: /\\b(0x[a-fA-F0-9]{40})\\b/g,\n placeholder: '[ETH_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ethereum cryptocurrency addresses'\n};\n\n/**\n * Litecoin Addresses\n * Format: L or M + 26-34 base58 chars (legacy), ltc1 + 39-59 chars (bech32)\n */\nexport const LITECOIN_ADDRESS: PIIPattern = {\n type: 'LITECOIN_ADDRESS',\n regex: /\\b([LM][a-km-zA-HJ-NP-Z1-9]{26,33}|ltc1[a-z0-9]{39,59})\\b/g,\n placeholder: '[LTC_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Litecoin cryptocurrency addresses',\n validator: (value: string, context: string) => {\n const cryptoContext = /crypto|litecoin|ltc|wallet|address/i.test(context);\n return cryptoContext || value.startsWith('ltc1');\n }\n};\n\n/**\n * Monero Addresses\n * Format: 4 or 8 + 94 base58 chars\n */\nexport const MONERO_ADDRESS: PIIPattern = {\n type: 'MONERO_ADDRESS',\n regex: /\\b([48][a-km-zA-HJ-NP-Z1-9]{94})\\b/g,\n placeholder: '[XMR_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Monero cryptocurrency addresses',\n validator: (value: string, context: string) => {\n const cryptoContext = /crypto|monero|xmr|wallet|address/i.test(context);\n return cryptoContext && value.length === 95;\n }\n};\n\n/**\n * Ripple (XRP) Addresses\n * Format: r + 24-34 base58 chars\n */\nexport const RIPPLE_ADDRESS: PIIPattern = {\n type: 'RIPPLE_ADDRESS',\n regex: /\\b(r[a-km-zA-HJ-NP-Z1-9]{24,34})\\b/g,\n placeholder: '[XRP_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ripple (XRP) cryptocurrency addresses',\n validator: (value: string, context: string) => {\n const cryptoContext = /crypto|ripple|xrp|wallet|address/i.test(context);\n return cryptoContext && value.length >= 25 && value.length <= 35;\n }\n};\n\n/**\n * Cardano Addresses\n * Format: addr1 + 58-104 bech32 chars\n */\nexport const CARDANO_ADDRESS: PIIPattern = {\n type: 'CARDANO_ADDRESS',\n regex: /\\b(addr1[a-z0-9]{58,104})\\b/g,\n placeholder: '[ADA_ADDR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Cardano (ADA) cryptocurrency addresses'\n};\n\n/**\n * Crypto Transaction Hashes\n * Bitcoin/Ethereum: 64 hex characters\n */\nexport const CRYPTO_TX_HASH: PIIPattern = {\n type: 'CRYPTO_TX_HASH',\n regex: /\\b(?:TX|TXID|TRANSACTION[-\\s]?HASH)[:\\s]+([a-fA-F0-9]{64})\\b/gi,\n placeholder: '[CRYPTO_TX_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Cryptocurrency transaction hashes',\n validator: (_value: string, context: string) => {\n return /crypto|bitcoin|ethereum|blockchain|transaction|tx|txid/i.test(context);\n }\n};\n\n/**\n * Payment Card Track 1 Data\n * Format: %B + PAN + ^ + Name + ^ + Expiry + Service Code + Discretionary Data + ?\n */\nexport const CARD_TRACK1_DATA: PIIPattern = {\n type: 'CARD_TRACK1_DATA',\n regex: /%B\\d{13,19}\\^[^^]+\\^\\d{4}\\d{3}[^?]+\\?/g,\n placeholder: '[TRACK1_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Payment card Track 1 magnetic stripe data'\n};\n\n/**\n * Payment Card Track 2 Data\n * Format: ;PAN=Expiry+Service Code+Discretionary Data+?\n */\nexport const CARD_TRACK2_DATA: PIIPattern = {\n type: 'CARD_TRACK2_DATA',\n regex: /;\\d{13,19}=\\d{4}\\d{3}[^?]+\\?/g,\n placeholder: '[TRACK2_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Payment card Track 2 magnetic stripe data'\n};\n\n/**\n * CVV/CVC in Payment Context\n * 3-4 digits when mentioned with card/payment keywords\n */\nexport const CVV_IN_CONTEXT: PIIPattern = {\n type: 'CVV_CODE',\n regex: /\\b(?:CVV|CVC|CVV2|CID|CSC)[:\\s]+(\\d{3,4})\\b/gi,\n placeholder: '[CVV_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Card verification value (CVV/CVC) codes',\n validator: (value: string, _context: string) => {\n return value.length >= 3 && value.length <= 4;\n }\n};\n\n/**\n * Card Expiration Dates in Payment Context\n * Formats: MM/YY, MM/YYYY, MM-YY, MMYY\n */\nexport const CARD_EXPIRY_IN_CONTEXT: PIIPattern = {\n type: 'CARD_EXPIRY',\n regex: /\\b(?:EXP(?:IRY|IRATION)?|VALID\\s+THRU)[:\\s]+(\\d{2}[\\/\\-]\\d{2,4}|\\d{4})\\b/gi,\n placeholder: '[EXPIRY_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Card expiration dates',\n validator: (value: string, context: string) => {\n const cardContext = /card|payment|credit|debit|visa|mastercard|amex/i.test(context);\n // Validate month if in MM/YY format\n if (value.includes('/') || value.includes('-')) {\n const parts = value.split(/[\\/\\-]/);\n const month = parseInt(parts[0]);\n return cardContext && month >= 1 && month <= 12;\n }\n return cardContext;\n }\n};\n\n/**\n * Stock/Security Ticker Symbols with Trade Details\n * Format: Ticker symbol followed by trade info\n */\nexport const STOCK_TRADE: PIIPattern = {\n type: 'STOCK_TRADE',\n regex: /\\b([A-Z]{1,5})\\s+(?:BUY|SELL|SOLD|BOUGHT)\\s+(\\d+(?:,\\d{3})*(?:\\.\\d{2})?)\\s+(?:@|at)\\s+\\$?(\\d+(?:\\.\\d{2,4})?)\\b/gi,\n placeholder: '[TRADE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Stock trade details with ticker, quantity, and price',\n validator: (_value: string, context: string) => {\n return /stock|trade|buy|sell|shares|equity|portfolio/i.test(context);\n }\n};\n\n/**\n * Bank Wire Transfer Details\n * Captures wire transfer instructions with account details\n */\nexport const WIRE_TRANSFER_DETAILS: PIIPattern = {\n type: 'WIRE_TRANSFER_DETAILS',\n regex: /\\b(?:WIRE\\s+TO|TRANSFER\\s+TO|BENEFICIARY)[:\\s]+([A-Z0-9\\s,.-]{20,100})/gi,\n placeholder: '[WIRE_DETAILS_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Bank wire transfer beneficiary details',\n validator: (_value: string, context: string) => {\n return /wire|transfer|beneficiary|recipient|iban|swift|aba|routing/i.test(context);\n }\n};\n\n/**\n * Payment Card Token (from payment gateways)\n */\nexport const PAYMENT_TOKEN: PIIPattern = {\n type: 'PAYMENT_TOKEN',\n regex: /\\b(?:tok|card|pm|src)_[a-zA-Z0-9]{24,}/g,\n placeholder: '[PAY_TOKEN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Payment gateway tokens (Stripe, etc.)'\n};\n\n/**\n * Customer ID (from payment gateways)\n */\nexport const PAYMENT_CUSTOMER_ID: PIIPattern = {\n type: 'PAYMENT_CUSTOMER_ID',\n regex: /\\b(cus_[a-zA-Z0-9]{14,})/g,\n placeholder: '[CUST_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Payment gateway customer IDs'\n};\n\n/**\n * Subscription ID (from payment gateways)\n */\nexport const SUBSCRIPTION_ID: PIIPattern = {\n type: 'SUBSCRIPTION_ID',\n regex: /\\b(sub_[a-zA-Z0-9]{14,})/g,\n placeholder: '[SUB_ID_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Payment subscription IDs'\n};\n\n/**\n * Account Statement References\n */\nexport const STATEMENT_REF: PIIPattern = {\n type: 'STATEMENT_REF',\n regex: /\\b(?:STATEMENT|STMT)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[STMT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Account statement reference numbers'\n};\n\n/**\n * Standing Order References\n */\nexport const STANDING_ORDER_REF: PIIPattern = {\n type: 'STANDING_ORDER_REF',\n regex: /\\b(?:STANDING[-\\s]?ORDER|SO)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[SO_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Standing order reference numbers'\n};\n\n/**\n * Payment Reference Numbers (generic)\n */\nexport const PAYMENT_REFERENCE: PIIPattern = {\n type: 'PAYMENT_REFERENCE',\n regex: /\\b(?:PAYMENT|PAY)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[PAY_REF_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Generic payment reference numbers'\n};\n\n/**\n * Card Authorization Codes\n */\nexport const CARD_AUTH_CODE: PIIPattern = {\n type: 'CARD_AUTH_CODE',\n regex: /\\b(?:AUTH(?:ORIZATION)?|APPROVAL)[-\\s]?(?:CODE|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[AUTH_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Card authorization codes',\n validator: (_value: string, context: string) => {\n return /payment|card|transaction|auth|approval/i.test(context);\n }\n};\n\n/**\n * Merchant ID\n */\nexport const MERCHANT_ID: PIIPattern = {\n type: 'MERCHANT_ID',\n regex: /\\b(?:MERCHANT|MID)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[MERCHANT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Merchant identification numbers',\n validator: (_value: string, context: string) => {\n return /merchant|terminal|pos|payment|processor/i.test(context);\n }\n};\n\n/**\n * Terminal ID (POS)\n */\nexport const TERMINAL_ID: PIIPattern = {\n type: 'TERMINAL_ID',\n regex: /\\b(?:TERMINAL|TID|POS)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[TERMINAL_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Point of sale terminal IDs',\n validator: (_value: string, context: string) => {\n return /terminal|pos|point.of.sale|card.reader/i.test(context);\n }\n};\n\n/**\n * UK Bank Account Number (IBAN format)\n * Format: GB followed by 2 check digits, 4-letter bank code, and 14-digit account number\n */\nexport const UK_BANK_ACCOUNT_IBAN: PIIPattern = {\n type: 'UK_BANK_ACCOUNT_IBAN',\n regex: /\\b(GB\\d{2}[A-Z]{4}\\d{14})\\b/g,\n placeholder: '[UK_IBAN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'UK bank account numbers in IBAN format',\n validator: (value: string) => {\n return value.startsWith('GB') && value.length === 22;\n }\n};\n\n/**\n * UK Sort Code and Account Number Combined\n * Format: XX-XX-XX followed by 8-digit account number\n */\nexport const UK_SORT_CODE_ACCOUNT: PIIPattern = {\n type: 'UK_SORT_CODE_ACCOUNT',\n regex: /\\b(\\d{2}[-]\\d{2}[-]\\d{2}\\s?\\d{8})\\b/g,\n placeholder: '[UK_ACCOUNT_{n}]',\n priority: 95,\n severity: 'high',\n description: 'UK sort code and account number combination'\n};\n\n// Export all financial patterns\nexport const financialPatterns: PIIPattern[] = [\n SWIFT_BIC,\n TRANSACTION_ID,\n INVESTMENT_ACCOUNT,\n WIRE_TRANSFER_REF,\n WIRE_TRANSFER_DETAILS,\n DD_MANDATE,\n CHEQUE_NUMBER,\n TRADING_ACCOUNT,\n LOAN_ACCOUNT,\n BITCOIN_ADDRESS,\n ETHEREUM_ADDRESS,\n LITECOIN_ADDRESS,\n MONERO_ADDRESS,\n RIPPLE_ADDRESS,\n CARDANO_ADDRESS,\n CRYPTO_TX_HASH,\n CARD_TRACK1_DATA,\n CARD_TRACK2_DATA,\n CVV_IN_CONTEXT,\n CARD_EXPIRY_IN_CONTEXT,\n STOCK_TRADE,\n PAYMENT_TOKEN,\n PAYMENT_CUSTOMER_ID,\n SUBSCRIPTION_ID,\n STATEMENT_REF,\n STANDING_ORDER_REF,\n PAYMENT_REFERENCE,\n CARD_AUTH_CODE,\n MERCHANT_ID,\n TERMINAL_ID,\n UK_BANK_ACCOUNT_IBAN,\n UK_SORT_CODE_ACCOUNT\n];\n","/**\n * Technology, Security, and API Patterns\n * API keys, tokens, credentials, and infrastructure identifiers\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * AWS Access Key ID\n * Format: AKIA + 16 alphanumeric characters\n */\nexport const AWS_ACCESS_KEY: PIIPattern = {\n type: 'AWS_ACCESS_KEY',\n regex: /\\b(AKIA[0-9A-Z]{16})\\b/g,\n placeholder: '[AWS_KEY_{n}]',\n priority: 95,\n severity: 'high',\n description: 'AWS Access Key ID'\n};\n\n/**\n * AWS Secret Access Key\n * Format: 40 base64 characters\n */\nexport const AWS_SECRET_KEY: PIIPattern = {\n type: 'AWS_SECRET_KEY',\n regex: /(?:aws.{0,20})?(?:secret.{0,20})?([a-zA-Z0-9/+=]{40})/gi,\n placeholder: '[AWS_SECRET_{n}]',\n priority: 98,\n severity: 'high',\n description: 'AWS Secret Access Key',\n validator: (_value: string, context: string) => {\n // Must be in AWS/secret context\n return /aws|amazon|secret|access.key/i.test(context);\n }\n};\n\n/**\n * Google API Key\n * Format: AIza + 35 characters\n */\nexport const GOOGLE_API_KEY: PIIPattern = {\n type: 'GOOGLE_API_KEY',\n regex: /\\b(AIza[0-9A-Za-z\\-_]{35})\\b/g,\n placeholder: '[GOOGLE_API_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Google API Key'\n};\n\n/**\n * Stripe API Keys\n * Format: sk_live_, pk_live_, sk_test_, pk_test_\n */\nexport const STRIPE_API_KEY: PIIPattern = {\n type: 'STRIPE_API_KEY',\n regex: /\\b((sk|pk)_(live|test)_[0-9a-zA-Z]{24,})\\b/g,\n placeholder: '[STRIPE_KEY_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Stripe API Keys'\n};\n\n/**\n * GitHub Personal Access Token\n * Format: ghp_, gho_, ghu_, ghs_, ghr_\n */\nexport const GITHUB_TOKEN: PIIPattern = {\n type: 'GITHUB_TOKEN',\n regex: /\\b(gh[pousr]_[A-Za-z0-9]{36,})\\b/g,\n placeholder: '[GITHUB_TOKEN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'GitHub Personal Access Token'\n};\n\n/**\n * JWT Token\n * Format: eyJ... (base64)\n */\nexport const JWT_TOKEN: PIIPattern = {\n type: 'JWT_TOKEN',\n regex: /\\b(eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)\\b/g,\n placeholder: '[JWT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'JSON Web Token (JWT)'\n};\n\n/**\n * Generic API Key Pattern\n */\nexport const GENERIC_API_KEY: PIIPattern = {\n type: 'GENERIC_API_KEY',\n regex: /\\b(?:api.{0,5}key|apikey|api.token)[:\\s=]+([a-zA-Z0-9_\\-]{20,})\\b/gi,\n placeholder: '[API_KEY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Generic API key pattern',\n validator: (value: string, context: string) => {\n // Exclude common false positives\n const excluded = /example|sample|test|fake|demo|placeholder|xxx/i;\n return !excluded.test(value) && !excluded.test(context);\n }\n};\n\n/**\n * Generic Secret/Password\n */\nexport const GENERIC_SECRET: PIIPattern = {\n type: 'GENERIC_SECRET',\n regex: /\\b(?:password|passwd|pwd|secret)[:\\s=]+([a-zA-Z0-9!@#$%^&*()_+\\-=\\[\\]{}|;:,.<>?]{8,})\\b/gi,\n placeholder: '[SECRET_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Generic passwords and secrets',\n validator: (value: string, _context: string) => {\n // Exclude obvious placeholders\n const excluded = /example|sample|test|fake|demo|placeholder|xxx|password|secret|\\*+/i;\n return !excluded.test(value) && value.length >= 8;\n }\n};\n\n/**\n * Private Key Headers\n */\nexport const PRIVATE_KEY: PIIPattern = {\n type: 'PRIVATE_KEY',\n regex: /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----[\\s\\S]{20,}?-----END (?:RSA |EC )?PRIVATE KEY-----/g,\n placeholder: '[PRIVATE_KEY_{n}]',\n priority: 98,\n severity: 'high',\n description: 'RSA/EC Private Keys'\n};\n\n/**\n * SSH Private Key\n */\nexport const SSH_PRIVATE_KEY: PIIPattern = {\n type: 'SSH_PRIVATE_KEY',\n regex: /-----BEGIN OPENSSH PRIVATE KEY-----[\\s\\S]{20,}?-----END OPENSSH PRIVATE KEY-----/g,\n placeholder: '[SSH_KEY_{n}]',\n priority: 98,\n severity: 'high',\n description: 'SSH Private Keys'\n};\n\n/**\n * Database Connection String\n */\nexport const DATABASE_CONNECTION: PIIPattern = {\n type: 'DATABASE_CONNECTION',\n regex: /(?:postgres|mysql|mongodb|redis|sqlite):\\/\\/[^\\s:]+:[^\\s@]+@[^\\s]+/gi,\n placeholder: '[DB_CONN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Database connection strings with credentials'\n};\n\n/**\n * AWS ARN\n */\nexport const AWS_ARN: PIIPattern = {\n type: 'AWS_ARN',\n regex: /\\b(arn:aws:[a-z0-9\\-]+:[a-z0-9\\-]*:[0-9]{12}:[a-zA-Z0-9\\/\\-_:]+)\\b/g,\n placeholder: '[AWS_ARN_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'AWS Amazon Resource Name',\n validator: (_value: string, context: string) => {\n // Only in cloud/AWS context\n return /aws|amazon|cloud|arn|resource/i.test(context);\n }\n};\n\n/**\n * Docker Hub Credentials\n */\nexport const DOCKER_AUTH: PIIPattern = {\n type: 'DOCKER_AUTH',\n regex: /\\{[^}]*\"auth\"\\s*:\\s*\"([A-Za-z0-9+/=]{20,})\"[^}]*\\}/g,\n placeholder: '[DOCKER_AUTH_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Docker authentication tokens'\n};\n\n/**\n * Slack Webhook\n */\nexport const SLACK_WEBHOOK: PIIPattern = {\n type: 'SLACK_WEBHOOK',\n regex: /https:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Z0-9]+\\/[A-Z0-9]+\\/[A-Za-z0-9]+/g,\n placeholder: '[SLACK_WEBHOOK_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Slack incoming webhook URLs'\n};\n\n/**\n * Slack Token\n */\nexport const SLACK_TOKEN: PIIPattern = {\n type: 'SLACK_TOKEN',\n regex: /\\b(xox[baprs]-[0-9a-zA-Z\\-]{10,})\\b/g,\n placeholder: '[SLACK_TOKEN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Slack API tokens'\n};\n\n/**\n * Twilio API Key\n */\nexport const TWILIO_API_KEY: PIIPattern = {\n type: 'TWILIO_API_KEY',\n regex: /\\b(SK[a-z0-9]{32})\\b/g,\n placeholder: '[TWILIO_KEY_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Twilio API Keys',\n validator: (_value: string, context: string) => {\n return /twilio|sms|phone|messaging/i.test(context);\n }\n};\n\n/**\n * Mailgun API Key\n */\nexport const MAILGUN_API_KEY: PIIPattern = {\n type: 'MAILGUN_API_KEY',\n regex: /\\b(key-[a-z0-9]{32})\\b/g,\n placeholder: '[MAILGUN_KEY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Mailgun API Keys',\n validator: (_value: string, context: string) => {\n return /mailgun|email|mail/i.test(context);\n }\n};\n\n/**\n * SendGrid API Key\n */\nexport const SENDGRID_API_KEY: PIIPattern = {\n type: 'SENDGRID_API_KEY',\n regex: /\\b(SG\\.[a-zA-Z0-9_\\-]{22}\\.[a-zA-Z0-9_\\-]{43})\\b/g,\n placeholder: '[SENDGRID_KEY_{n}]',\n priority: 90,\n severity: 'high',\n description: 'SendGrid API Keys'\n};\n\n/**\n * Session ID (generic)\n */\nexport const SESSION_ID: PIIPattern = {\n type: 'SESSION_ID',\n regex: /\\b(?:session|sess|sid)[:\\s=]+([a-f0-9]{32,})\\b/gi,\n placeholder: '[SESSION_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Session identifiers',\n validator: (value: string, _context: string) => {\n return value.length >= 32 && /^[a-f0-9]+$/.test(value);\n }\n};\n\n/**\n * Bearer Token (Authorization header)\n */\nexport const BEARER_TOKEN: PIIPattern = {\n type: 'BEARER_TOKEN',\n regex: /\\bBearer\\s+([a-zA-Z0-9_\\-\\.]{20,})/g,\n placeholder: '[BEARER_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Bearer authentication tokens'\n};\n\n/**\n * Azure Resource ID\n * Format: /subscriptions/{guid}/resourceGroups/{name}/...\n */\nexport const AZURE_RESOURCE_ID: PIIPattern = {\n type: 'AZURE_RESOURCE_ID',\n regex: /\\/subscriptions\\/[a-f0-9\\-]{36}\\/resourceGroups\\/[a-zA-Z0-9\\-_]+\\/providers\\/[a-zA-Z0-9\\.\\-_\\/]+/gi,\n placeholder: '[AZURE_RES_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Azure Resource IDs',\n validator: (_value: string, context: string) => {\n return /azure|microsoft|cloud|resource/i.test(context);\n }\n};\n\n/**\n * Azure Storage Account Key\n */\nexport const AZURE_STORAGE_KEY: PIIPattern = {\n type: 'AZURE_STORAGE_KEY',\n regex: /\\b(?:DefaultEndpointsProtocol|AccountKey)=([a-zA-Z0-9+/=]{88})/g,\n placeholder: '[AZURE_KEY_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Azure Storage Account Keys',\n validator: (_value: string, context: string) => {\n return /azure|storage|account|connection/i.test(context);\n }\n};\n\n/**\n * GCP Service Account Key\n */\nexport const GCP_SERVICE_ACCOUNT: PIIPattern = {\n type: 'GCP_SERVICE_ACCOUNT',\n regex: /\\{[^}]*\"type\"\\s*:\\s*\"service_account\"[^}]*\"private_key_id\"\\s*:\\s*\"([a-z0-9]{40})\"[^}]*\\}/gi,\n placeholder: '[GCP_SA_{n}]',\n priority: 95,\n severity: 'high',\n description: 'GCP Service Account Keys'\n};\n\n/**\n * Kubernetes Secret\n */\nexport const KUBERNETES_SECRET: PIIPattern = {\n type: 'KUBERNETES_SECRET',\n regex: /\\b(?:kind:\\s*Secret|apiVersion:\\s*v1)\\s[\\s\\S]{0,500}?data:\\s*\\n\\s+[a-zA-Z0-9\\-_]+:\\s*([A-Za-z0-9+/=]{20,})/g,\n placeholder: '[K8S_SECRET_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kubernetes Secret data',\n validator: (_value: string, context: string) => {\n return /kubernetes|k8s|secret|configmap/i.test(context);\n }\n};\n\n/**\n * Cookie Session Token\n */\nexport const COOKIE_SESSION: PIIPattern = {\n type: 'COOKIE_SESSION',\n regex: /\\b(?:set-cookie|cookie):\\s*(?:session|sessid|sid|auth)=([a-zA-Z0-9_\\-\\.]{20,})/gi,\n placeholder: '[COOKIE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'HTTP session cookies'\n};\n\n/**\n * NPM Token\n */\nexport const NPM_TOKEN: PIIPattern = {\n type: 'NPM_TOKEN',\n regex: /\\b(npm_[A-Za-z0-9]{36})\\b/g,\n placeholder: '[NPM_TOKEN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'NPM authentication tokens'\n};\n\n/**\n * PyPI Token\n */\nexport const PYPI_TOKEN: PIIPattern = {\n type: 'PYPI_TOKEN',\n regex: /\\b(pypi-[A-Za-z0-9_\\-]{100,})\\b/g,\n placeholder: '[PYPI_TOKEN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Python PyPI tokens'\n};\n\n/**\n * Heroku API Key\n */\nexport const HEROKU_API_KEY: PIIPattern = {\n type: 'HEROKU_API_KEY',\n regex: /\\b([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\\b/g,\n placeholder: '[HEROKU_KEY_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Heroku API keys',\n validator: (_value: string, context: string) => {\n return /heroku|api.key|auth/i.test(context);\n }\n};\n\n/**\n * Firebase API Key\n */\nexport const FIREBASE_API_KEY: PIIPattern = {\n type: 'FIREBASE_API_KEY',\n regex: /\\b(AIza[0-9A-Za-z\\-_]{35})\\b/g,\n placeholder: '[FIREBASE_KEY_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Firebase API keys',\n validator: (_value: string, context: string) => {\n return /firebase|google|cloud/i.test(context);\n }\n};\n\n/**\n * OAuth Client Secret\n */\nexport const OAUTH_CLIENT_SECRET: PIIPattern = {\n type: 'OAUTH_CLIENT_SECRET',\n regex: /\\b(?:client.?secret|consumer.?secret)[:=\\s]+([a-zA-Z0-9_\\-]{20,})/gi,\n placeholder: '[OAUTH_SECRET_{n}]',\n priority: 95,\n severity: 'high',\n description: 'OAuth client secrets',\n validator: (value: string, _context: string) => {\n const excluded = /example|sample|test|fake|demo|placeholder/i;\n return !excluded.test(value);\n }\n};\n\n/**\n * Generic OAuth Token\n */\nexport const OAUTH_TOKEN: PIIPattern = {\n type: 'OAUTH_TOKEN',\n regex: /\\b(?:oauth.?token|access.?token)[:=\\s]+([a-zA-Z0-9_\\-\\.]{20,})/gi,\n placeholder: '[OAUTH_TOKEN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'OAuth access tokens',\n validator: (value: string, _context: string) => {\n const excluded = /example|sample|test|fake|demo|placeholder/i;\n return !excluded.test(value) && value.length >= 20;\n }\n};\n\n// Export all technology patterns\nexport const technologyPatterns: PIIPattern[] = [\n AWS_ACCESS_KEY,\n AWS_SECRET_KEY,\n GOOGLE_API_KEY,\n STRIPE_API_KEY,\n GITHUB_TOKEN,\n JWT_TOKEN,\n GENERIC_API_KEY,\n GENERIC_SECRET,\n PRIVATE_KEY,\n SSH_PRIVATE_KEY,\n DATABASE_CONNECTION,\n AWS_ARN,\n DOCKER_AUTH,\n SLACK_WEBHOOK,\n SLACK_TOKEN,\n TWILIO_API_KEY,\n MAILGUN_API_KEY,\n SENDGRID_API_KEY,\n SESSION_ID,\n BEARER_TOKEN,\n AZURE_RESOURCE_ID,\n AZURE_STORAGE_KEY,\n GCP_SERVICE_ACCOUNT,\n KUBERNETES_SECRET,\n COOKIE_SESSION,\n NPM_TOKEN,\n PYPI_TOKEN,\n HEROKU_API_KEY,\n FIREBASE_API_KEY,\n OAUTH_CLIENT_SECRET,\n OAUTH_TOKEN\n];\n","/**\n * Legal Industry PII Patterns\n * For law firms, courts, legal services - attorney-client privilege protection\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Case Numbers (various court formats)\n */\nexport const CASE_NUMBER: PIIPattern = {\n type: 'CASE_NUMBER',\n regex: /\\b(?:CASE|DOCKET|FILE)[-\\s]?(?:NO|NUM(?:BER)?|REF)?[-\\s]?[:#]?\\s*([A-Z]{1,3}[-]?\\d{2,4}[-]?[A-Z]{0,3}[-]?\\d{4,8})\\b/gi,\n placeholder: '[CASE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Court case and docket numbers'\n};\n\n/**\n * Matter Numbers (law firm internal references)\n */\nexport const MATTER_NUMBER: PIIPattern = {\n type: 'MATTER_NUMBER',\n regex: /\\b(?:MATTER|ENGAGEMENT|CLIENT[-\\s]?MATTER)[-\\s]?(?:NO|NUM(?:BER)?|REF|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[MATTER_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Law firm matter and engagement numbers',\n validator: (_value: string, context: string) => {\n return /legal|matter|client|engagement|firm|attorney|counsel/i.test(context);\n }\n};\n\n/**\n * Attorney Bar Numbers\n */\nexport const BAR_NUMBER: PIIPattern = {\n type: 'BAR_NUMBER',\n regex: /\\b(?:BAR|ATTORNEY|LAWYER)[-\\s]?(?:NO|NUM(?:BER)?|REG(?:ISTRATION)?|LIC(?:ENSE)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{5,12})\\b/gi,\n placeholder: '[BAR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Attorney bar registration numbers'\n};\n\n/**\n * Exhibit Numbers\n */\nexport const EXHIBIT_NUMBER: PIIPattern = {\n type: 'EXHIBIT_NUMBER',\n regex: /\\bEXHIBIT[-\\s]?([A-Z]{1,2}[-]?\\d{1,4})\\b/gi,\n placeholder: '[EXHIBIT_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Legal exhibit reference numbers',\n validator: (_value: string, context: string) => {\n return /exhibit|evidence|document|trial|hearing|deposition/i.test(context);\n }\n};\n\n/**\n * Deposition References\n */\nexport const DEPOSITION_REF: PIIPattern = {\n type: 'DEPOSITION_REF',\n regex: /\\b(?:DEPOSITION|DEPO|DEP)[-\\s]?(?:NO|NUM(?:BER)?|REF|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[DEPO_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Deposition reference numbers',\n validator: (_value: string, context: string) => {\n return /deposition|depo|testimony|transcript|witness/i.test(context);\n }\n};\n\n/**\n * Discovery Request Numbers\n */\nexport const DISCOVERY_NUMBER: PIIPattern = {\n type: 'DISCOVERY_NUMBER',\n regex: /\\b(?:DISCOVERY|INTERROGATORY|REQUEST|RFP|RFA)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{1,4}[-]?\\d{1,4})\\b/gi,\n placeholder: '[DISCOVERY_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Discovery request, interrogatory, and production numbers'\n};\n\n/**\n * Court Reporter License\n */\nexport const COURT_REPORTER_LICENSE: PIIPattern = {\n type: 'COURT_REPORTER_LICENSE',\n regex: /\\b(?:COURT[-\\s]?REPORTER|CSR|RPR)[-\\s]?(?:LIC(?:ENSE)?|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{2,3}[-]?\\d{4,8})\\b/gi,\n placeholder: '[CSR_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Court reporter license numbers'\n};\n\n/**\n * Subpoena Numbers\n */\nexport const SUBPOENA_NUMBER: PIIPattern = {\n type: 'SUBPOENA_NUMBER',\n regex: /\\b(?:SUBPOENA|SUMMONS)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[SUBPOENA_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Subpoena and summons numbers'\n};\n\n/**\n * Judgment/Order Numbers\n */\nexport const JUDGMENT_NUMBER: PIIPattern = {\n type: 'JUDGMENT_NUMBER',\n regex: /\\b(?:JUDGMENT|ORDER|DECREE)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[JUDGMENT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Court judgment and order numbers',\n validator: (_value: string, context: string) => {\n return /judgment|order|decree|ruling|decision|court/i.test(context);\n }\n};\n\n/**\n * Patent/Trademark Application Numbers\n */\nexport const PATENT_NUMBER: PIIPattern = {\n type: 'PATENT_NUMBER',\n regex: /\\b(?:(?:US|EP|WO|PCT)[-\\s]?)?(?:PATENT|PAT)[-\\s]?(?:NO|NUM(?:BER)?|APPL(?:ICATION)?)?[-\\s]?[:#]?\\s*([A-Z]{0,2}\\d{6,10}[A-Z0-9]{0,3})\\b/gi,\n placeholder: '[PATENT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Patent and trademark application numbers'\n};\n\n/**\n * Settlement Agreement IDs\n */\nexport const SETTLEMENT_ID: PIIPattern = {\n type: 'SETTLEMENT_ID',\n regex: /\\b(?:SETTLEMENT|AGREEMENT)[-\\s]?(?:ID|NO|NUM(?:BER)?|REF)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[SETTLEMENT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Settlement agreement identifiers',\n validator: (_value: string, context: string) => {\n return /settlement|agreement|resolution|mediation|arbitration/i.test(context);\n }\n};\n\n/**\n * Client Identifiers (confidential)\n */\nexport const CLIENT_ID: PIIPattern = {\n type: 'CLIENT_ID',\n regex: /\\b(?:CLIENT)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[CLIENT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Law firm client identifiers',\n validator: (_value: string, context: string) => {\n return /client|legal|matter|billing|invoice|retainer/i.test(context);\n }\n};\n\n/**\n * Retainer Agreement Numbers\n */\nexport const RETAINER_NUMBER: PIIPattern = {\n type: 'RETAINER_NUMBER',\n regex: /\\b(?:RETAINER)[-\\s]?(?:NO|NUM(?:BER)?|AGREEMENT)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RETAINER_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Retainer agreement numbers'\n};\n\n/**\n * Notary License Numbers\n */\nexport const NOTARY_LICENSE: PIIPattern = {\n type: 'NOTARY_LICENSE',\n regex: /\\b(?:NOTARY|NOTARIAL)[-\\s]?(?:LIC(?:ENSE)?|COMMISSION|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[NOTARY_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Notary public license and commission numbers'\n};\n\n/**\n * Bankruptcy Case Numbers\n */\nexport const BANKRUPTCY_CASE: PIIPattern = {\n type: 'BANKRUPTCY_CASE',\n regex: /\\b(?:BK|BANKRUPTCY)[-\\s]?(?:NO|NUM(?:BER)?|CASE)?[-\\s]?[:#]?\\s*(\\d{2}[-]?\\d{5}[-]?[A-Z]{0,3})\\b/gi,\n placeholder: '[BK_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Bankruptcy case numbers'\n};\n\n/**\n * Probate Case Numbers\n */\nexport const PROBATE_CASE: PIIPattern = {\n type: 'PROBATE_CASE',\n regex: /\\b(?:PROBATE|ESTATE)[-\\s]?(?:NO|NUM(?:BER)?|CASE)?[-\\s]?[:#]?\\s*([A-Z]{1,2}\\d{6,10})\\b/gi,\n placeholder: '[PROBATE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Probate and estate case numbers',\n validator: (_value: string, context: string) => {\n return /probate|estate|will|trust|inheritance|decedent/i.test(context);\n }\n};\n\n/**\n * Confidentiality Agreement IDs\n */\nexport const NDA_ID: PIIPattern = {\n type: 'NDA_ID',\n regex: /\\b(?:NDA|CONFIDENTIALITY|NON[-\\s]?DISCLOSURE)[-\\s]?(?:AGREEMENT)?[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[NDA_{n}]',\n priority: 75,\n severity: 'high',\n description: 'Non-disclosure and confidentiality agreement numbers'\n};\n\n/**\n * Contract Reference Code\n */\nexport const CONTRACT_REFERENCE: PIIPattern = {\n type: 'CONTRACT_REFERENCE',\n regex: /\\bCNTR[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{8})\\b/gi,\n placeholder: '[CONTRACT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Contract reference codes'\n};\n\n// Export all legal patterns\nexport const legalPatterns: PIIPattern[] = [\n CASE_NUMBER,\n MATTER_NUMBER,\n BAR_NUMBER,\n EXHIBIT_NUMBER,\n DEPOSITION_REF,\n DISCOVERY_NUMBER,\n COURT_REPORTER_LICENSE,\n SUBPOENA_NUMBER,\n JUDGMENT_NUMBER,\n PATENT_NUMBER,\n SETTLEMENT_ID,\n CLIENT_ID,\n RETAINER_NUMBER,\n NOTARY_LICENSE,\n BANKRUPTCY_CASE,\n PROBATE_CASE,\n NDA_ID,\n CONTRACT_REFERENCE\n];\n","/**\n * Education Industry PII Patterns\n * For schools, universities, educational institutions - FERPA compliance\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Student ID Numbers\n */\nexport const STUDENT_ID: PIIPattern = {\n type: 'STUDENT_ID',\n regex: /\\b(?:STUDENT|PUPIL|SCHOLAR)[-\\s]?(?:ID|NUM(?:BER)?|NO)?[-\\s]?[:#]?\\s*([A-Z]{0,2}\\d{6,10})\\b/gi,\n placeholder: '[STUDENT_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Student identification numbers'\n};\n\n/**\n * University/College ID\n */\nexport const UNIVERSITY_ID: PIIPattern = {\n type: 'UNIVERSITY_ID',\n regex: /\\b(?:UNIVERSITY|COLLEGE|UNI)[-\\s]?(?:ID|NUM(?:BER)?|NO)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[UNI_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'University and college ID numbers',\n validator: (_value: string, context: string) => {\n return /university|college|campus|student|enrollment|registr/i.test(context);\n }\n};\n\n/**\n * Course Numbers/Codes\n */\nexport const COURSE_CODE: PIIPattern = {\n type: 'COURSE_CODE',\n regex: /\\b([A-Z]{2,4}\\s?\\d{3,4}[A-Z]?)\\b/g,\n placeholder: '[COURSE_{n}]',\n priority: 60,\n severity: 'low',\n description: 'Course codes and numbers',\n validator: (value: string, context: string) => {\n // Only in academic context\n const academicContext = /course|class|section|semester|quarter|curriculum|syllabus/i.test(context);\n // Format check: letters followed by numbers\n const validFormat = /^[A-Z]{2,4}\\s?\\d{3,4}[A-Z]?$/.test(value);\n return academicContext && validFormat;\n }\n};\n\n/**\n * Grade/GPA References (when explicit)\n */\nexport const GRADE_REFERENCE: PIIPattern = {\n type: 'GRADE_REFERENCE',\n regex: /\\b(?:GPA|GRADE[-\\s]?POINT[-\\s]?AVERAGE)[-\\s]?[:#]?\\s*((?:[0-4]\\.\\d{1,2})|(?:\\d\\.\\d{2}))\\b/gi,\n placeholder: '[GPA_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Grade Point Average (GPA) references'\n};\n\n/**\n * Transcript ID Numbers\n */\nexport const TRANSCRIPT_ID: PIIPattern = {\n type: 'TRANSCRIPT_ID',\n regex: /\\b(?:TRANSCRIPT)[-\\s]?(?:ID|NUM(?:BER)?|NO|REF)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TRANSCRIPT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Academic transcript identifiers'\n};\n\n/**\n * Library Card Numbers\n */\nexport const LIBRARY_CARD: PIIPattern = {\n type: 'LIBRARY_CARD',\n regex: /\\b(?:LIBRARY)[-\\s]?(?:CARD|ID|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[LIBRARY_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Library card numbers'\n};\n\n/**\n * Teacher/Faculty ID\n */\nexport const FACULTY_ID: PIIPattern = {\n type: 'FACULTY_ID',\n regex: /\\b(?:FACULTY|TEACHER|INSTRUCTOR|PROFESSOR|STAFF)[-\\s]?(?:ID|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{1,2}\\d{6,10})\\b/gi,\n placeholder: '[FACULTY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Faculty and teacher identification numbers',\n validator: (_value: string, context: string) => {\n return /faculty|teacher|instructor|professor|staff|employee|personnel/i.test(context);\n }\n};\n\n/**\n * Enrollment Numbers\n */\nexport const ENROLLMENT_NUMBER: PIIPattern = {\n type: 'ENROLLMENT_NUMBER',\n regex: /\\b(?:ENROLLMENT|REGISTRATION)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ENROLLMENT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Course enrollment and registration numbers'\n};\n\n/**\n * Financial Aid ID\n */\nexport const FINANCIAL_AID_ID: PIIPattern = {\n type: 'FINANCIAL_AID_ID',\n regex: /\\b(?:FINANCIAL[-\\s]?AID|FAFSA|AID[-\\s]?APPLICATION)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[AID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Financial aid and FAFSA identifiers'\n};\n\n/**\n * Degree/Certificate Numbers\n */\nexport const DEGREE_NUMBER: PIIPattern = {\n type: 'DEGREE_NUMBER',\n regex: /\\b(?:DEGREE|DIPLOMA|CERTIFICATE)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[DEGREE_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Degree and certificate numbers',\n validator: (_value: string, context: string) => {\n return /degree|diploma|certificate|graduation|credential/i.test(context);\n }\n};\n\n/**\n * Exam/Test ID Numbers\n */\nexport const EXAM_ID: PIIPattern = {\n type: 'EXAM_ID',\n regex: /\\b(?:EXAM|TEST|QUIZ|ASSESSMENT)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[EXAM_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Examination and test identifiers',\n validator: (_value: string, context: string) => {\n return /exam|test|quiz|assessment|midterm|final|score/i.test(context);\n }\n};\n\n/**\n * Exam Registration Numbers (standardized format)\n */\nexport const EXAM_REGISTRATION_NUMBER: PIIPattern = {\n type: 'EXAM_REGISTRATION_NUMBER',\n regex: /\\bEXAM[-\\s]?(\\d{4}[-]\\d{4})\\b/gi,\n placeholder: '[EXAM_REG_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Exam registration numbers (standardized format)'\n};\n\n/**\n * Dorm/Housing Assignment\n */\nexport const HOUSING_ASSIGNMENT: PIIPattern = {\n type: 'HOUSING_ASSIGNMENT',\n regex: /\\b(?:DORM|ROOM|HOUSING)[-\\s]?(?:NO|NUM(?:BER)?|ASSIGNMENT)?[-\\s]?[:#]?\\s*([A-Z0-9]{4,10})\\b/gi,\n placeholder: '[HOUSING_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Dormitory and housing assignments',\n validator: (_value: string, context: string) => {\n return /dorm|housing|residence|room|building|floor|suite/i.test(context);\n }\n};\n\n/**\n * Meal Plan ID\n */\nexport const MEAL_PLAN_ID: PIIPattern = {\n type: 'MEAL_PLAN_ID',\n regex: /\\b(?:MEAL[-\\s]?PLAN|DINING)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[MEAL_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Meal plan and dining identifiers'\n};\n\n/**\n * Parking Permit Numbers\n */\nexport const PARKING_PERMIT: PIIPattern = {\n type: 'PARKING_PERMIT',\n regex: /\\b(?:PARKING)[-\\s]?(?:PERMIT|PASS|DECAL)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PARKING_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Parking permit numbers'\n};\n\n/**\n * Scholarship ID Numbers\n */\nexport const SCHOLARSHIP_ID: PIIPattern = {\n type: 'SCHOLARSHIP_ID',\n regex: /\\b(?:SCHOLARSHIP|GRANT|AWARD)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[SCHOLARSHIP_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Scholarship and grant award numbers',\n validator: (_value: string, context: string) => {\n return /scholarship|grant|award|fellowship|stipend|financial/i.test(context);\n }\n};\n\n/**\n * Graduation Year (when combined with other PII)\n */\nexport const GRADUATION_YEAR: PIIPattern = {\n type: 'GRADUATION_YEAR',\n regex: /\\b(?:CLASS[-\\s]?OF|GRADUATING[-\\s]?CLASS|GRAD(?:UATION)?[-\\s]?YEAR)[-\\s]?[:#]?\\s*(['']?\\d{2}|[12]\\d{3})\\b/gi,\n placeholder: '[GRAD_YEAR_{n}]',\n priority: 65,\n severity: 'low',\n description: 'Graduation year references'\n};\n\n/**\n * Application ID (admissions)\n */\nexport const APPLICATION_ID: PIIPattern = {\n type: 'APPLICATION_ID',\n regex: /\\b(?:APPLICATION|ADMISSION|APPLICANT)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[APPLICATION_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Admissions application identifiers',\n validator: (_value: string, context: string) => {\n return /application|admission|applicant|prospective|admit|enroll/i.test(context);\n }\n};\n\n/**\n * Alumni ID Numbers\n */\nexport const ALUMNI_ID: PIIPattern = {\n type: 'ALUMNI_ID',\n regex: /\\b(?:ALUMNI|ALUMNUS|ALUMNA)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ALUMNI_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Alumni identification numbers'\n};\n\n/**\n * Research Grant Numbers\n */\nexport const RESEARCH_GRANT: PIIPattern = {\n type: 'RESEARCH_GRANT',\n regex: /\\b(?:GRANT|RESEARCH|FUNDING)[-\\s]?(?:NO|NUM(?:BER)?|ID|REF)?[-\\s]?[:#]?\\s*([A-Z]{2,4}[-]?\\d{6,10})\\b/gi,\n placeholder: '[GRANT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Research grant and funding numbers',\n validator: (_value: string, context: string) => {\n return /grant|research|funding|nsf|nih|award|project/i.test(context);\n }\n};\n\n/**\n * Department Codes\n */\nexport const DEPARTMENT_CODE: PIIPattern = {\n type: 'DEPARTMENT_CODE',\n regex: /\\b(?:DEPT|DEPARTMENT)[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*([A-Z]{3,6})\\b/g,\n placeholder: '[DEPT_{n}]',\n priority: 55,\n severity: 'low',\n description: 'Academic department codes',\n validator: (value: string, context: string) => {\n const academicContext = /department|college|school|faculty|division/i.test(context);\n const minLength = value.length >= 3;\n return academicContext && minLength;\n }\n};\n\n// Export all education patterns\nexport const educationPatterns: PIIPattern[] = [\n STUDENT_ID,\n UNIVERSITY_ID,\n COURSE_CODE,\n GRADE_REFERENCE,\n TRANSCRIPT_ID,\n LIBRARY_CARD,\n FACULTY_ID,\n ENROLLMENT_NUMBER,\n FINANCIAL_AID_ID,\n DEGREE_NUMBER,\n EXAM_ID,\n EXAM_REGISTRATION_NUMBER,\n HOUSING_ASSIGNMENT,\n MEAL_PLAN_ID,\n PARKING_PERMIT,\n SCHOLARSHIP_ID,\n GRADUATION_YEAR,\n APPLICATION_ID,\n ALUMNI_ID,\n RESEARCH_GRANT,\n DEPARTMENT_CODE\n];\n","/**\n * HR and Recruitment Industry PII Patterns\n * For human resources, recruiting, talent acquisition - employee privacy protection\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Employee ID Numbers\n */\nexport const EMPLOYEE_ID: PIIPattern = {\n type: 'EMPLOYEE_ID',\n regex: /\\b(?:EMPLOYEE|EMP|STAFF|PERSONNEL|WORKER)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{0,2}\\d{4,10})\\b/gi,\n placeholder: '[EMP_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Employee identification numbers'\n};\n\n/**\n * Payroll Numbers\n */\nexport const PAYROLL_NUMBER: PIIPattern = {\n type: 'PAYROLL_NUMBER',\n regex: /\\b(?:PAYROLL|PAY)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PAYROLL_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Payroll identification numbers',\n validator: (_value: string, context: string) => {\n return /payroll|salary|compensation|pay|wage|earning/i.test(context);\n }\n};\n\n/**\n * Salary Information (with currency)\n */\nexport const SALARY_AMOUNT: PIIPattern = {\n type: 'SALARY_AMOUNT',\n regex: /\\b(?:SALARY|COMPENSATION|PAY|WAGE|EARNING)[-\\s]?[:#]?\\s*(?:[$£€¥]\\s?)?(\\d{1,3}(?:[,\\s]\\d{3})*(?:\\.\\d{2})?)\\b/gi,\n placeholder: '[SALARY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Salary and compensation amounts',\n validator: (value: string, context: string) => {\n // Only in compensation context\n const compContext = /salary|compensation|pay|wage|earning|income|annual|hourly/i.test(context);\n // Value should be reasonable (1000+)\n const numValue = parseInt(value.replace(/[,\\s]/g, ''));\n return compContext && numValue >= 1000;\n }\n};\n\n/**\n * Performance Review IDs\n */\nexport const PERFORMANCE_REVIEW_ID: PIIPattern = {\n type: 'PERFORMANCE_REVIEW_ID',\n regex: /\\b(?:PERFORMANCE|REVIEW|APPRAISAL|EVALUATION)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[REVIEW_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Performance review and appraisal identifiers',\n validator: (_value: string, context: string) => {\n return /performance|review|appraisal|evaluation|rating|assessment/i.test(context);\n }\n};\n\n/**\n * Job Application IDs\n */\nexport const JOB_APPLICATION_ID: PIIPattern = {\n type: 'JOB_APPLICATION_ID',\n regex: /\\b(?:APPLICATION|CANDIDATE|APPLICANT)[-\\s]?(?:ID|NO|NUM(?:BER)?|REF)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[APPLICATION_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Job application and candidate identifiers',\n validator: (_value: string, context: string) => {\n return /application|candidate|applicant|job|position|recruit|hiring/i.test(context);\n }\n};\n\n/**\n * Resume/CV References\n */\nexport const RESUME_ID: PIIPattern = {\n type: 'RESUME_ID',\n regex: /\\b(?:RESUME|CV|CURRICULUM[-\\s]?VITAE)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RESUME_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Resume and CV identifiers'\n};\n\n/**\n * Benefits Plan Numbers\n */\nexport const BENEFITS_PLAN_NUMBER: PIIPattern = {\n type: 'BENEFITS_PLAN_NUMBER',\n regex: /\\b(?:BENEFITS?|INSURANCE|HEALTH[-\\s]?PLAN)[-\\s]?(?:PLAN)?[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[BENEFITS_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Employee benefits and insurance plan numbers',\n validator: (_value: string, context: string) => {\n return /benefit|insurance|health|dental|vision|plan|policy|enrollment/i.test(context);\n }\n};\n\n/**\n * 401(k) / Retirement Account Numbers\n */\nexport const RETIREMENT_ACCOUNT: PIIPattern = {\n type: 'RETIREMENT_ACCOUNT',\n regex: /\\b(?:401K|403B|IRA|RETIREMENT|PENSION)[-\\s]?(?:ACCOUNT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[RETIREMENT_{n}]',\n priority: 90,\n severity: 'high',\n description: '401(k), IRA, and retirement account numbers',\n validator: (_value: string, context: string) => {\n return /401k|403b|ira|retirement|pension|fund|invest|contribution/i.test(context);\n }\n};\n\n/**\n * Direct Deposit Account References\n */\nexport const DIRECT_DEPOSIT_REF: PIIPattern = {\n type: 'DIRECT_DEPOSIT_REF',\n regex: /\\b(?:DIRECT[-\\s]?DEPOSIT|DD|ROUTING)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*(\\d{9})\\b/g,\n placeholder: '[DD_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Direct deposit and routing numbers',\n validator: (_value: string, context: string) => {\n return /direct[-\\s]?deposit|routing|bank|account|payroll|pay/i.test(context);\n }\n};\n\n/**\n * Background Check IDs\n */\nexport const BACKGROUND_CHECK_ID: PIIPattern = {\n type: 'BACKGROUND_CHECK_ID',\n regex: /\\b(?:BACKGROUND[-\\s]?CHECK|BGC|SCREENING)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[BGC_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Background check and screening identifiers'\n};\n\n/**\n * Drug Test IDs\n */\nexport const DRUG_TEST_ID: PIIPattern = {\n type: 'DRUG_TEST_ID',\n regex: /\\b(?:DRUG[-\\s]?TEST|SCREENING|URINALYSIS)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[DRUG_TEST_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Drug test and screening identifiers',\n validator: (_value: string, context: string) => {\n return /drug|test|screening|urinalysis|specimen|sample/i.test(context);\n }\n};\n\n/**\n * Timesheet/Timecard Numbers\n */\nexport const TIMESHEET_NUMBER: PIIPattern = {\n type: 'TIMESHEET_NUMBER',\n regex: /\\b(?:TIMESHEET|TIMECARD|TIME[-\\s]?ENTRY)[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TIMESHEET_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Timesheet and timecard numbers'\n};\n\n/**\n * Training Certification IDs\n */\nexport const TRAINING_CERT_ID: PIIPattern = {\n type: 'TRAINING_CERT_ID',\n regex: /\\b(?:TRAINING|CERTIFICATION|CERT)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TRAINING_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Training and certification identifiers',\n validator: (_value: string, context: string) => {\n return /training|certification|cert|course|completion|credential/i.test(context);\n }\n};\n\n/**\n * Expense Report Numbers\n */\nexport const EXPENSE_REPORT_NUMBER: PIIPattern = {\n type: 'EXPENSE_REPORT_NUMBER',\n regex: /\\b(?:EXPENSE|REIMBURSEMENT)[-\\s]?(?:REPORT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[EXPENSE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Expense report and reimbursement numbers',\n validator: (_value: string, context: string) => {\n return /expense|reimbursement|travel|claim|receipt/i.test(context);\n }\n};\n\n/**\n * PTO/Leave Request IDs\n */\nexport const LEAVE_REQUEST_ID: PIIPattern = {\n type: 'LEAVE_REQUEST_ID',\n regex: /\\b(?:PTO|LEAVE|VACATION|TIME[-\\s]?OFF)[-\\s]?(?:REQUEST)?[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[LEAVE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Leave request and time-off identifiers',\n validator: (_value: string, context: string) => {\n return /pto|leave|vacation|time[-\\s]?off|absence|sick|personal/i.test(context);\n }\n};\n\n/**\n * Termination/Exit Interview IDs\n */\nexport const EXIT_INTERVIEW_ID: PIIPattern = {\n type: 'EXIT_INTERVIEW_ID',\n regex: /\\b(?:EXIT|TERMINATION|SEPARATION)[-\\s]?(?:INTERVIEW)?[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[EXIT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Exit interview and termination identifiers',\n validator: (_value: string, context: string) => {\n return /exit|termination|separation|offboard|departure|resign/i.test(context);\n }\n};\n\n/**\n * Disciplinary Action IDs\n */\nexport const DISCIPLINARY_ACTION_ID: PIIPattern = {\n type: 'DISCIPLINARY_ACTION_ID',\n regex: /\\b(?:DISCIPLINARY|INCIDENT|WARNING|VIOLATION)[-\\s]?(?:ACTION)?[-\\s]?(?:NO|NUM(?:BER)?|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[DISCIPLINE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Disciplinary action and incident identifiers',\n validator: (_value: string, context: string) => {\n return /disciplinary|incident|warning|violation|misconduct|investigation/i.test(context);\n }\n};\n\n/**\n * Emergency Contact References\n */\nexport const EMERGENCY_CONTACT_REF: PIIPattern = {\n type: 'EMERGENCY_CONTACT_REF',\n regex: /\\b(?:EMERGENCY[-\\s]?CONTACT|ICE)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[EMERGENCY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Emergency contact reference numbers',\n validator: (_value: string, context: string) => {\n return /emergency|contact|ice|next[-\\s]?of[-\\s]?kin/i.test(context);\n }\n};\n\n/**\n * Work Permit/Visa Numbers\n */\nexport const WORK_PERMIT: PIIPattern = {\n type: 'WORK_PERMIT',\n regex: /\\b(?:WORK[-\\s]?PERMIT|VISA|H1B|GREEN[-\\s]?CARD|EAD)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,15})\\b/gi,\n placeholder: '[WORK_PERMIT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Work permits, visas, and immigration documents'\n};\n\n/**\n * Security Clearance Levels\n */\nexport const SECURITY_CLEARANCE: PIIPattern = {\n type: 'SECURITY_CLEARANCE',\n regex: /\\b(?:CLEARANCE|SECURITY[-\\s]?LEVEL)[-\\s]?[:#]?\\s*(TOP[-\\s]?SECRET|SECRET|CONFIDENTIAL|[A-Z]{2,3}\\/SCI)\\b/gi,\n placeholder: '[CLEARANCE_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Security clearance levels and classifications'\n};\n\n/**\n * Recruitment Agency References\n */\nexport const RECRUITER_REF: PIIPattern = {\n type: 'RECRUITER_REF',\n regex: /\\b(?:RECRUITER|AGENCY)[-\\s]?(?:REF|ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RECRUITER_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Recruitment agency reference numbers',\n validator: (_value: string, context: string) => {\n return /recruiter|agency|headhunter|placement|referral/i.test(context);\n }\n};\n\n// Export all HR patterns\nexport const hrPatterns: PIIPattern[] = [\n EMPLOYEE_ID,\n PAYROLL_NUMBER,\n SALARY_AMOUNT,\n PERFORMANCE_REVIEW_ID,\n JOB_APPLICATION_ID,\n RESUME_ID,\n BENEFITS_PLAN_NUMBER,\n RETIREMENT_ACCOUNT,\n DIRECT_DEPOSIT_REF,\n BACKGROUND_CHECK_ID,\n DRUG_TEST_ID,\n TIMESHEET_NUMBER,\n TRAINING_CERT_ID,\n EXPENSE_REPORT_NUMBER,\n LEAVE_REQUEST_ID,\n EXIT_INTERVIEW_ID,\n DISCIPLINARY_ACTION_ID,\n EMERGENCY_CONTACT_REF,\n WORK_PERMIT,\n SECURITY_CLEARANCE,\n RECRUITER_REF\n];\n","/**\n * Insurance and Claims Industry PII Patterns\n * For insurance companies, claims processing, policy management\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Insurance Claim ID\n */\nexport const CLAIM_ID: PIIPattern = {\n type: 'CLAIM_ID',\n regex: /\\bCLAIM[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{8,12})\\b/gi,\n placeholder: '[CLAIM_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Insurance claim identification numbers',\n validator: (_value: string, context: string) => {\n return /claim|insurance|policy|accident|loss|damage|settlement/i.test(context);\n }\n};\n\n/**\n * Insurance Policy Number\n */\nexport const POLICY_NUMBER: PIIPattern = {\n type: 'POLICY_NUMBER',\n regex: /\\bPOLICY[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{2,4}\\d{6,10})\\b/gi,\n placeholder: '[POLICY_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Insurance policy numbers'\n};\n\n/**\n * Policy Holder ID\n */\nexport const POLICY_HOLDER_ID: PIIPattern = {\n type: 'POLICY_HOLDER_ID',\n regex: /\\b(?:POLICY[-\\s]?HOLDER|INSURED|POLICYHOLDER)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9-]{8,14})\\b/gi,\n placeholder: '[HOLDER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Policy holder identification numbers'\n};\n\n/**\n * Insurance Quote Reference\n */\nexport const QUOTE_REFERENCE: PIIPattern = {\n type: 'QUOTE_REFERENCE',\n regex: /\\b(?:QUOTE|QTE)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[QUOTE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Insurance quote reference numbers',\n validator: (_value: string, context: string) => {\n return /quote|quotation|estimate|premium|insurance/i.test(context);\n }\n};\n\n/**\n * Insurance Certificate Number\n */\nexport const INSURANCE_CERTIFICATE: PIIPattern = {\n type: 'INSURANCE_CERTIFICATE',\n regex: /\\b(?:CERTIFICATE|CERT)[-\\s]?(?:OF[-\\s]?INSURANCE)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[CERT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Insurance certificate numbers',\n validator: (_value: string, context: string) => {\n return /certificate|insurance|coverage|proof/i.test(context);\n }\n};\n\n/**\n * Adjuster ID\n */\nexport const ADJUSTER_ID: PIIPattern = {\n type: 'ADJUSTER_ID',\n regex: /\\b(?:ADJUSTER|ADJ)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ADJUSTER_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Insurance adjuster identification numbers',\n validator: (_value: string, context: string) => {\n return /adjuster|claims|inspector|evaluator/i.test(context);\n }\n};\n\n/**\n * Underwriter ID\n */\nexport const UNDERWRITER_ID: PIIPattern = {\n type: 'UNDERWRITER_ID',\n regex: /\\b(?:UNDERWRITER|UW)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[UW_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Insurance underwriter identification numbers',\n validator: (_value: string, context: string) => {\n return /underwriter|underwriting|policy|risk|assessment/i.test(context);\n }\n};\n\n/**\n * Incident Report Number\n */\nexport const INCIDENT_REPORT_NUMBER: PIIPattern = {\n type: 'INCIDENT_REPORT_NUMBER',\n regex: /\\b(?:INCIDENT|ACCIDENT)[-\\s]?(?:REPORT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[INCIDENT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Incident and accident report numbers',\n validator: (_value: string, context: string) => {\n return /incident|accident|report|event|occurrence|loss/i.test(context);\n }\n};\n\n/**\n * Premium Payment Reference\n */\nexport const PREMIUM_PAYMENT_REF: PIIPattern = {\n type: 'PREMIUM_PAYMENT_REF',\n regex: /\\b(?:PREMIUM)[-\\s]?(?:PAYMENT)?[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[PREMIUM_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Premium payment reference numbers'\n};\n\n/**\n * Reinsurance Treaty Number\n */\nexport const REINSURANCE_TREATY: PIIPattern = {\n type: 'REINSURANCE_TREATY',\n regex: /\\b(?:REINSURANCE|TREATY)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[TREATY_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Reinsurance treaty numbers',\n validator: (_value: string, context: string) => {\n return /reinsurance|treaty|cession|facultative/i.test(context);\n }\n};\n\n// Export all insurance patterns\nexport const insurancePatterns: PIIPattern[] = [\n CLAIM_ID,\n POLICY_NUMBER,\n POLICY_HOLDER_ID,\n QUOTE_REFERENCE,\n INSURANCE_CERTIFICATE,\n ADJUSTER_ID,\n UNDERWRITER_ID,\n INCIDENT_REPORT_NUMBER,\n PREMIUM_PAYMENT_REF,\n REINSURANCE_TREATY\n];\n","/**\n * Retail and E-Commerce Industry PII Patterns\n * For online/offline retail, order management, customer loyalty programs\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Order Number\n */\nexport const ORDER_NUMBER: PIIPattern = {\n type: 'ORDER_NUMBER',\n regex: /\\b(?:ORD(?:ER)?[-\\s](?:NO|NUM(?:BER)?)?[-\\s:#]?\\s*|ORDER\\s+(?:NO|NUM(?:BER)?)?[:\\s]+)([A-Z0-9-]{8,14})\\b/gi,\n placeholder: '[ORDER_{n}]',\n priority: 90, // Higher priority than phones (85) to match \"ORD-1234567890\" correctly\n severity: 'medium',\n description: 'E-commerce order numbers',\n validator: (value: string, _context: string) => {\n // Must contain at least one digit\n return /\\d/.test(value);\n }\n};\n\n/**\n * Loyalty Card Number\n */\nexport const LOYALTY_CARD_NUMBER: PIIPattern = {\n type: 'LOYALTY_CARD_NUMBER',\n regex: /\\bLOYALTY[-\\s]?(?:CARD)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{10,16})\\b/gi,\n placeholder: '[LOYALTY_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Customer loyalty card numbers',\n validator: (_value: string, context: string) => {\n return /loyalty|rewards|points|membership|customer/i.test(context);\n }\n};\n\n/**\n * Customer ID\n */\nexport const CUSTOMER_ID: PIIPattern = {\n type: 'CUSTOMER_ID',\n regex: /\\b(?:CUSTOMER|CUST)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[CUSTOMER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Customer identification numbers',\n validator: (_value: string, context: string) => {\n return /customer|account|profile|user|buyer/i.test(context);\n }\n};\n\n/**\n * Device ID/Tag (for inventory or customer devices)\n */\nexport const DEVICE_ID_TAG: PIIPattern = {\n type: 'DEVICE_ID_TAG',\n regex: /\\bDEVID:([A-F0-9]{16})\\b/gi,\n placeholder: '[DEVICE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Device identification tags'\n};\n\n/**\n * Gift Card Numbers\n */\nexport const GIFT_CARD_NUMBER: PIIPattern = {\n type: 'GIFT_CARD_NUMBER',\n regex: /\\b(?:GIFT[-\\s]?CARD|GC)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{12,19})\\b/gi,\n placeholder: '[GIFTCARD_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Gift card numbers',\n validator: (_value: string, context: string) => {\n return /gift|card|voucher|coupon|certificate/i.test(context);\n }\n};\n\n/**\n * Return/RMA Number\n */\nexport const RMA_NUMBER: PIIPattern = {\n type: 'RMA_NUMBER',\n regex: /\\b(?:RMA|RETURN)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[RMA_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Return merchandise authorization numbers',\n validator: (_value: string, context: string) => {\n return /rma|return|refund|exchange|merchandise/i.test(context);\n }\n};\n\n/**\n * Shipping Tracking Number\n */\nexport const SHIPPING_TRACKING: PIIPattern = {\n type: 'SHIPPING_TRACKING',\n regex: /\\b(?:TRACKING|TRACK)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,30})\\b/gi,\n placeholder: '[TRACKING_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Shipping and delivery tracking numbers',\n validator: (_value: string, context: string) => {\n return /tracking|shipment|delivery|package|parcel|courier/i.test(context);\n }\n};\n\n/**\n * Invoice Number\n */\nexport const INVOICE_NUMBER: PIIPattern = {\n type: 'INVOICE_NUMBER',\n regex: /\\b(?:INVOICE|INV)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[INVOICE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Invoice numbers',\n validator: (_value: string, context: string) => {\n return /invoice|bill|payment|receipt|purchase/i.test(context);\n }\n};\n\n/**\n * Shopping Cart Session ID\n */\nexport const CART_SESSION_ID: PIIPattern = {\n type: 'CART_SESSION_ID',\n regex: /\\b(?:CART|SESSION)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([a-f0-9]{32,64})\\b/gi,\n placeholder: '[CART_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Shopping cart session identifiers',\n validator: (_value: string, context: string) => {\n return /cart|session|basket|checkout/i.test(context);\n }\n};\n\n/**\n * Coupon/Promo Code\n */\nexport const PROMO_CODE: PIIPattern = {\n type: 'PROMO_CODE',\n regex: /\\b(?:PROMO|COUPON|DISCOUNT)[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[PROMO_{n}]',\n priority: 65,\n severity: 'low',\n description: 'Promotional and coupon codes',\n validator: (_value: string, context: string) => {\n return /promo|coupon|discount|code|voucher|offer/i.test(context);\n }\n};\n\n/**\n * Wishlist ID\n */\nexport const WISHLIST_ID: PIIPattern = {\n type: 'WISHLIST_ID',\n regex: /\\b(?:WISHLIST|WISH[-\\s]?LIST)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[WISHLIST_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Customer wishlist identifiers',\n validator: (_value: string, context: string) => {\n return /wishlist|wish|list|saved|favorite/i.test(context);\n }\n};\n\n/**\n * Product SKU (when combined with customer data)\n */\nexport const PRODUCT_SKU: PIIPattern = {\n type: 'PRODUCT_SKU',\n regex: /\\bSKU[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[SKU_{n}]',\n priority: 60,\n severity: 'low',\n description: 'Product stock keeping units'\n};\n\n// Export all retail patterns\nexport const retailPatterns: PIIPattern[] = [\n ORDER_NUMBER,\n LOYALTY_CARD_NUMBER,\n CUSTOMER_ID,\n DEVICE_ID_TAG,\n GIFT_CARD_NUMBER,\n RMA_NUMBER,\n SHIPPING_TRACKING,\n INVOICE_NUMBER,\n CART_SESSION_ID,\n PROMO_CODE,\n WISHLIST_ID,\n PRODUCT_SKU\n];\n","/**\n * Telecommunications and Utilities Industry PII Patterns\n * For telecom providers, utilities, energy companies\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Customer Account Number\n */\nexport const TELECOMS_ACCOUNT_NUMBER: PIIPattern = {\n type: 'TELECOMS_ACCOUNT_NUMBER',\n regex: /\\bACC(?:OUNT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{8,12})\\b/gi,\n placeholder: '[ACCOUNT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Telecommunications customer account numbers',\n validator: (_value: string, context: string) => {\n return /account|customer|subscriber|service|utility|telecom/i.test(context);\n }\n};\n\n/**\n * Meter Serial Number\n */\nexport const METER_SERIAL_NUMBER: PIIPattern = {\n type: 'METER_SERIAL_NUMBER',\n regex: /\\bMTR[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{8,12})\\b/gi,\n placeholder: '[METER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Utility meter serial numbers'\n};\n\n/**\n * SIM/IMSI Number\n */\nexport const IMSI_NUMBER: PIIPattern = {\n type: 'IMSI_NUMBER',\n regex: /\\bIMSI[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{15})\\b/gi,\n placeholder: '[IMSI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'International Mobile Subscriber Identity numbers'\n};\n\n/**\n * IMEI (International Mobile Equipment Identity)\n */\nexport const IMEI_NUMBER: PIIPattern = {\n type: 'IMEI_NUMBER',\n regex: /\\bIMEI[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{15})\\b/gi,\n placeholder: '[IMEI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'International Mobile Equipment Identity numbers'\n};\n\n/**\n * SIM Card Number\n */\nexport const SIM_CARD_NUMBER: PIIPattern = {\n type: 'SIM_CARD_NUMBER',\n regex: /\\bSIM[-\\s]?(?:CARD)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{19,20})\\b/gi,\n placeholder: '[SIM_{n}]',\n priority: 85,\n severity: 'high',\n description: 'SIM card identification numbers',\n validator: (_value: string, context: string) => {\n return /sim|card|mobile|cellular|phone/i.test(context);\n }\n};\n\n/**\n * Service Request Number\n */\nexport const SERVICE_REQUEST_NUMBER: PIIPattern = {\n type: 'SERVICE_REQUEST_NUMBER',\n regex: /\\b(?:SERVICE|SR)[-\\s]?(?:REQUEST)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[SERVICE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Service request and ticket numbers',\n validator: (_value: string, context: string) => {\n return /service|request|ticket|support|maintenance|repair/i.test(context);\n }\n};\n\n/**\n * Utility Bill Account Number\n */\nexport const UTILITY_BILL_ACCOUNT: PIIPattern = {\n type: 'UTILITY_BILL_ACCOUNT',\n regex: /\\b(?:BILL|BILLING)[-\\s]?(?:ACCOUNT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{8,14})\\b/gi,\n placeholder: '[BILL_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Utility billing account numbers',\n validator: (_value: string, context: string) => {\n return /bill|billing|utility|electric|gas|water|energy/i.test(context);\n }\n};\n\n/**\n * Installation Reference Number\n */\nexport const INSTALLATION_REF: PIIPattern = {\n type: 'INSTALLATION_REF',\n regex: /\\b(?:INSTALLATION|INSTALL)[-\\s]?(?:REF(?:ERENCE)?|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[INSTALL_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Installation reference numbers',\n validator: (_value: string, context: string) => {\n return /installation|install|setup|deployment|activation/i.test(context);\n }\n};\n\n/**\n * Phone Line Number (masked format)\n */\nexport const PHONE_LINE_NUMBER: PIIPattern = {\n type: 'PHONE_LINE_NUMBER',\n regex: /\\b(?:LINE|NUMBER)[-\\s]?(?:NO)?[-\\s]?[:#]?\\s*(\\d{3}[-\\s]?\\d{3}[-\\s]?\\d{4})\\b/g,\n placeholder: '[PHONE_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Phone line numbers',\n validator: (_value: string, context: string) => {\n return /phone|line|number|mobile|landline|telephone/i.test(context);\n }\n};\n\n/**\n * Broadband/Internet Service ID\n */\nexport const BROADBAND_SERVICE_ID: PIIPattern = {\n type: 'BROADBAND_SERVICE_ID',\n regex: /\\b(?:BROADBAND|INTERNET|ISP)[-\\s]?(?:SERVICE)?[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[BROADBAND_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Broadband and internet service identifiers',\n validator: (_value: string, context: string) => {\n return /broadband|internet|isp|connection|service/i.test(context);\n }\n};\n\n/**\n * Equipment Serial Number (routers, modems, etc.)\n */\nexport const EQUIPMENT_SERIAL: PIIPattern = {\n type: 'EQUIPMENT_SERIAL',\n regex: /\\b(?:EQUIPMENT|DEVICE|ROUTER|MODEM)[-\\s]?(?:SERIAL)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,16})\\b/gi,\n placeholder: '[EQUIPMENT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Equipment and device serial numbers',\n validator: (_value: string, context: string) => {\n return /equipment|device|router|modem|serial|hardware/i.test(context);\n }\n};\n\n/**\n * Smart Meter ID\n */\nexport const SMART_METER_ID: PIIPattern = {\n type: 'SMART_METER_ID',\n regex: /\\b(?:SMART[-\\s]?METER)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,16})\\b/gi,\n placeholder: '[SMART_METER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Smart meter identification numbers',\n validator: (_value: string, context: string) => {\n return /smart|meter|energy|electric|gas|monitoring/i.test(context);\n }\n};\n\n// Export all telecoms patterns\nexport const telecomsPatterns: PIIPattern[] = [\n TELECOMS_ACCOUNT_NUMBER,\n METER_SERIAL_NUMBER,\n IMSI_NUMBER,\n IMEI_NUMBER,\n SIM_CARD_NUMBER,\n SERVICE_REQUEST_NUMBER,\n UTILITY_BILL_ACCOUNT,\n INSTALLATION_REF,\n PHONE_LINE_NUMBER,\n BROADBAND_SERVICE_ID,\n EQUIPMENT_SERIAL,\n SMART_METER_ID\n];\n","/**\n * Manufacturing and Supply Chain Industry PII Patterns\n * For manufacturers, suppliers, logistics, inventory management\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Supplier ID\n */\nexport const SUPPLIER_ID: PIIPattern = {\n type: 'SUPPLIER_ID',\n regex: /\\bSUPP(?:LIER)?[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{2}\\d{5,8})\\b/gi,\n placeholder: '[SUPPLIER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Supplier identification numbers'\n};\n\n/**\n * Part Number (with potentially sensitive pricing)\n */\nexport const PART_NUMBER: PIIPattern = {\n type: 'PART_NUMBER',\n regex: /\\bP(?:ART)?N[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([0-9A-Z]{6,12})\\b/gi,\n placeholder: '[PART_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Part numbers and component identifiers',\n validator: (_value: string, context: string) => {\n return /part|component|item|sku|product|inventory/i.test(context);\n }\n};\n\n/**\n * Purchase Order Number\n */\nexport const PURCHASE_ORDER_NUMBER: PIIPattern = {\n type: 'PURCHASE_ORDER_NUMBER',\n regex: /\\bP(?:URCHASE[-\\s]?)?O(?:RDER)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[PO_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Purchase order numbers'\n};\n\n/**\n * Work Order Number\n */\nexport const WORK_ORDER_NUMBER: PIIPattern = {\n type: 'WORK_ORDER_NUMBER',\n regex: /\\bW(?:ORK[-\\s]?)?O(?:RDER)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[WO_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Work order numbers',\n validator: (_value: string, context: string) => {\n return /work|order|job|task|production/i.test(context);\n }\n};\n\n/**\n * Batch/Lot Number\n */\nexport const BATCH_LOT_NUMBER: PIIPattern = {\n type: 'BATCH_LOT_NUMBER',\n regex: /\\b(?:BATCH|LOT)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[BATCH_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Batch and lot numbers for manufacturing traceability',\n validator: (_value: string, context: string) => {\n return /batch|lot|production|manufacturing|quality/i.test(context);\n }\n};\n\n/**\n * Serial Number (product/component)\n */\nexport const MANUFACTURING_SERIAL: PIIPattern = {\n type: 'MANUFACTURING_SERIAL',\n regex: /\\b(?:SERIAL|SN)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[SERIAL_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Product and component serial numbers',\n validator: (_value: string, context: string) => {\n return /serial|sn|product|device|unit|item/i.test(context);\n }\n};\n\n/**\n * Vendor Code\n */\nexport const VENDOR_CODE: PIIPattern = {\n type: 'VENDOR_CODE',\n regex: /\\bVEND(?:OR)?[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{4,10})\\b/gi,\n placeholder: '[VENDOR_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Vendor codes and identifiers',\n validator: (_value: string, context: string) => {\n return /vendor|supplier|partner|contractor/i.test(context);\n }\n};\n\n/**\n * Bill of Materials (BOM) Number\n */\nexport const BOM_NUMBER: PIIPattern = {\n type: 'BOM_NUMBER',\n regex: /\\bBOM[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[BOM_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Bill of materials numbers',\n validator: (_value: string, context: string) => {\n return /bom|bill|materials|assembly|component/i.test(context);\n }\n};\n\n/**\n * Quality Control Certificate Number\n */\nexport const QC_CERTIFICATE_NUMBER: PIIPattern = {\n type: 'QC_CERTIFICATE_NUMBER',\n regex: /\\b(?:QC|QUALITY)[-\\s]?(?:CERT(?:IFICATE)?)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[QC_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Quality control certificate numbers',\n validator: (_value: string, context: string) => {\n return /quality|qc|certificate|inspection|test|compliance/i.test(context);\n }\n};\n\n/**\n * Shipping Container Number\n */\nexport const CONTAINER_NUMBER: PIIPattern = {\n type: 'CONTAINER_NUMBER',\n regex: /\\b(?:CONTAINER|CNTR)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{4}\\d{7})\\b/gi,\n placeholder: '[CONTAINER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Shipping container numbers (ISO 6346 format)',\n validator: (value: string) => {\n // ISO 6346: 4 letters + 7 digits\n return /^[A-Z]{4}\\d{7}$/.test(value);\n }\n};\n\n/**\n * Pallet ID\n */\nexport const PALLET_ID: PIIPattern = {\n type: 'PALLET_ID',\n regex: /\\bPALLET[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[PALLET_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Pallet identification numbers',\n validator: (_value: string, context: string) => {\n return /pallet|shipping|warehouse|logistics/i.test(context);\n }\n};\n\n/**\n * Manufacturing Routing Number\n */\nexport const ROUTING_NUMBER_MFG: PIIPattern = {\n type: 'ROUTING_NUMBER_MFG',\n regex: /\\bROUTING[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ROUTING_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Manufacturing routing numbers',\n validator: (_value: string, context: string) => {\n return /routing|manufacturing|process|production|workflow/i.test(context);\n }\n};\n\n/**\n * RFQ (Request for Quote) Number\n */\nexport const RFQ_NUMBER: PIIPattern = {\n type: 'RFQ_NUMBER',\n regex: /\\bRFQ[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RFQ_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Request for quote numbers',\n validator: (_value: string, context: string) => {\n return /rfq|quote|quotation|request|procurement/i.test(context);\n }\n};\n\n/**\n * Project Code (internal)\n */\nexport const PROJECT_CODE: PIIPattern = {\n type: 'PROJECT_CODE',\n regex: /\\b(?:PROJECT|PROJ)[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{4,10})\\b/gi,\n placeholder: '[PROJECT_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Internal project codes',\n validator: (_value: string, context: string) => {\n return /project|proj|initiative|program/i.test(context);\n }\n};\n\n// Export all manufacturing patterns\nexport const manufacturingPatterns: PIIPattern[] = [\n SUPPLIER_ID,\n PART_NUMBER,\n PURCHASE_ORDER_NUMBER,\n WORK_ORDER_NUMBER,\n BATCH_LOT_NUMBER,\n MANUFACTURING_SERIAL,\n VENDOR_CODE,\n BOM_NUMBER,\n QC_CERTIFICATE_NUMBER,\n CONTAINER_NUMBER,\n PALLET_ID,\n ROUTING_NUMBER_MFG,\n RFQ_NUMBER,\n PROJECT_CODE\n];\n","/**\n * Transportation and Automotive Industry PII Patterns\n * For automotive, logistics, transportation services\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Vehicle Identification Number (VIN)\n * 17-character alphanumeric code (excludes I, O, Q)\n */\nexport const VIN: PIIPattern = {\n type: 'VIN',\n regex: /\\bVIN[-\\s]?[:#]?\\s*([A-HJ-NPR-Z0-9]{17})\\b/gi,\n placeholder: '[VIN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Vehicle Identification Number',\n validator: (value: string) => {\n // VIN is exactly 17 characters, excludes I, O, Q\n return value.length === 17 && /^[A-HJ-NPR-Z0-9]{17}$/.test(value);\n }\n};\n\n/**\n * License Plate Number\n */\nexport const LICENSE_PLATE: PIIPattern = {\n type: 'LICENSE_PLATE',\n regex: /\\b(?:LICENSE|PLATE|REG(?:ISTRATION)?)[-\\s]?(?:NO|NUM(?:BER)?|PLATE)?[-\\s]?[:#]?\\s*([A-Z0-9]{2,8})\\b/gi,\n placeholder: '[PLATE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Vehicle license plate numbers',\n validator: (_value: string, context: string) => {\n return /license|plate|registration|vehicle|car|auto/i.test(context);\n }\n};\n\n/**\n * Fleet Vehicle ID\n */\nexport const FLEET_VEHICLE_ID: PIIPattern = {\n type: 'FLEET_VEHICLE_ID',\n regex: /\\b(?:FLEET|VEHICLE)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[FLEET_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Fleet vehicle identification numbers',\n validator: (_value: string, context: string) => {\n return /fleet|vehicle|car|truck|van|unit/i.test(context);\n }\n};\n\n/**\n * Telematics Device ID\n */\nexport const TELEMATICS_DEVICE_ID: PIIPattern = {\n type: 'TELEMATICS_DEVICE_ID',\n regex: /\\b(?:TELEMATICS|GPS[-\\s]?DEVICE)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,16})\\b/gi,\n placeholder: '[TELEMATICS_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Telematics and GPS device identifiers',\n validator: (_value: string, context: string) => {\n return /telematics|gps|tracking|device|monitor/i.test(context);\n }\n};\n\n/**\n * Booking/Reservation Number\n */\nexport const BOOKING_NUMBER: PIIPattern = {\n type: 'BOOKING_NUMBER',\n regex: /\\b(?:BOOKING|RESERVATION|RES)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[BOOKING_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Transportation booking and reservation numbers',\n validator: (_value: string, context: string) => {\n return /booking|reservation|ticket|travel|flight|train|bus/i.test(context);\n }\n};\n\n/**\n * Driver ID\n */\nexport const DRIVER_ID: PIIPattern = {\n type: 'DRIVER_ID',\n regex: /\\bDRIVER[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[DRIVER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Driver identification numbers',\n validator: (_value: string, context: string) => {\n return /driver|operator|chauffeur/i.test(context);\n }\n};\n\n/**\n * Shipment Tracking Number\n */\nexport const SHIPMENT_TRACKING: PIIPattern = {\n type: 'SHIPMENT_TRACKING',\n regex: /\\b(?:SHIPMENT|TRACKING)[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,30})\\b/gi,\n placeholder: '[SHIPMENT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Shipment tracking numbers',\n validator: (_value: string, context: string) => {\n return /shipment|tracking|delivery|freight|cargo/i.test(context);\n }\n};\n\n/**\n * Toll Tag/Transponder ID\n */\nexport const TOLL_TAG_ID: PIIPattern = {\n type: 'TOLL_TAG_ID',\n regex: /\\b(?:TOLL[-\\s]?TAG|E[-]?ZPASS|TRANSPONDER)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[TOLL_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Toll tag and transponder identifiers',\n validator: (_value: string, context: string) => {\n return /toll|tag|ezpass|transponder|fastrak/i.test(context);\n }\n};\n\n/**\n * Inspection Certificate Number\n */\nexport const INSPECTION_CERTIFICATE: PIIPattern = {\n type: 'INSPECTION_CERTIFICATE',\n regex: /\\b(?:INSPECTION|INSP)[-\\s]?(?:CERT(?:IFICATE)?)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[INSPECTION_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Vehicle inspection certificate numbers',\n validator: (_value: string, context: string) => {\n return /inspection|certificate|safety|emissions|test/i.test(context);\n }\n};\n\n/**\n * Odometer Reading Reference\n */\nexport const ODOMETER_READING_REF: PIIPattern = {\n type: 'ODOMETER_READING_REF',\n regex: /\\b(?:ODOMETER|MILEAGE)[-\\s]?[:#]?\\s*(\\d{1,7})\\s*(?:KM|MILES|MI)\\b/gi,\n placeholder: '[ODO_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Odometer readings',\n validator: (_value: string, context: string) => {\n return /odometer|mileage|miles|km|reading/i.test(context);\n }\n};\n\n/**\n * Insurance Policy Number (vehicle-specific)\n */\nexport const VEHICLE_INSURANCE_POLICY: PIIPattern = {\n type: 'VEHICLE_INSURANCE_POLICY',\n regex: /\\b(?:AUTO|VEHICLE|CAR)[-\\s]?(?:INSURANCE)?[-\\s]?(?:POLICY)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{2,4}\\d{6,10})\\b/gi,\n placeholder: '[AUTO_POLICY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Vehicle insurance policy numbers',\n validator: (_value: string, context: string) => {\n return /auto|vehicle|car|insurance|policy|coverage/i.test(context);\n }\n};\n\n/**\n * Taxi/Rideshare Trip ID\n */\nexport const TRIP_ID: PIIPattern = {\n type: 'TRIP_ID',\n regex: /\\b(?:TRIP|RIDE)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[TRIP_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Trip and ride identification numbers',\n validator: (_value: string, context: string) => {\n return /trip|ride|journey|fare|taxi|uber|lyft/i.test(context);\n }\n};\n\n// Export all transportation patterns\nexport const transportationPatterns: PIIPattern[] = [\n VIN,\n LICENSE_PLATE,\n FLEET_VEHICLE_ID,\n TELEMATICS_DEVICE_ID,\n BOOKING_NUMBER,\n DRIVER_ID,\n SHIPMENT_TRACKING,\n TOLL_TAG_ID,\n INSPECTION_CERTIFICATE,\n ODOMETER_READING_REF,\n VEHICLE_INSURANCE_POLICY,\n TRIP_ID\n];\n","/**\n * Media and Publishing Industry PII Patterns\n * For journalism, publishing, content creation, media companies\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Interviewee ID\n */\nexport const INTERVIEWEE_ID: PIIPattern = {\n type: 'INTERVIEWEE_ID',\n regex: /\\bINTV[-\\s]?([A-Z]{1}\\d{5})\\b/gi,\n placeholder: '[INTERVIEWEE_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Interviewee identification numbers for anonymity'\n};\n\n/**\n * Source ID (confidential sources)\n */\nexport const SOURCE_ID: PIIPattern = {\n type: 'SOURCE_ID',\n regex: /\\bSOURCE[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[SOURCE_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Confidential source identifiers',\n validator: (_value: string, context: string) => {\n return /source|informant|confidential|anonymous|whistleblower/i.test(context);\n }\n};\n\n/**\n * Article/Story ID\n */\nexport const ARTICLE_ID: PIIPattern = {\n type: 'ARTICLE_ID',\n regex: /\\b(?:ARTICLE|STORY)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ARTICLE_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Article and story identification numbers',\n validator: (_value: string, context: string) => {\n return /article|story|piece|content|publication/i.test(context);\n }\n};\n\n/**\n * Manuscript ID\n */\nexport const MANUSCRIPT_ID: PIIPattern = {\n type: 'MANUSCRIPT_ID',\n regex: /\\b(?:MANUSCRIPT|MS)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[MANUSCRIPT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Manuscript identification numbers',\n validator: (_value: string, context: string) => {\n return /manuscript|ms|draft|submission|review/i.test(context);\n }\n};\n\n/**\n * Press Pass ID\n */\nexport const PRESS_PASS_ID: PIIPattern = {\n type: 'PRESS_PASS_ID',\n regex: /\\b(?:PRESS[-\\s]?PASS|MEDIA[-\\s]?CREDENTIAL)[-\\s]?(?:ID|NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PRESS_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Press pass and media credential numbers',\n validator: (_value: string, context: string) => {\n return /press|media|credential|pass|journalist|reporter/i.test(context);\n }\n};\n\n/**\n * Contributor/Freelancer ID\n */\nexport const CONTRIBUTOR_ID: PIIPattern = {\n type: 'CONTRIBUTOR_ID',\n regex: /\\b(?:CONTRIBUTOR|FREELANCER|WRITER)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[CONTRIBUTOR_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Contributor and freelancer identification numbers',\n validator: (_value: string, context: string) => {\n return /contributor|freelancer|writer|author|journalist/i.test(context);\n }\n};\n\n/**\n * Publishing Contract Number\n */\nexport const PUBLISHING_CONTRACT: PIIPattern = {\n type: 'PUBLISHING_CONTRACT',\n regex: /\\b(?:PUBLISHING|PUB)[-\\s]?(?:CONTRACT)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[PUB_CONTRACT_{n}]',\n priority: 80,\n severity: 'high',\n description: 'Publishing contract numbers',\n validator: (_value: string, context: string) => {\n return /publishing|contract|agreement|deal|rights/i.test(context);\n }\n};\n\n/**\n * Editorial Ticket/Task ID\n */\nexport const EDITORIAL_TICKET: PIIPattern = {\n type: 'EDITORIAL_TICKET',\n regex: /\\b(?:EDITORIAL|EDIT)[-\\s]?(?:TICKET|TASK)?[-\\s]?(?:ID|NO)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[EDIT_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Editorial ticket and task identifiers',\n validator: (_value: string, context: string) => {\n return /editorial|edit|task|ticket|assignment/i.test(context);\n }\n};\n\n/**\n * Subscriber ID\n */\nexport const SUBSCRIBER_ID: PIIPattern = {\n type: 'SUBSCRIBER_ID',\n regex: /\\bSUBSCRIBER[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[SUBSCRIBER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Subscriber identification numbers',\n validator: (_value: string, context: string) => {\n return /subscriber|subscription|member|account|reader/i.test(context);\n }\n};\n\n/**\n * ISBN (International Standard Book Number)\n */\nexport const ISBN: PIIPattern = {\n type: 'ISBN',\n regex: /\\bISBN[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*(\\d{3}[-\\s]?\\d{1,5}[-\\s]?\\d{1,7}[-\\s]?\\d{1,7}[-\\s]?\\d{1})\\b/gi,\n placeholder: '[ISBN_{n}]',\n priority: 65,\n severity: 'low',\n description: 'International Standard Book Numbers'\n};\n\n/**\n * Copyright Registration Number\n */\nexport const COPYRIGHT_REG: PIIPattern = {\n type: 'COPYRIGHT_REG',\n regex: /\\b(?:COPYRIGHT|©)[-\\s]?(?:REG(?:ISTRATION)?)?[-\\s]?(?:NO|NUM(?:BER)?)?[-\\s]?[:#]?\\s*([A-Z]{2,3}\\d{6,10})\\b/gi,\n placeholder: '[COPYRIGHT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Copyright registration numbers',\n validator: (_value: string, context: string) => {\n return /copyright|registration|intellectual|property|rights/i.test(context);\n }\n};\n\n/**\n * Production ID (film/video)\n */\nexport const PRODUCTION_ID: PIIPattern = {\n type: 'PRODUCTION_ID',\n regex: /\\b(?:PRODUCTION|PROD)[-\\s]?(?:ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PRODUCTION_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Film and video production identifiers',\n validator: (_value: string, context: string) => {\n return /production|film|video|shoot|project/i.test(context);\n }\n};\n\n// Export all media patterns\nexport const mediaPatterns: PIIPattern[] = [\n INTERVIEWEE_ID,\n SOURCE_ID,\n ARTICLE_ID,\n MANUSCRIPT_ID,\n PRESS_PASS_ID,\n CONTRIBUTOR_ID,\n PUBLISHING_CONTRACT,\n EDITORIAL_TICKET,\n SUBSCRIBER_ID,\n ISBN,\n COPYRIGHT_REG,\n PRODUCTION_ID\n];\n","/**\n * Charitable Sector & Non-Profit Organization Patterns\n * Detects identifiers commonly used in charities, NGOs, and non-profit organizations\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Donor ID - Unique identifier for charitable donors\n * Format: DONOR-XXXXXX, D-XXXXXX, DON-XXXXXX\n * Priority: 85 (High - donor privacy is critical)\n */\nexport const DONOR_ID: PIIPattern = {\n type: 'DONOR_ID',\n regex: /\\b(?:DONOR|DON|D)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[DONOR_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Charitable donor identification numbers',\n validator: (_value: string, context: string) => {\n return /donor|donation|charitable|contribution|gift|philanthrop/i.test(context);\n }\n};\n\n/**\n * Donation Reference Number\n * Format: DN-XXXXXX, DONATION-XXXXXX, GIFT-XXXXXX\n * Priority: 80\n */\nexport const DONATION_REFERENCE: PIIPattern = {\n type: 'DONATION_REFERENCE',\n regex: /\\b(?:DONATION|DN|GIFT|CONTRIB)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[DONATION_REF_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Donation and contribution reference numbers'\n};\n\n/**\n * UK Charity Registration Number\n * Format: XXXXXXX (7 digits) or XXXXXXX-X (7 digits + check digit)\n * Priority: 75\n */\nexport const UK_CHARITY_NUMBER: PIIPattern = {\n type: 'UK_CHARITY_NUMBER',\n regex: /\\b(?:Charity\\s+(?:No|Number|Registration|Reg)\\.?\\s*:?\\s*)?(\\d{6,7}(?:-\\d)?)\\b/gi,\n placeholder: '[UK_CHARITY_{n}]',\n priority: 75,\n severity: 'low',\n description: 'UK charity registration numbers',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n return digits.length >= 6 && digits.length <= 8 && /charity|charitable|commission/i.test(context);\n }\n};\n\n/**\n * US EIN (Employer Identification Number) - Used by US charities/non-profits\n * Format: XX-XXXXXXX\n * Priority: 90\n */\nexport const US_EIN: PIIPattern = {\n type: 'US_EIN',\n regex: /\\b(?:EIN|Tax\\s+ID|Federal\\s+Tax\\s+ID)\\.?\\s*:?\\s*(\\d{2}-\\d{7})\\b/gi,\n placeholder: '[EIN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'US Employer Identification Numbers (nonprofit tax IDs)',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n return digits.length === 9 && /nonprofit|charity|501\\(c\\)|tax[-\\s]exempt|foundation/i.test(context);\n }\n};\n\n/**\n * Grant Reference Number\n * Format: GR-XXXXXX, GRANT-XXXXXX, G-XXXXXX\n * Priority: 75\n */\nexport const GRANT_REFERENCE: PIIPattern = {\n type: 'GRANT_REFERENCE',\n regex: /\\b(?:GRANT|GR|G)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[GRANT_REF_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Grant and funding reference numbers',\n validator: (_value: string, context: string) => {\n return /grant|funding|award|endowment|foundation/i.test(context);\n }\n};\n\n/**\n * Beneficiary ID - Identifier for aid/service recipients\n * Format: BEN-XXXXXX, BENEF-XXXXXX, B-XXXXXX\n * Priority: 90 (High - beneficiary privacy is critical)\n */\nexport const BENEFICIARY_ID: PIIPattern = {\n type: 'BENEFICIARY_ID',\n regex: /\\b(?:BENEFICIARY|BENEF|BEN|B)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[BENEFICIARY_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Charitable beneficiary identification numbers',\n validator: (_value: string, context: string) => {\n return /beneficiary|recipient|aid|assistance|service\\s+user/i.test(context);\n }\n};\n\n/**\n * Fundraising Campaign Code\n * Format: CAMP-XXXX, FC-XXXX, CAMPAIGN-XXXX\n * Priority: 60\n */\nexport const CAMPAIGN_CODE: PIIPattern = {\n type: 'CAMPAIGN_CODE',\n regex: /\\b(?:CAMPAIGN|CAMP|FC)[-_]?[A-Z0-9]{4,12}\\b/gi,\n placeholder: '[CAMPAIGN_{n}]',\n priority: 60,\n severity: 'low',\n description: 'Fundraising campaign reference codes'\n};\n\n/**\n * UK Gift Aid Declaration Reference\n * Format: GA-XXXXXX, GIFTAID-XXXXXX\n * Priority: 80\n */\nexport const GIFT_AID_REFERENCE: PIIPattern = {\n type: 'GIFT_AID_REFERENCE',\n regex: /\\b(?:GIFT\\s*AID|GA)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[GIFT_AID_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'UK Gift Aid declaration reference numbers',\n validator: (_value: string, context: string) => {\n return /gift\\s*aid|tax\\s+relief|declaration/i.test(context);\n }\n};\n\n/**\n * Volunteer ID\n * Format: VOL-XXXXXX, V-XXXXXX\n * Priority: 75\n */\nexport const VOLUNTEER_ID: PIIPattern = {\n type: 'VOLUNTEER_ID',\n regex: /\\b(?:VOLUNTEER|VOL|V)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[VOLUNTEER_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Volunteer identification numbers',\n validator: (_value: string, context: string) => {\n return /volunteer|volunteering|community\\s+service/i.test(context);\n }\n};\n\n/**\n * Membership Number (Charity/Association)\n * Format: MEM-XXXXXX, MEMBER-XXXXXX, M-XXXXXX\n * Priority: 70\n */\nexport const MEMBERSHIP_NUMBER: PIIPattern = {\n type: 'MEMBERSHIP_NUMBER',\n regex: /\\b(?:MEMBER(?:SHIP)?|MEM|M)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[MEMBER_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Charity and association membership numbers',\n validator: (_value: string, context: string) => {\n return /member|membership|association|society|club/i.test(context);\n }\n};\n\n/**\n * Legacy/Bequest Reference\n * Format: LEG-XXXXXX, LEGACY-XXXXXX, BEQUEST-XXXXXX\n * Priority: 85\n */\nexport const LEGACY_REFERENCE: PIIPattern = {\n type: 'LEGACY_REFERENCE',\n regex: /\\b(?:LEGACY|LEG|BEQUEST|BEQ)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[LEGACY_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Legacy and bequest reference numbers',\n validator: (_value: string, context: string) => {\n return /legacy|bequest|will|estate|inheritance|in\\s+memory/i.test(context);\n }\n};\n\n/**\n * Export all charitable patterns\n */\nexport const charitablePatterns: PIIPattern[] = [\n DONOR_ID,\n DONATION_REFERENCE,\n UK_CHARITY_NUMBER,\n US_EIN,\n GRANT_REFERENCE,\n BENEFICIARY_ID,\n CAMPAIGN_CODE,\n GIFT_AID_REFERENCE,\n VOLUNTEER_ID,\n MEMBERSHIP_NUMBER,\n LEGACY_REFERENCE\n];\n","/**\n * Procurement & Supply Chain Patterns\n * Detects identifiers commonly used in procurement, purchasing, and supply chain operations\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Purchase Order (PO) Number\n * Format: PO-XXXXXX, PO#XXXXXX, POXXXXXX\n * Priority: 75\n */\nexport const PURCHASE_ORDER: PIIPattern = {\n type: 'PURCHASE_ORDER',\n regex: /\\b(?:PO|Purchase\\s+Order)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[PO_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Purchase order numbers',\n validator: (_value: string, context: string) => {\n return /purchase|order|procurement|buying/i.test(context);\n }\n};\n\n/**\n * Request for Quotation (RFQ) Number\n * Format: RFQ-XXXXXX, RFQ#XXXXXX\n * Priority: 70\n */\nexport const RFQ_NUMBER: PIIPattern = {\n type: 'RFQ_NUMBER',\n regex: /\\b(?:RFQ|Request\\s+for\\s+Quotation)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[RFQ_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Request for Quotation reference numbers'\n};\n\n/**\n * Request for Proposal (RFP) Number\n * Format: RFP-XXXXXX, RFP#XXXXXX\n * Priority: 70\n */\nexport const RFP_NUMBER: PIIPattern = {\n type: 'RFP_NUMBER',\n regex: /\\b(?:RFP|Request\\s+for\\s+Proposal)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[RFP_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Request for Proposal reference numbers'\n};\n\n/**\n * Tender Reference Number\n * Format: TN-XXXXXX, TENDER-XXXXXX, T-XXXXXX\n * Priority: 75\n */\nexport const TENDER_REFERENCE: PIIPattern = {\n type: 'TENDER_REFERENCE',\n regex: /\\b(?:TENDER|TN|T)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[TENDER_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Tender and bidding reference numbers',\n validator: (_value: string, context: string) => {\n return /tender|bid|bidding|procurement|competition/i.test(context);\n }\n};\n\n/**\n * Supplier/Vendor ID\n * Format: SUP-XXXXXX, VENDOR-XXXXXX, V-XXXXXX\n * Priority: 70\n */\nexport const SUPPLIER_ID: PIIPattern = {\n type: 'SUPPLIER_ID',\n regex: /\\b(?:SUPPLIER|SUP|VENDOR|VEN)[-_]?\\d{6,10}\\b/gi,\n placeholder: '[SUPPLIER_ID_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Supplier and vendor identification numbers',\n validator: (_value: string, context: string) => {\n return /supplier|vendor|provider|contractor/i.test(context);\n }\n};\n\n/**\n * Contract Reference Number\n * Format: CON-XXXXXX, CONTRACT-XXXXXX, C-XXXXXX\n * Priority: 80\n */\nexport const CONTRACT_REFERENCE: PIIPattern = {\n type: 'CONTRACT_REFERENCE',\n regex: /\\b(?:CONTRACT|CON|C)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[CONTRACT_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Procurement contract reference numbers',\n validator: (_value: string, context: string) => {\n return /contract|agreement|procurement|supply/i.test(context);\n }\n};\n\n/**\n * Requisition Number\n * Format: REQ-XXXXXX, PR-XXXXXX (Purchase Requisition)\n * Priority: 70\n */\nexport const REQUISITION_NUMBER: PIIPattern = {\n type: 'REQUISITION_NUMBER',\n regex: /\\b(?:REQ|REQUISITION|PR|Purchase\\s+Requisition)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[REQ_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Purchase requisition numbers'\n};\n\n/**\n * Procurement Card Number (P-Card) - Last 4 digits only for security\n * Format: P-Card ending XXXX\n * Priority: 90\n */\nexport const PCARD_REFERENCE: PIIPattern = {\n type: 'PCARD_REFERENCE',\n regex: /\\b(?:P[-\\s]?Card|Procurement\\s+Card).*?(?:ending|last\\s+4|XXXX)[-\\s]?(\\d{4})\\b/gi,\n placeholder: '[PCARD_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Procurement card references (partial numbers)'\n};\n\n/**\n * Catalog/Part Number\n * Format: CAT-XXXXXX, PN-XXXXXX, PART-XXXXXX\n * Priority: 60\n */\nexport const CATALOG_NUMBER: PIIPattern = {\n type: 'CATALOG_NUMBER',\n regex: /\\b(?:CATALOG|CAT|PART|PN)[-#]?[A-Z0-9]{6,15}\\b/gi,\n placeholder: '[CATALOG_{n}]',\n priority: 60,\n severity: 'low',\n description: 'Catalog and part numbers',\n validator: (_value: string, context: string) => {\n return /catalog|part|sku|item|product/i.test(context);\n }\n};\n\n/**\n * Quotation Reference\n * Format: QUO-XXXXXX, QUOTE-XXXXXX, Q-XXXXXX\n * Priority: 70\n */\nexport const QUOTATION_REFERENCE: PIIPattern = {\n type: 'QUOTATION_REFERENCE',\n regex: /\\b(?:QUOTATION|QUOTE|QUO|Q)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[QUOTE_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Quotation reference numbers',\n validator: (_value: string, context: string) => {\n return /quot|price|estimate|proposal/i.test(context);\n }\n};\n\n/**\n * Goods Receipt Note (GRN)\n * Format: GRN-XXXXXX, GR-XXXXXX\n * Priority: 65\n */\nexport const GOODS_RECEIPT: PIIPattern = {\n type: 'GOODS_RECEIPT',\n regex: /\\b(?:GRN|Goods\\s+Receipt)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[GRN_{n}]',\n priority: 65,\n severity: 'low',\n description: 'Goods receipt note numbers'\n};\n\n/**\n * Framework Agreement Reference\n * Format: FWK-XXXXXX, FRAMEWORK-XXXXXX\n * Priority: 75\n */\nexport const FRAMEWORK_AGREEMENT: PIIPattern = {\n type: 'FRAMEWORK_AGREEMENT',\n regex: /\\b(?:FRAMEWORK|FWK|FA)[-_]?\\d{6,12}\\b/gi,\n placeholder: '[FRAMEWORK_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Framework agreement reference numbers',\n validator: (_value: string, context: string) => {\n return /framework|agreement|procurement/i.test(context);\n }\n};\n\n/**\n * Blanket Order Number\n * Format: BO-XXXXXX, BLANKET-XXXXXX\n * Priority: 70\n */\nexport const BLANKET_ORDER: PIIPattern = {\n type: 'BLANKET_ORDER',\n regex: /\\b(?:BLANKET|BO|Blanket\\s+Order)[-#\\s]?(\\d{6,12})\\b/gi,\n placeholder: '[BLANKET_ORDER_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Blanket purchase order numbers'\n};\n\n/**\n * Export all procurement patterns\n */\nexport const procurementPatterns: PIIPattern[] = [\n PURCHASE_ORDER,\n RFQ_NUMBER,\n RFP_NUMBER,\n TENDER_REFERENCE,\n SUPPLIER_ID,\n CONTRACT_REFERENCE,\n REQUISITION_NUMBER,\n PCARD_REFERENCE,\n CATALOG_NUMBER,\n QUOTATION_REFERENCE,\n GOODS_RECEIPT,\n FRAMEWORK_AGREEMENT,\n BLANKET_ORDER\n];\n","/**\n * Emergency Services Industry PII Patterns\n * For emergency response, public safety, disaster management\n *\n * CRITICAL: These patterns handle highly sensitive emergency response data\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Emergency Call Reference Number\n * Formats: Various (CAD-NNNNNN, EMG-YYYY-NNNNNN, INCIDENT-NNNNN, etc.)\n * Used by 911, 999, 112, and other emergency dispatch systems\n */\nexport const EMERGENCY_CALL_REF: PIIPattern = {\n type: 'EMERGENCY_CALL_REF',\n regex: /\\b(?:EMERGENCY|INCIDENT|CALL|CAD|DISPATCH|EVENT)[-\\s]?(?:REF|NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[EMERGENCY_REF_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Emergency services call reference numbers',\n validator: (_value: string, context: string) => {\n return /emergency|911|999|112|ambulance|fire|police|dispatch|incident|call[- ]?center/i.test(context);\n }\n};\n\n/**\n * Police Report Number\n * Format: Department-specific (PR-YYYY-NNNNNNN, RPT-NNNNNN, etc.)\n */\nexport const POLICE_REPORT_NUMBER: PIIPattern = {\n type: 'POLICE_REPORT_NUMBER',\n regex: /\\b(?:POLICE|PR|RPT|REPORT|CASE)[-\\s]?(?:NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*(\\d{4}[-\\s]?\\d{5,10}|[A-Z]{2,4}[-\\s]?\\d{6,10})\\b/gi,\n placeholder: '[POLICE_RPT_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Police report and case numbers',\n validator: (_value: string, context: string) => {\n return /police|officer|citation|arrest|detective|sheriff|trooper|constable|case[- ]?number/i.test(context);\n }\n};\n\n/**\n * Fire Incident Number\n * Format: Department-specific (FI-YYYY-NNNNN, FIRE-NNNNNN, etc.)\n */\nexport const FIRE_INCIDENT_NUMBER: PIIPattern = {\n type: 'FIRE_INCIDENT_NUMBER',\n regex: /\\b(?:FIRE|FI|FD)[-\\s]?(?:INCIDENT|INC|NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*(\\d{4}[-\\s]?\\d{4,8}|[A-Z]{2,4}[-\\s]?\\d{5,10})\\b/gi,\n placeholder: '[FIRE_INC_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Fire department incident numbers',\n validator: (_value: string, context: string) => {\n return /fire|firefighter|dept|department|incident|response|station|alarm/i.test(context);\n }\n};\n\n/**\n * Ambulance Service Call ID\n * Format: Service-specific (AMB-NNNNNN, EMS-YYYY-NNNNN, etc.)\n */\nexport const AMBULANCE_CALL_ID: PIIPattern = {\n type: 'AMBULANCE_CALL_ID',\n regex: /\\b(?:AMBULANCE|AMB|EMS|PARAMEDIC)[-\\s]?(?:CALL|ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[AMB_CALL_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ambulance and EMS call identifiers',\n validator: (_value: string, context: string) => {\n return /ambulance|ems|paramedic|emergency[- ]?medical|transport|patient[- ]?care/i.test(context);\n }\n};\n\n/**\n * Paramedic Certification Number\n * Format: State/country-specific (NREMT-P-NNNNNN, EMT-STATE-NNNNN, etc.)\n */\nexport const PARAMEDIC_CERTIFICATION: PIIPattern = {\n type: 'PARAMEDIC_CERTIFICATION',\n regex: /\\b(?:NREMT|EMT|PARAMEDIC)[-\\s]?(?:P|B|A|I)?[-\\s]?(?:CERT|LICENSE|LIC)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PARAMEDIC_CERT_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Paramedic and EMT certification numbers',\n validator: (_value: string, context: string) => {\n return /paramedic|emt|nremt|emergency[- ]?medical[- ]?tech|certification|license|certified|medic/i.test(context);\n }\n};\n\n/**\n * Emergency Shelter Registration\n * Format: Shelter-specific (SHELTER-A-NNNNN, REG-NNNNNN, etc.)\n * Used during disasters and emergency evacuations\n */\nexport const EMERGENCY_SHELTER_ID: PIIPattern = {\n type: 'EMERGENCY_SHELTER_ID',\n regex: /\\b(?:SHELTER|EVACUATION|REFUGE)[-\\s]?(?:REG|ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{5,12})\\b/gi,\n placeholder: '[SHELTER_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Emergency shelter registration identifiers',\n validator: (_value: string, context: string) => {\n return /shelter|evacuation|refuge|displaced|disaster|emergency[- ]?housing/i.test(context);\n }\n};\n\n/**\n * Disaster Victim Identification (DVI)\n * Format: International standard (DVI-YYYY-NNNNN)\n * Used in mass casualty incidents\n */\nexport const DISASTER_VICTIM_ID: PIIPattern = {\n type: 'DISASTER_VICTIM_ID',\n regex: /\\b(?:DVI|VICTIM)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*(\\d{4}[-\\s]?\\d{4,8})\\b/gi,\n placeholder: '[DVI_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Disaster victim identification numbers',\n validator: (_value: string, context: string) => {\n return /disaster|victim|dvi|casualty|identification|mass[- ]?casualty|morgue/i.test(context);\n }\n};\n\n/**\n * Search and Rescue Mission ID\n * Format: SAR-YYYY-NNNNN, RESCUE-NNNNNN\n */\nexport const SEARCH_RESCUE_MISSION_ID: PIIPattern = {\n type: 'SEARCH_RESCUE_MISSION_ID',\n regex: /\\b(?:SAR|SEARCH|RESCUE|MISSION)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[SAR_MISSION_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Search and rescue mission identifiers',\n validator: (_value: string, context: string) => {\n return /search|rescue|sar|mission|lost|missing|coast[- ]?guard/i.test(context);\n }\n};\n\n/**\n * Emergency Medical Incident Number\n * Format: Various (MED-NNNNNN, MI-YYYY-NNNNN)\n */\nexport const EMERGENCY_MEDICAL_INCIDENT: PIIPattern = {\n type: 'EMERGENCY_MEDICAL_INCIDENT',\n regex: /\\b(?:MEDICAL|MED|MI)[-\\s]?(?:INCIDENT|INC|EMERGENCY|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[MED_INC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Emergency medical incident numbers',\n validator: (_value: string, context: string) => {\n return /medical|emergency|incident|patient|treatment|hospital|trauma/i.test(context);\n }\n};\n\n/**\n * Firefighter Badge Number\n * Format: Department-specific (BADGE-NNNN, FF-NNNNN)\n */\nexport const FIREFIGHTER_BADGE: PIIPattern = {\n type: 'FIREFIGHTER_BADGE',\n regex: /\\b(?:BADGE|FF|FIREFIGHTER)[-\\s]?(?:NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*(\\d{3,6})\\b/gi,\n placeholder: '[FF_BADGE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Firefighter badge numbers',\n validator: (_value: string, context: string) => {\n return /firefighter|fire[- ]?dept|badge|ff|station|apparatus/i.test(context);\n }\n};\n\n/**\n * Police Officer Badge Number\n * Format: Department-specific (BADGE-NNNN, SHIELD-NNNNN)\n */\nexport const POLICE_BADGE: PIIPattern = {\n type: 'POLICE_BADGE',\n regex: /\\b(?:BADGE|SHIELD|OFFICER)[-\\s]?(?:NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*(\\d{3,6})\\b/gi,\n placeholder: '[POLICE_BADGE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Police officer badge numbers',\n validator: (_value: string, context: string) => {\n return /police|officer|badge|shield|dept|department|patrol/i.test(context);\n }\n};\n\n/**\n * Missing Person Case Number\n * Format: MP-YYYY-NNNNN, MISSING-NNNNNN\n */\nexport const MISSING_PERSON_CASE: PIIPattern = {\n type: 'MISSING_PERSON_CASE',\n regex: /\\b(?:MISSING|MP|AMBER)[-\\s]?(?:PERSON|CASE|ALERT)?[-\\s]?(?:NO|NUMBER|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[MISSING_CASE_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Missing person case numbers',\n validator: (_value: string, context: string) => {\n return /missing|amber|alert|person|child|endangered|located|found/i.test(context);\n }\n};\n\n/**\n * 911/Emergency Dispatcher ID\n * Format: DISPATCHER-NNNNN, DISP-NNN\n */\nexport const DISPATCHER_ID: PIIPattern = {\n type: 'DISPATCHER_ID',\n regex: /\\b(?:DISPATCHER|DISP)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{3,8})\\b/gi,\n placeholder: '[DISPATCHER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Emergency dispatcher identification numbers',\n validator: (_value: string, context: string) => {\n return /dispatcher|911|999|112|emergency|operator|call[- ]?center/i.test(context);\n }\n};\n\n/**\n * Hazmat Incident Number\n * Format: HAZMAT-YYYY-NNNNN, HM-NNNNNN\n */\nexport const HAZMAT_INCIDENT: PIIPattern = {\n type: 'HAZMAT_INCIDENT',\n regex: /\\b(?:HAZMAT|HM)[-\\s]?(?:INCIDENT|INC|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[HAZMAT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Hazardous materials incident numbers',\n validator: (_value: string, context: string) => {\n return /hazmat|hazardous|material|chemical|spill|containment|decontamination/i.test(context);\n }\n};\n\n// Export all emergency services patterns\nexport const emergencyServicesPatterns: PIIPattern[] = [\n EMERGENCY_CALL_REF,\n POLICE_REPORT_NUMBER,\n FIRE_INCIDENT_NUMBER,\n AMBULANCE_CALL_ID,\n PARAMEDIC_CERTIFICATION,\n EMERGENCY_SHELTER_ID,\n DISASTER_VICTIM_ID,\n SEARCH_RESCUE_MISSION_ID,\n EMERGENCY_MEDICAL_INCIDENT,\n FIREFIGHTER_BADGE,\n POLICE_BADGE,\n MISSING_PERSON_CASE,\n DISPATCHER_ID,\n HAZMAT_INCIDENT\n];\n","/**\n * Real Estate & Property Industry PII Patterns\n * For property transactions, mortgages, leases, and real estate operations\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Property Assessor Parcel Number (APN)\n * Format: XXX-XXX-XXX or XXXXXXX (varies by jurisdiction)\n * Used by tax assessors to uniquely identify land parcels\n */\nexport const PROPERTY_PARCEL_NUMBER: PIIPattern = {\n type: 'PROPERTY_PARCEL_NUMBER',\n regex: /\\b(?:APN|PARCEL|ASSESSOR)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{3}[-\\s]?\\d{3}[-\\s]?\\d{3}(?:[-\\s]?\\d{1,3})?)\\b/gi,\n placeholder: '[APN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Property assessor parcel numbers',\n validator: (_value: string, context: string) => {\n return /property|parcel|assessor|land|real[- ]?estate|apn|tax|deed/i.test(context);\n }\n};\n\n/**\n * Multiple Listing Service (MLS) Number\n * Format: Alphanumeric, varies by MLS region\n * Used by real estate brokers to list properties\n */\nexport const MLS_LISTING_NUMBER: PIIPattern = {\n type: 'MLS_LISTING_NUMBER',\n regex: /\\bMLS[-\\s]?(?:NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[MLS_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'MLS (Multiple Listing Service) property listing numbers',\n validator: (_value: string, context: string) => {\n return /mls|listing|real[- ]?estate|property|broker|agent|sale|for[- ]sale/i.test(context);\n }\n};\n\n/**\n * Mortgage Loan Number\n * Format: Various (typically 8-12 digits or alphanumeric)\n * Used by lenders to track mortgage accounts\n */\nexport const MORTGAGE_LOAN_NUMBER: PIIPattern = {\n type: 'MORTGAGE_LOAN_NUMBER',\n regex: /\\b(?:MORTGAGE|LOAN|MTG)[-\\s]?(?:NO|NUM|NUMBER|ID|ACCOUNT)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,14})\\b/gi,\n placeholder: '[MORTGAGE_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Mortgage and home loan account numbers',\n validator: (_value: string, context: string) => {\n return /mortgage|loan|lender|lending|home[- ]?loan|refinance|foreclosure|escrow/i.test(context);\n }\n};\n\n/**\n * Property Tax Account Number\n * Format: Varies by jurisdiction (typically numeric)\n * Used by municipalities for property tax billing\n */\nexport const PROPERTY_TAX_ACCOUNT: PIIPattern = {\n type: 'PROPERTY_TAX_ACCOUNT',\n regex: /\\b(?:PROPERTY[- ]?TAX|TAX|MUNICIPAL)[-\\s]?(?:ACCOUNT|ACCT|NO|NUMBER|ID)?[-\\s]?[:#]?\\s*(\\d{6,12})\\b/gi,\n placeholder: '[TAX_ACCT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Property tax account numbers',\n validator: (_value: string, context: string) => {\n return /property[- ]?tax|municipal|county|city|tax[- ]?bill|assessment|levy/i.test(context);\n }\n};\n\n/**\n * HOA (Homeowners Association) Account Number\n * Format: Numeric or alphanumeric\n * Used by HOAs to track member accounts\n */\nexport const HOA_ACCOUNT_NUMBER: PIIPattern = {\n type: 'HOA_ACCOUNT_NUMBER',\n regex: /\\bHOA[-\\s]?(?:ACCOUNT|ACCT|NO|NUMBER|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[HOA_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'HOA (Homeowners Association) account numbers',\n validator: (_value: string, context: string) => {\n return /hoa|homeowners|association|condo|dues|fee|community/i.test(context);\n }\n};\n\n/**\n * Title/Deed Number\n * Format: Alphanumeric (varies by recording office)\n * Used to identify property title documents\n */\nexport const TITLE_DEED_NUMBER: PIIPattern = {\n type: 'TITLE_DEED_NUMBER',\n regex: /\\b(?:TITLE|DEED)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[DEED_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Property title and deed numbers',\n validator: (_value: string, context: string) => {\n return /title|deed|recording|recorder|registry|land[- ]?registry|conveyance/i.test(context);\n }\n};\n\n/**\n * Real Estate License Number\n * Format: State-specific (typically alphanumeric)\n * Used to identify licensed real estate agents and brokers\n */\nexport const REAL_ESTATE_LICENSE: PIIPattern = {\n type: 'REAL_ESTATE_LICENSE',\n regex: /\\b(?:REAL[- ]?ESTATE|RE|BROKER)[-\\s]?(?:LICENSE|LIC)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RE_LIC_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Real estate agent/broker license numbers',\n validator: (_value: string, context: string) => {\n return /real[- ]?estate|broker|agent|license|realtor|certified/i.test(context);\n }\n};\n\n/**\n * Appraisal Reference Number\n * Format: Alphanumeric\n * Used by appraisers to track property valuations\n */\nexport const APPRAISAL_REFERENCE: PIIPattern = {\n type: 'APPRAISAL_REFERENCE',\n regex: /\\b(?:APPRAISAL|APPR)[-\\s]?(?:NO|NUM|NUMBER|REF|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[APPR_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Property appraisal reference numbers',\n validator: (_value: string, context: string) => {\n return /appraisal|appraiser|valuation|value|assessment|market[- ]?value/i.test(context);\n }\n};\n\n/**\n * Escrow Account Number\n * Format: Numeric or alphanumeric\n * Used by escrow companies for transaction accounts\n */\nexport const ESCROW_NUMBER: PIIPattern = {\n type: 'ESCROW_NUMBER',\n regex: /\\bESCROW[-\\s]?(?:NO|NUM|NUMBER|ACCOUNT|ACCT|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[ESCROW_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Escrow account numbers',\n validator: (_value: string, context: string) => {\n return /escrow|closing|settlement|title[- ]?company|transaction/i.test(context);\n }\n};\n\n/**\n * Lease Agreement Reference\n * Format: Alphanumeric\n * Used to identify rental lease contracts\n */\nexport const LEASE_AGREEMENT_NUMBER: PIIPattern = {\n type: 'LEASE_AGREEMENT_NUMBER',\n regex: /\\b(?:LEASE|RENTAL)[-\\s]?(?:AGREEMENT|CONTRACT|NO|NUM|NUMBER|ID)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[LEASE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Lease and rental agreement numbers',\n validator: (_value: string, context: string) => {\n return /lease|rental|tenant|landlord|rent|renter|apartment|unit/i.test(context);\n }\n};\n\n// Export all real estate patterns\nexport const realEstatePatterns: PIIPattern[] = [\n PROPERTY_PARCEL_NUMBER,\n MLS_LISTING_NUMBER,\n MORTGAGE_LOAN_NUMBER,\n PROPERTY_TAX_ACCOUNT,\n HOA_ACCOUNT_NUMBER,\n TITLE_DEED_NUMBER,\n REAL_ESTATE_LICENSE,\n APPRAISAL_REFERENCE,\n ESCROW_NUMBER,\n LEASE_AGREEMENT_NUMBER\n];\n","/**\n * Gig Economy Platform PII Patterns\n * For rideshare, delivery, freelance, and on-demand service platforms\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Uber Trip/Ride ID\n * Format: Alphanumeric (typically UUID or custom format)\n * Used to track individual rides\n */\nexport const UBER_TRIP_ID: PIIPattern = {\n type: 'UBER_TRIP_ID',\n regex: /\\bUBER[-\\s]?(?:TRIP|RIDE)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,24})\\b/gi,\n placeholder: '[UBER_TRIP_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Uber trip/ride identifier',\n validator: (_value: string, context: string) => {\n return /uber|rideshare|ride|trip|driver|passenger/i.test(context);\n }\n};\n\n/**\n * Lyft Ride ID\n * Format: Alphanumeric\n * Used to track individual rides\n */\nexport const LYFT_RIDE_ID: PIIPattern = {\n type: 'LYFT_RIDE_ID',\n regex: /\\bLYFT[-\\s]?(?:RIDE|TRIP)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,24})\\b/gi,\n placeholder: '[LYFT_RIDE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Lyft ride identifier',\n validator: (_value: string, context: string) => {\n return /lyft|rideshare|ride|trip|driver|passenger/i.test(context);\n }\n};\n\n/**\n * DoorDash Order ID\n * Format: Alphanumeric\n * Used to track food delivery orders\n */\nexport const DOORDASH_ORDER_ID: PIIPattern = {\n type: 'DOORDASH_ORDER_ID',\n regex: /\\b(?:DOORDASH|DD)[-\\s]?(?:ORDER|DELIVERY)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[DD_ORDER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'DoorDash order identifier',\n validator: (_value: string, context: string) => {\n return /doordash|dasher|delivery|order|food[- ]?delivery/i.test(context);\n }\n};\n\n/**\n * Uber Eats Order ID\n * Format: Alphanumeric\n * Used to track food delivery orders\n */\nexport const UBEREATS_ORDER_ID: PIIPattern = {\n type: 'UBEREATS_ORDER_ID',\n regex: /\\bUBER[-\\s]?EATS[-\\s]?(?:ORDER|DELIVERY)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[UE_ORDER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Uber Eats order identifier',\n validator: (_value: string, context: string) => {\n return /uber[- ]?eats|delivery|order|food[- ]?delivery/i.test(context);\n }\n};\n\n/**\n * Grubhub Order ID\n * Format: Numeric or alphanumeric\n * Used to track food delivery orders\n */\nexport const GRUBHUB_ORDER_ID: PIIPattern = {\n type: 'GRUBHUB_ORDER_ID',\n regex: /\\bGRUBHUB[-\\s]?(?:ORDER)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[GH_ORDER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Grubhub order identifier',\n validator: (_value: string, context: string) => {\n return /grubhub|delivery|order|food[- ]?delivery|restaurant/i.test(context);\n }\n};\n\n/**\n * Airbnb Reservation ID\n * Format: Alphanumeric (typically 9+ characters)\n * Used to track bookings\n */\nexport const AIRBNB_RESERVATION_ID: PIIPattern = {\n type: 'AIRBNB_RESERVATION_ID',\n regex: /\\bAIRBNB[-\\s]?(?:RESERVATION|BOOKING|CONF(?:IRMATION)?)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{9,16})\\b/gi,\n placeholder: '[AIRBNB_RES_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Airbnb reservation/booking identifier',\n validator: (_value: string, context: string) => {\n return /airbnb|reservation|booking|host|guest|stay|accommodation/i.test(context);\n }\n};\n\n/**\n * Instacart Order ID\n * Format: Numeric or alphanumeric\n * Used to track grocery delivery orders\n */\nexport const INSTACART_ORDER_ID: PIIPattern = {\n type: 'INSTACART_ORDER_ID',\n regex: /\\bINSTACART[-\\s]?(?:ORDER|DELIVERY)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[IC_ORDER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Instacart order identifier',\n validator: (_value: string, context: string) => {\n return /instacart|shopper|grocery|delivery|order/i.test(context);\n }\n};\n\n/**\n * TaskRabbit Task ID\n * Format: Numeric or alphanumeric\n * Used to track service tasks\n */\nexport const TASKRABBIT_TASK_ID: PIIPattern = {\n type: 'TASKRABBIT_TASK_ID',\n regex: /\\b(?:TASKRABBIT|TR)[-\\s]?(?:TASK|JOB)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[TR_TASK_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'TaskRabbit task identifier',\n validator: (_value: string, context: string) => {\n return /taskrabbit|tasker|task|job|service|handyman/i.test(context);\n }\n};\n\n/**\n * Upwork Job/Contract ID\n * Format: Alphanumeric\n * Used to track freelance projects\n */\nexport const UPWORK_JOB_ID: PIIPattern = {\n type: 'UPWORK_JOB_ID',\n regex: /\\bUPWORK[-\\s]?(?:JOB|CONTRACT|PROJECT)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[UW_JOB_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Upwork job/contract identifier',\n validator: (_value: string, context: string) => {\n return /upwork|freelance|contract|job|project|client|proposal/i.test(context);\n }\n};\n\n/**\n * Fiverr Order/Gig ID\n * Format: Alphanumeric\n * Used to track freelance orders\n */\nexport const FIVERR_ORDER_ID: PIIPattern = {\n type: 'FIVERR_ORDER_ID',\n regex: /\\bFIVERR[-\\s]?(?:ORDER|GIG)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[FV_ORDER_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Fiverr order/gig identifier',\n validator: (_value: string, context: string) => {\n return /fiverr|seller|buyer|gig|order|freelance/i.test(context);\n }\n};\n\n/**\n * Postmates Delivery ID\n * Format: Alphanumeric\n * Used to track deliveries\n */\nexport const POSTMATES_DELIVERY_ID: PIIPattern = {\n type: 'POSTMATES_DELIVERY_ID',\n regex: /\\bPOSTMATES[-\\s]?(?:DELIVERY|ORDER)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[PM_DEL_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Postmates delivery identifier',\n validator: (_value: string, context: string) => {\n return /postmates|delivery|order|courier|food/i.test(context);\n }\n};\n\n/**\n * Generic Gig Platform User ID\n * Format: Alphanumeric\n * Catches common gig platform user identifiers\n */\nexport const GIG_PLATFORM_USER_ID: PIIPattern = {\n type: 'GIG_PLATFORM_USER_ID',\n regex: /\\b(?:DRIVER|DASHER|SHOPPER|TASKER|COURIER|RIDER)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,16})\\b/gi,\n placeholder: '[GIG_USER_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Gig economy platform user identifier',\n validator: (_value: string, context: string) => {\n return /driver|dasher|shopper|tasker|courier|rider|delivery|gig[- ]?economy|platform/i.test(context);\n }\n};\n\n/**\n * Generic Gig Platform Order/Trip ID\n * Format: Alphanumeric\n * Catches generic order/trip patterns\n */\nexport const GIG_PLATFORM_ORDER_ID: PIIPattern = {\n type: 'GIG_PLATFORM_ORDER_ID',\n regex: /\\b(?:ORDER|TRIP|DELIVERY|BOOKING)[-\\s]?[:#]\\s*([A-Z0-9]{8,20})\\b/gi,\n placeholder: '[GIG_ORDER_{n}]',\n priority: 65,\n severity: 'medium',\n description: 'Generic gig platform order/trip identifier',\n validator: (value: string, context: string) => {\n // Must have gig platform context\n const hasGigContext = /uber|lyft|doordash|airbnb|instacart|taskrabbit|postmates|grubhub|delivery|rideshare/i.test(context);\n\n // Should have order/trip related context\n const hasOrderContext = /order|trip|delivery|booking|ride|reservation/i.test(context);\n\n return hasGigContext && hasOrderContext && value.length >= 8;\n }\n};\n\n// Export all gig economy patterns\nexport const gigEconomyPatterns: PIIPattern[] = [\n UBER_TRIP_ID,\n LYFT_RIDE_ID,\n DOORDASH_ORDER_ID,\n UBEREATS_ORDER_ID,\n GRUBHUB_ORDER_ID,\n AIRBNB_RESERVATION_ID,\n INSTACART_ORDER_ID,\n TASKRABBIT_TASK_ID,\n UPWORK_JOB_ID,\n FIVERR_ORDER_ID,\n POSTMATES_DELIVERY_ID,\n GIG_PLATFORM_USER_ID,\n GIG_PLATFORM_ORDER_ID\n];\n","/**\n * Hospitality & Tourism Industry PII Patterns\n * For hotels, airlines, travel agencies, and tourism services\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Airline Passenger Name Record (PNR)\n * Format: 6 alphanumeric characters\n * Used by airlines for booking references\n */\nexport const AIRLINE_PNR: PIIPattern = {\n type: 'AIRLINE_PNR',\n regex: /\\b(?:PNR|BOOKING|CONFIRMATION)[-\\s]?(?:NO|NUM|NUMBER|CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{6})\\b/gi,\n placeholder: '[PNR_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Airline Passenger Name Record (PNR)',\n validator: (value: string, context: string) => {\n // Must be exactly 6 alphanumeric characters\n if (value.length !== 6) return false;\n\n // Must have airline/flight context\n return /airline|flight|booking|reservation|pnr|travel|passenger|ticket/i.test(context);\n }\n};\n\n/**\n * Hotel Reservation Number\n * Format: Varies by hotel chain (typically alphanumeric)\n * Used for hotel booking confirmations\n */\nexport const HOTEL_RESERVATION: PIIPattern = {\n type: 'HOTEL_RESERVATION',\n regex: /\\b(?:HOTEL|RESERVATION|CONF(?:IRMATION)?|BOOKING)[-\\s]?(?:NO|NUM|NUMBER|CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,14})\\b/gi,\n placeholder: '[HOTEL_RES_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Hotel reservation/confirmation number',\n validator: (_value: string, context: string) => {\n return /hotel|reservation|booking|room|accommodation|stay|check[-\\s]?in|lodging/i.test(context);\n }\n};\n\n/**\n * Frequent Flyer Number\n * Format: Varies by airline (typically numeric or alphanumeric)\n * Used for airline loyalty programs\n */\nexport const FREQUENT_FLYER_NUMBER: PIIPattern = {\n type: 'FREQUENT_FLYER_NUMBER',\n regex: /\\b(?:FREQUENT[- ]?FLYER|FF|MILEAGE|LOYALTY)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[FF_NUM_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Frequent flyer/loyalty program number',\n validator: (_value: string, context: string) => {\n return /frequent[- ]?flyer|miles|mileage|loyalty|rewards|member|airline/i.test(context);\n }\n};\n\n/**\n * Hotel Loyalty Number\n * Format: Varies by hotel chain\n * Used for hotel rewards programs (Marriott, Hilton, etc.)\n */\nexport const HOTEL_LOYALTY_NUMBER: PIIPattern = {\n type: 'HOTEL_LOYALTY_NUMBER',\n regex: /\\b(?:MEMBER|LOYALTY|REWARDS)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[HOTEL_LOYALTY_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Hotel loyalty/rewards program number',\n validator: (_value: string, context: string) => {\n return /hotel|marriott|hilton|hyatt|ihg|loyalty|rewards|points|member/i.test(context);\n }\n};\n\n/**\n * Cruise Booking Number\n * Format: Alphanumeric\n * Used by cruise lines for reservations\n */\nexport const CRUISE_BOOKING_NUMBER: PIIPattern = {\n type: 'CRUISE_BOOKING_NUMBER',\n regex: /\\b(?:CRUISE|BOOKING|RESERVATION)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[CRUISE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Cruise line booking number',\n validator: (_value: string, context: string) => {\n return /cruise|ship|sailing|voyage|cabin|carnival|royal[- ]?caribbean|norwegian/i.test(context);\n }\n};\n\n/**\n * Travel Agency Booking Reference\n * Format: Alphanumeric\n * Used by travel agencies for client bookings\n */\nexport const TRAVEL_AGENCY_BOOKING: PIIPattern = {\n type: 'TRAVEL_AGENCY_BOOKING',\n regex: /\\b(?:TRAVEL|AGENCY|BOOKING|TRIP)[-\\s]?(?:REF|REFERENCE|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TRAVEL_REF_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Travel agency booking reference',\n validator: (_value: string, context: string) => {\n return /travel[- ]?agency|tour|package|itinerary|booking|vacation/i.test(context);\n }\n};\n\n/**\n * Rental Car Confirmation\n * Format: Alphanumeric\n * Used by car rental companies (Hertz, Enterprise, etc.)\n */\nexport const RENTAL_CAR_CONFIRMATION: PIIPattern = {\n type: 'RENTAL_CAR_CONFIRMATION',\n regex: /\\b(?:RENTAL|CAR|VEHICLE)[-\\s]?(?:CONF(?:IRMATION)?|RESERVATION|BOOKING)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[CAR_RENTAL_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Rental car confirmation number',\n validator: (_value: string, context: string) => {\n return /rental|car|vehicle|hertz|enterprise|avis|budget|rent/i.test(context);\n }\n};\n\n/**\n * Theme Park Ticket Number\n * Format: Alphanumeric or numeric\n * Used by theme parks and attractions\n */\nexport const THEME_PARK_TICKET: PIIPattern = {\n type: 'THEME_PARK_TICKET',\n regex: /\\b(?:TICKET|PASS|ADMISSION)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[TICKET_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Theme park or attraction ticket number',\n validator: (value: string, context: string) => {\n // Should be 8+ characters to avoid false positives\n if (value.length < 8) return false;\n\n return /theme[- ]?park|disney|universal|attraction|admission|ticket|pass|entry/i.test(context);\n }\n};\n\n/**\n * TSA PreCheck Number (Known Traveler Number)\n * Format: 9-10 alphanumeric characters\n * Used by US TSA for expedited screening\n */\nexport const TSA_PRECHECK_NUMBER: PIIPattern = {\n type: 'TSA_PRECHECK_NUMBER',\n regex: /\\b(?:TSA|PRECHECK|KTN|KNOWN[- ]?TRAVELER)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{9,10})\\b/gi,\n placeholder: '[TSA_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'TSA PreCheck / Known Traveler Number',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 9 || length > 10) return false;\n\n return /tsa|precheck|pre[- ]?check|ktn|known[- ]?traveler|security|screening/i.test(context);\n }\n};\n\n/**\n * Global Entry Number\n * Format: 9 digits (PASS ID)\n * Used for expedited customs/immigration\n */\nexport const GLOBAL_ENTRY_NUMBER: PIIPattern = {\n type: 'GLOBAL_ENTRY_NUMBER',\n regex: /\\b(?:GLOBAL[- ]?ENTRY|PASS[- ]?ID)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{9})\\b/gi,\n placeholder: '[GLOBAL_ENTRY_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Global Entry / PASS ID number',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n return /global[- ]?entry|pass[- ]?id|customs|immigration|cbp|trusted[- ]?traveler/i.test(context);\n }\n};\n\n// Export all hospitality patterns\nexport const hospitalityPatterns: PIIPattern[] = [\n AIRLINE_PNR,\n HOTEL_RESERVATION,\n FREQUENT_FLYER_NUMBER,\n HOTEL_LOYALTY_NUMBER,\n CRUISE_BOOKING_NUMBER,\n TRAVEL_AGENCY_BOOKING,\n RENTAL_CAR_CONFIRMATION,\n THEME_PARK_TICKET,\n TSA_PRECHECK_NUMBER,\n GLOBAL_ENTRY_NUMBER\n];\n","/**\n * Professional Certifications PII Patterns\n * For professional licenses, certifications, and credentials\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * PMP (Project Management Professional) Certification\n * Format: 7-9 digit number\n * Issued by PMI (Project Management Institute)\n */\nexport const PMP_CERTIFICATION: PIIPattern = {\n type: 'PMP_CERTIFICATION',\n regex: /\\bPMP[-\\s]?(?:ID|NO|NUM|NUMBER|CERT(?:IFICATION)?)?[-\\s]?[:#]?\\s*(\\d{7,9})\\b/gi,\n placeholder: '[PMP_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'PMP (Project Management Professional) certification number',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 7 || length > 9) return false;\n\n return /pmp|project[- ]?management|pmi|certification|certified/i.test(context);\n }\n};\n\n/**\n * CPA (Certified Public Accountant) License\n * Format: Varies by state (typically numeric)\n * Issued by state boards of accountancy\n */\nexport const CPA_LICENSE: PIIPattern = {\n type: 'CPA_LICENSE',\n regex: /\\bCPA[-\\s]?(?:LICENSE|LIC|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{5,10})\\b/gi,\n placeholder: '[CPA_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'CPA (Certified Public Accountant) license number',\n validator: (_value: string, context: string) => {\n return /cpa|certified[- ]?public[- ]?accountant|accountancy|license|accounting/i.test(context);\n }\n};\n\n/**\n * PE (Professional Engineer) License\n * Format: Varies by state (typically numeric or alphanumeric)\n * Issued by state engineering boards\n */\nexport const PE_LICENSE: PIIPattern = {\n type: 'PE_LICENSE',\n regex: /\\bPE[-\\s]?(?:LICENSE|LIC|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{5,10})\\b/gi,\n placeholder: '[PE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'PE (Professional Engineer) license number',\n validator: (_value: string, context: string) => {\n return /professional[- ]?engineer|engineering|pe[- ]?license|registered[- ]?engineer/i.test(context);\n }\n};\n\n/**\n * Nursing License (RN)\n * Format: Varies by state (typically numeric)\n * Issued by state boards of nursing\n */\nexport const NURSING_LICENSE: PIIPattern = {\n type: 'NURSING_LICENSE',\n regex: /\\b(?:RN|LPN|NP|NURSING)[-\\s]?(?:LICENSE|LIC|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[RN_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Nursing license number (RN, LPN, NP)',\n validator: (_value: string, context: string) => {\n return /nurse|nursing|rn|lpn|registered[- ]?nurse|license|practitioner/i.test(context);\n }\n};\n\n/**\n * Teaching Certificate/License\n * Format: Varies by state (typically numeric or alphanumeric)\n * Issued by state education departments\n */\nexport const TEACHING_LICENSE: PIIPattern = {\n type: 'TEACHING_LICENSE',\n regex: /\\b(?:TEACHING|TEACHER|EDUCATOR)[-\\s]?(?:LICENSE|LIC|CERT(?:IFICATE)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TEACHER_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Teaching certificate/license number',\n validator: (_value: string, context: string) => {\n return /teacher|teaching|educator|education|certificate|license|certified/i.test(context);\n }\n};\n\n/**\n * AWS Certification ID\n * Format: Alphanumeric\n * Issued by Amazon Web Services for cloud certifications\n */\nexport const AWS_CERTIFICATION: PIIPattern = {\n type: 'AWS_CERTIFICATION',\n regex: /\\bAWS[-\\s]?(?:CERT(?:IFICATION)?|ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[AWS_CERT_{n}]',\n priority: 75,\n severity: 'low',\n description: 'AWS (Amazon Web Services) certification ID',\n validator: (_value: string, context: string) => {\n return /aws|amazon[- ]?web[- ]?services|cloud|certification|certified|solutions[- ]?architect/i.test(context);\n }\n};\n\n/**\n * Microsoft Certification ID (MCID)\n * Format: Alphanumeric\n * Issued by Microsoft for technical certifications\n */\nexport const MICROSOFT_CERTIFICATION: PIIPattern = {\n type: 'MICROSOFT_CERTIFICATION',\n regex: /\\b(?:MICROSOFT|MCID|MS)[-\\s]?(?:CERT(?:IFICATION)?|ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[MS_CERT_{n}]',\n priority: 75,\n severity: 'low',\n description: 'Microsoft certification ID (MCID)',\n validator: (_value: string, context: string) => {\n return /microsoft|mcid|azure|certification|certified|mcsa|mcse/i.test(context);\n }\n};\n\n/**\n * Cisco Certification ID (CSCO)\n * Format: Alphanumeric\n * Issued by Cisco for networking certifications\n */\nexport const CISCO_CERTIFICATION: PIIPattern = {\n type: 'CISCO_CERTIFICATION',\n regex: /\\b(?:CISCO|CSCO)[-\\s]?(?:CERT(?:IFICATION)?|ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[CISCO_CERT_{n}]',\n priority: 75,\n severity: 'low',\n description: 'Cisco certification ID',\n validator: (_value: string, context: string) => {\n return /cisco|ccna|ccnp|ccie|networking|certification|certified/i.test(context);\n }\n};\n\n/**\n * CompTIA Certification ID\n * Format: Alphanumeric\n * Issued by CompTIA for IT certifications\n */\nexport const COMPTIA_CERTIFICATION: PIIPattern = {\n type: 'COMPTIA_CERTIFICATION',\n regex: /\\bCOMPTIA[-\\s]?(?:CERT(?:IFICATION)?|ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{8,16})\\b/gi,\n placeholder: '[COMPTIA_{n}]',\n priority: 75,\n severity: 'low',\n description: 'CompTIA certification ID',\n validator: (_value: string, context: string) => {\n return /comptia|a\\+|security\\+|network\\+|certification|certified/i.test(context);\n }\n};\n\n/**\n * Series Licenses (Financial)\n * Format: CRD number (typically numeric)\n * FINRA licenses (Series 7, 63, 65, etc.)\n */\nexport const FINRA_LICENSE: PIIPattern = {\n type: 'FINRA_LICENSE',\n regex: /\\b(?:CRD|SERIES|FINRA)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{6,8})\\b/gi,\n placeholder: '[FINRA_{n}]',\n priority: 85,\n severity: 'high',\n description: 'FINRA license number (CRD, Series licenses)',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 6 || length > 8) return false;\n\n return /finra|crd|series|broker|dealer|securities|license|registered/i.test(context);\n }\n};\n\n// Export all professional certification patterns\nexport const professionalCertificationPatterns: PIIPattern[] = [\n PMP_CERTIFICATION,\n CPA_LICENSE,\n PE_LICENSE,\n NURSING_LICENSE,\n TEACHING_LICENSE,\n AWS_CERTIFICATION,\n MICROSOFT_CERTIFICATION,\n CISCO_CERTIFICATION,\n COMPTIA_CERTIFICATION,\n FINRA_LICENSE\n];\n","/**\n * Gaming & Esports Industry PII Patterns\n * For gaming platforms, esports, and competitive gaming\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Riot Games Account ID (Riot ID)\n * Format: Username#TagLine (e.g., Player#1234)\n * Used for League of Legends, Valorant, etc.\n */\nexport const RIOT_ID: PIIPattern = {\n type: 'RIOT_ID',\n regex: /\\b([a-zA-Z0-9_]{3,16})#([a-zA-Z0-9]{3,5})\\b/g,\n placeholder: '[RIOT_ID_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Riot Games account ID (Riot ID)',\n validator: (value: string, context: string) => {\n // Must contain # separator\n if (!value.includes('#')) return false;\n\n const [username, tagline] = value.split('#');\n if (username.length < 3 || username.length > 16) return false;\n if (tagline.length < 3 || tagline.length > 5) return false;\n\n // Context validation\n return /riot|league[- ]?of[- ]?legends|valorant|tft|teamfight[- ]?tactics|gaming/i.test(context);\n }\n};\n\n/**\n * Twitch Username\n * Format: Alphanumeric with underscores (4-25 chars)\n * Used for streaming platform\n */\nexport const TWITCH_USERNAME: PIIPattern = {\n type: 'TWITCH_USERNAME',\n regex: /\\bTWITCH[-\\s]?(?:USER|NAME|ID)?[-\\s]?[:#]?\\s*([a-zA-Z0-9_]{4,25})\\b/gi,\n placeholder: '[TWITCH_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Twitch username',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 4 || length > 25) return false;\n\n // Context validation\n return /twitch|streaming|streamer|channel|live|broadcast/i.test(context);\n }\n};\n\n/**\n * Esports Player ID\n * Format: Varies by platform (alphanumeric)\n * Generic esports tournament player ID\n */\nexport const ESPORTS_PLAYER_ID: PIIPattern = {\n type: 'ESPORTS_PLAYER_ID',\n regex: /\\b(?:PLAYER|COMPETITOR|PARTICIPANT)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[PLAYER_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Esports player/competitor ID',\n validator: (_value: string, context: string) => {\n return /esports|tournament|competition|player|competitor|gaming|league/i.test(context);\n }\n};\n\n/**\n * Gaming Tournament Registration ID\n * Format: Alphanumeric\n * Used for tournament sign-ups and brackets\n */\nexport const TOURNAMENT_REGISTRATION_ID: PIIPattern = {\n type: 'TOURNAMENT_REGISTRATION_ID',\n regex: /\\b(?:TOURNAMENT|BRACKET|REGISTRATION|REG)[-\\s]?(?:ID|NO|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[TOURNEY_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Gaming tournament registration ID',\n validator: (_value: string, context: string) => {\n return /tournament|bracket|registration|competition|event|gaming|esports/i.test(context);\n }\n};\n\n/**\n * Roblox User ID\n * Format: Numeric (1-12 digits)\n * Used for Roblox platform\n */\nexport const ROBLOX_USER_ID: PIIPattern = {\n type: 'ROBLOX_USER_ID',\n regex: /\\bROBLOX[-\\s]?(?:USER|ID)?[-\\s]?[:#]?\\s*(\\d{1,12})\\b/gi,\n placeholder: '[ROBLOX_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Roblox user ID',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 1 || length > 12) return false;\n\n // Context validation\n return /roblox|robux|user|player|gaming/i.test(context);\n }\n};\n\n/**\n * Minecraft UUID\n * Format: 32 hex characters (with or without hyphens)\n * Used for Minecraft player identification\n */\nexport const MINECRAFT_UUID: PIIPattern = {\n type: 'MINECRAFT_UUID',\n regex: /\\b([0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})\\b/gi,\n placeholder: '[MC_UUID_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Minecraft player UUID',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/-/g, '');\n if (cleaned.length !== 32) return false;\n\n // Must be valid hex\n if (!/^[0-9a-f]+$/i.test(cleaned)) return false;\n\n // Context validation\n return /minecraft|mc|mojang|player|uuid|server/i.test(context);\n }\n};\n\n/**\n * Fortnite Account ID\n * Format: Alphanumeric (32 chars)\n * Used for Epic Games Fortnite\n */\nexport const FORTNITE_ACCOUNT_ID: PIIPattern = {\n type: 'FORTNITE_ACCOUNT_ID',\n regex: /\\b(?:FORTNITE|FN)[-\\s]?(?:ACCOUNT|USER|ID)?[-\\s]?[:#]?\\s*([a-f0-9]{32})\\b/gi,\n placeholder: '[FN_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Fortnite account ID',\n validator: (value: string, context: string) => {\n if (value.length !== 32) return false;\n\n // Must be hex\n if (!/^[a-f0-9]+$/i.test(value)) return false;\n\n // Context validation\n return /fortnite|epic[- ]?games|battle[- ]?royale|gaming/i.test(context);\n }\n};\n\n/**\n * Call of Duty Player ID (Activision ID)\n * Format: Username#1234567\n * Used for COD franchise games\n */\nexport const COD_PLAYER_ID: PIIPattern = {\n type: 'COD_PLAYER_ID',\n regex: /\\b([a-zA-Z0-9_]{3,16})#(\\d{7})\\b/g,\n placeholder: '[COD_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Call of Duty / Activision player ID',\n validator: (value: string, context: string) => {\n if (!value.includes('#')) return false;\n\n const [username, id] = value.split('#');\n if (username.length < 3 || username.length > 16) return false;\n if (id.length !== 7) return false;\n\n // Context validation\n return /call[- ]?of[- ]?duty|cod|warzone|activision|gaming/i.test(context);\n }\n};\n\n/**\n * Apex Legends Player ID\n * Format: Alphanumeric\n * Used for Apex Legends (EA/Respawn)\n */\nexport const APEX_PLAYER_ID: PIIPattern = {\n type: 'APEX_PLAYER_ID',\n regex: /\\b(?:APEX|EA)[-\\s]?(?:ID|PLAYER)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,16})\\b/gi,\n placeholder: '[APEX_ID_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Apex Legends player ID',\n validator: (_value: string, context: string) => {\n return /apex[- ]?legends|apex|ea|respawn|gaming|player/i.test(context);\n }\n};\n\n/**\n * Dota 2 Friend ID\n * Format: 9-10 digit numeric\n * Used for Dota 2 (Steam-based)\n */\nexport const DOTA_FRIEND_ID: PIIPattern = {\n type: 'DOTA_FRIEND_ID',\n regex: /\\bDOTA[-\\s]?(?:ID|FRIEND)?[-\\s]?[:#]?\\s*(\\d{9,10})\\b/gi,\n placeholder: '[DOTA_ID_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Dota 2 friend ID',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 9 || length > 10) return false;\n\n // Context validation\n return /dota|steam|valve|gaming|player|moba/i.test(context);\n }\n};\n\n/**\n * CS:GO Friend Code\n * Format: XXXXX-XXXXX format\n * Used for Counter-Strike: Global Offensive\n */\nexport const CSGO_FRIEND_CODE: PIIPattern = {\n type: 'CSGO_FRIEND_CODE',\n regex: /\\b(?:CS:?GO|COUNTER[- ]?STRIKE)[-\\s]?(?:FRIEND[- ]?CODE|CODE)?[-\\s]?[:#]?\\s*([A-Z0-9]{5}-[A-Z0-9]{5})\\b/gi,\n placeholder: '[CSGO_CODE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'CS:GO friend code',\n validator: (value: string, context: string) => {\n // Must be in XXXXX-XXXXX format\n if (!/^[A-Z0-9]{5}-[A-Z0-9]{5}$/.test(value)) return false;\n\n // Context validation\n return /cs:?go|counter[- ]?strike|steam|valve|gaming/i.test(context);\n }\n};\n\n/**\n * Overwatch BattleTag\n * Format: Username#1234\n * Covered by BATTLETAG in digital-identity, but adding gaming context\n */\nexport const OVERWATCH_BATTLETAG: PIIPattern = {\n type: 'OVERWATCH_BATTLETAG',\n regex: /\\b([a-zA-Z][a-zA-Z0-9]{2,11})#(\\d{4,5})\\b/g,\n placeholder: '[OW_TAG_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Overwatch BattleTag',\n validator: (value: string, context: string) => {\n const parts = value.split('#');\n if (parts.length !== 2) return false;\n if (parts[0].length < 3 || parts[0].length > 12) return false;\n if (parts[1].length < 4 || parts[1].length > 5) return false;\n\n // Context validation - must mention Overwatch specifically\n return /overwatch|ow2|blizzard|gaming|player/i.test(context);\n }\n};\n\n// Export all gaming patterns\nexport const gamingPatterns: PIIPattern[] = [\n RIOT_ID,\n TWITCH_USERNAME,\n ESPORTS_PLAYER_ID,\n TOURNAMENT_REGISTRATION_ID,\n ROBLOX_USER_ID,\n MINECRAFT_UUID,\n FORTNITE_ACCOUNT_ID,\n COD_PLAYER_ID,\n APEX_PLAYER_ID,\n DOTA_FRIEND_ID,\n CSGO_FRIEND_CODE,\n OVERWATCH_BATTLETAG\n];\n","/**\n * Vehicle and Transportation Identifiers\n * License plates, VINs, and vehicle-related identifiers\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * Vehicle Identification Number (VIN)\n * Format: 17 characters (letters and digits, no I, O, Q)\n */\nexport const VIN_NUMBER: PIIPattern = {\n type: 'VIN_NUMBER',\n regex: /\\bVIN[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-HJ-NPR-Z0-9]{17})\\b/gi,\n placeholder: '[VIN_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Vehicle Identification Number (VIN)',\n validator: (value: string, context: string) => {\n // VINs don't use I, O, or Q to avoid confusion with 1, 0\n if (/[IOQ]/i.test(value)) return false;\n\n // Must be in vehicle context\n return /vin|vehicle|car|auto|motor|registration|title|insurance/i.test(context);\n }\n};\n\n/**\n * US License Plates - Generic Pattern\n * Matches most US state formats (3-8 alphanumeric characters)\n */\nexport const US_LICENSE_PLATE: PIIPattern = {\n type: 'US_LICENSE_PLATE',\n regex: /\\b(?:PLATE|LICENSE|TAG)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{3,8})\\b/gi,\n placeholder: '[PLATE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'US License Plate',\n validator: (value: string, context: string) => {\n // Must be in vehicle/license context\n if (!/plate|license|tag|vehicle|car|registration|dmv/i.test(context)) {\n return false;\n }\n\n // Exclude pure numbers (likely not a plate)\n if (/^\\d+$/.test(value)) return false;\n\n // Exclude very short values\n if (value.length < 3) return false;\n\n return true;\n }\n};\n\n/**\n * California License Plate\n * Format: 1ABC234 (digit + 3 letters + 3 digits)\n */\nexport const CALIFORNIA_LICENSE_PLATE: PIIPattern = {\n type: 'CALIFORNIA_LICENSE_PLATE',\n regex: /\\b(\\d[A-Z]{3}\\d{3})\\b/g,\n placeholder: '[CA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'California License Plate',\n validator: (_value: string, context: string) => {\n return /california|ca\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * New York License Plate\n * Format: ABC1234 or ABC-1234\n */\nexport const NEW_YORK_LICENSE_PLATE: PIIPattern = {\n type: 'NEW_YORK_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}-?\\d{4})\\b/g,\n placeholder: '[NY_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'New York License Plate',\n validator: (_value: string, context: string) => {\n return /new\\s?york|ny\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Texas License Plate\n * Format: ABC1234 or AB1-C234\n */\nexport const TEXAS_LICENSE_PLATE: PIIPattern = {\n type: 'TEXAS_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4}|[A-Z]{2}\\d-[A-Z]\\d{3})\\b/g,\n placeholder: '[TX_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Texas License Plate',\n validator: (_value: string, context: string) => {\n return /texas|tx\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Florida License Plate\n * Format: ABC D12 or ABCD 12\n */\nexport const FLORIDA_LICENSE_PLATE: PIIPattern = {\n type: 'FLORIDA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3,4}\\s[A-Z]?\\d{2})\\b/g,\n placeholder: '[FL_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Florida License Plate',\n validator: (_value: string, context: string) => {\n return /florida|fl\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Illinois License Plate\n * Format: AB12345 (2 letters + 5 digits)\n */\nexport const ILLINOIS_LICENSE_PLATE: PIIPattern = {\n type: 'ILLINOIS_LICENSE_PLATE',\n regex: /\\b([A-Z]{2}\\d{5})\\b/g,\n placeholder: '[IL_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Illinois License Plate',\n validator: (_value: string, context: string) => {\n return /illinois|il\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Pennsylvania License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const PENNSYLVANIA_LICENSE_PLATE: PIIPattern = {\n type: 'PENNSYLVANIA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[PA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Pennsylvania License Plate',\n validator: (_value: string, context: string) => {\n return /pennsylvania|pa\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Ohio License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const OHIO_LICENSE_PLATE: PIIPattern = {\n type: 'OHIO_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[OH_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Ohio License Plate',\n validator: (_value: string, context: string) => {\n return /ohio|oh\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Michigan License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const MICHIGAN_LICENSE_PLATE: PIIPattern = {\n type: 'MICHIGAN_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[MI_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Michigan License Plate',\n validator: (_value: string, context: string) => {\n return /michigan|mi\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Georgia License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const GEORGIA_LICENSE_PLATE: PIIPattern = {\n type: 'GEORGIA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[GA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Georgia License Plate',\n validator: (_value: string, context: string) => {\n return /georgia|ga\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * North Carolina License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const NORTH_CAROLINA_LICENSE_PLATE: PIIPattern = {\n type: 'NORTH_CAROLINA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[NC_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'North Carolina License Plate',\n validator: (_value: string, context: string) => {\n return /north\\s?carolina|nc\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * New Jersey License Plate\n * Format: A12BCD (letter + 2 digits + 3 letters)\n */\nexport const NEW_JERSEY_LICENSE_PLATE: PIIPattern = {\n type: 'NEW_JERSEY_LICENSE_PLATE',\n regex: /\\b([A-Z]\\d{2}[A-Z]{3})\\b/g,\n placeholder: '[NJ_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'New Jersey License Plate',\n validator: (_value: string, context: string) => {\n return /new\\s?jersey|nj\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Virginia License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const VIRGINIA_LICENSE_PLATE: PIIPattern = {\n type: 'VIRGINIA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[VA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Virginia License Plate',\n validator: (_value: string, context: string) => {\n return /virginia|va\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Washington License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const WASHINGTON_LICENSE_PLATE: PIIPattern = {\n type: 'WASHINGTON_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[WA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Washington License Plate',\n validator: (_value: string, context: string) => {\n return /washington|wa\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Massachusetts License Plate\n * Format: 1ABC23 (digit + 3 letters + 2 digits)\n */\nexport const MASSACHUSETTS_LICENSE_PLATE: PIIPattern = {\n type: 'MASSACHUSETTS_LICENSE_PLATE',\n regex: /\\b(\\d[A-Z]{3}\\d{2})\\b/g,\n placeholder: '[MA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Massachusetts License Plate',\n validator: (_value: string, context: string) => {\n return /massachusetts|ma\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Arizona License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const ARIZONA_LICENSE_PLATE: PIIPattern = {\n type: 'ARIZONA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[AZ_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Arizona License Plate',\n validator: (_value: string, context: string) => {\n return /arizona|az\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Tennessee License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const TENNESSEE_LICENSE_PLATE: PIIPattern = {\n type: 'TENNESSEE_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[TN_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Tennessee License Plate',\n validator: (_value: string, context: string) => {\n return /tennessee|tn\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Indiana License Plate\n * Format: 123ABC (3 digits + 3 letters)\n */\nexport const INDIANA_LICENSE_PLATE: PIIPattern = {\n type: 'INDIANA_LICENSE_PLATE',\n regex: /\\b(\\d{3}[A-Z]{3})\\b/g,\n placeholder: '[IN_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Indiana License Plate',\n validator: (_value: string, context: string) => {\n return /indiana|in\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Missouri License Plate\n * Format: AB1C2D (2 letters + digit + letter + digit + letter)\n */\nexport const MISSOURI_LICENSE_PLATE: PIIPattern = {\n type: 'MISSOURI_LICENSE_PLATE',\n regex: /\\b([A-Z]{2}\\d[A-Z]\\d[A-Z])\\b/g,\n placeholder: '[MO_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Missouri License Plate',\n validator: (_value: string, context: string) => {\n return /missouri|mo\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Maryland License Plate\n * Format: 1AB2345 (digit + 2 letters + 4 digits)\n */\nexport const MARYLAND_LICENSE_PLATE: PIIPattern = {\n type: 'MARYLAND_LICENSE_PLATE',\n regex: /\\b(\\d[A-Z]{2}\\d{4})\\b/g,\n placeholder: '[MD_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Maryland License Plate',\n validator: (_value: string, context: string) => {\n return /maryland|md\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Wisconsin License Plate\n * Format: ABC1234 (3 letters + 4 digits)\n */\nexport const WISCONSIN_LICENSE_PLATE: PIIPattern = {\n type: 'WISCONSIN_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{4})\\b/g,\n placeholder: '[WI_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Wisconsin License Plate',\n validator: (_value: string, context: string) => {\n return /wisconsin|wi\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Colorado License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const COLORADO_LICENSE_PLATE: PIIPattern = {\n type: 'COLORADO_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[CO_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Colorado License Plate',\n validator: (_value: string, context: string) => {\n return /colorado|co\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Minnesota License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const MINNESOTA_LICENSE_PLATE: PIIPattern = {\n type: 'MINNESOTA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[MN_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Minnesota License Plate',\n validator: (_value: string, context: string) => {\n return /minnesota|mn\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * South Carolina License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const SOUTH_CAROLINA_LICENSE_PLATE: PIIPattern = {\n type: 'SOUTH_CAROLINA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[SC_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'South Carolina License Plate',\n validator: (_value: string, context: string) => {\n return /south\\s?carolina|sc\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Alabama License Plate\n * Format: 12AB345 (2 digits + 2 letters + 3 digits)\n */\nexport const ALABAMA_LICENSE_PLATE: PIIPattern = {\n type: 'ALABAMA_LICENSE_PLATE',\n regex: /\\b(\\d{2}[A-Z]{2}\\d{3})\\b/g,\n placeholder: '[AL_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Alabama License Plate',\n validator: (_value: string, context: string) => {\n return /alabama|al\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Louisiana License Plate\n * Format: 123ABC (3 digits + 3 letters)\n */\nexport const LOUISIANA_LICENSE_PLATE: PIIPattern = {\n type: 'LOUISIANA_LICENSE_PLATE',\n regex: /\\b(\\d{3}[A-Z]{3})\\b/g,\n placeholder: '[LA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Louisiana License Plate',\n validator: (_value: string, context: string) => {\n return /louisiana|la\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Kentucky License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const KENTUCKY_LICENSE_PLATE: PIIPattern = {\n type: 'KENTUCKY_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[KY_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Kentucky License Plate',\n validator: (_value: string, context: string) => {\n return /kentucky|ky\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Oregon License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const OREGON_LICENSE_PLATE: PIIPattern = {\n type: 'OREGON_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[OR_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Oregon License Plate',\n validator: (_value: string, context: string) => {\n return /oregon|or\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Oklahoma License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const OKLAHOMA_LICENSE_PLATE: PIIPattern = {\n type: 'OKLAHOMA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[OK_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Oklahoma License Plate',\n validator: (_value: string, context: string) => {\n return /oklahoma|ok\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Connecticut License Plate\n * Format: 123ABC or ABC123\n */\nexport const CONNECTICUT_LICENSE_PLATE: PIIPattern = {\n type: 'CONNECTICUT_LICENSE_PLATE',\n regex: /\\b(\\d{3}[A-Z]{3}|[A-Z]{3}\\d{3})\\b/g,\n placeholder: '[CT_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Connecticut License Plate',\n validator: (_value: string, context: string) => {\n return /connecticut|ct\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Utah License Plate\n * Format: A12BCD (letter + 2 digits + 3 letters)\n */\nexport const UTAH_LICENSE_PLATE: PIIPattern = {\n type: 'UTAH_LICENSE_PLATE',\n regex: /\\b([A-Z]\\d{2}[A-Z]{3})\\b/g,\n placeholder: '[UT_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Utah License Plate',\n validator: (_value: string, context: string) => {\n return /utah|ut\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Iowa License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const IOWA_LICENSE_PLATE: PIIPattern = {\n type: 'IOWA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[IA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Iowa License Plate',\n validator: (_value: string, context: string) => {\n return /iowa|ia\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Nevada License Plate\n * Format: 12A345 (2 digits + letter + 3 digits)\n */\nexport const NEVADA_LICENSE_PLATE: PIIPattern = {\n type: 'NEVADA_LICENSE_PLATE',\n regex: /\\b(\\d{2}[A-Z]\\d{3})\\b/g,\n placeholder: '[NV_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Nevada License Plate',\n validator: (_value: string, context: string) => {\n return /nevada|nv\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Arkansas License Plate\n * Format: 123ABC (3 digits + 3 letters)\n */\nexport const ARKANSAS_LICENSE_PLATE: PIIPattern = {\n type: 'ARKANSAS_LICENSE_PLATE',\n regex: /\\b(\\d{3}[A-Z]{3})\\b/g,\n placeholder: '[AR_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Arkansas License Plate',\n validator: (_value: string, context: string) => {\n return /arkansas|ar\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Mississippi License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const MISSISSIPPI_LICENSE_PLATE: PIIPattern = {\n type: 'MISSISSIPPI_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[MS_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Mississippi License Plate',\n validator: (_value: string, context: string) => {\n return /mississippi|ms\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Kansas License Plate\n * Format: 123ABC (3 digits + 3 letters)\n */\nexport const KANSAS_LICENSE_PLATE: PIIPattern = {\n type: 'KANSAS_LICENSE_PLATE',\n regex: /\\b(\\d{3}[A-Z]{3})\\b/g,\n placeholder: '[KS_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Kansas License Plate',\n validator: (_value: string, context: string) => {\n return /kansas|ks\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * New Mexico License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const NEW_MEXICO_LICENSE_PLATE: PIIPattern = {\n type: 'NEW_MEXICO_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[NM_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'New Mexico License Plate',\n validator: (_value: string, context: string) => {\n return /new\\s?mexico|nm\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Nebraska License Plate\n * Format: A12345 (letter + 5 digits)\n */\nexport const NEBRASKA_LICENSE_PLATE: PIIPattern = {\n type: 'NEBRASKA_LICENSE_PLATE',\n regex: /\\b([A-Z]\\d{5})\\b/g,\n placeholder: '[NE_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Nebraska License Plate',\n validator: (_value: string, context: string) => {\n return /nebraska|ne\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * West Virginia License Plate\n * Format: 1AB234 (digit + 2 letters + 3 digits)\n */\nexport const WEST_VIRGINIA_LICENSE_PLATE: PIIPattern = {\n type: 'WEST_VIRGINIA_LICENSE_PLATE',\n regex: /\\b(\\d[A-Z]{2}\\d{3})\\b/g,\n placeholder: '[WV_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'West Virginia License Plate',\n validator: (_value: string, context: string) => {\n return /west\\s?virginia|wv\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Idaho License Plate\n * Format: 1A12345 (digit + letter + 5 digits)\n */\nexport const IDAHO_LICENSE_PLATE: PIIPattern = {\n type: 'IDAHO_LICENSE_PLATE',\n regex: /\\b(\\d[A-Z]\\d{5})\\b/g,\n placeholder: '[ID_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Idaho License Plate',\n validator: (_value: string, context: string) => {\n return /idaho|id\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Hawaii License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const HAWAII_LICENSE_PLATE: PIIPattern = {\n type: 'HAWAII_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[HI_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Hawaii License Plate',\n validator: (_value: string, context: string) => {\n return /hawaii|hi\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * New Hampshire License Plate\n * Format: 123AB or 1234AB\n */\nexport const NEW_HAMPSHIRE_LICENSE_PLATE: PIIPattern = {\n type: 'NEW_HAMPSHIRE_LICENSE_PLATE',\n regex: /\\b(\\d{3,4}[A-Z]{2})\\b/g,\n placeholder: '[NH_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'New Hampshire License Plate',\n validator: (_value: string, context: string) => {\n return /new\\s?hampshire|nh\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Maine License Plate\n * Format: 1234AB (4 digits + 2 letters)\n */\nexport const MAINE_LICENSE_PLATE: PIIPattern = {\n type: 'MAINE_LICENSE_PLATE',\n regex: /\\b(\\d{4}[A-Z]{2})\\b/g,\n placeholder: '[ME_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Maine License Plate',\n validator: (_value: string, context: string) => {\n return /maine|me\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Montana License Plate\n * Format: 1-12345A (digit dash 5 digits letter)\n */\nexport const MONTANA_LICENSE_PLATE: PIIPattern = {\n type: 'MONTANA_LICENSE_PLATE',\n regex: /\\b(\\d-\\d{5}[A-Z])\\b/g,\n placeholder: '[MT_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Montana License Plate',\n validator: (_value: string, context: string) => {\n return /montana|mt\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Rhode Island License Plate\n * Format: 123456 (6 digits)\n */\nexport const RHODE_ISLAND_LICENSE_PLATE: PIIPattern = {\n type: 'RHODE_ISLAND_LICENSE_PLATE',\n regex: /\\b(\\d{6})\\b/g,\n placeholder: '[RI_PLATE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Rhode Island License Plate',\n validator: (_value: string, context: string) => {\n return /rhode\\s?island|ri\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Delaware License Plate\n * Format: 123456 (6 digits)\n */\nexport const DELAWARE_LICENSE_PLATE: PIIPattern = {\n type: 'DELAWARE_LICENSE_PLATE',\n regex: /\\b(\\d{6})\\b/g,\n placeholder: '[DE_PLATE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Delaware License Plate',\n validator: (_value: string, context: string) => {\n return /delaware|de\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * South Dakota License Plate\n * Format: 12A345 (2 digits + letter + 3 digits)\n */\nexport const SOUTH_DAKOTA_LICENSE_PLATE: PIIPattern = {\n type: 'SOUTH_DAKOTA_LICENSE_PLATE',\n regex: /\\b(\\d{2}[A-Z]\\d{3})\\b/g,\n placeholder: '[SD_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'South Dakota License Plate',\n validator: (_value: string, context: string) => {\n return /south\\s?dakota|sd\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * North Dakota License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const NORTH_DAKOTA_LICENSE_PLATE: PIIPattern = {\n type: 'NORTH_DAKOTA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[ND_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'North Dakota License Plate',\n validator: (_value: string, context: string) => {\n return /north\\s?dakota|nd\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Alaska License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const ALASKA_LICENSE_PLATE: PIIPattern = {\n type: 'ALASKA_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[AK_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Alaska License Plate',\n validator: (_value: string, context: string) => {\n return /alaska|ak\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Vermont License Plate\n * Format: ABC123 (3 letters + 3 digits)\n */\nexport const VERMONT_LICENSE_PLATE: PIIPattern = {\n type: 'VERMONT_LICENSE_PLATE',\n regex: /\\b([A-Z]{3}\\d{3})\\b/g,\n placeholder: '[VT_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Vermont License Plate',\n validator: (_value: string, context: string) => {\n return /vermont|vt\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * Wyoming License Plate\n * Format: 12345 (5 digits)\n */\nexport const WYOMING_LICENSE_PLATE: PIIPattern = {\n type: 'WYOMING_LICENSE_PLATE',\n regex: /\\b(\\d{5})\\b/g,\n placeholder: '[WY_PLATE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Wyoming License Plate',\n validator: (_value: string, context: string) => {\n return /wyoming|wy\\s|plate|license|dmv|vehicle/i.test(context);\n }\n};\n\n/**\n * UK Vehicle Registration (License Plate)\n * Format: AB12 CDE or AB12CDE\n */\nexport const UK_LICENSE_PLATE: PIIPattern = {\n type: 'UK_LICENSE_PLATE',\n regex: /\\b([A-Z]{2}\\d{2}\\s?[A-Z]{3})\\b/g,\n placeholder: '[UK_PLATE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'UK Vehicle Registration Plate',\n validator: (_value: string, context: string) => {\n return /uk|british|britain|registration|number\\s?plate|vehicle|dvla/i.test(context);\n }\n};\n\n/**\n * German License Plate\n * Format: AB-CD 1234 (city code + letters + numbers)\n */\nexport const GERMAN_LICENSE_PLATE: PIIPattern = {\n type: 'GERMAN_LICENSE_PLATE',\n regex: /\\b([A-ZÄÖÜ]{1,3}[-\\s][A-ZÄÖÜ]{1,2}\\s?\\d{1,4})\\b/gi,\n placeholder: '[DE_PLATE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'German License Plate (Kennzeichen)',\n validator: (_value: string, context: string) => {\n return /german|deutschland|kennzeichen|license|plate|vehicle|kfz/i.test(context);\n }\n};\n\n/**\n * French License Plate\n * Format: AB-123-CD\n */\nexport const FRENCH_LICENSE_PLATE: PIIPattern = {\n type: 'FRENCH_LICENSE_PLATE',\n regex: /\\b([A-Z]{2}-\\d{3}-[A-Z]{2})\\b/gi,\n placeholder: '[FR_PLATE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'French License Plate (Plaque d\\'immatriculation)',\n validator: (_value: string, context: string) => {\n return /french|france|immatriculation|license|plate|vehicle/i.test(context);\n }\n};\n\n/**\n * Canadian License Plate\n * Format: ABCD 123 (varies by province)\n */\nexport const CANADIAN_LICENSE_PLATE: PIIPattern = {\n type: 'CANADIAN_LICENSE_PLATE',\n regex: /\\b([A-Z]{3,4}[-\\s]?\\d{3,4})\\b/g,\n placeholder: '[CA_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Canadian License Plate',\n validator: (_value: string, context: string) => {\n return /canad|ontario|quebec|british\\s?columbia|alberta|plate|license|vehicle/i.test(context);\n }\n};\n\n/**\n * Australian License Plate\n * Format: ABC123 or ABC-123 (varies by state)\n */\nexport const AUSTRALIAN_LICENSE_PLATE: PIIPattern = {\n type: 'AUSTRALIAN_LICENSE_PLATE',\n regex: /\\b([A-Z]{2,3}[-\\s]?\\d{2,4})\\b/g,\n placeholder: '[AU_PLATE_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Australian License Plate',\n validator: (_value: string, context: string) => {\n return /australia|nsw|victoria|queensland|south\\s?australia|plate|license|rego|registration/i.test(context);\n }\n};\n\n/**\n * Japanese License Plate\n * Format: XX 12-34 or Region 123 あ 12-34\n */\nexport const JAPANESE_LICENSE_PLATE: PIIPattern = {\n type: 'JAPANESE_LICENSE_PLATE',\n regex: /\\b([あ-ん]{1}\\s?\\d{2}-\\d{2}|\\d{2,3}\\s?[あ-ん]\\s?\\d{2}-\\d{2})\\b/g,\n placeholder: '[JP_PLATE_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Japanese License Plate (ナンバープレート)',\n validator: (_value: string, context: string) => {\n return /japan|japanese|ナンバー|車両|plate|license|vehicle/i.test(context);\n }\n};\n\n/**\n * Generic International License Plate\n * Fallback pattern for other countries\n */\nexport const INTERNATIONAL_LICENSE_PLATE: PIIPattern = {\n type: 'INTERNATIONAL_LICENSE_PLATE',\n regex: /\\b(?:PLATE|REGISTRATION|TAG)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{4,10})\\b/gi,\n placeholder: '[PLATE_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'International License Plate',\n validator: (_value: string, context: string) => {\n return /plate|registration|license|vehicle|car|motor/i.test(context);\n }\n};\n\nexport const vehiclePatterns: PIIPattern[] = [\n VIN_NUMBER,\n US_LICENSE_PLATE,\n CALIFORNIA_LICENSE_PLATE,\n NEW_YORK_LICENSE_PLATE,\n TEXAS_LICENSE_PLATE,\n FLORIDA_LICENSE_PLATE,\n ILLINOIS_LICENSE_PLATE,\n PENNSYLVANIA_LICENSE_PLATE,\n OHIO_LICENSE_PLATE,\n MICHIGAN_LICENSE_PLATE,\n GEORGIA_LICENSE_PLATE,\n NORTH_CAROLINA_LICENSE_PLATE,\n NEW_JERSEY_LICENSE_PLATE,\n VIRGINIA_LICENSE_PLATE,\n WASHINGTON_LICENSE_PLATE,\n MASSACHUSETTS_LICENSE_PLATE,\n ARIZONA_LICENSE_PLATE,\n TENNESSEE_LICENSE_PLATE,\n INDIANA_LICENSE_PLATE,\n MISSOURI_LICENSE_PLATE,\n MARYLAND_LICENSE_PLATE,\n WISCONSIN_LICENSE_PLATE,\n COLORADO_LICENSE_PLATE,\n MINNESOTA_LICENSE_PLATE,\n SOUTH_CAROLINA_LICENSE_PLATE,\n ALABAMA_LICENSE_PLATE,\n LOUISIANA_LICENSE_PLATE,\n KENTUCKY_LICENSE_PLATE,\n OREGON_LICENSE_PLATE,\n OKLAHOMA_LICENSE_PLATE,\n CONNECTICUT_LICENSE_PLATE,\n UTAH_LICENSE_PLATE,\n IOWA_LICENSE_PLATE,\n NEVADA_LICENSE_PLATE,\n ARKANSAS_LICENSE_PLATE,\n MISSISSIPPI_LICENSE_PLATE,\n KANSAS_LICENSE_PLATE,\n NEW_MEXICO_LICENSE_PLATE,\n NEBRASKA_LICENSE_PLATE,\n WEST_VIRGINIA_LICENSE_PLATE,\n IDAHO_LICENSE_PLATE,\n HAWAII_LICENSE_PLATE,\n NEW_HAMPSHIRE_LICENSE_PLATE,\n MAINE_LICENSE_PLATE,\n MONTANA_LICENSE_PLATE,\n RHODE_ISLAND_LICENSE_PLATE,\n DELAWARE_LICENSE_PLATE,\n SOUTH_DAKOTA_LICENSE_PLATE,\n NORTH_DAKOTA_LICENSE_PLATE,\n ALASKA_LICENSE_PLATE,\n VERMONT_LICENSE_PLATE,\n WYOMING_LICENSE_PLATE,\n UK_LICENSE_PLATE,\n GERMAN_LICENSE_PLATE,\n FRENCH_LICENSE_PLATE,\n CANADIAN_LICENSE_PLATE,\n AUSTRALIAN_LICENSE_PLATE,\n JAPANESE_LICENSE_PLATE,\n INTERNATIONAL_LICENSE_PLATE\n];\n","/**\n * Logistics and Shipping Identifiers\n * Tracking numbers, container numbers, bill of lading\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * FedEx Tracking Number\n * Format: 12 digits or 15 digits, or 20 digits (SmartPost)\n */\nexport const FEDEX_TRACKING: PIIPattern = {\n type: 'FEDEX_TRACKING',\n regex: /\\b(?:FEDEX|FDX)[-\\s]?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{12}|\\d{15}|\\d{20})\\b/gi,\n placeholder: '[FEDEX_TRACK_{n}]',\n priority: 85,\n severity: 'low',\n description: 'FedEx tracking number',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 12 && len !== 15 && len !== 20) return false;\n\n return /fedex|fed\\s?ex|fdx|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * UPS Tracking Number\n * Format: 1Z + 16 characters\n */\nexport const UPS_TRACKING: PIIPattern = {\n type: 'UPS_TRACKING',\n regex: /\\b(?:UPS[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(1Z[A-Z0-9]{16})\\b/gi,\n placeholder: '[UPS_TRACK_{n}]',\n priority: 90,\n severity: 'low',\n description: 'UPS tracking number',\n validator: (value: string, context: string) => {\n if (!value.startsWith('1Z')) return false;\n if (value.length !== 18) return false;\n\n return /ups|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * USPS Tracking Number\n * Format: Various formats (20-22 digits)\n */\nexport const USPS_TRACKING: PIIPattern = {\n type: 'USPS_TRACKING',\n regex: /\\b(?:USPS|US\\s?MAIL)[-\\s]?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{20,22}|[A-Z]{2}\\d{9}US)\\b/gi,\n placeholder: '[USPS_TRACK_{n}]',\n priority: 85,\n severity: 'low',\n description: 'USPS tracking number',\n validator: (value: string, context: string) => {\n // USPS Priority Mail: starts with 9 and 20-22 digits\n // USPS Certified Mail: 20 digits\n // USPS International: 13 chars with US suffix\n if (value.includes('US')) {\n return value.length === 13 && /^[A-Z]{2}\\d{9}US$/.test(value);\n }\n\n const len = value.length;\n if (len < 20 || len > 22) return false;\n\n return /usps|us\\s?mail|postal|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * DHL Tracking Number\n * Format: 10-11 digits\n */\nexport const DHL_TRACKING: PIIPattern = {\n type: 'DHL_TRACKING',\n regex: /\\b(?:DHL[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{10,11})\\b/gi,\n placeholder: '[DHL_TRACK_{n}]',\n priority: 85,\n severity: 'low',\n description: 'DHL tracking number',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 10 && len !== 11) return false;\n\n return /dhl|tracking|shipment|package|delivery|express/i.test(context);\n }\n};\n\n/**\n * Amazon Tracking (TBA)\n * Format: TBA + 12 digits\n */\nexport const AMAZON_TRACKING: PIIPattern = {\n type: 'AMAZON_TRACKING',\n regex: /\\b(TBA\\d{12})\\b/gi,\n placeholder: '[AMAZON_TRACK_{n}]',\n priority: 90,\n severity: 'low',\n description: 'Amazon tracking number',\n validator: (value: string, _context: string) => {\n return value.startsWith('TBA') && value.length === 15;\n }\n};\n\n/**\n * TNT Express Tracking Number\n * Format: 9 digits or 13 alphanumeric\n */\nexport const TNT_TRACKING: PIIPattern = {\n type: 'TNT_TRACKING',\n regex: /\\b(?:TNT[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{9}|[A-Z0-9]{13})\\b/gi,\n placeholder: '[TNT_TRACK_{n}]',\n priority: 85,\n severity: 'low',\n description: 'TNT Express tracking number',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 9 && len !== 13) return false;\n\n return /tnt|tracking|shipment|package|delivery|express/i.test(context);\n }\n};\n\n/**\n * China Post Tracking Number\n * Format: 13 characters (starts with R or C, ends with CN)\n */\nexport const CHINA_POST_TRACKING: PIIPattern = {\n type: 'CHINA_POST_TRACKING',\n regex: /\\b(?:CHINA\\s?POST[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([RC][A-Z]\\d{9}CN)\\b/gi,\n placeholder: '[CHINA_POST_{n}]',\n priority: 85,\n severity: 'low',\n description: 'China Post tracking number',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n if (!value.endsWith('CN')) return false;\n if (!/^[RC]/.test(value)) return false;\n\n return /china\\s?post|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * Japan Post Tracking Number\n * Format: 13 characters (2 letters + 9 digits + JP)\n */\nexport const JAPAN_POST_TRACKING: PIIPattern = {\n type: 'JAPAN_POST_TRACKING',\n regex: /\\b(?:JAPAN\\s?POST[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}\\d{9}JP)\\b/gi,\n placeholder: '[JAPAN_POST_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Japan Post tracking number',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n if (!value.endsWith('JP')) return false;\n\n return /japan\\s?post|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * Royal Mail Tracking Number (UK)\n * Format: 13 characters (2 letters + 9 digits + GB)\n */\nexport const ROYAL_MAIL_TRACKING: PIIPattern = {\n type: 'ROYAL_MAIL_TRACKING',\n regex: /\\b(?:ROYAL\\s?MAIL[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}\\d{9}GB)\\b/gi,\n placeholder: '[ROYAL_MAIL_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Royal Mail tracking number',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n if (!value.endsWith('GB')) return false;\n\n return /royal\\s?mail|tracking|shipment|package|delivery|post\\s?office/i.test(context);\n }\n};\n\n/**\n * Canada Post Tracking Number\n * Format: 16 digits\n */\nexport const CANADA_POST_TRACKING: PIIPattern = {\n type: 'CANADA_POST_TRACKING',\n regex: /\\b(?:CANADA\\s?POST[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{16})\\b/gi,\n placeholder: '[CANADA_POST_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Canada Post tracking number',\n validator: (value: string, context: string) => {\n if (value.length !== 16) return false;\n\n return /canada\\s?post|tracking|shipment|package|delivery|postes|canada/i.test(context);\n }\n};\n\n/**\n * Australia Post Tracking Number\n * Format: 13 characters (2 letters + 9 digits + AU)\n */\nexport const AUSTRALIA_POST_TRACKING: PIIPattern = {\n type: 'AUSTRALIA_POST_TRACKING',\n regex: /\\b(?:AUSTRALIA\\s?POST[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}\\d{9}AU)\\b/gi,\n placeholder: '[AUSTRALIA_POST_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Australia Post tracking number',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n if (!value.endsWith('AU')) return false;\n\n return /australia\\s?post|aus\\s?post|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * Purolator Tracking Number (Canada)\n * Format: 12 digits or PIN format\n */\nexport const PUROLATOR_TRACKING: PIIPattern = {\n type: 'PUROLATOR_TRACKING',\n regex: /\\b(?:PUROLATOR[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER|PIN)?[-\\s]?[:#]?\\s*(\\d{12}|P\\d{10})\\b/gi,\n placeholder: '[PUROLATOR_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Purolator tracking number',\n validator: (value: string, context: string) => {\n if (value.startsWith('P')) {\n return value.length === 11;\n }\n if (value.length !== 12) return false;\n\n return /purolator|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * OnTrac Tracking Number\n * Format: C + 14 digits\n */\nexport const ONTRAC_TRACKING: PIIPattern = {\n type: 'ONTRAC_TRACKING',\n regex: /\\b(?:ONTRAC|ON\\s?TRAC|LASERSHIP)[-\\s]?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(C\\d{14})\\b/gi,\n placeholder: '[ONTRAC_{n}]',\n priority: 85,\n severity: 'low',\n description: 'OnTrac/LaserShip tracking number',\n validator: (value: string, context: string) => {\n if (!value.startsWith('C')) return false;\n if (value.length !== 15) return false;\n\n return /ontrac|on\\s?trac|lasership|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * GLS Tracking Number (Europe)\n * Format: Various formats, typically 11-13 digits\n */\nexport const GLS_TRACKING: PIIPattern = {\n type: 'GLS_TRACKING',\n regex: /\\b(?:GLS[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{11,13})\\b/gi,\n placeholder: '[GLS_{n}]',\n priority: 80,\n severity: 'low',\n description: 'GLS tracking number (Europe)',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len < 11 || len > 13) return false;\n\n return /gls|general\\s?logistics|tracking|shipment|package|delivery/i.test(context);\n }\n};\n\n/**\n * Aramex Tracking Number (Middle East)\n * Format: 11-12 digits\n */\nexport const ARAMEX_TRACKING: PIIPattern = {\n type: 'ARAMEX_TRACKING',\n regex: /\\b(?:ARAMEX[-\\s]?)?(?:TRACK(?:ING)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{11,12})\\b/gi,\n placeholder: '[ARAMEX_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Aramex tracking number',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 11 && len !== 12) return false;\n\n return /aramex|tracking|shipment|package|delivery|express/i.test(context);\n }\n};\n\n/**\n * Generic Tracking Number\n * Fallback for other carriers\n */\nexport const GENERIC_TRACKING_NUMBER: PIIPattern = {\n type: 'GENERIC_TRACKING_NUMBER',\n regex: /\\b(?:TRACK(?:ING)?|SHIPMENT|PACKAGE)[-\\s]?(?:ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{10,25})\\b/gi,\n placeholder: '[TRACKING_{n}]',\n priority: 70,\n severity: 'low',\n description: 'Generic tracking number',\n validator: (value: string, context: string) => {\n // Must be in shipping context\n if (!/track|ship|package|delivery|carrier|freight/i.test(context)) {\n return false;\n }\n\n // Reasonable length for tracking numbers\n const len = value.length;\n return len >= 10 && len <= 25;\n }\n};\n\n/**\n * Bill of Lading (BOL)\n * Format: Varies, typically alphanumeric\n */\nexport const BILL_OF_LADING: PIIPattern = {\n type: 'BILL_OF_LADING',\n regex: /\\b(?:BOL|B\\/L|BILL\\s?OF\\s?LADING)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,20})\\b/gi,\n placeholder: '[BOL_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Bill of Lading number',\n validator: (_value: string, context: string) => {\n return /bill\\s?of\\s?lading|bol|b\\/l|shipping|freight|cargo|shipment/i.test(context);\n }\n};\n\n/**\n * Container Number (Shipping Container)\n * Format: 4 letters + 7 digits (ISO 6346)\n */\nexport const SHIPPING_CONTAINER_NUMBER: PIIPattern = {\n type: 'SHIPPING_CONTAINER_NUMBER',\n regex: /\\b([A-Z]{4}\\d{7})\\b/g,\n placeholder: '[CONTAINER_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Shipping container number (ISO 6346)',\n validator: (value: string, context: string) => {\n // ISO 6346 format: 3 letters (owner) + U/J/Z + 6 digits + check digit\n if (!/^[A-Z]{3}[UJZ]\\d{7}$/.test(value)) return false;\n\n return /container|shipping|freight|cargo|iso\\s?6346/i.test(context);\n }\n};\n\n/**\n * Air Waybill (AWB) Number\n * Format: 3 digits (airline code) + 8 digits\n */\nexport const AIR_WAYBILL_NUMBER: PIIPattern = {\n type: 'AIR_WAYBILL_NUMBER',\n regex: /\\b(?:AWB|AIR\\s?WAYBILL)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{3}[-\\s]?\\d{8})\\b/gi,\n placeholder: '[AWB_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Air Waybill number',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n if (digits.length !== 11) return false;\n\n return /awb|air\\s?waybill|air\\s?freight|cargo|shipment/i.test(context);\n }\n};\n\n/**\n * Pro Number (Freight)\n * Format: Varies, typically 9-10 digits\n */\nexport const PRO_NUMBER: PIIPattern = {\n type: 'PRO_NUMBER',\n regex: /\\bPRO[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{9,10})\\b/gi,\n placeholder: '[PRO_{n}]',\n priority: 85,\n severity: 'low',\n description: 'PRO number (freight)',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 9 && len !== 10) return false;\n\n return /pro\\s?number|freight|ltl|shipment|carrier/i.test(context);\n }\n};\n\n/**\n * Master Airway Bill (MAWB)\n * Format: 3 digits + 8 digits\n */\nexport const MASTER_AIRWAY_BILL: PIIPattern = {\n type: 'MASTER_AIRWAY_BILL',\n regex: /\\bMAWB[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{3}[-\\s]?\\d{8})\\b/gi,\n placeholder: '[MAWB_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Master Airway Bill',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n if (digits.length !== 11) return false;\n\n return /mawb|master\\s?airway|consolidation|freight|cargo/i.test(context);\n }\n};\n\nexport const logisticsPatterns: PIIPattern[] = [\n FEDEX_TRACKING,\n UPS_TRACKING,\n USPS_TRACKING,\n DHL_TRACKING,\n AMAZON_TRACKING,\n TNT_TRACKING,\n CHINA_POST_TRACKING,\n JAPAN_POST_TRACKING,\n ROYAL_MAIL_TRACKING,\n CANADA_POST_TRACKING,\n AUSTRALIA_POST_TRACKING,\n PUROLATOR_TRACKING,\n ONTRAC_TRACKING,\n GLS_TRACKING,\n ARAMEX_TRACKING,\n GENERIC_TRACKING_NUMBER,\n BILL_OF_LADING,\n SHIPPING_CONTAINER_NUMBER,\n AIR_WAYBILL_NUMBER,\n PRO_NUMBER,\n MASTER_AIRWAY_BILL\n];\n","/**\n * Aviation Industry Identifiers\n * IATA codes, flight numbers, aircraft identifiers\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * IATA Airport Code\n * Format: 3 letters (e.g., JFK, LAX, LHR)\n */\nexport const IATA_AIRPORT_CODE: PIIPattern = {\n type: 'IATA_AIRPORT_CODE',\n regex: /\\b(?:AIRPORT|FROM|TO|VIA|IATA)[-\\s]?(?:CODE)?[-\\s]?[:#]?\\s*([A-Z]{3})\\b/gi,\n placeholder: '[AIRPORT_{n}]',\n priority: 75,\n severity: 'low',\n description: 'IATA Airport Code',\n validator: (_value: string, context: string) => {\n return /airport|iata|flight|departure|arrival|terminal/i.test(context);\n }\n};\n\n/**\n * Flight Number\n * Format: 2-3 letter airline code + 1-4 digits (e.g., AA123, BA4567)\n */\nexport const FLIGHT_NUMBER: PIIPattern = {\n type: 'FLIGHT_NUMBER',\n regex: /\\b(?:FLIGHT|FLT)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2,3}\\s?\\d{1,4})\\b/gi,\n placeholder: '[FLIGHT_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Flight Number',\n validator: (value: string, context: string) => {\n const clean = value.replace(/\\s/g, '');\n // Airline code (2-3 letters) + flight number (1-4 digits)\n if (!/^[A-Z]{2,3}\\d{1,4}$/.test(clean)) return false;\n\n return /flight|airline|departure|arrival|boarding|gate/i.test(context);\n }\n};\n\n/**\n * Aircraft Tail Number (N-Number for US)\n * Format: N followed by 1-5 alphanumeric characters\n */\nexport const AIRCRAFT_TAIL_NUMBER: PIIPattern = {\n type: 'AIRCRAFT_TAIL_NUMBER',\n regex: /\\b(N[1-9][0-9]{0,4}[A-Z]{0,2})\\b/g,\n placeholder: '[TAIL_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Aircraft Tail Number (US N-Number)',\n validator: (value: string, _context: string) => {\n // US tail numbers start with N\n if (!value.startsWith('N')) return false;\n // Length between 2-6 characters\n if (value.length < 2 || value.length > 6) return false;\n // Cannot start with N0\n if (value[1] === '0') return false;\n\n return true;\n }\n};\n\n/**\n * International Aircraft Registration\n * Format: Country prefix (1-2 letters) + alphanumeric\n */\nexport const AIRCRAFT_REGISTRATION: PIIPattern = {\n type: 'AIRCRAFT_REGISTRATION',\n regex: /\\b(?:REGISTRATION|REG|TAIL)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{1,2}-[A-Z0-9]{3,5})\\b/gi,\n placeholder: '[AIRCRAFT_REG_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'International Aircraft Registration',\n validator: (_value: string, context: string) => {\n return /aircraft|plane|aviation|registration|tail\\s?number/i.test(context);\n }\n};\n\n/**\n * FAA Airman Certificate Number\n * Format: 7-8 digits\n */\nexport const FAA_AIRMAN_CERTIFICATE: PIIPattern = {\n type: 'FAA_AIRMAN_CERTIFICATE',\n regex: /\\b(?:FAA|AIRMAN|PILOT)[-\\s]?(?:CERT(?:IFICATE)?|LICENSE)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{7,8})\\b/gi,\n placeholder: '[FAA_CERT_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'FAA Airman Certificate Number',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 7 && len !== 8) return false;\n\n return /faa|airman|pilot|certificate|license|aviation/i.test(context);\n }\n};\n\n/**\n * ICAO Aircraft Type Designator\n * Format: 2-4 characters (e.g., B738, A320, B77W)\n */\nexport const ICAO_AIRCRAFT_TYPE: PIIPattern = {\n type: 'ICAO_AIRCRAFT_TYPE',\n regex: /\\b(?:AIRCRAFT|TYPE|ICAO)[-\\s]?(?:CODE|DESIGNATOR)?[-\\s]?[:#]?\\s*([A-Z][0-9][A-Z0-9]{1,2})\\b/gi,\n placeholder: '[AIRCRAFT_TYPE_{n}]',\n priority: 70,\n severity: 'low',\n description: 'ICAO Aircraft Type Designator',\n validator: (_value: string, context: string) => {\n return /aircraft|type|icao|model|boeing|airbus/i.test(context);\n }\n};\n\n/**\n * Aircraft Mode S Code (24-bit ICAO address)\n * Format: 6 hexadecimal characters\n */\nexport const AIRCRAFT_MODE_S: PIIPattern = {\n type: 'AIRCRAFT_MODE_S',\n regex: /\\b(?:MODE\\s?S|ICAO\\s?ADDRESS)[-\\s]?[:#]?\\s*([A-F0-9]{6})\\b/gi,\n placeholder: '[MODE_S_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Aircraft Mode S Code (ICAO 24-bit address)',\n validator: (value: string, context: string) => {\n if (value.length !== 6) return false;\n if (!/^[A-F0-9]{6}$/i.test(value)) return false;\n\n return /mode\\s?s|icao|aircraft|transponder|adsb/i.test(context);\n }\n};\n\n/**\n * Airline Booking Reference (PNR/Locator)\n * Format: 6 alphanumeric characters\n */\nexport const AIRLINE_BOOKING_REFERENCE: PIIPattern = {\n type: 'AIRLINE_BOOKING_REFERENCE',\n regex: /\\b(?:BOOKING|RESERVATION|LOCATOR|REFERENCE)[-\\s]?(?:CODE|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6})\\b/gi,\n placeholder: '[BOOKING_REF_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Airline Booking Reference/Locator',\n validator: (_value: string, context: string) => {\n return /booking|reservation|locator|reference|pnr|airline|flight/i.test(context);\n }\n};\n\n/**\n * IATA Airline Code\n * Format: 2 letters (e.g., AA, BA, DL)\n */\nexport const IATA_AIRLINE_CODE: PIIPattern = {\n type: 'IATA_AIRLINE_CODE',\n regex: /\\b(?:AIRLINE|CARRIER)[-\\s]?(?:CODE|IATA)?[-\\s]?[:#]?\\s*([A-Z]{2})\\b/gi,\n placeholder: '[AIRLINE_{n}]',\n priority: 70,\n severity: 'low',\n description: 'IATA Airline Code',\n validator: (_value: string, context: string) => {\n return /airline|carrier|iata|flight|aviation/i.test(context);\n }\n};\n\nexport const aviationPatterns: PIIPattern[] = [\n IATA_AIRPORT_CODE,\n FLIGHT_NUMBER,\n AIRCRAFT_TAIL_NUMBER,\n AIRCRAFT_REGISTRATION,\n FAA_AIRMAN_CERTIFICATE,\n ICAO_AIRCRAFT_TYPE,\n AIRCRAFT_MODE_S,\n AIRLINE_BOOKING_REFERENCE,\n IATA_AIRLINE_CODE\n];\n","/**\n * Maritime Industry Identifiers\n * Ship registration, IMO numbers, MMSI, maritime radio callsigns\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * IMO Ship Identification Number\n * Format: IMO followed by 7 digits\n */\nexport const IMO_NUMBER: PIIPattern = {\n type: 'IMO_NUMBER',\n regex: /\\bIMO[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{7})\\b/gi,\n placeholder: '[IMO_{n}]',\n priority: 90,\n severity: 'medium',\n description: 'IMO Ship Identification Number',\n validator: (value: string, context: string) => {\n if (value.length !== 7) return false;\n\n // IMO number checksum validation\n const digits = value.split('').map(Number);\n let sum = 0;\n for (let i = 0; i < 6; i++) {\n sum += digits[i] * (7 - i);\n }\n const checkDigit = sum % 10;\n\n if (checkDigit !== digits[6]) return false;\n\n return /imo|ship|vessel|maritime|shipping|marine/i.test(context);\n }\n};\n\n/**\n * MMSI (Maritime Mobile Service Identity)\n * Format: 9 digits\n */\nexport const MMSI_NUMBER: PIIPattern = {\n type: 'MMSI_NUMBER',\n regex: /\\bMMSI[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{9})\\b/gi,\n placeholder: '[MMSI_{n}]',\n priority: 90,\n severity: 'medium',\n description: 'MMSI (Maritime Mobile Service Identity)',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n // MMSI first 3 digits are MID (Maritime Identification Digits)\n // Valid range: 200-799\n const mid = parseInt(value.substring(0, 3));\n if (mid < 200 || mid > 799) return false;\n\n return /mmsi|maritime|ship|vessel|ais|vhf|radio/i.test(context);\n }\n};\n\n/**\n * Maritime Radio Callsign\n * Format: Varies by country, typically 3-7 alphanumeric\n */\nexport const MARITIME_CALLSIGN: PIIPattern = {\n type: 'MARITIME_CALLSIGN',\n regex: /\\b(?:CALLSIGN|CALL\\s?SIGN)[-\\s]?[:#]?\\s*([A-Z0-9]{3,7})\\b/gi,\n placeholder: '[CALLSIGN_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Maritime Radio Callsign',\n validator: (_value: string, context: string) => {\n return /callsign|call\\s?sign|radio|maritime|vessel|ship|vhf/i.test(context);\n }\n};\n\n/**\n * Official Ship Number\n * Format: Varies by country registry\n */\nexport const OFFICIAL_SHIP_NUMBER: PIIPattern = {\n type: 'OFFICIAL_SHIP_NUMBER',\n regex: /\\b(?:OFFICIAL|SHIP)[-\\s]?(?:NO|NUM|NUMBER)[-\\s]?[:#]?\\s*([A-Z0-9]{5,12})\\b/gi,\n placeholder: '[SHIP_NUM_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Official Ship Number',\n validator: (_value: string, context: string) => {\n return /official|ship|vessel|registration|registry|flag\\s?state/i.test(context);\n }\n};\n\n/**\n * Port State Control Inspection ID\n * Format: Varies, typically alphanumeric\n */\nexport const PSC_INSPECTION_ID: PIIPattern = {\n type: 'PSC_INSPECTION_ID',\n regex: /\\b(?:PSC|INSPECTION)[-\\s]?(?:ID|NO|NUM|NUMBER)[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[PSC_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Port State Control Inspection ID',\n validator: (_value: string, context: string) => {\n return /psc|port\\s?state|inspection|maritime|vessel|ship|compliance/i.test(context);\n }\n};\n\n/**\n * Seafarer Identification Number (SID)\n * Format: Country code + 9 alphanumeric (varies by issuing country)\n */\nexport const SEAFARER_ID: PIIPattern = {\n type: 'SEAFARER_ID',\n regex: /\\b(?:SEAFARER|MARINER|SID)[-\\s]?(?:ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2,3}[A-Z0-9]{9})\\b/gi,\n placeholder: '[SEAFARER_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Seafarer Identification Number',\n validator: (value: string, context: string) => {\n if (value.length < 11 || value.length > 12) return false;\n\n return /seafarer|mariner|sid|maritime|crew|seaman|sailor/i.test(context);\n }\n};\n\n/**\n * Lloyd's Register Number (LR Number)\n * Format: Alphanumeric, typically 7 characters\n */\nexport const LLOYDS_REGISTER_NUMBER: PIIPattern = {\n type: 'LLOYDS_REGISTER_NUMBER',\n regex: /\\b(?:LLOYD'?S?|LR)[-\\s]?(?:REG(?:ISTER)?|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{7})\\b/gi,\n placeholder: '[LR_NUM_{n}]',\n priority: 85,\n severity: 'low',\n description: 'Lloyd\\'s Register Number',\n validator: (_value: string, context: string) => {\n return /lloyd|lr|register|classification|ship|vessel|maritime/i.test(context);\n }\n};\n\nexport const maritimePatterns: PIIPattern[] = [\n IMO_NUMBER,\n MMSI_NUMBER,\n MARITIME_CALLSIGN,\n OFFICIAL_SHIP_NUMBER,\n PSC_INSPECTION_ID,\n SEAFARER_ID,\n LLOYDS_REGISTER_NUMBER\n];\n","/**\n * Environmental & Regulatory Identifiers\n * EPA IDs, permits, waste tracking, environmental compliance\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * EPA ID Number\n * Format: 2-letter state code + 9 alphanumeric characters\n */\nexport const EPA_ID_NUMBER: PIIPattern = {\n type: 'EPA_ID_NUMBER',\n regex: /\\bEPA[-\\s]?(?:ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}[A-Z0-9]{9})\\b/gi,\n placeholder: '[EPA_ID_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'EPA Identification Number',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n // First 2 characters should be state code\n const stateCode = value.substring(0, 2);\n const validStateCodes = /^[A-Z]{2}$/;\n if (!validStateCodes.test(stateCode)) return false;\n\n return /epa|environmental|hazardous|waste|rcra|generator/i.test(context);\n }\n};\n\n/**\n * NPDES Permit Number (National Pollutant Discharge Elimination System)\n * Format: 2-letter state + 7-9 alphanumeric\n */\nexport const NPDES_PERMIT: PIIPattern = {\n type: 'NPDES_PERMIT',\n regex: /\\bNPDES[-\\s]?(?:PERMIT|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}[A-Z0-9]{7,9})\\b/gi,\n placeholder: '[NPDES_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'NPDES Permit Number',\n validator: (_value: string, context: string) => {\n return /npdes|permit|discharge|wastewater|water\\s?quality/i.test(context);\n }\n};\n\n/**\n * Hazardous Waste Manifest Number\n * Format: 9 digits\n */\nexport const HAZARDOUS_WASTE_MANIFEST: PIIPattern = {\n type: 'HAZARDOUS_WASTE_MANIFEST',\n regex: /\\b(?:MANIFEST|WASTE)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{9})\\b/gi,\n placeholder: '[MANIFEST_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Hazardous Waste Manifest Number',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n return /manifest|hazardous|waste|rcra|generator|transporter/i.test(context);\n }\n};\n\n/**\n * Air Quality Permit Number\n * Format: Varies by state, typically alphanumeric\n */\nexport const AIR_QUALITY_PERMIT: PIIPattern = {\n type: 'AIR_QUALITY_PERMIT',\n regex: /\\b(?:AIR|EMISSION)[-\\s]?PERMIT[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[AIR_PERMIT_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Air Quality Permit Number',\n validator: (_value: string, context: string) => {\n return /air|emission|permit|quality|pollution|stack/i.test(context);\n }\n};\n\n/**\n * Water Quality Certificate Number\n * Format: Varies, typically alphanumeric\n */\nexport const WATER_QUALITY_CERTIFICATE: PIIPattern = {\n type: 'WATER_QUALITY_CERTIFICATE',\n regex: /\\bWATER[-\\s]?(?:QUALITY|CERT(?:IFICATE)?)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[WATER_CERT_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Water Quality Certificate Number',\n validator: (_value: string, context: string) => {\n return /water|quality|certificate|permit|discharge|wetland/i.test(context);\n }\n};\n\n/**\n * Storm Water Permit Number\n * Format: Varies, typically alphanumeric with state prefix\n */\nexport const STORM_WATER_PERMIT: PIIPattern = {\n type: 'STORM_WATER_PERMIT',\n regex: /\\bSTORM\\s?WATER[-\\s]?PERMIT[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{2}[A-Z0-9]{6,10})\\b/gi,\n placeholder: '[STORM_PERMIT_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Storm Water Permit Number',\n validator: (_value: string, context: string) => {\n return /storm|water|runoff|permit|npdes|swppp/i.test(context);\n }\n};\n\n/**\n * Underground Storage Tank (UST) ID\n * Format: Varies by state, typically alphanumeric\n */\nexport const UST_ID: PIIPattern = {\n type: 'UST_ID',\n regex: /\\bUST[-\\s]?(?:ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,12})\\b/gi,\n placeholder: '[UST_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Underground Storage Tank ID',\n validator: (_value: string, context: string) => {\n return /ust|underground|storage|tank|petroleum|fuel/i.test(context);\n }\n};\n\n/**\n * Facility ID (for environmental reporting)\n * Format: Varies, typically alphanumeric\n */\nexport const FACILITY_ID: PIIPattern = {\n type: 'FACILITY_ID',\n regex: /\\bFACILITY[-\\s]?ID[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[FACILITY_{n}]',\n priority: 75,\n severity: 'low',\n description: 'Environmental Facility ID',\n validator: (_value: string, context: string) => {\n return /facility|plant|site|environmental|epa|compliance/i.test(context);\n }\n};\n\n/**\n * Toxic Release Inventory (TRI) Facility ID\n * Format: 11 characters (typically numeric)\n */\nexport const TRI_FACILITY_ID: PIIPattern = {\n type: 'TRI_FACILITY_ID',\n regex: /\\bTRI[-\\s]?(?:FACILITY|ID)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{11})\\b/gi,\n placeholder: '[TRI_FAC_{n}]',\n priority: 85,\n severity: 'low',\n description: 'TRI Facility ID Number',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n return /tri|toxic\\s?release|inventory|facility|epa|emissions/i.test(context);\n }\n};\n\n/**\n * Spill Report Number\n * Format: Varies, typically alphanumeric\n */\nexport const SPILL_REPORT_NUMBER: PIIPattern = {\n type: 'SPILL_REPORT_NUMBER',\n regex: /\\bSPILL[-\\s]?(?:REPORT|NO|NUM|NUMBER)[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[SPILL_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Environmental Spill Report Number',\n validator: (_value: string, context: string) => {\n return /spill|release|incident|environmental|response|cleanup/i.test(context);\n }\n};\n\n/**\n * Remediation Site ID\n * Format: Varies, typically alphanumeric\n */\nexport const REMEDIATION_SITE_ID: PIIPattern = {\n type: 'REMEDIATION_SITE_ID',\n regex: /\\b(?:REMEDIATION|CLEANUP)[-\\s]?SITE[-\\s]?(?:ID|NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[REMEDIATION_{n}]',\n priority: 80,\n severity: 'low',\n description: 'Remediation Site ID',\n validator: (_value: string, context: string) => {\n return /remediation|cleanup|site|superfund|brownfield|contamination/i.test(context);\n }\n};\n\n/**\n * Environmental Compliance Certificate Number\n * Format: Varies, typically alphanumeric\n */\nexport const ENVIRONMENTAL_CERTIFICATE: PIIPattern = {\n type: 'ENVIRONMENTAL_CERTIFICATE',\n regex: /\\bENVIRONMENTAL[-\\s]?(?:CERT(?:IFICATE)?|COMPLIANCE)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z0-9]{6,15})\\b/gi,\n placeholder: '[ENV_CERT_{n}]',\n priority: 75,\n severity: 'low',\n description: 'Environmental Compliance Certificate',\n validator: (_value: string, context: string) => {\n return /environmental|compliance|certificate|permit|authorization/i.test(context);\n }\n};\n\nexport const environmentalPatterns: PIIPattern[] = [\n EPA_ID_NUMBER,\n NPDES_PERMIT,\n HAZARDOUS_WASTE_MANIFEST,\n AIR_QUALITY_PERMIT,\n WATER_QUALITY_CERTIFICATE,\n STORM_WATER_PERMIT,\n UST_ID,\n FACILITY_ID,\n TRI_FACILITY_ID,\n SPILL_REPORT_NUMBER,\n REMEDIATION_SITE_ID,\n ENVIRONMENTAL_CERTIFICATE\n];\n","/**\n * Middle East National ID Patterns\n * Comprehensive coverage for Gulf Cooperation Council (GCC) and regional countries\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * UAE Emirates ID\n * Format: 784-YYYY-NNNNNNN-C (15 digits)\n * Example: 784-1990-1234567-1\n */\nexport const UAE_EMIRATES_ID: PIIPattern = {\n type: 'UAE_EMIRATES_ID',\n regex: /\\b(784[-\\s]?\\d{4}[-\\s]?\\d{7}[-\\s]?\\d)\\b/g,\n placeholder: '[UAE_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'UAE Emirates ID (15 digits starting with 784)',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n\n // Must be exactly 15 digits and start with 784\n if (digits.length !== 15 || !digits.startsWith('784')) {\n return false;\n }\n\n // Context validation for better accuracy\n return /uae|emirates|dubai|abu[- ]?dhabi|national[- ]?id|emirates[- ]?id/i.test(context);\n }\n};\n\n/**\n * Saudi Arabia National ID\n * Format: 1NNNNNNNNN or 2NNNNNNNNN (10 digits)\n * First digit: 1 for Saudi nationals, 2 for residents (Iqama)\n * Example: 1234567890\n */\nexport const SAUDI_NATIONAL_ID: PIIPattern = {\n type: 'SAUDI_NATIONAL_ID',\n regex: /\\b([12]\\d{9})\\b/g,\n placeholder: '[SA_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Saudi Arabia National ID or Iqama (10 digits)',\n validator: (value: string, context: string) => {\n // Must be 10 digits starting with 1 or 2\n if (value.length !== 10) return false;\n if (!/^[12]/.test(value)) return false;\n\n // Context validation\n return /saudi|ksa|kingdom|iqama|national[- ]?id|muqeem/i.test(context);\n }\n};\n\n/**\n * Israel Teudat Zehut (ID Number)\n * Format: 9 digits with Luhn checksum\n * Example: 123456782\n */\nexport const ISRAEL_ID: PIIPattern = {\n type: 'ISRAEL_ID',\n regex: /\\b(\\d{9})\\b/g,\n placeholder: '[IL_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Israel Teudat Zehut ID number (9 digits with checksum)',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n // Context validation for better accuracy\n return /israel|teudat|zehut|israeli|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Turkey TC Kimlik No (Turkish ID Number)\n * Format: 11 digits with checksum algorithm\n * First digit cannot be 0\n * Example: 12345678901\n */\nexport const TURKEY_ID: PIIPattern = {\n type: 'TURKEY_ID',\n regex: /\\b([1-9]\\d{10})\\b/g,\n placeholder: '[TR_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Turkey TC Kimlik No (11 digits with checksum)',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n if (value[0] === '0') return false;\n\n // Context validation for better accuracy\n return /turkey|turkish|tc|kimlik|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Qatar ID (QID)\n * Format: 11 digits\n * Example: 12345678901\n */\nexport const QATAR_ID: PIIPattern = {\n type: 'QATAR_ID',\n regex: /\\b(\\d{11})\\b/g,\n placeholder: '[QA_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Qatar ID (QID) - 11 digits',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n // Context validation required to avoid false positives\n return /qatar|qid|doha|national[- ]?id|resident[- ]?permit/i.test(context);\n }\n};\n\n/**\n * Kuwait Civil ID\n * Format: 12 digits (YYMMDDSSSSC)\n * YY: Birth year, MM: Month, DD: Day, SSSS: Serial, C: Check digit\n * Example: 290010112345\n */\nexport const KUWAIT_CIVIL_ID: PIIPattern = {\n type: 'KUWAIT_CIVIL_ID',\n regex: /\\b(\\d{12})\\b/g,\n placeholder: '[KW_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kuwait Civil ID (12 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 12) return false;\n\n // Context validation required\n if (!/kuwait|civil[- ]?id|national[- ]?id/i.test(context)) {\n return false;\n }\n\n // Basic date validation (YYMMDD)\n const month = parseInt(value.substring(2, 4));\n const day = parseInt(value.substring(4, 6));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n/**\n * Bahrain CPR (Central Population Register)\n * Format: 9 digits (YYMMDDXXX)\n * YY: Birth year (e.g., 85 for 1985), MM: Month, DD: Day, XXX: Serial\n * Example: 850101123\n */\nexport const BAHRAIN_CPR: PIIPattern = {\n type: 'BAHRAIN_CPR',\n regex: /\\b(\\d{9})\\b/g,\n placeholder: '[BH_CPR_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Bahrain CPR (Central Population Register) - 9 digits',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n // Context validation required\n if (!/bahrain|cpr|central[- ]?population|national[- ]?id/i.test(context)) {\n return false;\n }\n\n // Date validation (YYMMDD)\n const month = parseInt(value.substring(2, 4));\n const day = parseInt(value.substring(4, 6));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n/**\n * Oman Civil ID\n * Format: 8 digits\n * Example: 12345678\n */\nexport const OMAN_CIVIL_ID: PIIPattern = {\n type: 'OMAN_CIVIL_ID',\n regex: /\\b(\\d{8})\\b/g,\n placeholder: '[OM_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Oman Civil ID (8 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n // Context validation required for 8-digit number\n return /oman|muscat|civil[- ]?id|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Jordan National ID\n * Format: 10 digits\n * Example: 1234567890\n */\nexport const JORDAN_NATIONAL_ID: PIIPattern = {\n type: 'JORDAN_NATIONAL_ID',\n regex: /\\b(\\d{10})\\b/g,\n placeholder: '[JO_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Jordan National ID (10 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 10) return false;\n\n // Context validation required\n return /jordan|amman|national[- ]?id|jordanian/i.test(context);\n }\n};\n\n/**\n * Lebanon National ID\n * Format: 7-8 digits\n * Example: 1234567\n */\nexport const LEBANON_NATIONAL_ID: PIIPattern = {\n type: 'LEBANON_NATIONAL_ID',\n regex: /\\b(\\d{7,8})\\b/g,\n placeholder: '[LB_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Lebanon National ID (7-8 digits)',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length !== 7 && length !== 8) return false;\n\n // Context validation required\n return /lebanon|lebanese|beirut|national[- ]?id/i.test(context);\n }\n};\n\n// Export all Middle East patterns\nexport const middleEastPatterns: PIIPattern[] = [\n UAE_EMIRATES_ID,\n SAUDI_NATIONAL_ID,\n ISRAEL_ID,\n TURKEY_ID,\n QATAR_ID,\n KUWAIT_CIVIL_ID,\n BAHRAIN_CPR,\n OMAN_CIVIL_ID,\n JORDAN_NATIONAL_ID,\n LEBANON_NATIONAL_ID\n];\n","/**\n * African National ID Patterns\n * Comprehensive coverage for major African economies\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * South Africa ID Number (RSA ID)\n * Format: 13 digits (YYMMDDSSSSCZZ)\n * YY: Birth year, MM: Month, DD: Day\n * SSSS: Sequence number (odd=male, even=female)\n * C: Citizenship (0=SA, 1=non-SA)\n * ZZ: Checksum (Luhn algorithm)\n */\nexport const SOUTH_AFRICA_ID: PIIPattern = {\n type: 'SOUTH_AFRICA_ID',\n regex: /\\b(\\d{13})\\b/g,\n placeholder: '[ZA_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'South African ID number (13 digits with date and checksum)',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n\n // Context validation required\n if (!/south[- ]?africa|rsa|za|national[- ]?id|identity|id[- ]?number/i.test(context)) {\n return false;\n }\n\n // Basic date validation (YYMMDD)\n const month = parseInt(value.substring(2, 4));\n const day = parseInt(value.substring(4, 6));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n/**\n * Nigeria National Identification Number (NIN)\n * Format: 11 digits\n * Example: 12345678901\n */\nexport const NIGERIA_NIN: PIIPattern = {\n type: 'NIGERIA_NIN',\n regex: /\\b(\\d{11})\\b/g,\n placeholder: '[NG_NIN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Nigeria National Identification Number (11 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n // Context validation required\n return /nigeria|nin|national[- ]?id|identity|nigerian/i.test(context);\n }\n};\n\n/**\n * Nigeria Bank Verification Number (BVN)\n * Format: 11 digits\n * Used by Nigerian banks for customer identification\n */\nexport const NIGERIA_BVN: PIIPattern = {\n type: 'NIGERIA_BVN',\n regex: /\\bBVN[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{11})\\b/gi,\n placeholder: '[NG_BVN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Nigeria Bank Verification Number',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n // Context validation required\n return /bvn|bank[- ]?verification|nigeria|nigerian|banking/i.test(context);\n }\n};\n\n/**\n * Kenya National ID Number\n * Format: 7-8 digits\n * Example: 12345678\n */\nexport const KENYA_NATIONAL_ID: PIIPattern = {\n type: 'KENYA_NATIONAL_ID',\n regex: /\\b(\\d{7,8})\\b/g,\n placeholder: '[KE_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kenya National ID number (7-8 digits)',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 7 || length > 8) return false;\n\n // Context validation required\n return /kenya|kenyan|national[- ]?id|identity/i.test(context);\n }\n};\n\n/**\n * Kenya Revenue Authority PIN (KRA PIN)\n * Format: A000000000X (letter + 9 digits + letter)\n * Used for tax identification\n */\nexport const KENYA_KRA_PIN: PIIPattern = {\n type: 'KENYA_KRA_PIN',\n regex: /\\b(A\\d{9}[A-Z])\\b/g,\n placeholder: '[KRA_PIN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kenya Revenue Authority PIN (tax number)',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n if (!value.startsWith('A')) return false;\n\n // Context validation required\n return /kra|kenya|revenue|authority|tax|pin|taxpayer/i.test(context);\n }\n};\n\n/**\n * Egypt National ID\n * Format: 14 digits (YYYYMMDDLLLCCG)\n * YYYY: Birth year, MM: Month, DD: Day\n * LLL: Location code, CC: Sequence, G: Gender\n */\nexport const EGYPT_NATIONAL_ID: PIIPattern = {\n type: 'EGYPT_NATIONAL_ID',\n regex: /\\b([12]\\d{13})\\b/g,\n placeholder: '[EG_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Egypt National ID (14 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 14) return false;\n\n // Context validation required\n if (!/egypt|egyptian|national[- ]?id|identity/i.test(context)) {\n return false;\n }\n\n // Basic format validation - first digit should be 1 or 2 (century)\n const century = parseInt(value[0]);\n if (century !== 1 && century !== 2) return false;\n\n // Basic date validation (YYMMDD portion)\n const month = parseInt(value.substring(5, 7));\n const day = parseInt(value.substring(7, 9));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n/**\n * Ghana Card (National ID)\n * Format: GHA-XXXXXXXXX-X (15 characters)\n * Example: GHA-123456789-0\n */\nexport const GHANA_CARD: PIIPattern = {\n type: 'GHANA_CARD',\n regex: /\\b(GHA-\\d{9}-\\d)\\b/g,\n placeholder: '[GH_CARD_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ghana Card national ID',\n validator: (value: string, context: string) => {\n if (value.length !== 15) return false;\n if (!value.startsWith('GHA-')) return false;\n\n // Context validation required\n return /ghana|ghanaian|ghana[- ]?card|national[- ]?id|identity/i.test(context);\n }\n};\n\n/**\n * Morocco National ID (CNIE)\n * Format: Alphanumeric (various formats)\n * Example: AB123456 or 12345678\n */\nexport const MOROCCO_NATIONAL_ID: PIIPattern = {\n type: 'MOROCCO_NATIONAL_ID',\n regex: /\\b(?:CNIE|ID)[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*([A-Z]{1,2}\\d{6,8}|\\d{8})\\b/gi,\n placeholder: '[MA_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Morocco National ID (CNIE)',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 6 || length > 10) return false;\n\n // Context validation required\n return /morocco|moroccan|cnie|national[- ]?id|identity/i.test(context);\n }\n};\n\n// Export all Africa patterns\nexport const africaPatterns: PIIPattern[] = [\n SOUTH_AFRICA_ID,\n NIGERIA_NIN,\n NIGERIA_BVN,\n KENYA_NATIONAL_ID,\n KENYA_KRA_PIN,\n EGYPT_NATIONAL_ID,\n GHANA_CARD,\n MOROCCO_NATIONAL_ID\n];\n","/**\n * Southeast Asian National ID Patterns\n * Coverage for ASEAN countries\n */\n\nimport { PIIPattern } from '../../types';\n\n/**\n * Indonesia NIK (Nomor Induk Kependudukan)\n * Format: 16 digits (DDMMYY location codes)\n * Example: 1234567890123456\n */\nexport const INDONESIA_NIK: PIIPattern = {\n type: 'INDONESIA_NIK',\n regex: /\\b(\\d{16})\\b/g,\n placeholder: '[ID_NIK_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Indonesia NIK (National ID number, 16 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 16) return false;\n\n // Context validation required\n return /indonesia|indonesian|nik|nomor[- ]?induk|ktp|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Indonesia NPWP (Tax ID)\n * Format: 15 digits (XX.XXX.XXX.X-XXX.XXX)\n * Example: 12.345.678.9-012.345\n */\nexport const INDONESIA_NPWP: PIIPattern = {\n type: 'INDONESIA_NPWP',\n regex: /\\b(\\d{2}\\.?\\d{3}\\.?\\d{3}\\.?\\d[-\\.]?\\d{3}\\.?\\d{3})\\b/g,\n placeholder: '[ID_NPWP_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Indonesia NPWP (Tax ID number)',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/[.\\-]/g, '');\n if (cleaned.length !== 15) return false;\n\n // Context validation required\n return /indonesia|npwp|tax|pajak|wajib[- ]?pajak/i.test(context);\n }\n};\n\n/**\n * Thailand National ID\n * Format: 13 digits with checksum\n * Example: 1234567890123\n */\nexport const THAILAND_NATIONAL_ID: PIIPattern = {\n type: 'THAILAND_NATIONAL_ID',\n regex: /\\b(\\d{13})\\b/g,\n placeholder: '[TH_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Thailand National ID (13 digits with checksum)',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n\n // Context validation required\n if (!/thailand|thai|national[- ]?id|บัตร|ประชาชน/i.test(context)) {\n return false;\n }\n\n // Basic checksum validation (MOD 11)\n const digits = value.split('').map(Number);\n let sum = 0;\n for (let i = 0; i < 12; i++) {\n sum += digits[i] * (13 - i);\n }\n const checkDigit = (11 - (sum % 11)) % 10;\n return checkDigit === digits[12];\n }\n};\n\n/**\n * Malaysia MyKad (IC Number)\n * Format: 12 digits (YYMMDD-PB-####)\n * YY: Year, MM: Month, DD: Day, PB: Place of birth, ####: Serial\n */\nexport const MALAYSIA_MYKAD: PIIPattern = {\n type: 'MALAYSIA_MYKAD',\n regex: /\\b(\\d{6}[-\\s]?\\d{2}[-\\s]?\\d{4})\\b/g,\n placeholder: '[MY_IC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Malaysia MyKad/IC number (12 digits)',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/[-\\s]/g, '');\n if (cleaned.length !== 12) return false;\n\n // Context validation required\n if (!/malaysia|malaysian|mykad|ic[- ]?number|kad[- ]?pengenalan/i.test(context)) {\n return false;\n }\n\n // Basic date validation (YYMMDD)\n const month = parseInt(cleaned.substring(2, 4));\n const day = parseInt(cleaned.substring(4, 6));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n/**\n * Philippines UMID (Unified Multi-Purpose ID)\n * Format: 12 digits (XXXX-XXXXXXX-X)\n * Example: 1234-5678901-2\n */\nexport const PHILIPPINES_UMID: PIIPattern = {\n type: 'PHILIPPINES_UMID',\n regex: /\\b(\\d{4}[-\\s]?\\d{7}[-\\s]?\\d)\\b/g,\n placeholder: '[PH_UMID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Philippines UMID number (12 digits)',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/[-\\s]/g, '');\n if (cleaned.length !== 12) return false;\n\n // Context validation required\n return /philippines|filipino|umid|unified|multipurpose|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Vietnam CCCD (Citizen Identity Card)\n * Format: 12 digits\n * Example: 001234567890\n */\nexport const VIETNAM_CCCD: PIIPattern = {\n type: 'VIETNAM_CCCD',\n regex: /\\b(\\d{12})\\b/g,\n placeholder: '[VN_CCCD_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Vietnam CCCD (Citizen Identity Card, 12 digits)',\n validator: (value: string, context: string) => {\n if (value.length !== 12) return false;\n\n // Context validation required\n return /vietnam|vietnamese|cccd|citizen[- ]?identity|cmnd|national[- ]?id/i.test(context);\n }\n};\n\n/**\n * Myanmar NRC (National Registration Card)\n * Format: X/XXX(N)XXXXXX\n * Example: 12/OuKaMa(N)123456\n */\nexport const MYANMAR_NRC: PIIPattern = {\n type: 'MYANMAR_NRC',\n regex: /\\b(\\d{1,2}\\/[A-Z][a-z]+\\([NC]\\)\\d{6})\\b/g,\n placeholder: '[MM_NRC_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Myanmar NRC (National Registration Card)',\n validator: (value: string, context: string) => {\n // Must contain (N) or (C) indicator\n if (!/\\([NC]\\)/.test(value)) return false;\n\n // Context validation required\n return /myanmar|burmese|nrc|national[- ]?registration|identity/i.test(context);\n }\n};\n\n// Export all Southeast Asia patterns\nexport const southeastAsiaPatterns: PIIPattern[] = [\n INDONESIA_NIK,\n INDONESIA_NPWP,\n THAILAND_NATIONAL_ID,\n MALAYSIA_MYKAD,\n PHILIPPINES_UMID,\n VIETNAM_CCCD,\n MYANMAR_NRC\n];\n","/**\n * Latin American National IDs\n * Government identification numbers for Latin American countries\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * Argentina DNI (Documento Nacional de Identidad)\n * Format: 7-8 digits\n */\nexport const ARGENTINA_DNI: PIIPattern = {\n type: 'ARGENTINA_DNI',\n regex: /\\b(\\d{7,8})\\b/g,\n placeholder: '[AR_DNI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Argentina National ID (DNI)',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 7 && len !== 8) return false;\n\n return /argentina|argentin|dni|documento\\s?nacional|identidad/i.test(context);\n }\n};\n\n/**\n * Argentina CUIT/CUIL (Tax ID)\n * Format: XX-XXXXXXXX-X (11 digits with check digit)\n */\nexport const ARGENTINA_CUIT: PIIPattern = {\n type: 'ARGENTINA_CUIT',\n regex: /\\b(\\d{2}-\\d{8}-\\d{1})\\b/g,\n placeholder: '[AR_CUIT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Argentina CUIT/CUIL (Tax ID)',\n validator: (value: string, context: string) => {\n const digits = value.replace(/-/g, '');\n if (digits.length !== 11) return false;\n\n return /argentina|cuit|cuil|tax|impuesto|tributario/i.test(context);\n }\n};\n\n/**\n * Chile RUT (Rol Único Tributario)\n * Format: XX.XXX.XXX-X (8-9 digits + check digit K or 0-9)\n */\nexport const CHILE_RUT: PIIPattern = {\n type: 'CHILE_RUT',\n regex: /\\b(\\d{1,2}\\.\\d{3}\\.\\d{3}-[\\dKk])\\b/g,\n placeholder: '[CL_RUT_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Chile RUT (National ID/Tax ID)',\n validator: (value: string, context: string) => {\n // Remove formatting\n const clean = value.replace(/[.\\-]/g, '');\n\n // Must be 8-9 digits + check digit\n if (clean.length < 8 || clean.length > 9) return false;\n\n // Check digit validation (Modulo 11)\n const body = clean.slice(0, -1);\n const checkDigit = clean.slice(-1).toUpperCase();\n\n let sum = 0;\n let multiplier = 2;\n\n for (let i = body.length - 1; i >= 0; i--) {\n sum += parseInt(body[i]) * multiplier;\n multiplier = multiplier === 7 ? 2 : multiplier + 1;\n }\n\n const remainder = sum % 11;\n const expectedCheck = remainder === 0 ? '0' : remainder === 1 ? 'K' : String(11 - remainder);\n\n if (checkDigit !== expectedCheck) return false;\n\n return /chile|chilean|rut|rol\\s?único|tributario|cédula/i.test(context);\n }\n};\n\n/**\n * Colombia Cédula de Ciudadanía\n * Format: 6-10 digits\n */\nexport const COLOMBIA_CEDULA: PIIPattern = {\n type: 'COLOMBIA_CEDULA',\n regex: /\\b(?:CC|CÉDULA|CEDULA)[-\\s]?(?:NO|NUM)?[-\\s]?[:#]?\\s*(\\d{6,10})\\b/gi,\n placeholder: '[CO_CC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Colombia Cédula de Ciudadanía',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len < 6 || len > 10) return false;\n\n return /colombia|colombian|cédula|cedula|ciudadanía|cc\\s/i.test(context);\n }\n};\n\n/**\n * Colombia NIT (Tax ID for companies)\n * Format: 9 digits + check digit\n */\nexport const COLOMBIA_NIT: PIIPattern = {\n type: 'COLOMBIA_NIT',\n regex: /\\bNIT[-\\s]?(?:NO|NUM)?[-\\s]?[:#]?\\s*(\\d{9}-\\d{1})\\b/gi,\n placeholder: '[CO_NIT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Colombia NIT (Tax ID)',\n validator: (value: string, context: string) => {\n const digits = value.replace(/-/g, '');\n if (digits.length !== 10) return false;\n\n return /colombia|nit|tax|impuesto|tributario|empresa/i.test(context);\n }\n};\n\n/**\n * Peru DNI (Documento Nacional de Identidad)\n * Format: 8 digits\n */\nexport const PERU_DNI: PIIPattern = {\n type: 'PERU_DNI',\n regex: /\\b(\\d{8})\\b/g,\n placeholder: '[PE_DNI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Peru National ID (DNI)',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /peru|peruvian|perú|peruano|dni|documento\\s?nacional|identidad|reniec/i.test(context);\n }\n};\n\n/**\n * Peru RUC (Tax ID)\n * Format: 11 digits\n */\nexport const PERU_RUC: PIIPattern = {\n type: 'PERU_RUC',\n regex: /\\bRUC[-\\s]?(?:NO|NUM)?[-\\s]?[:#]?\\s*(\\d{11})\\b/gi,\n placeholder: '[PE_RUC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Peru RUC (Tax ID)',\n validator: (value: string, context: string) => {\n if (value.length !== 11) return false;\n\n // RUC starts with 10, 15, 17, or 20\n const prefix = value.substring(0, 2);\n if (!['10', '15', '17', '20'].includes(prefix)) return false;\n\n return /peru|perú|ruc|tax|sunat|tributario/i.test(context);\n }\n};\n\n/**\n * Venezuela Cédula de Identidad\n * Format: V-XXXXXXXX or E-XXXXXXXX (1-8 digits)\n */\nexport const VENEZUELA_CEDULA: PIIPattern = {\n type: 'VENEZUELA_CEDULA',\n regex: /\\b([VE]-\\d{1,8})\\b/gi,\n placeholder: '[VE_CI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Venezuela Cédula de Identidad',\n validator: (value: string, context: string) => {\n // V = Venezuelan, E = Foreign resident\n if (!value.toUpperCase().startsWith('V-') && !value.toUpperCase().startsWith('E-')) {\n return false;\n }\n\n return /venezuela|venezuelan|cédula|cedula|identidad|ci\\s/i.test(context);\n }\n};\n\n/**\n * Venezuela RIF (Tax ID)\n * Format: J-XXXXXXXX-X or V-XXXXXXXX-X\n */\nexport const VENEZUELA_RIF: PIIPattern = {\n type: 'VENEZUELA_RIF',\n regex: /\\b([VEJG]-\\d{8,9}-\\d{1})\\b/gi,\n placeholder: '[VE_RIF_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Venezuela RIF (Tax ID)',\n validator: (value: string, context: string) => {\n const prefix = value[0].toUpperCase();\n // V=Person, E=Foreign, J=Legal entity, G=Government\n if (!['V', 'E', 'J', 'G'].includes(prefix)) return false;\n\n return /venezuela|rif|tax|seniat|tributario/i.test(context);\n }\n};\n\n/**\n * Ecuador Cédula de Identidad\n * Format: 10 digits\n */\nexport const ECUADOR_CEDULA: PIIPattern = {\n type: 'ECUADOR_CEDULA',\n regex: /\\b(\\d{10})\\b/g,\n placeholder: '[EC_CI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ecuador Cédula de Identidad',\n validator: (value: string, context: string) => {\n if (value.length !== 10) return false;\n\n // Province code (first 2 digits) should be 01-24\n const province = parseInt(value.substring(0, 2));\n if (province < 1 || province > 24) return false;\n\n // Third digit should be 0-6 (0-5 for persons, 6 for public sector, 9 for legal entities)\n const thirdDigit = parseInt(value[2]);\n if (thirdDigit > 6 && thirdDigit !== 9) return false;\n\n return /ecuador|ecuadorian|cédula|cedula|identidad/i.test(context);\n }\n};\n\n/**\n * Uruguay Cédula de Identidad\n * Format: X.XXX.XXX-X (7 digits + check digit)\n */\nexport const URUGUAY_CEDULA: PIIPattern = {\n type: 'URUGUAY_CEDULA',\n regex: /\\b(\\d{1}\\.\\d{3}\\.\\d{3}-\\d{1})\\b/g,\n placeholder: '[UY_CI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Uruguay Cédula de Identidad',\n validator: (value: string, context: string) => {\n const digits = value.replace(/[.\\-]/g, '');\n if (digits.length !== 8) return false;\n\n return /uruguay|uruguayan|cédula|cedula|identidad/i.test(context);\n }\n};\n\nexport const latinAmericaPatterns: PIIPattern[] = [\n ARGENTINA_DNI,\n ARGENTINA_CUIT,\n CHILE_RUT,\n COLOMBIA_CEDULA,\n COLOMBIA_NIT,\n PERU_DNI,\n PERU_RUC,\n VENEZUELA_CEDULA,\n VENEZUELA_RIF,\n ECUADOR_CEDULA,\n URUGUAY_CEDULA\n];\n","/**\n * Eastern European National IDs\n * Government identification numbers for Eastern European countries\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * Russian Passport Number\n * Format: 10 digits (XXXX XXXXXX - series + number)\n */\nexport const RUSSIAN_PASSPORT: PIIPattern = {\n type: 'RUSSIAN_PASSPORT',\n regex: /\\b(\\d{4}\\s?\\d{6})\\b/g,\n placeholder: '[RU_PASSPORT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Russian Passport Number',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\s/g, '');\n if (digits.length !== 10) return false;\n\n return /russia|russian|passport|паспорт|российский/i.test(context);\n }\n};\n\n/**\n * Russian SNILS (Pension Fund Number)\n * Format: XXX-XXX-XXX XX (11 digits with check digits)\n */\nexport const RUSSIAN_SNILS: PIIPattern = {\n type: 'RUSSIAN_SNILS',\n regex: /\\b(\\d{3}-\\d{3}-\\d{3}\\s?\\d{2})\\b/g,\n placeholder: '[RU_SNILS_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Russian SNILS (Pension Fund Number)',\n validator: (value: string, context: string) => {\n const digits = value.replace(/[-\\s]/g, '');\n if (digits.length !== 11) return false;\n\n return /russia|russian|snils|снилс|pension|пенсионный/i.test(context);\n }\n};\n\n/**\n * Ukrainian Passport Number\n * Format: 2 letters + 6 digits (e.g., AA123456)\n */\nexport const UKRAINIAN_PASSPORT: PIIPattern = {\n type: 'UKRAINIAN_PASSPORT',\n regex: /\\b([A-Z]{2}\\d{6})\\b/g,\n placeholder: '[UA_PASSPORT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ukrainian Passport Number',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /ukrain|passport|паспорт|український/i.test(context);\n }\n};\n\n/**\n * Ukrainian Tax ID (INN)\n * Format: 10 digits\n */\nexport const UKRAINIAN_INN: PIIPattern = {\n type: 'UKRAINIAN_INN',\n regex: /\\bINN[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{10})\\b/gi,\n placeholder: '[UA_INN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Ukrainian Tax ID (INN)',\n validator: (value: string, context: string) => {\n if (value.length !== 10) return false;\n\n return /ukrain|inn|tax|податковий|інн/i.test(context);\n }\n};\n\n/**\n * Czech Republic National ID (Rodné číslo)\n * Format: YYMMDD/XXXX (10 digits with slash)\n */\nexport const CZECH_NATIONAL_ID: PIIPattern = {\n type: 'CZECH_NATIONAL_ID',\n regex: /\\b(\\d{6}\\/\\d{4})\\b/g,\n placeholder: '[CZ_ID_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Czech Republic National ID (Rodné číslo)',\n validator: (value: string, context: string) => {\n const parts = value.split('/');\n if (parts.length !== 2) return false;\n\n const datepart = parts[0];\n const serial = parts[1];\n\n if (datepart.length !== 6 || serial.length !== 4) return false;\n\n // Basic date validation (YYMMDD)\n const month = parseInt(datepart.substring(2, 4));\n const day = parseInt(datepart.substring(4, 6));\n\n // Month can be 01-12 (males) or 51-62 (females - add 50)\n const adjustedMonth = month > 50 ? month - 50 : month;\n if (adjustedMonth < 1 || adjustedMonth > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return /czech|czechia|republic|rodné|číslo|national\\s?id/i.test(context);\n }\n};\n\n/**\n * Romanian Personal Numeric Code (CNP)\n * Format: 13 digits\n */\nexport const ROMANIAN_CNP: PIIPattern = {\n type: 'ROMANIAN_CNP',\n regex: /\\bCNP[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{13})\\b/gi,\n placeholder: '[RO_CNP_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Romanian Personal Numeric Code (CNP)',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n\n // First digit: 1-2 (born 1900-1999), 3-4 (born 1800-1899), 5-6 (born 2000-2099), 7-8 (residents), 9 (foreign)\n const firstDigit = parseInt(value[0]);\n if (firstDigit < 1 || firstDigit > 9) return false;\n\n // Date part (positions 2-7): YYMMDD\n const month = parseInt(value.substring(3, 5));\n const day = parseInt(value.substring(5, 7));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return /romania|romanian|cnp|cod\\s?numeric|personal/i.test(context);\n }\n};\n\n/**\n * Hungarian Personal ID (Személyi igazolvány szám)\n * Format: 6 digits + 2 letters (e.g., 123456AB)\n */\nexport const HUNGARIAN_PERSONAL_ID: PIIPattern = {\n type: 'HUNGARIAN_PERSONAL_ID',\n regex: /\\b(\\d{6}[A-Z]{2})\\b/g,\n placeholder: '[HU_ID_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Hungarian Personal ID',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /hungar|magyar|személyi|igazolvány|personal\\s?id/i.test(context);\n }\n};\n\n/**\n * Hungarian Tax ID (Adóazonosító jel)\n * Format: 10 digits\n */\nexport const HUNGARIAN_TAX_ID: PIIPattern = {\n type: 'HUNGARIAN_TAX_ID',\n regex: /\\b(\\d{10})\\b/g,\n placeholder: '[HU_TAX_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Hungarian Tax ID (Adóazonosító jel)',\n validator: (value: string, context: string) => {\n if (value.length !== 10) return false;\n\n return /hungar|magyar|adó|tax|adóazonosító/i.test(context);\n }\n};\n\n/**\n * Bulgarian Personal Number (ЕГН - Единен граждански номер)\n * Format: 10 digits (YYMMDDXXXX)\n */\nexport const BULGARIAN_PERSONAL_NUMBER: PIIPattern = {\n type: 'BULGARIAN_PERSONAL_NUMBER',\n regex: /\\b(\\d{10})\\b/g,\n placeholder: '[BG_EGN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Bulgarian Personal Number (EGN)',\n validator: (value: string, context: string) => {\n if (value.length !== 10) return false;\n\n // Date validation (YYMMDD)\n const month = parseInt(value.substring(2, 4));\n const day = parseInt(value.substring(4, 6));\n\n // Month can be 01-12 or 21-32 (born before 1900) or 41-52 (born after 2000)\n const adjustedMonth = month > 40 ? month - 40 : month > 20 ? month - 20 : month;\n if (adjustedMonth < 1 || adjustedMonth > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return /bulgaria|bulgarian|егн|personal\\s?number|единен/i.test(context);\n }\n};\n\n/**\n * Serbian Personal ID (JMBG - Jedinstveni matični broj građana)\n * Format: 13 digits (DDMMYYYRRSSSC)\n */\nexport const SERBIAN_JMBG: PIIPattern = {\n type: 'SERBIAN_JMBG',\n regex: /\\b(\\d{13})\\b/g,\n placeholder: '[RS_JMBG_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Serbian Personal ID (JMBG)',\n validator: (value: string, context: string) => {\n if (value.length !== 13) return false;\n\n // Date validation (DDMMYYY)\n const day = parseInt(value.substring(0, 2));\n const month = parseInt(value.substring(2, 4));\n\n if (day < 1 || day > 31) return false;\n if (month < 1 || month > 12) return false;\n\n return /serb|serbia|jmbg|jedinstveni|matični|personal/i.test(context);\n }\n};\n\nexport const easternEuropePatterns: PIIPattern[] = [\n RUSSIAN_PASSPORT,\n RUSSIAN_SNILS,\n UKRAINIAN_PASSPORT,\n UKRAINIAN_INN,\n CZECH_NATIONAL_ID,\n ROMANIAN_CNP,\n HUNGARIAN_PERSONAL_ID,\n HUNGARIAN_TAX_ID,\n BULGARIAN_PERSONAL_NUMBER,\n SERBIAN_JMBG\n];\n","/**\n * Oceania & Pacific Island National IDs\n * Government identification numbers for Oceania and Pacific Island nations\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * New Zealand Driver License Number\n * Format: 2 letters + 6 digits (e.g., AB123456)\n */\nexport const NEW_ZEALAND_DRIVER_LICENSE: PIIPattern = {\n type: 'NEW_ZEALAND_DRIVER_LICENSE',\n regex: /\\b([A-Z]{2}\\d{6})\\b/g,\n placeholder: '[NZ_DL_{n}]',\n priority: 90,\n severity: 'high',\n description: 'New Zealand Driver License Number',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /new\\s?zealand|nz|kiwi|driver|license|licence/i.test(context);\n }\n};\n\n/**\n * New Zealand IRD Number (Tax ID)\n * Format: 8-9 digits with check digit\n */\nexport const NEW_ZEALAND_IRD: PIIPattern = {\n type: 'NEW_ZEALAND_IRD',\n regex: /\\bIRD[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{8,9})\\b/gi,\n placeholder: '[NZ_IRD_{n}]',\n priority: 90,\n severity: 'high',\n description: 'New Zealand IRD Number (Tax ID)',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 8 && len !== 9) return false;\n\n return /new\\s?zealand|nz|ird|tax|inland\\s?revenue/i.test(context);\n }\n};\n\n/**\n * New Zealand Passport Number\n * Format: 2 letters + 6 digits (e.g., LA123456)\n */\nexport const NEW_ZEALAND_PASSPORT: PIIPattern = {\n type: 'NEW_ZEALAND_PASSPORT',\n regex: /\\b([A-Z]{2}\\d{6})\\b/g,\n placeholder: '[NZ_PASSPORT_{n}]',\n priority: 85,\n severity: 'high',\n description: 'New Zealand Passport Number',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /new\\s?zealand|nz|passport|travel\\s?document/i.test(context);\n }\n};\n\n/**\n * Fiji National ID\n * Format: Varies, typically 8-10 alphanumeric\n */\nexport const FIJI_NATIONAL_ID: PIIPattern = {\n type: 'FIJI_NATIONAL_ID',\n regex: /\\b(?:FIJI|FJ)[-\\s]?(?:ID|NATIONAL\\s?ID)[-\\s]?[:#]?\\s*([A-Z0-9]{8,10})\\b/gi,\n placeholder: '[FJ_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Fiji National ID',\n validator: (_value: string, context: string) => {\n return /fiji|fijian|national\\s?id|identity/i.test(context);\n }\n};\n\n/**\n * Papua New Guinea National ID\n * Format: Varies, typically alphanumeric\n */\nexport const PNG_NATIONAL_ID: PIIPattern = {\n type: 'PNG_NATIONAL_ID',\n regex: /\\b(?:PNG|PAPUA)[-\\s]?(?:ID|NATIONAL\\s?ID)[-\\s]?[:#]?\\s*([A-Z0-9]{8,12})\\b/gi,\n placeholder: '[PNG_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Papua New Guinea National ID',\n validator: (_value: string, context: string) => {\n return /papua|png|new\\s?guinea|national\\s?id|identity/i.test(context);\n }\n};\n\n/**\n * Samoa National ID\n * Format: Varies, typically numeric\n */\nexport const SAMOA_NATIONAL_ID: PIIPattern = {\n type: 'SAMOA_NATIONAL_ID',\n regex: /\\b(?:SAMOA|WS)[-\\s]?(?:ID|NATIONAL\\s?ID)[-\\s]?[:#]?\\s*(\\d{8,10})\\b/gi,\n placeholder: '[WS_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Samoa National ID',\n validator: (_value: string, context: string) => {\n return /samoa|samoan|national\\s?id|identity/i.test(context);\n }\n};\n\n/**\n * Tonga National ID\n * Format: Varies, typically alphanumeric\n */\nexport const TONGA_NATIONAL_ID: PIIPattern = {\n type: 'TONGA_NATIONAL_ID',\n regex: /\\b(?:TONGA|TO)[-\\s]?(?:ID|NATIONAL\\s?ID)[-\\s]?[:#]?\\s*([A-Z0-9]{8,10})\\b/gi,\n placeholder: '[TO_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Tonga National ID',\n validator: (_value: string, context: string) => {\n return /tonga|tongan|national\\s?id|identity/i.test(context);\n }\n};\n\nexport const oceaniaPatterns: PIIPattern[] = [\n NEW_ZEALAND_DRIVER_LICENSE,\n NEW_ZEALAND_IRD,\n NEW_ZEALAND_PASSPORT,\n FIJI_NATIONAL_ID,\n PNG_NATIONAL_ID,\n SAMOA_NATIONAL_ID,\n TONGA_NATIONAL_ID\n];\n","/**\n * Central Asian National IDs\n * Government identification numbers for Central Asian countries\n */\n\nimport type { PIIPattern } from '../../types';\n\n/**\n * Kazakhstan Individual Identification Number (IIN)\n * Format: 12 digits (YYMMDDXXXXXX)\n */\nexport const KAZAKHSTAN_IIN: PIIPattern = {\n type: 'KAZAKHSTAN_IIN',\n regex: /\\bIIN[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{12})\\b/gi,\n placeholder: '[KZ_IIN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kazakhstan Individual Identification Number (IIN)',\n validator: (value: string, context: string) => {\n if (value.length !== 12) return false;\n\n // Basic date validation (first 6 digits: YYMMDD)\n const year = parseInt(value.substring(0, 2));\n const month = parseInt(value.substring(2, 4));\n const day = parseInt(value.substring(4, 6));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return /kazakh|kazakhstan|iin|жсн|individual\\s?identification/i.test(context);\n }\n};\n\n/**\n * Uzbekistan Passport Number\n * Format: 2 letters + 7 digits (e.g., AA1234567)\n */\nexport const UZBEKISTAN_PASSPORT: PIIPattern = {\n type: 'UZBEKISTAN_PASSPORT',\n regex: /\\b([A-Z]{2}\\d{7})\\b/g,\n placeholder: '[UZ_PASSPORT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Uzbekistan Passport Number',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n return /uzbek|uzbekistan|passport|pasport/i.test(context);\n }\n};\n\n/**\n * Uzbekistan Tax ID (STIR)\n * Format: 9 digits\n */\nexport const UZBEKISTAN_STIR: PIIPattern = {\n type: 'UZBEKISTAN_STIR',\n regex: /\\bSTIR[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{9})\\b/gi,\n placeholder: '[UZ_STIR_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Uzbekistan Tax ID (STIR)',\n validator: (value: string, context: string) => {\n if (value.length !== 9) return false;\n\n return /uzbek|uzbekistan|stir|tax|inn|soliq/i.test(context);\n }\n};\n\n/**\n * Kyrgyzstan Personal ID Number (PIN)\n * Format: 14 digits\n */\nexport const KYRGYZSTAN_PIN: PIIPattern = {\n type: 'KYRGYZSTAN_PIN',\n regex: /\\bPIN[-\\s]?(?:NO|NUM|NUMBER)?[-\\s]?[:#]?\\s*(\\d{14})\\b/gi,\n placeholder: '[KG_PIN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Kyrgyzstan Personal ID Number (PIN)',\n validator: (value: string, context: string) => {\n if (value.length !== 14) return false;\n\n return /kyrgyz|kyrgyzstan|pin|личный|номер/i.test(context);\n }\n};\n\n/**\n * Tajikistan National ID\n * Format: Varies, typically 9-10 digits\n */\nexport const TAJIKISTAN_NATIONAL_ID: PIIPattern = {\n type: 'TAJIKISTAN_NATIONAL_ID',\n regex: /\\b(?:TAJIK|TJ)[-\\s]?(?:ID|NATIONAL\\s?ID)[-\\s]?[:#]?\\s*(\\d{9,10})\\b/gi,\n placeholder: '[TJ_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Tajikistan National ID',\n validator: (value: string, context: string) => {\n const len = value.length;\n if (len !== 9 && len !== 10) return false;\n\n return /tajik|tajikistan|national\\s?id|identity/i.test(context);\n }\n};\n\n/**\n * Turkmenistan Passport Number\n * Format: 1 letter + 7 digits (e.g., A1234567)\n */\nexport const TURKMENISTAN_PASSPORT: PIIPattern = {\n type: 'TURKMENISTAN_PASSPORT',\n regex: /\\b([A-Z]\\d{7})\\b/g,\n placeholder: '[TM_PASSPORT_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Turkmenistan Passport Number',\n validator: (value: string, context: string) => {\n if (value.length !== 8) return false;\n\n return /turkmen|turkmenistan|passport|pasport/i.test(context);\n }\n};\n\nexport const centralAsiaPatterns: PIIPattern[] = [\n KAZAKHSTAN_IIN,\n UZBEKISTAN_PASSPORT,\n UZBEKISTAN_STIR,\n KYRGYZSTAN_PIN,\n TAJIKISTAN_NATIONAL_ID,\n TURKMENISTAN_PASSPORT\n];\n","/**\n * International PII Patterns\n * Government IDs and identification numbers for countries worldwide\n */\n\nimport { PIIPattern } from '../types';\nimport { middleEastPatterns } from './international/middle-east';\nimport { africaPatterns } from './international/africa';\nimport { southeastAsiaPatterns } from './international/southeast-asia';\nimport { latinAmericaPatterns } from './international/latin-america';\nimport { easternEuropePatterns } from './international/eastern-europe';\nimport { oceaniaPatterns } from './international/oceania';\nimport { centralAsiaPatterns } from './international/central-asia';\n\n// ==================== EUROPE ====================\n\n/**\n * German Tax ID (Steueridentifikationsnummer)\n * Format: 11 digits with checksum\n */\nexport const GERMAN_TAX_ID: PIIPattern = {\n type: 'GERMAN_TAX_ID',\n regex: /\\b(\\d{11})\\b/g,\n placeholder: '[DE_TAX_ID_{n}]',\n priority: 85,\n severity: 'high',\n description: 'German Tax Identification Number (Steueridentifikationsnummer)',\n validator: (value: string, context: string) => {\n // Must be in German/tax context\n const relevantContext = /steuer|tax|german|deutschland|finanzamt/i.test(context);\n if (!relevantContext) return false;\n\n // Checksum validation (simplified - full validation is complex)\n const digits = value.split('').map(Number);\n\n // Basic rules: exactly 11 digits, one digit appears 2 or 3 times, others max once\n const digitCounts = new Map<number, number>();\n digits.forEach(d => digitCounts.set(d, (digitCounts.get(d) || 0) + 1));\n\n const counts = Array.from(digitCounts.values());\n const hasDoubleOrTriple = counts.some(c => c === 2 || c === 3);\n const noQuadruple = counts.every(c => c <= 3);\n\n return hasDoubleOrTriple && noQuadruple;\n }\n};\n\n/**\n * French Social Security Number (Numéro de Sécurité Sociale)\n * Format: 15 digits (1 sex + 2 year + 2 month + 2 dept + 3 commune + 3 order + 2 key)\n */\nexport const FRENCH_SOCIAL_SECURITY: PIIPattern = {\n type: 'FRENCH_SOCIAL_SECURITY',\n regex: /\\b([12]\\s?\\d{2}\\s?\\d{2}\\s?\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{2})\\b/g,\n placeholder: '[FR_SSN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'French Social Security Number',\n validator: (value: string, _context: string) => {\n const cleaned = value.replace(/\\s/g, '');\n\n // Must start with 1 or 2 (sex)\n if (!/^[12]/.test(cleaned)) return false;\n\n // Year (positions 2-3) should be valid\n const year = parseInt(cleaned.substring(1, 3));\n if (year > 99) return false;\n\n // Month (positions 4-5) should be 01-12 or special codes\n const month = parseInt(cleaned.substring(3, 5));\n if (month < 1 || month > 20) return false; // 20 allows for special codes\n\n return true;\n }\n};\n\n/**\n * Spanish DNI/NIE (Documento Nacional de Identidad / Número de Identidad de Extranjero)\n * Format: 8 digits + 1 letter OR Letter + 7 digits + 1 letter\n */\nexport const SPANISH_DNI: PIIPattern = {\n type: 'SPANISH_DNI',\n regex: /\\b([0-9]{8}[-\\s]?[A-Z]|[XYZ][-\\s]?[0-9]{7}[-\\s]?[A-Z])\\b/gi,\n placeholder: '[ES_DNI_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Spanish National ID (DNI) or Foreigner ID (NIE)',\n validator: (value: string, _context: string) => {\n const cleaned = value.replace(/[-\\s]/g, '').toUpperCase();\n const letters = 'TRWAGMYFPDXBNJZSQVHLCKE';\n\n let numbers: string;\n let letter: string;\n\n if (/^[XYZ]/.test(cleaned)) {\n // NIE format\n numbers = cleaned.substring(1, 8);\n letter = cleaned[8];\n // Replace X, Y, Z with 0, 1, 2 for calculation\n const prefix = cleaned[0] === 'X' ? '0' : cleaned[0] === 'Y' ? '1' : '2';\n numbers = prefix + numbers;\n } else {\n // DNI format\n numbers = cleaned.substring(0, 8);\n letter = cleaned[8];\n }\n\n const num = parseInt(numbers);\n const expectedLetter = letters[num % 23];\n\n return letter === expectedLetter;\n }\n};\n\n/**\n * Italian Fiscal Code (Codice Fiscale)\n * Format: 16 characters (surname + name + birthdate + birthplace + checksum)\n */\nexport const ITALIAN_FISCAL_CODE: PIIPattern = {\n type: 'ITALIAN_FISCAL_CODE',\n regex: /\\b([A-Z]{6}\\d{2}[A-Z]\\d{2}[A-Z]\\d{3}[A-Z])\\b/gi,\n placeholder: '[IT_CF_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Italian Fiscal Code (Codice Fiscale)',\n validator: (value: string, _context: string) => {\n const code = value.toUpperCase();\n\n // Month code must be valid (A-H = Jan-Aug, L-T = Sep-Dec, skipping I)\n const monthCode = code[8];\n const validMonths = 'ABCDEHLMPRST';\n if (!validMonths.includes(monthCode)) return false;\n\n // Day must be valid (01-31 for males, 41-71 for females)\n const day = parseInt(code.substring(9, 11));\n if ((day < 1 || day > 31) && (day < 41 || day > 71)) return false;\n\n // Checksum validation\n const oddMap: Record<string, number> = {\n '0': 1, '1': 0, '2': 5, '3': 7, '4': 9, '5': 13, '6': 15, '7': 17, '8': 19, '9': 21,\n 'A': 1, 'B': 0, 'C': 5, 'D': 7, 'E': 9, 'F': 13, 'G': 15, 'H': 17, 'I': 19, 'J': 21,\n 'K': 2, 'L': 4, 'M': 18, 'N': 20, 'O': 11, 'P': 3, 'Q': 6, 'R': 8, 'S': 12, 'T': 14,\n 'U': 16, 'V': 10, 'W': 22, 'X': 25, 'Y': 24, 'Z': 23\n };\n\n const evenMap: Record<string, number> = {\n '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,\n 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,\n 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,\n 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25\n };\n\n let sum = 0;\n for (let i = 0; i < 15; i++) {\n const char = code[i];\n sum += i % 2 === 0 ? oddMap[char] : evenMap[char];\n }\n\n const checkChar = String.fromCharCode(65 + (sum % 26));\n return checkChar === code[15];\n }\n};\n\n/**\n * Dutch BSN (Burgerservicenummer)\n * Format: 9 digits with checksum (11-proof)\n */\nexport const DUTCH_BSN: PIIPattern = {\n type: 'DUTCH_BSN',\n regex: /\\b(\\d{9})\\b/g,\n placeholder: '[NL_BSN_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Dutch Citizen Service Number (BSN)',\n validator: (value: string, context: string) => {\n // Must be in Dutch context\n const relevantContext = /bsn|dutch|netherlands|nederland|burger/i.test(context);\n if (!relevantContext) return false;\n\n // 11-proof checksum\n const digits = value.split('').map(Number);\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n sum += digits[i] * (9 - i);\n }\n sum -= digits[8]; // Last digit is subtracted\n\n return sum % 11 === 0;\n }\n};\n\n/**\n * Polish PESEL\n * Format: 11 digits (birthdate + serial + sex + checksum)\n */\nexport const POLISH_PESEL: PIIPattern = {\n type: 'POLISH_PESEL',\n regex: /\\b(\\d{11})\\b/g,\n placeholder: '[PL_PESEL_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Polish National Identification Number (PESEL)',\n validator: (value: string, context: string) => {\n // Must be in Polish context\n const relevantContext = /pesel|polish|poland|polska/i.test(context);\n if (!relevantContext) return false;\n\n // Checksum validation\n const weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];\n const digits = value.split('').map(Number);\n\n let sum = 0;\n for (let i = 0; i < 10; i++) {\n sum += digits[i] * weights[i];\n }\n\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === digits[10];\n }\n};\n\n// ==================== ASIA-PACIFIC ====================\n\n/**\n * Indian Aadhaar Number\n * Format: 12 digits with checksum (Verhoeff algorithm)\n */\nexport const INDIAN_AADHAAR: PIIPattern = {\n type: 'INDIAN_AADHAAR',\n regex: /\\b(\\d{4}\\s?\\d{4}\\s?\\d{4})\\b/g,\n placeholder: '[IN_AADHAAR_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Indian Aadhaar Number',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/\\s/g, '');\n\n // Must be in Indian context\n const relevantContext = /aadhaar|aadhar|india|indian|uid/i.test(context);\n if (!relevantContext) return false;\n\n // Verhoeff checksum validation (simplified)\n // Full implementation would require multiplication and permutation tables\n // For now, basic length and format check\n return cleaned.length === 12 && /^\\d{12}$/.test(cleaned);\n }\n};\n\n/**\n * Australian Medicare Number\n * Format: 10 digits (9 digits + 1 check digit)\n */\nexport const AUSTRALIAN_MEDICARE: PIIPattern = {\n type: 'AUSTRALIAN_MEDICARE',\n regex: /\\b([2-6]\\d{3}\\s?\\d{5}\\s?\\d)\\b/g,\n placeholder: '[AU_MEDICARE_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Australian Medicare Number',\n validator: (value: string, _context: string) => {\n const cleaned = value.replace(/\\s/g, '');\n\n // Must start with 2-6\n if (!/^[2-6]/.test(cleaned)) return false;\n\n // Checksum validation\n const weights = [1, 3, 7, 9, 1, 3, 7, 9];\n const digits = cleaned.split('').map(Number);\n\n let sum = 0;\n for (let i = 0; i < 8; i++) {\n sum += digits[i] * weights[i];\n }\n\n const checkDigit = sum % 10;\n return checkDigit === digits[8];\n }\n};\n\n/**\n * Australian Tax File Number (TFN)\n * Format: 9 digits with checksum\n */\nexport const AUSTRALIAN_TFN: PIIPattern = {\n type: 'AUSTRALIAN_TFN',\n regex: /\\b(\\d{3}\\s?\\d{3}\\s?\\d{3})\\b/g,\n placeholder: '[AU_TFN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Australian Tax File Number',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/\\s/g, '');\n\n // Must be in tax/Australian context\n const relevantContext = /tfn|tax.file|australian|australia/i.test(context);\n if (!relevantContext) return false;\n\n // Checksum validation\n const weights = [1, 4, 3, 7, 5, 8, 6, 9, 10];\n const digits = cleaned.split('').map(Number);\n\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += digits[i] * weights[i];\n }\n\n return sum % 11 === 0;\n }\n};\n\n/**\n * Singapore NRIC/FIN\n * Format: Letter + 7 digits + checksum letter\n */\nexport const SINGAPORE_NRIC: PIIPattern = {\n type: 'SINGAPORE_NRIC',\n regex: /\\b([STFGM]\\d{7}[A-Z])\\b/gi,\n placeholder: '[SG_NRIC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Singapore NRIC/FIN',\n validator: (value: string, _context: string) => {\n const code = value.toUpperCase();\n const prefix = code[0];\n const digits = code.substring(1, 8).split('').map(Number);\n const checkLetter = code[8];\n\n // Weight factors\n const weights = [2, 7, 6, 5, 4, 3, 2];\n let sum = 0;\n for (let i = 0; i < 7; i++) {\n sum += digits[i] * weights[i];\n }\n\n // Different check letter tables for different prefixes\n const stLetters = 'JZIHGFEDCBA';\n const fgLetters = 'XWUTRQPNMLK';\n const mLetters = 'KMLKJIHGFEDCBA';\n\n let expectedLetter: string;\n if (prefix === 'S' || prefix === 'T') {\n expectedLetter = stLetters[sum % 11];\n } else if (prefix === 'F' || prefix === 'G') {\n expectedLetter = fgLetters[sum % 11];\n } else { // M\n expectedLetter = mLetters[sum % 11];\n }\n\n return checkLetter === expectedLetter;\n }\n};\n\n/**\n * Japanese My Number\n * Format: 12 digits with checksum\n */\nexport const JAPANESE_MY_NUMBER: PIIPattern = {\n type: 'JAPANESE_MY_NUMBER',\n regex: /\\b(\\d{4}\\s?\\d{4}\\s?\\d{4})\\b/g,\n placeholder: '[JP_MY_NUMBER_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Japanese My Number',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/\\s/g, '');\n\n // Must be in Japanese context\n const relevantContext = /my.number|japan|japanese|マイナンバー/i.test(context);\n if (!relevantContext) return false;\n\n // Checksum validation (Luhn-like)\n const digits = cleaned.split('').map(Number);\n const weights = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1];\n\n let sum = 0;\n for (let i = 0; i < 11; i++) {\n let product = digits[i] * weights[i];\n sum += Math.floor(product / 10) + (product % 10);\n }\n\n const checkDigit = (10 - (sum % 10)) % 10;\n return checkDigit === digits[11];\n }\n};\n\n/**\n * South Korean RRN (Resident Registration Number)\n * Format: 6 digits (YYMMDD) + 7 digits (region + gender + serial + checksum)\n */\nexport const SOUTH_KOREAN_RRN: PIIPattern = {\n type: 'SOUTH_KOREAN_RRN',\n regex: /\\b(\\d{6}[-\\s]?[1-4]\\d{6})\\b/g,\n placeholder: '[KR_RRN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'South Korean Resident Registration Number',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/[-\\s]/g, '');\n\n // Must be in Korean context\n const relevantContext = /rrn|korean|korea|주민등록번호/i.test(context);\n if (!relevantContext) return false;\n\n // Gender digit must be 1-4\n const genderDigit = parseInt(cleaned[6]);\n if (genderDigit < 1 || genderDigit > 4) return false;\n\n // Checksum validation\n const weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];\n const digits = cleaned.split('').map(Number);\n\n let sum = 0;\n for (let i = 0; i < 12; i++) {\n sum += digits[i] * weights[i];\n }\n\n const checkDigit = (11 - (sum % 11)) % 10;\n return checkDigit === digits[12];\n }\n};\n\n// ==================== AMERICAS ====================\n\n/**\n * Canadian Social Insurance Number (SIN)\n * Format: 9 digits with Luhn checksum\n */\nexport const CANADIAN_SIN: PIIPattern = {\n type: 'CANADIAN_SIN',\n regex: /\\b(\\d{3}[-\\s]?\\d{3}[-\\s]?\\d{3})\\b/g,\n placeholder: '[CA_SIN_{n}]',\n priority: 95,\n severity: 'high',\n description: 'Canadian Social Insurance Number',\n validator: (value: string, context: string) => {\n const cleaned = value.replace(/[-\\s]/g, '');\n\n // Must be in Canadian context\n const relevantContext = /sin|social.insurance|canadian|canada/i.test(context);\n if (!relevantContext) return false;\n\n // Luhn checksum validation\n const digits = cleaned.split('').map(Number);\n let sum = 0;\n\n for (let i = 0; i < 9; i++) {\n let digit = digits[i];\n if (i % 2 === 1) {\n digit *= 2;\n if (digit > 9) digit -= 9;\n }\n sum += digit;\n }\n\n return sum % 10 === 0;\n }\n};\n\n/**\n * Brazilian CPF (Cadastro de Pessoas Físicas)\n * Format: 11 digits with checksum\n */\nexport const BRAZILIAN_CPF: PIIPattern = {\n type: 'BRAZILIAN_CPF',\n regex: /\\b(\\d{3}\\.?\\d{3}\\.?\\d{3}-?\\d{2})\\b/g,\n placeholder: '[BR_CPF_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Brazilian CPF (Individual Taxpayer ID)',\n validator: (value: string, _context: string) => {\n const cleaned = value.replace(/[.\\-]/g, '');\n const digits = cleaned.split('').map(Number);\n\n // Check for all same digits (invalid)\n if (new Set(digits).size === 1) return false;\n\n // First check digit\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += digits[i] * (10 - i);\n }\n let check1 = 11 - (sum % 11);\n if (check1 >= 10) check1 = 0;\n\n if (check1 !== digits[9]) return false;\n\n // Second check digit\n sum = 0;\n for (let i = 0; i < 10; i++) {\n sum += digits[i] * (11 - i);\n }\n let check2 = 11 - (sum % 11);\n if (check2 >= 10) check2 = 0;\n\n return check2 === digits[10];\n }\n};\n\n/**\n * Brazilian CNPJ (Company ID)\n * Format: 14 digits with checksum\n */\nexport const BRAZILIAN_CNPJ: PIIPattern = {\n type: 'BRAZILIAN_CNPJ',\n regex: /\\b(\\d{2}\\.?\\d{3}\\.?\\d{3}\\/?\\d{4}-?\\d{2})\\b/g,\n placeholder: '[BR_CNPJ_{n}]',\n priority: 85,\n severity: 'high',\n description: 'Brazilian CNPJ (Company Tax ID)',\n validator: (value: string, _context: string) => {\n const cleaned = value.replace(/[.\\-\\/]/g, '');\n const digits = cleaned.split('').map(Number);\n\n // First check digit\n const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n let sum = 0;\n for (let i = 0; i < 12; i++) {\n sum += digits[i] * weights1[i];\n }\n let check1 = sum % 11;\n check1 = check1 < 2 ? 0 : 11 - check1;\n\n if (check1 !== digits[12]) return false;\n\n // Second check digit\n const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n sum = 0;\n for (let i = 0; i < 13; i++) {\n sum += digits[i] * weights2[i];\n }\n let check2 = sum % 11;\n check2 = check2 < 2 ? 0 : 11 - check2;\n\n return check2 === digits[13];\n }\n};\n\n/**\n * Mexican CURP (Clave Única de Registro de Población)\n * Format: 18 characters (4 letters + 6 digits (YYMMDD) + 1 letter + 6 alphanumeric + 1 digit)\n */\nexport const MEXICAN_CURP: PIIPattern = {\n type: 'MEXICAN_CURP',\n regex: /\\b([A-Z]{4}\\d{6}[HM][A-Z]{5}[0-9A-Z]\\d)\\b/gi,\n placeholder: '[MX_CURP_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Mexican CURP (Population Registry Code)',\n validator: (value: string, _context: string) => {\n const curp = value.toUpperCase();\n\n // Gender must be H (Hombre/Male) or M (Mujer/Female)\n const gender = curp[10];\n if (gender !== 'H' && gender !== 'M') return false;\n\n // State code (positions 11-12) must be valid\n const validStates = [\n 'AS', 'BC', 'BS', 'CC', 'CL', 'CM', 'CS', 'CH', 'DF', 'DG',\n 'GT', 'GR', 'HG', 'JC', 'MC', 'MN', 'MS', 'NT', 'NL', 'OC',\n 'PL', 'QT', 'QR', 'SP', 'SL', 'SR', 'TC', 'TS', 'TL', 'VZ',\n 'YN', 'ZS', 'NE' // NE = Nacido en el Extranjero (Born abroad)\n ];\n const stateCode = curp.substring(11, 13);\n return validStates.includes(stateCode);\n }\n};\n\n/**\n * Mexican RFC (Registro Federal de Contribuyentes)\n * Format: 12-13 characters (4 letters + 6 digits + 2-3 alphanumeric)\n */\nexport const MEXICAN_RFC: PIIPattern = {\n type: 'MEXICAN_RFC',\n regex: /\\b([A-Z&Ñ]{3,4}\\d{6}[A-Z0-9]{2,3})\\b/gi,\n placeholder: '[MX_RFC_{n}]',\n priority: 90,\n severity: 'high',\n description: 'Mexican RFC (Tax ID)',\n validator: (value: string, context: string) => {\n const rfc = value.toUpperCase();\n\n // Must be in Mexican/tax context\n const relevantContext = /rfc|mexican|mexico|impuesto|contribuyente/i.test(context);\n if (!relevantContext) return false;\n\n // Length must be 12 (individuals) or 13 (legal entities)\n if (rfc.length !== 12 && rfc.length !== 13) return false;\n\n // Date part (positions 4-9) should be valid YYMMDD\n // Year (positions 4-5) not validated as 00-99 are all potentially valid\n const month = parseInt(rfc.substring(6, 8));\n const day = parseInt(rfc.substring(8, 10));\n\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n\n return true;\n }\n};\n\n// Export all international patterns\nexport const internationalPatterns: PIIPattern[] = [\n // Europe\n GERMAN_TAX_ID,\n FRENCH_SOCIAL_SECURITY,\n SPANISH_DNI,\n ITALIAN_FISCAL_CODE,\n DUTCH_BSN,\n POLISH_PESEL,\n\n // Asia-Pacific\n INDIAN_AADHAAR,\n AUSTRALIAN_MEDICARE,\n AUSTRALIAN_TFN,\n SINGAPORE_NRIC,\n JAPANESE_MY_NUMBER,\n SOUTH_KOREAN_RRN,\n\n // Americas\n CANADIAN_SIN,\n BRAZILIAN_CPF,\n BRAZILIAN_CNPJ,\n MEXICAN_CURP,\n MEXICAN_RFC,\n\n // Middle East\n ...middleEastPatterns,\n\n // Africa\n ...africaPatterns,\n\n // Southeast Asia\n ...southeastAsiaPatterns,\n\n // Latin America\n ...latinAmericaPatterns,\n\n // Eastern Europe\n ...easternEuropePatterns,\n\n // Oceania & Pacific\n ...oceaniaPatterns,\n\n // Central Asia\n ...centralAsiaPatterns\n];\n","/**\n * Digital Identity PII Patterns\n * Social media, gaming platforms, and modern digital identifiers\n */\n\nimport { PIIPattern } from '../types';\n\n/**\n * Discord User ID (Snowflake)\n * Format: 17-19 digit unique identifier\n * Example: 123456789012345678\n */\nexport const DISCORD_USER_ID: PIIPattern = {\n type: 'DISCORD_USER_ID',\n regex: /\\b(\\d{17,19})\\b/g,\n placeholder: '[DISCORD_ID_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Discord user ID (Snowflake format)',\n validator: (value: string, context: string) => {\n // Must be 17-19 digits\n if (value.length < 17 || value.length > 19) return false;\n\n // Context validation required (many numeric IDs could match)\n return /discord|snowflake|user[-_]?id|server|guild/i.test(context);\n }\n};\n\n/**\n * Steam ID64\n * Format: 17-digit number starting with 765\n * Example: 76561198012345678\n */\nexport const STEAM_ID64: PIIPattern = {\n type: 'STEAM_ID64',\n regex: /\\b(765\\d{14})\\b/g,\n placeholder: '[STEAM_ID_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Steam 64-bit user ID',\n validator: (value: string, context: string) => {\n if (!value.startsWith('765') || value.length !== 17) return false;\n\n // Context validation\n return /steam|gaming|player|profile|valve|community/i.test(context);\n }\n};\n\n/**\n * Social Media Handle (Generic)\n * Format: @username (3-30 characters)\n * Covers Twitter, Instagram, TikTok, etc.\n */\nexport const SOCIAL_MEDIA_HANDLE: PIIPattern = {\n type: 'SOCIAL_MEDIA_HANDLE',\n regex: /@([a-zA-Z0-9_]{3,30})\\b/g,\n placeholder: '[@HANDLE_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Social media handle/username',\n validator: (value: string, context: string) => {\n // Must be valid handle format\n if (value.length < 3 || value.length > 30) return false;\n\n // Context validation\n return /twitter|instagram|tiktok|social|handle|profile|mention|tag/i.test(context);\n }\n};\n\n/**\n * Twitter/X User ID\n * Format: 5-19 digit numeric ID\n * Example: 12345678901234567\n */\nexport const TWITTER_USER_ID: PIIPattern = {\n type: 'TWITTER_USER_ID',\n regex: /\\b(\\d{5,19})\\b/g,\n placeholder: '[TWITTER_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Twitter/X numeric user ID',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 5 || length > 19) return false;\n\n // Context validation required for numeric ID\n return /twitter|tweet|@|user[-_]?id|x\\.com/i.test(context);\n }\n};\n\n/**\n * Facebook Profile ID\n * Format: 15-17 digit numeric ID\n * Example: 100012345678901\n */\nexport const FACEBOOK_ID: PIIPattern = {\n type: 'FACEBOOK_ID',\n regex: /\\b(\\d{15,17})\\b/g,\n placeholder: '[FB_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Facebook numeric profile ID',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 15 || length > 17) return false;\n\n // Context validation required\n return /facebook|fb|profile|meta|user[-_]?id/i.test(context);\n }\n};\n\n/**\n * Instagram Username\n * Format: alphanumeric, periods, underscores (1-30 chars)\n * Example: user.name_123\n */\nexport const INSTAGRAM_USERNAME: PIIPattern = {\n type: 'INSTAGRAM_USERNAME',\n regex: /\\b([a-zA-Z0-9._]{1,30})\\b/g,\n placeholder: '[IG_USER_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Instagram username',\n validator: (value: string, context: string) => {\n // Must be valid Instagram format\n if (value.length < 1 || value.length > 30) return false;\n if (!/^[a-zA-Z0-9._]+$/.test(value)) return false;\n\n // Context validation strongly required\n return /instagram|ig|insta|profile|handle/i.test(context);\n }\n};\n\n/**\n * TikTok Username\n * Format: alphanumeric, periods, underscores (2-24 chars)\n * Example: @user.name123\n */\nexport const TIKTOK_USERNAME: PIIPattern = {\n type: 'TIKTOK_USERNAME',\n regex: /@([a-zA-Z0-9._]{2,24})\\b/g,\n placeholder: '[@TIKTOK_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'TikTok username',\n validator: (value: string, context: string) => {\n if (value.length < 2 || value.length > 24) return false;\n\n // Context validation\n return /tiktok|tt|video|profile|creator/i.test(context);\n }\n};\n\n/**\n * LinkedIn Profile URL/ID\n * Format: Various (numeric ID or custom URL slug)\n * Example: /in/john-smith-123456/\n */\nexport const LINKEDIN_PROFILE: PIIPattern = {\n type: 'LINKEDIN_PROFILE',\n regex: /\\/in\\/([a-zA-Z0-9-]{3,100})\\/?/g,\n placeholder: '[LINKEDIN_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'LinkedIn profile URL identifier',\n validator: (value: string, context: string) => {\n if (value.length < 3 || value.length > 100) return false;\n\n // Context validation\n return /linkedin|profile|professional|connection|network/i.test(context);\n }\n};\n\n/**\n * YouTube Channel ID\n * Format: 24-character alphanumeric\n * Example: UC1234567890abcdefghijk\n */\nexport const YOUTUBE_CHANNEL_ID: PIIPattern = {\n type: 'YOUTUBE_CHANNEL_ID',\n regex: /\\b(UC[a-zA-Z0-9_-]{22})\\b/g,\n placeholder: '[YT_CHANNEL_{n}]',\n priority: 75,\n severity: 'low',\n description: 'YouTube channel ID',\n validator: (value: string, context: string) => {\n if (!value.startsWith('UC') || value.length !== 24) return false;\n\n // Context validation\n return /youtube|yt|channel|video|creator|subscriber/i.test(context);\n }\n};\n\n/**\n * Reddit Username\n * Format: u/username (3-20 characters)\n * Example: u/username123\n */\nexport const REDDIT_USERNAME: PIIPattern = {\n type: 'REDDIT_USERNAME',\n regex: /u\\/([a-zA-Z0-9_-]{3,20})\\b/g,\n placeholder: '[REDDIT_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Reddit username',\n validator: (value: string, context: string) => {\n if (value.length < 3 || value.length > 20) return false;\n\n // Context validation\n return /reddit|subreddit|post|comment|karma/i.test(context);\n }\n};\n\n/**\n * Xbox Gamertag\n * Format: alphanumeric with spaces (3-15 chars)\n * Example: GamerName123\n */\nexport const XBOX_GAMERTAG: PIIPattern = {\n type: 'XBOX_GAMERTAG',\n regex: /\\b([a-zA-Z][a-zA-Z0-9 ]{2,14})\\b/g,\n placeholder: '[XBOX_TAG_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Xbox Live Gamertag',\n validator: (value: string, context: string) => {\n if (value.length < 3 || value.length > 15) return false;\n if (!/^[a-zA-Z]/.test(value)) return false;\n\n // Context validation strongly required\n return /xbox|gamertag|live|microsoft|gaming|player/i.test(context);\n }\n};\n\n/**\n * PlayStation Network ID\n * Format: alphanumeric, hyphens, underscores (3-16 chars)\n * Example: PSN_User123\n */\nexport const PSN_ID: PIIPattern = {\n type: 'PSN_ID',\n regex: /\\b([a-zA-Z][a-zA-Z0-9_-]{2,15})\\b/g,\n placeholder: '[PSN_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'PlayStation Network ID',\n validator: (value: string, context: string) => {\n if (value.length < 3 || value.length > 16) return false;\n if (!/^[a-zA-Z]/.test(value)) return false;\n\n // Context validation required\n return /playstation|psn|sony|ps4|ps5|gamer|player/i.test(context);\n }\n};\n\n/**\n * Nintendo Friend Code (Switch)\n * Format: SW-XXXX-XXXX-XXXX (12 digits)\n * Example: SW-1234-5678-9012\n */\nexport const NINTENDO_FRIEND_CODE: PIIPattern = {\n type: 'NINTENDO_FRIEND_CODE',\n regex: /\\bSW[-\\s]?(\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4})\\b/gi,\n placeholder: '[NINTENDO_FC_{n}]',\n priority: 85,\n severity: 'medium',\n description: 'Nintendo Switch Friend Code',\n validator: (value: string, context: string) => {\n const digits = value.replace(/\\D/g, '');\n if (digits.length !== 12) return false;\n\n // Context validation\n return /nintendo|switch|friend[- ]?code|gaming/i.test(context);\n }\n};\n\n/**\n * Battle.net BattleTag\n * Format: Name#1234 (name + 4-5 digit discriminator)\n * Example: Player#12345\n */\nexport const BATTLETAG: PIIPattern = {\n type: 'BATTLETAG',\n regex: /\\b([a-zA-Z][a-zA-Z0-9]{2,11}#\\d{4,5})\\b/g,\n placeholder: '[BTAG_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Battle.net BattleTag',\n validator: (value: string, context: string) => {\n // Value should be Name#NNNN format\n const parts = value.split('#');\n if (parts.length !== 2) return false;\n if (parts[0].length < 3 || parts[0].length > 12) return false;\n if (parts[1].length < 4 || parts[1].length > 5) return false;\n\n // Context validation\n return /battle|battletag|blizzard|overwatch|warcraft|diablo/i.test(context);\n }\n};\n\n/**\n * Epic Games Account ID\n * Format: 32-character hex string\n * Example: 1234567890abcdef1234567890abcdef\n */\nexport const EPIC_GAMES_ID: PIIPattern = {\n type: 'EPIC_GAMES_ID',\n regex: /\\b([a-f0-9]{32})\\b/gi,\n placeholder: '[EPIC_ID_{n}]',\n priority: 75,\n severity: 'medium',\n description: 'Epic Games account ID',\n validator: (value: string, context: string) => {\n if (value.length !== 32) return false;\n if (!/^[a-f0-9]+$/i.test(value)) return false;\n\n // Context validation required\n return /epic|fortnite|unreal|games|launcher|account/i.test(context);\n }\n};\n\n/**\n * Telegram User ID\n * Format: Numeric (up to 10 digits)\n * Example: 123456789\n */\nexport const TELEGRAM_USER_ID: PIIPattern = {\n type: 'TELEGRAM_USER_ID',\n regex: /\\b(\\d{6,10})\\b/g,\n placeholder: '[TG_ID_{n}]',\n priority: 70,\n severity: 'medium',\n description: 'Telegram user ID',\n validator: (value: string, context: string) => {\n const length = value.length;\n if (length < 6 || length > 10) return false;\n\n // Context validation required\n return /telegram|tg|chat|user[-_]?id|messenger/i.test(context);\n }\n};\n\n// Export all digital identity patterns\nexport const digitalIdentityPatterns: PIIPattern[] = [\n DISCORD_USER_ID,\n STEAM_ID64,\n SOCIAL_MEDIA_HANDLE,\n TWITTER_USER_ID,\n FACEBOOK_ID,\n INSTAGRAM_USERNAME,\n TIKTOK_USERNAME,\n LINKEDIN_PROFILE,\n YOUTUBE_CHANNEL_ID,\n REDDIT_USERNAME,\n XBOX_GAMERTAG,\n PSN_ID,\n NINTENDO_FRIEND_CODE,\n BATTLETAG,\n EPIC_GAMES_ID,\n TELEGRAM_USER_ID\n];\n","/**\n * Export all pattern categories\n */\n\nimport { PIIPattern } from '../types';\nimport { personalPatterns } from './personal';\nimport { financialPatterns } from './financial';\nimport { governmentPatterns } from './government';\nimport { contactPatterns } from './contact';\nimport { networkPatterns } from './network';\nimport { cryptoExtendedPatterns } from './financial/crypto-extended';\n\n// Industry-specific patterns\nimport { healthcarePatterns } from './industries/healthcare';\nimport { financialPatterns as financeIndustryPatterns } from './industries/financial';\nimport { technologyPatterns } from './industries/technology';\nimport { legalPatterns } from './industries/legal';\nimport { educationPatterns } from './industries/education';\nimport { hrPatterns } from './industries/hr';\nimport { insurancePatterns } from './industries/insurance';\nimport { retailPatterns } from './industries/retail';\nimport { telecomsPatterns } from './industries/telecoms';\nimport { manufacturingPatterns } from './industries/manufacturing';\nimport { transportationPatterns } from './industries/transportation';\nimport { mediaPatterns } from './industries/media';\nimport { charitablePatterns } from './industries/charitable';\nimport { procurementPatterns } from './industries/procurement';\nimport { emergencyServicesPatterns } from './industries/emergency-services';\nimport { realEstatePatterns } from './industries/real-estate';\nimport { gigEconomyPatterns } from './industries/gig-economy';\nimport { hospitalityPatterns } from './industries/hospitality';\nimport { professionalCertificationPatterns } from './industries/professional-certifications';\nimport { gamingPatterns } from './industries/gaming';\nimport { vehiclePatterns } from './industries/vehicles';\nimport { logisticsPatterns } from './industries/logistics';\nimport { aviationPatterns } from './industries/aviation';\nimport { maritimePatterns } from './industries/maritime';\nimport { environmentalPatterns } from './industries/environmental';\n\n// International patterns\nimport { internationalPatterns } from './international';\n\n// Digital identity patterns\nimport { digitalIdentityPatterns } from './digital-identity';\n\n/**\n * All default PII patterns\n */\nexport const allPatterns: PIIPattern[] = [\n ...personalPatterns,\n ...financialPatterns,\n ...cryptoExtendedPatterns,\n ...governmentPatterns,\n ...contactPatterns,\n ...networkPatterns,\n ...healthcarePatterns,\n ...financeIndustryPatterns,\n ...technologyPatterns,\n ...legalPatterns,\n ...educationPatterns,\n ...hrPatterns,\n ...insurancePatterns,\n ...retailPatterns,\n ...realEstatePatterns,\n ...gigEconomyPatterns,\n ...hospitalityPatterns,\n ...professionalCertificationPatterns,\n ...gamingPatterns,\n ...vehiclePatterns,\n ...logisticsPatterns,\n ...aviationPatterns,\n ...maritimePatterns,\n ...environmentalPatterns,\n ...telecomsPatterns,\n ...manufacturingPatterns,\n ...transportationPatterns,\n ...mediaPatterns,\n ...charitablePatterns,\n ...procurementPatterns,\n ...emergencyServicesPatterns,\n ...internationalPatterns,\n ...digitalIdentityPatterns\n];\n\n/**\n * Get patterns by category\n */\nexport function getPatternsByCategory(category: string): PIIPattern[] {\n switch (category) {\n case 'personal':\n return personalPatterns;\n case 'financial':\n case 'crypto':\n case 'cryptocurrency':\n return [...financialPatterns, ...cryptoExtendedPatterns, ...financeIndustryPatterns];\n case 'government':\n return [...governmentPatterns, ...internationalPatterns];\n case 'contact':\n return contactPatterns;\n case 'network':\n return networkPatterns;\n case 'healthcare':\n return healthcarePatterns;\n case 'legal':\n return legalPatterns;\n case 'education':\n return educationPatterns;\n case 'hr':\n case 'recruitment':\n return hrPatterns;\n case 'credentials':\n case 'technology':\n return technologyPatterns;\n case 'insurance':\n return insurancePatterns;\n case 'retail':\n case 'ecommerce':\n return retailPatterns;\n case 'telecoms':\n case 'telecommunications':\n case 'utilities':\n return telecomsPatterns;\n case 'manufacturing':\n return manufacturingPatterns;\n case 'transportation':\n case 'automotive':\n return transportationPatterns;\n case 'media':\n case 'publishing':\n return mediaPatterns;\n case 'charitable':\n case 'charity':\n case 'nonprofit':\n case 'ngo':\n return charitablePatterns;\n case 'procurement':\n case 'purchasing':\n case 'supply-chain':\n return procurementPatterns;\n case 'emergency':\n case 'emergency-services':\n case 'public-safety':\n case '911':\n case 'first-responders':\n return emergencyServicesPatterns;\n case 'digital-identity':\n case 'social-media':\n case 'gaming':\n case 'online-identity':\n return digitalIdentityPatterns;\n case 'real-estate':\n case 'property':\n case 'realestate':\n return realEstatePatterns;\n case 'gig-economy':\n case 'gig':\n case 'rideshare':\n case 'delivery':\n case 'freelance':\n return gigEconomyPatterns;\n case 'hospitality':\n case 'tourism':\n case 'travel':\n case 'hotel':\n case 'airline':\n return hospitalityPatterns;\n case 'certifications':\n case 'professional-certifications':\n case 'licenses':\n return professionalCertificationPatterns;\n case 'esports':\n case 'videogames':\n case 'gamers':\n return gamingPatterns;\n case 'vehicles':\n case 'license-plates':\n case 'vin':\n return vehiclePatterns;\n case 'logistics':\n case 'shipping':\n case 'tracking':\n case 'freight':\n return logisticsPatterns;\n case 'aviation':\n case 'flight':\n case 'aircraft':\n return aviationPatterns;\n case 'maritime':\n case 'vessel':\n case 'marine':\n case 'ship':\n return maritimePatterns;\n case 'environmental':\n case 'regulatory':\n case 'epa':\n case 'compliance':\n case 'permits':\n return environmentalPatterns;\n default:\n return [];\n }\n}\n\nexport {\n personalPatterns,\n financialPatterns,\n cryptoExtendedPatterns,\n governmentPatterns,\n contactPatterns,\n networkPatterns,\n healthcarePatterns,\n financeIndustryPatterns,\n technologyPatterns,\n legalPatterns,\n educationPatterns,\n hrPatterns,\n insurancePatterns,\n retailPatterns,\n realEstatePatterns,\n gigEconomyPatterns,\n hospitalityPatterns,\n professionalCertificationPatterns,\n gamingPatterns,\n vehiclePatterns,\n logisticsPatterns,\n aviationPatterns,\n maritimePatterns,\n environmentalPatterns,\n telecomsPatterns,\n manufacturingPatterns,\n transportationPatterns,\n mediaPatterns,\n charitablePatterns,\n procurementPatterns,\n emergencyServicesPatterns,\n internationalPatterns,\n digitalIdentityPatterns\n};\n","/**\n * Deterministic hashing utilities for placeholder generation\n */\n\n/**\n * Simple deterministic hash function for generating consistent placeholders\n * Uses FNV-1a hash algorithm for speed and good distribution\n */\nexport function deterministicHash(str: string): number {\n let hash = 2166136261; // FNV offset basis\n\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n\n return hash >>> 0; // Convert to unsigned 32-bit integer\n}\n\n/**\n * Generate a deterministic identifier for PII values\n * Same value always gets the same ID\n */\nexport function generateDeterministicId(value: string, type: string): string {\n const hash = deterministicHash(`${type}:${value.toLowerCase()}`);\n return (hash % 10000).toString().padStart(4, '0');\n}\n","/**\n * Compliance preset configurations\n */\n\nimport { OpenRedactionOptions } from '../types';\n\n/**\n * GDPR compliance preset - European Union data protection\n */\nexport const gdprPreset: Partial<OpenRedactionOptions> = {\n includeNames: true,\n includeEmails: true,\n includePhones: true,\n includeAddresses: true,\n patterns: [\n 'EMAIL',\n 'NAME',\n 'PHONE_UK',\n 'PHONE_UK_MOBILE',\n 'PHONE_INTERNATIONAL',\n 'IPV4',\n 'IPV6',\n 'POSTCODE_UK',\n 'ADDRESS_STREET',\n 'NATIONAL_INSURANCE_UK',\n 'NHS_NUMBER',\n 'PASSPORT_UK',\n 'DRIVING_LICENSE_UK',\n 'IBAN',\n 'CREDIT_CARD'\n ]\n};\n\n/**\n * HIPAA compliance preset - US healthcare data protection\n */\nexport const hipaaPreset: Partial<OpenRedactionOptions> = {\n includeNames: true,\n includeEmails: true,\n includePhones: true,\n includeAddresses: true,\n patterns: [\n 'EMAIL',\n 'NAME',\n 'SSN',\n 'PHONE_US',\n 'ZIP_CODE_US',\n 'ADDRESS_STREET',\n 'DATE_OF_BIRTH',\n 'PASSPORT_US',\n 'DRIVING_LICENSE_US',\n 'CREDIT_CARD',\n 'BANK_ACCOUNT_UK',\n 'IPV4',\n 'IPV6',\n 'EMPLOYEE_ID'\n ]\n};\n\n/**\n * CCPA compliance preset - California consumer privacy\n */\nexport const ccpaPreset: Partial<OpenRedactionOptions> = {\n includeNames: true,\n includeEmails: true,\n includePhones: true,\n includeAddresses: true,\n patterns: [\n 'EMAIL',\n 'NAME',\n 'SSN',\n 'PHONE_US',\n 'ZIP_CODE_US',\n 'ADDRESS_STREET',\n 'IPV4',\n 'IPV6',\n 'CREDIT_CARD',\n 'PASSPORT_US',\n 'DRIVING_LICENSE_US',\n 'USERNAME'\n ]\n};\n\n/**\n * Get preset configuration by name\n */\nexport function getPreset(name: string): Partial<OpenRedactionOptions> {\n switch (name.toLowerCase()) {\n case 'gdpr':\n return gdprPreset;\n case 'hipaa':\n return hipaaPreset;\n case 'ccpa':\n return ccpaPreset;\n default:\n return {};\n }\n}\n","/**\n * Redaction strategies for different modes\n */\n\nimport type { RedactionMode, PIIDetection } from '../types';\n\n/**\n * Apply redaction based on mode\n */\nexport function applyRedactionMode(\n value: string,\n type: string,\n mode: RedactionMode,\n placeholder: string\n): string {\n switch (mode) {\n case 'placeholder':\n return placeholder;\n\n case 'mask-middle':\n return maskMiddle(value, type);\n\n case 'mask-all':\n return '*'.repeat(value.length);\n\n case 'format-preserving':\n return formatPreserving(value, type);\n\n case 'token-replace':\n return tokenReplace(value, type);\n\n default:\n return placeholder;\n }\n}\n\n/**\n * Mask middle characters while preserving edges\n * Examples:\n * - Email: j***@example.com\n * - Phone: 555-**-1234\n * - SSN: ***-**-1234\n * - Credit Card: 4532-****-****-1234\n */\nfunction maskMiddle(value: string, type: string): string {\n // Email: preserve first char of username and full domain\n if (type.includes('EMAIL')) {\n const atIndex = value.indexOf('@');\n if (atIndex > 0) {\n const username = value.substring(0, atIndex);\n const domain = value.substring(atIndex);\n const maskedUsername = username.length <= 2\n ? '*'.repeat(username.length)\n : username[0] + '*'.repeat(username.length - 1);\n return maskedUsername + domain;\n }\n }\n\n // Phone: preserve area code and last 4 digits\n if (type.includes('PHONE')) {\n // Extract digits\n const digits = value.replace(/\\D/g, '');\n if (digits.length >= 10) {\n // US/UK format: show first 3 and last 4\n const areaCode = digits.substring(0, 3);\n const lastFour = digits.substring(digits.length - 4);\n const middleCount = digits.length - 7;\n return `${areaCode}-${'*'.repeat(middleCount > 0 ? middleCount : 2)}-${lastFour}`;\n }\n }\n\n // SSN: mask first 5 digits, show last 4\n if (type === 'SSN') {\n const digits = value.replace(/\\D/g, '');\n if (digits.length === 9) {\n const lastFour = digits.substring(5);\n return `***-**-${lastFour}`;\n }\n }\n\n // Credit Card: show first 4 and last 4\n if (type === 'CREDIT_CARD') {\n const digits = value.replace(/\\D/g, '');\n if (digits.length >= 13) {\n const first = digits.substring(0, 4);\n const last = digits.substring(digits.length - 4);\n const middleGroups = Math.floor((digits.length - 8) / 4);\n const middle = ('****-'.repeat(middleGroups) + '****').substring(0, (digits.length - 8));\n return `${first}-${middle}-${last}`;\n }\n }\n\n // Default: show first 2 and last 2 chars\n if (value.length <= 4) {\n return '*'.repeat(value.length);\n }\n const showCount = Math.min(2, Math.floor(value.length * 0.2));\n const first = value.substring(0, showCount);\n const last = value.substring(value.length - showCount);\n const maskCount = value.length - (showCount * 2);\n return `${first}${'*'.repeat(maskCount)}${last}`;\n}\n\n/**\n * Format-preserving redaction - maintains structure\n * Examples:\n * - SSN: XXX-XX-XXXX\n * - Phone: (XXX) XXX-XXXX\n * - Email: XXXXX@XXXXXX.XXX\n * - Date: XX/XX/XXXX\n */\nfunction formatPreserving(value: string, type: string): string {\n let result = '';\n\n for (let i = 0; i < value.length; i++) {\n const char = value[i];\n\n // Preserve special characters and whitespace\n if (!/[a-zA-Z0-9]/.test(char)) {\n result += char;\n }\n // Replace letters with X\n else if (/[a-zA-Z]/.test(char)) {\n result += char === char.toUpperCase() ? 'X' : 'x';\n }\n // Replace digits with X\n else {\n result += 'X';\n }\n }\n\n return result;\n}\n\n/**\n * Token replacement - replace with realistic fake data\n * Uses deterministic generation based on hash\n */\nfunction tokenReplace(value: string, type: string): string {\n // Simple hash for deterministic generation\n const hash = simpleHash(value);\n\n if (type.includes('EMAIL')) {\n const domains = ['example.com', 'test.com', 'sample.org', 'demo.net'];\n const usernames = ['user', 'john.doe', 'jane.smith', 'test.account'];\n return `${usernames[hash % usernames.length]}${hash % 100}@${domains[hash % domains.length]}`;\n }\n\n if (type.includes('PHONE')) {\n // Generate fake phone number\n const areaCode = 555;\n const exchange = (hash % 900) + 100;\n const line = (hash % 9000) + 1000;\n return `(${areaCode}) ${exchange}-${line}`;\n }\n\n if (type === 'SSN') {\n // Generate fake SSN (invalid range)\n const area = ((hash % 899) + 100);\n const group = ((hash % 99) + 1).toString().padStart(2, '0');\n const serial = ((hash % 9999) + 1).toString().padStart(4, '0');\n return `${area}-${group}-${serial}`;\n }\n\n if (type === 'CREDIT_CARD') {\n // Generate fake credit card (invalid Luhn)\n const first = '4532'; // Visa-like\n const segments = [\n ((hash % 9000) + 1000).toString(),\n ((hash % 9000) + 1000).toString(),\n ((hash % 9000) + 1000).toString()\n ];\n return `${first}-${segments.join('-')}`;\n }\n\n if (type.includes('NAME')) {\n const firstNames = ['John', 'Jane', 'Alex', 'Sam', 'Chris', 'Pat'];\n const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Davis'];\n return `${firstNames[hash % firstNames.length]} ${lastNames[(hash >> 4) % lastNames.length]}`;\n }\n\n // Default: generic replacement\n return `[REDACTED_${type}]`;\n}\n\n/**\n * Simple hash function for deterministic token generation\n */\nfunction simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash);\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface WhitelistEntry {\n pattern: string;\n confidence: number;\n occurrences: number;\n firstSeen: number;\n lastSeen: number;\n contexts: string[];\n}\n\nexport interface PatternAdjustment {\n type: string;\n issue: string;\n suggestion: string;\n confidence: number;\n examples: string[];\n occurrences: number;\n}\n\nexport interface LearningStats {\n totalDetections: number;\n falsePositives: number;\n falseNegatives: number;\n accuracy: number;\n lastUpdated: number;\n}\n\nexport interface FeedbackEntry {\n text: string;\n type: string;\n context: string;\n isFalsePositive: boolean;\n timestamp: number;\n}\n\nexport interface LearningData {\n version: string;\n whitelist: WhitelistEntry[];\n patternAdjustments: PatternAdjustment[];\n stats: LearningStats;\n}\n\nexport class LocalLearningStore {\n private filePath: string;\n private data: LearningData;\n private autoSave: boolean;\n private confidenceThreshold: number;\n\n constructor(filePath: string = '.openredaction/learnings.json', options: {\n autoSave?: boolean;\n confidenceThreshold?: number;\n } = {}) {\n this.filePath = filePath;\n this.autoSave = options.autoSave ?? true;\n this.confidenceThreshold = options.confidenceThreshold ?? 0.85;\n this.data = this.load();\n }\n\n /**\n * Load learning data from file\n */\n private load(): LearningData {\n try {\n if (fs.existsSync(this.filePath)) {\n const content = fs.readFileSync(this.filePath, 'utf-8');\n return JSON.parse(content);\n }\n } catch (error) {\n // File doesn't exist or invalid JSON, start fresh\n }\n\n return {\n version: '1.0',\n whitelist: [],\n patternAdjustments: [],\n stats: {\n totalDetections: 0,\n falsePositives: 0,\n falseNegatives: 0,\n accuracy: 1.0,\n lastUpdated: Date.now()\n }\n };\n }\n\n /**\n * Save learning data to file\n */\n private save(): void {\n try {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n this.data.stats.lastUpdated = Date.now();\n fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));\n } catch (error) {\n console.error('Failed to save learning data:', error);\n }\n }\n\n /**\n * Record a false positive detection\n */\n recordFalsePositive(text: string, _type: string, context: string): void {\n this.data.stats.falsePositives++;\n this.data.stats.totalDetections++;\n this.updateAccuracy();\n\n // Find or create whitelist entry\n let entry = this.data.whitelist.find(e => e.pattern === text);\n\n if (entry) {\n entry.occurrences++;\n entry.lastSeen = Date.now();\n if (!entry.contexts.includes(context)) {\n entry.contexts.push(context);\n }\n // Increase confidence with each occurrence\n entry.confidence = Math.min(0.99, entry.confidence + 0.05);\n } else {\n entry = {\n pattern: text,\n confidence: 0.5, // Start with medium confidence\n occurrences: 1,\n firstSeen: Date.now(),\n lastSeen: Date.now(),\n contexts: [context]\n };\n this.data.whitelist.push(entry);\n }\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Record a false negative (missed detection)\n */\n recordFalseNegative(text: string, type: string, _context: string): void {\n this.data.stats.falseNegatives++;\n this.data.stats.totalDetections++;\n this.updateAccuracy();\n\n // Find or create pattern adjustment\n let adjustment = this.data.patternAdjustments.find(\n a => a.type === type && a.examples.includes(text)\n );\n\n if (adjustment) {\n adjustment.occurrences++;\n adjustment.confidence = Math.min(0.99, adjustment.confidence + 0.05);\n } else {\n adjustment = {\n type,\n issue: `Pattern not detected`,\n suggestion: `Consider adding pattern for: ${text}`,\n confidence: 0.5,\n examples: [text],\n occurrences: 1\n };\n this.data.patternAdjustments.push(adjustment);\n }\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Record a correct detection\n */\n recordCorrectDetection(): void {\n this.data.stats.totalDetections++;\n this.updateAccuracy();\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Update accuracy calculation\n */\n private updateAccuracy(): void {\n const total = this.data.stats.totalDetections;\n if (total === 0) {\n this.data.stats.accuracy = 1.0;\n return;\n }\n\n const incorrect = this.data.stats.falsePositives + this.data.stats.falseNegatives;\n this.data.stats.accuracy = (total - incorrect) / total;\n }\n\n /**\n * Get whitelist entries above confidence threshold\n */\n getWhitelist(): string[] {\n return this.data.whitelist\n .filter(e => e.confidence >= this.confidenceThreshold)\n .map(e => e.pattern);\n }\n\n /**\n * Get all whitelist entries with metadata\n */\n getWhitelistEntries(): WhitelistEntry[] {\n return this.data.whitelist;\n }\n\n /**\n * Get pattern adjustments above confidence threshold\n */\n getPatternAdjustments(): PatternAdjustment[] {\n return this.data.patternAdjustments\n .filter(a => a.confidence >= this.confidenceThreshold)\n .sort((a, b) => b.occurrences - a.occurrences);\n }\n\n /**\n * Get all pattern adjustments\n */\n getAllPatternAdjustments(): PatternAdjustment[] {\n return this.data.patternAdjustments;\n }\n\n /**\n * Get learning statistics\n */\n getStats(): LearningStats {\n return { ...this.data.stats };\n }\n\n /**\n * Get confidence score for a specific pattern\n */\n getConfidence(pattern: string): number {\n const entry = this.data.whitelist.find(e => e.pattern === pattern);\n return entry?.confidence ?? 0;\n }\n\n /**\n * Get occurrences count for a specific pattern\n */\n getOccurrences(pattern: string): number {\n const entry = this.data.whitelist.find(e => e.pattern === pattern);\n return entry?.occurrences ?? 0;\n }\n\n /**\n * Manually add pattern to whitelist\n */\n addToWhitelist(pattern: string, confidence: number = 0.9): void {\n const existing = this.data.whitelist.find(e => e.pattern === pattern);\n\n if (existing) {\n existing.confidence = confidence;\n existing.occurrences++;\n existing.lastSeen = Date.now();\n } else {\n this.data.whitelist.push({\n pattern,\n confidence,\n occurrences: 1,\n firstSeen: Date.now(),\n lastSeen: Date.now(),\n contexts: []\n });\n }\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Remove pattern from whitelist\n */\n removeFromWhitelist(pattern: string): void {\n this.data.whitelist = this.data.whitelist.filter(e => e.pattern !== pattern);\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Clear all learning data\n */\n clear(): void {\n this.data = {\n version: '1.0',\n whitelist: [],\n patternAdjustments: [],\n stats: {\n totalDetections: 0,\n falsePositives: 0,\n falseNegatives: 0,\n accuracy: 1.0,\n lastUpdated: Date.now()\n }\n };\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Export learning data (for sharing)\n */\n export(options: {\n includeContexts?: boolean;\n minConfidence?: number;\n } = {}): LearningData {\n const minConfidence = options.minConfidence ?? 0.7;\n const includeContexts = options.includeContexts ?? false;\n\n return {\n version: this.data.version,\n whitelist: this.data.whitelist\n .filter(e => e.confidence >= minConfidence)\n .map(e => ({\n ...e,\n contexts: includeContexts ? e.contexts : []\n })),\n patternAdjustments: this.data.patternAdjustments\n .filter(a => a.confidence >= minConfidence),\n stats: this.data.stats\n };\n }\n\n /**\n * Import learning data (merge with existing)\n */\n import(data: LearningData, merge: boolean = true): void {\n if (!merge) {\n this.data = data;\n this.save();\n return;\n }\n\n // Merge whitelist entries\n for (const entry of data.whitelist) {\n const existing = this.data.whitelist.find(e => e.pattern === entry.pattern);\n\n if (existing) {\n // Keep higher confidence and sum occurrences\n existing.confidence = Math.max(existing.confidence, entry.confidence);\n existing.occurrences += entry.occurrences;\n existing.lastSeen = Math.max(existing.lastSeen, entry.lastSeen);\n existing.contexts = [...new Set([...existing.contexts, ...entry.contexts])];\n } else {\n this.data.whitelist.push(entry);\n }\n }\n\n // Merge pattern adjustments\n for (const adjustment of data.patternAdjustments) {\n const existing = this.data.patternAdjustments.find(a =>\n a.type === adjustment.type && a.issue === adjustment.issue\n );\n\n if (existing) {\n existing.confidence = Math.max(existing.confidence, adjustment.confidence);\n existing.occurrences += adjustment.occurrences;\n existing.examples = [...new Set([...existing.examples, ...adjustment.examples])];\n } else {\n this.data.patternAdjustments.push(adjustment);\n }\n }\n\n // Merge stats\n this.data.stats.totalDetections += data.stats.totalDetections;\n this.data.stats.falsePositives += data.stats.falsePositives;\n this.data.stats.falseNegatives += data.stats.falseNegatives;\n this.updateAccuracy();\n\n if (this.autoSave) {\n this.save();\n }\n }\n\n /**\n * Manually save data\n */\n flush(): void {\n this.save();\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { OpenRedactionOptions } from '../types.js';\n\nexport interface OpenRedactionConfig extends OpenRedactionOptions {\n extends?: string | string[];\n learnedPatterns?: string;\n learningOptions?: {\n autoSave?: boolean;\n confidenceThreshold?: number;\n };\n}\n\n/**\n * Load configuration from .openredaction.config.js\n */\nexport class ConfigLoader {\n private configPath: string;\n private searchPaths: string[];\n\n constructor(configPath?: string, cwd: string = process.cwd()) {\n this.configPath = configPath || '';\n this.searchPaths = [\n cwd,\n path.join(cwd, '.openredaction'),\n path.join(process.env.HOME || '~', '.openredaction')\n ];\n }\n\n /**\n * Find config file in search paths\n */\n private findConfigFile(): string | null {\n if (this.configPath && fs.existsSync(this.configPath)) {\n return this.configPath;\n }\n\n const configNames = [\n '.openredaction.config.js',\n '.openredaction.config.mjs',\n '.openredaction.config.json',\n 'openredaction.config.js',\n 'openredaction.config.mjs',\n 'openredaction.config.json'\n ];\n\n for (const searchPath of this.searchPaths) {\n for (const configName of configNames) {\n const fullPath = path.join(searchPath, configName);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Load config file\n */\n async load(): Promise<OpenRedactionConfig | null> {\n const configFile = this.findConfigFile();\n\n if (!configFile) {\n return null;\n }\n\n try {\n if (configFile.endsWith('.json')) {\n const content = fs.readFileSync(configFile, 'utf-8');\n return JSON.parse(content);\n }\n\n // Load JS/MJS config\n const config = await import(configFile);\n return config.default || config;\n } catch (error) {\n console.error(`Failed to load config from ${configFile}:`, error);\n return null;\n }\n }\n\n /**\n * Resolve presets and extends\n */\n resolveConfig(config: OpenRedactionConfig): OpenRedactionOptions {\n const resolved: OpenRedactionOptions = { ...config };\n\n // Handle extends\n if (config.extends) {\n const presets = Array.isArray(config.extends) ? config.extends : [config.extends];\n\n for (const preset of presets) {\n const presetConfig = this.loadPreset(preset);\n if (presetConfig) {\n Object.assign(resolved, presetConfig, config); // Config overrides preset\n }\n }\n }\n\n return resolved;\n }\n\n /**\n * Load built-in preset\n */\n private loadPreset(preset: string): OpenRedactionOptions | null {\n // Handle built-in presets\n if (preset === 'openredaction:recommended') {\n return {\n includeNames: true,\n includeAddresses: true,\n includePhones: true,\n includeEmails: true,\n deterministic: true\n };\n }\n\n if (preset === 'openredaction:strict') {\n return {\n includeNames: true,\n includeAddresses: true,\n includePhones: true,\n includeEmails: true,\n deterministic: true,\n preset: 'gdpr'\n };\n }\n\n if (preset === 'openredaction:minimal') {\n return {\n includeNames: false,\n includeAddresses: false,\n includePhones: true,\n includeEmails: true,\n deterministic: true\n };\n }\n\n // Handle compliance presets\n if (preset.startsWith('openredaction:')) {\n const complianceType = preset.replace('openredaction:', '') as 'gdpr' | 'hipaa' | 'ccpa';\n if (['gdpr', 'hipaa', 'ccpa'].includes(complianceType)) {\n return { preset: complianceType };\n }\n }\n\n return null;\n }\n\n /**\n * Create a default config file\n */\n static createDefaultConfig(outputPath: string = '.openredaction.config.js'): void {\n const defaultConfig = `/**\n * OpenRedaction Configuration\n * @see https://github.com/openredact/openredact\n */\nexport default {\n // Extend built-in presets\n // Options: 'openredaction:recommended', 'openredaction:strict', 'openredaction:minimal'\n // Or compliance: 'openredaction:gdpr', 'openredaction:hipaa', 'openredaction:ccpa'\n extends: ['openredaction:recommended'],\n\n // Detection options\n includeNames: true,\n includeAddresses: true,\n includePhones: true,\n includeEmails: true,\n\n // Deterministic placeholders (same PII -> same placeholder)\n deterministic: true,\n\n // Whitelist - patterns to never redact\n whitelist: [\n 'Example Corp',\n 'Test User',\n 'API'\n ],\n\n // Custom patterns\n customPatterns: [\n {\n name: 'INTERNAL_ID',\n regex: /INT-\\\\d{6}/g,\n category: 'personal',\n priority: 90,\n description: 'Internal employee ID'\n }\n ],\n\n // Learning options\n learnedPatterns: '.openredaction/learnings.json',\n learningOptions: {\n autoSave: true,\n confidenceThreshold: 0.85\n }\n};\n`;\n\n fs.writeFileSync(outputPath, defaultConfig);\n console.log(`Created config file: ${outputPath}`);\n }\n}\n","/**\n * Context Analysis for PII Detection\n * Provides NLP-lite features to reduce false positives\n */\n\nexport interface ContextAnalysis {\n /** 5 words before detection */\n beforeWords: string[];\n /** 5 words after detection */\n afterWords: string[];\n /** Full sentence containing detection */\n sentence: string;\n /** Inferred document type */\n documentType: 'email' | 'document' | 'code' | 'chat' | 'unknown';\n /** Confidence that this is actual PII (0-1) */\n confidence: number;\n}\n\nexport interface ContextFeatures {\n /** Contains technical terms */\n hasTechnicalContext: boolean;\n /** Contains business/corporate terms */\n hasBusinessContext: boolean;\n /** Contains medical/healthcare terms */\n hasMedicalContext: boolean;\n /** Contains financial terms */\n hasFinancialContext: boolean;\n /** Contains example/test indicators */\n hasExampleContext: boolean;\n /** Position in document (0-1, 0 = start, 1 = end) */\n relativePosition: number;\n}\n\n/**\n * Extract context around a detection\n */\nexport function extractContext(\n text: string,\n startPos: number,\n endPos: number,\n wordsBefore: number = 5,\n wordsAfter: number = 5\n): {\n before: string;\n after: string;\n beforeWords: string[];\n afterWords: string[];\n sentence: string;\n} {\n // Extract before context\n const beforeText = text.substring(Math.max(0, startPos - 250), startPos);\n const beforeWordArray = beforeText.split(/\\s+/).filter(w => w.length > 0);\n const beforeWords = beforeWordArray.slice(-wordsBefore);\n const before = beforeWords.join(' ');\n\n // Extract after context\n const afterText = text.substring(endPos, Math.min(text.length, endPos + 250));\n const afterWordArray = afterText.split(/\\s+/).filter(w => w.length > 0);\n const afterWords = afterWordArray.slice(0, wordsAfter);\n const after = afterWords.join(' ');\n\n // Extract full sentence\n const sentence = extractSentence(text, startPos, endPos);\n\n return {\n before,\n after,\n beforeWords,\n afterWords,\n sentence\n };\n}\n\n/**\n * Extract the full sentence containing the detection\n */\nfunction extractSentence(text: string, startPos: number, endPos: number): string {\n // Find sentence boundaries (., !, ?, or newline)\n const sentenceStart = findSentenceStart(text, startPos);\n const sentenceEnd = findSentenceEnd(text, endPos);\n\n return text.substring(sentenceStart, sentenceEnd).trim();\n}\n\nfunction findSentenceStart(text: string, pos: number): number {\n // Look backwards for sentence boundary\n for (let i = pos - 1; i >= 0; i--) {\n const char = text[i];\n if (char === '.' || char === '!' || char === '?' || char === '\\n') {\n return i + 1;\n }\n }\n return 0; // Start of document\n}\n\nfunction findSentenceEnd(text: string, pos: number): number {\n // Look forwards for sentence boundary\n for (let i = pos; i < text.length; i++) {\n const char = text[i];\n if (char === '.' || char === '!' || char === '?' || char === '\\n') {\n return i + 1;\n }\n }\n return text.length; // End of document\n}\n\n/**\n * Infer document type from content\n */\nexport function inferDocumentType(text: string): ContextAnalysis['documentType'] {\n const sample = text.substring(0, Math.min(1000, text.length)).toLowerCase();\n\n // Email indicators\n const emailIndicators = /\\b(from|to|subject|dear|regards|sincerely|cc|bcc):/gi;\n const emailScore = (sample.match(emailIndicators) || []).length;\n\n // Code indicators\n const codeIndicators = /\\b(function|const|let|var|class|import|export|return|if|else|for|while)\\b/g;\n const codeScore = (sample.match(codeIndicators) || []).length;\n\n // Chat indicators\n const chatIndicators = /<.*?>|^\\[?\\d{1,2}:\\d{2}\\]?|^>|^@/gm;\n const chatScore = (sample.match(chatIndicators) || []).length;\n\n // Determine type based on scores\n if (codeScore > 5) return 'code';\n if (emailScore > 2) return 'email';\n if (chatScore > 3) return 'chat';\n\n return 'document';\n}\n\n/**\n * Extract context features for classification\n */\nexport function analyzeContextFeatures(fullContext: string): ContextFeatures {\n const lower = fullContext.toLowerCase();\n\n // Technical context\n const technicalTerms = /\\b(api|sdk|cli|gui|json|xml|http|url|database|server|client|endpoint|variable|function|method|class|interface|code|debug|log)\\b/g;\n const hasTechnicalContext = (lower.match(technicalTerms) || []).length > 0;\n\n // Business context\n const businessTerms = /\\b(company|corporation|corp|ltd|llc|inc|ceo|cto|cfo|manager|director|employee|staff|team|department|office|business)\\b/g;\n const hasBusinessContext = (lower.match(businessTerms) || []).length > 0;\n\n // Medical context\n const medicalTerms = /\\b(patient|doctor|physician|nurse|hospital|clinic|medical|health|diagnosis|treatment|prescription|medication|surgery|exam|test|lab|specimen)\\b/g;\n const hasMedicalContext = (lower.match(medicalTerms) || []).length > 0;\n\n // Financial context\n const financialTerms = /\\b(bank|account|payment|transaction|transfer|wire|credit|debit|balance|deposit|withdrawal|loan|mortgage|investment|trading|stock|bond)\\b/g;\n const hasFinancialContext = (lower.match(financialTerms) || []).length > 0;\n\n // Example/test indicators - more precise detection\n // Strong test indicators (very likely to be test data)\n const strongTestPatterns = [\n /\\b(test|testing|dummy|mock|fake)\\s+(data|value|example|user|account|email|phone)/i,\n /\\bfor\\s+(testing|demonstration|example)\\s+purposes/i,\n /\\b(this|here)\\s+is\\s+(an?\\s+)?(example|sample|test)/i,\n /\\bxxx+|000+|111+|123+/i, // Obvious placeholder patterns\n /\\blorem\\s+ipsum/i\n ];\n\n // Weak test indicators (might just be normal text mentioning \"example\")\n const weakTestTerms = /\\b(example|sample|test|demo|placeholder|dummy|mock)\\b/g;\n const weakMatches = (lower.match(weakTestTerms) || []).length;\n const strongMatch = strongTestPatterns.some(pattern => pattern.test(fullContext));\n\n // Only flag as example context if strong indicators or multiple weak indicators\n const hasExampleContext = strongMatch || weakMatches >= 2;\n\n return {\n hasTechnicalContext,\n hasBusinessContext,\n hasMedicalContext,\n hasFinancialContext,\n hasExampleContext,\n relativePosition: 0 // Will be set by caller\n };\n}\n\n/**\n * Calculate confidence score for a detection based on context\n */\nexport function calculateContextConfidence(\n _value: string,\n patternType: string,\n context: {\n before: string;\n after: string;\n sentence: string;\n documentType: ContextAnalysis['documentType'];\n features: ContextFeatures;\n }\n): number {\n let confidence = 0.8; // Base confidence (increased from 0.7)\n\n // Document type adjustments\n if (context.documentType === 'code') {\n // Lower confidence for most PII in code\n const credentialPatterns = ['API_KEY', 'JWT', 'BEARER_TOKEN', 'AWS_ACCESS_KEY', 'GITHUB_TOKEN', 'SECRET'];\n if (!credentialPatterns.some(p => patternType.includes(p))) {\n confidence -= 0.15; // Reduced penalty from 0.2\n }\n } else if (context.documentType === 'email') {\n // Higher confidence for PII in emails\n if (['EMAIL', 'PHONE', 'NAME', 'ADDRESS'].includes(patternType.split('_')[0])) {\n confidence += 0.1;\n }\n }\n\n // Feature-based adjustments\n if (context.features.hasExampleContext) {\n // Moderate penalty for example/test context (reduced from 0.4)\n confidence -= 0.15;\n }\n\n // Medical context boost\n const medicalPatterns = ['MEDICAL', 'MRN', 'PATIENT', 'NHS', 'NPI', 'DEA', 'ICD', 'CPT', 'PRESCRIPTION'];\n if (context.features.hasMedicalContext && medicalPatterns.some(p => patternType.includes(p))) {\n // Boost medical patterns in medical context\n confidence += 0.15;\n }\n\n // Financial context boost\n const financialPatterns = ['ACCOUNT', 'TRANSACTION', 'SWIFT', 'IBAN', 'BITCOIN', 'ETHEREUM', 'CRYPTO', 'PAYMENT'];\n if (context.features.hasFinancialContext && financialPatterns.some(p => patternType.includes(p))) {\n // Boost financial patterns in financial context\n confidence += 0.15;\n }\n\n // Technical context - reduce confidence for non-credentials\n const credentialPatterns = ['API_KEY', 'TOKEN', 'SECRET', 'AWS', 'GITHUB', 'STRIPE', 'JWT'];\n if (context.features.hasTechnicalContext && !credentialPatterns.some(p => patternType.includes(p))) {\n // Reduce confidence for non-credential PII in technical context (reduced from 0.1)\n confidence -= 0.05;\n }\n\n // Context word analysis\n const beforeLower = context.before.toLowerCase();\n const afterLower = context.after.toLowerCase();\n\n // Positive indicators\n const positiveIndicators = [\n { pattern: /\\b(dear|hello|hi|mr|mrs|ms|dr)\\s*$/i, boost: 0.2, types: ['NAME'] },\n { pattern: /^(is|was|wrote|said|told)/i, boost: 0.15, types: ['NAME'] },\n { pattern: /\\b(call|phone|tel|mobile):\\s*$/i, boost: 0.2, types: ['PHONE'] },\n { pattern: /\\b(email|e-mail|contact):\\s*$/i, boost: 0.2, types: ['EMAIL'] },\n { pattern: /\\b(patient|subject|participant):\\s*$/i, boost: 0.25, types: ['NAME', 'PATIENT_ID', 'MRN'] },\n { pattern: /\\b(account|acct)[\\s#:]*$/i, boost: 0.2, types: ['ACCOUNT', 'BANK'] }\n ];\n\n for (const indicator of positiveIndicators) {\n if (indicator.pattern.test(beforeLower)) {\n const matchesType = indicator.types.some(t => patternType.includes(t));\n if (matchesType) {\n confidence += indicator.boost;\n }\n }\n }\n\n // Negative indicators\n const negativeIndicators = [\n { pattern: /\\b(the|a|an)\\s*$/i, penalty: 0.3, types: ['NAME'] },\n { pattern: /\\b(version|v|release)\\s*$/i, penalty: 0.4, types: ['PHONE', 'NUMBER'] },\n { pattern: /^\\s*(street|avenue|road|drive|way)/i, penalty: 0.2, types: ['NAME'] }\n ];\n\n for (const indicator of negativeIndicators) {\n if (indicator.pattern.test(beforeLower) || indicator.pattern.test(afterLower)) {\n const matchesType = indicator.types.some(t => patternType.includes(t));\n if (matchesType) {\n confidence -= indicator.penalty;\n }\n }\n }\n\n // Clamp confidence to [0, 1]\n return Math.max(0, Math.min(1, confidence));\n}\n\n/**\n * Perform full context analysis\n */\nexport function analyzeFullContext(\n text: string,\n value: string,\n patternType: string,\n startPos: number,\n endPos: number\n): ContextAnalysis {\n const { before, after, beforeWords, afterWords, sentence } = extractContext(\n text,\n startPos,\n endPos\n );\n\n const documentType = inferDocumentType(text);\n const fullContext = before + ' ' + value + ' ' + after;\n const features = analyzeContextFeatures(fullContext);\n features.relativePosition = startPos / text.length;\n\n const confidence = calculateContextConfidence(value, patternType, {\n before,\n after,\n sentence,\n documentType,\n features\n });\n\n return {\n beforeWords,\n afterWords,\n sentence,\n documentType,\n confidence\n };\n}\n","/**\n * False Positive Detection and Filtering\n * Identifies and filters out common false positives\n */\n\nexport interface FalsePositiveRule {\n /** Pattern type this rule applies to */\n patternType: string | string[];\n /** Matching function */\n matcher: (value: string, context: string) => boolean;\n /** Description of the false positive */\n description: string;\n /** Severity of the false positive (how confident we are it's not PII) */\n severity: 'high' | 'medium' | 'low';\n}\n\n/**\n * Common false positive rules\n */\nexport const commonFalsePositives: FalsePositiveRule[] = [\n // Version numbers that look like phone numbers\n {\n patternType: ['PHONE', 'PHONE_UK', 'PHONE_US'],\n matcher: (value: string, context: string) => {\n // Version number patterns: v1.2.3, version 2.0.1, etc.\n const versionContext = /\\b(version|v|ver|release|build)\\s*[:\\s]*/i;\n if (versionContext.test(context)) return true;\n\n // Semver-like patterns\n const semverPattern = /^\\d{1,2}\\.\\d{1,2}\\.\\d{1,4}$/;\n if (semverPattern.test(value.replace(/[\\s()-]/g, ''))) return true;\n\n return false;\n },\n description: 'Version number mistaken for phone number',\n severity: 'high'\n },\n\n // Dates that look like phone numbers\n {\n patternType: ['PHONE', 'PHONE_UK', 'PHONE_US'],\n matcher: (value: string, context: string) => {\n // Date context indicators\n const dateContext = /\\b(date|born|birth|dob|created|updated|on|since|until|before|after)\\s*[:\\s]*/i;\n if (dateContext.test(context)) return true;\n\n // Common date formats that might match phone patterns\n const datePatterns = [\n /^\\d{2}[-/]\\d{2}[-/]\\d{4}$/, // DD-MM-YYYY or MM-DD-YYYY\n /^\\d{4}[-/]\\d{2}[-/]\\d{2}$/, // YYYY-MM-DD\n /^\\d{2}[-/]\\d{2}[-/]\\d{2}$/ // DD-MM-YY or MM-DD-YY\n ];\n\n const cleaned = value.replace(/[\\s()]/g, '');\n return datePatterns.some(pattern => pattern.test(cleaned));\n },\n description: 'Date mistaken for phone number',\n severity: 'high'\n },\n\n // IP addresses that might match certain patterns\n {\n patternType: ['PHONE', 'ACCOUNT', 'ID'],\n matcher: (value: string, context: string) => {\n // IP address pattern\n const ipPattern = /^(\\d{1,3}\\.){3}\\d{1,3}$/;\n if (ipPattern.test(value)) return true;\n\n // IP context\n const ipContext = /\\b(ip|address|server|host|network|subnet)\\s*[:\\s]*/i;\n return ipContext.test(context);\n },\n description: 'IP address mistaken for PII',\n severity: 'high'\n },\n\n // Measurements and dimensions\n {\n patternType: ['PHONE', 'NUMBER'],\n matcher: (value: string, context: string) => {\n // Unit indicators\n const unitContext = /\\b(cm|mm|km|m|ft|in|inch|meter|mile|kg|lb|oz|gram|litre|liter|ml|gb|mb|kb)\\s*$/i;\n const hasUnit = unitContext.test(context + ' ' + value);\n\n // Measurement context\n const measureContext = /\\b(size|width|height|length|weight|distance|volume|capacity|dimension)\\s*[:\\s]*/i;\n\n return hasUnit || measureContext.test(context);\n },\n description: 'Measurement mistaken for PII',\n severity: 'medium'\n },\n\n // Years that might match ID patterns\n {\n patternType: ['PHONE', 'ID', 'NUMBER'],\n matcher: (value: string) => {\n // Year range 1900-2099\n const yearPattern = /^(19|20)\\d{2}$/;\n const cleaned = value.replace(/[\\s()-]/g, '');\n return yearPattern.test(cleaned);\n },\n description: 'Year mistaken for PII',\n severity: 'medium'\n },\n\n // Prices and monetary amounts\n {\n patternType: ['PHONE', 'ACCOUNT', 'NUMBER'],\n matcher: (value: string, context: string) => {\n // Currency symbols or context\n const currencyContext = /\\b(price|cost|amount|total|subtotal|fee|charge|payment|\\$|£|€|¥|USD|GBP|EUR)\\s*[:\\s]*/i;\n if (currencyContext.test(context)) return true;\n\n // Price pattern with decimals\n const pricePattern = /^\\d{1,6}\\.\\d{2}$/;\n return pricePattern.test(value.replace(/[\\s,]/g, ''));\n },\n description: 'Price mistaken for PII',\n severity: 'medium'\n },\n\n // Port numbers\n {\n patternType: ['PHONE', 'ID', 'NUMBER'],\n matcher: (value: string, context: string) => {\n const portContext = /\\bport[:\\s]*$/i;\n const portPattern = /^([1-9]\\d{0,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$/;\n\n return portContext.test(context) && portPattern.test(value);\n },\n description: 'Port number mistaken for PII',\n severity: 'high'\n },\n\n // Percentages\n {\n patternType: ['PHONE', 'NUMBER'],\n matcher: (value: string, context: string) => {\n // Check if percent/% appears after the value\n const fullContext = context + ' ' + value;\n const percentAfter = /\\d+(\\.\\d+)?\\s*(percent|percentage|%)/i;\n return percentAfter.test(fullContext);\n },\n description: 'Percentage mistaken for PII',\n severity: 'high'\n },\n\n // Codes and identifiers in technical documentation\n {\n patternType: ['NAME', 'EMAIL'],\n matcher: (value: string, context: string) => {\n // Technical placeholders\n const techPlaceholders = /\\b(foo|bar|baz|qux|example|test|demo|sample|placeholder|dummy|mock)\\b/i;\n if (techPlaceholders.test(value.toLowerCase())) return true;\n\n // Code comment context\n const codeCommentContext = /(\\/\\/|\\/\\*|\\*|#|--|<!--|;)/;\n return codeCommentContext.test(context);\n },\n description: 'Technical placeholder mistaken for PII',\n severity: 'high'\n },\n\n // Generic test data\n {\n patternType: ['EMAIL', 'NAME', 'PHONE', 'ADDRESS'],\n matcher: (value: string) => {\n const testPatterns = [\n /test\\d*@/i,\n /example\\.com$/i,\n /foo@/i,\n /bar@/i,\n /johndoe/i,\n /janedoe/i,\n /^xxx+$/i,\n /^000[-\\s]*000[-\\s]*000/i\n ];\n\n return testPatterns.some(pattern => pattern.test(value));\n },\n description: 'Test data mistaken for PII',\n severity: 'high'\n },\n\n // Article and determiners before names\n {\n patternType: ['NAME'],\n matcher: (_value: string, context: string) => {\n // Articles right before the match\n const articlePattern = /\\b(the|a|an)\\s*$/i;\n return articlePattern.test(context);\n },\n description: 'Common word after article, not a name',\n severity: 'medium'\n },\n\n // Programming keywords\n {\n patternType: ['NAME'],\n matcher: (value: string, context: string) => {\n const keywords = [\n 'function', 'const', 'let', 'var', 'class', 'interface', 'type', 'enum',\n 'public', 'private', 'protected', 'static', 'async', 'await', 'return',\n 'import', 'export', 'from', 'default', 'extends', 'implements'\n ];\n\n const valueLower = value.toLowerCase();\n if (keywords.includes(valueLower)) return true;\n\n // Code context\n const codeContext = /\\b(def|fn|func|method|prop|attr)\\s*[:\\s]*/i;\n return codeContext.test(context);\n },\n description: 'Programming keyword mistaken for name',\n severity: 'high'\n },\n\n // Email domains that are common false positives\n {\n patternType: ['EMAIL'],\n matcher: (value: string) => {\n const commonDomains = [\n 'localhost',\n 'example.com',\n 'example.org',\n 'example.net',\n 'test.com',\n 'demo.com',\n 'sample.com',\n 'invalid.com',\n 'domain.com'\n ];\n\n const domain = value.split('@')[1]?.toLowerCase();\n return commonDomains.includes(domain);\n },\n description: 'Example email domain',\n severity: 'high'\n },\n\n // Common non-PII numbers in financial context\n {\n patternType: ['ACCOUNT', 'CARD'],\n matcher: (value: string, _context: string) => {\n // Zero-filled test numbers\n if (/^0+$/.test(value.replace(/[\\s-]/g, ''))) return true;\n\n // Repeating digits\n const cleaned = value.replace(/[\\s-]/g, '');\n if (/^(\\d)\\1+$/.test(cleaned)) return true;\n\n // Sequential numbers\n if (/^(0123456789|1234567890|9876543210)/.test(cleaned)) return true;\n\n return false;\n },\n description: 'Test account/card number',\n severity: 'high'\n },\n\n // Timestamps\n {\n patternType: ['PHONE', 'ID', 'NUMBER'],\n matcher: (_value: string, context: string) => {\n const timestampContext = /\\b(timestamp|time|epoch|unix|millis|seconds|created.at|updated.at)\\s*[:\\s]*/i;\n return timestampContext.test(context);\n },\n description: 'Timestamp mistaken for PII',\n severity: 'medium'\n }\n];\n\n/**\n * Check if a detection is a false positive\n */\nexport function isFalsePositive(\n value: string,\n patternType: string,\n context: string,\n rules: FalsePositiveRule[] = commonFalsePositives\n): {\n isFalsePositive: boolean;\n matchedRule?: FalsePositiveRule;\n confidence: number; // 0-1, how confident we are it's a false positive\n} {\n for (const rule of rules) {\n // Check if rule applies to this pattern type\n const applies = Array.isArray(rule.patternType)\n ? rule.patternType.some(t => patternType.includes(t))\n : patternType.includes(rule.patternType);\n\n if (!applies) continue;\n\n // Check if the matcher identifies this as a false positive\n if (rule.matcher(value, context)) {\n const confidence = rule.severity === 'high' ? 0.9 : rule.severity === 'medium' ? 0.7 : 0.5;\n return {\n isFalsePositive: true,\n matchedRule: rule,\n confidence\n };\n }\n }\n\n return {\n isFalsePositive: false,\n confidence: 0\n };\n}\n\n/**\n * Filter out false positives from detections\n */\nexport function filterFalsePositives<T extends { value: string; type: string }>(\n detections: T[],\n getText: (detection: T) => { value: string; context: string },\n threshold: number = 0.7\n): T[] {\n return detections.filter(detection => {\n const { value, context } = getText(detection);\n const result = isFalsePositive(value, detection.type, context);\n\n // Only filter if confidence is above threshold\n return !(result.isFalsePositive && result.confidence >= threshold);\n });\n}\n","/**\n * Multi-pass Detection System\n * Processes patterns in priority-based passes for better accuracy\n */\n\nimport { PIIPattern, PIIDetection } from '../types';\n\n/**\n * Detection pass configuration\n */\nexport interface DetectionPass {\n /** Pass name for debugging */\n name: string;\n /** Minimum priority for this pass */\n minPriority: number;\n /** Maximum priority for this pass */\n maxPriority: number;\n /** Pattern types to include (optional filter) */\n includeTypes?: string[];\n /** Pattern types to exclude (optional filter) */\n excludeTypes?: string[];\n /** Description of what this pass detects */\n description: string;\n}\n\n/**\n * Default multi-pass configuration\n * Processes patterns in priority order from highest to lowest\n */\nexport const defaultPasses: DetectionPass[] = [\n {\n name: 'critical-credentials',\n minPriority: 95,\n maxPriority: 100,\n includeTypes: ['API_KEY', 'TOKEN', 'SECRET', 'PASSWORD', 'PRIVATE_KEY', 'AWS', 'GITHUB', 'STRIPE'],\n description: 'Critical credentials and API keys (priority 95-100)'\n },\n {\n name: 'high-confidence',\n minPriority: 85,\n maxPriority: 94,\n description: 'High-confidence patterns with strong validation (priority 85-94)'\n },\n {\n name: 'standard-pii',\n minPriority: 70,\n maxPriority: 84,\n description: 'Standard PII patterns (priority 70-84)'\n },\n {\n name: 'low-priority',\n minPriority: 0,\n maxPriority: 69,\n description: 'Low priority patterns (priority 0-69)'\n }\n];\n\n/**\n * Group patterns into passes based on priority\n */\nexport function groupPatternsByPass(\n patterns: PIIPattern[],\n passes: DetectionPass[] = defaultPasses\n): Map<string, PIIPattern[]> {\n const grouped = new Map<string, PIIPattern[]>();\n\n // Initialize all passes\n for (const pass of passes) {\n grouped.set(pass.name, []);\n }\n\n // Group patterns into appropriate passes\n for (const pattern of patterns) {\n for (const pass of passes) {\n // Check priority range\n if (pattern.priority < pass.minPriority || pattern.priority > pass.maxPriority) {\n continue;\n }\n\n // Check include types filter\n if (pass.includeTypes && pass.includeTypes.length > 0) {\n const matchesInclude = pass.includeTypes.some(type =>\n pattern.type.includes(type)\n );\n if (!matchesInclude) continue;\n }\n\n // Check exclude types filter\n if (pass.excludeTypes && pass.excludeTypes.length > 0) {\n const matchesExclude = pass.excludeTypes.some(type =>\n pattern.type.includes(type)\n );\n if (matchesExclude) continue;\n }\n\n // Add to this pass\n grouped.get(pass.name)!.push(pattern);\n break; // Pattern assigned, move to next pattern\n }\n }\n\n // Sort patterns within each pass by priority (highest first)\n for (const [passName, passPatterns] of grouped.entries()) {\n passPatterns.sort((a, b) => b.priority - a.priority);\n grouped.set(passName, passPatterns);\n }\n\n return grouped;\n}\n\n/**\n * Statistics for multi-pass detection\n */\nexport interface MultiPassStats {\n /** Total passes executed */\n totalPasses: number;\n /** Detections per pass */\n detectionsPerPass: Map<string, number>;\n /** Patterns processed per pass */\n patternsPerPass: Map<string, number>;\n /** Time spent per pass (ms) */\n timePerPass: Map<string, number>;\n /** Total processing time (ms) */\n totalTime: number;\n}\n\n/**\n * Check if a range overlaps with existing detections\n */\nexport function overlapsWithExisting(\n start: number,\n end: number,\n ranges: Array<[number, number]>\n): boolean {\n return ranges.some(\n ([existingStart, existingEnd]) =>\n (start >= existingStart && start < existingEnd) ||\n (end > existingStart && end <= existingEnd) ||\n (start <= existingStart && end >= existingEnd)\n );\n}\n\n/**\n * Merge detections from multiple passes\n * Earlier passes (higher priority) take precedence for overlapping ranges\n */\nexport function mergePassDetections(\n passDetections: Map<string, PIIDetection[]>,\n passes: DetectionPass[]\n): PIIDetection[] {\n const merged: PIIDetection[] = [];\n const processedRanges: Array<[number, number]> = [];\n\n // Process passes in order (highest priority first)\n for (const pass of passes) {\n const detections = passDetections.get(pass.name) || [];\n\n for (const detection of detections) {\n const [start, end] = detection.position;\n\n // Skip if this range overlaps with a higher-priority detection\n if (overlapsWithExisting(start, end, processedRanges)) {\n continue;\n }\n\n // Add detection and mark range as processed\n merged.push(detection);\n processedRanges.push([start, end]);\n }\n }\n\n return merged;\n}\n\n/**\n * Create a simple multi-pass configuration for common use cases\n */\nexport function createSimpleMultiPass(options?: {\n /** Number of passes (2-5, default: 3) */\n numPasses?: number;\n /** Prioritize credentials first */\n prioritizeCredentials?: boolean;\n}): DetectionPass[] {\n const numPasses = Math.min(Math.max(options?.numPasses || 3, 2), 5);\n const prioritizeCredentials = options?.prioritizeCredentials ?? true;\n\n const passes: DetectionPass[] = [];\n\n // Remaining passes: divide priority range evenly\n const startPriority = prioritizeCredentials ? 0 : 0;\n const endPriority = prioritizeCredentials ? 89 : 100;\n const range = endPriority - startPriority;\n const passesNeeded = prioritizeCredentials ? numPasses - 1 : numPasses;\n const step = Math.floor(range / passesNeeded);\n\n // Build passes from low to high priority\n const regularPasses: DetectionPass[] = [];\n for (let i = 0; i < passesNeeded; i++) {\n const min = startPriority + (i * step);\n const max = i === passesNeeded - 1 ? endPriority : startPriority + ((i + 1) * step) - 1;\n\n regularPasses.push({\n name: `pass-${i + 1}`,\n minPriority: min,\n maxPriority: max,\n description: `Priority ${min}-${max}`\n });\n }\n\n // Add regular passes in reverse order (highest priority first)\n passes.push(...regularPasses.reverse());\n\n // Add credentials pass first (highest priority)\n if (prioritizeCredentials) {\n passes.unshift({\n name: 'credentials',\n minPriority: 90,\n maxPriority: 100,\n includeTypes: ['API_KEY', 'TOKEN', 'SECRET', 'PASSWORD', 'AWS', 'GITHUB', 'STRIPE', 'JWT'],\n description: 'Credentials and API keys'\n });\n }\n\n return passes;\n}\n","/**\n * Lightweight NER (Named Entity Recognition) integration using compromise.js\n * Provides semantic detection to complement regex-based pattern matching\n */\n\nimport type { PIIMatch } from '../types';\n\n/**\n * NER entity types supported\n */\nexport type NEREntityType = 'PERSON' | 'ORGANIZATION' | 'PLACE' | 'DATE' | 'MONEY' | 'PHONE' | 'EMAIL' | 'URL';\n\n/**\n * NER detection result\n */\nexport interface NERMatch {\n /** Entity type */\n type: NEREntityType;\n /** Matched text */\n text: string;\n /** Start position in text */\n start: number;\n /** End position in text */\n end: number;\n /** Confidence from NER (0-1) */\n confidence: number;\n /** Additional context */\n context?: {\n sentence?: string;\n tags?: string[];\n };\n}\n\n/**\n * Hybrid detection result (regex + NER)\n */\nexport interface HybridMatch extends PIIMatch {\n /** Whether this match was confirmed by NER */\n nerConfirmed: boolean;\n /** NER confidence if confirmed */\n nerConfidence?: number;\n}\n\n/**\n * NER Detector using compromise.js\n * Lightweight NLP library (7KB) for English text analysis\n */\nexport class NERDetector {\n private nlp?: any;\n private available: boolean = false;\n\n constructor() {\n // Try to load compromise.js (optional peer dependency)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.nlp = require('compromise');\n this.available = true;\n } catch {\n // compromise not installed - NER features disabled\n this.available = false;\n }\n }\n\n /**\n * Check if NER is available (compromise.js installed)\n */\n isAvailable(): boolean {\n return this.available;\n }\n\n /**\n * Detect named entities in text\n */\n detect(text: string): NERMatch[] {\n if (!this.available || !this.nlp) {\n return [];\n }\n\n const matches: NERMatch[] = [];\n\n try {\n const doc = this.nlp(text);\n\n // Extract person names\n const people = doc.people();\n people.forEach((person: any) => {\n const personText = person.text();\n const offset = text.indexOf(personText);\n\n if (offset !== -1) {\n matches.push({\n type: 'PERSON',\n text: personText,\n start: offset,\n end: offset + personText.length,\n confidence: 0.85, // Base confidence for NER detection\n context: {\n sentence: this.getSentence(text, offset),\n tags: person.tags()\n }\n });\n }\n });\n\n // Extract organizations\n const orgs = doc.organizations();\n orgs.forEach((org: any) => {\n const orgText = org.text();\n const offset = text.indexOf(orgText);\n\n if (offset !== -1) {\n matches.push({\n type: 'ORGANIZATION',\n text: orgText,\n start: offset,\n end: offset + orgText.length,\n confidence: 0.80,\n context: {\n sentence: this.getSentence(text, offset),\n tags: org.tags()\n }\n });\n }\n });\n\n // Extract places\n const places = doc.places();\n places.forEach((place: any) => {\n const placeText = place.text();\n const offset = text.indexOf(placeText);\n\n if (offset !== -1) {\n matches.push({\n type: 'PLACE',\n text: placeText,\n start: offset,\n end: offset + placeText.length,\n confidence: 0.75,\n context: {\n sentence: this.getSentence(text, offset),\n tags: place.tags()\n }\n });\n }\n });\n\n // Extract dates\n const dates = doc.dates();\n dates.forEach((date: any) => {\n const dateText = date.text();\n const offset = text.indexOf(dateText);\n\n if (offset !== -1) {\n matches.push({\n type: 'DATE',\n text: dateText,\n start: offset,\n end: offset + dateText.length,\n confidence: 0.90,\n context: {\n sentence: this.getSentence(text, offset),\n tags: date.tags()\n }\n });\n }\n });\n\n // Extract money/currency\n const money = doc.money();\n money.forEach((m: any) => {\n const moneyText = m.text();\n const offset = text.indexOf(moneyText);\n\n if (offset !== -1) {\n matches.push({\n type: 'MONEY',\n text: moneyText,\n start: offset,\n end: offset + moneyText.length,\n confidence: 0.85,\n context: {\n sentence: this.getSentence(text, offset),\n tags: m.tags()\n }\n });\n }\n });\n\n // Extract emails (compromise.js supports this)\n const emails = doc.match('#Email');\n emails.forEach((email: any) => {\n const emailText = email.text();\n const offset = text.indexOf(emailText);\n\n if (offset !== -1) {\n matches.push({\n type: 'EMAIL',\n text: emailText,\n start: offset,\n end: offset + emailText.length,\n confidence: 0.95,\n context: {\n sentence: this.getSentence(text, offset)\n }\n });\n }\n });\n\n // Extract phone numbers (compromise.js supports this)\n const phones = doc.match('#PhoneNumber');\n phones.forEach((phone: any) => {\n const phoneText = phone.text();\n const offset = text.indexOf(phoneText);\n\n if (offset !== -1) {\n matches.push({\n type: 'PHONE',\n text: phoneText,\n start: offset,\n end: offset + phoneText.length,\n confidence: 0.85,\n context: {\n sentence: this.getSentence(text, offset)\n }\n });\n }\n });\n\n // Extract URLs (compromise.js supports this)\n const urls = doc.match('#Url');\n urls.forEach((url: any) => {\n const urlText = url.text();\n const offset = text.indexOf(urlText);\n\n if (offset !== -1) {\n matches.push({\n type: 'URL',\n text: urlText,\n start: offset,\n end: offset + urlText.length,\n confidence: 0.90,\n context: {\n sentence: this.getSentence(text, offset)\n }\n });\n }\n });\n } catch (error) {\n // NER detection failed, return empty array\n console.warn('[NERDetector] Detection failed:', error);\n return [];\n }\n\n // Remove duplicates (same text at same position)\n return this.deduplicateMatches(matches);\n }\n\n /**\n * Check if a regex match is confirmed by NER\n */\n isConfirmedByNER(\n regexMatch: PIIMatch,\n nerMatches: NERMatch[]\n ): { confirmed: boolean; confidence?: number } {\n // Check if any NER match overlaps with regex match\n for (const nerMatch of nerMatches) {\n const overlap = this.calculateOverlap(\n regexMatch.start,\n regexMatch.end,\n nerMatch.start,\n nerMatch.end\n );\n\n // Consider confirmed if overlap > 50%\n if (overlap > 0.5) {\n return {\n confirmed: true,\n confidence: nerMatch.confidence\n };\n }\n }\n\n return { confirmed: false };\n }\n\n /**\n * Boost confidence of regex matches that are confirmed by NER\n */\n hybridDetection(\n regexMatches: PIIMatch[],\n text: string\n ): HybridMatch[] {\n if (!this.available) {\n // NER not available, return regex matches as-is with nerConfirmed: false\n return regexMatches.map(match => ({\n ...match,\n nerConfirmed: false\n }));\n }\n\n // Run NER detection\n const nerMatches = this.detect(text);\n\n // Check each regex match against NER\n return regexMatches.map(match => {\n const { confirmed, confidence: nerConfidence } = this.isConfirmedByNER(match, nerMatches);\n\n if (confirmed && nerConfidence) {\n // Boost confidence for NER-confirmed matches\n const boostedConfidence = Math.min(1.0, match.confidence * 1.3);\n\n return {\n ...match,\n confidence: boostedConfidence,\n nerConfirmed: true,\n nerConfidence\n };\n }\n\n return {\n ...match,\n nerConfirmed: false\n };\n });\n }\n\n /**\n * Calculate overlap between two ranges (0-1)\n */\n private calculateOverlap(\n start1: number,\n end1: number,\n start2: number,\n end2: number\n ): number {\n const overlapStart = Math.max(start1, start2);\n const overlapEnd = Math.min(end1, end2);\n\n if (overlapStart >= overlapEnd) {\n return 0; // No overlap\n }\n\n const overlapLength = overlapEnd - overlapStart;\n const minLength = Math.min(end1 - start1, end2 - start2);\n\n return overlapLength / minLength;\n }\n\n /**\n * Remove duplicate NER matches\n */\n private deduplicateMatches(matches: NERMatch[]): NERMatch[] {\n const seen = new Set<string>();\n const unique: NERMatch[] = [];\n\n for (const match of matches) {\n const key = `${match.type}:${match.start}:${match.end}:${match.text}`;\n\n if (!seen.has(key)) {\n seen.add(key);\n unique.push(match);\n }\n }\n\n return unique;\n }\n\n /**\n * Extract sentence containing the match\n */\n private getSentence(text: string, position: number): string {\n // Find sentence boundaries\n const start = this.findSentenceStart(text, position);\n const end = this.findSentenceEnd(text, position);\n\n return text.substring(start, end).trim();\n }\n\n /**\n * Find start of sentence\n */\n private findSentenceStart(text: string, pos: number): number {\n for (let i = pos - 1; i >= 0; i--) {\n const char = text[i];\n if (char === '.' || char === '!' || char === '?' || char === '\\n') {\n return i + 1;\n }\n }\n return 0;\n }\n\n /**\n * Find end of sentence\n */\n private findSentenceEnd(text: string, pos: number): number {\n for (let i = pos; i < text.length; i++) {\n const char = text[i];\n if (char === '.' || char === '!' || char === '?' || char === '\\n') {\n return i + 1;\n }\n }\n return text.length;\n }\n\n /**\n * Extract additional NER-only detections (entities not caught by regex)\n */\n extractNEROnly(\n nerMatches: NERMatch[],\n regexMatches: PIIMatch[]\n ): NERMatch[] {\n const nerOnly: NERMatch[] = [];\n\n for (const nerMatch of nerMatches) {\n // Check if this NER match overlaps with any regex match\n const hasOverlap = regexMatches.some(regexMatch => {\n const overlap = this.calculateOverlap(\n regexMatch.start,\n regexMatch.end,\n nerMatch.start,\n nerMatch.end\n );\n return overlap > 0.3; // Consider overlap if > 30%\n });\n\n if (!hasOverlap) {\n nerOnly.push(nerMatch);\n }\n }\n\n return nerOnly;\n }\n}\n\n/**\n * Create an NER detector instance\n */\nexport function createNERDetector(): NERDetector {\n return new NERDetector();\n}\n","/**\n * Contextual Rules Engine\n * Defines proximity-based rules and keyword patterns for confidence boosting\n */\n\nimport type { PIIMatch } from '../types';\n\n/**\n * Proximity rule for context-based confidence adjustment\n */\nexport interface ProximityRule {\n /** Pattern type this rule applies to (e.g., 'EMAIL', 'PHONE', 'SSN') */\n patternType: string | string[];\n /** Keywords to look for near the match */\n keywords: string[];\n /** Maximum word distance from match (default: 10) */\n proximityWindow?: number;\n /** Confidence boost if keyword found (0-1) */\n confidenceBoost?: number;\n /** Confidence penalty if keyword found (0-1) */\n confidencePenalty?: number;\n /** Whether match must come AFTER keyword (default: both directions) */\n keywordBefore?: boolean;\n /** Whether match must come BEFORE keyword (default: both directions) */\n keywordAfter?: boolean;\n /** Rule description */\n description?: string;\n}\n\n/**\n * Domain-specific vocabulary for context detection\n */\nexport interface DomainVocabulary {\n /** Domain name */\n domain: 'medical' | 'legal' | 'financial' | 'technical' | 'hr' | 'custom';\n /** Domain-specific terms */\n terms: string[];\n /** Pattern types to boost in this domain */\n boostPatterns?: string[];\n /** Confidence boost amount (default: 0.15) */\n boostAmount?: number;\n}\n\n/**\n * Contextual rules configuration\n */\nexport interface ContextRulesConfig {\n /** Proximity rules */\n proximityRules?: ProximityRule[];\n /** Domain vocabularies */\n domainVocabularies?: DomainVocabulary[];\n /** Enable default rules (default: true) */\n useDefaultRules?: boolean;\n}\n\n/**\n * Default proximity rules for common PII patterns\n */\nexport const DEFAULT_PROXIMITY_RULES: ProximityRule[] = [\n // EMAIL rules\n {\n patternType: 'EMAIL',\n keywords: ['email', 'e-mail', 'contact', 'reach', 'write', 'send to'],\n proximityWindow: 5,\n confidenceBoost: 0.2,\n keywordBefore: true,\n description: 'Email preceded by email-related keywords'\n },\n {\n patternType: 'EMAIL',\n keywords: ['example', 'test', 'sample', 'demo'],\n proximityWindow: 8,\n confidencePenalty: 0.25,\n description: 'Email near test/example keywords'\n },\n\n // PHONE rules\n {\n patternType: ['PHONE', 'PHONE_UK', 'PHONE_US', 'PHONE_UK_MOBILE'],\n keywords: ['call', 'phone', 'tel', 'telephone', 'mobile', 'cell', 'ring', 'dial'],\n proximityWindow: 5,\n confidenceBoost: 0.2,\n keywordBefore: true,\n description: 'Phone number preceded by phone-related keywords'\n },\n {\n patternType: ['PHONE', 'PHONE_UK', 'PHONE_US'],\n keywords: ['fax', 'fax number'],\n proximityWindow: 5,\n confidencePenalty: 0.15,\n description: 'Likely a fax number, not personal phone'\n },\n\n // NAME rules\n {\n patternType: 'NAME',\n keywords: ['mr', 'mrs', 'ms', 'miss', 'dr', 'prof', 'professor', 'dear', 'hello', 'hi'],\n proximityWindow: 3,\n confidenceBoost: 0.25,\n keywordBefore: true,\n description: 'Name preceded by salutation'\n },\n {\n patternType: 'NAME',\n keywords: ['said', 'wrote', 'told', 'asked', 'replied', 'mentioned', 'stated'],\n proximityWindow: 5,\n confidenceBoost: 0.15,\n keywordBefore: true,\n description: 'Name preceded by speech verb'\n },\n {\n patternType: 'NAME',\n keywords: ['the', 'a', 'an', 'this', 'that'],\n proximityWindow: 1,\n confidencePenalty: 0.3,\n keywordBefore: true,\n description: 'Preceded by article - likely not a name'\n },\n\n // SSN rules\n {\n patternType: 'SSN',\n keywords: ['ssn', 'social security', 'social security number', 'social-security'],\n proximityWindow: 8,\n confidenceBoost: 0.25,\n description: 'SSN near SSN-related keywords'\n },\n {\n patternType: 'SSN',\n keywords: ['example', 'test', 'sample', '123-45-6789', '000-00-0000'],\n proximityWindow: 10,\n confidencePenalty: 0.4,\n description: 'SSN near example/test keywords or obvious test SSN'\n },\n\n // ACCOUNT rules\n {\n patternType: ['BANK_ACCOUNT', 'ACCOUNT_NUMBER', 'IBAN', 'SWIFT'],\n keywords: ['account', 'acct', 'account number', 'account#', 'bank account'],\n proximityWindow: 8,\n confidenceBoost: 0.2,\n description: 'Account number near account-related keywords'\n },\n\n // CREDIT CARD rules\n {\n patternType: 'CREDIT_CARD',\n keywords: ['card', 'credit card', 'debit card', 'visa', 'mastercard', 'amex', 'discover'],\n proximityWindow: 8,\n confidenceBoost: 0.2,\n description: 'Card number near card-related keywords'\n },\n {\n patternType: 'CREDIT_CARD',\n keywords: ['test', 'example', '4111', '4111111111111111'],\n proximityWindow: 10,\n confidencePenalty: 0.35,\n description: 'Near test card numbers'\n },\n\n // ADDRESS rules\n {\n patternType: ['ADDRESS', 'STREET_ADDRESS'],\n keywords: ['address', 'street', 'lives at', 'located at', 'residing at'],\n proximityWindow: 8,\n confidenceBoost: 0.15,\n description: 'Address near address-related keywords'\n },\n\n // MEDICAL rules\n {\n patternType: ['MRN', 'PATIENT_ID', 'NHS_NUMBER', 'MEDICAL_RECORD'],\n keywords: ['patient', 'subject', 'participant', 'mrn', 'medical record'],\n proximityWindow: 8,\n confidenceBoost: 0.25,\n description: 'Medical ID near medical keywords'\n },\n\n // DATE OF BIRTH rules\n {\n patternType: 'DATE_OF_BIRTH',\n keywords: ['dob', 'date of birth', 'birth date', 'birthdate', 'born', 'birthday'],\n proximityWindow: 8,\n confidenceBoost: 0.25,\n description: 'DOB near birth-related keywords'\n },\n\n // PASSPORT rules\n {\n patternType: 'PASSPORT',\n keywords: ['passport', 'passport number', 'passport#'],\n proximityWindow: 8,\n confidenceBoost: 0.2,\n description: 'Passport near passport keywords'\n },\n\n // DRIVER LICENSE rules\n {\n patternType: ['DRIVERS_LICENSE', 'DRIVING_LICENCE'],\n keywords: ['license', 'licence', 'driver', 'driving', 'dl#', 'dl number'],\n proximityWindow: 8,\n confidenceBoost: 0.2,\n description: 'License near license keywords'\n }\n];\n\n/**\n * Default domain vocabularies\n */\nexport const DEFAULT_DOMAIN_VOCABULARIES: DomainVocabulary[] = [\n {\n domain: 'medical',\n terms: [\n 'patient', 'doctor', 'physician', 'nurse', 'hospital', 'clinic', 'medical',\n 'health', 'diagnosis', 'treatment', 'prescription', 'medication', 'surgery',\n 'exam', 'test', 'lab', 'specimen', 'chart', 'record', 'mrn', 'hipaa',\n 'healthcare', 'practitioner', 'provider', 'pharmacy', 'radiology'\n ],\n boostPatterns: ['MRN', 'PATIENT_ID', 'NHS_NUMBER', 'NPI', 'DEA', 'MEDICAL'],\n boostAmount: 0.15\n },\n {\n domain: 'legal',\n terms: [\n 'case', 'court', 'judge', 'attorney', 'lawyer', 'counsel', 'plaintiff',\n 'defendant', 'lawsuit', 'litigation', 'docket', 'tribunal', 'hearing',\n 'deposition', 'subpoena', 'warrant', 'verdict', 'settlement', 'contract',\n 'agreement', 'legal', 'law', 'bar number', 'case number'\n ],\n boostPatterns: ['CASE_NUMBER', 'DOCKET', 'BAR_NUMBER', 'LEGAL'],\n boostAmount: 0.15\n },\n {\n domain: 'financial',\n terms: [\n 'bank', 'account', 'payment', 'transaction', 'transfer', 'wire', 'credit',\n 'debit', 'balance', 'deposit', 'withdrawal', 'loan', 'mortgage', 'investment',\n 'trading', 'stock', 'bond', 'portfolio', 'iban', 'swift', 'routing',\n 'bic', 'ach', 'financial', 'finance', 'money', 'currency', 'crypto'\n ],\n boostPatterns: ['BANK_ACCOUNT', 'IBAN', 'SWIFT', 'ROUTING', 'CREDIT_CARD', 'BITCOIN'],\n boostAmount: 0.15\n },\n {\n domain: 'hr',\n terms: [\n 'employee', 'staff', 'personnel', 'workforce', 'human resources', 'hr',\n 'payroll', 'salary', 'compensation', 'benefits', 'onboarding', 'offboarding',\n 'termination', 'resignation', 'promotion', 'performance', 'review',\n 'evaluation', 'disciplinary', 'complaint', 'grievance', 'harassment'\n ],\n boostPatterns: ['EMPLOYEE_ID', 'PAYROLL', 'HR'],\n boostAmount: 0.15\n },\n {\n domain: 'technical',\n terms: [\n 'api', 'key', 'token', 'secret', 'password', 'credential', 'auth',\n 'authentication', 'authorization', 'oauth', 'jwt', 'bearer', 'session',\n 'access', 'refresh', 'client', 'server', 'endpoint', 'webhook', 'sdk'\n ],\n boostPatterns: ['API_KEY', 'JWT', 'BEARER_TOKEN', 'AWS_ACCESS_KEY', 'SECRET'],\n boostAmount: 0.2\n }\n];\n\n/**\n * Contextual Rules Engine\n */\nexport class ContextRulesEngine {\n private proximityRules: ProximityRule[];\n private domainVocabularies: DomainVocabulary[];\n\n constructor(config?: ContextRulesConfig) {\n const useDefaults = config?.useDefaultRules !== false;\n\n this.proximityRules = [\n ...(useDefaults ? DEFAULT_PROXIMITY_RULES : []),\n ...(config?.proximityRules || [])\n ];\n\n this.domainVocabularies = [\n ...(useDefaults ? DEFAULT_DOMAIN_VOCABULARIES : []),\n ...(config?.domainVocabularies || [])\n ];\n }\n\n /**\n * Apply proximity rules to adjust confidence\n */\n applyProximityRules(\n match: PIIMatch,\n text: string\n ): PIIMatch {\n let adjustedConfidence = match.confidence;\n\n // Find applicable rules for this pattern type\n const applicableRules = this.proximityRules.filter(rule => {\n if (Array.isArray(rule.patternType)) {\n return rule.patternType.some(type => match.type.includes(type));\n }\n return match.type.includes(rule.patternType);\n });\n\n for (const rule of applicableRules) {\n const hasKeyword = this.checkProximity(\n text,\n match.start,\n match.end,\n rule.keywords,\n rule.proximityWindow || 10,\n rule.keywordBefore,\n rule.keywordAfter\n );\n\n if (hasKeyword) {\n if (rule.confidenceBoost) {\n adjustedConfidence += rule.confidenceBoost;\n }\n if (rule.confidencePenalty) {\n adjustedConfidence -= rule.confidencePenalty;\n }\n }\n }\n\n // Clamp to [0, 1]\n adjustedConfidence = Math.max(0, Math.min(1, adjustedConfidence));\n\n return {\n ...match,\n confidence: adjustedConfidence\n };\n }\n\n /**\n * Apply domain vocabulary boosting\n */\n applyDomainBoosting(\n matches: PIIMatch[],\n text: string\n ): PIIMatch[] {\n // Detect which domain(s) the text belongs to\n const detectedDomains = this.detectDomains(text);\n\n if (detectedDomains.length === 0) {\n return matches; // No domain detected\n }\n\n // Apply domain-specific boosts\n return matches.map(match => {\n let boosted = false;\n let adjustedConfidence = match.confidence;\n\n for (const domain of detectedDomains) {\n const vocabulary = this.domainVocabularies.find(v => v.domain === domain);\n\n if (vocabulary && vocabulary.boostPatterns) {\n const shouldBoost = vocabulary.boostPatterns.some(pattern =>\n match.type.includes(pattern)\n );\n\n if (shouldBoost) {\n adjustedConfidence += vocabulary.boostAmount || 0.15;\n boosted = true;\n }\n }\n }\n\n if (boosted) {\n return {\n ...match,\n confidence: Math.min(1, adjustedConfidence)\n };\n }\n\n return match;\n });\n }\n\n /**\n * Check if keywords are within proximity window\n */\n private checkProximity(\n text: string,\n matchStart: number,\n matchEnd: number,\n keywords: string[],\n proximityWindow: number,\n keywordBefore?: boolean,\n keywordAfter?: boolean\n ): boolean {\n // Extract context before and after match\n const beforeText = text.substring(Math.max(0, matchStart - 500), matchStart);\n const afterText = text.substring(matchEnd, Math.min(text.length, matchEnd + 500));\n\n // Split into words\n const beforeWords = beforeText.split(/\\s+/).filter(w => w.length > 0);\n const afterWords = afterText.split(/\\s+/).filter(w => w.length > 0);\n\n // Get proximity window\n const beforeWindowWords = beforeWords.slice(-proximityWindow);\n const afterWindowWords = afterWords.slice(0, proximityWindow);\n\n // Check for keywords\n const beforeLower = beforeWindowWords.join(' ').toLowerCase();\n const afterLower = afterWindowWords.join(' ').toLowerCase();\n\n for (const keyword of keywords) {\n const keywordLower = keyword.toLowerCase();\n\n if (keywordBefore && beforeLower.includes(keywordLower)) {\n return true;\n }\n\n if (keywordAfter && afterLower.includes(keywordLower)) {\n return true;\n }\n\n if (!keywordBefore && !keywordAfter) {\n // Check both directions\n if (beforeLower.includes(keywordLower) || afterLower.includes(keywordLower)) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Detect which domains the text belongs to\n */\n private detectDomains(text: string): DomainVocabulary['domain'][] {\n const textLower = text.toLowerCase();\n const detectedDomains: DomainVocabulary['domain'][] = [];\n\n for (const vocabulary of this.domainVocabularies) {\n let termCount = 0;\n\n for (const term of vocabulary.terms) {\n if (textLower.includes(term.toLowerCase())) {\n termCount++;\n }\n }\n\n // Require at least 3 domain terms to consider it that domain\n if (termCount >= 3) {\n detectedDomains.push(vocabulary.domain);\n }\n }\n\n return detectedDomains;\n }\n\n /**\n * Add custom proximity rule\n */\n addProximityRule(rule: ProximityRule): void {\n this.proximityRules.push(rule);\n }\n\n /**\n * Add custom domain vocabulary\n */\n addDomainVocabulary(vocabulary: DomainVocabulary): void {\n this.domainVocabularies.push(vocabulary);\n }\n\n /**\n * Get all proximity rules\n */\n getProximityRules(): ProximityRule[] {\n return [...this.proximityRules];\n }\n\n /**\n * Get all domain vocabularies\n */\n getDomainVocabularies(): DomainVocabulary[] {\n return [...this.domainVocabularies];\n }\n}\n\n/**\n * Create a context rules engine instance\n */\nexport function createContextRulesEngine(config?: ContextRulesConfig): ContextRulesEngine {\n return new ContextRulesEngine(config);\n}\n","/**\n * Severity Classification System\n * Assigns severity levels to PII patterns and calculates risk scores\n */\n\nimport type { PIIPattern, PIIDetection } from '../types';\n\n/**\n * Severity level for PII types\n */\nexport type SeverityLevel = 'critical' | 'high' | 'medium' | 'low';\n\n/**\n * Severity classification with reasoning\n */\nexport interface SeverityClassification {\n /** Severity level */\n level: SeverityLevel;\n /** Numeric score (0-10) */\n score: number;\n /** Reasoning for classification */\n reason?: string;\n}\n\n/**\n * Risk score calculation result\n */\nexport interface RiskScore {\n /** Overall risk score (0-1) */\n score: number;\n /** Risk level */\n level: 'very-high' | 'high' | 'medium' | 'low' | 'minimal';\n /** Contributing factors */\n factors: {\n piiCount: number;\n avgSeverity: number;\n avgConfidence: number;\n criticalCount: number;\n highCount: number;\n };\n}\n\n/**\n * Default severity mappings by pattern type\n */\nexport const DEFAULT_SEVERITY_MAP: Record<string, SeverityLevel> = {\n // CRITICAL - Highly sensitive, major identity theft risk\n 'SSN': 'critical',\n 'SOCIAL_SECURITY': 'critical',\n 'CREDIT_CARD': 'critical',\n 'CVV': 'critical',\n 'BANK_ACCOUNT': 'critical',\n 'ROUTING_NUMBER': 'critical',\n 'PASSPORT': 'critical',\n 'DRIVERS_LICENSE': 'critical',\n 'DRIVING_LICENCE': 'critical',\n 'NHS_NUMBER': 'critical',\n 'NI_NUMBER': 'critical',\n 'NATIONAL_INSURANCE': 'critical',\n 'TAX_ID': 'critical',\n 'EIN': 'critical',\n 'ITIN': 'critical',\n 'SIN': 'critical', // Canadian\n 'TFN': 'critical', // Australian\n 'AADHAAR': 'critical', // Indian\n 'MEDICAL_RECORD': 'critical',\n 'MRN': 'critical',\n 'PATIENT_ID': 'critical',\n 'DEA_NUMBER': 'critical',\n 'NPI': 'critical',\n 'API_KEY': 'critical',\n 'SECRET_KEY': 'critical',\n 'AWS_SECRET_KEY': 'critical',\n 'PRIVATE_KEY': 'critical',\n 'SSH_KEY': 'critical',\n 'JWT': 'critical',\n 'OAUTH_SECRET': 'critical',\n 'PASSWORD': 'critical',\n 'BEARER_TOKEN': 'critical',\n 'BITCOIN_PRIVATE': 'critical',\n\n // HIGH - Personal identifiers, significant privacy risk\n 'EMAIL': 'high',\n 'PHONE': 'high',\n 'PHONE_UK': 'high',\n 'PHONE_US': 'high',\n 'PHONE_MOBILE': 'high',\n 'NAME': 'high',\n 'FULL_NAME': 'high',\n 'DATE_OF_BIRTH': 'high',\n 'DOB': 'high',\n 'ADDRESS': 'high',\n 'STREET_ADDRESS': 'high',\n 'IBAN': 'high',\n 'SWIFT': 'high',\n 'BIC': 'high',\n 'IFSC': 'high', // Indian bank code\n 'CLABE': 'high', // Mexican bank code\n 'IP_ADDRESS': 'high',\n 'MAC_ADDRESS': 'high',\n 'VEHICLE_VIN': 'high',\n 'LICENSE_PLATE': 'high',\n 'GITHUB_TOKEN': 'high',\n 'AWS_ACCESS_KEY': 'high',\n 'STRIPE_KEY': 'high',\n 'GOOGLE_API_KEY': 'high',\n 'PRESCRIPTION': 'high',\n 'BIOMETRIC': 'high',\n\n // MEDIUM - Business/organizational identifiers, moderate risk\n 'EMPLOYEE_ID': 'medium',\n 'USERNAME': 'medium',\n 'COMPANY_NUMBER': 'medium',\n 'VAT_NUMBER': 'medium',\n 'UTR': 'medium', // UK tax reference\n 'ORDER_NUMBER': 'medium',\n 'INVOICE_NUMBER': 'medium',\n 'ACCOUNT_NUMBER': 'medium', // Generic account\n 'CUSTOMER_ID': 'medium',\n 'TRANSACTION_ID': 'medium',\n 'CASE_NUMBER': 'medium',\n 'DOCKET_NUMBER': 'medium',\n 'BAR_NUMBER': 'medium',\n 'TRACKING_NUMBER': 'medium',\n 'SESSION_ID': 'medium',\n 'DEVICE_ID': 'medium',\n 'CERTIFICATE_NUMBER': 'medium',\n 'POLICY_NUMBER': 'medium', // Insurance\n 'MEMBERSHIP_ID': 'medium',\n 'LOYALTY_CARD': 'medium',\n 'GIFT_CARD': 'medium',\n 'BITCOIN_ADDRESS': 'medium', // Public address\n 'ETHEREUM_ADDRESS': 'medium',\n 'CRYPTOCURRENCY': 'medium',\n\n // LOW - Public or less sensitive information\n 'POSTCODE': 'low',\n 'ZIP_CODE': 'low',\n 'POSTAL_CODE': 'low',\n 'URL': 'low',\n 'DOMAIN': 'low',\n 'ORGANIZATION': 'low',\n 'COMPANY': 'low',\n 'PRODUCT_SKU': 'low',\n 'COUPON_CODE': 'low',\n 'PROMO_CODE': 'low',\n 'PLACEHOLDER': 'low'\n};\n\n/**\n * Severity scores (for numeric calculations)\n */\nexport const SEVERITY_SCORES: Record<SeverityLevel, number> = {\n 'critical': 10,\n 'high': 7,\n 'medium': 4,\n 'low': 2\n};\n\n/**\n * Severity Classifier\n */\nexport class SeverityClassifier {\n private severityMap: Record<string, SeverityLevel>;\n\n constructor(customMap?: Record<string, SeverityLevel>) {\n this.severityMap = {\n ...DEFAULT_SEVERITY_MAP,\n ...(customMap || {})\n };\n }\n\n /**\n * Classify severity for a pattern type\n */\n classify(patternType: string): SeverityClassification {\n // Check for exact match\n if (this.severityMap[patternType]) {\n return {\n level: this.severityMap[patternType],\n score: SEVERITY_SCORES[this.severityMap[patternType]],\n reason: `Mapped severity for ${patternType}`\n };\n }\n\n // Check for partial matches (e.g., \"PHONE_UK_MOBILE\" matches \"PHONE\")\n for (const [key, severity] of Object.entries(this.severityMap)) {\n if (patternType.includes(key) || key.includes(patternType)) {\n return {\n level: severity,\n score: SEVERITY_SCORES[severity],\n reason: `Partial match: ${patternType} ≈ ${key}`\n };\n }\n }\n\n // Default to medium if unknown\n return {\n level: 'medium',\n score: SEVERITY_SCORES['medium'],\n reason: `Unknown pattern type, defaulting to medium`\n };\n }\n\n /**\n * Ensure pattern has severity assigned\n */\n ensurePatternSeverity(pattern: PIIPattern): PIIPattern {\n if (pattern.severity) {\n return pattern; // Already has severity\n }\n\n const classification = this.classify(pattern.type);\n\n return {\n ...pattern,\n severity: classification.level\n };\n }\n\n /**\n * Ensure all patterns have severity\n */\n ensureAllSeverity(patterns: PIIPattern[]): PIIPattern[] {\n return patterns.map(p => this.ensurePatternSeverity(p));\n }\n\n /**\n * Calculate risk score for a set of detections\n */\n calculateRiskScore(detections: PIIDetection[]): RiskScore {\n if (detections.length === 0) {\n return {\n score: 0,\n level: 'minimal',\n factors: {\n piiCount: 0,\n avgSeverity: 0,\n avgConfidence: 0,\n criticalCount: 0,\n highCount: 0\n }\n };\n }\n\n // Count by severity\n let criticalCount = 0;\n let highCount = 0;\n let mediumCount = 0;\n let lowCount = 0;\n\n // Calculate average confidence\n let totalConfidence = 0;\n let totalSeverityScore = 0;\n\n for (const detection of detections) {\n // Count severity\n if (detection.severity === 'critical') criticalCount++;\n else if (detection.severity === 'high') highCount++;\n else if (detection.severity === 'medium') mediumCount++;\n else if (detection.severity === 'low') lowCount++;\n\n // Sum confidence\n totalConfidence += detection.confidence || 0.8;\n\n // Sum severity score\n totalSeverityScore += SEVERITY_SCORES[detection.severity];\n }\n\n const avgConfidence = totalConfidence / detections.length;\n const avgSeverity = totalSeverityScore / detections.length;\n\n // Calculate risk score (0-1)\n // Formula: weighted by count, severity, and confidence\n const countFactor = Math.min(detections.length / 10, 1); // Cap at 10 items\n const severityFactor = avgSeverity / 10; // Normalize to 0-1\n const criticalFactor = Math.min(criticalCount / 5, 1); // Heavy weight on critical\n const confidenceFactor = avgConfidence;\n\n const riskScore =\n 0.3 * countFactor +\n 0.3 * severityFactor +\n 0.3 * criticalFactor +\n 0.1 * confidenceFactor;\n\n // Clamp to [0, 1]\n const clampedScore = Math.max(0, Math.min(1, riskScore));\n\n // Determine risk level\n let level: RiskScore['level'];\n if (clampedScore >= 0.8) level = 'very-high';\n else if (clampedScore >= 0.6) level = 'high';\n else if (clampedScore >= 0.4) level = 'medium';\n else if (clampedScore >= 0.2) level = 'low';\n else level = 'minimal';\n\n return {\n score: clampedScore,\n level,\n factors: {\n piiCount: detections.length,\n avgSeverity,\n avgConfidence,\n criticalCount,\n highCount\n }\n };\n }\n\n /**\n * Get severity for a pattern type\n */\n getSeverity(patternType: string): SeverityLevel {\n return this.classify(patternType).level;\n }\n\n /**\n * Get severity score for a pattern type\n */\n getSeverityScore(patternType: string): number {\n return this.classify(patternType).score;\n }\n\n /**\n * Add custom severity mapping\n */\n addSeverityMapping(patternType: string, severity: SeverityLevel): void {\n this.severityMap[patternType] = severity;\n }\n\n /**\n * Get all severity mappings\n */\n getSeverityMap(): Record<string, SeverityLevel> {\n return { ...this.severityMap };\n }\n\n /**\n * Filter detections by severity threshold\n */\n filterBySeverity(\n detections: PIIDetection[],\n minSeverity: SeverityLevel\n ): PIIDetection[] {\n const minScore = SEVERITY_SCORES[minSeverity];\n\n return detections.filter(detection => {\n const score = SEVERITY_SCORES[detection.severity];\n return score >= minScore;\n });\n }\n\n /**\n * Group detections by severity\n */\n groupBySeverity(detections: PIIDetection[]): Record<SeverityLevel, PIIDetection[]> {\n const grouped: Record<SeverityLevel, PIIDetection[]> = {\n critical: [],\n high: [],\n medium: [],\n low: []\n };\n\n for (const detection of detections) {\n grouped[detection.severity].push(detection);\n }\n\n return grouped;\n }\n}\n\n/**\n * Create a severity classifier instance\n */\nexport function createSeverityClassifier(customMap?: Record<string, SeverityLevel>): SeverityClassifier {\n return new SeverityClassifier(customMap);\n}\n\n/**\n * Quick helper to get severity for a pattern type\n */\nexport function getSeverity(patternType: string): SeverityLevel {\n const classifier = new SeverityClassifier();\n return classifier.getSeverity(patternType);\n}\n\n/**\n * Quick helper to calculate risk score\n */\nexport function calculateRisk(detections: PIIDetection[]): RiskScore {\n const classifier = new SeverityClassifier();\n return classifier.calculateRiskScore(detections);\n}\n","/**\n * Simple LRU cache for performance optimization\n */\n\nexport class LRUCache<K, V> {\n private cache: Map<K, V>;\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.cache = new Map();\n this.maxSize = maxSize;\n }\n\n get(key: K): V | undefined {\n const value = this.cache.get(key);\n if (value !== undefined) {\n // Move to end (most recently used)\n this.cache.delete(key);\n this.cache.set(key, value);\n }\n return value;\n }\n\n set(key: K, value: V): void {\n // Delete if exists to update position\n if (this.cache.has(key)) {\n this.cache.delete(key);\n }\n\n // Add new entry\n this.cache.set(key, value);\n\n // Evict oldest if over capacity\n if (this.cache.size > this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n this.cache.delete(firstKey);\n }\n }\n\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n\n/**\n * Create a hash for caching purposes\n */\nexport function hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(36);\n}\n\n/**\n * Memoize function results\n */\nexport function memoize<T extends (...args: any[]) => any>(\n fn: T,\n options: {\n maxSize?: number;\n keyFn?: (...args: Parameters<T>) => string;\n } = {}\n): T {\n const cache = new LRUCache<string, ReturnType<T>>(options.maxSize || 100);\n const keyFn = options.keyFn || ((...args: Parameters<T>) => JSON.stringify(args));\n\n return ((...args: Parameters<T>) => {\n const key = keyFn(...args);\n\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const result = fn(...args);\n cache.set(key, result);\n return result;\n }) as T;\n}\n","/**\n * Explain API for debugging PII detections\n * Provides detailed insights into why text was or wasn't detected\n */\n\nimport { PIIPattern, PIIDetection } from '../types';\nimport { OpenRedaction } from '../detector';\nimport { analyzeFullContext, ContextAnalysis } from '../context/ContextAnalyzer';\nimport { isFalsePositive } from '../filters/FalsePositiveFilter';\n\n/**\n * Pattern match result for explain\n */\nexport interface PatternMatchResult {\n /** Pattern that was tested */\n pattern: PIIPattern;\n /** Whether the pattern matched */\n matched: boolean;\n /** Matched value (if matched) */\n matchedValue?: string;\n /** Position of match (if matched) */\n position?: [number, number];\n /** Why it didn't match or was filtered */\n reason?: string;\n /** Validator result (if validator exists) */\n validatorPassed?: boolean;\n /** Context analysis (if enabled) */\n contextAnalysis?: ContextAnalysis;\n /** False positive check (if enabled) */\n falsePositiveCheck?: {\n isFalsePositive: boolean;\n confidence: number;\n reason?: string;\n };\n}\n\n/**\n * Explanation for a specific text\n */\nexport interface TextExplanation {\n /** Original text */\n text: string;\n /** All pattern match results */\n patternResults: PatternMatchResult[];\n /** Patterns that matched */\n matchedPatterns: PatternMatchResult[];\n /** Patterns that didn't match */\n unmatchedPatterns: PatternMatchResult[];\n /** Patterns that matched but were filtered */\n filteredPatterns: PatternMatchResult[];\n /** Final detections */\n detections: PIIDetection[];\n /** Summary statistics */\n summary: {\n totalPatternsChecked: number;\n patternsMatched: number;\n patternsFiltered: number;\n finalDetections: number;\n };\n}\n\n/**\n * Explain API for debugging\n */\nexport class ExplainAPI {\n private detector: OpenRedaction;\n private patterns: PIIPattern[];\n private options: {\n enableContextAnalysis: boolean;\n confidenceThreshold: number;\n enableFalsePositiveFilter: boolean;\n falsePositiveThreshold: number;\n whitelist: string[];\n };\n\n constructor(detector: OpenRedaction) {\n this.detector = detector;\n this.patterns = detector.getPatterns();\n\n // Test a simple detection to infer options from behavior\n const testResult = detector.detect('Contact: admin@business.co.uk');\n const hasConfidence = testResult.detections.length > 0 && testResult.detections[0].confidence !== undefined;\n\n // Access detector's private options to get whitelist\n const detectorOptions = (detector as any).options;\n\n // Infer options from detector behavior\n this.options = {\n enableContextAnalysis: hasConfidence,\n confidenceThreshold: detectorOptions?.confidenceThreshold || 0.5,\n enableFalsePositiveFilter: detectorOptions?.enableFalsePositiveFilter || false,\n falsePositiveThreshold: detectorOptions?.falsePositiveThreshold || 0.7,\n whitelist: detectorOptions?.whitelist || []\n };\n }\n\n /**\n * Explain why text was or wasn't detected as PII\n */\n explain(text: string): TextExplanation {\n const patternResults: PatternMatchResult[] = [];\n const matchedPatterns: PatternMatchResult[] = [];\n const unmatchedPatterns: PatternMatchResult[] = [];\n const filteredPatterns: PatternMatchResult[] = [];\n\n // Test each pattern\n for (const pattern of this.patterns) {\n const regex = new RegExp(pattern.regex.source, pattern.regex.flags);\n const match = regex.exec(text);\n\n if (!match) {\n // Pattern didn't match\n const result: PatternMatchResult = {\n pattern,\n matched: false,\n reason: 'Pattern regex did not match text'\n };\n patternResults.push(result);\n unmatchedPatterns.push(result);\n continue;\n }\n\n // Pattern matched - extract value\n const value = match[1] !== undefined ? match[1] : match[0];\n const fullMatch = match[0];\n\n let startPos: number;\n let endPos: number;\n\n if (match[1] !== undefined) {\n const captureIndex = fullMatch.indexOf(value);\n startPos = match.index + captureIndex;\n endPos = startPos + value.length;\n } else {\n startPos = match.index;\n endPos = startPos + value.length;\n }\n\n // Get context for analysis\n const contextStart = Math.max(0, startPos - 50);\n const contextEnd = Math.min(text.length, endPos + 50);\n const context = text.substring(contextStart, contextEnd);\n\n const result: PatternMatchResult = {\n pattern,\n matched: true,\n matchedValue: value,\n position: [startPos, endPos]\n };\n\n // Check validator\n if (pattern.validator) {\n const validatorResult = pattern.validator(value, context);\n result.validatorPassed = validatorResult;\n\n if (!validatorResult) {\n result.reason = 'Failed pattern validator';\n patternResults.push(result);\n filteredPatterns.push(result);\n continue;\n }\n }\n\n // Check false positive filter\n if (this.options.enableFalsePositiveFilter) {\n const fpResult = isFalsePositive(value, pattern.type, context);\n result.falsePositiveCheck = {\n isFalsePositive: fpResult.isFalsePositive,\n confidence: fpResult.confidence,\n reason: fpResult.matchedRule?.description\n };\n\n if (fpResult.isFalsePositive && fpResult.confidence >= this.options.falsePositiveThreshold) {\n result.reason = `Filtered as false positive: ${fpResult.matchedRule?.description || 'Unknown reason'}`;\n patternResults.push(result);\n filteredPatterns.push(result);\n continue;\n }\n }\n\n // Perform context analysis\n if (this.options.enableContextAnalysis) {\n const contextAnalysis = analyzeFullContext(\n text,\n value,\n pattern.type,\n startPos,\n endPos\n );\n result.contextAnalysis = contextAnalysis;\n\n if (contextAnalysis.confidence < this.options.confidenceThreshold) {\n result.reason = `Low confidence (${(contextAnalysis.confidence * 100).toFixed(1)}% < ${this.options.confidenceThreshold * 100}% threshold)`;\n patternResults.push(result);\n filteredPatterns.push(result);\n continue;\n }\n }\n\n // Check whitelist\n if (this.options.whitelist.some(term =>\n value.toLowerCase().includes(term.toLowerCase())\n )) {\n result.reason = 'Matched whitelist term';\n patternResults.push(result);\n filteredPatterns.push(result);\n continue;\n }\n\n // Pattern matched and passed all filters\n patternResults.push(result);\n matchedPatterns.push(result);\n }\n\n // Get final detections\n const detections = this.detector.detect(text).detections;\n\n return {\n text,\n patternResults,\n matchedPatterns,\n unmatchedPatterns,\n filteredPatterns,\n detections,\n summary: {\n totalPatternsChecked: this.patterns.length,\n patternsMatched: matchedPatterns.length,\n patternsFiltered: filteredPatterns.length,\n finalDetections: detections.length\n }\n };\n }\n\n /**\n * Explain a specific detection\n */\n explainDetection(detection: PIIDetection, text: string): {\n detection: PIIDetection;\n pattern?: PIIPattern;\n contextAnalysis?: ContextAnalysis;\n reasoning: string[];\n } {\n const pattern = this.patterns.find(p => p.type === detection.type);\n const reasoning: string[] = [];\n\n reasoning.push(`Detected as ${detection.type}`);\n reasoning.push(`Severity: ${detection.severity}`);\n\n if (detection.confidence !== undefined) {\n reasoning.push(`Confidence: ${(detection.confidence * 100).toFixed(1)}%`);\n }\n\n if (pattern) {\n reasoning.push(`Matched pattern: ${pattern.description || pattern.type}`);\n reasoning.push(`Pattern priority: ${pattern.priority}`);\n }\n\n let contextAnalysis: ContextAnalysis | undefined;\n if (detection.confidence !== undefined) {\n // If detection has confidence, context analysis was performed\n const [start, end] = detection.position;\n contextAnalysis = analyzeFullContext(\n text,\n detection.value,\n detection.type,\n start,\n end\n );\n\n if (contextAnalysis) {\n reasoning.push(`Document type: ${contextAnalysis.documentType}`);\n reasoning.push(`Context confidence: ${(contextAnalysis.confidence * 100).toFixed(1)}%`);\n }\n }\n\n return {\n detection,\n pattern,\n contextAnalysis,\n reasoning\n };\n }\n\n /**\n * Suggest why text wasn't detected\n */\n suggestWhy(text: string, expectedType: string): {\n text: string;\n expectedType: string;\n suggestions: string[];\n similarPatterns: PIIPattern[];\n } {\n const suggestions: string[] = [];\n const similarPatterns: PIIPattern[] = [];\n\n // Find patterns of expected type\n const typePatterns = this.patterns.filter(p =>\n p.type === expectedType || p.type.includes(expectedType)\n );\n\n if (typePatterns.length === 0) {\n suggestions.push(`No patterns found for type: ${expectedType}`);\n suggestions.push('Available types: ' + [...new Set(this.patterns.map(p => p.type))].join(', '));\n return { text, expectedType, suggestions, similarPatterns };\n }\n\n // Check if any pattern matches\n for (const pattern of typePatterns) {\n const regex = new RegExp(pattern.regex.source, pattern.regex.flags);\n const match = regex.exec(text);\n\n if (match) {\n similarPatterns.push(pattern);\n const value = match[1] !== undefined ? match[1] : match[0];\n suggestions.push(`Pattern \"${pattern.type}\" matched value: \"${value}\"`);\n\n // Check why it was filtered\n const explanation = this.explain(text);\n const filtered = explanation.filteredPatterns.find(r => r.pattern.type === pattern.type);\n\n if (filtered && filtered.reason) {\n suggestions.push(`But was filtered: ${filtered.reason}`);\n }\n }\n }\n\n if (similarPatterns.length === 0) {\n suggestions.push(`Text didn't match any ${expectedType} patterns`);\n suggestions.push('Possible reasons:');\n suggestions.push(' - Format doesn\\'t match expected pattern');\n suggestions.push(' - Contains invalid characters');\n suggestions.push(' - Fails validation checks');\n suggestions.push(' - Too short or too long');\n\n // Show example patterns\n if (typePatterns.length > 0) {\n const examplePattern = typePatterns[0];\n suggestions.push(`\\nExample ${expectedType} pattern: ${examplePattern.regex.source.substring(0, 100)}...`);\n }\n }\n\n return {\n text,\n expectedType,\n suggestions,\n similarPatterns\n };\n }\n\n /**\n * Get debugging information for entire detection process\n */\n debug(text: string): {\n text: string;\n textLength: number;\n enabledFeatures: string[];\n patternCount: number;\n explanation: TextExplanation;\n performance: {\n estimatedTime: string;\n };\n } {\n const start = performance.now();\n const explanation = this.explain(text);\n const duration = performance.now() - start;\n\n const enabledFeatures: string[] = [];\n if (this.options.enableContextAnalysis) {\n enabledFeatures.push('Context Analysis');\n }\n if (this.options.enableFalsePositiveFilter) {\n enabledFeatures.push('False Positive Filter');\n }\n if (this.options.whitelist.length > 0) {\n enabledFeatures.push(`Whitelist (${this.options.whitelist.length} entries)`);\n }\n\n return {\n text,\n textLength: text.length,\n enabledFeatures,\n patternCount: this.patterns.length,\n explanation,\n performance: {\n estimatedTime: `${duration.toFixed(2)}ms`\n }\n };\n }\n}\n\n/**\n * Helper to create explain API from detector\n */\nexport function createExplainAPI(detector: OpenRedaction): ExplainAPI {\n return new ExplainAPI(detector);\n}\n","/**\n * Report generation for PII detection results\n * Generates static HTML and Markdown reports - 100% offline, zero dependencies\n */\n\nimport { DetectionResult } from '../types';\nimport { OpenRedaction } from '../detector';\n\n/**\n * Report format options\n */\nexport type ReportFormat = 'html' | 'markdown';\n\n/**\n * Report type options\n */\nexport type ReportType = 'summary' | 'detailed' | 'compliance';\n\n/**\n * Report generation options\n */\nexport interface ReportOptions {\n /** Report format */\n format: ReportFormat;\n /** Report type */\n type?: ReportType;\n /** Report title */\n title?: string;\n /** Include original text (default: false for privacy) */\n includeOriginalText?: boolean;\n /** Include redacted text (default: true) */\n includeRedactedText?: boolean;\n /** Include detection details (default: true) */\n includeDetectionDetails?: boolean;\n /** Include statistics (default: true) */\n includeStatistics?: boolean;\n /** Include explanation (requires ExplainAPI, default: false) */\n includeExplanation?: boolean;\n /** Company/project name for compliance reports */\n organizationName?: string;\n /** Additional metadata */\n metadata?: Record<string, string>;\n}\n\n/**\n * Report generator for PII detection results\n */\nexport class ReportGenerator {\n constructor(_detector: OpenRedaction) {\n // Detector not currently used, reserved for future features\n }\n\n /**\n * Generate a report from detection results\n */\n generate(result: DetectionResult, options: ReportOptions): string {\n const opts: Required<ReportOptions> = {\n format: options.format,\n type: options.type || 'summary',\n title: options.title || 'PII Detection Report',\n includeOriginalText: options.includeOriginalText ?? false,\n includeRedactedText: options.includeRedactedText ?? true,\n includeDetectionDetails: options.includeDetectionDetails ?? true,\n includeStatistics: options.includeStatistics ?? true,\n includeExplanation: options.includeExplanation ?? false,\n organizationName: options.organizationName || 'Organization',\n metadata: options.metadata || {}\n };\n\n if (opts.format === 'html') {\n return this.generateHTML(result, opts);\n } else {\n return this.generateMarkdown(result, opts);\n }\n }\n\n /**\n * Generate HTML report\n */\n private generateHTML(result: DetectionResult, options: Required<ReportOptions>): string {\n const timestamp = new Date().toISOString();\n const stats = this.calculateStatistics(result);\n\n let html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${this.escapeHtml(options.title)}</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n line-height: 1.6;\n color: #333;\n background: #f5f5f5;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n padding: 40px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n }\n h1 {\n color: #2c3e50;\n border-bottom: 3px solid #3498db;\n padding-bottom: 10px;\n margin-bottom: 20px;\n }\n h2 {\n color: #34495e;\n margin-top: 30px;\n margin-bottom: 15px;\n border-bottom: 2px solid #ecf0f1;\n padding-bottom: 8px;\n }\n h3 {\n color: #7f8c8d;\n margin-top: 20px;\n margin-bottom: 10px;\n }\n .meta {\n background: #ecf0f1;\n padding: 15px;\n border-radius: 4px;\n margin-bottom: 20px;\n font-size: 0.9em;\n }\n .meta-item {\n margin: 5px 0;\n }\n .meta-label {\n font-weight: 600;\n color: #34495e;\n }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 15px;\n margin: 20px 0;\n }\n .stat-card {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 20px;\n border-radius: 8px;\n text-align: center;\n }\n .stat-card.warning {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n }\n .stat-card.success {\n background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n }\n .stat-value {\n font-size: 2em;\n font-weight: bold;\n margin-bottom: 5px;\n }\n .stat-label {\n font-size: 0.9em;\n opacity: 0.9;\n }\n .detection-table {\n width: 100%;\n border-collapse: collapse;\n margin: 20px 0;\n }\n .detection-table th,\n .detection-table td {\n padding: 12px;\n text-align: left;\n border-bottom: 1px solid #ecf0f1;\n }\n .detection-table th {\n background: #34495e;\n color: white;\n font-weight: 600;\n }\n .detection-table tr:hover {\n background: #f8f9fa;\n }\n .badge {\n display: inline-block;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 0.85em;\n font-weight: 600;\n }\n .badge-high {\n background: #e74c3c;\n color: white;\n }\n .badge-medium {\n background: #f39c12;\n color: white;\n }\n .badge-low {\n background: #3498db;\n color: white;\n }\n .text-box {\n background: #2c3e50;\n color: #ecf0f1;\n padding: 20px;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n overflow-x: auto;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n .highlight {\n background: #f39c12;\n color: #2c3e50;\n padding: 2px 4px;\n border-radius: 2px;\n font-weight: 600;\n }\n .footer {\n margin-top: 40px;\n padding-top: 20px;\n border-top: 2px solid #ecf0f1;\n text-align: center;\n color: #7f8c8d;\n font-size: 0.9em;\n }\n @media print {\n body { background: white; padding: 0; }\n .container { box-shadow: none; }\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h1>${this.escapeHtml(options.title)}</h1>\n\n <div class=\"meta\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Generated:</span> ${timestamp}\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Organization:</span> ${this.escapeHtml(options.organizationName)}\n </div>\n`;\n\n // Add custom metadata\n for (const [key, value] of Object.entries(options.metadata)) {\n html += ` <div class=\"meta-item\">\n <span class=\"meta-label\">${this.escapeHtml(key)}:</span> ${this.escapeHtml(value)}\n </div>\n`;\n }\n\n html += ` </div>\n`;\n\n // Statistics section\n if (options.includeStatistics) {\n html += `\n <h2>Summary Statistics</h2>\n <div class=\"stats\">\n <div class=\"stat-card ${stats.totalDetections > 0 ? 'warning' : 'success'}\">\n <div class=\"stat-value\">${stats.totalDetections}</div>\n <div class=\"stat-label\">PII Detected</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${stats.uniqueTypes}</div>\n <div class=\"stat-label\">Unique Types</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${stats.highSeverity}</div>\n <div class=\"stat-label\">High Severity</div>\n </div>\n ${result.stats?.processingTime ? `\n <div class=\"stat-card success\">\n <div class=\"stat-value\">${result.stats.processingTime}ms</div>\n <div class=\"stat-label\">Processing Time</div>\n </div>` : ''}\n </div>\n`;\n\n // Type breakdown\n html += `\n <h3>Detection Breakdown</h3>\n <table class=\"detection-table\">\n <thead>\n <tr>\n <th>PII Type</th>\n <th>Count</th>\n <th>Percentage</th>\n </tr>\n </thead>\n <tbody>\n`;\n for (const [type, count] of Object.entries(stats.typeBreakdown)) {\n const percentage = ((count / stats.totalDetections) * 100).toFixed(1);\n html += ` <tr>\n <td>${this.escapeHtml(type)}</td>\n <td>${count}</td>\n <td>${percentage}%</td>\n </tr>\n`;\n }\n html += ` </tbody>\n </table>\n`;\n }\n\n // Detection details\n if (options.includeDetectionDetails && result.detections.length > 0) {\n html += `\n <h2>Detection Details</h2>\n <table class=\"detection-table\">\n <thead>\n <tr>\n <th>Type</th>\n <th>Value</th>\n <th>Position</th>\n <th>Severity</th>\n ${result.detections[0].confidence !== undefined ? '<th>Confidence</th>' : ''}\n </tr>\n </thead>\n <tbody>\n`;\n for (const detection of result.detections) {\n const severityClass = detection.severity === 'high' ? 'badge-high' :\n detection.severity === 'medium' ? 'badge-medium' : 'badge-low';\n html += ` <tr>\n <td>${this.escapeHtml(detection.type)}</td>\n <td><code>${this.escapeHtml(detection.value)}</code></td>\n <td>${detection.position[0]}-${detection.position[1]}</td>\n <td><span class=\"badge ${severityClass}\">${detection.severity.toUpperCase()}</span></td>\n ${detection.confidence !== undefined ? `<td>${(detection.confidence * 100).toFixed(1)}%</td>` : ''}\n </tr>\n`;\n }\n html += ` </tbody>\n </table>\n`;\n }\n\n // Redacted text\n if (options.includeRedactedText) {\n html += `\n <h2>Redacted Text</h2>\n <div class=\"text-box\">${this.escapeHtml(result.redacted)}</div>\n`;\n }\n\n // Original text (privacy warning)\n if (options.includeOriginalText) {\n html += `\n <h2>Original Text (Sensitive)</h2>\n <div class=\"text-box\">${this.escapeHtml(result.original)}</div>\n`;\n }\n\n // Footer\n html += `\n <div class=\"footer\">\n <p>Generated by OpenRedaction - Production-ready PII detection library</p>\n <p>Report Type: ${options.type.toUpperCase()} | Format: HTML</p>\n </div>\n </div>\n</body>\n</html>`;\n\n return html;\n }\n\n /**\n * Generate Markdown report\n */\n private generateMarkdown(result: DetectionResult, options: Required<ReportOptions>): string {\n const timestamp = new Date().toISOString();\n const stats = this.calculateStatistics(result);\n\n let md = `# ${options.title}\\n\\n`;\n\n // Metadata\n md += `## Metadata\\n\\n`;\n md += `- **Generated:** ${timestamp}\\n`;\n md += `- **Organization:** ${options.organizationName}\\n`;\n for (const [key, value] of Object.entries(options.metadata)) {\n md += `- **${key}:** ${value}\\n`;\n }\n md += `\\n`;\n\n // Statistics\n if (options.includeStatistics) {\n md += `## Summary Statistics\\n\\n`;\n md += `| Metric | Value |\\n`;\n md += `|--------|-------|\\n`;\n md += `| Total PII Detected | ${stats.totalDetections} |\\n`;\n md += `| Unique Types | ${stats.uniqueTypes} |\\n`;\n md += `| High Severity | ${stats.highSeverity} |\\n`;\n if (result.stats?.processingTime) {\n md += `| Processing Time | ${result.stats.processingTime}ms |\\n`;\n }\n md += `\\n`;\n\n // Type breakdown\n md += `### Detection Breakdown\\n\\n`;\n md += `| PII Type | Count | Percentage |\\n`;\n md += `|----------|-------|------------|\\n`;\n for (const [type, count] of Object.entries(stats.typeBreakdown)) {\n const percentage = ((count / stats.totalDetections) * 100).toFixed(1);\n md += `| ${type} | ${count} | ${percentage}% |\\n`;\n }\n md += `\\n`;\n }\n\n // Detection details\n if (options.includeDetectionDetails && result.detections.length > 0) {\n md += `## Detection Details\\n\\n`;\n md += `| Type | Value | Position | Severity |${result.detections[0].confidence !== undefined ? ' Confidence |' : ''}\\n`;\n md += `|------|-------|----------|----------|${result.detections[0].confidence !== undefined ? '------------|' : ''}\\n`;\n for (const detection of result.detections) {\n md += `| ${detection.type} | \\`${detection.value}\\` | ${detection.position[0]}-${detection.position[1]} | ${detection.severity.toUpperCase()} |`;\n if (detection.confidence !== undefined) {\n md += ` ${(detection.confidence * 100).toFixed(1)}% |`;\n }\n md += `\\n`;\n }\n md += `\\n`;\n }\n\n // Redacted text\n if (options.includeRedactedText) {\n md += `## Redacted Text\\n\\n`;\n md += `\\`\\`\\`\\n${result.redacted}\\n\\`\\`\\`\\n\\n`;\n }\n\n // Original text (privacy warning)\n if (options.includeOriginalText) {\n md += `## Original Text (Sensitive)\\n\\n`;\n md += `⚠️ **WARNING:** This section contains unredacted sensitive data.\\n\\n`;\n md += `\\`\\`\\`\\n${result.original}\\n\\`\\`\\`\\n\\n`;\n }\n\n // Footer\n md += `---\\n\\n`;\n md += `*Generated by OpenRedaction - Production-ready PII detection library*\\n`;\n md += `*Report Type: ${options.type.toUpperCase()} | Format: MARKDOWN*\\n`;\n\n return md;\n }\n\n /**\n * Calculate statistics from detection results\n */\n private calculateStatistics(result: DetectionResult): {\n totalDetections: number;\n uniqueTypes: number;\n highSeverity: number;\n typeBreakdown: Record<string, number>;\n } {\n const typeBreakdown: Record<string, number> = {};\n let highSeverity = 0;\n\n for (const detection of result.detections) {\n typeBreakdown[detection.type] = (typeBreakdown[detection.type] || 0) + 1;\n if (detection.severity === 'high') {\n highSeverity++;\n }\n }\n\n return {\n totalDetections: result.detections.length,\n uniqueTypes: Object.keys(typeBreakdown).length,\n highSeverity,\n typeBreakdown\n };\n }\n\n /**\n * Escape HTML special characters\n */\n private escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n return text.replace(/[&<>\"']/g, m => map[m]);\n }\n}\n\n/**\n * Helper to create report generator\n */\nexport function createReportGenerator(detector: OpenRedaction): ReportGenerator {\n return new ReportGenerator(detector);\n}\n","import { PIIPattern } from '../types';\nimport { LocalLearningStore } from '../learning/LocalLearningStore';\n\nexport interface PatternStats {\n type: string;\n totalDetections: number;\n falsePositives: number;\n falseNegatives: number;\n accuracy: number;\n priority: number;\n adjustedPriority: number;\n}\n\nexport interface OptimizerOptions {\n learningWeight: number; // How much to weight learning data (0-1)\n minSampleSize: number; // Minimum detections before adjusting priority\n maxPriorityAdjustment: number; // Maximum +/- adjustment to priority\n}\n\n/**\n * Priority Optimizer - Dynamically adjusts pattern priorities based on learning data\n */\nexport class PriorityOptimizer {\n private learningStore: LocalLearningStore;\n private options: OptimizerOptions;\n\n constructor(learningStore: LocalLearningStore, options: Partial<OptimizerOptions> = {}) {\n this.learningStore = learningStore;\n this.options = {\n learningWeight: options.learningWeight ?? 0.3, // 30% weight to learning data\n minSampleSize: options.minSampleSize ?? 10, // Need 10+ detections to adjust\n maxPriorityAdjustment: options.maxPriorityAdjustment ?? 15 // Max ±15 priority points\n };\n }\n\n /**\n * Optimize pattern priorities based on learning data\n */\n optimizePatterns(patterns: PIIPattern[]): PIIPattern[] {\n // Get learning stats\n const whitelistEntries = this.learningStore.getWhitelistEntries();\n const patternAdjustments = this.learningStore.getAllPatternAdjustments();\n\n // Calculate false positive rate per pattern type\n const fpCountByType = new Map<string, number>();\n\n for (const entry of whitelistEntries) {\n // Whitelist entries represent false positives\n const occurrences = entry.occurrences;\n\n // Try to infer pattern type from contexts\n // This is a heuristic - in a real system we'd track this explicitly\n const inferredType = this.inferPatternType(entry.pattern);\n\n if (inferredType) {\n fpCountByType.set(inferredType, (fpCountByType.get(inferredType) || 0) + occurrences);\n }\n }\n\n // Calculate false negative rate per pattern type\n const fnCountByType = new Map<string, number>();\n\n for (const adjustment of patternAdjustments) {\n fnCountByType.set(adjustment.type, (fnCountByType.get(adjustment.type) || 0) + adjustment.occurrences);\n }\n\n // Calculate total detections per type (estimated)\n const totalDetectionsByType = new Map<string, number>();\n for (const pattern of patterns) {\n const fpCount = fpCountByType.get(pattern.type) || 0;\n const fnCount = fnCountByType.get(pattern.type) || 0;\n\n // Estimate total detections (this is approximate)\n // In a real system, we'd track actual detections per pattern\n const estimated = Math.max(fpCount + fnCount + 10, 1);\n totalDetectionsByType.set(pattern.type, estimated);\n }\n\n // Optimize each pattern's priority\n const optimizedPatterns = patterns.map(pattern => {\n const fpCount = fpCountByType.get(pattern.type) || 0;\n const fnCount = fnCountByType.get(pattern.type) || 0;\n const totalDetections = totalDetectionsByType.get(pattern.type) || 1;\n\n // Skip optimization if not enough data\n if (totalDetections < this.options.minSampleSize) {\n return pattern;\n }\n\n // Calculate priority adjustment\n let adjustment = 0;\n\n // If high false positive rate, decrease priority\n const fpRate = fpCount / totalDetections;\n if (fpRate > 0.1) { // More than 10% FP rate\n adjustment -= fpRate * this.options.maxPriorityAdjustment;\n }\n\n // If high false negative rate, increase priority\n const fnRate = fnCount / totalDetections;\n if (fnRate > 0.1) { // More than 10% FN rate\n adjustment += fnRate * this.options.maxPriorityAdjustment;\n }\n\n // Weight the adjustment\n adjustment *= this.options.learningWeight;\n\n // Clamp adjustment\n adjustment = Math.max(\n -this.options.maxPriorityAdjustment,\n Math.min(this.options.maxPriorityAdjustment, adjustment)\n );\n\n // Calculate new priority\n const newPriority = Math.max(0, Math.min(100, pattern.priority + adjustment));\n\n // Return pattern with adjusted priority (if significant change)\n if (Math.abs(adjustment) > 1) {\n return {\n ...pattern,\n priority: Math.round(newPriority)\n };\n }\n\n return pattern;\n });\n\n return optimizedPatterns;\n }\n\n /**\n * Get pattern statistics with learning data\n */\n getPatternStats(patterns: PIIPattern[]): PatternStats[] {\n const whitelistEntries = this.learningStore.getWhitelistEntries();\n const patternAdjustments = this.learningStore.getAllPatternAdjustments();\n\n // Calculate stats per pattern type\n const fpCountByType = new Map<string, number>();\n for (const entry of whitelistEntries) {\n const inferredType = this.inferPatternType(entry.pattern);\n if (inferredType) {\n fpCountByType.set(inferredType, (fpCountByType.get(inferredType) || 0) + entry.occurrences);\n }\n }\n\n const fnCountByType = new Map<string, number>();\n for (const adjustment of patternAdjustments) {\n fnCountByType.set(adjustment.type, (fnCountByType.get(adjustment.type) || 0) + adjustment.occurrences);\n }\n\n // Build stats for each pattern\n const stats: PatternStats[] = patterns.map(pattern => {\n const fpCount = fpCountByType.get(pattern.type) || 0;\n const fnCount = fnCountByType.get(pattern.type) || 0;\n const totalDetections = Math.max(fpCount + fnCount + 10, 1);\n const incorrect = fpCount + fnCount;\n const accuracy = (totalDetections - incorrect) / totalDetections;\n\n return {\n type: pattern.type,\n totalDetections,\n falsePositives: fpCount,\n falseNegatives: fnCount,\n accuracy,\n priority: pattern.priority,\n adjustedPriority: pattern.priority // Will be updated by optimizePatterns\n };\n });\n\n return stats;\n }\n\n /**\n * Infer pattern type from a whitelisted value\n * This is a heuristic - in production we'd track this explicitly\n */\n private inferPatternType(value: string): string | null {\n // Email pattern\n if (/@/.test(value)) return 'EMAIL';\n\n // Phone pattern\n if (/^\\+?\\d[\\d\\s\\-()]{7,}$/.test(value)) return 'PHONE';\n\n // SSN pattern\n if (/^\\d{3}-\\d{2}-\\d{4}$/.test(value)) return 'SSN';\n\n // Credit card pattern\n if (/^\\d{4}[\\s\\-]?\\d{4}[\\s\\-]?\\d{4}[\\s\\-]?\\d{4}$/.test(value)) return 'CREDIT_CARD';\n\n // IP address pattern\n if (/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(value)) return 'IP_ADDRESS';\n\n // Name pattern (2-4 capitalized words)\n if (/^[A-Z][a-z]+(\\s[A-Z][a-z]+){1,3}$/.test(value)) return 'NAME';\n\n // Default: couldn't infer\n return null;\n }\n\n /**\n * Reset all priority adjustments\n */\n resetPriorities(patterns: PIIPattern[]): PIIPattern[] {\n // This would restore original priorities from a stored baseline\n // For now, just return patterns as-is\n return patterns;\n }\n\n /**\n * Get optimizer configuration\n */\n getOptions(): OptimizerOptions {\n return { ...this.options };\n }\n\n /**\n * Update optimizer configuration\n */\n setOptions(options: Partial<OptimizerOptions>): void {\n this.options = {\n ...this.options,\n ...options\n };\n }\n}\n\n/**\n * Create a priority optimizer instance\n */\nexport function createPriorityOptimizer(\n learningStore: LocalLearningStore,\n options?: Partial<OptimizerOptions>\n): PriorityOptimizer {\n return new PriorityOptimizer(learningStore, options);\n}\n","/**\n * Custom error class for OpenRedaction with helpful messages and suggestions\n */\n\nexport interface ErrorSuggestion {\n message: string;\n code?: string;\n docs?: string;\n}\n\nexport class OpenRedactionError extends Error {\n public code: string;\n public suggestion?: ErrorSuggestion;\n public context?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: string = 'OPENREDACTION_ERROR',\n suggestion?: ErrorSuggestion,\n context?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'OpenRedactionError';\n this.code = code;\n this.suggestion = suggestion;\n this.context = context;\n\n // Maintain proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, OpenRedactionError);\n }\n }\n\n /**\n * Get formatted error message with suggestions\n */\n getFormattedMessage(): string {\n let formatted = `[${this.code}] ${this.message}`;\n\n if (this.suggestion) {\n formatted += `\\n\\nSuggestion: ${this.suggestion.message}`;\n\n if (this.suggestion.code) {\n formatted += `\\n\\nTry:\\n${this.suggestion.code}`;\n }\n\n if (this.suggestion.docs) {\n formatted += `\\n\\nDocs: ${this.suggestion.docs}`;\n }\n }\n\n if (this.context && Object.keys(this.context).length > 0) {\n formatted += `\\n\\nContext: ${JSON.stringify(this.context, null, 2)}`;\n }\n\n return formatted;\n }\n}\n\n/**\n * Factory functions for common error scenarios\n */\n\nexport function createInvalidPatternError(patternType: string, reason: string): OpenRedactionError {\n return new OpenRedactionError(\n `Invalid pattern '${patternType}': ${reason}`,\n 'INVALID_PATTERN',\n {\n message: 'Check your pattern regex and validator functions',\n code: `const pattern: PIIPattern = {\n type: '${patternType}',\n regex: /your-regex-here/g,\n placeholder: '[${patternType}_{n}]',\n priority: 80,\n severity: 'medium',\n description: 'Your description',\n validator: (value, context) => true\n};`,\n docs: 'https://github.com/sam247/openredaction#custom-patterns'\n },\n { patternType, reason }\n );\n}\n\nexport function createValidationError(value: string, patternType: string): OpenRedactionError {\n return new OpenRedactionError(\n `Value '${value}' failed validation for pattern type '${patternType}'`,\n 'VALIDATION_FAILED',\n {\n message: 'The value matched the regex but failed custom validation. Consider whitelisting if this is expected.',\n code: `redactor.addToWhitelist('${value}', 0.9);`,\n docs: 'https://github.com/sam247/openredaction#whitelisting'\n },\n { value, patternType }\n );\n}\n\nexport function createHighMemoryError(textSize: number): OpenRedactionError {\n const sizeMB = (textSize / 1024 / 1024).toFixed(2);\n\n return new OpenRedactionError(\n `Text size is ${sizeMB}MB. Consider using streaming API for large documents.`,\n 'HIGH_MEMORY_USAGE',\n {\n message: 'Use StreamingDetector for memory-efficient processing of large documents',\n code: `import { createStreamingDetector } from 'openredaction';\n\nconst streaming = createStreamingDetector(redactor, {\n chunkSize: 2048,\n overlap: 100\n});\n\nfor await (const chunk of streaming.processStream(largeText)) {\n console.log(chunk.detections);\n}`,\n docs: 'https://github.com/sam247/openredaction#streaming-api'\n },\n { textSize, sizeMB }\n );\n}\n\nexport function createConfigLoadError(path: string, reason: string): OpenRedactionError {\n return new OpenRedactionError(\n `Failed to load config from '${path}': ${reason}`,\n 'CONFIG_LOAD_ERROR',\n {\n message: 'Check that your config file exists and is valid JSON',\n code: `{\n \"patterns\": [\"EMAIL\", \"PHONE\", \"SSN\"],\n \"preset\": \"gdpr\",\n \"customPatterns\": [],\n \"whitelist\": []\n}`,\n docs: 'https://github.com/sam247/openredaction#configuration'\n },\n { path, reason }\n );\n}\n\nexport function createLearningDisabledError(): OpenRedactionError {\n return new OpenRedactionError(\n 'Learning system is disabled',\n 'LEARNING_DISABLED',\n {\n message: 'Enable learning to use recordFalsePositive, recordFalseNegative, and other learning features',\n code: `const redactor = new OpenRedaction({\n enableLearning: true,\n learningStorePath: '.openredaction/learnings.json'\n});`,\n docs: 'https://github.com/sam247/openredaction#learning-system'\n }\n );\n}\n\nexport function createOptimizationDisabledError(): OpenRedactionError {\n return new OpenRedactionError(\n 'Priority optimization is disabled',\n 'OPTIMIZATION_DISABLED',\n {\n message: 'Enable priority optimization to use dynamic priority adjustment features',\n code: `const redactor = new OpenRedaction({\n enablePriorityOptimization: true,\n optimizerOptions: {\n learningWeight: 0.3,\n minSampleSize: 10,\n maxPriorityAdjustment: 15\n }\n});`,\n docs: 'https://github.com/sam247/openredaction#priority-optimization'\n }\n );\n}\n\nexport function createMultiPassDisabledError(): OpenRedactionError {\n return new OpenRedactionError(\n 'Multi-pass detection is disabled',\n 'MULTIPASS_DISABLED',\n {\n message: 'Enable multi-pass detection for improved accuracy with priority-based passes',\n code: `const redactor = new OpenRedaction({\n enableMultiPass: true,\n multiPassCount: 3\n});`,\n docs: 'https://github.com/sam247/openredaction#multi-pass-detection'\n }\n );\n}\n\nexport function createCacheDisabledError(): OpenRedactionError {\n return new OpenRedactionError(\n 'Result caching is disabled',\n 'CACHE_DISABLED',\n {\n message: 'Enable caching for high-volume usage and better performance',\n code: `const redactor = new OpenRedaction({\n enableCache: true,\n cacheSize: 100 // Cache last 100 results\n});`,\n docs: 'https://github.com/sam247/openredaction#caching'\n }\n );\n}\n","/**\n * Safe regex execution utilities with ReDoS protection\n * Zero-dependency implementation using time-based checks\n */\n\nexport interface SafeRegexOptions {\n timeout?: number; // Timeout in milliseconds (default: 100ms)\n maxMatches?: number; // Maximum number of matches to prevent infinite loops (default: 10000)\n}\n\nexport class RegexTimeoutError extends Error {\n constructor(pattern: string, timeout: number) {\n super(`Regex execution exceeded timeout of ${timeout}ms: ${pattern}`);\n this.name = 'RegexTimeoutError';\n }\n}\n\nexport class RegexMaxMatchesError extends Error {\n constructor(pattern: string, maxMatches: number) {\n super(`Regex execution exceeded max matches of ${maxMatches}: ${pattern}`);\n this.name = 'RegexMaxMatchesError';\n }\n}\n\n/**\n * Safely execute regex with timeout protection\n * Uses periodic time checks to prevent catastrophic backtracking\n *\n * Note: Does NOT reset lastIndex - caller is responsible for managing state\n */\nexport function safeExec(\n regex: RegExp,\n text: string,\n options: SafeRegexOptions = {}\n): RegExpExecArray | null {\n const timeout = options.timeout ?? 100; // Default 100ms\n const startTime = performance.now();\n\n // Do NOT reset lastIndex - let the regex maintain state for global matching\n // The caller should reset it before starting a new search\n\n try {\n const result = regex.exec(text);\n\n // Check if execution took too long\n const elapsed = performance.now() - startTime;\n if (elapsed > timeout) {\n throw new RegexTimeoutError(regex.source, timeout);\n }\n\n return result;\n } catch (error) {\n if (error instanceof RegexTimeoutError) {\n throw error;\n }\n // Re-throw other errors\n throw error;\n }\n}\n\n/**\n * Safely execute regex.exec() in a loop with timeout and match limit protection\n * Returns all matches or throws on timeout/limit exceeded\n */\nexport function safeExecAll(\n regex: RegExp,\n text: string,\n options: SafeRegexOptions = {}\n): RegExpExecArray[] {\n const timeout = options.timeout ?? 100; // Default 100ms per match check\n const maxMatches = options.maxMatches ?? 10000; // Default 10k matches\n const startTime = performance.now();\n const matches: RegExpExecArray[] = [];\n\n // Ensure regex has global flag for exec loop\n if (!regex.global) {\n const match = safeExec(regex, text, options);\n return match ? [match] : [];\n }\n\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n let checkCounter = 0;\n const checkInterval = 10; // Check time every N iterations\n\n while ((match = regex.exec(text)) !== null) {\n matches.push(match);\n\n // Prevent infinite loops on zero-length matches\n if (match.index === lastIndex) {\n regex.lastIndex++;\n }\n lastIndex = match.index;\n\n // Check match limit\n if (matches.length >= maxMatches) {\n throw new RegexMaxMatchesError(regex.source, maxMatches);\n }\n\n // Periodically check timeout (not on every iteration for performance)\n checkCounter++;\n if (checkCounter % checkInterval === 0) {\n const elapsed = performance.now() - startTime;\n if (elapsed > timeout) {\n throw new RegexTimeoutError(regex.source, timeout);\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Test if a regex pattern is potentially unsafe (basic static analysis)\n * Detects common ReDoS patterns\n *\n * Note: This is a very basic heuristic check. The real protection comes from\n * the execution timeout in safeExec(). This just catches obvious mistakes.\n */\nexport function isUnsafePattern(pattern: string): boolean {\n // Check for obviously dangerous patterns only\n // More sophisticated detection requires full regex AST parsing\n\n // Check for directly consecutive quantifiers (syntax error): a*+ or a++\n if (/\\*\\+|\\+\\*|\\+\\+|\\*\\*/.test(pattern)) {\n return true;\n }\n\n // Check for very obviously nested quantifiers like (a+)+ or (b*)*\n // But be very conservative to avoid false positives\n if (/\\(a\\+\\)\\+|\\(b\\*\\)\\*|\\(c\\+\\)\\+/.test(pattern)) {\n return true;\n }\n\n // For now, be very permissive. The timeout protection is the real defense.\n // Static analysis of regex is notoriously difficult without parsing.\n return false;\n}\n\n/**\n * Validate a regex pattern before use\n * Throws error if pattern is potentially unsafe\n */\nexport function validatePattern(pattern: string | RegExp): void {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n\n // Check pattern length\n if (patternStr.length > 5000) {\n throw new Error(`Regex pattern too long: ${patternStr.length} chars (max 5000)`);\n }\n\n // Check for unsafe patterns\n if (isUnsafePattern(patternStr)) {\n throw new Error(`Potentially unsafe regex pattern detected: ${patternStr.substring(0, 100)}...`);\n }\n\n // Try to compile the pattern to ensure it's valid\n try {\n new RegExp(patternStr);\n } catch (error) {\n throw new Error(`Invalid regex pattern: ${(error as Error).message}`);\n }\n}\n\n/**\n * Compile a regex with validation and return a safe wrapper\n */\nexport function compileSafeRegex(\n pattern: string | RegExp,\n flags?: string\n): RegExp {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n const finalFlags = flags || (typeof pattern === 'string' ? undefined : pattern.flags);\n\n // Validate before compilation\n validatePattern(patternStr);\n\n return new RegExp(patternStr, finalFlags);\n}\n","/**\n * Main OpenRedaction detector implementation\n */\n\nimport {\n PIIPattern,\n PIIDetection,\n DetectionResult,\n OpenRedactionOptions,\n IAuditLogger,\n IMetricsCollector,\n IRBACManager\n} from './types';\nimport { InMemoryAuditLogger } from './audit';\nimport { InMemoryMetricsCollector } from './metrics';\nimport { RBACManager, getPredefinedRole } from './rbac';\nimport { allPatterns, getPatternsByCategory } from './patterns';\nimport { generateDeterministicId } from './utils/hash';\nimport { getPreset } from './utils/presets';\nimport { applyRedactionMode } from './utils/redaction-strategies';\nimport { LocalLearningStore } from './learning/LocalLearningStore.js';\nimport { ConfigLoader } from './config/ConfigLoader.js';\nimport { analyzeFullContext } from './context/ContextAnalyzer.js';\nimport { isFalsePositive } from './filters/FalsePositiveFilter.js';\nimport { createSimpleMultiPass, groupPatternsByPass, mergePassDetections, type DetectionPass } from './multipass/MultiPassDetector.js';\nimport { NERDetector } from './ml/NERDetector.js';\nimport { ContextRulesEngine, type ContextRulesConfig } from './context/ContextRules.js';\nimport { SeverityClassifier } from './severity/SeverityClassifier.js';\nimport type { PIIMatch } from './types';\nimport { LRUCache, hashString } from './utils/cache.js';\nimport { ExplainAPI, createExplainAPI } from './explain/ExplainAPI.js';\nimport { createReportGenerator, type ReportOptions } from './reports/ReportGenerator.js';\nimport { PriorityOptimizer, createPriorityOptimizer, type OptimizerOptions } from './optimizer/PriorityOptimizer.js';\nimport {\n createLearningDisabledError,\n createOptimizationDisabledError\n} from './errors/OpenRedactionError.js';\nimport { safeExec, validatePattern, RegexTimeoutError } from './utils/safe-regex.js';\n\n/**\n * Main OpenRedaction class for detecting and redacting PII\n */\nimport type { RedactionMode } from './types';\n\nexport class OpenRedaction {\n private patterns: PIIPattern[];\n private compiledPatterns: Map<PIIPattern, RegExp> = new Map(); // Pre-compiled regex cache\n private options: {\n includeNames: boolean;\n includeAddresses: boolean;\n includePhones: boolean;\n includeEmails: boolean;\n patterns: string[];\n categories: string[]; // Pattern categories to include (e.g., ['personal', 'financial'])\n customPatterns: PIIPattern[];\n whitelist: string[];\n deterministic: boolean;\n redactionMode: RedactionMode;\n preset?: 'gdpr' | 'hipaa' | 'ccpa';\n enableContextAnalysis: boolean;\n confidenceThreshold: number;\n enableFalsePositiveFilter: boolean;\n falsePositiveThreshold: number;\n enableMultiPass: boolean;\n multiPassCount: number;\n enableCache: boolean;\n cacheSize: number;\n enablePriorityOptimization: boolean;\n optimizerOptions: OptimizerOptions;\n debug: boolean;\n maxInputSize: number; // Maximum input size in bytes (default: 10MB)\n regexTimeout: number; // Regex execution timeout in ms (default: 100ms)\n };\n private multiPassConfig?: DetectionPass[];\n private resultCache?: LRUCache<string, DetectionResult>;\n private valueToPlaceholder: Map<string, string> = new Map();\n private placeholderCounter: Map<string, number> = new Map();\n private learningStore?: LocalLearningStore;\n private priorityOptimizer?: PriorityOptimizer;\n private enableLearning: boolean;\n private auditLogger?: IAuditLogger;\n private auditUser?: string;\n private auditSessionId?: string;\n private auditMetadata?: Record<string, unknown>;\n private metricsCollector?: IMetricsCollector;\n private rbacManager?: IRBACManager;\n private nerDetector?: NERDetector;\n private contextRulesEngine?: ContextRulesEngine;\n private severityClassifier: SeverityClassifier;\n\n constructor(options: OpenRedactionOptions & {\n configPath?: string;\n enableLearning?: boolean;\n learningStorePath?: string;\n enablePriorityOptimization?: boolean;\n optimizerOptions?: Partial<OptimizerOptions>;\n enableNER?: boolean;\n enableContextRules?: boolean;\n contextRulesConfig?: ContextRulesConfig;\n maxInputSize?: number;\n regexTimeout?: number;\n } = {}) {\n // Apply preset if specified\n const presetOptions = options.preset ? getPreset(options.preset) : {};\n\n // Merge options with defaults\n const mergedOptions = {\n includeNames: true,\n includeAddresses: true,\n includePhones: true,\n includeEmails: true,\n patterns: [],\n categories: [], // Empty = use all categories\n customPatterns: [],\n whitelist: [],\n deterministic: true,\n redactionMode: 'placeholder' as RedactionMode, // Default: [EMAIL_1234]\n enableContextAnalysis: true, // Enabled by default (fine-tuned)\n confidenceThreshold: 0.5, // Balanced threshold (filters <50% confidence)\n enableFalsePositiveFilter: false, // Disabled by default (experimental)\n falsePositiveThreshold: 0.7,\n enableMultiPass: false, // Disabled by default (opt-in for better accuracy)\n multiPassCount: 3, // Default: 3 passes when enabled\n enableCache: false, // Disabled by default (opt-in for high-volume usage)\n cacheSize: 100, // Default: cache up to 100 results\n enablePriorityOptimization: false, // Disabled by default (opt-in)\n debug: false, // Disabled by default (opt-in for debugging)\n maxInputSize: 10 * 1024 * 1024, // Default: 10MB max input size\n regexTimeout: 100, // Default: 100ms regex timeout\n ...presetOptions,\n ...options\n };\n\n this.options = {\n ...mergedOptions,\n optimizerOptions: {\n learningWeight: options.optimizerOptions?.learningWeight ?? 0.3,\n minSampleSize: options.optimizerOptions?.minSampleSize ?? 10,\n maxPriorityAdjustment: options.optimizerOptions?.maxPriorityAdjustment ?? 15\n }\n };\n\n // Initialize result cache if enabled\n if (this.options.enableCache) {\n this.resultCache = new LRUCache<string, DetectionResult>(this.options.cacheSize);\n }\n\n // Initialize multi-pass configuration if enabled\n if (this.options.enableMultiPass) {\n this.multiPassConfig = createSimpleMultiPass({\n numPasses: this.options.multiPassCount,\n prioritizeCredentials: true\n });\n }\n\n // Enable learning by default\n this.enableLearning = options.enableLearning ?? true;\n\n // Initialize learning store if enabled\n if (this.enableLearning) {\n const learningPath = options.learningStorePath || '.openredaction/learnings.json';\n this.learningStore = new LocalLearningStore(learningPath, {\n autoSave: true,\n confidenceThreshold: 0.85\n });\n\n // Merge learned whitelist with user whitelist\n const learnedWhitelist = this.learningStore.getWhitelist();\n this.options.whitelist = [...this.options.whitelist, ...learnedWhitelist];\n\n // Initialize priority optimizer if enabled\n if (this.options.enablePriorityOptimization) {\n this.priorityOptimizer = createPriorityOptimizer(\n this.learningStore,\n this.options.optimizerOptions\n );\n }\n }\n\n // Build pattern list\n this.patterns = this.buildPatternList();\n\n // Validate all patterns (especially custom ones)\n this.validatePatterns();\n\n // Pre-compile all regex patterns for performance\n this.precompilePatterns();\n\n // Apply priority optimization if enabled\n if (this.priorityOptimizer) {\n this.patterns = this.priorityOptimizer.optimizePatterns(this.patterns);\n }\n\n // Initialize severity classifier (always enabled)\n this.severityClassifier = new SeverityClassifier();\n\n // Ensure all patterns have severity assigned\n this.patterns = this.severityClassifier.ensureAllSeverity(this.patterns);\n\n // Sort by priority (highest first)\n this.patterns.sort((a, b) => b.priority - a.priority);\n\n // Initialize audit logging if enabled\n if (options.enableAuditLog) {\n this.auditLogger = options.auditLogger || new InMemoryAuditLogger();\n this.auditUser = options.auditUser;\n this.auditSessionId = options.auditSessionId;\n this.auditMetadata = options.auditMetadata;\n }\n\n // Initialize metrics collection if enabled\n if (options.enableMetrics) {\n this.metricsCollector = options.metricsCollector || new InMemoryMetricsCollector();\n }\n\n // Initialize RBAC if enabled\n if (options.enableRBAC) {\n if (options.rbacManager) {\n this.rbacManager = options.rbacManager;\n } else if (options.role) {\n // Use predefined role\n const role = getPredefinedRole(options.role);\n if (role) {\n this.rbacManager = new RBACManager(role);\n }\n } else {\n // Default to admin role\n this.rbacManager = new RBACManager();\n }\n }\n\n // Initialize NER detector if enabled (requires compromise.js peer dependency)\n if (options.enableNER) {\n this.nerDetector = new NERDetector();\n if (!this.nerDetector.isAvailable()) {\n console.warn('[OpenRedaction] NER enabled but compromise.js not installed. Install with: npm install compromise');\n console.warn('[OpenRedaction] Falling back to regex-only detection.');\n this.nerDetector = undefined;\n }\n }\n\n // Initialize context rules engine if enabled\n if (options.enableContextRules !== false) {\n // Enabled by default for better accuracy\n this.contextRulesEngine = new ContextRulesEngine(options.contextRulesConfig);\n }\n }\n\n /**\n * Create OpenRedaction instance from config file\n */\n static async fromConfig(configPath?: string): Promise<OpenRedaction> {\n const loader = new ConfigLoader(configPath);\n const config = await loader.load();\n\n if (!config) {\n return new OpenRedaction();\n }\n\n const resolved = loader.resolveConfig(config);\n\n return new OpenRedaction({\n ...resolved,\n enableLearning: true,\n learningStorePath: config.learnedPatterns\n });\n }\n\n /**\n * Build the list of patterns based on options\n * Supports three filtering modes (in order of priority):\n * 1. Specific pattern types (patterns option)\n * 2. Pattern categories (categories option) - NEW!\n * 3. All patterns with type-specific filters (includeNames, etc.)\n */\n private buildPatternList(): PIIPattern[] {\n let patterns: PIIPattern[];\n\n // Priority 1: If specific patterns are whitelisted, use only those\n if (this.options.patterns && this.options.patterns.length > 0) {\n patterns = allPatterns.filter(p =>\n this.options.patterns!.includes(p.type)\n );\n }\n // Priority 2: If categories are specified, use only those categories\n else if (this.options.categories && this.options.categories.length > 0) {\n patterns = [];\n for (const category of this.options.categories) {\n const categoryPatterns = getPatternsByCategory(category);\n patterns.push(...categoryPatterns);\n }\n // Remove duplicates (some patterns may be in multiple categories)\n patterns = Array.from(new Map(patterns.map(p => [p.type, p])).values());\n\n if (this.options.debug) {\n console.log(`[OpenRedaction] Loaded ${patterns.length} patterns from categories: ${this.options.categories.join(', ')}`);\n }\n }\n // Priority 3: Use all patterns, filtered by category options\n else {\n patterns = allPatterns.filter(pattern => {\n // Filter by category options\n if (pattern.type === 'NAME' && !this.options.includeNames) return false;\n if (pattern.type.startsWith('EMAIL') && !this.options.includeEmails) return false;\n if (pattern.type.startsWith('PHONE') && !this.options.includePhones) return false;\n if (pattern.type.startsWith('ADDRESS') && !this.options.includeAddresses) return false;\n if (pattern.type.startsWith('POSTCODE') && !this.options.includeAddresses) return false;\n if (pattern.type.startsWith('ZIP') && !this.options.includeAddresses) return false;\n\n return true;\n });\n }\n\n // Add custom patterns\n if (this.options.customPatterns && this.options.customPatterns.length > 0) {\n patterns.push(...this.options.customPatterns);\n }\n\n return patterns;\n }\n\n /**\n * Validate all patterns to prevent malicious regex injection\n * ONLY validates custom patterns - built-in patterns are already vetted\n * Timeout protection in safeExec() is the primary defense against ReDoS\n */\n private validatePatterns(): void {\n // Only validate custom patterns (user-provided)\n // Built-in patterns are already vetted and safe\n if (!this.options.customPatterns || this.options.customPatterns.length === 0) {\n if (this.options.debug) {\n console.log(`[OpenRedaction] No custom patterns to validate. ${this.patterns.length} built-in patterns loaded.`);\n }\n return;\n }\n\n // Validate each custom pattern\n for (const customPattern of this.options.customPatterns) {\n try {\n validatePattern(customPattern.regex);\n } catch (error) {\n const errorMsg = `[OpenRedaction] Invalid custom pattern '${customPattern.type}': ${(error as Error).message}`;\n throw new Error(errorMsg); // Security issue - reject invalid custom patterns\n }\n }\n\n if (this.options.debug) {\n console.log(`[OpenRedaction] Validated ${this.options.customPatterns.length} custom patterns. Total patterns: ${this.patterns.length}`);\n }\n }\n\n /**\n * Pre-compile all regex patterns for performance\n * Avoids creating new RegExp objects on every detect() call\n */\n private precompilePatterns(): void {\n this.compiledPatterns.clear();\n\n for (const pattern of this.patterns) {\n const regex = new RegExp(pattern.regex.source, pattern.regex.flags);\n this.compiledPatterns.set(pattern, regex);\n }\n\n if (this.options.debug) {\n console.log(`[OpenRedaction] Pre-compiled ${this.compiledPatterns.size} regex patterns`);\n }\n }\n\n /**\n * Process patterns and detect PII\n * Used by both single-pass and multi-pass detection\n */\n private processPatterns(\n text: string,\n patterns: PIIPattern[],\n processedRanges: Array<[number, number]>\n ): PIIDetection[] {\n let detections: PIIDetection[] = [];\n\n // Process each pattern\n for (const pattern of patterns) {\n // Use pre-compiled regex for performance\n const regex = this.compiledPatterns.get(pattern);\n if (!regex) {\n if (this.options.debug) {\n console.warn(`[OpenRedaction] Pattern '${pattern.type}' not found in compiled cache, skipping`);\n }\n continue;\n }\n\n let match: RegExpExecArray | null;\n let matchCount = 0;\n const maxMatches = 10000; // Safety limit to prevent infinite loops\n\n // Reset regex state\n regex.lastIndex = 0;\n\n try {\n while ((match = safeExec(regex, text, { timeout: this.options.regexTimeout })) !== null) {\n matchCount++;\n\n // Safety check for excessive matches\n if (matchCount >= maxMatches) {\n if (this.options.debug) {\n console.warn(`[OpenRedaction] Pattern '${pattern.type}' exceeded ${maxMatches} matches, stopping`);\n }\n break;\n }\n // Use capturing group if present, otherwise use full match\n const value = match[1] !== undefined ? match[1] : match[0];\n const fullMatch = match[0];\n\n // For captured groups, we need to find the actual position\n let startPos: number;\n let endPos: number;\n\n if (match[1] !== undefined) {\n // Find the captured group position within the full match\n const captureIndex = fullMatch.indexOf(value);\n startPos = match.index + captureIndex;\n endPos = startPos + value.length;\n } else {\n startPos = match.index;\n endPos = startPos + value.length;\n }\n\n // Skip if this range overlaps with already detected PII (higher priority wins)\n if (this.overlapsWithExisting(startPos, endPos, processedRanges)) {\n continue;\n }\n\n // Get context (50 chars before and after)\n const contextStart = Math.max(0, startPos - 50);\n const contextEnd = Math.min(text.length, endPos + 50);\n const context = text.substring(contextStart, contextEnd);\n\n // Run validator if present\n if (pattern.validator && !pattern.validator(value, context)) {\n continue;\n }\n\n // Check for false positives if enabled\n if (this.options.enableFalsePositiveFilter) {\n const fpResult = isFalsePositive(value, pattern.type, context);\n if (fpResult.isFalsePositive && fpResult.confidence >= this.options.falsePositiveThreshold) {\n // Skip this detection - likely a false positive\n continue;\n }\n }\n\n // Perform context analysis if enabled\n let confidence = 1.0; // Default confidence if analysis disabled\n if (this.options.enableContextAnalysis) {\n const contextAnalysis = analyzeFullContext(\n text,\n value,\n pattern.type,\n startPos,\n endPos\n );\n confidence = contextAnalysis.confidence;\n }\n\n // Apply context rules for proximity-based confidence adjustment\n if (this.contextRulesEngine) {\n const piiMatch: PIIMatch = {\n type: pattern.type,\n value,\n start: startPos,\n end: endPos,\n confidence,\n context: {\n before: text.substring(Math.max(0, startPos - 250), startPos),\n after: text.substring(endPos, Math.min(text.length, endPos + 250))\n }\n };\n\n const adjusted = this.contextRulesEngine.applyProximityRules(piiMatch, text);\n confidence = adjusted.confidence;\n }\n\n // Filter low-confidence detections\n if (confidence < this.options.confidenceThreshold) {\n continue;\n }\n\n // Check whitelist\n if (this.options.whitelist.some(term =>\n value.toLowerCase().includes(term.toLowerCase())\n )) {\n continue;\n }\n\n // Generate placeholder\n const placeholder = this.generatePlaceholder(value, pattern);\n\n // Add detection\n detections.push({\n type: pattern.type,\n value,\n placeholder,\n position: [startPos, endPos],\n severity: pattern.severity || 'medium',\n confidence\n });\n\n // Mark range as processed\n processedRanges.push([startPos, endPos]);\n }\n } catch (error) {\n // Handle regex timeout errors gracefully\n if (error instanceof RegexTimeoutError) {\n if (this.options.debug) {\n console.warn(`[OpenRedaction] ${error.message}`);\n }\n // Skip this pattern and continue with others\n continue;\n }\n // Re-throw other errors\n throw error;\n }\n }\n\n // Apply NER hybrid detection for confidence boosting\n if (this.nerDetector && detections.length > 0) {\n // Convert detections to PIIMatch format\n const piiMatches: PIIMatch[] = detections.map(det => ({\n type: det.type,\n value: det.value,\n start: det.position[0],\n end: det.position[1],\n confidence: det.confidence || 1.0,\n context: {\n before: text.substring(Math.max(0, det.position[0] - 50), det.position[0]),\n after: text.substring(det.position[1], Math.min(text.length, det.position[1] + 50))\n }\n }));\n\n // Apply hybrid detection\n const hybridMatches = this.nerDetector.hybridDetection(piiMatches, text);\n\n // Update detections with NER-boosted confidence\n detections = detections.map((det, index) => ({\n ...det,\n confidence: hybridMatches[index].confidence\n }));\n }\n\n // Apply domain-based confidence boosting\n if (this.contextRulesEngine && detections.length > 0) {\n // Convert detections to PIIMatch format\n const piiMatches: PIIMatch[] = detections.map(det => ({\n type: det.type,\n value: det.value,\n start: det.position[0],\n end: det.position[1],\n confidence: det.confidence || 1.0,\n context: {\n before: text.substring(Math.max(0, det.position[0] - 50), det.position[0]),\n after: text.substring(det.position[1], Math.min(text.length, det.position[1] + 50))\n }\n }));\n\n // Apply domain boosting\n const boostedMatches = this.contextRulesEngine.applyDomainBoosting(piiMatches, text);\n\n // Update detections with domain-boosted confidence\n detections = detections.map((det, index) => ({\n ...det,\n confidence: boostedMatches[index].confidence\n }));\n }\n\n return detections;\n }\n\n /**\n * Detect PII in text\n */\n detect(text: string): DetectionResult {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('detection:detect')) {\n throw new Error('[OpenRedaction] Permission denied: detection:detect required');\n }\n\n const startTime = performance.now();\n\n // Enforce input size limit (security critical)\n const textSize = new Blob([text]).size;\n if (textSize > this.options.maxInputSize) {\n throw new Error(\n `[OpenRedaction] Input size (${textSize} bytes) exceeds maximum allowed size (${this.options.maxInputSize} bytes). ` +\n `Set maxInputSize option to increase limit or use streaming/batch processing for large documents.`\n );\n }\n\n // Warn about large documents approaching the limit\n if (textSize > this.options.maxInputSize * 0.8 && this.options.debug) {\n console.warn(\n `[OpenRedaction] Input size (${textSize} bytes) is approaching maximum limit (${this.options.maxInputSize} bytes)`\n );\n }\n\n if (this.options.debug) {\n console.log(`[OpenRedaction] Detecting PII in ${textSize} byte text`);\n console.log(`[OpenRedaction] Active patterns: ${this.patterns.length}`);\n console.log(`[OpenRedaction] Multi-pass: ${this.options.enableMultiPass ? 'enabled' : 'disabled'}`);\n console.log(`[OpenRedaction] Cache: ${this.options.enableCache ? 'enabled' : 'disabled'}`);\n }\n\n // Check cache if enabled\n if (this.resultCache) {\n const cacheKey = hashString(text);\n const cached = this.resultCache.get(cacheKey);\n if (cached) {\n if (this.options.debug) {\n console.log('[OpenRedaction] Cache hit, returning cached result');\n }\n return cached;\n }\n }\n\n // Reset counters for this detection run if not deterministic\n if (!this.options.deterministic) {\n this.placeholderCounter.clear();\n this.valueToPlaceholder.clear();\n }\n\n let detections: PIIDetection[];\n const processedRanges: Array<[number, number]> = [];\n\n // Use multi-pass detection if enabled\n if (this.options.enableMultiPass && this.multiPassConfig) {\n // Group patterns by pass\n const patternGroups = groupPatternsByPass(this.patterns, this.multiPassConfig);\n const passDetections = new Map<string, PIIDetection[]>();\n\n // Process each pass in order\n for (const pass of this.multiPassConfig) {\n const passPatterns = patternGroups.get(pass.name) || [];\n if (passPatterns.length === 0) continue;\n\n // Process this pass\n const currentDetections = this.processPatterns(text, passPatterns, processedRanges);\n\n // Store detections for this pass\n passDetections.set(pass.name, currentDetections);\n\n // Update processed ranges for next pass\n for (const detection of currentDetections) {\n processedRanges.push(detection.position);\n }\n }\n\n // Merge detections from all passes\n detections = mergePassDetections(passDetections, this.multiPassConfig);\n } else {\n // Single-pass detection (original behavior)\n detections = this.processPatterns(text, this.patterns, processedRanges);\n }\n\n // Sort detections by position (descending) for proper replacement\n detections.sort((a, b) => b.position[0] - a.position[0]);\n\n // Build redacted text and redaction map\n let redacted = text;\n const redactionMap: Record<string, string> = {};\n\n for (const detection of detections) {\n const [start, end] = detection.position;\n redacted = redacted.substring(0, start) +\n detection.placeholder +\n redacted.substring(end);\n\n redactionMap[detection.placeholder] = detection.value;\n }\n\n const endTime = performance.now();\n const processingTime = Math.round((endTime - startTime) * 100) / 100;\n\n const result: DetectionResult = {\n original: text,\n redacted,\n detections: detections.reverse(), // Return in original order\n redactionMap,\n stats: {\n processingTime,\n piiCount: detections.length\n }\n };\n\n if (this.options.debug) {\n console.log(`[OpenRedaction] Detection complete: ${detections.length} PII found in ${processingTime}ms`);\n if (detections.length > 0) {\n const typeCounts: Record<string, number> = {};\n for (const detection of detections) {\n typeCounts[detection.type] = (typeCounts[detection.type] || 0) + 1;\n }\n console.log(`[OpenRedaction] Detection breakdown:`, typeCounts);\n }\n }\n\n // Log audit entry if enabled\n if (this.auditLogger) {\n try {\n const piiTypes = [...new Set(detections.map(d => d.type))];\n this.auditLogger.log({\n operation: 'redact',\n piiCount: detections.length,\n piiTypes,\n textLength: text.length,\n processingTimeMs: processingTime,\n redactionMode: this.options.redactionMode,\n success: true,\n user: this.auditUser,\n sessionId: this.auditSessionId,\n metadata: this.auditMetadata\n });\n } catch (error) {\n // Don't fail the redaction if audit logging fails\n if (this.options.debug) {\n console.error('[OpenRedaction] Audit logging failed:', error);\n }\n }\n }\n\n // Record metrics if enabled\n if (this.metricsCollector) {\n try {\n this.metricsCollector.recordRedaction(result, processingTime, this.options.redactionMode);\n } catch (error) {\n // Don't fail the redaction if metrics recording fails\n if (this.options.debug) {\n console.error('[OpenRedaction] Metrics recording failed:', error);\n }\n }\n }\n\n // Store in cache if enabled\n if (this.resultCache) {\n const cacheKey = hashString(text);\n this.resultCache.set(cacheKey, result);\n if (this.options.debug) {\n console.log('[OpenRedaction] Result cached');\n }\n }\n\n return result;\n }\n\n /**\n * Restore redacted text using redaction map\n */\n restore(redactedText: string, redactionMap: Record<string, string>): string {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('detection:restore')) {\n throw new Error('[OpenRedaction] Permission denied: detection:restore required');\n }\n\n const startTime = performance.now();\n let restored = redactedText;\n\n for (const [placeholder, value] of Object.entries(redactionMap)) {\n restored = restored.replace(new RegExp(this.escapeRegex(placeholder), 'g'), value);\n }\n\n const endTime = performance.now();\n const processingTime = Math.round((endTime - startTime) * 100) / 100;\n\n // Log audit entry if enabled\n if (this.auditLogger) {\n try {\n this.auditLogger.log({\n operation: 'restore',\n piiCount: Object.keys(redactionMap).length,\n piiTypes: [], // Types not available in restore context\n textLength: redactedText.length,\n processingTimeMs: processingTime,\n success: true,\n user: this.auditUser,\n sessionId: this.auditSessionId,\n metadata: this.auditMetadata\n });\n } catch (error) {\n // Don't fail the restore if audit logging fails\n if (this.options.debug) {\n console.error('[OpenRedaction] Audit logging failed:', error);\n }\n }\n }\n\n return restored;\n }\n\n /**\n * Generate placeholder for a detected value\n */\n private generatePlaceholder(value: string, pattern: PIIPattern): string {\n // Check if we've seen this value before (for deterministic mode)\n if (this.options.deterministic && this.valueToPlaceholder.has(value)) {\n return this.valueToPlaceholder.get(value)!;\n }\n\n let placeholder: string;\n\n // For non-placeholder modes, use redaction strategies directly\n if (this.options.redactionMode !== 'placeholder') {\n placeholder = applyRedactionMode(\n value,\n pattern.type,\n this.options.redactionMode,\n pattern.placeholder\n );\n // Still store mapping for consistency\n this.valueToPlaceholder.set(value, placeholder);\n return placeholder;\n }\n\n // Placeholder mode (default behavior)\n if (this.options.deterministic) {\n // Generate deterministic ID based on value\n const id = generateDeterministicId(value, pattern.type);\n placeholder = pattern.placeholder.replace('{n}', id);\n } else {\n // Use incrementing counter\n const count = (this.placeholderCounter.get(pattern.type) || 0) + 1;\n this.placeholderCounter.set(pattern.type, count);\n placeholder = pattern.placeholder.replace('{n}', count.toString());\n }\n\n // Store mapping\n this.valueToPlaceholder.set(value, placeholder);\n\n return placeholder;\n }\n\n /**\n * Check if a range overlaps with existing detections\n */\n private overlapsWithExisting(\n start: number,\n end: number,\n ranges: Array<[number, number]>\n ): boolean {\n return ranges.some(\n ([existingStart, existingEnd]) =>\n (start >= existingStart && start < existingEnd) ||\n (end > existingStart && end <= existingEnd) ||\n (start <= existingStart && end >= existingEnd)\n );\n }\n\n /**\n * Escape special regex characters\n */\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n /**\n * Get the list of active patterns\n */\n getPatterns(): PIIPattern[] {\n return [...this.patterns];\n }\n\n /**\n * Get severity-based scan results\n */\n scan(text: string): {\n high: PIIDetection[];\n medium: PIIDetection[];\n low: PIIDetection[];\n total: number;\n } {\n const result = this.detect(text);\n\n return {\n high: result.detections.filter(d => d.severity === 'high'),\n medium: result.detections.filter(d => d.severity === 'medium'),\n low: result.detections.filter(d => d.severity === 'low'),\n total: result.detections.length\n };\n }\n\n /**\n * Record a false positive (incorrectly detected as PII)\n */\n recordFalsePositive(detection: PIIDetection, context?: string): void {\n if (!this.learningStore) {\n throw createLearningDisabledError();\n }\n\n const ctx = context || '';\n this.learningStore.recordFalsePositive(detection.value, detection.type, ctx);\n\n // Update whitelist if confidence is high enough\n if (this.learningStore.getConfidence(detection.value) >= 0.85) {\n this.options.whitelist.push(detection.value);\n }\n }\n\n /**\n * Record a false negative (missed PII that should have been detected)\n */\n recordFalseNegative(text: string, expectedType: string, context?: string): void {\n if (!this.learningStore) {\n throw createLearningDisabledError();\n }\n\n const ctx = context || '';\n this.learningStore.recordFalseNegative(text, expectedType, ctx);\n }\n\n /**\n * Record a correct detection (for accuracy tracking)\n */\n recordCorrectDetection(): void {\n if (!this.learningStore) {\n return;\n }\n\n this.learningStore.recordCorrectDetection();\n }\n\n /**\n * Get learning statistics\n */\n getLearningStats() {\n if (!this.learningStore) {\n return null;\n }\n\n return this.learningStore.getStats();\n }\n\n /**\n * Get learned whitelist entries\n */\n getLearnedWhitelist() {\n if (!this.learningStore) {\n return [];\n }\n\n return this.learningStore.getWhitelistEntries();\n }\n\n /**\n * Get pattern adjustment suggestions\n */\n getPatternAdjustments() {\n if (!this.learningStore) {\n return [];\n }\n\n return this.learningStore.getPatternAdjustments();\n }\n\n /**\n * Export learned patterns for sharing\n */\n exportLearnings(options?: {\n includeContexts?: boolean;\n minConfidence?: number;\n }) {\n if (!this.learningStore) {\n return null;\n }\n\n return this.learningStore.export(options);\n }\n\n /**\n * Import learned patterns from another source\n */\n importLearnings(data: any, merge: boolean = true): void {\n if (!this.learningStore) {\n throw createLearningDisabledError();\n }\n\n this.learningStore.import(data, merge);\n\n // Update whitelist with newly learned patterns\n const learnedWhitelist = this.learningStore.getWhitelist();\n this.options.whitelist = [...new Set([...this.options.whitelist, ...learnedWhitelist])];\n }\n\n /**\n * Manually add a term to the whitelist\n */\n addToWhitelist(pattern: string, confidence: number = 0.9): void {\n if (!this.learningStore) {\n this.options.whitelist.push(pattern);\n return;\n }\n\n this.learningStore.addToWhitelist(pattern, confidence);\n this.options.whitelist.push(pattern);\n }\n\n /**\n * Remove a term from the whitelist\n */\n removeFromWhitelist(pattern: string): void {\n if (this.learningStore) {\n this.learningStore.removeFromWhitelist(pattern);\n }\n\n this.options.whitelist = this.options.whitelist.filter(w => w !== pattern);\n }\n\n /**\n * Get the learning store instance\n */\n getLearningStore(): LocalLearningStore | undefined {\n return this.learningStore;\n }\n\n /**\n * Get the priority optimizer instance\n */\n getPriorityOptimizer(): PriorityOptimizer | undefined {\n return this.priorityOptimizer;\n }\n\n /**\n * Optimize pattern priorities based on learning data\n * Call this to re-optimize priorities after accumulating new learning data\n */\n optimizePriorities(): void {\n if (!this.priorityOptimizer) {\n throw createOptimizationDisabledError();\n }\n\n // Re-optimize patterns\n this.patterns = this.priorityOptimizer.optimizePatterns(this.patterns);\n\n // Re-sort by new priorities\n this.patterns.sort((a, b) => b.priority - a.priority);\n\n // Clear cache if enabled (priorities changed, cached results may be invalid)\n if (this.resultCache) {\n this.resultCache.clear();\n }\n }\n\n /**\n * Get pattern statistics with learning data\n */\n getPatternStats() {\n if (!this.priorityOptimizer) {\n return null;\n }\n\n return this.priorityOptimizer.getPatternStats(this.patterns);\n }\n\n /**\n * Clear the result cache (if caching is enabled)\n */\n clearCache(): void {\n if (this.resultCache) {\n this.resultCache.clear();\n }\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; maxSize: number; enabled: boolean } {\n return {\n size: this.resultCache?.size || 0,\n maxSize: this.options.cacheSize,\n enabled: this.options.enableCache\n };\n }\n\n /**\n * Get the audit logger instance (if audit logging is enabled)\n */\n getAuditLogger(): IAuditLogger | undefined {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('audit:read')) {\n throw new Error('[OpenRedaction] Permission denied: audit:read required');\n }\n\n return this.auditLogger;\n }\n\n /**\n * Get the metrics collector instance (if metrics collection is enabled)\n */\n getMetricsCollector(): IMetricsCollector | undefined {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('metrics:read')) {\n throw new Error('[OpenRedaction] Permission denied: metrics:read required');\n }\n\n return this.metricsCollector;\n }\n\n /**\n * Get the RBAC manager instance (if RBAC is enabled)\n */\n getRBACManager(): IRBACManager | undefined {\n return this.rbacManager;\n }\n\n /**\n * Create an explain API for debugging detections\n */\n explain(): ExplainAPI {\n return createExplainAPI(this);\n }\n\n /**\n * Generate a report from detection results\n */\n generateReport(result: DetectionResult, options: ReportOptions): string {\n const generator = createReportGenerator(this);\n return generator.generate(result, options);\n }\n\n /**\n * Export current configuration\n */\n exportConfig(metadata?: {\n description?: string;\n author?: string;\n tags?: string[];\n }): string {\n const { ConfigExporter } = require('./config/ConfigExporter.js');\n return ConfigExporter.exportToString(this.options, metadata, true);\n }\n\n /**\n * Run health check\n */\n async healthCheck(options?: {\n testDetection?: boolean;\n checkPerformance?: boolean;\n performanceThreshold?: number;\n memoryThreshold?: number;\n }): Promise<any> {\n const { HealthChecker } = await import('./health/HealthCheck.js');\n const checker = new HealthChecker(this);\n return checker.check(options);\n }\n\n /**\n * Quick health check (minimal overhead)\n */\n async quickHealthCheck(): Promise<{ status: 'healthy' | 'unhealthy'; message: string }> {\n const { HealthChecker } = await import('./health/HealthCheck.js');\n const checker = new HealthChecker(this);\n return checker.quickCheck();\n }\n\n /**\n * Detect PII in a document (PDF, DOCX, TXT)\n * Requires optional peer dependencies:\n * - pdf-parse for PDF support\n * - mammoth for DOCX support\n */\n async detectDocument(\n buffer: Buffer,\n options?: import('./document/types').DocumentOptions\n ): Promise<import('./document/types').DocumentResult> {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('detection:detect')) {\n throw new Error('[OpenRedaction] Permission denied: detection:detect required');\n }\n\n const { createDocumentProcessor } = await import('./document');\n const processor = createDocumentProcessor();\n\n const extractionStart = performance.now();\n\n // Extract text from document\n const text = await processor.extractText(buffer, options);\n const metadata = await processor.getMetadata(buffer, options);\n\n const extractionEnd = performance.now();\n const extractionTime = Math.round((extractionEnd - extractionStart) * 100) / 100;\n\n // Detect PII in extracted text\n const detection = this.detect(text);\n\n return {\n text,\n metadata,\n detection,\n fileSize: buffer.length,\n extractionTime\n };\n }\n\n /**\n * Detect PII in a document file from filesystem\n * Convenience method that reads file and calls detectDocument\n */\n async detectDocumentFile(\n filePath: string,\n options?: import('./document/types').DocumentOptions\n ): Promise<import('./document/types').DocumentResult> {\n // Check RBAC permission\n if (this.rbacManager && !this.rbacManager.hasPermission('detection:detect')) {\n throw new Error('[OpenRedaction] Permission denied: detection:detect required');\n }\n\n const fs = await import('fs/promises');\n const buffer = await fs.readFile(filePath);\n\n return this.detectDocument(buffer, options);\n }\n\n /**\n * Batch detect PII in multiple texts using worker threads (parallel)\n * Significantly faster for processing many texts\n */\n static async detectBatch(\n texts: string[],\n options?: OpenRedactionOptions & { numWorkers?: number }\n ): Promise<DetectionResult[]> {\n const { createWorkerPool } = await import('./workers');\n const pool = createWorkerPool({ numWorkers: options?.numWorkers });\n\n try {\n await pool.initialize();\n\n const tasks = texts.map((text, index) => ({\n type: 'detect' as const,\n id: `detect_${index}`,\n text,\n options\n }));\n\n const results = await Promise.all(\n tasks.map(task => pool.execute<DetectionResult>(task))\n );\n\n return results;\n } finally {\n await pool.terminate();\n }\n }\n\n /**\n * Batch process multiple documents using worker threads (parallel)\n * Efficient for processing many documents at once\n */\n static async detectDocumentsBatch(\n buffers: Buffer[],\n options?: import('./document/types').DocumentOptions & { numWorkers?: number }\n ): Promise<import('./document/types').DocumentResult[]> {\n const { createWorkerPool } = await import('./workers');\n const pool = createWorkerPool({ numWorkers: options?.numWorkers });\n\n try {\n await pool.initialize();\n\n const tasks = buffers.map((buffer, index) => ({\n type: 'document' as const,\n id: `document_${index}`,\n buffer,\n options\n }));\n\n const results = await Promise.all(\n tasks.map(task => pool.execute(task))\n );\n\n return results;\n } finally {\n await pool.terminate();\n }\n }\n}\n","/**\n * Streaming API for processing large documents\n * Allows efficient processing of documents in chunks\n */\n\nimport { PIIDetection, DetectionResult } from '../types';\nimport { OpenRedaction } from '../detector';\n\n/**\n * Chunk result for streaming detection\n */\nexport interface ChunkResult {\n /** Chunk index */\n chunkIndex: number;\n /** Detections found in this chunk */\n detections: PIIDetection[];\n /** Redacted chunk text */\n redactedChunk: string;\n /** Original chunk text */\n originalChunk: string;\n /** Byte offset of this chunk in the original document */\n byteOffset: number;\n}\n\n/**\n * Streaming detection options\n */\nexport interface StreamingOptions {\n /** Chunk size in characters (default: 2048) */\n chunkSize?: number;\n /** Overlap between chunks to catch patterns at boundaries (default: 100) */\n overlap?: number;\n /** Enable progressive redaction (default: true) */\n progressiveRedaction?: boolean;\n}\n\n/**\n * Streaming detector for large documents\n */\nexport class StreamingDetector {\n private detector: OpenRedaction;\n private options: Required<StreamingOptions>;\n\n constructor(detector: OpenRedaction, options: StreamingOptions = {}) {\n this.detector = detector;\n this.options = {\n chunkSize: options.chunkSize || 2048,\n overlap: options.overlap || 100,\n progressiveRedaction: options.progressiveRedaction ?? true\n };\n }\n\n /**\n * Process a large text in chunks\n * Returns an async generator that yields chunk results\n */\n async *processStream(text: string): AsyncGenerator<ChunkResult, void, undefined> {\n const { chunkSize, overlap } = this.options;\n const textLength = text.length;\n let position = 0;\n let chunkIndex = 0;\n const processedRanges = new Set<string>();\n\n while (position < textLength) {\n // Calculate chunk boundaries\n const start = Math.max(0, position - overlap);\n const end = Math.min(textLength, position + chunkSize);\n const chunk = text.substring(start, end);\n const byteOffset = start;\n\n // Detect PII in this chunk\n const result = this.detector.detect(chunk);\n\n // Filter out detections we've already processed\n const newDetections = result.detections.filter((detection: PIIDetection) => {\n const absoluteStart = byteOffset + detection.position[0];\n const absoluteEnd = byteOffset + detection.position[1];\n const rangeKey = `${absoluteStart}-${absoluteEnd}`;\n\n // Skip if we've already processed this exact detection\n if (processedRanges.has(rangeKey)) {\n return false;\n }\n\n // For first chunk, include all detections\n // For subsequent chunks, only include detections in the non-overlap region\n const chunkStartInDoc = position;\n const detectionStartInDoc = absoluteStart;\n const isInMainRegion = chunkIndex === 0 || detectionStartInDoc >= chunkStartInDoc;\n\n if (isInMainRegion) {\n processedRanges.add(rangeKey);\n return true;\n }\n\n return false;\n });\n\n // Adjust positions to be relative to the full document\n const adjustedDetections = newDetections.map((detection: PIIDetection) => ({\n ...detection,\n position: [\n byteOffset + detection.position[0],\n byteOffset + detection.position[1]\n ] as [number, number]\n }));\n\n // Build redacted chunk (if progressive redaction is enabled)\n let redactedChunk = chunk;\n if (this.options.progressiveRedaction) {\n // Sort by position descending for proper replacement\n const sortedDetections = [...result.detections].sort(\n (a, b) => b.position[0] - a.position[0]\n );\n\n for (const detection of sortedDetections) {\n const [start, end] = detection.position;\n redactedChunk =\n redactedChunk.substring(0, start) +\n detection.placeholder +\n redactedChunk.substring(end);\n }\n }\n\n yield {\n chunkIndex,\n detections: adjustedDetections,\n redactedChunk,\n originalChunk: chunk,\n byteOffset\n };\n\n // Move to next chunk\n position += chunkSize;\n chunkIndex++;\n }\n }\n\n /**\n * Process entire stream and collect all results\n */\n async processComplete(text: string): Promise<DetectionResult> {\n const allDetections: PIIDetection[] = [];\n let redactedText = text;\n\n for await (const chunk of this.processStream(text)) {\n allDetections.push(...chunk.detections);\n }\n\n // Sort detections by position (descending) for proper replacement\n allDetections.sort((a, b) => b.position[0] - a.position[0]);\n\n // Build complete redacted text\n const redactionMap: Record<string, string> = {};\n\n for (const detection of allDetections) {\n const [start, end] = detection.position;\n redactedText =\n redactedText.substring(0, start) +\n detection.placeholder +\n redactedText.substring(end);\n\n redactionMap[detection.placeholder] = detection.value;\n }\n\n return {\n original: text,\n redacted: redactedText,\n detections: allDetections.reverse(), // Return in original order\n redactionMap,\n stats: {\n piiCount: allDetections.length\n }\n };\n }\n\n /**\n * Process a file stream (Node.js only)\n */\n async *processFileStream(\n readableStream: ReadableStream<Uint8Array> | NodeJS.ReadableStream\n ): AsyncGenerator<ChunkResult, void, undefined> {\n const decoder = new TextDecoder();\n let buffer = '';\n const reader = 'getReader' in readableStream\n ? readableStream.getReader()\n : null;\n\n if (reader) {\n // Web Streams API (browser/modern Node.js)\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete chunks from buffer\n while (buffer.length >= this.options.chunkSize) {\n const chunk = buffer.substring(0, this.options.chunkSize);\n buffer = buffer.substring(this.options.chunkSize);\n\n // Process this chunk\n for await (const result of this.processStream(chunk)) {\n yield result;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // Process remaining buffer\n if (buffer.length > 0) {\n for await (const result of this.processStream(buffer)) {\n yield result;\n }\n }\n } else {\n // Node.js Stream (legacy)\n const nodeStream = readableStream as NodeJS.ReadableStream;\n\n for await (const chunk of nodeStream) {\n buffer += decoder.decode(chunk as Uint8Array, { stream: true });\n\n // Process complete chunks from buffer\n while (buffer.length >= this.options.chunkSize) {\n const textChunk = buffer.substring(0, this.options.chunkSize);\n buffer = buffer.substring(this.options.chunkSize);\n\n // Process this chunk\n for await (const result of this.processStream(textChunk)) {\n yield result;\n }\n }\n }\n\n // Process remaining buffer\n if (buffer.length > 0) {\n for await (const result of this.processStream(buffer)) {\n yield result;\n }\n }\n }\n }\n\n /**\n * Get chunk statistics\n */\n getChunkStats(textLength: number): {\n numChunks: number;\n chunkSize: number;\n overlap: number;\n estimatedMemory: number;\n } {\n const numChunks = Math.ceil(textLength / this.options.chunkSize);\n const estimatedMemory = (this.options.chunkSize + this.options.overlap) * 2; // UTF-16 chars\n\n return {\n numChunks,\n chunkSize: this.options.chunkSize,\n overlap: this.options.overlap,\n estimatedMemory\n };\n }\n}\n\n/**\n * Helper to create a streaming detector from OpenRedaction instance\n */\nexport function createStreamingDetector(\n detector: OpenRedaction,\n options?: StreamingOptions\n): StreamingDetector {\n return new StreamingDetector(detector, options);\n}\n","/**\n * Batch processing for multiple documents\n * Efficient processing of arrays of texts\n */\n\nimport { DetectionResult } from '../types';\nimport { OpenRedaction } from '../detector';\n\n/**\n * Batch processing options\n */\nexport interface BatchOptions {\n /** Enable parallel processing (default: false) */\n parallel?: boolean;\n /** Maximum concurrency for parallel processing (default: 4) */\n maxConcurrency?: number;\n /** Progress callback */\n onProgress?: (completed: number, total: number) => void;\n}\n\n/**\n * Batch processing result\n */\nexport interface BatchResult {\n /** Individual results for each document */\n results: DetectionResult[];\n /** Total processing stats */\n stats: {\n /** Total documents processed */\n totalDocuments: number;\n /** Total PII detections across all documents */\n totalDetections: number;\n /** Total processing time in milliseconds */\n totalTime: number;\n /** Average time per document */\n avgTimePerDocument: number;\n };\n}\n\n/**\n * Batch processor for processing multiple documents\n */\nexport class BatchProcessor {\n private detector: OpenRedaction;\n\n constructor(detector: OpenRedaction) {\n this.detector = detector;\n }\n\n /**\n * Process multiple documents sequentially\n */\n processSequential(\n documents: string[],\n options: BatchOptions = {}\n ): BatchResult {\n const startTime = performance.now();\n const results: DetectionResult[] = [];\n\n for (let i = 0; i < documents.length; i++) {\n const result = this.detector.detect(documents[i]);\n results.push(result);\n\n if (options.onProgress) {\n options.onProgress(i + 1, documents.length);\n }\n }\n\n const endTime = performance.now();\n const totalTime = endTime - startTime;\n\n return {\n results,\n stats: {\n totalDocuments: documents.length,\n totalDetections: results.reduce((sum, r) => sum + r.detections.length, 0),\n totalTime,\n avgTimePerDocument: totalTime / documents.length\n }\n };\n }\n\n /**\n * Process multiple documents in parallel\n */\n async processParallel(\n documents: string[],\n options: BatchOptions = {}\n ): Promise<BatchResult> {\n const startTime = performance.now();\n const maxConcurrency = options.maxConcurrency || 4;\n const results: DetectionResult[] = new Array(documents.length);\n let completed = 0;\n\n // Process in batches of maxConcurrency\n for (let i = 0; i < documents.length; i += maxConcurrency) {\n const batch = documents.slice(i, i + maxConcurrency);\n const batchPromises = batch.map((doc, batchIndex) => {\n return Promise.resolve().then(() => {\n const result = this.detector.detect(doc);\n results[i + batchIndex] = result;\n completed++;\n\n if (options.onProgress) {\n options.onProgress(completed, documents.length);\n }\n\n return result;\n });\n });\n\n await Promise.all(batchPromises);\n }\n\n const endTime = performance.now();\n const totalTime = endTime - startTime;\n\n return {\n results,\n stats: {\n totalDocuments: documents.length,\n totalDetections: results.reduce((sum, r) => sum + r.detections.length, 0),\n totalTime,\n avgTimePerDocument: totalTime / documents.length\n }\n };\n }\n\n /**\n * Process multiple documents (automatically chooses sequential or parallel)\n */\n async process(\n documents: string[],\n options: BatchOptions = {}\n ): Promise<BatchResult> {\n if (options.parallel) {\n return this.processParallel(documents, options);\n } else {\n return Promise.resolve(this.processSequential(documents, options));\n }\n }\n\n /**\n * Process documents with automatic batching\n * Useful for very large arrays of documents\n */\n async *processStream(\n documents: string[],\n batchSize: number = 10\n ): AsyncGenerator<DetectionResult, void, undefined> {\n for (let i = 0; i < documents.length; i += batchSize) {\n const batch = documents.slice(i, i + batchSize);\n\n for (const doc of batch) {\n const result = this.detector.detect(doc);\n yield result;\n }\n }\n }\n\n /**\n * Get aggregated statistics across multiple results\n */\n getAggregatedStats(results: DetectionResult[]): {\n totalDetections: number;\n detectionsByType: Record<string, number>;\n detectionsBySeverity: Record<string, number>;\n avgConfidence: number;\n } {\n const detectionsByType: Record<string, number> = {};\n const detectionsBySeverity: Record<string, number> = {};\n let totalConfidence = 0;\n let totalWithConfidence = 0;\n\n for (const result of results) {\n for (const detection of result.detections) {\n // Count by type\n detectionsByType[detection.type] = (detectionsByType[detection.type] || 0) + 1;\n\n // Count by severity\n detectionsBySeverity[detection.severity] = (detectionsBySeverity[detection.severity] || 0) + 1;\n\n // Track confidence\n if (detection.confidence !== undefined) {\n totalConfidence += detection.confidence;\n totalWithConfidence++;\n }\n }\n }\n\n return {\n totalDetections: results.reduce((sum, r) => sum + r.detections.length, 0),\n detectionsByType,\n detectionsBySeverity,\n avgConfidence: totalWithConfidence > 0 ? totalConfidence / totalWithConfidence : 0\n };\n }\n}\n\n/**\n * Helper to create a batch processor\n */\nexport function createBatchProcessor(detector: OpenRedaction): BatchProcessor {\n return new BatchProcessor(detector);\n}\n","/**\n * Express middleware for PII detection\n * Local-first server-side PII detection and redaction\n */\n\nimport { OpenRedaction } from '../detector';\nimport type { DetectionResult, OpenRedactionOptions } from '../types';\nimport type { Request, Response, NextFunction } from 'express';\n\n/**\n * Middleware options\n */\nexport interface OpenRedactionMiddlewareOptions extends OpenRedactionOptions {\n /** Auto-redact request body (default: false) */\n autoRedact?: boolean;\n /** Fields to check in request body (default: all) */\n fields?: string[];\n /** Skip detection for certain routes (regex patterns) */\n skipRoutes?: RegExp[];\n /** Add PII detection results to request object (default: true) */\n attachResults?: boolean;\n /** Custom handler for PII detection */\n onDetection?: (req: Request, result: DetectionResult) => void;\n /** Fail request if PII detected (default: false) */\n failOnPII?: boolean;\n /** Add response headers with PII info (default: false) */\n addHeaders?: boolean;\n}\n\n/**\n * Extended Express Request with PII detection results\n */\nexport interface OpenRedactionRequest extends Request {\n pii?: {\n detected: boolean;\n count: number;\n result: DetectionResult;\n redacted?: any;\n };\n}\n\n/**\n * Create Express middleware for PII detection\n */\nexport function openredactionMiddleware(options: OpenRedactionMiddlewareOptions = {}) {\n // Extract middleware-specific options\n const {\n autoRedact = false,\n fields = [],\n skipRoutes = [],\n attachResults = true,\n onDetection,\n failOnPII = false,\n addHeaders = false,\n ...detectorOptions\n } = options;\n\n // Create detector with only OpenRedactionOptions\n const detector = new OpenRedaction(detectorOptions);\n\n return (req: Request, res: Response, next: NextFunction) => {\n // Skip if route matches skip pattern\n if (skipRoutes.some(pattern => pattern.test(req.path))) {\n return next();\n }\n\n // Only process if there's a body\n if (!req.body || typeof req.body !== 'object') {\n return next();\n }\n\n try {\n // Determine which fields to check\n const fieldsToCheck = fields.length > 0\n ? fields\n : Object.keys(req.body);\n\n // Collect all text to check\n const textsToCheck: Array<{ field: string; value: string }> = [];\n\n for (const field of fieldsToCheck) {\n const value = req.body[field];\n if (typeof value === 'string' && value.length > 0) {\n textsToCheck.push({ field, value });\n }\n }\n\n // Detect PII in all fields\n let totalDetections = 0;\n const results: Record<string, DetectionResult> = {};\n const redactedBody: any = { ...req.body };\n\n for (const { field, value } of textsToCheck) {\n const result = detector.detect(value);\n\n if (result.detections.length > 0) {\n totalDetections += result.detections.length;\n results[field] = result;\n\n // Auto-redact if enabled\n if (autoRedact) {\n redactedBody[field] = result.redacted;\n }\n }\n }\n\n // Attach results to request\n if (attachResults) {\n const extReq = req as OpenRedactionRequest;\n extReq.pii = {\n detected: totalDetections > 0,\n count: totalDetections,\n result: results[Object.keys(results)[0]] || {\n original: '',\n redacted: '',\n detections: [],\n redactionMap: {},\n stats: { piiCount: 0 }\n },\n redacted: autoRedact ? redactedBody : undefined\n };\n }\n\n // Replace body if auto-redact is enabled\n if (autoRedact && totalDetections > 0) {\n req.body = redactedBody;\n }\n\n // Add response headers if enabled\n if (addHeaders && totalDetections > 0) {\n res.setHeader('X-PII-Detected', 'true');\n res.setHeader('X-PII-Count', totalDetections.toString());\n }\n\n // Call custom handler\n if (onDetection && totalDetections > 0 && Object.keys(results).length > 0) {\n onDetection(req, results[Object.keys(results)[0]]);\n }\n\n // Fail if PII detected and failOnPII is true\n if (failOnPII && totalDetections > 0) {\n return res.status(400).json({\n error: 'PII detected in request',\n message: 'Personal Identifiable Information was detected and rejected',\n piiCount: totalDetections,\n fields: Object.keys(results)\n });\n }\n\n next();\n } catch (error) {\n next(error);\n }\n };\n}\n\n/**\n * Express route handler for PII detection\n */\nexport function detectPII(options: OpenRedactionOptions = {}) {\n const detector = new OpenRedaction(options);\n\n return (req: Request, res: Response): void => {\n const text = req.body?.text || req.query.text as string;\n\n if (!text) {\n res.status(400).json({\n error: 'Missing text parameter',\n message: 'Provide text in request body or query parameter'\n });\n return;\n }\n\n const result = detector.detect(text);\n\n res.json({\n detected: result.detections.length > 0,\n count: result.detections.length,\n detections: result.detections,\n redacted: result.redacted,\n stats: result.stats\n });\n };\n}\n\n/**\n * Express route handler for generating reports\n */\nexport function generateReport(options: OpenRedactionOptions = {}) {\n const detector = new OpenRedaction(options);\n\n return (req: Request, res: Response): void => {\n const text = req.body?.text;\n const format = (req.body?.format || req.query.format || 'json') as string;\n\n if (!text) {\n res.status(400).json({\n error: 'Missing text parameter'\n });\n return;\n }\n\n const result = detector.detect(text);\n\n if (format === 'html') {\n const html = detector.generateReport(result, {\n format: 'html',\n title: req.body?.title || 'PII Detection Report'\n });\n res.setHeader('Content-Type', 'text/html');\n res.send(html);\n } else if (format === 'markdown') {\n const md = detector.generateReport(result, {\n format: 'markdown',\n title: req.body?.title || 'PII Detection Report'\n });\n res.setHeader('Content-Type', 'text/markdown');\n res.send(md);\n } else {\n res.json({\n detected: result.detections.length > 0,\n count: result.detections.length,\n detections: result.detections,\n redacted: result.redacted,\n stats: result.stats\n });\n }\n };\n}\n","/**\n * React hooks for PII detection\n * Local-first client-side PII detection in React applications\n *\n * NOTE: These are TypeScript hook definitions.\n * React is a peer dependency - users must install React separately.\n */\n\nimport { OpenRedaction } from '../detector';\nimport type { DetectionResult, OpenRedactionOptions } from '../types';\nimport { useState, useEffect, useMemo, useCallback } from 'react';\n\n/**\n * Hook for PII detection in React components\n *\n * @example\n * ```tsx\n * function MyForm() {\n * const { detect, result, isDetecting } = useOpenRedaction();\n *\n * const handleSubmit = (text: string) => {\n * const detection = detect(text);\n * if (detection.detections.length > 0) {\n * alert('PII detected!');\n * }\n * };\n * }\n * ```\n */\nexport function useOpenRedaction(options?: OpenRedactionOptions) {\n const detector = useMemo(() => new OpenRedaction(options), [options]);\n const [result, setResult] = useState<DetectionResult | null>(null);\n const [isDetecting, setIsDetecting] = useState(false);\n\n const detect = useCallback((text: string): DetectionResult => {\n setIsDetecting(true);\n const detection = detector.detect(text);\n setResult(detection);\n setIsDetecting(false);\n return detection;\n }, [detector]);\n\n const clear = useCallback(() => {\n setResult(null);\n }, []);\n\n return {\n detect,\n result,\n isDetecting,\n hasPII: result ? result.detections.length > 0 : false,\n count: result ? result.detections.length : 0,\n clear,\n detector\n };\n}\n\n/**\n * Hook for real-time PII detection with debouncing\n *\n * @example\n * ```tsx\n * function EmailInput() {\n * const [email, setEmail] = useState('');\n * const { result, hasPII } = usePIIDetector(email, { debounce: 500 });\n *\n * return (\n * <div>\n * <input value={email} onChange={e => setEmail(e.target.value)} />\n * {hasPII && <Warning>PII detected!</Warning>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePIIDetector(\n text: string,\n options?: OpenRedactionOptions & { debounce?: number }\n) {\n const { debounce = 300, ...redactOptions } = options || {};\n const detector = useMemo(() => new OpenRedaction(redactOptions), [redactOptions]);\n const [result, setResult] = useState<DetectionResult | null>(null);\n const [isDetecting, setIsDetecting] = useState(false);\n\n useEffect(() => {\n if (!text) {\n setResult(null);\n return;\n }\n\n setIsDetecting(true);\n const timer = setTimeout(() => {\n const detection = detector.detect(text);\n setResult(detection);\n setIsDetecting(false);\n }, debounce);\n\n return () => {\n clearTimeout(timer);\n setIsDetecting(false);\n };\n }, [text, detector, debounce]);\n\n return {\n result,\n isDetecting,\n hasPII: result ? result.detections.length > 0 : false,\n count: result ? result.detections.length : 0,\n detections: result?.detections || []\n };\n}\n\n/**\n * Hook for form field PII validation\n *\n * @example\n * ```tsx\n * function UserForm() {\n * const emailValidation = useFormFieldValidator({\n * failOnPII: true,\n * types: ['EMAIL', 'PHONE']\n * });\n *\n * return (\n * <input\n * {...emailValidation.getFieldProps()}\n * onChange={e => emailValidation.validate(e.target.value)}\n * />\n * );\n * }\n * ```\n */\nexport function useFormFieldValidator(options?: OpenRedactionOptions & {\n failOnPII?: boolean;\n types?: string[];\n onPIIDetected?: (result: DetectionResult) => void;\n}) {\n const { failOnPII = false, types = [], onPIIDetected, ...redactOptions } = options || {};\n const detector = useMemo(() => new OpenRedaction(redactOptions), [redactOptions]);\n const [value, setValue] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<DetectionResult | null>(null);\n\n const validate = useCallback((inputValue: string) => {\n setValue(inputValue);\n\n if (!inputValue) {\n setError(null);\n setResult(null);\n return true;\n }\n\n const detection = detector.detect(inputValue);\n setResult(detection);\n\n // Filter by types if specified\n const relevantDetections = types.length > 0\n ? detection.detections.filter((d) => types.includes(d.type))\n : detection.detections;\n\n if (relevantDetections.length > 0) {\n if (failOnPII) {\n setError(`Sensitive information detected: ${relevantDetections[0].type}`);\n }\n\n if (onPIIDetected) {\n onPIIDetected(detection);\n }\n\n return false;\n }\n\n setError(null);\n return true;\n }, [detector, failOnPII, types, onPIIDetected]);\n\n const getFieldProps = useCallback(() => ({\n value,\n 'aria-invalid': error ? 'true' : 'false',\n 'aria-describedby': error ? 'pii-error' : undefined\n }), [value, error]);\n\n return {\n value,\n error,\n result,\n validate,\n getFieldProps,\n isValid: !error,\n hasPII: result ? result.detections.length > 0 : false\n };\n}\n\n/**\n * Hook for batch PII detection\n *\n * @example\n * ```tsx\n * function BatchProcessor() {\n * const { processAll, results, isProcessing } = useBatchDetector();\n *\n * const handleProcess = async () => {\n * const documents = ['text1', 'text2', 'text3'];\n * await processAll(documents);\n * };\n * }\n * ```\n */\nexport function useBatchDetector(options?: OpenRedactionOptions) {\n const detector = useMemo(() => new OpenRedaction(options), [options]);\n const [results, setResults] = useState<DetectionResult[]>([]);\n const [isProcessing, setIsProcessing] = useState(false);\n const [progress, setProgress] = useState(0);\n\n const processAll = useCallback(async (texts: string[]) => {\n setIsProcessing(true);\n setProgress(0);\n const detections: DetectionResult[] = [];\n\n for (let i = 0; i < texts.length; i++) {\n const result = detector.detect(texts[i]);\n detections.push(result);\n setProgress(((i + 1) / texts.length) * 100);\n\n // Allow UI to update\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n\n setResults(detections);\n setIsProcessing(false);\n setProgress(100);\n\n return detections;\n }, [detector]);\n\n const clear = useCallback(() => {\n setResults([]);\n setProgress(0);\n }, []);\n\n const totalDetections = useMemo(\n () => results.reduce((sum: number, r: DetectionResult) => sum + r.detections.length, 0),\n [results]\n );\n\n return {\n processAll,\n results,\n isProcessing,\n progress,\n totalDetections,\n clear\n };\n}\n\n/**\n * Hook for PII detection with auto-redaction\n *\n * @example\n * ```tsx\n * function SecureTextArea() {\n * const { text, setText, redactedText, hasPII } = useAutoRedact();\n *\n * return (\n * <div>\n * <textarea value={text} onChange={e => setText(e.target.value)} />\n * {hasPII && <div>Redacted: {redactedText}</div>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useAutoRedact(options?: OpenRedactionOptions & { debounce?: number }) {\n const { debounce = 300, ...redactOptions } = options || {};\n const detector = useMemo(() => new OpenRedaction(redactOptions), [redactOptions]);\n const [text, setText] = useState('');\n const [result, setResult] = useState<DetectionResult | null>(null);\n\n useEffect(() => {\n if (!text) {\n setResult(null);\n return;\n }\n\n const timer = setTimeout(() => {\n const detection = detector.detect(text);\n setResult(detection);\n }, debounce);\n\n return () => clearTimeout(timer);\n }, [text, detector, debounce]);\n\n return {\n text,\n setText,\n result,\n redactedText: result?.redacted || text,\n hasPII: result ? result.detections.length > 0 : false,\n detections: result?.detections || [],\n count: result ? result.detections.length : 0\n };\n}\n","/**\n * Multi-tenancy support for SaaS deployments\n * Provides tenant isolation, quotas, and per-tenant configuration\n */\n\nimport type {\n OpenRedactionOptions,\n PIIPattern,\n IAuditLogger,\n IMetricsCollector\n} from '../types';\nimport { OpenRedaction } from '../detector';\n\n/**\n * Tenant configuration\n */\nexport interface TenantConfig {\n /** Tenant unique identifier */\n tenantId: string;\n /** Tenant display name */\n name: string;\n /** Tenant-specific OpenRedaction options */\n options?: OpenRedactionOptions;\n /** Tenant-specific custom patterns */\n customPatterns?: PIIPattern[];\n /** Tenant-specific whitelist */\n whitelist?: string[];\n /** Tenant quota limits */\n quotas?: TenantQuotas;\n /** Tenant API key (for authentication) */\n apiKey?: string;\n /** Tenant metadata */\n metadata?: Record<string, unknown>;\n /** Tenant status */\n status: 'active' | 'suspended' | 'trial';\n /** Trial expiry date (for trial tenants) */\n trialExpiresAt?: Date;\n /** Created timestamp */\n createdAt: Date;\n /** Last updated timestamp */\n updatedAt: Date;\n}\n\n/**\n * Tenant quota limits\n */\nexport interface TenantQuotas {\n /** Maximum requests per month (undefined = unlimited) */\n maxRequestsPerMonth?: number;\n /** Maximum text length per request (characters) */\n maxTextLength?: number;\n /** Maximum patterns allowed */\n maxPatterns?: number;\n /** Maximum audit logs to retain */\n maxAuditLogs?: number;\n /** Rate limit: requests per minute */\n rateLimit?: number;\n}\n\n/**\n * Tenant usage statistics\n */\nexport interface TenantUsage {\n /** Tenant ID */\n tenantId: string;\n /** Total requests this month */\n requestsThisMonth: number;\n /** Total text processed this month (characters) */\n textProcessedThisMonth: number;\n /** Total PII detected this month */\n piiDetectedThisMonth: number;\n /** Last request timestamp */\n lastRequestAt?: Date;\n /** Monthly usage reset date */\n monthlyResetDate: Date;\n}\n\n/**\n * Tenant quota exceeded error\n */\nexport class TenantQuotaExceededError extends Error {\n constructor(\n public tenantId: string,\n public quota: string,\n public limit: number,\n public current: number\n ) {\n super(`Tenant ${tenantId} exceeded ${quota} quota: ${current}/${limit}`);\n this.name = 'TenantQuotaExceededError';\n }\n}\n\n/**\n * Tenant not found error\n */\nexport class TenantNotFoundError extends Error {\n constructor(public tenantId: string) {\n super(`Tenant not found: ${tenantId}`);\n this.name = 'TenantNotFoundError';\n }\n}\n\n/**\n * Tenant suspended error\n */\nexport class TenantSuspendedError extends Error {\n constructor(public tenantId: string) {\n super(`Tenant is suspended: ${tenantId}`);\n this.name = 'TenantSuspendedError';\n }\n}\n\n/**\n * Multi-tenant manager for SaaS deployments\n */\nexport class TenantManager {\n private tenants: Map<string, TenantConfig> = new Map();\n private usage: Map<string, TenantUsage> = new Map();\n private detectors: Map<string, OpenRedaction> = new Map();\n private rateLimitTracking: Map<string, number[]> = new Map();\n private auditLoggers: Map<string, IAuditLogger> = new Map();\n private metricsCollectors: Map<string, IMetricsCollector> = new Map();\n\n /**\n * Register a new tenant\n */\n registerTenant(config: Omit<TenantConfig, 'createdAt' | 'updatedAt'>): TenantConfig {\n if (this.tenants.has(config.tenantId)) {\n throw new Error(`Tenant already exists: ${config.tenantId}`);\n }\n\n const fullConfig: TenantConfig = {\n ...config,\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n this.tenants.set(config.tenantId, fullConfig);\n\n // Initialize usage tracking\n this.usage.set(config.tenantId, {\n tenantId: config.tenantId,\n requestsThisMonth: 0,\n textProcessedThisMonth: 0,\n piiDetectedThisMonth: 0,\n monthlyResetDate: this.getNextMonthlyResetDate()\n });\n\n // Initialize rate limit tracking\n this.rateLimitTracking.set(config.tenantId, []);\n\n return fullConfig;\n }\n\n /**\n * Update tenant configuration\n */\n updateTenant(tenantId: string, updates: Partial<Omit<TenantConfig, 'tenantId' | 'createdAt'>>): TenantConfig {\n const config = this.getTenantConfig(tenantId);\n\n const updated: TenantConfig = {\n ...config,\n ...updates,\n updatedAt: new Date()\n };\n\n this.tenants.set(tenantId, updated);\n\n // Clear cached detector to force recreation with new config\n this.detectors.delete(tenantId);\n\n return updated;\n }\n\n /**\n * Get tenant configuration\n */\n getTenantConfig(tenantId: string): TenantConfig {\n const config = this.tenants.get(tenantId);\n if (!config) {\n throw new TenantNotFoundError(tenantId);\n }\n return config;\n }\n\n /**\n * Get or create tenant-specific detector instance\n */\n getDetector(tenantId: string): OpenRedaction {\n this.validateTenantStatus(tenantId);\n\n // Return cached detector if exists\n if (this.detectors.has(tenantId)) {\n return this.detectors.get(tenantId)!;\n }\n\n // Create new detector with tenant config\n const config = this.getTenantConfig(tenantId);\n const options: OpenRedactionOptions = {\n ...config.options,\n customPatterns: config.customPatterns,\n whitelist: config.whitelist,\n auditLogger: this.getAuditLogger(tenantId),\n metricsCollector: this.getMetricsCollector(tenantId),\n auditUser: config.tenantId,\n auditMetadata: {\n tenantId: config.tenantId,\n tenantName: config.name\n }\n };\n\n const detector = new OpenRedaction(options);\n this.detectors.set(tenantId, detector);\n\n return detector;\n }\n\n /**\n * Perform detection with tenant isolation and quota checks\n */\n async detect(tenantId: string, text: string): Promise<any> {\n // Validate tenant status\n this.validateTenantStatus(tenantId);\n\n // Check quotas\n await this.checkQuotas(tenantId, text);\n\n // Track usage\n this.trackRequest(tenantId, text);\n\n // Get tenant detector and perform detection\n const detector = this.getDetector(tenantId);\n const result = detector.detect(text);\n\n // Update usage stats\n const usage = this.usage.get(tenantId)!;\n usage.piiDetectedThisMonth += result.detections.length;\n usage.lastRequestAt = new Date();\n\n return result;\n }\n\n /**\n * Validate tenant status (active, trial expiry)\n */\n private validateTenantStatus(tenantId: string): void {\n const config = this.getTenantConfig(tenantId);\n\n // Check if suspended\n if (config.status === 'suspended') {\n throw new TenantSuspendedError(tenantId);\n }\n\n // Check trial expiry\n if (config.status === 'trial' && config.trialExpiresAt) {\n if (new Date() > config.trialExpiresAt) {\n throw new TenantSuspendedError(tenantId);\n }\n }\n }\n\n /**\n * Check tenant quotas before processing\n */\n private async checkQuotas(tenantId: string, text: string): Promise<void> {\n const config = this.getTenantConfig(tenantId);\n const usage = this.usage.get(tenantId)!;\n\n // Check if monthly reset is needed\n if (new Date() > usage.monthlyResetDate) {\n this.resetMonthlyUsage(tenantId);\n }\n\n const quotas = config.quotas;\n if (!quotas) {\n return; // No quotas configured\n }\n\n // Check monthly request limit\n if (quotas.maxRequestsPerMonth !== undefined) {\n if (usage.requestsThisMonth >= quotas.maxRequestsPerMonth) {\n throw new TenantQuotaExceededError(\n tenantId,\n 'maxRequestsPerMonth',\n quotas.maxRequestsPerMonth,\n usage.requestsThisMonth\n );\n }\n }\n\n // Check text length limit\n if (quotas.maxTextLength !== undefined) {\n if (text.length > quotas.maxTextLength) {\n throw new TenantQuotaExceededError(\n tenantId,\n 'maxTextLength',\n quotas.maxTextLength,\n text.length\n );\n }\n }\n\n // Check rate limit\n if (quotas.rateLimit !== undefined) {\n const requestsInLastMinute = this.getRequestsInLastMinute(tenantId);\n if (requestsInLastMinute >= quotas.rateLimit) {\n throw new TenantQuotaExceededError(\n tenantId,\n 'rateLimit',\n quotas.rateLimit,\n requestsInLastMinute\n );\n }\n }\n\n // Check pattern count limit\n if (quotas.maxPatterns !== undefined) {\n const patternCount = config.customPatterns?.length || 0;\n if (patternCount > quotas.maxPatterns) {\n throw new TenantQuotaExceededError(\n tenantId,\n 'maxPatterns',\n quotas.maxPatterns,\n patternCount\n );\n }\n }\n }\n\n /**\n * Track request for usage and rate limiting\n */\n private trackRequest(tenantId: string, text: string): void {\n const usage = this.usage.get(tenantId)!;\n\n // Update monthly usage\n usage.requestsThisMonth++;\n usage.textProcessedThisMonth += text.length;\n\n // Track for rate limiting (store timestamp)\n const timestamps = this.rateLimitTracking.get(tenantId) || [];\n timestamps.push(Date.now());\n\n // Keep only last 60 seconds of timestamps\n const oneMinuteAgo = Date.now() - 60 * 1000;\n const recentTimestamps = timestamps.filter(ts => ts > oneMinuteAgo);\n this.rateLimitTracking.set(tenantId, recentTimestamps);\n }\n\n /**\n * Get number of requests in last minute\n */\n private getRequestsInLastMinute(tenantId: string): number {\n const timestamps = this.rateLimitTracking.get(tenantId) || [];\n const oneMinuteAgo = Date.now() - 60 * 1000;\n return timestamps.filter(ts => ts > oneMinuteAgo).length;\n }\n\n /**\n * Reset monthly usage statistics\n */\n private resetMonthlyUsage(tenantId: string): void {\n const usage = this.usage.get(tenantId);\n if (!usage) {\n return;\n }\n\n usage.requestsThisMonth = 0;\n usage.textProcessedThisMonth = 0;\n usage.piiDetectedThisMonth = 0;\n usage.monthlyResetDate = this.getNextMonthlyResetDate();\n }\n\n /**\n * Get next monthly reset date (1st of next month)\n */\n private getNextMonthlyResetDate(): Date {\n const now = new Date();\n const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n return nextMonth;\n }\n\n /**\n * Get tenant usage statistics\n */\n getTenantUsage(tenantId: string): TenantUsage {\n this.validateTenantExists(tenantId);\n\n const usage = this.usage.get(tenantId);\n if (!usage) {\n throw new Error(`Usage data not found for tenant: ${tenantId}`);\n }\n\n return { ...usage };\n }\n\n /**\n * Get all tenants\n */\n getAllTenants(): TenantConfig[] {\n return Array.from(this.tenants.values());\n }\n\n /**\n * Get tenants by status\n */\n getTenantsByStatus(status: TenantConfig['status']): TenantConfig[] {\n return Array.from(this.tenants.values()).filter(t => t.status === status);\n }\n\n /**\n * Authenticate tenant by API key\n */\n authenticateByApiKey(apiKey: string): TenantConfig | null {\n for (const config of this.tenants.values()) {\n if (config.apiKey === apiKey) {\n return config;\n }\n }\n return null;\n }\n\n /**\n * Suspend a tenant\n */\n suspendTenant(tenantId: string): void {\n this.updateTenant(tenantId, { status: 'suspended' });\n }\n\n /**\n * Activate a tenant\n */\n activateTenant(tenantId: string): void {\n this.updateTenant(tenantId, { status: 'active' });\n }\n\n /**\n * Delete a tenant and all associated data\n */\n deleteTenant(tenantId: string): void {\n this.validateTenantExists(tenantId);\n\n this.tenants.delete(tenantId);\n this.usage.delete(tenantId);\n this.detectors.delete(tenantId);\n this.rateLimitTracking.delete(tenantId);\n this.auditLoggers.delete(tenantId);\n this.metricsCollectors.delete(tenantId);\n }\n\n /**\n * Set tenant-specific audit logger\n */\n setAuditLogger(tenantId: string, logger: IAuditLogger): void {\n this.validateTenantExists(tenantId);\n this.auditLoggers.set(tenantId, logger);\n }\n\n /**\n * Get tenant-specific audit logger\n */\n getAuditLogger(tenantId: string): IAuditLogger | undefined {\n return this.auditLoggers.get(tenantId);\n }\n\n /**\n * Set tenant-specific metrics collector\n */\n setMetricsCollector(tenantId: string, collector: IMetricsCollector): void {\n this.validateTenantExists(tenantId);\n this.metricsCollectors.set(tenantId, collector);\n }\n\n /**\n * Get tenant-specific metrics collector\n */\n getMetricsCollector(tenantId: string): IMetricsCollector | undefined {\n return this.metricsCollectors.get(tenantId);\n }\n\n /**\n * Get aggregate statistics across all tenants\n */\n getAggregateStats(): {\n totalTenants: number;\n activeTenants: number;\n trialTenants: number;\n suspendedTenants: number;\n totalRequestsThisMonth: number;\n totalTextProcessedThisMonth: number;\n totalPiiDetectedThisMonth: number;\n } {\n const tenants = Array.from(this.tenants.values());\n const usages = Array.from(this.usage.values());\n\n return {\n totalTenants: tenants.length,\n activeTenants: tenants.filter(t => t.status === 'active').length,\n trialTenants: tenants.filter(t => t.status === 'trial').length,\n suspendedTenants: tenants.filter(t => t.status === 'suspended').length,\n totalRequestsThisMonth: usages.reduce((sum, u) => sum + u.requestsThisMonth, 0),\n totalTextProcessedThisMonth: usages.reduce((sum, u) => sum + u.textProcessedThisMonth, 0),\n totalPiiDetectedThisMonth: usages.reduce((sum, u) => sum + u.piiDetectedThisMonth, 0)\n };\n }\n\n /**\n * Validate tenant exists\n */\n private validateTenantExists(tenantId: string): void {\n if (!this.tenants.has(tenantId)) {\n throw new TenantNotFoundError(tenantId);\n }\n }\n\n /**\n * Export tenant configuration as JSON\n */\n exportTenantConfig(tenantId: string): string {\n const config = this.getTenantConfig(tenantId);\n return JSON.stringify(config, null, 2);\n }\n\n /**\n * Import tenant configuration from JSON\n */\n importTenantConfig(json: string): TenantConfig {\n const config = JSON.parse(json) as TenantConfig;\n\n // Validate required fields\n if (!config.tenantId || !config.name || !config.status) {\n throw new Error('Invalid tenant configuration: missing required fields');\n }\n\n // Register or update tenant\n if (this.tenants.has(config.tenantId)) {\n return this.updateTenant(config.tenantId, config);\n } else {\n return this.registerTenant(config);\n }\n }\n}\n\n/**\n * Create a tenant manager instance\n */\nexport function createTenantManager(): TenantManager {\n return new TenantManager();\n}\n\n/**\n * Default tenant quotas for different tiers\n */\nexport const DEFAULT_TIER_QUOTAS = {\n free: {\n maxRequestsPerMonth: 1000,\n maxTextLength: 10000,\n maxPatterns: 10,\n maxAuditLogs: 100,\n rateLimit: 10 // per minute\n },\n starter: {\n maxRequestsPerMonth: 10000,\n maxTextLength: 50000,\n maxPatterns: 50,\n maxAuditLogs: 1000,\n rateLimit: 50\n },\n professional: {\n maxRequestsPerMonth: 100000,\n maxTextLength: 100000,\n maxPatterns: 200,\n maxAuditLogs: 10000,\n rateLimit: 200\n },\n enterprise: {\n // No limits for enterprise\n maxRequestsPerMonth: undefined,\n maxTextLength: undefined,\n maxPatterns: undefined,\n maxAuditLogs: undefined,\n rateLimit: undefined\n }\n} as const;\n","/**\n * Webhook and Alert System for event-driven notifications\n * Supports HTTP webhooks with retry logic, circuit breaker, and event filtering\n */\n\nimport type { DetectionResult } from '../types';\n\n/**\n * Webhook event types\n */\nexport type WebhookEventType =\n | 'pii.detected.high_risk' // High/critical severity PII detected\n | 'pii.detected.bulk' // Large number of PII items detected\n | 'pii.processing.failed' // Processing error occurred\n | 'pii.processing.slow' // Processing took longer than threshold\n | 'quota.exceeded' // Tenant quota exceeded\n | 'tenant.suspended' // Tenant suspended\n | 'audit.tamper_detected' // Audit log tampering detected\n | 'custom'; // Custom event\n\n/**\n * Webhook event payload\n */\nexport interface WebhookEvent {\n /** Event unique ID */\n id: string;\n /** Event type */\n type: WebhookEventType;\n /** Event timestamp (ISO 8601) */\n timestamp: string;\n /** Event severity */\n severity: 'critical' | 'high' | 'medium' | 'low' | 'info';\n /** Event data */\n data: Record<string, unknown>;\n /** Source identifier (e.g., tenant ID) */\n source?: string;\n /** Custom metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Webhook configuration\n */\nexport interface WebhookConfig {\n /** Webhook unique ID */\n id: string;\n /** Webhook URL to POST events to */\n url: string;\n /** Event types to subscribe to (empty = all events) */\n events?: WebhookEventType[];\n /** Minimum severity to trigger webhook */\n minSeverity?: 'critical' | 'high' | 'medium' | 'low' | 'info';\n /** Custom headers to include in requests */\n headers?: Record<string, string>;\n /** Secret for HMAC signature (optional but recommended) */\n secret?: string;\n /** Enable webhook (default: true) */\n enabled?: boolean;\n /** Retry configuration */\n retry?: {\n /** Maximum retry attempts (default: 3) */\n maxAttempts?: number;\n /** Initial delay in ms (default: 1000) */\n initialDelay?: number;\n /** Maximum delay in ms (default: 60000) */\n maxDelay?: number;\n /** Backoff multiplier (default: 2) */\n backoffMultiplier?: number;\n };\n /** Timeout in ms (default: 5000) */\n timeout?: number;\n /** Tenant ID (for multi-tenant setups) */\n tenantId?: string;\n}\n\n/**\n * Webhook delivery status\n */\nexport type WebhookDeliveryStatus = 'pending' | 'success' | 'failed' | 'circuit_open';\n\n/**\n * Webhook delivery record\n */\nexport interface WebhookDelivery {\n /** Delivery ID */\n id: string;\n /** Webhook ID */\n webhookId: string;\n /** Event that was delivered */\n event: WebhookEvent;\n /** Delivery status */\n status: WebhookDeliveryStatus;\n /** HTTP status code */\n statusCode?: number;\n /** Delivery timestamp */\n timestamp: Date;\n /** Attempt number */\n attempt: number;\n /** Error message if failed */\n error?: string;\n /** Response body */\n responseBody?: string;\n /** Delivery duration in ms */\n durationMs?: number;\n}\n\n/**\n * Circuit breaker state\n */\ninterface CircuitBreakerState {\n /** Current state */\n state: 'closed' | 'open' | 'half_open';\n /** Failure count */\n failureCount: number;\n /** Last failure time */\n lastFailureTime?: Date;\n /** Next retry time (when state is open) */\n nextRetryTime?: Date;\n}\n\n/**\n * Webhook statistics\n */\nexport interface WebhookStats {\n /** Webhook ID */\n webhookId: string;\n /** Total deliveries */\n totalDeliveries: number;\n /** Successful deliveries */\n successfulDeliveries: number;\n /** Failed deliveries */\n failedDeliveries: number;\n /** Average delivery time in ms */\n avgDeliveryTimeMs: number;\n /** Last delivery time */\n lastDeliveryTime?: Date;\n /** Circuit breaker state */\n circuitState: 'closed' | 'open' | 'half_open';\n}\n\n/**\n * Webhook Manager\n * Manages webhook subscriptions, delivery, retries, and circuit breaking\n */\nexport class WebhookManager {\n private webhooks: Map<string, WebhookConfig> = new Map();\n private deliveryHistory: WebhookDelivery[] = [];\n private circuitBreakers: Map<string, CircuitBreakerState> = new Map();\n private pendingRetries: Map<string, NodeJS.Timeout> = new Map();\n private maxHistorySize: number;\n\n // Circuit breaker configuration\n private readonly FAILURE_THRESHOLD = 5;\n private readonly RESET_TIMEOUT_MS = 60000; // 1 minute\n\n constructor(options?: { maxHistorySize?: number }) {\n this.maxHistorySize = options?.maxHistorySize ?? 1000;\n }\n\n /**\n * Register a webhook\n */\n registerWebhook(config: WebhookConfig): void {\n if (this.webhooks.has(config.id)) {\n throw new Error(`Webhook already registered: ${config.id}`);\n }\n\n // Validate URL\n try {\n new URL(config.url);\n } catch {\n throw new Error(`Invalid webhook URL: ${config.url}`);\n }\n\n this.webhooks.set(config.id, {\n ...config,\n enabled: config.enabled ?? true,\n retry: {\n maxAttempts: config.retry?.maxAttempts ?? 3,\n initialDelay: config.retry?.initialDelay ?? 1000,\n maxDelay: config.retry?.maxDelay ?? 60000,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2\n },\n timeout: config.timeout ?? 5000\n });\n\n // Initialize circuit breaker\n this.circuitBreakers.set(config.id, {\n state: 'closed',\n failureCount: 0\n });\n }\n\n /**\n * Update webhook configuration\n */\n updateWebhook(id: string, updates: Partial<Omit<WebhookConfig, 'id'>>): void {\n const webhook = this.webhooks.get(id);\n if (!webhook) {\n throw new Error(`Webhook not found: ${id}`);\n }\n\n this.webhooks.set(id, {\n ...webhook,\n ...updates\n });\n }\n\n /**\n * Delete webhook\n */\n deleteWebhook(id: string): void {\n this.webhooks.delete(id);\n this.circuitBreakers.delete(id);\n\n // Cancel any pending retries\n const retry = this.pendingRetries.get(id);\n if (retry) {\n clearTimeout(retry);\n this.pendingRetries.delete(id);\n }\n }\n\n /**\n * Get webhook configuration\n */\n getWebhook(id: string): WebhookConfig | undefined {\n return this.webhooks.get(id);\n }\n\n /**\n * Get all webhooks\n */\n getAllWebhooks(): WebhookConfig[] {\n return Array.from(this.webhooks.values());\n }\n\n /**\n * Emit an event to all subscribed webhooks\n */\n async emitEvent(event: Omit<WebhookEvent, 'id' | 'timestamp'>): Promise<void> {\n const fullEvent: WebhookEvent = {\n id: this.generateId(),\n timestamp: new Date().toISOString(),\n ...event\n };\n\n // Find matching webhooks\n const matchingWebhooks = this.findMatchingWebhooks(fullEvent);\n\n // Deliver to all matching webhooks (parallel)\n await Promise.all(\n matchingWebhooks.map(webhook => this.deliverWebhook(webhook, fullEvent, 1))\n );\n }\n\n /**\n * Emit high-risk PII detection event\n */\n async emitHighRiskPII(result: DetectionResult, tenantId?: string): Promise<void> {\n const highRiskDetections = result.detections.filter(\n d => d.severity === 'critical' || d.severity === 'high'\n );\n\n if (highRiskDetections.length === 0) {\n return;\n }\n\n await this.emitEvent({\n type: 'pii.detected.high_risk',\n severity: 'high',\n data: {\n detectionCount: highRiskDetections.length,\n types: [...new Set(highRiskDetections.map(d => d.type))],\n severities: [...new Set(highRiskDetections.map(d => d.severity))],\n textLength: result.original.length\n },\n source: tenantId\n });\n }\n\n /**\n * Emit bulk PII detection event\n */\n async emitBulkPII(result: DetectionResult, threshold: number = 10, tenantId?: string): Promise<void> {\n if (result.detections.length < threshold) {\n return;\n }\n\n await this.emitEvent({\n type: 'pii.detected.bulk',\n severity: 'medium',\n data: {\n detectionCount: result.detections.length,\n types: [...new Set(result.detections.map(d => d.type))],\n textLength: result.original.length\n },\n source: tenantId\n });\n }\n\n /**\n * Emit processing error event\n */\n async emitProcessingError(error: Error, tenantId?: string): Promise<void> {\n await this.emitEvent({\n type: 'pii.processing.failed',\n severity: 'high',\n data: {\n error: error.message,\n stack: error.stack\n },\n source: tenantId\n });\n }\n\n /**\n * Emit slow processing event\n */\n async emitSlowProcessing(durationMs: number, threshold: number = 5000, tenantId?: string): Promise<void> {\n if (durationMs < threshold) {\n return;\n }\n\n await this.emitEvent({\n type: 'pii.processing.slow',\n severity: 'low',\n data: {\n durationMs,\n thresholdMs: threshold\n },\n source: tenantId\n });\n }\n\n /**\n * Find webhooks that match the event\n */\n private findMatchingWebhooks(event: WebhookEvent): WebhookConfig[] {\n return Array.from(this.webhooks.values()).filter(webhook => {\n // Check if enabled\n if (!webhook.enabled) {\n return false;\n }\n\n // Check tenant filtering\n if (webhook.tenantId && event.source !== webhook.tenantId) {\n return false;\n }\n\n // Check event type filtering\n if (webhook.events && webhook.events.length > 0) {\n if (!webhook.events.includes(event.type)) {\n return false;\n }\n }\n\n // Check severity filtering\n if (webhook.minSeverity) {\n const severityOrder = ['info', 'low', 'medium', 'high', 'critical'];\n const eventSeverityIndex = severityOrder.indexOf(event.severity);\n const minSeverityIndex = severityOrder.indexOf(webhook.minSeverity);\n\n if (eventSeverityIndex < minSeverityIndex) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * Deliver webhook with retry logic\n */\n private async deliverWebhook(\n webhook: WebhookConfig,\n event: WebhookEvent,\n attempt: number\n ): Promise<void> {\n // Check circuit breaker\n const circuitState = this.circuitBreakers.get(webhook.id);\n if (!circuitState) {\n return;\n }\n\n if (circuitState.state === 'open') {\n // Check if we should move to half-open\n if (circuitState.nextRetryTime && new Date() >= circuitState.nextRetryTime) {\n circuitState.state = 'half_open';\n circuitState.failureCount = 0;\n } else {\n // Circuit is open, skip delivery\n this.recordDelivery({\n id: this.generateId(),\n webhookId: webhook.id,\n event,\n status: 'circuit_open',\n timestamp: new Date(),\n attempt,\n error: 'Circuit breaker is open'\n });\n return;\n }\n }\n\n const startTime = Date.now();\n const deliveryId = this.generateId();\n\n try {\n // Make HTTP request\n const response = await this.makeHttpRequest(webhook, event);\n\n const durationMs = Date.now() - startTime;\n\n // Record successful delivery\n this.recordDelivery({\n id: deliveryId,\n webhookId: webhook.id,\n event,\n status: 'success',\n statusCode: response.statusCode,\n timestamp: new Date(),\n attempt,\n responseBody: response.body,\n durationMs\n });\n\n // Reset circuit breaker on success\n if (circuitState.state === 'half_open') {\n circuitState.state = 'closed';\n circuitState.failureCount = 0;\n }\n } catch (error: any) {\n const durationMs = Date.now() - startTime;\n\n // Record failed delivery\n this.recordDelivery({\n id: deliveryId,\n webhookId: webhook.id,\n event,\n status: 'failed',\n statusCode: error.statusCode,\n timestamp: new Date(),\n attempt,\n error: error.message,\n durationMs\n });\n\n // Update circuit breaker\n circuitState.failureCount++;\n circuitState.lastFailureTime = new Date();\n\n if (circuitState.failureCount >= this.FAILURE_THRESHOLD) {\n circuitState.state = 'open';\n circuitState.nextRetryTime = new Date(Date.now() + this.RESET_TIMEOUT_MS);\n console.warn(`[WebhookManager] Circuit breaker opened for webhook ${webhook.id}`);\n }\n\n // Retry if attempts remaining\n const maxAttempts = webhook.retry!.maxAttempts!;\n if (attempt < maxAttempts) {\n const delay = this.calculateRetryDelay(attempt, webhook.retry!);\n console.log(`[WebhookManager] Retrying webhook ${webhook.id} in ${delay}ms (attempt ${attempt + 1}/${maxAttempts})`);\n\n const timeout = setTimeout(() => {\n this.deliverWebhook(webhook, event, attempt + 1).catch(err => {\n console.error(`[WebhookManager] Retry failed for webhook ${webhook.id}:`, err);\n });\n this.pendingRetries.delete(webhook.id);\n }, delay);\n\n this.pendingRetries.set(webhook.id, timeout);\n }\n }\n }\n\n /**\n * Make HTTP request to webhook URL\n */\n private async makeHttpRequest(\n webhook: WebhookConfig,\n event: WebhookEvent\n ): Promise<{ statusCode: number; body: string }> {\n try {\n // Try to use fetch (Node 18+) or https module\n let fetch: any;\n try {\n fetch = globalThis.fetch;\n } catch {\n // Fetch not available, use https module (implementation stub)\n throw new Error('[WebhookManager] HTTP client not available. Requires Node 18+ with fetch support.');\n }\n\n // Calculate HMAC signature if secret provided\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': 'OpenRedaction-Webhook/1.0',\n ...webhook.headers\n };\n\n if (webhook.secret) {\n const signature = this.calculateHmacSignature(event, webhook.secret);\n headers['X-Webhook-Signature'] = signature;\n headers['X-Webhook-Signature-Algorithm'] = 'sha256';\n }\n\n // Add event metadata headers\n headers['X-Event-Id'] = event.id;\n headers['X-Event-Type'] = event.type;\n headers['X-Event-Timestamp'] = event.timestamp;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), webhook.timeout);\n\n try {\n const response = await fetch(webhook.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(event),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n const body = await response.text();\n\n if (!response.ok) {\n throw Object.assign(new Error(`HTTP ${response.status}: ${response.statusText}`), {\n statusCode: response.status\n });\n }\n\n return {\n statusCode: response.status,\n body\n };\n } catch (error: any) {\n clearTimeout(timeoutId);\n throw error;\n }\n } catch (error: any) {\n throw Object.assign(new Error(`Webhook delivery failed: ${error.message}`), {\n statusCode: error.statusCode || 0\n });\n }\n }\n\n /**\n * Calculate HMAC signature for webhook verification\n */\n private calculateHmacSignature(event: WebhookEvent, secret: string): string {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const payload = JSON.stringify(event);\n return crypto\n .createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n } catch {\n throw new Error('[WebhookManager] Crypto module not available for HMAC signatures');\n }\n }\n\n /**\n * Calculate retry delay with exponential backoff\n */\n private calculateRetryDelay(attempt: number, retryConfig: NonNullable<WebhookConfig['retry']>): number {\n const { initialDelay, maxDelay, backoffMultiplier } = retryConfig;\n const delay = initialDelay! * Math.pow(backoffMultiplier!, attempt - 1);\n return Math.min(delay, maxDelay!);\n }\n\n /**\n * Record delivery in history\n */\n private recordDelivery(delivery: WebhookDelivery): void {\n this.deliveryHistory.push(delivery);\n\n // Trim history if too large\n if (this.deliveryHistory.length > this.maxHistorySize) {\n this.deliveryHistory.shift();\n }\n }\n\n /**\n * Get delivery history for a webhook\n */\n getDeliveryHistory(webhookId: string, limit?: number): WebhookDelivery[] {\n const history = this.deliveryHistory.filter(d => d.webhookId === webhookId);\n\n if (limit) {\n return history.slice(-limit);\n }\n\n return history;\n }\n\n /**\n * Get webhook statistics\n */\n getWebhookStats(webhookId: string): WebhookStats {\n const deliveries = this.deliveryHistory.filter(d => d.webhookId === webhookId);\n const successful = deliveries.filter(d => d.status === 'success');\n const failed = deliveries.filter(d => d.status === 'failed');\n\n const avgDeliveryTime = deliveries.length > 0\n ? deliveries.reduce((sum, d) => sum + (d.durationMs || 0), 0) / deliveries.length\n : 0;\n\n const lastDelivery = deliveries.length > 0\n ? deliveries[deliveries.length - 1].timestamp\n : undefined;\n\n const circuit = this.circuitBreakers.get(webhookId);\n\n return {\n webhookId,\n totalDeliveries: deliveries.length,\n successfulDeliveries: successful.length,\n failedDeliveries: failed.length,\n avgDeliveryTimeMs: avgDeliveryTime,\n lastDeliveryTime: lastDelivery,\n circuitState: circuit?.state || 'closed'\n };\n }\n\n /**\n * Get aggregate statistics for all webhooks\n */\n getAggregateStats(): {\n totalWebhooks: number;\n enabledWebhooks: number;\n totalDeliveries: number;\n successfulDeliveries: number;\n failedDeliveries: number;\n avgDeliveryTimeMs: number;\n } {\n const webhooks = Array.from(this.webhooks.values());\n const successful = this.deliveryHistory.filter(d => d.status === 'success');\n const failed = this.deliveryHistory.filter(d => d.status === 'failed');\n\n const avgDeliveryTime = this.deliveryHistory.length > 0\n ? this.deliveryHistory.reduce((sum, d) => sum + (d.durationMs || 0), 0) / this.deliveryHistory.length\n : 0;\n\n return {\n totalWebhooks: webhooks.length,\n enabledWebhooks: webhooks.filter(w => w.enabled).length,\n totalDeliveries: this.deliveryHistory.length,\n successfulDeliveries: successful.length,\n failedDeliveries: failed.length,\n avgDeliveryTimeMs: avgDeliveryTime\n };\n }\n\n /**\n * Clear delivery history\n */\n clearHistory(): void {\n this.deliveryHistory = [];\n }\n\n /**\n * Generate unique ID\n */\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Create a webhook manager instance\n */\nexport function createWebhookManager(options?: { maxHistorySize?: number }): WebhookManager {\n return new WebhookManager(options);\n}\n\n/**\n * Verify webhook HMAC signature\n */\nexport function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string,\n algorithm: 'sha256' | 'sha512' = 'sha256'\n): boolean {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const crypto = require('crypto');\n const expectedSignature = crypto\n .createHmac(algorithm, secret)\n .update(payload)\n .digest('hex');\n\n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n );\n } catch {\n return false;\n }\n}\n","/**\n * REST API Server for OpenRedaction\n * Provides HTTP/REST endpoints for PII detection and redaction\n */\n\nimport type { OpenRedactionOptions, DetectionResult } from '../types';\nimport { OpenRedaction } from '../detector';\nimport type { TenantManager } from '../tenancy/TenantManager';\nimport type { WebhookManager } from '../webhooks/WebhookManager';\nimport type { PersistentAuditLogger } from '../audit/PersistentAuditLogger';\nimport type { PrometheusServer } from '../metrics/PrometheusServer';\n\n/**\n * API Server configuration\n */\nexport interface APIServerConfig {\n /** Server port (default: 3000) */\n port?: number;\n /** Server host (default: '0.0.0.0') */\n host?: string;\n /** Enable CORS (default: true) */\n enableCors?: boolean;\n /** CORS origin (default: '*') */\n corsOrigin?: string | string[];\n /** API key for authentication (optional) */\n apiKey?: string;\n /** Enable rate limiting (default: true) */\n enableRateLimit?: boolean;\n /** Rate limit: requests per minute (default: 60) */\n rateLimit?: number;\n /** Request body size limit (default: '10mb') */\n bodyLimit?: string;\n /** Enable request logging (default: true) */\n enableLogging?: boolean;\n /** Tenant manager (for multi-tenant mode) */\n tenantManager?: TenantManager;\n /** Webhook manager */\n webhookManager?: WebhookManager;\n /** Persistent audit logger */\n auditLogger?: PersistentAuditLogger;\n /** Prometheus server */\n prometheusServer?: PrometheusServer;\n /** Default OpenRedaction options (for non-tenant mode) */\n defaultOptions?: OpenRedactionOptions;\n}\n\n/**\n * API request with authentication\n */\nexport interface APIRequest {\n /** Request body */\n body: any;\n /** Headers */\n headers: Record<string, string | string[] | undefined>;\n /** Query parameters */\n query: Record<string, string | string[] | undefined>;\n /** Path parameters */\n params: Record<string, string>;\n /** Authenticated tenant ID (if multi-tenant) */\n tenantId?: string;\n /** Client IP address */\n ip?: string;\n}\n\n/**\n * API response\n */\nexport interface APIResponse {\n /** Status code */\n status: number;\n /** Response body */\n body: any;\n /** Headers */\n headers?: Record<string, string>;\n}\n\n/**\n * REST API Server\n * Lightweight HTTP server for OpenRedaction with Express-like interface\n */\nexport class APIServer {\n private server?: any;\n private config: Required<Omit<APIServerConfig, 'apiKey' | 'tenantManager' | 'webhookManager' | 'auditLogger' | 'prometheusServer' | 'defaultOptions' | 'corsOrigin'>> &\n Pick<APIServerConfig, 'apiKey' | 'tenantManager' | 'webhookManager' | 'auditLogger' | 'prometheusServer' | 'defaultOptions' | 'corsOrigin'>;\n private detector?: OpenRedaction;\n private isRunning: boolean = false;\n private rateLimitTracking: Map<string, number[]> = new Map();\n\n constructor(config?: APIServerConfig) {\n this.config = {\n port: config?.port ?? 3000,\n host: config?.host ?? '0.0.0.0',\n enableCors: config?.enableCors ?? true,\n corsOrigin: config?.corsOrigin ?? '*',\n apiKey: config?.apiKey,\n enableRateLimit: config?.enableRateLimit ?? true,\n rateLimit: config?.rateLimit ?? 60,\n bodyLimit: config?.bodyLimit ?? '10mb',\n enableLogging: config?.enableLogging ?? true,\n tenantManager: config?.tenantManager,\n webhookManager: config?.webhookManager,\n auditLogger: config?.auditLogger,\n prometheusServer: config?.prometheusServer,\n defaultOptions: config?.defaultOptions\n };\n\n // Initialize detector if not using multi-tenant mode\n if (!this.config.tenantManager) {\n this.detector = new OpenRedaction(this.config.defaultOptions);\n }\n }\n\n /**\n * Start the API server\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error('[APIServer] Server is already running');\n }\n\n try {\n // Try to use native http module\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const http = require('http');\n\n this.server = http.createServer(this.handleRequest.bind(this));\n\n return new Promise<void>((resolve, reject) => {\n this.server.listen(this.config.port, this.config.host, () => {\n this.isRunning = true;\n console.log(`[APIServer] Server started on http://${this.config.host}:${this.config.port}`);\n console.log(`[APIServer] API Documentation: http://${this.config.host}:${this.config.port}/api/docs`);\n resolve();\n });\n\n this.server.on('error', (error: any) => {\n reject(new Error(`[APIServer] Failed to start server: ${error.message}`));\n });\n });\n } catch (error: any) {\n throw new Error(`[APIServer] Failed to initialize HTTP server: ${error.message}`);\n }\n }\n\n /**\n * Stop the server\n */\n async stop(): Promise<void> {\n if (!this.isRunning || !this.server) {\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n this.server.close((error: any) => {\n if (error) {\n reject(new Error(`[APIServer] Failed to stop server: ${error.message}`));\n } else {\n this.isRunning = false;\n console.log('[APIServer] Server stopped');\n resolve();\n }\n });\n });\n }\n\n /**\n * Handle incoming HTTP requests\n */\n private async handleRequest(req: any, res: any): Promise<void> {\n const startTime = Date.now();\n\n try {\n // Parse request\n const apiReq = await this.parseRequest(req);\n\n // CORS\n if (this.config.enableCors) {\n res.setHeader('Access-Control-Allow-Origin', Array.isArray(this.config.corsOrigin) ? this.config.corsOrigin.join(', ') : this.config.corsOrigin);\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key, X-Tenant-ID');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n }\n\n // Authentication\n if (this.config.apiKey) {\n const providedKey = apiReq.headers['x-api-key'] as string || apiReq.headers['authorization']?.toString().replace('Bearer ', '');\n if (providedKey !== this.config.apiKey) {\n this.sendResponse(res, {\n status: 401,\n body: { error: 'Unauthorized', message: 'Invalid API key' }\n });\n return;\n }\n }\n\n // Multi-tenant authentication\n if (this.config.tenantManager) {\n const tenantApiKey = apiReq.headers['x-api-key'] as string;\n if (tenantApiKey) {\n const tenant = this.config.tenantManager.authenticateByApiKey(tenantApiKey);\n if (tenant) {\n apiReq.tenantId = tenant.tenantId;\n } else {\n this.sendResponse(res, {\n status: 401,\n body: { error: 'Unauthorized', message: 'Invalid tenant API key' }\n });\n return;\n }\n } else {\n // Check X-Tenant-ID header\n const tenantId = apiReq.headers['x-tenant-id'] as string;\n if (!tenantId) {\n this.sendResponse(res, {\n status: 400,\n body: { error: 'Bad Request', message: 'X-Tenant-ID header required for multi-tenant mode' }\n });\n return;\n }\n apiReq.tenantId = tenantId;\n }\n }\n\n // Rate limiting\n if (this.config.enableRateLimit) {\n const clientKey = apiReq.tenantId || apiReq.ip || 'unknown';\n if (!this.checkRateLimit(clientKey)) {\n this.sendResponse(res, {\n status: 429,\n body: { error: 'Too Many Requests', message: `Rate limit exceeded: ${this.config.rateLimit} requests per minute` }\n });\n return;\n }\n }\n\n // Route request\n const response = await this.routeRequest(apiReq);\n\n // Log request\n if (this.config.enableLogging) {\n const durationMs = Date.now() - startTime;\n console.log(`[APIServer] ${req.method} ${req.url} ${response.status} ${durationMs}ms`);\n }\n\n this.sendResponse(res, response);\n } catch (error: any) {\n console.error('[APIServer] Request handler error:', error);\n this.sendResponse(res, {\n status: 500,\n body: { error: 'Internal Server Error', message: error.message }\n });\n }\n }\n\n /**\n * Parse HTTP request\n */\n private async parseRequest(req: any): Promise<APIRequest> {\n // Parse URL\n const url = new URL(req.url, `http://${req.headers.host || 'localhost'}`);\n\n // Parse body\n let body: any = {};\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n body = await this.parseBody(req);\n }\n\n return {\n body,\n headers: req.headers,\n query: Object.fromEntries(url.searchParams),\n params: {},\n ip: req.socket.remoteAddress\n };\n }\n\n /**\n * Parse request body\n */\n private async parseBody(req: any): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk: any) => {\n body += chunk.toString();\n });\n req.on('end', () => {\n try {\n resolve(JSON.parse(body || '{}'));\n } catch {\n resolve({});\n }\n });\n req.on('error', reject);\n });\n }\n\n /**\n * Route request to appropriate handler\n */\n private async routeRequest(req: APIRequest): Promise<APIResponse> {\n const url = new URL(req.headers.host ? `http://${req.headers.host}` : 'http://localhost');\n const path = url.pathname;\n const method = req.headers[':method'] || 'GET';\n\n // API routes\n if (path === '/api/detect' && method === 'POST') {\n return this.handleDetect(req);\n }\n if (path === '/api/redact' && method === 'POST') {\n return this.handleRedact(req);\n }\n if (path === '/api/restore' && method === 'POST') {\n return this.handleRestore(req);\n }\n if (path === '/api/audit/logs' && method === 'GET') {\n return this.handleAuditLogs(req);\n }\n if (path === '/api/audit/stats' && method === 'GET') {\n return this.handleAuditStats(req);\n }\n if (path === '/api/metrics' && method === 'GET') {\n return this.handleMetrics(req);\n }\n if (path === '/api/patterns' && method === 'GET') {\n return this.handleGetPatterns(req);\n }\n if (path === '/api/health' && method === 'GET') {\n return this.handleHealth(req);\n }\n if (path === '/api/docs' && method === 'GET') {\n return this.handleDocs(req);\n }\n if (path === '/' && method === 'GET') {\n return this.handleRoot(req);\n }\n\n return {\n status: 404,\n body: { error: 'Not Found', message: `Route not found: ${method} ${path}` }\n };\n }\n\n /**\n * Handle POST /api/detect\n */\n private async handleDetect(req: APIRequest): Promise<APIResponse> {\n const { text } = req.body;\n\n if (!text || typeof text !== 'string') {\n return {\n status: 400,\n body: { error: 'Bad Request', message: 'Missing or invalid \"text\" field' }\n };\n }\n\n try {\n let result: DetectionResult;\n\n if (req.tenantId && this.config.tenantManager) {\n // Multi-tenant mode\n result = await this.config.tenantManager.detect(req.tenantId, text);\n } else if (this.detector) {\n // Single-tenant mode\n result = this.detector.detect(text);\n } else {\n throw new Error('No detector available');\n }\n\n // Emit webhook events\n if (this.config.webhookManager) {\n await this.config.webhookManager.emitHighRiskPII(result, req.tenantId);\n await this.config.webhookManager.emitBulkPII(result, 10, req.tenantId);\n }\n\n return {\n status: 200,\n body: {\n success: true,\n result: {\n detections: result.detections,\n stats: result.stats\n }\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Detection Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle POST /api/redact\n */\n private async handleRedact(req: APIRequest): Promise<APIResponse> {\n const { text } = req.body;\n\n if (!text || typeof text !== 'string') {\n return {\n status: 400,\n body: { error: 'Bad Request', message: 'Missing or invalid \"text\" field' }\n };\n }\n\n try {\n let result: DetectionResult;\n\n if (req.tenantId && this.config.tenantManager) {\n result = await this.config.tenantManager.detect(req.tenantId, text);\n } else if (this.detector) {\n result = this.detector.detect(text);\n } else {\n throw new Error('No detector available');\n }\n\n return {\n status: 200,\n body: {\n success: true,\n result: {\n original: result.original,\n redacted: result.redacted,\n detections: result.detections,\n stats: result.stats\n }\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Redaction Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle POST /api/restore\n */\n private async handleRestore(req: APIRequest): Promise<APIResponse> {\n const { redacted, redactionMap } = req.body;\n\n if (!redacted || !redactionMap) {\n return {\n status: 400,\n body: { error: 'Bad Request', message: 'Missing \"redacted\" or \"redactionMap\" fields' }\n };\n }\n\n try {\n let detector: OpenRedaction;\n\n if (req.tenantId && this.config.tenantManager) {\n detector = this.config.tenantManager.getDetector(req.tenantId);\n } else if (this.detector) {\n detector = this.detector;\n } else {\n throw new Error('No detector available');\n }\n\n const restored = detector.restore(redacted, redactionMap);\n\n return {\n status: 200,\n body: {\n success: true,\n result: { restored }\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Restore Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle GET /api/audit/logs\n */\n private async handleAuditLogs(req: APIRequest): Promise<APIResponse> {\n if (!this.config.auditLogger) {\n return {\n status: 501,\n body: { error: 'Not Implemented', message: 'Audit logging not configured' }\n };\n }\n\n try {\n const limit = parseInt(req.query.limit as string || '100');\n const logs = await this.config.auditLogger.queryLogs({ limit });\n\n return {\n status: 200,\n body: {\n success: true,\n logs\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Query Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle GET /api/audit/stats\n */\n private async handleAuditStats(_req: APIRequest): Promise<APIResponse> {\n if (!this.config.auditLogger) {\n return {\n status: 501,\n body: { error: 'Not Implemented', message: 'Audit logging not configured' }\n };\n }\n\n try {\n const stats = await this.config.auditLogger.getStatsAsync();\n\n return {\n status: 200,\n body: {\n success: true,\n stats\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Query Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle GET /api/metrics\n */\n private async handleMetrics(req: APIRequest): Promise<APIResponse> {\n if (this.detector) {\n // Single-tenant metrics\n return {\n status: 200,\n body: {\n success: true,\n metrics: {}\n }\n };\n }\n\n if (this.config.tenantManager && req.tenantId) {\n // Multi-tenant metrics\n const usage = this.config.tenantManager.getTenantUsage(req.tenantId);\n\n return {\n status: 200,\n body: {\n success: true,\n metrics: usage\n }\n };\n }\n\n return {\n status: 501,\n body: { error: 'Not Implemented', message: 'Metrics not configured' }\n };\n }\n\n /**\n * Handle GET /api/patterns\n */\n private async handleGetPatterns(req: APIRequest): Promise<APIResponse> {\n try {\n let detector: OpenRedaction;\n\n if (req.tenantId && this.config.tenantManager) {\n detector = this.config.tenantManager.getDetector(req.tenantId);\n } else if (this.detector) {\n detector = this.detector;\n } else {\n throw new Error('No detector available');\n }\n\n const patterns = detector.getPatterns();\n\n return {\n status: 200,\n body: {\n success: true,\n patterns: patterns.map(p => ({\n type: p.type,\n priority: p.priority,\n description: p.description,\n severity: p.severity\n }))\n }\n };\n } catch (error: any) {\n return {\n status: 500,\n body: { error: 'Query Failed', message: error.message }\n };\n }\n }\n\n /**\n * Handle GET /api/health\n */\n private async handleHealth(_req: APIRequest): Promise<APIResponse> {\n return {\n status: 200,\n body: {\n status: 'healthy',\n uptime: process.uptime(),\n timestamp: new Date().toISOString(),\n multiTenant: !!this.config.tenantManager,\n features: {\n audit: !!this.config.auditLogger,\n webhooks: !!this.config.webhookManager,\n prometheus: !!this.config.prometheusServer\n }\n }\n };\n }\n\n /**\n * Handle GET /api/docs\n */\n private async handleDocs(_req: APIRequest): Promise<APIResponse> {\n const html = `\n<!DOCTYPE html>\n<html>\n<head>\n <title>OpenRedaction API Documentation</title>\n <style>\n body { font-family: sans-serif; max-width: 1200px; margin: 50px auto; padding: 20px; }\n h1 { color: #333; }\n h2 { color: #666; margin-top: 30px; border-bottom: 2px solid #eee; padding-bottom: 10px; }\n .endpoint { background: #f5f5f5; padding: 15px; margin: 15px 0; border-radius: 4px; border-left: 4px solid #0066cc; }\n .method { display: inline-block; padding: 4px 8px; border-radius: 3px; font-weight: bold; font-size: 12px; margin-right: 10px; }\n .method.post { background: #49cc90; color: white; }\n .method.get { background: #61affe; color: white; }\n code { background: #f0f0f0; padding: 2px 6px; border-radius: 3px; font-family: monospace; }\n pre { background: #f5f5f5; padding: 15px; border-radius: 4px; overflow-x: auto; }\n </style>\n</head>\n<body>\n <h1>OpenRedaction REST API</h1>\n <p>Production-ready PII detection and redaction API</p>\n\n <h2>Authentication</h2>\n <p>Include your API key in the <code>X-API-Key</code> header or <code>Authorization: Bearer YOUR_KEY</code> header.</p>\n ${this.config.tenantManager ? '<p>For multi-tenant mode, also include <code>X-Tenant-ID</code> header.</p>' : ''}\n\n <h2>Endpoints</h2>\n\n <div class=\"endpoint\">\n <span class=\"method post\">POST</span>\n <strong>/api/detect</strong>\n <p>Detect PII in text without redaction</p>\n <pre>{\n \"text\": \"My email is john@example.com and SSN is 123-45-6789\",\n \"options\": {\n \"includeNames\": true,\n \"includeEmails\": true\n }\n}</pre>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method post\">POST</span>\n <strong>/api/redact</strong>\n <p>Detect and redact PII in text</p>\n <pre>{\n \"text\": \"My email is john@example.com\",\n \"options\": {\n \"redactionMode\": \"placeholder\"\n }\n}</pre>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method post\">POST</span>\n <strong>/api/restore</strong>\n <p>Restore original text from redacted text</p>\n <pre>{\n \"redacted\": \"My email is [EMAIL_1]\",\n \"redactionMap\": {\n \"[EMAIL_1]\": \"john@example.com\"\n }\n}</pre>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method get\">GET</span>\n <strong>/api/patterns</strong>\n <p>Get available PII patterns</p>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method get\">GET</span>\n <strong>/api/audit/logs</strong>\n <p>Get audit logs (requires audit logger)</p>\n <p>Query params: <code>limit</code> (default: 100)</p>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method get\">GET</span>\n <strong>/api/audit/stats</strong>\n <p>Get audit statistics (requires audit logger)</p>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method get\">GET</span>\n <strong>/api/metrics</strong>\n <p>Get usage metrics</p>\n </div>\n\n <div class=\"endpoint\">\n <span class=\"method get\">GET</span>\n <strong>/api/health</strong>\n <p>Health check endpoint</p>\n </div>\n\n <h2>Configuration</h2>\n <ul>\n <li>Port: ${this.config.port}</li>\n <li>Host: ${this.config.host}</li>\n <li>CORS: ${this.config.enableCors ? 'Enabled' : 'Disabled'}</li>\n <li>Rate Limiting: ${this.config.enableRateLimit ? `${this.config.rateLimit} req/min` : 'Disabled'}</li>\n <li>Multi-Tenant: ${this.config.tenantManager ? 'Enabled' : 'Disabled'}</li>\n <li>Audit Logging: ${this.config.auditLogger ? 'Enabled' : 'Disabled'}</li>\n <li>Webhooks: ${this.config.webhookManager ? 'Enabled' : 'Disabled'}</li>\n </ul>\n</body>\n</html>\n `.trim();\n\n return {\n status: 200,\n body: html,\n headers: { 'Content-Type': 'text/html' }\n };\n }\n\n /**\n * Handle GET /\n */\n private async handleRoot(_req: APIRequest): Promise<APIResponse> {\n return {\n status: 200,\n body: {\n name: 'OpenRedaction API',\n version: '1.0.0',\n documentation: `/api/docs`,\n health: `/api/health`,\n endpoints: [\n 'POST /api/detect',\n 'POST /api/redact',\n 'POST /api/restore',\n 'GET /api/patterns',\n 'GET /api/audit/logs',\n 'GET /api/audit/stats',\n 'GET /api/metrics',\n 'GET /api/health'\n ]\n }\n };\n }\n\n /**\n * Send HTTP response\n */\n private sendResponse(res: any, response: APIResponse): void {\n const headers = {\n 'Content-Type': 'application/json',\n ...response.headers\n };\n\n res.writeHead(response.status, headers);\n\n if (typeof response.body === 'string') {\n res.end(response.body);\n } else {\n res.end(JSON.stringify(response.body));\n }\n }\n\n /**\n * Check rate limit\n */\n private checkRateLimit(clientKey: string): boolean {\n const now = Date.now();\n const timestamps = this.rateLimitTracking.get(clientKey) || [];\n\n // Remove timestamps older than 1 minute\n const oneMinuteAgo = now - 60 * 1000;\n const recentTimestamps = timestamps.filter(ts => ts > oneMinuteAgo);\n\n if (recentTimestamps.length >= this.config.rateLimit) {\n return false;\n }\n\n recentTimestamps.push(now);\n this.rateLimitTracking.set(clientKey, recentTimestamps);\n\n return true;\n }\n}\n\n/**\n * Create an API server instance\n */\nexport function createAPIServer(config?: APIServerConfig): APIServer {\n return new APIServer(config);\n}\n","/**\n * OpenRedaction - Production-ready PII detection and redaction library\n * @packageDocumentation\n */\n\nexport { OpenRedaction } from './detector';\n\nexport type {\n PIIPattern,\n PIIDetection,\n PIIMatch,\n DetectionResult,\n OpenRedactionOptions,\n RedactionMode,\n Validator,\n IAuditLogger,\n AuditLogEntry,\n AuditStats,\n IMetricsCollector,\n IMetricsExporter,\n RedactionMetrics,\n IRBACManager,\n Role,\n Permission,\n RoleName\n} from './types';\n\n// Audit logging\nexport {\n InMemoryAuditLogger,\n ConsoleAuditLogger,\n PersistentAuditLogger,\n createPersistentAuditLogger\n} from './audit';\nexport type {\n AuditBackend,\n AuditDatabaseConfig,\n RetentionPolicy,\n PersistentAuditLoggerOptions,\n HashedAuditLogEntry,\n IAuditDatabaseAdapter,\n AuditQueryFilter\n} from './audit';\n\n// Metrics collection\nexport {\n InMemoryMetricsCollector,\n PrometheusServer,\n createPrometheusServer,\n GRAFANA_DASHBOARD_TEMPLATE\n} from './metrics';\nexport type {\n PrometheusServerOptions\n} from './metrics';\n\n// RBAC (Role-Based Access Control)\nexport {\n RBACManager,\n createRBACManager,\n ADMIN_ROLE,\n ANALYST_ROLE,\n OPERATOR_ROLE,\n VIEWER_ROLE,\n ALL_PERMISSIONS,\n getPredefinedRole,\n createCustomRole\n} from './rbac';\n\n// Document processing (optional - requires peer dependencies)\nexport {\n DocumentProcessor,\n createDocumentProcessor,\n OCRProcessor,\n createOCRProcessor,\n JsonProcessor,\n createJsonProcessor,\n CsvProcessor,\n createCsvProcessor,\n XlsxProcessor,\n createXlsxProcessor\n} from './document';\nexport type {\n DocumentFormat,\n DocumentOptions,\n DocumentResult,\n DocumentMetadata,\n IDocumentProcessor,\n ImageFormat,\n OCRLanguage,\n OCROptions,\n IOCRProcessor,\n OCRResult,\n JsonProcessorOptions,\n JsonDetectionResult,\n CsvProcessorOptions,\n CsvDetectionResult,\n ColumnStats,\n CellMatch,\n XlsxProcessorOptions,\n XlsxDetectionResult,\n SheetDetectionResult\n} from './document';\n\nexport {\n allPatterns,\n personalPatterns,\n financialPatterns,\n governmentPatterns,\n contactPatterns,\n networkPatterns,\n getPatternsByCategory\n} from './patterns';\n\nexport {\n validateLuhn,\n validateIBAN,\n validateNINO,\n validateNHS,\n validateUKPassport,\n validateSSN,\n validateSortCode,\n validateName,\n validateEmail\n} from './validators';\n\nexport { gdprPreset, hipaaPreset, ccpaPreset, getPreset } from './utils/presets';\n\n// Local learning system\nexport { LocalLearningStore } from './learning/LocalLearningStore';\nexport type {\n WhitelistEntry,\n PatternAdjustment,\n LearningStats,\n LearningData\n} from './learning/LocalLearningStore';\n\n// Config system\nexport { ConfigLoader } from './config/ConfigLoader';\nexport type { OpenRedactionConfig } from './config/ConfigLoader';\n\n// Context analysis system\nexport {\n extractContext,\n inferDocumentType,\n analyzeContextFeatures,\n calculateContextConfidence,\n analyzeFullContext\n} from './context/ContextAnalyzer';\nexport type {\n ContextAnalysis,\n ContextFeatures\n} from './context/ContextAnalyzer';\n\n// Context rules engine (Phase 2)\nexport {\n ContextRulesEngine,\n createContextRulesEngine,\n DEFAULT_PROXIMITY_RULES,\n DEFAULT_DOMAIN_VOCABULARIES\n} from './context/ContextRules';\nexport type {\n ProximityRule,\n DomainVocabulary,\n ContextRulesConfig\n} from './context/ContextRules';\n\n// NER detection (Phase 2 - requires compromise.js peer dependency)\nexport {\n NERDetector,\n createNERDetector\n} from './ml/NERDetector';\nexport type {\n NEREntityType,\n NERMatch,\n HybridMatch\n} from './ml/NERDetector';\n\n// Severity classification (Phase 2)\nexport {\n SeverityClassifier,\n createSeverityClassifier,\n getSeverity,\n calculateRisk,\n DEFAULT_SEVERITY_MAP,\n SEVERITY_SCORES\n} from './severity/SeverityClassifier';\nexport type {\n SeverityLevel,\n SeverityClassification,\n RiskScore\n} from './severity/SeverityClassifier';\n\n// False positive filtering\nexport {\n isFalsePositive,\n filterFalsePositives,\n commonFalsePositives\n} from './filters/FalsePositiveFilter';\nexport type {\n FalsePositiveRule\n} from './filters/FalsePositiveFilter';\n\n// Multi-pass detection\nexport {\n groupPatternsByPass,\n mergePassDetections,\n createSimpleMultiPass,\n defaultPasses\n} from './multipass/MultiPassDetector';\nexport type {\n DetectionPass,\n MultiPassStats\n} from './multipass/MultiPassDetector';\n\n// Priority optimization\nexport {\n PriorityOptimizer,\n createPriorityOptimizer\n} from './optimizer/PriorityOptimizer';\nexport type {\n PatternStats,\n OptimizerOptions\n} from './optimizer/PriorityOptimizer';\n\n// Streaming API\nexport {\n StreamingDetector,\n createStreamingDetector\n} from './streaming/StreamingDetector';\nexport type {\n ChunkResult,\n StreamingOptions\n} from './streaming/StreamingDetector';\n\n// Worker threads (parallel processing)\nexport {\n WorkerPool,\n createWorkerPool\n} from './workers';\nexport type {\n WorkerTask,\n WorkerResult,\n WorkerPoolConfig,\n WorkerPoolStats,\n DetectTask,\n DocumentTask\n} from './workers';\n\n// Batch processing\nexport {\n BatchProcessor,\n createBatchProcessor\n} from './batch/BatchProcessor';\nexport type {\n BatchOptions,\n BatchResult\n} from './batch/BatchProcessor';\n\n// Explain API\nexport {\n ExplainAPI,\n createExplainAPI\n} from './explain/ExplainAPI';\nexport type {\n PatternMatchResult,\n TextExplanation\n} from './explain/ExplainAPI';\n\n// Report generation\nexport {\n ReportGenerator,\n createReportGenerator\n} from './reports/ReportGenerator';\nexport type {\n ReportOptions,\n ReportFormat,\n ReportType\n} from './reports/ReportGenerator';\n\n// Express integration\nexport {\n openredactionMiddleware,\n detectPII,\n generateReport\n} from './integrations/express';\nexport type {\n OpenRedactionMiddlewareOptions,\n OpenRedactionRequest\n} from './integrations/express';\n\n// React integration\nexport {\n useOpenRedaction,\n usePIIDetector,\n useFormFieldValidator,\n useBatchDetector,\n useAutoRedact\n} from './integrations/react';\n\n// Error handling\nexport {\n OpenRedactionError,\n createInvalidPatternError,\n createValidationError,\n createHighMemoryError,\n createConfigLoadError,\n createLearningDisabledError,\n createOptimizationDisabledError,\n createMultiPassDisabledError,\n createCacheDisabledError\n} from './errors/OpenRedactionError';\nexport type {\n ErrorSuggestion\n} from './errors/OpenRedactionError';\n\n// Multi-tenancy (Phase 3)\nexport {\n TenantManager,\n createTenantManager,\n TenantQuotaExceededError,\n TenantNotFoundError,\n TenantSuspendedError,\n DEFAULT_TIER_QUOTAS\n} from './tenancy';\nexport type {\n TenantConfig,\n TenantQuotas,\n TenantUsage\n} from './tenancy';\n\n// Webhooks and alerts (Phase 3)\nexport {\n WebhookManager,\n createWebhookManager,\n verifyWebhookSignature\n} from './webhooks';\nexport type {\n WebhookEventType,\n WebhookEvent,\n WebhookConfig,\n WebhookDeliveryStatus,\n WebhookDelivery,\n WebhookStats\n} from './webhooks';\n\n// REST API Server (Phase 3)\nexport {\n APIServer,\n createAPIServer\n} from './api';\nexport type {\n APIServerConfig,\n APIRequest,\n APIResponse\n} from './api';\n\n// Configuration Import/Export (Phase 3)\nexport {\n ConfigExporter,\n createConfigPreset,\n exportForVersionControl\n} from './config/ConfigExporter';\nexport type {\n ExportedConfig\n} from './config/ConfigExporter';\n\n// Health Check API (Phase 3)\nexport {\n HealthChecker,\n createHealthChecker,\n healthCheckMiddleware\n} from './health/HealthCheck';\nexport type {\n HealthCheckResult,\n HealthCheckStatus,\n HealthCheckOptions\n} from './health/HealthCheck';\n\n// Safe Regex Utilities (Security)\nexport {\n safeExec,\n safeExecAll,\n validatePattern,\n isUnsafePattern,\n compileSafeRegex,\n RegexTimeoutError,\n RegexMaxMatchesError\n} from './utils/safe-regex';\nexport type {\n SafeRegexOptions\n} from './utils/safe-regex';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4SO,SAAS,mBACd,MACA,aACA,SAKQ;AACR,SAAO,eAAe,eAAe,SAAS;AAAA,IAC5C,aAAa,GAAG,IAAI,KAAK,WAAW;AAAA,IACpC,MAAM,CAAC,MAAM,QAAQ;AAAA,EACvB,GAAG,IAAI;AACT;AAKO,SAAS,wBACd,SAKQ;AACR,SAAO,eAAe,eAAe,SAAS;AAAA,IAC5C,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM,CAAC,iBAAiB;AAAA,EAC1B,GAAG,IAAI;AACT;AA1UA,IAgDa;AAhDb;AAAA;AAAA;AAgDO,IAAM,iBAAN,MAAqB;AAAA;AAAA;AAAA;AAAA,MAM1B,OAAO,aACL,SAKA,UAKgB;AAChB,cAAM,WAA2B;AAAA,UAC/B,SAAS,KAAK;AAAA,UACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC,SAAS;AAAA,YACP,cAAc,QAAQ;AAAA,YACtB,kBAAkB,QAAQ;AAAA,YAC1B,eAAe,QAAQ;AAAA,YACvB,eAAe,QAAQ;AAAA,YACvB,UAAU,QAAQ;AAAA,YAClB,YAAY,QAAQ;AAAA,YACpB,WAAW,QAAQ;AAAA,YACnB,eAAe,QAAQ;AAAA,YACvB,eAAe,QAAQ;AAAA,YACvB,QAAQ,QAAQ;AAAA,YAChB,uBAAuB,QAAQ;AAAA,YAC/B,qBAAqB,QAAQ;AAAA,YAC7B,2BAA2B,QAAQ;AAAA,YACnC,wBAAwB,QAAQ;AAAA,YAChC,iBAAiB,QAAQ;AAAA,YACzB,gBAAgB,QAAQ;AAAA,YACxB,aAAa,QAAQ;AAAA,YACrB,WAAW,QAAQ;AAAA,YACnB,cAAc,QAAQ;AAAA,YACtB,cAAc,QAAQ;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAGA,YAAI,QAAQ,kBAAkB,QAAQ,eAAe,SAAS,GAAG;AAC/D,mBAAS,iBAAiB,QAAQ,eAAe,IAAI,QAAM;AAAA,YACzD,MAAM,EAAE;AAAA,YACR,OAAO,EAAE,MAAM;AAAA,YACf,OAAO,EAAE,MAAM;AAAA,YACf,UAAU,EAAE;AAAA,YACZ,aAAa,EAAE;AAAA,YACf,aAAa,EAAE;AAAA,YACf,UAAU,EAAE;AAAA,UACd,EAAE;AAAA,QACJ;AAGA,eAAO,KAAK,MAAM,KAAK,UAAU,QAAQ,CAAC;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,aACL,UACA,UAQA;AAEA,YAAI,CAAC,SAAS,WAAW,SAAS,YAAY,KAAK,gBAAgB;AACjE,kBAAQ;AAAA,YACN,qDAAqD,KAAK,cAAc,SAAS,SAAS,OAAO;AAAA,UACnG;AAAA,QACF;AAEA,cAAM,SAAc,EAAE,GAAG,SAAS,QAAQ;AAG1C,YAAI,SAAS,gBAAgB;AAC3B,iBAAO,iBAAiB,SAAS,eAAe,IAAI,OAAK;AACvD,kBAAM,UAAsB;AAAA,cAC1B,MAAM,EAAE;AAAA,cACR,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,KAAK;AAAA,cAClC,UAAU,EAAE;AAAA,cACZ,aAAa,EAAE;AAAA,cACf,aAAa,EAAE;AAAA,cACf,UAAU,EAAE;AAAA,YACd;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,eACL,SAKA,UAKA,QACQ;AACR,cAAM,WAAW,KAAK,aAAa,SAAS,QAAQ;AACpD,eAAO,KAAK,UAAU,UAAU,MAAM,SAAS,IAAI,MAAS;AAAA,MAC9D;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,iBAAiB,MAItB;AACA,cAAM,WAA2B,KAAK,MAAM,IAAI;AAChD,eAAO,KAAK,aAAa,QAAQ;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,aACX,UACA,SAKA,UAKe;AACf,cAAMA,MAAK,MAAM,OAAO,aAAa;AACrC,cAAM,UAAU,KAAK,eAAe,SAAS,UAAU,IAAI;AAC3D,cAAMA,IAAG,UAAU,UAAU,SAAS,OAAO;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,eAAe,UAIzB;AACD,cAAMA,MAAK,MAAM,OAAO,aAAa;AACrC,cAAM,UAAU,MAAMA,IAAG,SAAS,UAAU,OAAO;AACnD,eAAO,KAAK,iBAAiB,OAAO;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,eAAe,UAGpB;AACA,cAAM,SAAmB,CAAC;AAE1B,YAAI,CAAC,SAAS,SAAS;AACrB,iBAAO,KAAK,uBAAuB;AAAA,QACrC;AAEA,YAAI,CAAC,SAAS,WAAW;AACvB,iBAAO,KAAK,yBAAyB;AAAA,QACvC;AAEA,YAAI,CAAC,SAAS,SAAS;AACrB,iBAAO,KAAK,uBAAuB;AAAA,QACrC;AAGA,YAAI,SAAS,gBAAgB;AAC3B,qBAAW,WAAW,SAAS,gBAAgB;AAC7C,gBAAI,CAAC,QAAQ,QAAQ,CAAC,QAAQ,SAAS,CAAC,QAAQ,aAAa;AAC3D,qBAAO,KAAK,2BAA2B,QAAQ,IAAI,EAAE;AAAA,YACvD;AAEA,gBAAI;AACF,kBAAI,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,YACzC,SAAS,GAAG;AACV,qBAAO,KAAK,4BAA4B,QAAQ,IAAI,KAAM,EAAY,OAAO,EAAE;AAAA,YACjF;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,aACL,MACA,UACgB;AAChB,eAAO;AAAA,UACL,SAAS,KAAK;AAAA,UACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC,SAAS;AAAA,YACP,GAAG,KAAK;AAAA,YACR,GAAG,SAAS;AAAA;AAAA,YAEZ,UAAU,SAAS,QAAQ,YAAY,KAAK,QAAQ;AAAA,YACpD,YAAY,SAAS,QAAQ,cAAc,KAAK,QAAQ;AAAA,YACxD,WAAW;AAAA,cACT,GAAI,KAAK,QAAQ,aAAa,CAAC;AAAA,cAC/B,GAAI,SAAS,QAAQ,aAAa,CAAC;AAAA,YACrC;AAAA,UACF;AAAA,UACA,gBAAgB;AAAA,YACd,GAAI,KAAK,kBAAkB,CAAC;AAAA,YAC5B,GAAI,SAAS,kBAAkB,CAAC;AAAA,UAClC;AAAA,UACA,UAAU;AAAA,YACR,GAAG,KAAK;AAAA,YACR,GAAG,SAAS;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAlPE,IADW,eACa,iBAAiB;AAAA;AAAA;;;ACvCpC,IAAM,sBAAN,MAAkD;AAAA,EAIvD,YAAY,UAAkB,KAAO;AAHrC,SAAQ,OAAwB,CAAC;AAI/B,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAsD;AACxD,UAAM,aAA4B;AAAA,MAChC,GAAG;AAAA,MACH,IAAI,KAAK,WAAW;AAAA,MACpB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAEA,SAAK,KAAK,KAAK,UAAU;AAGzB,QAAI,KAAK,KAAK,SAAS,KAAK,SAAS;AACnC,WAAK,KAAK,MAAM;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAA2B;AACzB,WAAO,CAAC,GAAG,KAAK,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,WAAwD;AACzE,WAAO,KAAK,KAAK,OAAO,SAAO,IAAI,cAAc,SAAS;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,WAAiB,SAAgC;AAClE,UAAM,YAAY,UAAU,QAAQ;AACpC,UAAM,UAAU,QAAQ,QAAQ;AAEhC,WAAO,KAAK,KAAK,OAAO,SAAO;AAC7B,YAAM,UAAU,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ;AAChD,aAAO,WAAW,aAAa,WAAW;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,eAAuB;AACrB,WAAO,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AACpB,QAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,aAAO;AAAA,IACT;AAEA,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,KAAK,IAAI,SAAO;AAChC,aAAO;AAAA,QACL,KAAK,UAAU,IAAI,EAAE;AAAA,QACrB,KAAK,UAAU,IAAI,SAAS;AAAA,QAC5B,KAAK,UAAU,IAAI,SAAS;AAAA,QAC5B,IAAI,SAAS,SAAS;AAAA,QACtB,KAAK,UAAU,IAAI,SAAS,KAAK,GAAG,CAAC;AAAA,QACrC,IAAI,WAAW,SAAS;AAAA,QACxB,IAAI,iBAAiB,QAAQ,CAAC;AAAA,QAC9B,KAAK,UAAU,IAAI,iBAAiB,EAAE;AAAA,QACtC,IAAI,QAAQ,SAAS;AAAA,QACrB,KAAK,UAAU,IAAI,SAAS,EAAE;AAAA,QAC9B,KAAK,UAAU,IAAI,QAAQ,EAAE;AAAA,QAC7B,KAAK,UAAU,IAAI,aAAa,EAAE;AAAA,MACpC,EAAE,KAAK,GAAG;AAAA,IACZ,CAAC;AAED,WAAO,QAAQ,KAAK,GAAG,IAAI,OAAO,KAAK,KAAK,IAAI;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,OAAO,CAAC;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,WAAuB;AACrB,QAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,uBAAuB;AAAA,QACvB,aAAa,CAAC;AAAA,QACd,kBAAkB,CAAC;AAAA,QACnB,aAAa;AAAA,MACf;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK,KAAK;AAClC,UAAM,mBAAmB,KAAK,KAAK,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,UAAU,CAAC;AAC7E,UAAM,sBAAsB,KAAK,KAAK,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,kBAAkB,CAAC;AACxF,UAAM,wBAAwB,sBAAsB;AACpD,UAAM,eAAe,KAAK,KAAK,OAAO,SAAO,IAAI,OAAO,EAAE;AAC1D,UAAM,cAAc,eAAe;AAGnC,UAAM,eAAe,oBAAI,IAAoB;AAC7C,SAAK,KAAK,QAAQ,SAAO;AACvB,UAAI,SAAS,QAAQ,UAAQ;AAC3B,qBAAa,IAAI,OAAO,aAAa,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAC1D,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,cAAc,MAAM,KAAK,aAAa,QAAQ,CAAC,EAClD,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,MAAM,EAAE,EACxC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,EAAE;AAGd,UAAM,mBAA2C,CAAC;AAClD,SAAK,KAAK,QAAQ,SAAO;AACvB,uBAAiB,IAAI,SAAS,KAAK,iBAAiB,IAAI,SAAS,KAAK,KAAK;AAAA,IAC7E,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAqB;AAC3B,WAAO,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,OAAuB;AACvC,QAAI,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,IAAI,GAAG;AACtE,aAAO,IAAI,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AACF;AAMO,IAAM,qBAAN,MAAiD;AAAA,EAGtD,YAAY,UAAkB,KAAO;AACnC,SAAK,WAAW,IAAI,oBAAoB,OAAO;AAAA,EACjD;AAAA,EAEA,IAAI,OAAsD;AACxD,SAAK,SAAS,IAAI,KAAK;AACvB,YAAQ,IAAI,WAAW;AAAA,MACrB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,UAA2B;AACzB,WAAO,KAAK,SAAS,QAAQ;AAAA,EAC/B;AAAA,EAEA,mBAAmB,WAAwD;AACzE,WAAO,KAAK,SAAS,mBAAmB,SAAS;AAAA,EACnD;AAAA,EAEA,mBAAmB,WAAiB,SAAgC;AAClE,WAAO,KAAK,SAAS,mBAAmB,WAAW,OAAO;AAAA,EAC5D;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK,SAAS,aAAa;AAAA,EACpC;AAAA,EAEA,cAAsB;AACpB,WAAO,KAAK,SAAS,YAAY;AAAA,EACnC;AAAA,EAEA,QAAc;AACZ,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,WAAuB;AACrB,WAAO,KAAK,SAAS,SAAS;AAAA,EAChC;AACF;;;ACvOA,SAAS,kBAAkB;AAqIpB,IAAM,wBAAN,MAAoD;AAAA,EASzD,YAAY,SAAuC;AANnD,SAAQ,cAAqC,CAAC;AAC9C,SAAQ,WAAmB;AAC3B,SAAQ,WAAmB;AAE3B,SAAQ,cAAuB;AAG7B,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,WAAW;AAAA,QACT,YAAY,QAAQ,WAAW,cAAc;AAAA,QAC7C,SAAS,QAAQ,WAAW;AAAA,QAC5B,aAAa,QAAQ,WAAW,eAAe;AAAA,QAC/C,sBAAsB,QAAQ,WAAW,wBAAwB;AAAA,MACnE;AAAA,MACA,eAAe,QAAQ,iBAAiB;AAAA,MACxC,eAAe,QAAQ,iBAAiB;AAAA,MACxC,WAAW,QAAQ,aAAa;AAAA,MAChC,WAAW,QAAQ;AAAA,IACrB;AAGA,SAAK,UAAU,KAAK,cAAc,QAAQ,QAAQ;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AAEA,UAAM,KAAK,QAAQ,WAAW;AAG9B,UAAM,YAAY,MAAM,KAAK,QAAQ,aAAa;AAClD,QAAI,WAAW;AACb,WAAK,WAAW,UAAU;AAC1B,WAAK,WAAW,UAAU;AAAA,IAC5B;AAGA,QAAI,KAAK,QAAQ,UAAU,aAAa;AACtC,WAAK,qBAAqB;AAAA,IAC5B;AAEA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAsD;AAExD,UAAM,YAA2B;AAAA,MAC/B,IAAI,KAAK,WAAW;AAAA,MACpB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,GAAG;AAAA,IACL;AAGA,UAAM,cAAc,KAAK,kBAAkB,SAAS;AAGpD,SAAK,YAAY,KAAK,WAAW;AAGjC,UAAM,YAAY,KAAK,QAAQ,SAAS,aAAa;AACrD,QAAI,KAAK,YAAY,UAAU,WAAW;AAExC,WAAK,WAAW,EAAE,MAAM,SAAO;AAC7B,gBAAQ,MAAM,kDAAkD,GAAG;AAAA,MACrE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAA2B;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,QAA2D;AACzE,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AAGA,UAAM,KAAK,WAAW;AAEtB,WAAO,KAAK,QAAQ,MAAM,UAAU,CAAC,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,YAAyD;AAC1E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,YAAkB,UAAiC;AACpE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAuB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAkB,QAA4C;AAClE,UAAM,OAAO,MAAM,KAAK,UAAU,MAAM;AACxC,WAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,QAA4C;AACjE,UAAM,OAAO,MAAM,KAAK,UAAU,MAAM;AAExC,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AAGA,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,IAAI,SAAO;AAAA,MAC3B,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI,SAAS,KAAK,GAAG;AAAA,MACrB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI,iBAAiB;AAAA,MACrB,IAAI;AAAA,MACJ,IAAI,SAAS;AAAA,MACb,IAAI,QAAQ;AAAA,MACZ,IAAI,aAAa;AAAA,MACjB,IAAI;AAAA,MACJ,IAAI,gBAAgB;AAAA,MACpB,IAAI;AAAA,IACN,CAAC;AAED,WAAO;AAAA,MACL,QAAQ,KAAK,GAAG;AAAA,MAChB,GAAG,KAAK,IAAI,SAAO,IAAI,IAAI,WAAS,IAAI,OAAO,KAAK,EAAE,QAAQ,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,IACzF,EAAE,KAAK,IAAI;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,MAA6B;AACjD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,WAAO,KAAK,QAAQ,gBAAgB,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,WAAuB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAAgD;AAClE,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,OAAO,MAAM,KAAK,UAAU,MAAM;AAExC,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,uBAAuB;AAAA,QACvB,aAAa,CAAC;AAAA,QACd,kBAAkB,CAAC;AAAA,QACnB,aAAa;AAAA,MACf;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK;AAC7B,UAAM,mBAAmB,KAAK,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,UAAU,CAAC;AACxE,UAAM,sBAAsB,KAAK,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,kBAAkB,CAAC;AACnF,UAAM,wBAAwB,sBAAsB;AAGpD,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,SAAK,QAAQ,SAAO;AAClB,UAAI,SAAS,QAAQ,UAAQ;AAC3B,sBAAc,IAAI,OAAO,cAAc,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAC5D,CAAC;AAAA,IACH,CAAC;AAED,UAAM,cAAc,MAAM,KAAK,cAAc,QAAQ,CAAC,EACnD,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,MAAM,EAAE,EACxC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,EAAE;AAGd,UAAM,mBAA2C,CAAC;AAClD,SAAK,QAAQ,SAAO;AAClB,uBAAiB,IAAI,SAAS,KAAK,iBAAiB,IAAI,SAAS,KAAK,KAAK;AAAA,IAC7E,CAAC;AAGD,UAAM,eAAe,KAAK,OAAO,SAAO,IAAI,OAAO,EAAE;AACrD,UAAM,cAAc,eAAe;AAEnC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,eAAwB,aAIhD;AACD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,QAAI,CAAC,KAAK,QAAQ,eAAe;AAC/B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,YAAY,eAAe,WAAW;AAExE,QAAI,OAAO,OAAO;AAChB,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF,OAAO;AACL,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,OAAO;AAAA,QACjB,SAAS,yCAAyC,OAAO,QAAQ;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,KAAK,YAAY,WAAW,GAAG;AACjC;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,QAAQ,CAAC,GAAG,KAAK,WAAW;AAClC,SAAK,cAAc,CAAC;AAEpB,QAAI;AACF,YAAM,KAAK,QAAQ,YAAY,KAAK;AAAA,IACtC,SAAS,OAAO;AAEd,WAAK,YAAY,QAAQ,GAAG,KAAK;AACjC,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAE3B,QAAI,KAAK,cAAc;AACrB,oBAAc,KAAK,YAAY;AAAA,IACjC;AAGA,UAAM,KAAK,WAAW;AAGtB,UAAM,KAAK,QAAQ,MAAM;AAEzB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,OAA2C;AACnE,SAAK;AAEL,UAAM,cAAmC;AAAA,MACvC,GAAG;AAAA,MACH,MAAM;AAAA,MACN,cAAc,KAAK,YAAY;AAAA,MAC/B,UAAU,KAAK;AAAA,IACjB;AAGA,QAAI,KAAK,QAAQ,eAAe;AAC9B,kBAAY,OAAO,KAAK,cAAc,WAAW;AACjD,WAAK,WAAW,YAAY;AAAA,IAC9B,OAAO;AACL,kBAAY,OAAO;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,OAAkD;AACtE,UAAM,YAAY,KAAK,QAAQ;AAG/B,UAAM,OAAO,KAAK,UAAU;AAAA,MAC1B,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,kBAAkB,MAAM;AAAA,MACxB,eAAe,MAAM;AAAA,MACrB,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,cAAc,MAAM;AAAA,MACpB,UAAU,MAAM;AAAA,IAClB,CAAC;AAGD,QAAI,KAAK,QAAQ,WAAW;AAC1B,aAAO,WAAW,SAAS,EACxB,OAAO,KAAK,QAAQ,YAAY,IAAI,EACpC,OAAO,KAAK;AAAA,IACjB,OAAO;AACL,aAAO,WAAW,SAAS,EACxB,OAAO,IAAI,EACX,OAAO,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAqB;AAC3B,WAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,QAAoD;AACxE,YAAQ,OAAO,SAAS;AAAA,MACtB,KAAK;AACH,eAAO,IAAI,mBAAmB,QAAQ,KAAK,OAAO;AAAA,MACpD,KAAK;AACH,eAAO,IAAI,uBAAuB,QAAQ,KAAK,OAAO;AAAA,MACxD,KAAK;AACH,eAAO,IAAI,mBAAmB,QAAQ,KAAK,OAAO;AAAA,MACpD,KAAK;AACH,eAAO,IAAI,eAAe,QAAQ,KAAK,OAAO;AAAA,MAChD,KAAK;AACH,eAAO,IAAI,iBAAiB,QAAQ,KAAK,OAAO;AAAA,MAClD;AACE,cAAM,IAAI,MAAM,gDAAgD,OAAO,OAAO,EAAE;AAAA,IACpF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,UAAM,cAAc,KAAK,QAAQ,WAAW,wBAAwB,MAAM,KAAK,KAAK;AAEpF,SAAK,eAAe,YAAY,MAAM;AACpC,WAAK,WAAW,EAAE,MAAM,SAAO;AAC7B,gBAAQ,MAAM,2CAA2C,GAAG;AAAA,MAC9D,CAAC;AAAA,IACH,GAAG,UAAU;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAA4B;AACxC,QAAI,CAAC,KAAK,aAAa;AACrB;AAAA,IACF;AAEA,UAAM,EAAE,YAAY,QAAQ,IAAI,KAAK,QAAQ;AAG7C,QAAI,YAAY;AACd,YAAM,aAAa,oBAAI,KAAK;AAC5B,iBAAW,QAAQ,WAAW,QAAQ,IAAI,UAAU;AAEpD,YAAM,UAAU,MAAM,KAAK,gBAAgB,UAAU;AACrD,UAAI,UAAU,GAAG;AACf,gBAAQ,IAAI,4CAA4C,OAAO,oBAAoB,UAAU,OAAO;AAAA,MACtG;AAAA,IACF;AAGA,QAAI,SAAS;AACX,YAAM,QAAQ,MAAM,KAAK,QAAQ,MAAM;AACvC,UAAI,QAAQ,SAAS;AACnB,cAAM,WAAW,QAAQ;AAEzB,gBAAQ,IAAI,mDAAmD,QAAQ,0BAA0B,OAAO,GAAG;AAAA,MAC7G;AAAA,IACF;AAAA,EACF;AACF;AAKA,IAAM,qBAAN,MAA0D;AAAA,EAKxD,YAAY,QAA6B,SAA6F;AACpI,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,aAA4B;AAChC,QAAI;AAEF,YAAM,UAAU,UAAQ,gBAAgB;AACxC,YAAM,WAAW,KAAK,OAAO,YAAY;AAEzC,WAAK,KAAK,QAAQ,QAAQ;AAG1B,UAAI,KAAK,QAAQ,WAAW;AAC1B,aAAK,GAAG,OAAO,oBAAoB;AAAA,MACrC;AAGA,YAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,WAAK,GAAG,KAAK;AAAA,qCACkB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAmBvC;AAGD,WAAK,GAAG,KAAK;AAAA,yCACsB,SAAS,iBAAiB,SAAS;AAAA,yCACnC,SAAS,iBAAiB,SAAS;AAAA,yCACnC,SAAS,YAAY,SAAS;AAAA,yCAC9B,SAAS,iBAAiB,SAAS;AAAA,yCACnC,SAAS,gBAAgB,SAAS;AAAA,OACpE;AAAA,IACH,SAAS,OAAY;AACnB,YAAM,IAAI;AAAA,QACR,8CAA8C,MAAM,OAAO;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,OAA2C;AACtD,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,OAAO,KAAK,GAAG,QAAQ;AAAA,oBACb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,KAKxB;AAED,SAAK;AAAA,MACH,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK,UAAU,MAAM,QAAQ;AAAA,MAC7B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,iBAAiB;AAAA,MACvB,MAAM,UAAU,IAAI;AAAA,MACpB,MAAM,SAAS;AAAA,MACf,MAAM,QAAQ;AAAA,MACd,MAAM,aAAa;AAAA,MACnB,MAAM,WAAW,KAAK,UAAU,MAAM,QAAQ,IAAI;AAAA,MAClD,MAAM;AAAA,MACN,MAAM,gBAAgB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAA+C;AAC/D,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,OAAO,KAAK,GAAG,QAAQ;AAAA,oBACb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,KAKxB;AAED,UAAM,cAAc,KAAK,GAAG,YAAY,CAACC,aAAmC;AAC1E,iBAAW,SAASA,UAAS;AAC3B,aAAK;AAAA,UACH,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,KAAK,UAAU,MAAM,QAAQ;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM,iBAAiB;AAAA,UACvB,MAAM,UAAU,IAAI;AAAA,UACpB,MAAM,SAAS;AAAA,UACf,MAAM,QAAQ;AAAA,UACd,MAAM,aAAa;AAAA,UACnB,MAAM,WAAW,KAAK,UAAU,MAAM,QAAQ,IAAI;AAAA,UAClD,MAAM;AAAA,UACN,MAAM,gBAAgB;AAAA,QACxB;AAAA,MACF;AAAA,IACF,CAAC;AAED,gBAAY,OAAO;AAAA,EACrB;AAAA,EAEA,MAAM,MAAM,QAA0D;AACpE,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,aAAuB,CAAC;AAC9B,UAAM,SAAgB,CAAC;AAEvB,QAAI,OAAO,WAAW;AACpB,iBAAW,KAAK,eAAe;AAC/B,aAAO,KAAK,OAAO,SAAS;AAAA,IAC9B;AAEA,QAAI,OAAO,MAAM;AACf,iBAAW,KAAK,UAAU;AAC1B,aAAO,KAAK,OAAO,IAAI;AAAA,IACzB;AAEA,QAAI,OAAO,WAAW;AACpB,iBAAW,KAAK,eAAe;AAC/B,aAAO,KAAK,OAAO,SAAS;AAAA,IAC9B;AAEA,QAAI,OAAO,WAAW;AACpB,iBAAW,KAAK,gBAAgB;AAChC,aAAO,KAAK,OAAO,UAAU,YAAY,CAAC;AAAA,IAC5C;AAEA,QAAI,OAAO,SAAS;AAClB,iBAAW,KAAK,gBAAgB;AAChC,aAAO,KAAK,OAAO,QAAQ,YAAY,CAAC;AAAA,IAC1C;AAEA,QAAI,OAAO,YAAY,QAAW;AAChC,iBAAW,KAAK,aAAa;AAC7B,aAAO,KAAK,OAAO,UAAU,IAAI,CAAC;AAAA,IACpC;AAEA,UAAM,cAAc,WAAW,SAAS,IAAI,SAAS,WAAW,KAAK,OAAO,CAAC,KAAK;AAClF,UAAM,YAAY,OAAO,SAAS,QAAQ,QAAQ;AAClD,UAAM,QAAQ,OAAO,QAAQ,SAAS,OAAO,KAAK,KAAK;AACvD,UAAM,SAAS,OAAO,SAAS,UAAU,OAAO,MAAM,KAAK;AAE3D,UAAM,QAAQ;AAAA,sBACI,SAAS;AAAA,QACvB,WAAW;AAAA,0BACO,SAAS;AAAA,QAC3B,KAAK,IAAI,MAAM;AAAA;AAGnB,UAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AAEjD,WAAO,KAAK,IAAI,CAAC,QAAa,KAAK,WAAW,GAAG,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,MAAM,QAAqD;AAC/D,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,aAAuB,CAAC;AAC9B,UAAM,SAAgB,CAAC;AAEvB,QAAI,QAAQ,WAAW;AACrB,iBAAW,KAAK,eAAe;AAC/B,aAAO,KAAK,OAAO,SAAS;AAAA,IAC9B;AAEA,QAAI,QAAQ,WAAW;AACrB,iBAAW,KAAK,gBAAgB;AAChC,aAAO,KAAK,OAAO,UAAU,YAAY,CAAC;AAAA,IAC5C;AAEA,QAAI,QAAQ,SAAS;AACnB,iBAAW,KAAK,gBAAgB;AAChC,aAAO,KAAK,OAAO,QAAQ,YAAY,CAAC;AAAA,IAC1C;AAEA,UAAM,cAAc,WAAW,SAAS,IAAI,SAAS,WAAW,KAAK,OAAO,CAAC,KAAK;AAClF,UAAM,QAAQ,iCAAiC,SAAS,IAAI,WAAW;AAEvE,UAAM,SAAS,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AACnD,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,gBAAgB,MAA6B;AACjD,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,SAAS,KAAK,GAAG,QAAQ;AAAA,oBACf,SAAS;AAAA,KACxB,EAAE,IAAI,KAAK,YAAY,CAAC;AAEzB,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,eAAoD;AACxD,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,MAAM,KAAK,GAAG,QAAQ;AAAA,sBACV,SAAS;AAAA,KAC1B,EAAE,IAAI;AAEP,WAAO,MAAM,KAAK,WAAW,GAAG,IAAI;AAAA,EACtC;AAAA,EAEA,MAAM,YAAY,eAAwB,aAAsE;AAC9G,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,QAAQ,iBAAiB;AAC/B,UAAM,MAAM,eAAgB,MAAM,KAAK,MAAM;AAE7C,UAAM,OAAO,KAAK,GAAG,QAAQ;AAAA,sBACX,SAAS;AAAA,KAC1B,EAAE,IAAI,OAAO,GAAG;AAEjB,QAAI;AAEJ,eAAW,OAAO,MAAM;AACtB,YAAM,QAAQ,KAAK,WAAW,GAAG;AAEjC,UAAI,gBAAgB,MAAM,iBAAiB,cAAc;AACvD,eAAO,EAAE,OAAO,OAAO,UAAU,MAAM,SAAS;AAAA,MAClD;AAEA,qBAAe,MAAM;AAAA,IACvB;AAEA,WAAO,EAAE,OAAO,KAAK;AAAA,EACvB;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,WAAW,KAA+B;AAChD,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,MACf,UAAU,IAAI;AAAA,MACd,UAAU,KAAK,MAAM,IAAI,QAAQ;AAAA,MACjC,YAAY,IAAI;AAAA,MAChB,kBAAkB,IAAI;AAAA,MACtB,eAAe,IAAI,iBAAiB;AAAA,MACpC,SAAS,IAAI,YAAY;AAAA,MACzB,OAAO,IAAI,SAAS;AAAA,MACpB,MAAM,IAAI,QAAQ;AAAA,MAClB,WAAW,IAAI,aAAa;AAAA,MAC5B,UAAU,IAAI,WAAW,KAAK,MAAM,IAAI,QAAQ,IAAI;AAAA,MACpD,MAAM,IAAI;AAAA,MACV,cAAc,IAAI,gBAAgB;AAAA,MAClC,UAAU,IAAI;AAAA,IAChB;AAAA,EACF;AACF;AAKA,IAAM,yBAAN,MAA8D;AAAA,EAC5D,YAAY,SAA8B,UAA8F;AAAA,EAExI;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,IAAI,MAAM,4EAA4E;AAAA,EAC9F;AAAA,EAEA,MAAM,OAAO,QAA4C;AACvD,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,YAAY,UAAgD;AAChE,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,MAAM,SAA2D;AACrE,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,MAAM,SAAsD;AAChE,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,gBAAgB,OAA8B;AAClD,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,eAAoD;AACxD,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,YAAY,gBAAyB,cAAuE;AAChH,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,MAAM,QAAuB;AAAA,EAE7B;AACF;AAKA,IAAM,qBAAN,MAA0D;AAAA,EACxD,YAAY,SAA8B,UAA8F;AAAA,EAExI;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AAAA,EAEA,MAAM,OAAO,QAA4C;AACvD,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,YAAY,UAAgD;AAChE,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,MAAM,SAA2D;AACrE,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,MAAM,SAAsD;AAChE,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,gBAAgB,OAA8B;AAClD,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,eAAoD;AACxD,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,YAAY,gBAAyB,cAAuE;AAChH,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAAA,EAEA,MAAM,QAAuB;AAAA,EAE7B;AACF;AAKA,IAAM,iBAAN,MAAsD;AAAA,EACpD,YAAY,SAA8B,UAA8F;AAAA,EAExI;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,IAAI,MAAM,oFAAoF;AAAA,EACtG;AAAA,EAEA,MAAM,OAAO,QAA4C;AACvD,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,YAAY,UAAgD;AAChE,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,MAAM,SAA2D;AACrE,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,MAAM,SAAsD;AAChE,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,gBAAgB,OAA8B;AAClD,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,eAAoD;AACxD,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,YAAY,gBAAyB,cAAuE;AAChH,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAAA,EAEA,MAAM,QAAuB;AAAA,EAE7B;AACF;AAKA,IAAM,mBAAN,MAAwD;AAAA,EACtD,YAAY,SAA8B,UAA8F;AAAA,EAExI;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,OAAO,QAA4C;AACvD,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,YAAY,UAAgD;AAChE,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,MAAM,SAA2D;AACrE,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,MAAM,SAAsD;AAChE,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,gBAAgB,OAA8B;AAClD,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,eAAoD;AACxD,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,YAAY,gBAAyB,cAAuE;AAChH,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA,EAEA,MAAM,QAAuB;AAAA,EAE7B;AACF;AAKO,SAAS,4BAA4B,SAA8D;AACxG,SAAO,IAAI,sBAAsB,OAAO;AAC1C;;;ACpkCO,IAAM,2BAAN,MAA8E;AAAA,EAGnF,cAAc;AACZ,SAAK,UAAU,KAAK,mBAAmB;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAuC;AAC7C,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,uBAAuB;AAAA,MACvB,iBAAiB;AAAA,MACjB,WAAW,CAAC;AAAA,MACZ,iBAAiB,CAAC;AAAA,MAClB,aAAa;AAAA,MACb,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAAyB,kBAA0B,eAAoC;AACrG,SAAK,QAAQ;AACb,SAAK,QAAQ,oBAAoB,OAAO,WAAW;AACnD,SAAK,QAAQ,uBAAuB;AACpC,SAAK,QAAQ,wBAAwB,KAAK,QAAQ,sBAAsB,KAAK,QAAQ;AACrF,SAAK,QAAQ,mBAAmB,OAAO,SAAS;AAGhD,eAAW,aAAa,OAAO,YAAY;AACzC,WAAK,QAAQ,UAAU,UAAU,IAAI,KAAK,KAAK,QAAQ,UAAU,UAAU,IAAI,KAAK,KAAK;AAAA,IAC3F;AAGA,SAAK,QAAQ,gBAAgB,aAAa,KAAK,KAAK,QAAQ,gBAAgB,aAAa,KAAK,KAAK;AAEnG,SAAK,QAAQ,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAoB;AAClB,SAAK,QAAQ;AACb,SAAK,QAAQ,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAgC;AAC9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAA+B;AAC7B,WAAO,EAAE,GAAG,KAAK,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,UAAU,KAAK,mBAAmB;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,UAA4B,KAAK,SAAS,SAAiB,iBAAyB;AACnG,UAAM,QAAkB,CAAC;AACzB,UAAM,YAAY,KAAK,IAAI;AAG3B,UAAM,KAAK,UAAU,MAAM,wDAAwD;AACnF,UAAM,KAAK,UAAU,MAAM,2BAA2B;AACtD,UAAM,KAAK,GAAG,MAAM,qBAAqB,QAAQ,eAAe,IAAI,SAAS,EAAE;AAC/E,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,wDAAwD;AACnF,UAAM,KAAK,UAAU,MAAM,6BAA6B;AACxD,UAAM,KAAK,GAAG,MAAM,uBAAuB,QAAQ,gBAAgB,IAAI,SAAS,EAAE;AAClF,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,iEAAiE;AAC5F,UAAM,KAAK,UAAU,MAAM,+BAA+B;AAC1D,UAAM,KAAK,GAAG,MAAM,2BAA2B,QAAQ,sBAAsB,QAAQ,CAAC,CAAC,IAAI,SAAS,EAAE;AACtG,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,iEAAiE;AAC5F,UAAM,KAAK,UAAU,MAAM,mCAAmC;AAC9D,UAAM,KAAK,GAAG,MAAM,6BAA6B,QAAQ,oBAAoB,QAAQ,CAAC,CAAC,IAAI,SAAS,EAAE;AACtG,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,8DAA8D;AACzF,UAAM,KAAK,UAAU,MAAM,4BAA4B;AACvD,UAAM,KAAK,GAAG,MAAM,sBAAsB,QAAQ,eAAe,IAAI,SAAS,EAAE;AAChF,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,2CAA2C;AACtE,UAAM,KAAK,UAAU,MAAM,sBAAsB;AACjD,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,GAAG;AAC7D,YAAM,KAAK,GAAG,MAAM,sBAAsB,IAAI,MAAM,KAAK,IAAI,SAAS,EAAE;AAAA,IAC1E;AACA,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,uDAAuD;AAClF,UAAM,KAAK,UAAU,MAAM,4BAA4B;AACvD,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,eAAe,GAAG;AACnE,YAAM,KAAK,GAAG,MAAM,4BAA4B,IAAI,MAAM,KAAK,IAAI,SAAS,EAAE;AAAA,IAChF;AACA,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,sCAAsC;AACjE,UAAM,KAAK,UAAU,MAAM,uBAAuB;AAClD,UAAM,KAAK,GAAG,MAAM,iBAAiB,QAAQ,WAAW,IAAI,SAAS,EAAE;AACvE,UAAM,KAAK,EAAE;AAEb,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAA4B,KAAK,SAAS,SAAiB,iBAA2B;AACjG,UAAM,QAAkB,CAAC;AAGzB,UAAM,KAAK,GAAG,MAAM,qBAAqB,QAAQ,eAAe,IAAI;AACpE,UAAM,KAAK,GAAG,MAAM,uBAAuB,QAAQ,gBAAgB,IAAI;AACvE,UAAM,KAAK,GAAG,MAAM,6BAA6B,QAAQ,oBAAoB,QAAQ,CAAC,CAAC,IAAI;AAC3F,UAAM,KAAK,GAAG,MAAM,sBAAsB,QAAQ,eAAe,IAAI;AACrE,UAAM,KAAK,GAAG,MAAM,iBAAiB,QAAQ,WAAW,IAAI;AAG5D,UAAM,KAAK,GAAG,MAAM,2BAA2B,QAAQ,sBAAsB,QAAQ,CAAC,CAAC,IAAI;AAG3F,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,GAAG;AAC7D,YAAM,KAAK,GAAG,MAAM,gBAAgB,KAAK,YAAY,IAAI,EAAE;AAAA,IAC7D;AAGA,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,eAAe,GAAG;AACnE,YAAM,KAAK,GAAG,MAAM,sBAAsB,KAAK,YAAY,IAAI,EAAE;AAAA,IACnE;AAEA,WAAO;AAAA,EACT;AACF;;;AC7IO,IAAM,mBAAN,MAAuB;AAAA,EAQ5B,YAAY,kBAAqC,SAAmC;AAJpF,SAAQ,YAAqB;AAC7B,SAAQ,eAAuB;AAI7B,SAAK,mBAAmB;AACxB,SAAK,UAAU;AAAA,MACb,MAAM,SAAS,QAAQ;AAAA,MACvB,MAAM,SAAS,QAAQ;AAAA,MACvB,aAAa,SAAS,eAAe;AAAA,MACrC,QAAQ,SAAS,UAAU;AAAA,MAC3B,YAAY,SAAS,cAAc;AAAA,MACnC,YAAY,SAAS,cAAc;AAAA,MACnC,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AAEA,QAAI;AAGF,YAAM,OAAO,UAAQ,MAAM;AAE3B,WAAK,SAAS,KAAK,aAAa,KAAK,cAAc,KAAK,IAAI,CAAC;AAE7D,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,aAAK,OAAO,OAAO,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,MAAM;AAC7D,eAAK,YAAY;AACjB,kBAAQ;AAAA,YACN,uDAAuD,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,WAAW;AAAA,UAC1H;AACA,kBAAQ;AAAA,QACV,CAAC;AAED,aAAK,OAAO,GAAG,SAAS,CAAC,UAAe;AACtC,iBAAO,IAAI,MAAM,8CAA8C,MAAM,OAAO,EAAE,CAAC;AAAA,QACjF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,OAAY;AACnB,YAAM,IAAI,MAAM,wDAAwD,MAAM,OAAO,EAAE;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAK,OAAO,MAAM,CAAC,UAAe;AAChC,YAAI,OAAO;AACT,iBAAO,IAAI,MAAM,6CAA6C,MAAM,OAAO,EAAE,CAAC;AAAA,QAChF,OAAO;AACL,eAAK,YAAY;AACjB,kBAAQ,IAAI,mCAAmC;AAC/C,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,KAAU,KAAgB;AAC9C,SAAK;AAGL,QAAI,KAAK,QAAQ,YAAY;AAC3B,UAAI,UAAU,+BAA+B,GAAG;AAChD,UAAI,UAAU,gCAAgC,cAAc;AAC5D,UAAI,UAAU,gCAAgC,6BAA6B;AAE3E,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,IAAI,WAAW,OAAO;AACxB,UAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,UAAI,IAAI,oBAAoB;AAC5B;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,YAAY,KAAK,QAAQ,UAAU;AAClD,YAAM,aAAa,IAAI,QAAQ;AAE/B,UAAI,CAAC,cAAc,CAAC,KAAK,aAAa,UAAU,GAAG;AACjD,YAAI,UAAU,KAAK;AAAA,UACjB,gBAAgB;AAAA,UAChB,oBAAoB;AAAA,QACtB,CAAC;AACD,YAAI,IAAI,cAAc;AACtB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,MAAM,IAAI;AAEhB,QAAI,QAAQ,KAAK,QAAQ,aAAa;AACpC,WAAK,cAAc,KAAK,GAAG;AAAA,IAC7B,WAAW,QAAQ,KAAK,QAAQ,YAAY;AAC1C,WAAK,aAAa,KAAK,GAAG;AAAA,IAC5B,WAAW,QAAQ,KAAK;AACtB,WAAK,WAAW,KAAK,GAAG;AAAA,IAC1B,OAAO;AACL,UAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,UAAI,IAAI,WAAW;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,MAAW,KAAgB;AAC/C,QAAI;AACF,WAAK,iBAAiB,oBAAI,KAAK;AAE/B,YAAM,WAAW,KAAK,iBAAiB,YAAY;AACnD,YAAM,UAAU,SAAS,WAAW;AACpC,YAAM,mBAAmB,SAAS,iBAAiB,SAAS,KAAK,QAAQ,MAAM;AAG/E,YAAM,gBAAgB,KAAK,iBAAiB;AAC5C,YAAM,cAAc,mBAAmB,OAAO;AAE9C,UAAI,UAAU,KAAK,EAAE,gBAAgB,4BAA4B,CAAC;AAClE,UAAI,IAAI,WAAW;AAAA,IACrB,SAAS,OAAY;AACnB,cAAQ,MAAM,+CAA+C,KAAK;AAClE,UAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,UAAI,IAAI,uBAAuB;AAAA,IACjC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAW,KAAgB;AAC9C,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA,MACR,QAAQ,QAAQ,OAAO;AAAA,MACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,SAAS;AAAA,QACP,cAAc,KAAK;AAAA,QACnB,gBAAgB,KAAK,gBAAgB,YAAY;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,MAAW,KAAgB;AAC5C,UAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAkBU,KAAK,QAAQ,WAAW,KAAK,KAAK,QAAQ,WAAW;AAAA;AAAA;AAAA;AAAA,2BAIrD,KAAK,QAAQ,UAAU,KAAK,KAAK,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAM9D,KAAK,QAAQ,IAAI;AAAA,gBACjB,KAAK,QAAQ,IAAI;AAAA,0BACP,KAAK,QAAQ,MAAM;AAAA,wBACrB,KAAK,QAAQ,UAAU;AAAA,0BACrB,KAAK,QAAQ,WAAW,YAAY,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBASnD,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI;AAAA,qBACtC,KAAK,QAAQ,WAAW;AAAA,EAC3C,KAAK,QAAQ,WAAW;AAAA,mBACP,KAAK,QAAQ,QAAQ;AAAA,mBACrB,KAAK,QAAQ,QAAQ,MAAM,EAAE;AAAA;AAAA;AAAA;AAAA,MAI1C,KAAK;AAEP,QAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,QAAI,IAAI,IAAI;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,YAA6B;AAChD,QAAI;AACF,YAAM,oBAAoB,WAAW,MAAM,GAAG,EAAE,CAAC;AACjD,YAAM,cAAc,OAAO,KAAK,mBAAmB,QAAQ,EAAE,SAAS,OAAO;AAC7E,YAAM,CAAC,UAAU,QAAQ,IAAI,YAAY,MAAM,GAAG;AAElD,aAAO,aAAa,KAAK,QAAQ,YAAY,aAAa,KAAK,QAAQ;AAAA,IACzE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAA2B;AACjC,UAAM,SAAS,KAAK,QAAQ;AAC5B,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,QAAkB,CAAC;AAGzB,UAAM,KAAK,UAAU,MAAM,iDAAiD;AAC5E,UAAM,KAAK,UAAU,MAAM,gCAAgC;AAC3D,UAAM,KAAK,GAAG,MAAM,0BAA0B,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,EAAE;AACxF,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,UAAU,MAAM,mEAAmE;AAC9F,UAAM,KAAK,UAAU,MAAM,gCAAgC;AAC3D,UAAM,KAAK,GAAG,MAAM,0BAA0B,KAAK,YAAY,IAAI,SAAS,EAAE;AAC9E,UAAM,KAAK,EAAE;AAGb,QAAI,KAAK,gBAAgB;AACvB,YAAM,oBAAoB,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK,eAAe,QAAQ,KAAK,GAAI;AACxF,YAAM,KAAK,UAAU,MAAM,+DAA+D;AAC1F,YAAM,KAAK,UAAU,MAAM,mCAAmC;AAC9D,YAAM,KAAK,GAAG,MAAM,+BAA+B,iBAAiB,IAAI,SAAS,EAAE;AACnF,YAAM,KAAK,EAAE;AAAA,IACf;AAGA,UAAM,MAAM,QAAQ,YAAY;AAChC,UAAM,KAAK,UAAU,MAAM,mDAAmD;AAC9E,UAAM,KAAK,UAAU,MAAM,4BAA4B;AACvD,UAAM,KAAK,GAAG,MAAM,oCAAoC,IAAI,GAAG,IAAI,SAAS,EAAE;AAC9E,UAAM,KAAK,GAAG,MAAM,0CAA0C,IAAI,SAAS,IAAI,SAAS,EAAE;AAC1F,UAAM,KAAK,GAAG,MAAM,yCAAyC,IAAI,QAAQ,IAAI,SAAS,EAAE;AACxF,UAAM,KAAK,GAAG,MAAM,yCAAyC,IAAI,QAAQ,IAAI,SAAS,EAAE;AACxF,UAAM,KAAK,EAAE;AAEb,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,WAQE;AACA,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,MACnB,gBAAgB,KAAK;AAAA,MACrB,QAAQ,QAAQ,OAAO;AAAA,MACvB,MAAM,KAAK,QAAQ;AAAA,MACnB,MAAM,KAAK,QAAQ;AAAA,MACnB,aAAa,KAAK,QAAQ;AAAA,IAC5B;AAAA,EACF;AACF;AAKO,SAAS,uBACd,kBACA,SACkB;AAClB,SAAO,IAAI,iBAAiB,kBAAkB,OAAO;AACvD;AAMO,IAAM,6BAA6B;AAAA,EACxC,WAAW;AAAA,IACT,OAAO;AAAA,IACP,MAAM,CAAC,OAAO,aAAa,UAAU;AAAA,IACrC,UAAU;AAAA,IACV,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACzaO,IAAM,kBAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,aAAmB;AAAA,EAC9B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AACf;AAKO,IAAM,eAAqB;AAAA,EAChC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,gBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,cAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,UAAoC;AACpE,UAAQ,SAAS,YAAY,GAAG;AAAA,IAC9B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,iBAAiB,MAAc,aAA2B,aAA4B;AACpG,SAAO;AAAA,IACL;AAAA,IACA,aAAa,eAAe,gBAAgB,IAAI;AAAA,IAChD;AAAA,EACF;AACF;;;ACrGO,IAAM,cAAN,MAA0C;AAAA,EAG/C,YAAY,OAAa,YAAY;AACnC,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,YAAiC;AAC7C,WAAO,KAAK,KAAK,YAAY,SAAS,UAAU;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,aAAoC;AACpD,WAAO,YAAY,MAAM,gBAAc,KAAK,cAAc,UAAU,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,aAAoC;AACnD,WAAO,YAAY,KAAK,gBAAc,KAAK,cAAc,UAAU,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,WAAO,EAAE,GAAG,KAAK,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,MAAkB;AACxB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA+B;AAC7B,WAAO,CAAC,GAAG,KAAK,KAAK,WAAW;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,UAAsC;AACnD,QAAI,CAAC,KAAK,cAAc,cAAc,GAAG;AACvC,aAAO,CAAC;AAAA,IACV;AACA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,kBAAkB,MAAyB;AACzD,SAAO,IAAI,YAAY,IAAI;AAC7B;;;ACrEO,SAAS,aAAa,YAAoB,UAA4B;AAE3E,QAAM,UAAU,WAAW,QAAQ,UAAU,EAAE;AAG/C,MAAI,CAAC,cAAc,KAAK,OAAO,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM;AACV,MAAI,SAAS;AAGb,WAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,QAAI,QAAQ,SAAS,QAAQ,CAAC,GAAG,EAAE;AAEnC,QAAI,QAAQ;AACV,eAAS;AACT,UAAI,QAAQ,GAAG;AACb,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,WAAO;AACP,aAAS,CAAC;AAAA,EACZ;AAEA,SAAO,MAAM,OAAO;AACtB;AAKO,SAAS,aAAa,MAAc,UAA4B;AAErE,QAAM,UAAU,KAAK,QAAQ,OAAO,EAAE,EAAE,YAAY;AAGpD,MAAI,CAAC,mCAAmC,KAAK,OAAO,GAAG;AACrD,WAAO;AAAA,EACT;AAGA,QAAM,UAAkC;AAAA,IACtC,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAC5D,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,IAAI,IAAI;AAAA,EACtC;AAEA,QAAM,cAAc,QAAQ,UAAU,GAAG,CAAC;AAC1C,QAAM,iBAAiB,QAAQ,WAAW;AAE1C,MAAI,CAAC,kBAAkB,QAAQ,WAAW,gBAAgB;AACxD,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,QAAQ,UAAU,CAAC,IAAI,QAAQ,UAAU,GAAG,CAAC;AAGhE,QAAM,gBAAgB,WAAW;AAAA,IAAQ;AAAA,IAAU,CAAC,UACjD,KAAK,WAAW,CAAC,IAAI,IAAI,SAAS;AAAA,EACrC;AAGA,SAAO,MAAM,aAAa,MAAM;AAClC;AAKA,SAAS,MAAM,QAAwB;AACrC,MAAI,YAAY;AAChB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,iBAAa,YAAY,KAAK,SAAS,OAAO,CAAC,GAAG,EAAE,KAAK;AAAA,EAC3D;AACA,SAAO;AACT;AAKO,SAAS,aAAa,MAAc,UAA4B;AACrE,QAAM,UAAU,KAAK,QAAQ,OAAO,EAAE,EAAE,YAAY;AAGpD,MAAI,CAAC,sCAAsC,KAAK,OAAO,GAAG;AACxD,WAAO;AAAA,EACT;AAGA,QAAM,kBAAkB,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AACjE,QAAM,SAAS,QAAQ,UAAU,GAAG,CAAC;AAErC,SAAO,CAAC,gBAAgB,SAAS,MAAM;AACzC;AAKO,SAAS,YAAY,KAAa,UAA4B;AACnE,QAAM,UAAU,IAAI,QAAQ,UAAU,EAAE;AAExC,MAAI,CAAC,WAAW,KAAK,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AAGA,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,WAAO,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK,KAAK;AAAA,EAC1C;AAEA,QAAM,aAAa,KAAM,MAAM;AAC/B,QAAM,qBAAqB,eAAe,KAAK,IAAI;AAEnD,SAAO,uBAAuB,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK,eAAe;AAC3E;AAKO,SAAS,mBAAmB,UAAkB,UAA4B;AAC/E,QAAM,UAAU,SAAS,QAAQ,OAAO,EAAE,EAAE,YAAY;AAGxD,SAAO,UAAU,KAAK,OAAO,KAAK,eAAe,KAAK,OAAO;AAC/D;AAKO,SAAS,YAAY,KAAa,UAA4B;AACnE,QAAM,UAAU,IAAI,QAAQ,UAAU,EAAE;AAExC,MAAI,CAAC,UAAU,KAAK,OAAO,GAAG;AAC5B,WAAO;AAAA,EACT;AAGA,QAAM,OAAO,QAAQ,UAAU,GAAG,CAAC;AACnC,QAAM,QAAQ,QAAQ,UAAU,GAAG,CAAC;AACpC,QAAM,SAAS,QAAQ,UAAU,GAAG,CAAC;AAGrC,MAAI,SAAS,SAAS,SAAS,SAAS,SAAS,MAAM,EAAE,KAAK,KAAK;AACjE,WAAO;AAAA,EACT;AAGA,MAAI,UAAU,QAAQ,WAAW,QAAQ;AACvC,WAAO;AAAA,EACT;AAGA,QAAM,cAAc;AAAA,IAAC;AAAA,IAAa;AAAA,IAAa;AAAA,IAAa;AAAA,IACtC;AAAA,IAAa;AAAA,IAAa;AAAA,IAAa;AAAA,IAAa;AAAA,EAAW;AAErF,SAAO,CAAC,YAAY,SAAS,OAAO;AACtC;AAKO,SAAS,iBAAiB,UAAkB,UAA4B;AAC7E,QAAM,UAAU,SAAS,QAAQ,UAAU,EAAE;AAC7C,SAAO,UAAU,KAAK,OAAO;AAC/B;AAKO,SAAS,aAAa,MAAc,SAA0B;AAEnE,QAAM,gBAAgB;AAAA,IACpB;AAAA,IAAW;AAAA,IAAW;AAAA,IAAW;AAAA,IAAO;AAAA,IAAO;AAAA,IAC/C;AAAA,IAAU;AAAA,IAAW;AAAA,IAAa;AAAA,IAAY;AAAA,IAAU;AAAA,IAAY;AAAA,IACpE;AAAA,IAAW;AAAA,IAAY;AAAA,IAAS;AAAA,IAAS;AAAA,IAAO;AAAA,IAChD;AAAA,IAAQ;AAAA,IAAU;AAAA,IAAa;AAAA,IAAW;AAAA,IAAY;AAAA,IACtD;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAM;AAAA,IAAO;AAAA,IAAS;AAAA,IAAQ;AAAA,EACnD;AAEA,QAAM,YAAY,KAAK,YAAY;AAGnC,MAAI,cAAc,KAAK,UAAQ,UAAU,SAAS,IAAI,CAAC,GAAG;AACxD,WAAO;AAAA,EACT;AAGA,MAAI,SAAS,KAAK,YAAY,KAAK,KAAK,UAAU,GAAG;AACnD,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,QAAQ,YAAY;AACzC,MACE,aAAa,SAAS,UAAU,KAChC,aAAa,SAAS,WAAW,KACjC,aAAa,SAAS,cAAc,GACpC;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,SAAS,cAAc,OAAe,UAA4B;AAEvE,QAAM,aAAa;AAEnB,MAAI,CAAC,WAAW,KAAK,KAAK,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,QAAM,CAAC,OAAO,MAAM,IAAI,MAAM,MAAM,GAAG;AAGvC,MAAI,MAAM,SAAS,MAAM,OAAO,SAAS,KAAK;AAC5C,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACpPO,IAAM,mBAAiC;AAAA,EAC5C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;;;AC3CO,IAAM,oBAAkC;AAAA,EAC7C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,aAAa,KAAK;AAAA,IACxC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,aAAa,KAAK;AAAA,IACxC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,iBAAiB,KAAK;AAAA,IAC5C,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,UAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,YAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAClE,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,eAAO,SAAS,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC;AAAA,MACvC;AACA,YAAM,cAAc,KAAM,MAAM,MAAO;AACvC,aAAO,eAAe,SAAS,MAAM,EAAE,CAAC;AAAA,IAC1C;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AACpB,YAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,aAAO,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,UAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAI,SAAS;AACb,eAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9B,qBAAW,KAAK,WAAW,CAAC,IAAI,IAAI,SAAS;AAAA,QAC/C,OAAO;AACL,oBAAU;AAAA,QACZ;AAAA,MACF;AAGA,UAAI,MAAM;AACV,UAAI,YAAY;AAChB,eAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,YAAI,QAAQ,SAAS,OAAO,CAAC,CAAC;AAC9B,YAAI,WAAW;AACb,mBAAS;AACT,cAAI,QAAQ,EAAG,UAAS;AAAA,QAC1B;AACA,eAAO;AACP,oBAAY,CAAC;AAAA,MACf;AAEA,YAAM,cAAc,KAAM,MAAM,MAAO;AACvC,aAAO,eAAe,SAAS,MAAM,EAAE,CAAC;AAAA,IAC1C;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,UAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI;AACJ,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9B,kBAAQ,SAAS,IAAI;AAAA,QACvB,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,kBAAQ,KAAK,WAAW,CAAC,IAAI;AAAA,QAC/B,OAAO;AACL,iBAAO;AAAA,QACT;AAGA,YAAI,IAAI,MAAM,GAAG;AACf,mBAAS;AAAA,QACX;AAGA,eAAO,KAAK,MAAM,QAAQ,EAAE,IAAK,QAAQ;AAAA,MAC3C;AAEA,YAAM,cAAc,KAAM,MAAM,MAAO;AACvC,aAAO,eAAe,SAAS,MAAM,CAAC,CAAC;AAAA,IACzC;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,UAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,YAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACjC,UAAI,MAAM;AAEV,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI;AACJ,YAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9B,kBAAQ,SAAS,IAAI;AAAA,QACvB,OAAO;AACL,kBAAQ,KAAK,WAAW,CAAC,IAAI;AAAA,QAC/B;AACA,eAAO,QAAQ,QAAQ,CAAC;AAAA,MAC1B;AAEA,YAAM,cAAc,KAAM,MAAM,MAAO;AACvC,aAAO,eAAe,SAAS,MAAM,CAAC,CAAC;AAAA,IACzC;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,UAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAI,SAAS;AACb,iBAAW,QAAQ,OAAO;AACxB,YAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9B,oBAAU;AAAA,QACZ,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,qBAAW,KAAK,WAAW,CAAC,IAAI,IAAI,SAAS;AAAA,QAC/C,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AAGA,YAAM,cAAc,SAAS,OAAO,MAAM,EAAE,CAAC;AAC7C,YAAM,aAAa,OAAO,MAAM,GAAG,EAAE;AAGrC,UAAI,YAAY;AAChB,iBAAW,SAAS,YAAY;AAC9B,qBAAa,YAAY,KAAK,SAAS,KAAK,KAAK;AAAA,MACnD;AAEA,YAAM,aAAa,KAAK;AACxB,aAAO,eAAe;AAAA,IACxB;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;;;ACtOO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,YAAY,KAAK;AAAA,IACvC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,mBAAmB,KAAK;AAAA,IAC9C,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,aAAa,KAAK;AAAA,IACxC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU,YAAY,KAAK;AAAA,IACvC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW,CAAC,QAAgB,YAAoB;AAC9C,aAAO,oDAAoD,KAAK,OAAO;AAAA,IACzE;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW,CAAC,QAAgB,YAAoB;AAC9C,aAAO,mDAAmD,KAAK,OAAO;AAAA,IACxE;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW,CAAC,QAAgB,YAAoB;AAC9C,aAAO,kCAAkC,KAAK,OAAO;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,aAAO,OAAO,WAAW,MAAM,WAAW,KAAK,MAAM;AAAA,IACvD;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,YAAM,cAAc,QAAQ,UAAU,GAAG,CAAC,EAAE,YAAY;AACxD,YAAM,iBAAiB,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAE9L,UAAI,CAAC,eAAe,SAAS,WAAW,GAAG;AACzC,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,QAAQ,UAAU,CAAC;AAGlC,UAAI,gBAAgB,MAAM;AAExB,eAAO,kBAAkB,KAAK,MAAM;AAAA,MACtC,WAAW,gBAAgB,MAAM;AAE/B,eAAO,UAAU,KAAK,MAAM;AAAA,MAC9B,WAAW,gBAAgB,MAAM;AAE/B,eAAO,qBAAqB,KAAK,MAAM;AAAA,MACzC;AAGA,aAAO,WAAW,KAAK,MAAM;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AACvC,aAAO,0BAA0B,KAAK,OAAO;AAAA,IAC/C;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AAEtC,UAAI,OAAO,WAAW,EAAG,QAAO;AAGhC,UAAI,OAAO,CAAC,MAAM,IAAK,QAAO;AAG9B,YAAM,cAAc,SAAS,OAAO,CAAC,CAAC;AACtC,UAAI,gBAAgB,KAAK,gBAAgB,EAAG,QAAO;AAGnD,UAAI,cAAc,KAAK,MAAM,EAAG,QAAO;AAEvC,aAAO;AAAA,IACT;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AAEtC,UAAI,OAAO,WAAW,EAAG,QAAO;AAGhC,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,QAAQ,SAAS,OAAO,CAAC,CAAC;AAG9B,YAAI,IAAI,MAAM,GAAG;AACf,mBAAS;AACT,cAAI,QAAQ,GAAG;AACb,qBAAS;AAAA,UACX;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,OAAO;AAAA,IACtB;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;;;ACrQO,IAAM,kBAAgC;AAAA,EAC3C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;;;ACjEO,IAAM,kBAAgC;AAAA,EAC3C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,YAAM,WAAW,CAAC,WAAW,aAAa,iBAAiB;AAC3D,aAAO,CAAC,SAAS,SAAS,KAAK,KAAK,CAAC,MAAM,WAAW,UAAU,KAAK,CAAC,MAAM,WAAW,KAAK;AAAA,IAC9F;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,CAAC,UAAU;AAEpB,aAAO,UAAU,SAAS,CAAC,MAAM,WAAW,OAAO;AAAA,IACrD;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAW,CAAC,QAAgB,YAAoB;AAC9C,aAAO,8CAA8C,KAAK,OAAO;AAAA,IACnE;AAAA,EACF;AACF;;;ACvDO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAGnD,QAAI,CAAC,+CAA+C,KAAK,OAAO,GAAG;AACjE,aAAO;AAAA,IACT;AAGA,QAAI,yCAAyC,KAAK,KAAK,GAAG;AACxD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAGnD,QAAI,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO;AAGnC,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,UAAU,KAAK,KAAK,EAAG,QAAO;AAGnC,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAGnD,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,WAAW,SAAS,EAAG,QAAO;AAGzC,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAGnD,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,cAAc,KAAK,KAAK,EAAG,QAAO;AAGvC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,WAAW,KAAK,KAAK,EAAG,QAAO;AAGpC,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,GAAI,QAAO;AAG3D,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,GAAI,QAAO;AAG3D,WAAO,oEAAoE,KAAK,OAAO;AAAA,EACzF;AACF;AAOO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,YAAY,EAAE,SAAS,OAAO,EAAG,QAAO;AAGnD,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAGO,IAAM,yBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC7NO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,iBAAiB,+CAA+C,KAAK,OAAO;AAElF,UAAM,cAAc,YAAY,KAAK,KAAK;AAC1C,WAAO,kBAAkB;AAAA,EAC3B;AACF;AAMO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,OAAO,SAAS,KAAK;AAE3B,UAAM,aAAc,QAAQ,OAAO,QAAQ;AAE3C,UAAM,iBAAiB,2CAA2C,KAAK,OAAO;AAC9E,WAAO,cAAc;AAAA,EACvB;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAE9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,0DAA0D,KAAK,OAAO,GAAG;AAC5E,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AACzC,QAAI,MAAM;AACV,aAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,UAAI,QAAQ,OAAO,CAAC;AACpB,WAAK,OAAO,SAAS,KAAK,MAAM,GAAG;AACjC,iBAAS;AACT,YAAI,QAAQ,EAAG,UAAS;AAAA,MAC1B;AACA,aAAO;AAAA,IACT;AACA,UAAM,cAAc,KAAM,MAAM,MAAO;AACvC,WAAO,eAAe,OAAO,OAAO,SAAS,CAAC;AAAA,EAChD;AACF;AAMO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAE9C,UAAM,oBAAoB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC9G,QAAI,CAAC,kBAAkB,SAAS,MAAM,CAAC,EAAE,YAAY,CAAC,GAAG;AACvD,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,MAAM,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,MAAM;AACtD,UAAM,OAAO,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC;AAC7C,UAAM,QAAQ,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK;AACnD,UAAM,cAAc,OAAO,QAAQ;AAEnC,WAAO,eAAe,OAAO,CAAC;AAAA,EAChC;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,iBAAiB,+CAA+C,KAAK,OAAO;AAElF,UAAM,aAAa,MAAM,UAAU;AAEnC,UAAM,aAAa,wBAAwB,KAAK,KAAK;AACrD,WAAO,kBAAkB,cAAc;AAAA,EACzC;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAMO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAU;AACpB,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AAEtC,QAAI,OAAO,WAAW,GAAI,QAAO;AAGjC,UAAM,MAAM,SAAS,OAAO,UAAU,GAAG,CAAC,CAAC;AAC3C,UAAM,QAAQ,SAAS,OAAO,UAAU,GAAG,CAAC,CAAC;AAI7C,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAChC,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAGpC,QAAI,MAAM;AACV,UAAM,UAAU,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE3C,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,SAAS,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC;AAAA,IACxC;AAEA,UAAM,aAAa,KAAM,MAAM;AAC/B,UAAM,qBAAqB,eAAe,KAAK,IAAI,eAAe,KAAK,IAAI;AAE3E,WAAO,uBAAuB,SAAS,OAAO,CAAC,CAAC;AAAA,EAClD;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAU;AAEpB,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,UAAM,cAAc,QAAQ,UAAU,GAAG,CAAC,EAAE,YAAY;AACxD,UAAM,iBAAiB;AAAA,MACrB;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MACtD;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MACtD;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,IACpE;AAEA,QAAI,CAAC,eAAe,SAAS,WAAW,GAAG;AACzC,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,WAAO,cAAc,KAAK,MAAM;AAAA,EAClC;AACF;AAGO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACrfO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,mBAAmB,sDAAsD,KAAK,OAAO;AAE3F,UAAM,cAAc,MAAM,WAAW,KAAK,MAAM,WAAW;AAC3D,WAAO,oBAAoB;AAAA,EAC7B;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wBAAwB,KAAK,OAAO;AAAA,EAC7C;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAQO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAE9C,QAAI,MAAM,WAAW,KAAK,GAAG;AAE3B,aAAO,MAAM,UAAU,MAAM,MAAM,UAAU;AAAA,IAC/C,OAAO;AAEL,YAAM,eAAe,WAAW,KAAK,KAAK;AAC1C,YAAM,eAAe,cAAc,KAAK,KAAK;AAE7C,aAAO,gBAAgB;AAAA,IACzB;AAAA,EACF;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,gBAAgB,sCAAsC,KAAK,OAAO;AACxE,WAAO,iBAAiB,MAAM,WAAW,MAAM;AAAA,EACjD;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,gBAAgB,oCAAoC,KAAK,OAAO;AACtE,WAAO,iBAAiB,MAAM,WAAW;AAAA,EAC3C;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,gBAAgB,oCAAoC,KAAK,OAAO;AACtE,WAAO,iBAAiB,MAAM,UAAU,MAAM,MAAM,UAAU;AAAA,EAChE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,WAAO,MAAM,UAAU,KAAK,MAAM,UAAU;AAAA,EAC9C;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,cAAc,kDAAkD,KAAK,OAAO;AAElF,QAAI,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AAC9C,YAAM,QAAQ,MAAM,MAAM,QAAQ;AAClC,YAAM,QAAQ,SAAS,MAAM,CAAC,CAAC;AAC/B,aAAO,eAAe,SAAS,KAAK,SAAS;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8DAA8D,KAAK,OAAO;AAAA,EACnF;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAkB;AAC5B,WAAO,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW;AAAA,EACpD;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAGO,IAAMC,qBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACrfO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAE9C,WAAO,gCAAgC,KAAK,OAAO;AAAA,EACrD;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,WAAW;AACjB,WAAO,CAAC,SAAS,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,OAAO;AAAA,EACxD;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAE9C,UAAM,WAAW;AACjB,WAAO,CAAC,SAAS,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,EAClD;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,UAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAE9C,WAAO,iCAAiC,KAAK,OAAO;AAAA,EACtD;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8BAA8B,KAAK,OAAO;AAAA,EACnD;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sBAAsB,KAAK,OAAO;AAAA,EAC3C;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,WAAO,MAAM,UAAU,MAAM,cAAc,KAAK,KAAK;AAAA,EACvD;AACF;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kCAAkC,KAAK,OAAO;AAAA,EACvD;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oCAAoC,KAAK,OAAO;AAAA,EACzD;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mCAAmC,KAAK,OAAO;AAAA,EACxD;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uBAAuB,KAAK,OAAO;AAAA,EAC5C;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yBAAyB,KAAK,OAAO;AAAA,EAC9C;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,WAAW;AACjB,WAAO,CAAC,SAAS,KAAK,KAAK;AAAA,EAC7B;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,WAAW;AACjB,WAAO,CAAC,SAAS,KAAK,KAAK,KAAK,MAAM,UAAU;AAAA,EAClD;AACF;AAGO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC3cO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAKO,IAAM,SAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAGO,IAAM,gBAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC9PO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,kBAAkB,6DAA6D,KAAK,OAAO;AAEjG,UAAM,cAAc,+BAA+B,KAAK,KAAK;AAC7D,WAAO,mBAAmB;AAAA,EAC5B;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iEAAiE,KAAK,OAAO;AAAA,EACtF;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAKO,IAAM,UAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAKO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,kBAAkB,8CAA8C,KAAK,OAAO;AAClF,UAAM,YAAY,MAAM,UAAU;AAClC,WAAO,mBAAmB;AAAA,EAC5B;AACF;AAGO,IAAM,oBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACpTO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,cAAc,6DAA6D,KAAK,OAAO;AAE7F,UAAM,WAAW,SAAS,MAAM,QAAQ,UAAU,EAAE,CAAC;AACrD,WAAO,eAAe,YAAY;AAAA,EACpC;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+DAA+D,KAAK,OAAO;AAAA,EACpF;AACF;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iEAAiE,KAAK,OAAO;AAAA,EACtF;AACF;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oEAAoE,KAAK,OAAO;AAAA,EACzF;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAGO,IAAM,aAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACjUO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAGO,IAAM,oBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACtJO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAE9C,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gCAAgC,KAAK,OAAO;AAAA,EACrD;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qCAAqC,KAAK,OAAO;AAAA,EAC1D;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAGO,IAAM,iBAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1LO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kCAAkC,KAAK,OAAO;AAAA,EACvD;AACF;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAGO,IAAM,mBAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACtLO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kCAAkC,KAAK,OAAO;AAAA,EACvD;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAKO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAkB;AAE5B,WAAO,kBAAkB,KAAK,KAAK;AAAA,EACrC;AACF;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAKO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAKO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mCAAmC,KAAK,OAAO;AAAA,EACxD;AACF;AAGO,IAAM,wBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzNO,IAAM,MAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAkB;AAE5B,WAAO,MAAM,WAAW,MAAM,wBAAwB,KAAK,KAAK;AAAA,EAClE;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oCAAoC,KAAK,OAAO;AAAA,EACzD;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6BAA6B,KAAK,OAAO;AAAA,EAClD;AACF;AAKO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAKO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAKO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAKO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qCAAqC,KAAK,OAAO;AAAA,EAC1D;AACF;AAKO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAKO,IAAM,UAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAGO,IAAM,yBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACjMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAKO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAKO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAKO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAKO,IAAM,OAAmB;AAAA,EAC9B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAKO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAGO,IAAM,gBAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACvLO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,WAAO,OAAO,UAAU,KAAK,OAAO,UAAU,KAAK,iCAAiC,KAAK,OAAO;AAAA,EAClG;AACF;AAOO,IAAM,SAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,WAAO,OAAO,WAAW,KAAK,wDAAwD,KAAK,OAAO;AAAA,EACpG;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAOO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAKO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACjMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qCAAqC,KAAK,OAAO;AAAA,EAC1D;AACF;AAOO,IAAMC,cAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAMC,eAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAOO,IAAMC,sBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iCAAiC,KAAK,OAAO;AAAA,EACtD;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gCAAgC,KAAK,OAAO;AAAA,EACrD;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mCAAmC,KAAK,OAAO;AAAA,EACxD;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AACf;AAKO,IAAM,sBAAoC;AAAA,EAC/C;AAAA,EACAF;AAAA,EACA;AAAA,EACA;AAAA,EACAC;AAAA,EACAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACrNO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iFAAiF,KAAK,OAAO;AAAA,EACtG;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sFAAsF,KAAK,OAAO;AAAA,EAC3G;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oEAAoE,KAAK,OAAO;AAAA,EACzF;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4EAA4E,KAAK,OAAO;AAAA,EACjG;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4FAA4F,KAAK,OAAO;AAAA,EACjH;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sEAAsE,KAAK,OAAO;AAAA,EAC3F;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wEAAwE,KAAK,OAAO;AAAA,EAC7F;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAMO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gEAAgE,KAAK,OAAO;AAAA,EACrF;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wEAAwE,KAAK,OAAO;AAAA,EAC7F;AACF;AAGO,IAAM,4BAA0C;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AChPO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8DAA8D,KAAK,OAAO;AAAA,EACnF;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sEAAsE,KAAK,OAAO;AAAA,EAC3F;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2EAA2E,KAAK,OAAO;AAAA,EAChG;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uEAAuE,KAAK,OAAO;AAAA,EAC5F;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uEAAuE,KAAK,OAAO;AAAA,EAC5F;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mEAAmE,KAAK,OAAO;AAAA,EACxF;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAOO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAGO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACjLO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAOO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gFAAgF,KAAK,OAAO;AAAA,EACrG;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,gBAAgB,uFAAuF,KAAK,OAAO;AAGzH,UAAM,kBAAkB,gDAAgD,KAAK,OAAO;AAEpF,WAAO,iBAAiB,mBAAmB,MAAM,UAAU;AAAA,EAC7D;AACF;AAGO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC7OO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2EAA2E,KAAK,OAAO;AAAA,EAChG;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mEAAmE,KAAK,OAAO;AAAA,EACxF;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iEAAiE,KAAK,OAAO;AAAA,EACtF;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2EAA2E,KAAK,OAAO;AAAA,EAChG;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAOO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,WAAO,0EAA0E,KAAK,OAAO;AAAA,EAC/F;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAEtC,WAAO,wEAAwE,KAAK,OAAO;AAAA,EAC7F;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,6EAA6E,KAAK,OAAO;AAAA,EAClG;AACF;AAGO,IAAM,sBAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC7LO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AAErC,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAOO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0EAA0E,KAAK,OAAO;AAAA,EAC/F;AACF;AAOO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gFAAgF,KAAK,OAAO;AAAA,EACrG;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qEAAqE,KAAK,OAAO;AAAA,EAC1F;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yFAAyF,KAAK,OAAO;AAAA,EAC9G;AACF;AAOO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAOO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AAErC,WAAO,gEAAgE,KAAK,OAAO;AAAA,EACrF;AACF;AAGO,IAAM,oCAAkD;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACvLO,IAAM,UAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,SAAS,GAAG,EAAG,QAAO;AAEjC,UAAM,CAAC,UAAU,OAAO,IAAI,MAAM,MAAM,GAAG;AAC3C,QAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAI,QAAO;AACxD,QAAI,QAAQ,SAAS,KAAK,QAAQ,SAAS,EAAG,QAAO;AAGrD,WAAO,4EAA4E,KAAK,OAAO;AAAA,EACjG;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAOO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oEAAoE,KAAK,OAAO;AAAA,EACzF;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,mCAAmC,KAAK,OAAO;AAAA,EACxD;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,MAAM,EAAE;AACtC,QAAI,QAAQ,WAAW,GAAI,QAAO;AAGlC,QAAI,CAAC,eAAe,KAAK,OAAO,EAAG,QAAO;AAG1C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,eAAe,KAAK,KAAK,EAAG,QAAO;AAGxC,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,CAAC,MAAM,SAAS,GAAG,EAAG,QAAO;AAEjC,UAAM,CAAC,UAAU,EAAE,IAAI,MAAM,MAAM,GAAG;AACtC,QAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAI,QAAO;AACxD,QAAI,GAAG,WAAW,EAAG,QAAO;AAG5B,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,4BAA4B,KAAK,KAAK,EAAG,QAAO;AAGrD,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAI,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,GAAI,QAAO;AACxD,QAAI,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,EAAG,QAAO;AAGvD,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAGO,IAAM,iBAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxQO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,SAAS,KAAK,KAAK,EAAG,QAAO;AAGjC,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,kDAAkD,KAAK,OAAO,GAAG;AACpE,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,KAAK,KAAK,EAAG,QAAO;AAGhC,QAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,WAAO;AAAA,EACT;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,+BAA2C;AAAA,EACtD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAMO,IAAM,8BAA0C;AAAA,EACrD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAMO,IAAM,+BAA2C;AAAA,EACtD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,8BAA0C;AAAA,EACrD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,8BAA0C;AAAA,EACrD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+DAA+D,KAAK,OAAO;AAAA,EACpF;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yEAAyE,KAAK,OAAO;AAAA,EAC9F;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uFAAuF,KAAK,OAAO;AAAA,EAC5G;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,8BAA0C;AAAA,EACrD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAEO,IAAM,kBAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACv/BO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,MAAM,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAEnD,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,CAAC,MAAM,WAAW,IAAI,EAAG,QAAO;AACpC,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAI7C,QAAI,MAAM,SAAS,IAAI,GAAG;AACxB,aAAO,MAAM,WAAW,MAAM,oBAAoB,KAAK,KAAK;AAAA,IAC9D;AAEA,UAAM,MAAM,MAAM;AAClB,QAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AAEjC,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,WAAO,MAAM,WAAW,KAAK,KAAK,MAAM,WAAW;AAAA,EACrD;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAEpC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAClC,QAAI,CAAC,QAAQ,KAAK,KAAK,EAAG,QAAO;AAEjC,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAElC,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAElC,WAAO,iEAAiE,KAAK,OAAO;AAAA,EACtF;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAElC,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAG,GAAG;AACzB,aAAO,MAAM,WAAW;AAAA,IAC1B;AACA,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO;AACnC,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,iEAAiE,KAAK,OAAO;AAAA,EACtF;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AAEjC,WAAO,8DAA8D,KAAK,OAAO;AAAA,EACnF;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAMO,IAAM,0BAAsC;AAAA,EACjD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,+CAA+C,KAAK,OAAO,GAAG;AACjE,aAAO;AAAA,IACT;AAGA,UAAM,MAAM,MAAM;AAClB,WAAO,OAAO,MAAM,OAAO;AAAA,EAC7B;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+DAA+D,KAAK,OAAO;AAAA,EACpF;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,uBAAuB,KAAK,KAAK,EAAG,QAAO;AAEhD,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAEpC,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAEO,IAAM,oBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxaO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,QAAQ,MAAM,QAAQ,OAAO,EAAE;AAErC,QAAI,CAAC,sBAAsB,KAAK,KAAK,EAAG,QAAO;AAE/C,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAE9C,QAAI,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO;AAEnC,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,EAAG,QAAO;AAEjD,QAAI,MAAM,CAAC,MAAM,IAAK,QAAO;AAE7B,WAAO;AAAA,EACT;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,EAAG,QAAO;AAEnC,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAI,CAAC,iBAAiB,KAAK,KAAK,EAAG,QAAO;AAE1C,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,4DAA4D,KAAK,OAAO;AAAA,EACjF;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAEO,IAAM,mBAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACvKO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AACzC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,KAAK,IAAI;AAAA,IAC1B;AACA,UAAM,aAAa,MAAM;AAEzB,QAAI,eAAe,OAAO,CAAC,EAAG,QAAO;AAErC,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAI/B,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC1C,QAAI,MAAM,OAAO,MAAM,IAAK,QAAO;AAEnC,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,2DAA2D,KAAK,OAAO;AAAA,EAChF;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+DAA+D,KAAK,OAAO;AAAA,EACpF;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAEnD,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAEO,IAAM,mBAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzIO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,YAAY,MAAM,UAAU,GAAG,CAAC;AACtC,UAAM,kBAAkB;AACxB,QAAI,CAAC,gBAAgB,KAAK,SAAS,EAAG,QAAO;AAE7C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAMO,IAAM,2BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAMO,IAAM,SAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,wDAAwD,KAAK,OAAO;AAAA,EAC7E;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,+DAA+D,KAAK,OAAO;AAAA,EACpF;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,6DAA6D,KAAK,OAAO;AAAA,EAClF;AACF;AAEO,IAAM,wBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACnNO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AAGtC,QAAI,OAAO,WAAW,MAAM,CAAC,OAAO,WAAW,KAAK,GAAG;AACrD,aAAO;AAAA,IACT;AAGA,WAAO,oEAAoE,KAAK,OAAO;AAAA,EACzF;AACF;AAQO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,QAAQ,KAAK,KAAK,EAAG,QAAO;AAGjC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAOO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAQO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,MAAM,CAAC,MAAM,IAAK,QAAO;AAG7B,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAOO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAQO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,uCAAuC,KAAK,OAAO,GAAG;AACzD,aAAO;AAAA,IACT;AAGA,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAQO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,QAAI,CAAC,sDAAsD,KAAK,OAAO,GAAG;AACxE,aAAO;AAAA,IACT;AAGA,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,WAAW,KAAK,WAAW,EAAG,QAAO;AAGzC,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAGO,IAAM,qBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC/OO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,kEAAkE,KAAK,OAAO,GAAG;AACpF,aAAO;AAAA,IACT;AAGA,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAOO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAOO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,sDAAsD,KAAK,OAAO;AAAA,EAC3E;AACF;AAOO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AAGrC,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO;AAGnC,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAQO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,2CAA2C,KAAK,OAAO,GAAG;AAC7D,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,SAAS,MAAM,CAAC,CAAC;AACjC,QAAI,YAAY,KAAK,YAAY,EAAG,QAAO;AAG3C,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAOO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,MAAM,WAAW,MAAM,EAAG,QAAO;AAGtC,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,kDAAkD,KAAK,OAAO;AAAA,EACvE;AACF;AAGO,IAAM,iBAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACvMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,gEAAgE,KAAK,OAAO;AAAA,EACrF;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAC1C,QAAI,QAAQ,WAAW,GAAI,QAAO;AAGlC,WAAO,4CAA4C,KAAK,OAAO;AAAA,EACjE;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,QAAI,CAAC,8CAA8C,KAAK,OAAO,GAAG;AAChE,aAAO;AAAA,IACT;AAGA,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AACzC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,KAAK,KAAK;AAAA,IAC3B;AACA,UAAM,cAAc,KAAM,MAAM,MAAO;AACvC,WAAO,eAAe,OAAO,EAAE;AAAA,EACjC;AACF;AAOO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAC1C,QAAI,QAAQ,WAAW,GAAI,QAAO;AAGlC,QAAI,CAAC,6DAA6D,KAAK,OAAO,GAAG;AAC/E,aAAO;AAAA,IACT;AAGA,UAAM,QAAQ,SAAS,QAAQ,UAAU,GAAG,CAAC,CAAC;AAC9C,UAAM,MAAM,SAAS,QAAQ,UAAU,GAAG,CAAC,CAAC;AAE5C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAC1C,QAAI,QAAQ,WAAW,GAAI,QAAO;AAGlC,WAAO,kEAAkE,KAAK,OAAO;AAAA,EACvF;AACF;AAOO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,WAAO,qEAAqE,KAAK,OAAO;AAAA,EAC1F;AACF;AAOO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,WAAW,KAAK,KAAK,EAAG,QAAO;AAGpC,WAAO,0DAA0D,KAAK,OAAO;AAAA,EAC/E;AACF;AAGO,IAAM,wBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC3KO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,EAAG,QAAO;AAEnC,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,MAAM,EAAE;AACrC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,QAAQ,MAAM,QAAQ,UAAU,EAAE;AAGxC,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,EAAG,QAAO;AAGjD,UAAM,OAAO,MAAM,MAAM,GAAG,EAAE;AAC9B,UAAM,aAAa,MAAM,MAAM,EAAE,EAAE,YAAY;AAE/C,QAAI,MAAM;AACV,QAAI,aAAa;AAEjB,aAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,aAAO,SAAS,KAAK,CAAC,CAAC,IAAI;AAC3B,mBAAa,eAAe,IAAI,IAAI,aAAa;AAAA,IACnD;AAEA,UAAM,YAAY,MAAM;AACxB,UAAM,gBAAgB,cAAc,IAAI,MAAM,cAAc,IAAI,MAAM,OAAO,KAAK,SAAS;AAE3F,QAAI,eAAe,cAAe,QAAO;AAEzC,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,MAAM,EAAE;AACrC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,wEAAwE,KAAK,OAAO;AAAA,EAC7F;AACF;AAMO,IAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,SAAS,MAAM,UAAU,GAAG,CAAC;AACnC,QAAI,CAAC,CAAC,MAAM,MAAM,MAAM,IAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAEvD,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,CAAC,MAAM,YAAY,EAAE,WAAW,IAAI,KAAK,CAAC,MAAM,YAAY,EAAE,WAAW,IAAI,GAAG;AAClF,aAAO;AAAA,IACT;AAEA,WAAO,qDAAqD,KAAK,OAAO;AAAA,EAC1E;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,CAAC,EAAE,YAAY;AAEpC,QAAI,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,EAAE,SAAS,MAAM,EAAG,QAAO;AAEnD,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,WAAW,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC/C,QAAI,WAAW,KAAK,WAAW,GAAI,QAAO;AAG1C,UAAM,aAAa,SAAS,MAAM,CAAC,CAAC;AACpC,QAAI,aAAa,KAAK,eAAe,EAAG,QAAO;AAE/C,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,UAAU,EAAE;AACzC,QAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAEO,IAAM,uBAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzPO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,UAAU,EAAE;AACzC,QAAI,OAAO,WAAW,GAAI,QAAO;AAEjC,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,iCAAiC,KAAK,OAAO;AAAA,EACtD;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,WAAW,MAAM,CAAC;AACxB,UAAM,SAAS,MAAM,CAAC;AAEtB,QAAI,SAAS,WAAW,KAAK,OAAO,WAAW,EAAG,QAAO;AAGzD,UAAM,QAAQ,SAAS,SAAS,UAAU,GAAG,CAAC,CAAC;AAC/C,UAAM,MAAM,SAAS,SAAS,UAAU,GAAG,CAAC,CAAC;AAG7C,UAAM,gBAAgB,QAAQ,KAAK,QAAQ,KAAK;AAChD,QAAI,gBAAgB,KAAK,gBAAgB,GAAI,QAAO;AACpD,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,aAAa,SAAS,MAAM,CAAC,CAAC;AACpC,QAAI,aAAa,KAAK,aAAa,EAAG,QAAO;AAG7C,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAMO,IAAM,4BAAwC;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAG1C,UAAM,gBAAgB,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK;AAC1E,QAAI,gBAAgB,KAAK,gBAAgB,GAAI,QAAO;AACpD,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO,mDAAmD,KAAK,OAAO;AAAA,EACxE;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC1C,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE5C,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAChC,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAEpC,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAEO,IAAM,wBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACvOO,IAAM,6BAAyC;AAAA,EACpD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,gDAAgD,KAAK,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,EAAG,QAAO;AAEnC,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAMO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,iDAAiD,KAAK,OAAO;AAAA,EACtE;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,QAAgB,YAAoB;AAC9C,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAEO,IAAM,kBAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC3HO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAGhC,UAAM,OAAO,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC3C,UAAM,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5C,UAAM,MAAM,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;AAE1C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO,yDAAyD,KAAK,OAAO;AAAA,EAC9E;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,qCAAqC,KAAK,OAAO;AAAA,EAC1D;AACF;AAMO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAEhC,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAEpC,WAAO,2CAA2C,KAAK,OAAO;AAAA,EAChE;AACF;AAMO,IAAM,wBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WAAO,yCAAyC,KAAK,OAAO;AAAA,EAC9D;AACF;AAEO,IAAM,sBAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC/GO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,kBAAkB,2CAA2C,KAAK,OAAO;AAC/E,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AAGzC,UAAM,cAAc,oBAAI,IAAoB;AAC5C,WAAO,QAAQ,OAAK,YAAY,IAAI,IAAI,YAAY,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AAErE,UAAM,SAAS,MAAM,KAAK,YAAY,OAAO,CAAC;AAC9C,UAAM,oBAAoB,OAAO,KAAK,OAAK,MAAM,KAAK,MAAM,CAAC;AAC7D,UAAM,cAAc,OAAO,MAAM,OAAK,KAAK,CAAC;AAE5C,WAAO,qBAAqB;AAAA,EAC9B;AACF;AAMO,IAAM,yBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,QAAI,CAAC,QAAQ,KAAK,OAAO,EAAG,QAAO;AAGnC,UAAM,OAAO,SAAS,QAAQ,UAAU,GAAG,CAAC,CAAC;AAC7C,QAAI,OAAO,GAAI,QAAO;AAGtB,UAAM,QAAQ,SAAS,QAAQ,UAAU,GAAG,CAAC,CAAC;AAC9C,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AAEpC,WAAO;AAAA,EACT;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE,EAAE,YAAY;AACxD,UAAM,UAAU;AAEhB,QAAI;AACJ,QAAI;AAEJ,QAAI,SAAS,KAAK,OAAO,GAAG;AAE1B,gBAAU,QAAQ,UAAU,GAAG,CAAC;AAChC,eAAS,QAAQ,CAAC;AAElB,YAAM,SAAS,QAAQ,CAAC,MAAM,MAAM,MAAM,QAAQ,CAAC,MAAM,MAAM,MAAM;AACrE,gBAAU,SAAS;AAAA,IACrB,OAAO;AAEL,gBAAU,QAAQ,UAAU,GAAG,CAAC;AAChC,eAAS,QAAQ,CAAC;AAAA,IACpB;AAEA,UAAM,MAAM,SAAS,OAAO;AAC5B,UAAM,iBAAiB,QAAQ,MAAM,EAAE;AAEvC,WAAO,WAAW;AAAA,EACpB;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,OAAO,MAAM,YAAY;AAG/B,UAAM,YAAY,KAAK,CAAC;AACxB,UAAM,cAAc;AACpB,QAAI,CAAC,YAAY,SAAS,SAAS,EAAG,QAAO;AAG7C,UAAM,MAAM,SAAS,KAAK,UAAU,GAAG,EAAE,CAAC;AAC1C,SAAK,MAAM,KAAK,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAK,QAAO;AAG5D,UAAM,SAAiC;AAAA,MACrC,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MACjF,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MACjF,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAI,KAAK;AAAA,MACjF,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,IACpD;AAEA,UAAM,UAAkC;AAAA,MACtC,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAC7E,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAAG,KAAK;AAAA,MAC7E,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAC7E,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,MAAI,KAAK;AAAA,IAC7D;AAEA,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,OAAO,KAAK,CAAC;AACnB,aAAO,IAAI,MAAM,IAAI,OAAO,IAAI,IAAI,QAAQ,IAAI;AAAA,IAClD;AAEA,UAAM,YAAY,OAAO,aAAa,KAAM,MAAM,EAAG;AACrD,WAAO,cAAc,KAAK,EAAE;AAAA,EAC9B;AACF;AAMO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,kBAAkB,0CAA0C,KAAK,OAAO;AAC9E,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AACzC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,KAAK,IAAI;AAAA,IAC1B;AACA,WAAO,OAAO,CAAC;AAEf,WAAO,MAAM,OAAO;AAAA,EACtB;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,kBAAkB,8BAA8B,KAAK,OAAO;AAClE,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC7C,UAAM,SAAS,MAAM,MAAM,EAAE,EAAE,IAAI,MAAM;AAEzC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,cAAc,KAAM,MAAM,MAAO;AACvC,WAAO,eAAe,OAAO,EAAE;AAAA,EACjC;AACF;AAQO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,UAAM,kBAAkB,mCAAmC,KAAK,OAAO;AACvE,QAAI,CAAC,gBAAiB,QAAO;AAK7B,WAAO,QAAQ,WAAW,MAAM,WAAW,KAAK,OAAO;AAAA,EACzD;AACF;AAMO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,QAAI,CAAC,SAAS,KAAK,OAAO,EAAG,QAAO;AAGpC,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACvC,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAE3C,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,aAAa,MAAM;AACzB,WAAO,eAAe,OAAO,CAAC;AAAA,EAChC;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,UAAM,kBAAkB,qCAAqC,KAAK,OAAO;AACzE,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAC3C,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAE3C,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC9B;AAEA,WAAO,MAAM,OAAO;AAAA,EACtB;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,OAAO,MAAM,YAAY;AAC/B,UAAM,SAAS,KAAK,CAAC;AACrB,UAAM,SAAS,KAAK,UAAU,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,MAAM;AACxD,UAAM,cAAc,KAAK,CAAC;AAG1B,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACpC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC9B;AAGA,UAAM,YAAY;AAClB,UAAM,YAAY;AAClB,UAAM,WAAW;AAEjB,QAAI;AACJ,QAAI,WAAW,OAAO,WAAW,KAAK;AACpC,uBAAiB,UAAU,MAAM,EAAE;AAAA,IACrC,WAAW,WAAW,OAAO,WAAW,KAAK;AAC3C,uBAAiB,UAAU,MAAM,EAAE;AAAA,IACrC,OAAO;AACL,uBAAiB,SAAS,MAAM,EAAE;AAAA,IACpC;AAEA,WAAO,gBAAgB;AAAA,EACzB;AACF;AAMO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AAGvC,UAAM,kBAAkB,mCAAmC,KAAK,OAAO;AACvE,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAC3C,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAI,UAAU,OAAO,CAAC,IAAI,QAAQ,CAAC;AACnC,aAAO,KAAK,MAAM,UAAU,EAAE,IAAK,UAAU;AAAA,IAC/C;AAEA,UAAM,cAAc,KAAM,MAAM,MAAO;AACvC,WAAO,eAAe,OAAO,EAAE;AAAA,EACjC;AACF;AAMO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAG1C,UAAM,kBAAkB,2BAA2B,KAAK,OAAO;AAC/D,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,cAAc,SAAS,QAAQ,CAAC,CAAC;AACvC,QAAI,cAAc,KAAK,cAAc,EAAG,QAAO;AAG/C,UAAM,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACnD,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAE3C,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC9B;AAEA,UAAM,cAAc,KAAM,MAAM,MAAO;AACvC,WAAO,eAAe,OAAO,EAAE;AAAA,EACjC;AACF;AAQO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAG1C,UAAM,kBAAkB,wCAAwC,KAAK,OAAO;AAC5E,QAAI,CAAC,gBAAiB,QAAO;AAG7B,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAC3C,QAAI,MAAM;AAEV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,QAAQ,OAAO,CAAC;AACpB,UAAI,IAAI,MAAM,GAAG;AACf,iBAAS;AACT,YAAI,QAAQ,EAAG,UAAS;AAAA,MAC1B;AACA,aAAO;AAAA,IACT;AAEA,WAAO,MAAM,OAAO;AAAA,EACtB;AACF;AAMO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAC1C,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAG3C,QAAI,IAAI,IAAI,MAAM,EAAE,SAAS,EAAG,QAAO;AAGvC,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,OAAO,CAAC,KAAK,KAAK;AAAA,IAC3B;AACA,QAAI,SAAS,KAAM,MAAM;AACzB,QAAI,UAAU,GAAI,UAAS;AAE3B,QAAI,WAAW,OAAO,CAAC,EAAG,QAAO;AAGjC,UAAM;AACN,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,KAAK,KAAK;AAAA,IAC3B;AACA,QAAI,SAAS,KAAM,MAAM;AACzB,QAAI,UAAU,GAAI,UAAS;AAE3B,WAAO,WAAW,OAAO,EAAE;AAAA,EAC7B;AACF;AAMO,IAAM,iBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,UAAU,MAAM,QAAQ,YAAY,EAAE;AAC5C,UAAM,SAAS,QAAQ,MAAM,EAAE,EAAE,IAAI,MAAM;AAG3C,UAAM,WAAW,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACpD,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,IAAI,SAAS,CAAC;AAAA,IAC/B;AACA,QAAI,SAAS,MAAM;AACnB,aAAS,SAAS,IAAI,IAAI,KAAK;AAE/B,QAAI,WAAW,OAAO,EAAE,EAAG,QAAO;AAGlC,UAAM,WAAW,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACvD,UAAM;AACN,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAO,OAAO,CAAC,IAAI,SAAS,CAAC;AAAA,IAC/B;AACA,QAAI,SAAS,MAAM;AACnB,aAAS,SAAS,IAAI,IAAI,KAAK;AAE/B,WAAO,WAAW,OAAO,EAAE;AAAA,EAC7B;AACF;AAMO,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,aAAqB;AAC9C,UAAM,OAAO,MAAM,YAAY;AAG/B,UAAM,SAAS,KAAK,EAAE;AACtB,QAAI,WAAW,OAAO,WAAW,IAAK,QAAO;AAG7C,UAAM,cAAc;AAAA,MAClB;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MACtD;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MACtD;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MAAM;AAAA,MACtD;AAAA,MAAM;AAAA,MAAM;AAAA;AAAA,IACd;AACA,UAAM,YAAY,KAAK,UAAU,IAAI,EAAE;AACvC,WAAO,YAAY,SAAS,SAAS;AAAA,EACvC;AACF;AAMO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,MAAM,MAAM,YAAY;AAG9B,UAAM,kBAAkB,6CAA6C,KAAK,OAAO;AACjF,QAAI,CAAC,gBAAiB,QAAO;AAG7B,QAAI,IAAI,WAAW,MAAM,IAAI,WAAW,GAAI,QAAO;AAInD,UAAM,QAAQ,SAAS,IAAI,UAAU,GAAG,CAAC,CAAC;AAC1C,UAAM,MAAM,SAAS,IAAI,UAAU,GAAG,EAAE,CAAC;AAEzC,QAAI,QAAQ,KAAK,QAAQ,GAAI,QAAO;AACpC,QAAI,MAAM,KAAK,MAAM,GAAI,QAAO;AAEhC,WAAO;AAAA,EACT;AACF;AAGO,IAAM,wBAAsC;AAAA;AAAA,EAEjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA,GAAG;AAAA;AAAA,EAGH,GAAG;AAAA;AAAA,EAGH,GAAG;AAAA;AAAA,EAGH,GAAG;AAAA;AAAA,EAGH,GAAG;AAAA;AAAA,EAGH,GAAG;AAAA;AAAA,EAGH,GAAG;AACL;;;ACznBO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,MAAM,MAAM,SAAS,GAAI,QAAO;AAGnD,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,CAAC,MAAM,WAAW,KAAK,KAAK,MAAM,WAAW,GAAI,QAAO;AAG5D,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAOO,IAAM,sBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAGlD,WAAO,8DAA8D,KAAK,OAAO;AAAA,EACnF;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,sCAAsC,KAAK,OAAO;AAAA,EAC3D;AACF;AAOO,IAAM,cAA0B;AAAA,EACrC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,MAAM,SAAS,GAAI,QAAO;AAGvC,WAAO,wCAAwC,KAAK,OAAO;AAAA,EAC7D;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAClD,QAAI,CAAC,mBAAmB,KAAK,KAAK,EAAG,QAAO;AAG5C,WAAO,qCAAqC,KAAK,OAAO;AAAA,EAC1D;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAGlD,WAAO,mCAAmC,KAAK,OAAO;AAAA,EACxD;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,IAAK,QAAO;AAGnD,WAAO,oDAAoD,KAAK,OAAO;AAAA,EACzE;AACF;AAOO,IAAM,qBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,CAAC,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,GAAI,QAAO;AAG3D,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAOO,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAGlD,WAAO,uCAAuC,KAAK,OAAO;AAAA,EAC5D;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAClD,QAAI,CAAC,YAAY,KAAK,KAAK,EAAG,QAAO;AAGrC,WAAO,8CAA8C,KAAK,OAAO;AAAA,EACnE;AACF;AAOO,IAAM,SAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAI,QAAO;AAClD,QAAI,CAAC,YAAY,KAAK,KAAK,EAAG,QAAO;AAGrC,WAAO,6CAA6C,KAAK,OAAO;AAAA,EAClE;AACF;AAOO,IAAM,uBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,WAAW,GAAI,QAAO;AAGjC,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAOO,IAAM,YAAwB;AAAA,EACnC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAE7C,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAI,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,GAAI,QAAO;AACxD,QAAI,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,EAAG,QAAO;AAGvD,WAAO,uDAAuD,KAAK,OAAO;AAAA,EAC5E;AACF;AAOO,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,QAAI,MAAM,WAAW,GAAI,QAAO;AAChC,QAAI,CAAC,eAAe,KAAK,KAAK,EAAG,QAAO;AAGxC,WAAO,+CAA+C,KAAK,OAAO;AAAA,EACpE;AACF;AAOO,IAAM,mBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,OAAe,YAAoB;AAC7C,UAAM,SAAS,MAAM;AACrB,QAAI,SAAS,KAAK,SAAS,GAAI,QAAO;AAGtC,WAAO,0CAA0C,KAAK,OAAO;AAAA,EAC/D;AACF;AAGO,IAAM,0BAAwC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxTO,IAAM,cAA4B;AAAA,EACvC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAGC;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAKO,SAAS,sBAAsB,UAAgC;AACpE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,CAAC,GAAG,mBAAmB,GAAG,wBAAwB,GAAGA,kBAAuB;AAAA,IACrF,KAAK;AACH,aAAO,CAAC,GAAG,oBAAoB,GAAG,qBAAqB;AAAA,IACzD,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,CAAC;AAAA,EACZ;AACF;;;ACjMO,SAAS,kBAAkB,KAAqB;AACrD,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAQ,IAAI,WAAW,CAAC;AACxB,aAAS,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAAA,EAC3E;AAEA,SAAO,SAAS;AAClB;AAMO,SAAS,wBAAwB,OAAe,MAAsB;AAC3E,QAAM,OAAO,kBAAkB,GAAG,IAAI,IAAI,MAAM,YAAY,CAAC,EAAE;AAC/D,UAAQ,OAAO,KAAO,SAAS,EAAE,SAAS,GAAG,GAAG;AAClD;;;ACjBO,IAAM,aAA4C;AAAA,EACvD,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,cAA6C;AAAA,EACxD,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,aAA4C;AAAA,EACvD,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,UAAU,MAA6C;AACrE,UAAQ,KAAK,YAAY,GAAG;AAAA,IAC1B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,CAAC;AAAA,EACZ;AACF;;;ACxFO,SAAS,mBACd,OACA,MACA,MACA,aACQ;AACR,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IAET,KAAK;AACH,aAAO,WAAW,OAAO,IAAI;AAAA,IAE/B,KAAK;AACH,aAAO,IAAI,OAAO,MAAM,MAAM;AAAA,IAEhC,KAAK;AACH,aAAO,iBAAiB,OAAO,IAAI;AAAA,IAErC,KAAK;AACH,aAAO,aAAa,OAAO,IAAI;AAAA,IAEjC;AACE,aAAO;AAAA,EACX;AACF;AAUA,SAAS,WAAW,OAAe,MAAsB;AAEvD,MAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,UAAM,UAAU,MAAM,QAAQ,GAAG;AACjC,QAAI,UAAU,GAAG;AACf,YAAM,WAAW,MAAM,UAAU,GAAG,OAAO;AAC3C,YAAM,SAAS,MAAM,UAAU,OAAO;AACtC,YAAM,iBAAiB,SAAS,UAAU,IACtC,IAAI,OAAO,SAAS,MAAM,IAC1B,SAAS,CAAC,IAAI,IAAI,OAAO,SAAS,SAAS,CAAC;AAChD,aAAO,iBAAiB;AAAA,IAC1B;AAAA,EACF;AAGA,MAAI,KAAK,SAAS,OAAO,GAAG;AAE1B,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,UAAU,IAAI;AAEvB,YAAM,WAAW,OAAO,UAAU,GAAG,CAAC;AACtC,YAAM,WAAW,OAAO,UAAU,OAAO,SAAS,CAAC;AACnD,YAAM,cAAc,OAAO,SAAS;AACpC,aAAO,GAAG,QAAQ,IAAI,IAAI,OAAO,cAAc,IAAI,cAAc,CAAC,CAAC,IAAI,QAAQ;AAAA,IACjF;AAAA,EACF;AAGA,MAAI,SAAS,OAAO;AAClB,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,WAAW,OAAO,UAAU,CAAC;AACnC,aAAO,UAAU,QAAQ;AAAA,IAC3B;AAAA,EACF;AAGA,MAAI,SAAS,eAAe;AAC1B,UAAM,SAAS,MAAM,QAAQ,OAAO,EAAE;AACtC,QAAI,OAAO,UAAU,IAAI;AACvB,YAAMC,SAAQ,OAAO,UAAU,GAAG,CAAC;AACnC,YAAMC,QAAO,OAAO,UAAU,OAAO,SAAS,CAAC;AAC/C,YAAM,eAAe,KAAK,OAAO,OAAO,SAAS,KAAK,CAAC;AACvD,YAAM,UAAU,QAAQ,OAAO,YAAY,IAAI,QAAQ,UAAU,GAAI,OAAO,SAAS,CAAE;AACvF,aAAO,GAAGD,MAAK,IAAI,MAAM,IAAIC,KAAI;AAAA,IACnC;AAAA,EACF;AAGA,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO,IAAI,OAAO,MAAM,MAAM;AAAA,EAChC;AACA,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,SAAS,GAAG,CAAC;AAC5D,QAAM,QAAQ,MAAM,UAAU,GAAG,SAAS;AAC1C,QAAM,OAAO,MAAM,UAAU,MAAM,SAAS,SAAS;AACrD,QAAM,YAAY,MAAM,SAAU,YAAY;AAC9C,SAAO,GAAG,KAAK,GAAG,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;AAChD;AAUA,SAAS,iBAAiB,OAAe,MAAsB;AAC7D,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAGpB,QAAI,CAAC,cAAc,KAAK,IAAI,GAAG;AAC7B,gBAAU;AAAA,IACZ,WAES,WAAW,KAAK,IAAI,GAAG;AAC9B,gBAAU,SAAS,KAAK,YAAY,IAAI,MAAM;AAAA,IAChD,OAEK;AACH,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,aAAa,OAAe,MAAsB;AAEzD,QAAM,OAAO,WAAW,KAAK;AAE7B,MAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,UAAM,UAAU,CAAC,eAAe,YAAY,cAAc,UAAU;AACpE,UAAM,YAAY,CAAC,QAAQ,YAAY,cAAc,cAAc;AACnE,WAAO,GAAG,UAAU,OAAO,UAAU,MAAM,CAAC,GAAG,OAAO,GAAG,IAAI,QAAQ,OAAO,QAAQ,MAAM,CAAC;AAAA,EAC7F;AAEA,MAAI,KAAK,SAAS,OAAO,GAAG;AAE1B,UAAM,WAAW;AACjB,UAAM,WAAY,OAAO,MAAO;AAChC,UAAM,OAAQ,OAAO,MAAQ;AAC7B,WAAO,IAAI,QAAQ,KAAK,QAAQ,IAAI,IAAI;AAAA,EAC1C;AAEA,MAAI,SAAS,OAAO;AAElB,UAAM,OAAS,OAAO,MAAO;AAC7B,UAAM,SAAU,OAAO,KAAM,GAAG,SAAS,EAAE,SAAS,GAAG,GAAG;AAC1D,UAAM,UAAW,OAAO,OAAQ,GAAG,SAAS,EAAE,SAAS,GAAG,GAAG;AAC7D,WAAO,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM;AAAA,EACnC;AAEA,MAAI,SAAS,eAAe;AAE1B,UAAM,QAAQ;AACd,UAAM,WAAW;AAAA,OACb,OAAO,MAAQ,KAAM,SAAS;AAAA,OAC9B,OAAO,MAAQ,KAAM,SAAS;AAAA,OAC9B,OAAO,MAAQ,KAAM,SAAS;AAAA,IAClC;AACA,WAAO,GAAG,KAAK,IAAI,SAAS,KAAK,GAAG,CAAC;AAAA,EACvC;AAEA,MAAI,KAAK,SAAS,MAAM,GAAG;AACzB,UAAM,aAAa,CAAC,QAAQ,QAAQ,QAAQ,OAAO,SAAS,KAAK;AACjE,UAAM,YAAY,CAAC,SAAS,WAAW,YAAY,SAAS,SAAS,OAAO;AAC5E,WAAO,GAAG,WAAW,OAAO,WAAW,MAAM,CAAC,IAAI,WAAW,QAAQ,KAAK,UAAU,MAAM,CAAC;AAAA,EAC7F;AAGA,SAAO,aAAa,IAAI;AAC1B;AAKA,SAAS,WAAW,KAAqB;AACvC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,OAAO,IAAI,WAAW,CAAC;AAC7B,YAAS,QAAQ,KAAK,OAAQ;AAC9B,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,KAAK,IAAI,IAAI;AACtB;;;ACpMA,YAAY,QAAQ;AACpB,YAAY,UAAU;AA2Cf,IAAM,qBAAN,MAAyB;AAAA,EAM9B,YAAY,WAAmB,iCAAiC,UAG5D,CAAC,GAAG;AACN,SAAK,WAAW;AAChB,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,sBAAsB,QAAQ,uBAAuB;AAC1D,SAAK,OAAO,KAAK,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAqB;AAC3B,QAAI;AACF,UAAO,cAAW,KAAK,QAAQ,GAAG;AAChC,cAAM,UAAa,gBAAa,KAAK,UAAU,OAAO;AACtD,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B;AAAA,IACF,SAAS,OAAO;AAAA,IAEhB;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW,CAAC;AAAA,MACZ,oBAAoB,CAAC;AAAA,MACrB,OAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,aAAa,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAa;AACnB,QAAI;AACF,YAAM,MAAW,aAAQ,KAAK,QAAQ;AACtC,UAAI,CAAI,cAAW,GAAG,GAAG;AACvB,QAAG,aAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MACvC;AAEA,WAAK,KAAK,MAAM,cAAc,KAAK,IAAI;AACvC,MAAG,iBAAc,KAAK,UAAU,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IACpE,SAAS,OAAO;AACd,cAAQ,MAAM,iCAAiC,KAAK;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,MAAc,OAAe,SAAuB;AACtE,SAAK,KAAK,MAAM;AAChB,SAAK,KAAK,MAAM;AAChB,SAAK,eAAe;AAGpB,QAAI,QAAQ,KAAK,KAAK,UAAU,KAAK,OAAK,EAAE,YAAY,IAAI;AAE5D,QAAI,OAAO;AACT,YAAM;AACN,YAAM,WAAW,KAAK,IAAI;AAC1B,UAAI,CAAC,MAAM,SAAS,SAAS,OAAO,GAAG;AACrC,cAAM,SAAS,KAAK,OAAO;AAAA,MAC7B;AAEA,YAAM,aAAa,KAAK,IAAI,MAAM,MAAM,aAAa,IAAI;AAAA,IAC3D,OAAO;AACL,cAAQ;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA;AAAA,QACZ,aAAa;AAAA,QACb,WAAW,KAAK,IAAI;AAAA,QACpB,UAAU,KAAK,IAAI;AAAA,QACnB,UAAU,CAAC,OAAO;AAAA,MACpB;AACA,WAAK,KAAK,UAAU,KAAK,KAAK;AAAA,IAChC;AAEA,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,MAAc,MAAc,UAAwB;AACtE,SAAK,KAAK,MAAM;AAChB,SAAK,KAAK,MAAM;AAChB,SAAK,eAAe;AAGpB,QAAI,aAAa,KAAK,KAAK,mBAAmB;AAAA,MAC5C,OAAK,EAAE,SAAS,QAAQ,EAAE,SAAS,SAAS,IAAI;AAAA,IAClD;AAEA,QAAI,YAAY;AACd,iBAAW;AACX,iBAAW,aAAa,KAAK,IAAI,MAAM,WAAW,aAAa,IAAI;AAAA,IACrE,OAAO;AACL,mBAAa;AAAA,QACX;AAAA,QACA,OAAO;AAAA,QACP,YAAY,gCAAgC,IAAI;AAAA,QAChD,YAAY;AAAA,QACZ,UAAU,CAAC,IAAI;AAAA,QACf,aAAa;AAAA,MACf;AACA,WAAK,KAAK,mBAAmB,KAAK,UAAU;AAAA,IAC9C;AAEA,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,yBAA+B;AAC7B,SAAK,KAAK,MAAM;AAChB,SAAK,eAAe;AAEpB,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAuB;AAC7B,UAAM,QAAQ,KAAK,KAAK,MAAM;AAC9B,QAAI,UAAU,GAAG;AACf,WAAK,KAAK,MAAM,WAAW;AAC3B;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,KAAK,MAAM,iBAAiB,KAAK,KAAK,MAAM;AACnE,SAAK,KAAK,MAAM,YAAY,QAAQ,aAAa;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAyB;AACvB,WAAO,KAAK,KAAK,UACd,OAAO,OAAK,EAAE,cAAc,KAAK,mBAAmB,EACpD,IAAI,OAAK,EAAE,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAwC;AACtC,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,wBAA6C;AAC3C,WAAO,KAAK,KAAK,mBACd,OAAO,OAAK,EAAE,cAAc,KAAK,mBAAmB,EACpD,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,2BAAgD;AAC9C,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,WAA0B;AACxB,WAAO,EAAE,GAAG,KAAK,KAAK,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,SAAyB;AACrC,UAAM,QAAQ,KAAK,KAAK,UAAU,KAAK,OAAK,EAAE,YAAY,OAAO;AACjE,WAAO,OAAO,cAAc;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,SAAyB;AACtC,UAAM,QAAQ,KAAK,KAAK,UAAU,KAAK,OAAK,EAAE,YAAY,OAAO;AACjE,WAAO,OAAO,eAAe;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,SAAiB,aAAqB,KAAW;AAC9D,UAAM,WAAW,KAAK,KAAK,UAAU,KAAK,OAAK,EAAE,YAAY,OAAO;AAEpE,QAAI,UAAU;AACZ,eAAS,aAAa;AACtB,eAAS;AACT,eAAS,WAAW,KAAK,IAAI;AAAA,IAC/B,OAAO;AACL,WAAK,KAAK,UAAU,KAAK;AAAA,QACvB;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,WAAW,KAAK,IAAI;AAAA,QACpB,UAAU,KAAK,IAAI;AAAA,QACnB,UAAU,CAAC;AAAA,MACb,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,SAAuB;AACzC,SAAK,KAAK,YAAY,KAAK,KAAK,UAAU,OAAO,OAAK,EAAE,YAAY,OAAO;AAE3E,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,OAAO;AAAA,MACV,SAAS;AAAA,MACT,WAAW,CAAC;AAAA,MACZ,oBAAoB,CAAC;AAAA,MACrB,OAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,aAAa,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAGH,CAAC,GAAiB;AACpB,UAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,UAAM,kBAAkB,QAAQ,mBAAmB;AAEnD,WAAO;AAAA,MACL,SAAS,KAAK,KAAK;AAAA,MACnB,WAAW,KAAK,KAAK,UAClB,OAAO,OAAK,EAAE,cAAc,aAAa,EACzC,IAAI,QAAM;AAAA,QACT,GAAG;AAAA,QACH,UAAU,kBAAkB,EAAE,WAAW,CAAC;AAAA,MAC5C,EAAE;AAAA,MACJ,oBAAoB,KAAK,KAAK,mBAC3B,OAAO,OAAK,EAAE,cAAc,aAAa;AAAA,MAC5C,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAAoB,QAAiB,MAAY;AACtD,QAAI,CAAC,OAAO;AACV,WAAK,OAAO;AACZ,WAAK,KAAK;AACV;AAAA,IACF;AAGA,eAAW,SAAS,KAAK,WAAW;AAClC,YAAM,WAAW,KAAK,KAAK,UAAU,KAAK,OAAK,EAAE,YAAY,MAAM,OAAO;AAE1E,UAAI,UAAU;AAEZ,iBAAS,aAAa,KAAK,IAAI,SAAS,YAAY,MAAM,UAAU;AACpE,iBAAS,eAAe,MAAM;AAC9B,iBAAS,WAAW,KAAK,IAAI,SAAS,UAAU,MAAM,QAAQ;AAC9D,iBAAS,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,SAAS,UAAU,GAAG,MAAM,QAAQ,CAAC,CAAC;AAAA,MAC5E,OAAO;AACL,aAAK,KAAK,UAAU,KAAK,KAAK;AAAA,MAChC;AAAA,IACF;AAGA,eAAW,cAAc,KAAK,oBAAoB;AAChD,YAAM,WAAW,KAAK,KAAK,mBAAmB;AAAA,QAAK,OACjD,EAAE,SAAS,WAAW,QAAQ,EAAE,UAAU,WAAW;AAAA,MACvD;AAEA,UAAI,UAAU;AACZ,iBAAS,aAAa,KAAK,IAAI,SAAS,YAAY,WAAW,UAAU;AACzE,iBAAS,eAAe,WAAW;AACnC,iBAAS,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,SAAS,UAAU,GAAG,WAAW,QAAQ,CAAC,CAAC;AAAA,MACjF,OAAO;AACL,aAAK,KAAK,mBAAmB,KAAK,UAAU;AAAA,MAC9C;AAAA,IACF;AAGA,SAAK,KAAK,MAAM,mBAAmB,KAAK,MAAM;AAC9C,SAAK,KAAK,MAAM,kBAAkB,KAAK,MAAM;AAC7C,SAAK,KAAK,MAAM,kBAAkB,KAAK,MAAM;AAC7C,SAAK,eAAe;AAEpB,QAAI,KAAK,UAAU;AACjB,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,KAAK;AAAA,EACZ;AACF;;;AC1YA,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AAef,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAAY,YAAqB,MAAc,QAAQ,IAAI,GAAG;AAC5D,SAAK,aAAa,cAAc;AAChC,SAAK,cAAc;AAAA,MACjB;AAAA,MACK,WAAK,KAAK,gBAAgB;AAAA,MAC1B,WAAK,QAAQ,IAAI,QAAQ,KAAK,gBAAgB;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAgC;AACtC,QAAI,KAAK,cAAiB,eAAW,KAAK,UAAU,GAAG;AACrD,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,cAAc,KAAK,aAAa;AACzC,iBAAW,cAAc,aAAa;AACpC,cAAM,WAAgB,WAAK,YAAY,UAAU;AACjD,YAAO,eAAW,QAAQ,GAAG;AAC3B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAA4C;AAChD,UAAM,aAAa,KAAK,eAAe;AAEvC,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,IACT;AAEA,QAAI;AACF,UAAI,WAAW,SAAS,OAAO,GAAG;AAChC,cAAM,UAAa,iBAAa,YAAY,OAAO;AACnD,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B;AAGA,YAAM,SAAS,MAAM,OAAO;AAC5B,aAAO,OAAO,WAAW;AAAA,IAC3B,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,UAAU,KAAK,KAAK;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,QAAmD;AAC/D,UAAM,WAAiC,EAAE,GAAG,OAAO;AAGnD,QAAI,OAAO,SAAS;AAClB,YAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC,OAAO,OAAO;AAEhF,iBAAW,UAAU,SAAS;AAC5B,cAAM,eAAe,KAAK,WAAW,MAAM;AAC3C,YAAI,cAAc;AAChB,iBAAO,OAAO,UAAU,cAAc,MAAM;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,QAA6C;AAE9D,QAAI,WAAW,6BAA6B;AAC1C,aAAO;AAAA,QACL,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,eAAe;AAAA,QACf,eAAe;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,WAAW,wBAAwB;AACrC,aAAO;AAAA,QACL,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,eAAe;AAAA,QACf,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,WAAW,yBAAyB;AACtC,aAAO;AAAA,QACL,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,eAAe;AAAA,QACf,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,OAAO,WAAW,gBAAgB,GAAG;AACvC,YAAM,iBAAiB,OAAO,QAAQ,kBAAkB,EAAE;AAC1D,UAAI,CAAC,QAAQ,SAAS,MAAM,EAAE,SAAS,cAAc,GAAG;AACtD,eAAO,EAAE,QAAQ,eAAe;AAAA,MAClC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,oBAAoB,aAAqB,4BAAkC;AAChF,UAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CtB,IAAG,kBAAc,YAAY,aAAa;AAC1C,YAAQ,IAAI,wBAAwB,UAAU,EAAE;AAAA,EAClD;AACF;;;ACxKO,SAAS,eACd,MACA,UACA,QACA,cAAsB,GACtB,aAAqB,GAOrB;AAEA,QAAM,aAAa,KAAK,UAAU,KAAK,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ;AACvE,QAAM,kBAAkB,WAAW,MAAM,KAAK,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AACxE,QAAM,cAAc,gBAAgB,MAAM,CAAC,WAAW;AACtD,QAAM,SAAS,YAAY,KAAK,GAAG;AAGnC,QAAM,YAAY,KAAK,UAAU,QAAQ,KAAK,IAAI,KAAK,QAAQ,SAAS,GAAG,CAAC;AAC5E,QAAM,iBAAiB,UAAU,MAAM,KAAK,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AACtE,QAAM,aAAa,eAAe,MAAM,GAAG,UAAU;AACrD,QAAM,QAAQ,WAAW,KAAK,GAAG;AAGjC,QAAM,WAAW,gBAAgB,MAAM,UAAU,MAAM;AAEvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,gBAAgB,MAAc,UAAkB,QAAwB;AAE/E,QAAM,gBAAgB,kBAAkB,MAAM,QAAQ;AACtD,QAAM,cAAc,gBAAgB,MAAM,MAAM;AAEhD,SAAO,KAAK,UAAU,eAAe,WAAW,EAAE,KAAK;AACzD;AAEA,SAAS,kBAAkB,MAAc,KAAqB;AAE5D,WAAS,IAAI,MAAM,GAAG,KAAK,GAAG,KAAK;AACjC,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;AACjE,aAAO,IAAI;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,MAAc,KAAqB;AAE1D,WAAS,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK;AACtC,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;AACjE,aAAO,IAAI;AAAA,IACb;AAAA,EACF;AACA,SAAO,KAAK;AACd;AAKO,SAAS,kBAAkB,MAA+C;AAC/E,QAAM,SAAS,KAAK,UAAU,GAAG,KAAK,IAAI,KAAM,KAAK,MAAM,CAAC,EAAE,YAAY;AAG1E,QAAM,kBAAkB;AACxB,QAAM,cAAc,OAAO,MAAM,eAAe,KAAK,CAAC,GAAG;AAGzD,QAAM,iBAAiB;AACvB,QAAM,aAAa,OAAO,MAAM,cAAc,KAAK,CAAC,GAAG;AAGvD,QAAM,iBAAiB;AACvB,QAAM,aAAa,OAAO,MAAM,cAAc,KAAK,CAAC,GAAG;AAGvD,MAAI,YAAY,EAAG,QAAO;AAC1B,MAAI,aAAa,EAAG,QAAO;AAC3B,MAAI,YAAY,EAAG,QAAO;AAE1B,SAAO;AACT;AAKO,SAAS,uBAAuB,aAAsC;AAC3E,QAAM,QAAQ,YAAY,YAAY;AAGtC,QAAM,iBAAiB;AACvB,QAAM,uBAAuB,MAAM,MAAM,cAAc,KAAK,CAAC,GAAG,SAAS;AAGzE,QAAM,gBAAgB;AACtB,QAAM,sBAAsB,MAAM,MAAM,aAAa,KAAK,CAAC,GAAG,SAAS;AAGvE,QAAM,eAAe;AACrB,QAAM,qBAAqB,MAAM,MAAM,YAAY,KAAK,CAAC,GAAG,SAAS;AAGrE,QAAM,iBAAiB;AACvB,QAAM,uBAAuB,MAAM,MAAM,cAAc,KAAK,CAAC,GAAG,SAAS;AAIzE,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,gBAAgB;AACtB,QAAM,eAAe,MAAM,MAAM,aAAa,KAAK,CAAC,GAAG;AACvD,QAAM,cAAc,mBAAmB,KAAK,aAAW,QAAQ,KAAK,WAAW,CAAC;AAGhF,QAAM,oBAAoB,eAAe,eAAe;AAExD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA;AAAA,EACpB;AACF;AAKO,SAAS,2BACd,QACA,aACA,SAOQ;AACR,MAAI,aAAa;AAGjB,MAAI,QAAQ,iBAAiB,QAAQ;AAEnC,UAAMC,sBAAqB,CAAC,WAAW,OAAO,gBAAgB,kBAAkB,gBAAgB,QAAQ;AACxG,QAAI,CAACA,oBAAmB,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC,GAAG;AAC1D,oBAAc;AAAA,IAChB;AAAA,EACF,WAAW,QAAQ,iBAAiB,SAAS;AAE3C,QAAI,CAAC,SAAS,SAAS,QAAQ,SAAS,EAAE,SAAS,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC,GAAG;AAC7E,oBAAc;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,QAAQ,SAAS,mBAAmB;AAEtC,kBAAc;AAAA,EAChB;AAGA,QAAM,kBAAkB,CAAC,WAAW,OAAO,WAAW,OAAO,OAAO,OAAO,OAAO,OAAO,cAAc;AACvG,MAAI,QAAQ,SAAS,qBAAqB,gBAAgB,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC,GAAG;AAE5F,kBAAc;AAAA,EAChB;AAGA,QAAMC,qBAAoB,CAAC,WAAW,eAAe,SAAS,QAAQ,WAAW,YAAY,UAAU,SAAS;AAChH,MAAI,QAAQ,SAAS,uBAAuBA,mBAAkB,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC,GAAG;AAEhG,kBAAc;AAAA,EAChB;AAGA,QAAM,qBAAqB,CAAC,WAAW,SAAS,UAAU,OAAO,UAAU,UAAU,KAAK;AAC1F,MAAI,QAAQ,SAAS,uBAAuB,CAAC,mBAAmB,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC,GAAG;AAElG,kBAAc;AAAA,EAChB;AAGA,QAAM,cAAc,QAAQ,OAAO,YAAY;AAC/C,QAAM,aAAa,QAAQ,MAAM,YAAY;AAG7C,QAAM,qBAAqB;AAAA,IACzB,EAAE,SAAS,uCAAuC,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE;AAAA,IAC9E,EAAE,SAAS,8BAA8B,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE;AAAA,IACtE,EAAE,SAAS,mCAAmC,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE;AAAA,IAC3E,EAAE,SAAS,kCAAkC,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE;AAAA,IAC1E,EAAE,SAAS,yCAAyC,OAAO,MAAM,OAAO,CAAC,QAAQ,cAAc,KAAK,EAAE;AAAA,IACtG,EAAE,SAAS,6BAA6B,OAAO,KAAK,OAAO,CAAC,WAAW,MAAM,EAAE;AAAA,EACjF;AAEA,aAAW,aAAa,oBAAoB;AAC1C,QAAI,UAAU,QAAQ,KAAK,WAAW,GAAG;AACvC,YAAM,cAAc,UAAU,MAAM,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC;AACrE,UAAI,aAAa;AACf,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,qBAAqB;AAAA,IACzB,EAAE,SAAS,qBAAqB,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE;AAAA,IAC9D,EAAE,SAAS,8BAA8B,SAAS,KAAK,OAAO,CAAC,SAAS,QAAQ,EAAE;AAAA,IAClF,EAAE,SAAS,uCAAuC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE;AAAA,EAClF;AAEA,aAAW,aAAa,oBAAoB;AAC1C,QAAI,UAAU,QAAQ,KAAK,WAAW,KAAK,UAAU,QAAQ,KAAK,UAAU,GAAG;AAC7E,YAAM,cAAc,UAAU,MAAM,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC;AACrE,UAAI,aAAa;AACf,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAGA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC;AAC5C;AAKO,SAAS,mBACd,MACA,OACA,aACA,UACA,QACiB;AACjB,QAAM,EAAE,QAAQ,OAAO,aAAa,YAAY,SAAS,IAAI;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,eAAe,kBAAkB,IAAI;AAC3C,QAAM,cAAc,SAAS,MAAM,QAAQ,MAAM;AACjD,QAAM,WAAW,uBAAuB,WAAW;AACnD,WAAS,mBAAmB,WAAW,KAAK;AAE5C,QAAM,aAAa,2BAA2B,OAAO,aAAa;AAAA,IAChE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3SO,IAAM,uBAA4C;AAAA;AAAA,EAEvD;AAAA,IACE,aAAa,CAAC,SAAS,YAAY,UAAU;AAAA,IAC7C,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,iBAAiB;AACvB,UAAI,eAAe,KAAK,OAAO,EAAG,QAAO;AAGzC,YAAM,gBAAgB;AACtB,UAAI,cAAc,KAAK,MAAM,QAAQ,YAAY,EAAE,CAAC,EAAG,QAAO;AAE9D,aAAO;AAAA,IACT;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,YAAY,UAAU;AAAA,IAC7C,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,cAAc;AACpB,UAAI,YAAY,KAAK,OAAO,EAAG,QAAO;AAGtC,YAAM,eAAe;AAAA,QACnB;AAAA;AAAA,QACA;AAAA;AAAA,QACA;AAAA;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,QAAQ,WAAW,EAAE;AAC3C,aAAO,aAAa,KAAK,aAAW,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC3D;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,WAAW,IAAI;AAAA,IACtC,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,YAAY;AAClB,UAAI,UAAU,KAAK,KAAK,EAAG,QAAO;AAGlC,YAAM,YAAY;AAClB,aAAO,UAAU,KAAK,OAAO;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,QAAQ;AAAA,IAC/B,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,cAAc;AACpB,YAAM,UAAU,YAAY,KAAK,UAAU,MAAM,KAAK;AAGtD,YAAM,iBAAiB;AAEvB,aAAO,WAAW,eAAe,KAAK,OAAO;AAAA,IAC/C;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,MAAM,QAAQ;AAAA,IACrC,SAAS,CAAC,UAAkB;AAE1B,YAAM,cAAc;AACpB,YAAM,UAAU,MAAM,QAAQ,YAAY,EAAE;AAC5C,aAAO,YAAY,KAAK,OAAO;AAAA,IACjC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,WAAW,QAAQ;AAAA,IAC1C,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,kBAAkB;AACxB,UAAI,gBAAgB,KAAK,OAAO,EAAG,QAAO;AAG1C,YAAM,eAAe;AACrB,aAAO,aAAa,KAAK,MAAM,QAAQ,UAAU,EAAE,CAAC;AAAA,IACtD;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,MAAM,QAAQ;AAAA,IACrC,SAAS,CAAC,OAAe,YAAoB;AAC3C,YAAM,cAAc;AACpB,YAAM,cAAc;AAEpB,aAAO,YAAY,KAAK,OAAO,KAAK,YAAY,KAAK,KAAK;AAAA,IAC5D;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,QAAQ;AAAA,IAC/B,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,cAAc,UAAU,MAAM;AACpC,YAAM,eAAe;AACrB,aAAO,aAAa,KAAK,WAAW;AAAA,IACtC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,QAAQ,OAAO;AAAA,IAC7B,SAAS,CAAC,OAAe,YAAoB;AAE3C,YAAM,mBAAmB;AACzB,UAAI,iBAAiB,KAAK,MAAM,YAAY,CAAC,EAAG,QAAO;AAGvD,YAAM,qBAAqB;AAC3B,aAAO,mBAAmB,KAAK,OAAO;AAAA,IACxC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,QAAQ,SAAS,SAAS;AAAA,IACjD,SAAS,CAAC,UAAkB;AAC1B,YAAM,eAAe;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,aAAO,aAAa,KAAK,aAAW,QAAQ,KAAK,KAAK,CAAC;AAAA,IACzD;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,MAAM;AAAA,IACpB,SAAS,CAAC,QAAgB,YAAoB;AAE5C,YAAM,iBAAiB;AACvB,aAAO,eAAe,KAAK,OAAO;AAAA,IACpC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,MAAM;AAAA,IACpB,SAAS,CAAC,OAAe,YAAoB;AAC3C,YAAM,WAAW;AAAA,QACf;AAAA,QAAY;AAAA,QAAS;AAAA,QAAO;AAAA,QAAO;AAAA,QAAS;AAAA,QAAa;AAAA,QAAQ;AAAA,QACjE;AAAA,QAAU;AAAA,QAAW;AAAA,QAAa;AAAA,QAAU;AAAA,QAAS;AAAA,QAAS;AAAA,QAC9D;AAAA,QAAU;AAAA,QAAU;AAAA,QAAQ;AAAA,QAAW;AAAA,QAAW;AAAA,MACpD;AAEA,YAAM,aAAa,MAAM,YAAY;AACrC,UAAI,SAAS,SAAS,UAAU,EAAG,QAAO;AAG1C,YAAM,cAAc;AACpB,aAAO,YAAY,KAAK,OAAO;AAAA,IACjC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,OAAO;AAAA,IACrB,SAAS,CAAC,UAAkB;AAC1B,YAAM,gBAAgB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,SAAS,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,YAAY;AAChD,aAAO,cAAc,SAAS,MAAM;AAAA,IACtC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,WAAW,MAAM;AAAA,IAC/B,SAAS,CAAC,OAAe,aAAqB;AAE5C,UAAI,OAAO,KAAK,MAAM,QAAQ,UAAU,EAAE,CAAC,EAAG,QAAO;AAGrD,YAAM,UAAU,MAAM,QAAQ,UAAU,EAAE;AAC1C,UAAI,YAAY,KAAK,OAAO,EAAG,QAAO;AAGtC,UAAI,sCAAsC,KAAK,OAAO,EAAG,QAAO;AAEhE,aAAO;AAAA,IACT;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,MAAM,QAAQ;AAAA,IACrC,SAAS,CAAC,QAAgB,YAAoB;AAC5C,YAAM,mBAAmB;AACzB,aAAO,iBAAiB,KAAK,OAAO;AAAA,IACtC;AAAA,IACA,aAAa;AAAA,IACb,UAAU;AAAA,EACZ;AACF;AAKO,SAAS,gBACd,OACA,aACA,SACA,QAA6B,sBAK7B;AACA,aAAW,QAAQ,OAAO;AAExB,UAAM,UAAU,MAAM,QAAQ,KAAK,WAAW,IAC1C,KAAK,YAAY,KAAK,OAAK,YAAY,SAAS,CAAC,CAAC,IAClD,YAAY,SAAS,KAAK,WAAW;AAEzC,QAAI,CAAC,QAAS;AAGd,QAAI,KAAK,QAAQ,OAAO,OAAO,GAAG;AAChC,YAAM,aAAa,KAAK,aAAa,SAAS,MAAM,KAAK,aAAa,WAAW,MAAM;AACvF,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,aAAa;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,YAAY;AAAA,EACd;AACF;AAKO,SAAS,qBACd,YACA,SACA,YAAoB,KACf;AACL,SAAO,WAAW,OAAO,eAAa;AACpC,UAAM,EAAE,OAAO,QAAQ,IAAI,QAAQ,SAAS;AAC5C,UAAM,SAAS,gBAAgB,OAAO,UAAU,MAAM,OAAO;AAG7D,WAAO,EAAE,OAAO,mBAAmB,OAAO,cAAc;AAAA,EAC1D,CAAC;AACH;;;ACzSO,IAAM,gBAAiC;AAAA,EAC5C;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,cAAc,CAAC,WAAW,SAAS,UAAU,YAAY,eAAe,OAAO,UAAU,QAAQ;AAAA,IACjG,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AACF;AAKO,SAAS,oBACd,UACA,SAA0B,eACC;AAC3B,QAAM,UAAU,oBAAI,IAA0B;AAG9C,aAAW,QAAQ,QAAQ;AACzB,YAAQ,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3B;AAGA,aAAW,WAAW,UAAU;AAC9B,eAAW,QAAQ,QAAQ;AAEzB,UAAI,QAAQ,WAAW,KAAK,eAAe,QAAQ,WAAW,KAAK,aAAa;AAC9E;AAAA,MACF;AAGA,UAAI,KAAK,gBAAgB,KAAK,aAAa,SAAS,GAAG;AACrD,cAAM,iBAAiB,KAAK,aAAa;AAAA,UAAK,UAC5C,QAAQ,KAAK,SAAS,IAAI;AAAA,QAC5B;AACA,YAAI,CAAC,eAAgB;AAAA,MACvB;AAGA,UAAI,KAAK,gBAAgB,KAAK,aAAa,SAAS,GAAG;AACrD,cAAM,iBAAiB,KAAK,aAAa;AAAA,UAAK,UAC5C,QAAQ,KAAK,SAAS,IAAI;AAAA,QAC5B;AACA,YAAI,eAAgB;AAAA,MACtB;AAGA,cAAQ,IAAI,KAAK,IAAI,EAAG,KAAK,OAAO;AACpC;AAAA,IACF;AAAA,EACF;AAGA,aAAW,CAAC,UAAU,YAAY,KAAK,QAAQ,QAAQ,GAAG;AACxD,iBAAa,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACnD,YAAQ,IAAI,UAAU,YAAY;AAAA,EACpC;AAEA,SAAO;AACT;AAqBO,SAAS,qBACd,OACA,KACA,QACS;AACT,SAAO,OAAO;AAAA,IACZ,CAAC,CAAC,eAAe,WAAW,MACzB,SAAS,iBAAiB,QAAQ,eAClC,MAAM,iBAAiB,OAAO,eAC9B,SAAS,iBAAiB,OAAO;AAAA,EACtC;AACF;AAMO,SAAS,oBACd,gBACA,QACgB;AAChB,QAAM,SAAyB,CAAC;AAChC,QAAM,kBAA2C,CAAC;AAGlD,aAAW,QAAQ,QAAQ;AACzB,UAAM,aAAa,eAAe,IAAI,KAAK,IAAI,KAAK,CAAC;AAErD,eAAW,aAAa,YAAY;AAClC,YAAM,CAAC,OAAO,GAAG,IAAI,UAAU;AAG/B,UAAI,qBAAqB,OAAO,KAAK,eAAe,GAAG;AACrD;AAAA,MACF;AAGA,aAAO,KAAK,SAAS;AACrB,sBAAgB,KAAK,CAAC,OAAO,GAAG,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,sBAAsB,SAKlB;AAClB,QAAM,YAAY,KAAK,IAAI,KAAK,IAAI,SAAS,aAAa,GAAG,CAAC,GAAG,CAAC;AAClE,QAAM,wBAAwB,SAAS,yBAAyB;AAEhE,QAAM,SAA0B,CAAC;AAGjC,QAAM,gBAAgB,wBAAwB,IAAI;AAClD,QAAM,cAAc,wBAAwB,KAAK;AACjD,QAAM,QAAQ,cAAc;AAC5B,QAAM,eAAe,wBAAwB,YAAY,IAAI;AAC7D,QAAM,OAAO,KAAK,MAAM,QAAQ,YAAY;AAG5C,QAAM,gBAAiC,CAAC;AACxC,WAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,UAAM,MAAM,gBAAiB,IAAI;AACjC,UAAM,MAAM,MAAM,eAAe,IAAI,cAAc,iBAAkB,IAAI,KAAK,OAAQ;AAEtF,kBAAc,KAAK;AAAA,MACjB,MAAM,QAAQ,IAAI,CAAC;AAAA,MACnB,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,YAAY,GAAG,IAAI,GAAG;AAAA,IACrC,CAAC;AAAA,EACH;AAGA,SAAO,KAAK,GAAG,cAAc,QAAQ,CAAC;AAGtC,MAAI,uBAAuB;AACzB,WAAO,QAAQ;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,MACb,cAAc,CAAC,WAAW,SAAS,UAAU,YAAY,OAAO,UAAU,UAAU,KAAK;AAAA,MACzF,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACjLO,IAAM,cAAN,MAAkB;AAAA,EAIvB,cAAc;AAFd,SAAQ,YAAqB;AAI3B,QAAI;AAEF,WAAK,MAAM,UAAQ,YAAY;AAC/B,WAAK,YAAY;AAAA,IACnB,QAAQ;AAEN,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAA0B;AAC/B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,KAAK;AAChC,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,UAAsB,CAAC;AAE7B,QAAI;AACF,YAAM,MAAM,KAAK,IAAI,IAAI;AAGzB,YAAM,SAAS,IAAI,OAAO;AAC1B,aAAO,QAAQ,CAAC,WAAgB;AAC9B,cAAM,aAAa,OAAO,KAAK;AAC/B,cAAM,SAAS,KAAK,QAAQ,UAAU;AAEtC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,WAAW;AAAA,YACzB,YAAY;AAAA;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,cACvC,MAAM,OAAO,KAAK;AAAA,YACpB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,OAAO,IAAI,cAAc;AAC/B,WAAK,QAAQ,CAAC,QAAa;AACzB,cAAM,UAAU,IAAI,KAAK;AACzB,cAAM,SAAS,KAAK,QAAQ,OAAO;AAEnC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,QAAQ;AAAA,YACtB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,cACvC,MAAM,IAAI,KAAK;AAAA,YACjB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,SAAS,IAAI,OAAO;AAC1B,aAAO,QAAQ,CAAC,UAAe;AAC7B,cAAM,YAAY,MAAM,KAAK;AAC7B,cAAM,SAAS,KAAK,QAAQ,SAAS;AAErC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,UAAU;AAAA,YACxB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,cACvC,MAAM,MAAM,KAAK;AAAA,YACnB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,QAAQ,IAAI,MAAM;AACxB,YAAM,QAAQ,CAAC,SAAc;AAC3B,cAAM,WAAW,KAAK,KAAK;AAC3B,cAAM,SAAS,KAAK,QAAQ,QAAQ;AAEpC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,SAAS;AAAA,YACvB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,cACvC,MAAM,KAAK,KAAK;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,QAAQ,IAAI,MAAM;AACxB,YAAM,QAAQ,CAAC,MAAW;AACxB,cAAM,YAAY,EAAE,KAAK;AACzB,cAAM,SAAS,KAAK,QAAQ,SAAS;AAErC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,UAAU;AAAA,YACxB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,cACvC,MAAM,EAAE,KAAK;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,aAAO,QAAQ,CAAC,UAAe;AAC7B,cAAM,YAAY,MAAM,KAAK;AAC7B,cAAM,SAAS,KAAK,QAAQ,SAAS;AAErC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,UAAU;AAAA,YACxB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,YACzC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,SAAS,IAAI,MAAM,cAAc;AACvC,aAAO,QAAQ,CAAC,UAAe;AAC7B,cAAM,YAAY,MAAM,KAAK;AAC7B,cAAM,SAAS,KAAK,QAAQ,SAAS;AAErC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,UAAU;AAAA,YACxB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,YACzC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,YAAM,OAAO,IAAI,MAAM,MAAM;AAC7B,WAAK,QAAQ,CAAC,QAAa;AACzB,cAAM,UAAU,IAAI,KAAK;AACzB,cAAM,SAAS,KAAK,QAAQ,OAAO;AAEnC,YAAI,WAAW,IAAI;AACjB,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,SAAS,QAAQ;AAAA,YACtB,YAAY;AAAA,YACZ,SAAS;AAAA,cACP,UAAU,KAAK,YAAY,MAAM,MAAM;AAAA,YACzC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AAEd,cAAQ,KAAK,mCAAmC,KAAK;AACrD,aAAO,CAAC;AAAA,IACV;AAGA,WAAO,KAAK,mBAAmB,OAAO;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,iBACE,YACA,YAC6C;AAE7C,eAAW,YAAY,YAAY;AACjC,YAAM,UAAU,KAAK;AAAA,QACnB,WAAW;AAAA,QACX,WAAW;AAAA,QACX,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAGA,UAAI,UAAU,KAAK;AACjB,eAAO;AAAA,UACL,WAAW;AAAA,UACX,YAAY,SAAS;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,WAAW,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,gBACE,cACA,MACe;AACf,QAAI,CAAC,KAAK,WAAW;AAEnB,aAAO,aAAa,IAAI,YAAU;AAAA,QAChC,GAAG;AAAA,QACH,cAAc;AAAA,MAChB,EAAE;AAAA,IACJ;AAGA,UAAM,aAAa,KAAK,OAAO,IAAI;AAGnC,WAAO,aAAa,IAAI,WAAS;AAC/B,YAAM,EAAE,WAAW,YAAY,cAAc,IAAI,KAAK,iBAAiB,OAAO,UAAU;AAExF,UAAI,aAAa,eAAe;AAE9B,cAAM,oBAAoB,KAAK,IAAI,GAAK,MAAM,aAAa,GAAG;AAE9D,eAAO;AAAA,UACL,GAAG;AAAA,UACH,YAAY;AAAA,UACZ,cAAc;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,iBACN,QACA,MACA,QACA,MACQ;AACR,UAAM,eAAe,KAAK,IAAI,QAAQ,MAAM;AAC5C,UAAM,aAAa,KAAK,IAAI,MAAM,IAAI;AAEtC,QAAI,gBAAgB,YAAY;AAC9B,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,aAAa;AACnC,UAAM,YAAY,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AAEvD,WAAO,gBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,SAAiC;AAC1D,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,SAAqB,CAAC;AAE5B,eAAW,SAAS,SAAS;AAC3B,YAAM,MAAM,GAAG,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI,MAAM,GAAG,IAAI,MAAM,IAAI;AAEnE,UAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,aAAK,IAAI,GAAG;AACZ,eAAO,KAAK,KAAK;AAAA,MACnB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,MAAc,UAA0B;AAE1D,UAAM,QAAQ,KAAK,kBAAkB,MAAM,QAAQ;AACnD,UAAM,MAAM,KAAK,gBAAgB,MAAM,QAAQ;AAE/C,WAAO,KAAK,UAAU,OAAO,GAAG,EAAE,KAAK;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,MAAc,KAAqB;AAC3D,aAAS,IAAI,MAAM,GAAG,KAAK,GAAG,KAAK;AACjC,YAAM,OAAO,KAAK,CAAC;AACnB,UAAI,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;AACjE,eAAO,IAAI;AAAA,MACb;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAc,KAAqB;AACzD,aAAS,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK;AACtC,YAAM,OAAO,KAAK,CAAC;AACnB,UAAI,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;AACjE,eAAO,IAAI;AAAA,MACb;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,eACE,YACA,cACY;AACZ,UAAM,UAAsB,CAAC;AAE7B,eAAW,YAAY,YAAY;AAEjC,YAAM,aAAa,aAAa,KAAK,gBAAc;AACjD,cAAM,UAAU,KAAK;AAAA,UACnB,WAAW;AAAA,UACX,WAAW;AAAA,UACX,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AACA,eAAO,UAAU;AAAA,MACnB,CAAC;AAED,UAAI,CAAC,YAAY;AACf,gBAAQ,KAAK,QAAQ;AAAA,MACvB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,oBAAiC;AAC/C,SAAO,IAAI,YAAY;AACzB;;;AC7XO,IAAM,0BAA2C;AAAA;AAAA,EAEtD;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,SAAS,UAAU,WAAW,SAAS,SAAS,SAAS;AAAA,IACpE,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,WAAW,QAAQ,UAAU,MAAM;AAAA,IAC9C,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,SAAS,YAAY,YAAY,iBAAiB;AAAA,IAChE,UAAU,CAAC,QAAQ,SAAS,OAAO,aAAa,UAAU,QAAQ,QAAQ,MAAM;AAAA,IAChF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa,CAAC,SAAS,YAAY,UAAU;AAAA,IAC7C,UAAU,CAAC,OAAO,YAAY;AAAA,IAC9B,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,MAAM,OAAO,MAAM,QAAQ,MAAM,QAAQ,aAAa,QAAQ,SAAS,IAAI;AAAA,IACtF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,QAAQ,SAAS,QAAQ,SAAS,WAAW,aAAa,QAAQ;AAAA,IAC7E,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,OAAO,KAAK,MAAM,QAAQ,MAAM;AAAA,IAC3C,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,OAAO,mBAAmB,0BAA0B,iBAAiB;AAAA,IAChF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,WAAW,QAAQ,UAAU,eAAe,aAAa;AAAA,IACpE,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,gBAAgB,kBAAkB,QAAQ,OAAO;AAAA,IAC/D,UAAU,CAAC,WAAW,QAAQ,kBAAkB,YAAY,cAAc;AAAA,IAC1E,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,QAAQ,eAAe,cAAc,QAAQ,cAAc,QAAQ,UAAU;AAAA,IACxF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,QAAQ,WAAW,QAAQ,kBAAkB;AAAA,IACxD,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,WAAW,gBAAgB;AAAA,IACzC,UAAU,CAAC,WAAW,UAAU,YAAY,cAAc,aAAa;AAAA,IACvE,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,OAAO,cAAc,cAAc,gBAAgB;AAAA,IACjE,UAAU,CAAC,WAAW,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACvE,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,OAAO,iBAAiB,cAAc,aAAa,QAAQ,UAAU;AAAA,IAChF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa;AAAA,IACb,UAAU,CAAC,YAAY,mBAAmB,WAAW;AAAA,IACrD,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,aAAa,CAAC,mBAAmB,iBAAiB;AAAA,IAClD,UAAU,CAAC,WAAW,WAAW,UAAU,WAAW,OAAO,WAAW;AAAA,IACxE,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AACF;AAKO,IAAM,8BAAkD;AAAA,EAC7D;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,MAAW;AAAA,MAAU;AAAA,MAAa;AAAA,MAAS;AAAA,MAAY;AAAA,MAAU;AAAA,MACjE;AAAA,MAAU;AAAA,MAAa;AAAA,MAAa;AAAA,MAAgB;AAAA,MAAc;AAAA,MAClE;AAAA,MAAQ;AAAA,MAAQ;AAAA,MAAO;AAAA,MAAY;AAAA,MAAS;AAAA,MAAU;AAAA,MAAO;AAAA,MAC7D;AAAA,MAAc;AAAA,MAAgB;AAAA,MAAY;AAAA,MAAY;AAAA,IACxD;AAAA,IACA,eAAe,CAAC,OAAO,cAAc,cAAc,OAAO,OAAO,SAAS;AAAA,IAC1E,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,MAAQ;AAAA,MAAS;AAAA,MAAS;AAAA,MAAY;AAAA,MAAU;AAAA,MAAW;AAAA,MAC3D;AAAA,MAAa;AAAA,MAAW;AAAA,MAAc;AAAA,MAAU;AAAA,MAAY;AAAA,MAC5D;AAAA,MAAc;AAAA,MAAY;AAAA,MAAW;AAAA,MAAW;AAAA,MAAc;AAAA,MAC9D;AAAA,MAAa;AAAA,MAAS;AAAA,MAAO;AAAA,MAAc;AAAA,IAC7C;AAAA,IACA,eAAe,CAAC,eAAe,UAAU,cAAc,OAAO;AAAA,IAC9D,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,MAAQ;AAAA,MAAW;AAAA,MAAW;AAAA,MAAe;AAAA,MAAY;AAAA,MAAQ;AAAA,MACjE;AAAA,MAAS;AAAA,MAAW;AAAA,MAAW;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAY;AAAA,MACjE;AAAA,MAAW;AAAA,MAAS;AAAA,MAAQ;AAAA,MAAa;AAAA,MAAQ;AAAA,MAAS;AAAA,MAC1D;AAAA,MAAO;AAAA,MAAO;AAAA,MAAa;AAAA,MAAW;AAAA,MAAS;AAAA,MAAY;AAAA,IAC7D;AAAA,IACA,eAAe,CAAC,gBAAgB,QAAQ,SAAS,WAAW,eAAe,SAAS;AAAA,IACpF,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,MAAY;AAAA,MAAS;AAAA,MAAa;AAAA,MAAa;AAAA,MAAmB;AAAA,MAClE;AAAA,MAAW;AAAA,MAAU;AAAA,MAAgB;AAAA,MAAY;AAAA,MAAc;AAAA,MAC/D;AAAA,MAAe;AAAA,MAAe;AAAA,MAAa;AAAA,MAAe;AAAA,MAC1D;AAAA,MAAc;AAAA,MAAgB;AAAA,MAAa;AAAA,MAAa;AAAA,IAC1D;AAAA,IACA,eAAe,CAAC,eAAe,WAAW,IAAI;AAAA,IAC9C,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,MAAO;AAAA,MAAO;AAAA,MAAS;AAAA,MAAU;AAAA,MAAY;AAAA,MAAc;AAAA,MAC3D;AAAA,MAAkB;AAAA,MAAiB;AAAA,MAAS;AAAA,MAAO;AAAA,MAAU;AAAA,MAC7D;AAAA,MAAU;AAAA,MAAW;AAAA,MAAU;AAAA,MAAU;AAAA,MAAY;AAAA,MAAW;AAAA,IAClE;AAAA,IACA,eAAe,CAAC,WAAW,OAAO,gBAAgB,kBAAkB,QAAQ;AAAA,IAC5E,aAAa;AAAA,EACf;AACF;AAKO,IAAM,qBAAN,MAAyB;AAAA,EAI9B,YAAY,QAA6B;AACvC,UAAM,cAAc,QAAQ,oBAAoB;AAEhD,SAAK,iBAAiB;AAAA,MACpB,GAAI,cAAc,0BAA0B,CAAC;AAAA,MAC7C,GAAI,QAAQ,kBAAkB,CAAC;AAAA,IACjC;AAEA,SAAK,qBAAqB;AAAA,MACxB,GAAI,cAAc,8BAA8B,CAAC;AAAA,MACjD,GAAI,QAAQ,sBAAsB,CAAC;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBACE,OACA,MACU;AACV,QAAI,qBAAqB,MAAM;AAG/B,UAAM,kBAAkB,KAAK,eAAe,OAAO,UAAQ;AACzD,UAAI,MAAM,QAAQ,KAAK,WAAW,GAAG;AACnC,eAAO,KAAK,YAAY,KAAK,UAAQ,MAAM,KAAK,SAAS,IAAI,CAAC;AAAA,MAChE;AACA,aAAO,MAAM,KAAK,SAAS,KAAK,WAAW;AAAA,IAC7C,CAAC;AAED,eAAW,QAAQ,iBAAiB;AAClC,YAAM,aAAa,KAAK;AAAA,QACtB;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK,mBAAmB;AAAA,QACxB,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AAEA,UAAI,YAAY;AACd,YAAI,KAAK,iBAAiB;AACxB,gCAAsB,KAAK;AAAA,QAC7B;AACA,YAAI,KAAK,mBAAmB;AAC1B,gCAAsB,KAAK;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAGA,yBAAqB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,kBAAkB,CAAC;AAEhE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBACE,SACA,MACY;AAEZ,UAAM,kBAAkB,KAAK,cAAc,IAAI;AAE/C,QAAI,gBAAgB,WAAW,GAAG;AAChC,aAAO;AAAA,IACT;AAGA,WAAO,QAAQ,IAAI,WAAS;AAC1B,UAAI,UAAU;AACd,UAAI,qBAAqB,MAAM;AAE/B,iBAAW,UAAU,iBAAiB;AACpC,cAAM,aAAa,KAAK,mBAAmB,KAAK,OAAK,EAAE,WAAW,MAAM;AAExE,YAAI,cAAc,WAAW,eAAe;AAC1C,gBAAM,cAAc,WAAW,cAAc;AAAA,YAAK,aAChD,MAAM,KAAK,SAAS,OAAO;AAAA,UAC7B;AAEA,cAAI,aAAa;AACf,kCAAsB,WAAW,eAAe;AAChD,sBAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS;AACX,eAAO;AAAA,UACL,GAAG;AAAA,UACH,YAAY,KAAK,IAAI,GAAG,kBAAkB;AAAA,QAC5C;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,eACN,MACA,YACA,UACA,UACA,iBACA,eACA,cACS;AAET,UAAM,aAAa,KAAK,UAAU,KAAK,IAAI,GAAG,aAAa,GAAG,GAAG,UAAU;AAC3E,UAAM,YAAY,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,QAAQ,WAAW,GAAG,CAAC;AAGhF,UAAM,cAAc,WAAW,MAAM,KAAK,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AACpE,UAAM,aAAa,UAAU,MAAM,KAAK,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AAGlE,UAAM,oBAAoB,YAAY,MAAM,CAAC,eAAe;AAC5D,UAAM,mBAAmB,WAAW,MAAM,GAAG,eAAe;AAG5D,UAAM,cAAc,kBAAkB,KAAK,GAAG,EAAE,YAAY;AAC5D,UAAM,aAAa,iBAAiB,KAAK,GAAG,EAAE,YAAY;AAE1D,eAAW,WAAW,UAAU;AAC9B,YAAM,eAAe,QAAQ,YAAY;AAEzC,UAAI,iBAAiB,YAAY,SAAS,YAAY,GAAG;AACvD,eAAO;AAAA,MACT;AAEA,UAAI,gBAAgB,WAAW,SAAS,YAAY,GAAG;AACrD,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,iBAAiB,CAAC,cAAc;AAEnC,YAAI,YAAY,SAAS,YAAY,KAAK,WAAW,SAAS,YAAY,GAAG;AAC3E,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,MAA4C;AAChE,UAAM,YAAY,KAAK,YAAY;AACnC,UAAM,kBAAgD,CAAC;AAEvD,eAAW,cAAc,KAAK,oBAAoB;AAChD,UAAI,YAAY;AAEhB,iBAAW,QAAQ,WAAW,OAAO;AACnC,YAAI,UAAU,SAAS,KAAK,YAAY,CAAC,GAAG;AAC1C;AAAA,QACF;AAAA,MACF;AAGA,UAAI,aAAa,GAAG;AAClB,wBAAgB,KAAK,WAAW,MAAM;AAAA,MACxC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,MAA2B;AAC1C,SAAK,eAAe,KAAK,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,YAAoC;AACtD,SAAK,mBAAmB,KAAK,UAAU;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAqC;AACnC,WAAO,CAAC,GAAG,KAAK,cAAc;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,wBAA4C;AAC1C,WAAO,CAAC,GAAG,KAAK,kBAAkB;AAAA,EACpC;AACF;AAKO,SAAS,yBAAyB,QAAiD;AACxF,SAAO,IAAI,mBAAmB,MAAM;AACtC;;;AC3bO,IAAM,uBAAsD;AAAA;AAAA,EAEjE,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA;AAAA,EACP,OAAO;AAAA;AAAA,EACP,WAAW;AAAA;AAAA,EACX,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,cAAc;AAAA,EACd,cAAc;AAAA,EACd,OAAO;AAAA,EACP,WAAW;AAAA,EACX,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,mBAAmB;AAAA;AAAA,EAGnB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA;AAAA,EACT,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,aAAa;AAAA;AAAA,EAGb,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,OAAO;AAAA;AAAA,EACP,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA;AAAA,EAClB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,sBAAsB;AAAA,EACtB,iBAAiB;AAAA;AAAA,EACjB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,mBAAmB;AAAA;AAAA,EACnB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA;AAAA,EAGlB,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,OAAO;AAAA,EACP,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AACjB;AAKO,IAAM,kBAAiD;AAAA,EAC5D,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AACT;AAKO,IAAM,qBAAN,MAAyB;AAAA,EAG9B,YAAY,WAA2C;AACrD,SAAK,cAAc;AAAA,MACjB,GAAG;AAAA,MACH,GAAI,aAAa,CAAC;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,aAA6C;AAEpD,QAAI,KAAK,YAAY,WAAW,GAAG;AACjC,aAAO;AAAA,QACL,OAAO,KAAK,YAAY,WAAW;AAAA,QACnC,OAAO,gBAAgB,KAAK,YAAY,WAAW,CAAC;AAAA,QACpD,QAAQ,uBAAuB,WAAW;AAAA,MAC5C;AAAA,IACF;AAGA,eAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AAC9D,UAAI,YAAY,SAAS,GAAG,KAAK,IAAI,SAAS,WAAW,GAAG;AAC1D,eAAO;AAAA,UACL,OAAO;AAAA,UACP,OAAO,gBAAgB,QAAQ;AAAA,UAC/B,QAAQ,kBAAkB,WAAW,WAAM,GAAG;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAGA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,gBAAgB,QAAQ;AAAA,MAC/B,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,SAAiC;AACrD,QAAI,QAAQ,UAAU;AACpB,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,KAAK,SAAS,QAAQ,IAAI;AAEjD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,eAAe;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,UAAsC;AACtD,WAAO,SAAS,IAAI,OAAK,KAAK,sBAAsB,CAAC,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,YAAuC;AACxD,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,OAAO;AAAA,QACP,SAAS;AAAA,UACP,UAAU;AAAA,UACV,aAAa;AAAA,UACb,eAAe;AAAA,UACf,eAAe;AAAA,UACf,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAGA,QAAI,gBAAgB;AACpB,QAAI,YAAY;AAChB,QAAI,cAAc;AAClB,QAAI,WAAW;AAGf,QAAI,kBAAkB;AACtB,QAAI,qBAAqB;AAEzB,eAAW,aAAa,YAAY;AAElC,UAAI,UAAU,aAAa,WAAY;AAAA,eAC9B,UAAU,aAAa,OAAQ;AAAA,eAC/B,UAAU,aAAa,SAAU;AAAA,eACjC,UAAU,aAAa,MAAO;AAGvC,yBAAmB,UAAU,cAAc;AAG3C,4BAAsB,gBAAgB,UAAU,QAAQ;AAAA,IAC1D;AAEA,UAAM,gBAAgB,kBAAkB,WAAW;AACnD,UAAM,cAAc,qBAAqB,WAAW;AAIpD,UAAM,cAAc,KAAK,IAAI,WAAW,SAAS,IAAI,CAAC;AACtD,UAAM,iBAAiB,cAAc;AACrC,UAAM,iBAAiB,KAAK,IAAI,gBAAgB,GAAG,CAAC;AACpD,UAAM,mBAAmB;AAEzB,UAAM,YACJ,MAAM,cACN,MAAM,iBACN,MAAM,iBACN,MAAM;AAGR,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,SAAS,CAAC;AAGvD,QAAI;AACJ,QAAI,gBAAgB,IAAK,SAAQ;AAAA,aACxB,gBAAgB,IAAK,SAAQ;AAAA,aAC7B,gBAAgB,IAAK,SAAQ;AAAA,aAC7B,gBAAgB,IAAK,SAAQ;AAAA,QACjC,SAAQ;AAEb,WAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,UAAU,WAAW;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,aAAoC;AAC9C,WAAO,KAAK,SAAS,WAAW,EAAE;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,aAA6B;AAC5C,WAAO,KAAK,SAAS,WAAW,EAAE;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,aAAqB,UAA+B;AACrE,SAAK,YAAY,WAAW,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAgD;AAC9C,WAAO,EAAE,GAAG,KAAK,YAAY;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,iBACE,YACA,aACgB;AAChB,UAAM,WAAW,gBAAgB,WAAW;AAE5C,WAAO,WAAW,OAAO,eAAa;AACpC,YAAM,QAAQ,gBAAgB,UAAU,QAAQ;AAChD,aAAO,SAAS;AAAA,IAClB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,YAAmE;AACjF,UAAM,UAAiD;AAAA,MACrD,UAAU,CAAC;AAAA,MACX,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC;AAAA,MACT,KAAK,CAAC;AAAA,IACR;AAEA,eAAW,aAAa,YAAY;AAClC,cAAQ,UAAU,QAAQ,EAAE,KAAK,SAAS;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,yBAAyB,WAA+D;AACtG,SAAO,IAAI,mBAAmB,SAAS;AACzC;AAKO,SAAS,YAAY,aAAoC;AAC9D,QAAM,aAAa,IAAI,mBAAmB;AAC1C,SAAO,WAAW,YAAY,WAAW;AAC3C;AAKO,SAAS,cAAc,YAAuC;AACnE,QAAM,aAAa,IAAI,mBAAmB;AAC1C,SAAO,WAAW,mBAAmB,UAAU;AACjD;;;ACpYO,IAAM,WAAN,MAAqB;AAAA,EAI1B,YAAY,UAAkB,KAAK;AACjC,SAAK,QAAQ,oBAAI,IAAI;AACrB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,KAAuB;AACzB,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,UAAU,QAAW;AAEvB,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,MAAM,IAAI,KAAK,KAAK;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,KAAQ,OAAgB;AAE1B,QAAI,KAAK,MAAM,IAAI,GAAG,GAAG;AACvB,WAAK,MAAM,OAAO,GAAG;AAAA,IACvB;AAGA,SAAK,MAAM,IAAI,KAAK,KAAK;AAGzB,QAAI,KAAK,MAAM,OAAO,KAAK,SAAS;AAClC,YAAM,WAAW,KAAK,MAAM,KAAK,EAAE,KAAK,EAAE;AAC1C,WAAK,MAAM,OAAO,QAAQ;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,IAAI,KAAiB;AACnB,WAAO,KAAK,MAAM,IAAI,GAAG;AAAA,EAC3B;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAKO,SAAS,WAAW,KAAqB;AAC9C,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,OAAO,IAAI,WAAW,CAAC;AAC7B,YAAS,QAAQ,KAAK,OAAQ;AAC9B,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,KAAK,SAAS,EAAE;AACzB;;;ACCO,IAAM,aAAN,MAAiB;AAAA,EAWtB,YAAY,UAAyB;AACnC,SAAK,WAAW;AAChB,SAAK,WAAW,SAAS,YAAY;AAGrC,UAAM,aAAa,SAAS,OAAO,+BAA+B;AAClE,UAAM,gBAAgB,WAAW,WAAW,SAAS,KAAK,WAAW,WAAW,CAAC,EAAE,eAAe;AAGlG,UAAM,kBAAmB,SAAiB;AAG1C,SAAK,UAAU;AAAA,MACb,uBAAuB;AAAA,MACvB,qBAAqB,iBAAiB,uBAAuB;AAAA,MAC7D,2BAA2B,iBAAiB,6BAA6B;AAAA,MACzE,wBAAwB,iBAAiB,0BAA0B;AAAA,MACnE,WAAW,iBAAiB,aAAa,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,MAA+B;AACrC,UAAM,iBAAuC,CAAC;AAC9C,UAAM,kBAAwC,CAAC;AAC/C,UAAM,oBAA0C,CAAC;AACjD,UAAM,mBAAyC,CAAC;AAGhD,eAAW,WAAW,KAAK,UAAU;AACnC,YAAM,QAAQ,IAAI,OAAO,QAAQ,MAAM,QAAQ,QAAQ,MAAM,KAAK;AAClE,YAAM,QAAQ,MAAM,KAAK,IAAI;AAE7B,UAAI,CAAC,OAAO;AAEV,cAAMC,UAA6B;AAAA,UACjC;AAAA,UACA,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AACA,uBAAe,KAAKA,OAAM;AAC1B,0BAAkB,KAAKA,OAAM;AAC7B;AAAA,MACF;AAGA,YAAM,QAAQ,MAAM,CAAC,MAAM,SAAY,MAAM,CAAC,IAAI,MAAM,CAAC;AACzD,YAAM,YAAY,MAAM,CAAC;AAEzB,UAAI;AACJ,UAAI;AAEJ,UAAI,MAAM,CAAC,MAAM,QAAW;AAC1B,cAAM,eAAe,UAAU,QAAQ,KAAK;AAC5C,mBAAW,MAAM,QAAQ;AACzB,iBAAS,WAAW,MAAM;AAAA,MAC5B,OAAO;AACL,mBAAW,MAAM;AACjB,iBAAS,WAAW,MAAM;AAAA,MAC5B;AAGA,YAAM,eAAe,KAAK,IAAI,GAAG,WAAW,EAAE;AAC9C,YAAM,aAAa,KAAK,IAAI,KAAK,QAAQ,SAAS,EAAE;AACpD,YAAM,UAAU,KAAK,UAAU,cAAc,UAAU;AAEvD,YAAM,SAA6B;AAAA,QACjC;AAAA,QACA,SAAS;AAAA,QACT,cAAc;AAAA,QACd,UAAU,CAAC,UAAU,MAAM;AAAA,MAC7B;AAGA,UAAI,QAAQ,WAAW;AACrB,cAAM,kBAAkB,QAAQ,UAAU,OAAO,OAAO;AACxD,eAAO,kBAAkB;AAEzB,YAAI,CAAC,iBAAiB;AACpB,iBAAO,SAAS;AAChB,yBAAe,KAAK,MAAM;AAC1B,2BAAiB,KAAK,MAAM;AAC5B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK,QAAQ,2BAA2B;AAC1C,cAAM,WAAW,gBAAgB,OAAO,QAAQ,MAAM,OAAO;AAC7D,eAAO,qBAAqB;AAAA,UAC1B,iBAAiB,SAAS;AAAA,UAC1B,YAAY,SAAS;AAAA,UACrB,QAAQ,SAAS,aAAa;AAAA,QAChC;AAEA,YAAI,SAAS,mBAAmB,SAAS,cAAc,KAAK,QAAQ,wBAAwB;AAC1F,iBAAO,SAAS,+BAA+B,SAAS,aAAa,eAAe,gBAAgB;AACpG,yBAAe,KAAK,MAAM;AAC1B,2BAAiB,KAAK,MAAM;AAC5B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK,QAAQ,uBAAuB;AACtC,cAAM,kBAAkB;AAAA,UACtB;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AACA,eAAO,kBAAkB;AAEzB,YAAI,gBAAgB,aAAa,KAAK,QAAQ,qBAAqB;AACjE,iBAAO,SAAS,oBAAoB,gBAAgB,aAAa,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,QAAQ,sBAAsB,GAAG;AAC7H,yBAAe,KAAK,MAAM;AAC1B,2BAAiB,KAAK,MAAM;AAC5B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK,QAAQ,UAAU;AAAA,QAAK,UAC9B,MAAM,YAAY,EAAE,SAAS,KAAK,YAAY,CAAC;AAAA,MACjD,GAAG;AACD,eAAO,SAAS;AAChB,uBAAe,KAAK,MAAM;AAC1B,yBAAiB,KAAK,MAAM;AAC5B;AAAA,MACF;AAGA,qBAAe,KAAK,MAAM;AAC1B,sBAAgB,KAAK,MAAM;AAAA,IAC7B;AAGA,UAAM,aAAa,KAAK,SAAS,OAAO,IAAI,EAAE;AAE9C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,sBAAsB,KAAK,SAAS;AAAA,QACpC,iBAAiB,gBAAgB;AAAA,QACjC,kBAAkB,iBAAiB;AAAA,QACnC,iBAAiB,WAAW;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,WAAyB,MAKxC;AACA,UAAM,UAAU,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,UAAU,IAAI;AACjE,UAAM,YAAsB,CAAC;AAE7B,cAAU,KAAK,eAAe,UAAU,IAAI,EAAE;AAC9C,cAAU,KAAK,aAAa,UAAU,QAAQ,EAAE;AAEhD,QAAI,UAAU,eAAe,QAAW;AACtC,gBAAU,KAAK,gBAAgB,UAAU,aAAa,KAAK,QAAQ,CAAC,CAAC,GAAG;AAAA,IAC1E;AAEA,QAAI,SAAS;AACX,gBAAU,KAAK,oBAAoB,QAAQ,eAAe,QAAQ,IAAI,EAAE;AACxE,gBAAU,KAAK,qBAAqB,QAAQ,QAAQ,EAAE;AAAA,IACxD;AAEA,QAAI;AACJ,QAAI,UAAU,eAAe,QAAW;AAEtC,YAAM,CAAC,OAAO,GAAG,IAAI,UAAU;AAC/B,wBAAkB;AAAA,QAChB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAEA,UAAI,iBAAiB;AACnB,kBAAU,KAAK,kBAAkB,gBAAgB,YAAY,EAAE;AAC/D,kBAAU,KAAK,wBAAwB,gBAAgB,aAAa,KAAK,QAAQ,CAAC,CAAC,GAAG;AAAA,MACxF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAc,cAKvB;AACA,UAAM,cAAwB,CAAC;AAC/B,UAAM,kBAAgC,CAAC;AAGvC,UAAM,eAAe,KAAK,SAAS;AAAA,MAAO,OACxC,EAAE,SAAS,gBAAgB,EAAE,KAAK,SAAS,YAAY;AAAA,IACzD;AAEA,QAAI,aAAa,WAAW,GAAG;AAC7B,kBAAY,KAAK,+BAA+B,YAAY,EAAE;AAC9D,kBAAY,KAAK,sBAAsB,CAAC,GAAG,IAAI,IAAI,KAAK,SAAS,IAAI,OAAK,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AAC9F,aAAO,EAAE,MAAM,cAAc,aAAa,gBAAgB;AAAA,IAC5D;AAGA,eAAW,WAAW,cAAc;AAClC,YAAM,QAAQ,IAAI,OAAO,QAAQ,MAAM,QAAQ,QAAQ,MAAM,KAAK;AAClE,YAAM,QAAQ,MAAM,KAAK,IAAI;AAE7B,UAAI,OAAO;AACT,wBAAgB,KAAK,OAAO;AAC5B,cAAM,QAAQ,MAAM,CAAC,MAAM,SAAY,MAAM,CAAC,IAAI,MAAM,CAAC;AACzD,oBAAY,KAAK,YAAY,QAAQ,IAAI,qBAAqB,KAAK,GAAG;AAGtE,cAAM,cAAc,KAAK,QAAQ,IAAI;AACrC,cAAM,WAAW,YAAY,iBAAiB,KAAK,OAAK,EAAE,QAAQ,SAAS,QAAQ,IAAI;AAEvF,YAAI,YAAY,SAAS,QAAQ;AAC/B,sBAAY,KAAK,qBAAqB,SAAS,MAAM,EAAE;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB,WAAW,GAAG;AAChC,kBAAY,KAAK,yBAAyB,YAAY,WAAW;AACjE,kBAAY,KAAK,mBAAmB;AACpC,kBAAY,KAAK,2CAA4C;AAC7D,kBAAY,KAAK,iCAAiC;AAClD,kBAAY,KAAK,6BAA6B;AAC9C,kBAAY,KAAK,2BAA2B;AAG5C,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,iBAAiB,aAAa,CAAC;AACrC,oBAAY,KAAK;AAAA,UAAa,YAAY,aAAa,eAAe,MAAM,OAAO,UAAU,GAAG,GAAG,CAAC,KAAK;AAAA,MAC3G;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MASJ;AACA,UAAM,QAAQ,YAAY,IAAI;AAC9B,UAAM,cAAc,KAAK,QAAQ,IAAI;AACrC,UAAM,WAAW,YAAY,IAAI,IAAI;AAErC,UAAM,kBAA4B,CAAC;AACnC,QAAI,KAAK,QAAQ,uBAAuB;AACtC,sBAAgB,KAAK,kBAAkB;AAAA,IACzC;AACA,QAAI,KAAK,QAAQ,2BAA2B;AAC1C,sBAAgB,KAAK,uBAAuB;AAAA,IAC9C;AACA,QAAI,KAAK,QAAQ,UAAU,SAAS,GAAG;AACrC,sBAAgB,KAAK,cAAc,KAAK,QAAQ,UAAU,MAAM,WAAW;AAAA,IAC7E;AAEA,WAAO;AAAA,MACL;AAAA,MACA,YAAY,KAAK;AAAA,MACjB;AAAA,MACA,cAAc,KAAK,SAAS;AAAA,MAC5B;AAAA,MACA,aAAa;AAAA,QACX,eAAe,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,iBAAiB,UAAqC;AACpE,SAAO,IAAI,WAAW,QAAQ;AAChC;;;AC5VO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAAY,WAA0B;AAAA,EAEtC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,QAAyB,SAAgC;AAChE,UAAM,OAAgC;AAAA,MACpC,QAAQ,QAAQ;AAAA,MAChB,MAAM,QAAQ,QAAQ;AAAA,MACtB,OAAO,QAAQ,SAAS;AAAA,MACxB,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,yBAAyB,QAAQ,2BAA2B;AAAA,MAC5D,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,oBAAoB,QAAQ,sBAAsB;AAAA,MAClD,kBAAkB,QAAQ,oBAAoB;AAAA,MAC9C,UAAU,QAAQ,YAAY,CAAC;AAAA,IACjC;AAEA,QAAI,KAAK,WAAW,QAAQ;AAC1B,aAAO,KAAK,aAAa,QAAQ,IAAI;AAAA,IACvC,OAAO;AACL,aAAO,KAAK,iBAAiB,QAAQ,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,QAAyB,SAA0C;AACtF,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,QAAQ,KAAK,oBAAoB,MAAM;AAE7C,QAAI,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKJ,KAAK,WAAW,QAAQ,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAsJ/B,KAAK,WAAW,QAAQ,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA,qDAIa,SAAS;AAAA;AAAA;AAAA,wDAGN,KAAK,WAAW,QAAQ,gBAAgB,CAAC;AAAA;AAAA;AAK7F,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AAC3D,cAAQ;AAAA,mCACqB,KAAK,WAAW,GAAG,CAAC,YAAY,KAAK,WAAW,KAAK,CAAC;AAAA;AAAA;AAAA,IAGrF;AAEA,YAAQ;AAAA;AAIR,QAAI,QAAQ,mBAAmB;AAC7B,cAAQ;AAAA;AAAA;AAAA,8BAGgB,MAAM,kBAAkB,IAAI,YAAY,SAAS;AAAA,kCAC7C,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA,kCAIrB,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,kCAIjB,MAAM,YAAY;AAAA;AAAA;AAAA,QAG5C,OAAO,OAAO,iBAAiB;AAAA;AAAA,kCAEL,OAAO,MAAM,cAAc;AAAA;AAAA,gBAE7C,EAAE;AAAA;AAAA;AAKZ,cAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYR,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,aAAa,GAAG;AAC/D,cAAM,cAAe,QAAQ,MAAM,kBAAmB,KAAK,QAAQ,CAAC;AACpE,gBAAQ;AAAA,gBACA,KAAK,WAAW,IAAI,CAAC;AAAA,gBACrB,KAAK;AAAA,gBACL,UAAU;AAAA;AAAA;AAAA,MAGpB;AACA,cAAQ;AAAA;AAAA;AAAA,IAGV;AAGA,QAAI,QAAQ,2BAA2B,OAAO,WAAW,SAAS,GAAG;AACnE,cAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASF,OAAO,WAAW,CAAC,EAAE,eAAe,SAAY,wBAAwB,EAAE;AAAA;AAAA;AAAA;AAAA;AAKhF,iBAAW,aAAa,OAAO,YAAY;AACzC,cAAM,gBAAgB,UAAU,aAAa,SAAS,eACjC,UAAU,aAAa,WAAW,iBAAiB;AACxE,gBAAQ;AAAA,gBACA,KAAK,WAAW,UAAU,IAAI,CAAC;AAAA,sBACzB,KAAK,WAAW,UAAU,KAAK,CAAC;AAAA,gBACtC,UAAU,SAAS,CAAC,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAAA,mCAC3B,aAAa,KAAK,UAAU,SAAS,YAAY,CAAC;AAAA,YACzE,UAAU,eAAe,SAAY,QAAQ,UAAU,aAAa,KAAK,QAAQ,CAAC,CAAC,WAAW,EAAE;AAAA;AAAA;AAAA,MAGtG;AACA,cAAQ;AAAA;AAAA;AAAA,IAGV;AAGA,QAAI,QAAQ,qBAAqB;AAC/B,cAAQ;AAAA;AAAA,4BAEc,KAAK,WAAW,OAAO,QAAQ,CAAC;AAAA;AAAA,IAExD;AAGA,QAAI,QAAQ,qBAAqB;AAC/B,cAAQ;AAAA;AAAA,4BAEc,KAAK,WAAW,OAAO,QAAQ,CAAC;AAAA;AAAA,IAExD;AAGA,YAAQ;AAAA;AAAA;AAAA,wBAGY,QAAQ,KAAK,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAM9C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,QAAyB,SAA0C;AAC1F,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,QAAQ,KAAK,oBAAoB,MAAM;AAE7C,QAAI,KAAK,KAAK,QAAQ,KAAK;AAAA;AAAA;AAG3B,UAAM;AAAA;AAAA;AACN,UAAM,oBAAoB,SAAS;AAAA;AACnC,UAAM,uBAAuB,QAAQ,gBAAgB;AAAA;AACrD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AAC3D,YAAM,OAAO,GAAG,OAAO,KAAK;AAAA;AAAA,IAC9B;AACA,UAAM;AAAA;AAGN,QAAI,QAAQ,mBAAmB;AAC7B,YAAM;AAAA;AAAA;AACN,YAAM;AAAA;AACN,YAAM;AAAA;AACN,YAAM,0BAA0B,MAAM,eAAe;AAAA;AACrD,YAAM,oBAAoB,MAAM,WAAW;AAAA;AAC3C,YAAM,qBAAqB,MAAM,YAAY;AAAA;AAC7C,UAAI,OAAO,OAAO,gBAAgB;AAChC,cAAM,uBAAuB,OAAO,MAAM,cAAc;AAAA;AAAA,MAC1D;AACA,YAAM;AAAA;AAGN,YAAM;AAAA;AAAA;AACN,YAAM;AAAA;AACN,YAAM;AAAA;AACN,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,aAAa,GAAG;AAC/D,cAAM,cAAe,QAAQ,MAAM,kBAAmB,KAAK,QAAQ,CAAC;AACpE,cAAM,KAAK,IAAI,MAAM,KAAK,MAAM,UAAU;AAAA;AAAA,MAC5C;AACA,YAAM;AAAA;AAAA,IACR;AAGA,QAAI,QAAQ,2BAA2B,OAAO,WAAW,SAAS,GAAG;AACnE,YAAM;AAAA;AAAA;AACN,YAAM,yCAAyC,OAAO,WAAW,CAAC,EAAE,eAAe,SAAY,kBAAkB,EAAE;AAAA;AACnH,YAAM,yCAAyC,OAAO,WAAW,CAAC,EAAE,eAAe,SAAY,kBAAkB,EAAE;AAAA;AACnH,iBAAW,aAAa,OAAO,YAAY;AACzC,cAAM,KAAK,UAAU,IAAI,QAAQ,UAAU,KAAK,QAAQ,UAAU,SAAS,CAAC,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC,MAAM,UAAU,SAAS,YAAY,CAAC;AAC5I,YAAI,UAAU,eAAe,QAAW;AACtC,gBAAM,KAAK,UAAU,aAAa,KAAK,QAAQ,CAAC,CAAC;AAAA,QACnD;AACA,cAAM;AAAA;AAAA,MACR;AACA,YAAM;AAAA;AAAA,IACR;AAGA,QAAI,QAAQ,qBAAqB;AAC/B,YAAM;AAAA;AAAA;AACN,YAAM;AAAA,EAAW,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,IAClC;AAGA,QAAI,QAAQ,qBAAqB;AAC/B,YAAM;AAAA;AAAA;AACN,YAAM;AAAA;AAAA;AACN,YAAM;AAAA,EAAW,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,IAClC;AAGA,UAAM;AAAA;AAAA;AACN,UAAM;AAAA;AACN,UAAM,iBAAiB,QAAQ,KAAK,YAAY,CAAC;AAAA;AAEjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,QAK1B;AACA,UAAM,gBAAwC,CAAC;AAC/C,QAAI,eAAe;AAEnB,eAAW,aAAa,OAAO,YAAY;AACzC,oBAAc,UAAU,IAAI,KAAK,cAAc,UAAU,IAAI,KAAK,KAAK;AACvE,UAAI,UAAU,aAAa,QAAQ;AACjC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,iBAAiB,OAAO,WAAW;AAAA,MACnC,aAAa,OAAO,KAAK,aAAa,EAAE;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,MAAsB;AACvC,UAAM,MAA8B;AAAA,MAClC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,WAAO,KAAK,QAAQ,YAAY,OAAK,IAAI,CAAC,CAAC;AAAA,EAC7C;AACF;AAKO,SAAS,sBAAsB,UAA0C;AAC9E,SAAO,IAAI,gBAAgB,QAAQ;AACrC;;;AC7dO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YAAY,eAAmC,UAAqC,CAAC,GAAG;AACtF,SAAK,gBAAgB;AACrB,SAAK,UAAU;AAAA,MACb,gBAAgB,QAAQ,kBAAkB;AAAA;AAAA,MAC1C,eAAe,QAAQ,iBAAiB;AAAA;AAAA,MACxC,uBAAuB,QAAQ,yBAAyB;AAAA;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,UAAsC;AAErD,UAAM,mBAAmB,KAAK,cAAc,oBAAoB;AAChE,UAAM,qBAAqB,KAAK,cAAc,yBAAyB;AAGvE,UAAM,gBAAgB,oBAAI,IAAoB;AAE9C,eAAW,SAAS,kBAAkB;AAEpC,YAAM,cAAc,MAAM;AAI1B,YAAM,eAAe,KAAK,iBAAiB,MAAM,OAAO;AAExD,UAAI,cAAc;AAChB,sBAAc,IAAI,eAAe,cAAc,IAAI,YAAY,KAAK,KAAK,WAAW;AAAA,MACtF;AAAA,IACF;AAGA,UAAM,gBAAgB,oBAAI,IAAoB;AAE9C,eAAW,cAAc,oBAAoB;AAC3C,oBAAc,IAAI,WAAW,OAAO,cAAc,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,WAAW;AAAA,IACvG;AAGA,UAAM,wBAAwB,oBAAI,IAAoB;AACtD,eAAW,WAAW,UAAU;AAC9B,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AACnD,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AAInD,YAAM,YAAY,KAAK,IAAI,UAAU,UAAU,IAAI,CAAC;AACpD,4BAAsB,IAAI,QAAQ,MAAM,SAAS;AAAA,IACnD;AAGA,UAAM,oBAAoB,SAAS,IAAI,aAAW;AAChD,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AACnD,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AACnD,YAAM,kBAAkB,sBAAsB,IAAI,QAAQ,IAAI,KAAK;AAGnE,UAAI,kBAAkB,KAAK,QAAQ,eAAe;AAChD,eAAO;AAAA,MACT;AAGA,UAAI,aAAa;AAGjB,YAAM,SAAS,UAAU;AACzB,UAAI,SAAS,KAAK;AAChB,sBAAc,SAAS,KAAK,QAAQ;AAAA,MACtC;AAGA,YAAM,SAAS,UAAU;AACzB,UAAI,SAAS,KAAK;AAChB,sBAAc,SAAS,KAAK,QAAQ;AAAA,MACtC;AAGA,oBAAc,KAAK,QAAQ;AAG3B,mBAAa,KAAK;AAAA,QAChB,CAAC,KAAK,QAAQ;AAAA,QACd,KAAK,IAAI,KAAK,QAAQ,uBAAuB,UAAU;AAAA,MACzD;AAGA,YAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,QAAQ,WAAW,UAAU,CAAC;AAG5E,UAAI,KAAK,IAAI,UAAU,IAAI,GAAG;AAC5B,eAAO;AAAA,UACL,GAAG;AAAA,UACH,UAAU,KAAK,MAAM,WAAW;AAAA,QAClC;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,UAAwC;AACtD,UAAM,mBAAmB,KAAK,cAAc,oBAAoB;AAChE,UAAM,qBAAqB,KAAK,cAAc,yBAAyB;AAGvE,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,eAAW,SAAS,kBAAkB;AACpC,YAAM,eAAe,KAAK,iBAAiB,MAAM,OAAO;AACxD,UAAI,cAAc;AAChB,sBAAc,IAAI,eAAe,cAAc,IAAI,YAAY,KAAK,KAAK,MAAM,WAAW;AAAA,MAC5F;AAAA,IACF;AAEA,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,eAAW,cAAc,oBAAoB;AAC3C,oBAAc,IAAI,WAAW,OAAO,cAAc,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,WAAW;AAAA,IACvG;AAGA,UAAM,QAAwB,SAAS,IAAI,aAAW;AACpD,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AACnD,YAAM,UAAU,cAAc,IAAI,QAAQ,IAAI,KAAK;AACnD,YAAM,kBAAkB,KAAK,IAAI,UAAU,UAAU,IAAI,CAAC;AAC1D,YAAM,YAAY,UAAU;AAC5B,YAAM,YAAY,kBAAkB,aAAa;AAEjD,aAAO;AAAA,QACL,MAAM,QAAQ;AAAA,QACd;AAAA,QACA,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB;AAAA,QACA,UAAU,QAAQ;AAAA,QAClB,kBAAkB,QAAQ;AAAA;AAAA,MAC5B;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,OAA8B;AAErD,QAAI,IAAI,KAAK,KAAK,EAAG,QAAO;AAG5B,QAAI,wBAAwB,KAAK,KAAK,EAAG,QAAO;AAGhD,QAAI,sBAAsB,KAAK,KAAK,EAAG,QAAO;AAG9C,QAAI,8CAA8C,KAAK,KAAK,EAAG,QAAO;AAGtE,QAAI,uCAAuC,KAAK,KAAK,EAAG,QAAO;AAG/D,QAAI,oCAAoC,KAAK,KAAK,EAAG,QAAO;AAG5D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,UAAsC;AAGpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAA+B;AAC7B,WAAO,EAAE,GAAG,KAAK,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,SAA0C;AACnD,SAAK,UAAU;AAAA,MACb,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAKO,SAAS,wBACd,eACA,SACmB;AACnB,SAAO,IAAI,kBAAkB,eAAe,OAAO;AACrD;;;ACjOO,IAAM,qBAAN,MAAM,4BAA2B,MAAM;AAAA,EAK5C,YACE,SACA,OAAe,uBACf,YACA,SACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,UAAU;AAGf,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,mBAAkB;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA8B;AAC5B,QAAI,YAAY,IAAI,KAAK,IAAI,KAAK,KAAK,OAAO;AAE9C,QAAI,KAAK,YAAY;AACnB,mBAAa;AAAA;AAAA,cAAmB,KAAK,WAAW,OAAO;AAEvD,UAAI,KAAK,WAAW,MAAM;AACxB,qBAAa;AAAA;AAAA;AAAA,EAAa,KAAK,WAAW,IAAI;AAAA,MAChD;AAEA,UAAI,KAAK,WAAW,MAAM;AACxB,qBAAa;AAAA;AAAA,QAAa,KAAK,WAAW,IAAI;AAAA,MAChD;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,OAAO,KAAK,KAAK,OAAO,EAAE,SAAS,GAAG;AACxD,mBAAa;AAAA;AAAA,WAAgB,KAAK,UAAU,KAAK,SAAS,MAAM,CAAC,CAAC;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AACF;AAMO,SAAS,0BAA0B,aAAqB,QAAoC;AACjG,SAAO,IAAI;AAAA,IACT,oBAAoB,WAAW,MAAM,MAAM;AAAA,IAC3C;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,WACD,WAAW;AAAA;AAAA,mBAEH,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMxB,MAAM;AAAA,IACR;AAAA,IACA,EAAE,aAAa,OAAO;AAAA,EACxB;AACF;AAEO,SAAS,sBAAsB,OAAe,aAAyC;AAC5F,SAAO,IAAI;AAAA,IACT,UAAU,KAAK,yCAAyC,WAAW;AAAA,IACnE;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM,4BAA4B,KAAK;AAAA,MACvC,MAAM;AAAA,IACR;AAAA,IACA,EAAE,OAAO,YAAY;AAAA,EACvB;AACF;AAEO,SAAS,sBAAsB,UAAsC;AAC1E,QAAM,UAAU,WAAW,OAAO,MAAM,QAAQ,CAAC;AAEjD,SAAO,IAAI;AAAA,IACT,gBAAgB,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUN,MAAM;AAAA,IACR;AAAA,IACA,EAAE,UAAU,OAAO;AAAA,EACrB;AACF;AAEO,SAAS,sBAAsBC,OAAc,QAAoC;AACtF,SAAO,IAAI;AAAA,IACT,+BAA+BA,KAAI,MAAM,MAAM;AAAA,IAC/C;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMN,MAAM;AAAA,IACR;AAAA,IACA,EAAE,MAAAA,OAAM,OAAO;AAAA,EACjB;AACF;AAEO,SAAS,8BAAkD;AAChE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA,MAIN,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,kCAAsD;AACpE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQN,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,+BAAmD;AACjE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA,MAIN,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,2BAA+C;AAC7D,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA;AAAA;AAAA;AAAA,MAIN,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC/LO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,SAAiB,SAAiB;AAC5C,UAAM,uCAAuC,OAAO,OAAO,OAAO,EAAE;AACpE,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAY,SAAiB,YAAoB;AAC/C,UAAM,2CAA2C,UAAU,KAAK,OAAO,EAAE;AACzE,SAAK,OAAO;AAAA,EACd;AACF;AAQO,SAAS,SACd,OACA,MACA,UAA4B,CAAC,GACL;AACxB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,YAAY,YAAY,IAAI;AAKlC,MAAI;AACF,UAAM,SAAS,MAAM,KAAK,IAAI;AAG9B,UAAM,UAAU,YAAY,IAAI,IAAI;AACpC,QAAI,UAAU,SAAS;AACrB,YAAM,IAAI,kBAAkB,MAAM,QAAQ,OAAO;AAAA,IACnD;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,mBAAmB;AACtC,YAAM;AAAA,IACR;AAEA,UAAM;AAAA,EACR;AACF;AAMO,SAAS,YACd,OACA,MACA,UAA4B,CAAC,GACV;AACnB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,YAAY,YAAY,IAAI;AAClC,QAAM,UAA6B,CAAC;AAGpC,MAAI,CAAC,MAAM,QAAQ;AACjB,UAAMC,SAAQ,SAAS,OAAO,MAAM,OAAO;AAC3C,WAAOA,SAAQ,CAACA,MAAK,IAAI,CAAC;AAAA,EAC5B;AAEA,MAAI;AACJ,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,QAAM,gBAAgB;AAEtB,UAAQ,QAAQ,MAAM,KAAK,IAAI,OAAO,MAAM;AAC1C,YAAQ,KAAK,KAAK;AAGlB,QAAI,MAAM,UAAU,WAAW;AAC7B,YAAM;AAAA,IACR;AACA,gBAAY,MAAM;AAGlB,QAAI,QAAQ,UAAU,YAAY;AAChC,YAAM,IAAI,qBAAqB,MAAM,QAAQ,UAAU;AAAA,IACzD;AAGA;AACA,QAAI,eAAe,kBAAkB,GAAG;AACtC,YAAM,UAAU,YAAY,IAAI,IAAI;AACpC,UAAI,UAAU,SAAS;AACrB,cAAM,IAAI,kBAAkB,MAAM,QAAQ,OAAO;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,gBAAgB,SAA0B;AAKxD,MAAI,sBAAsB,KAAK,OAAO,GAAG;AACvC,WAAO;AAAA,EACT;AAIA,MAAI,gCAAgC,KAAK,OAAO,GAAG;AACjD,WAAO;AAAA,EACT;AAIA,SAAO;AACT;AAMO,SAAS,gBAAgB,SAAgC;AAC9D,QAAM,aAAa,OAAO,YAAY,WAAW,UAAU,QAAQ;AAGnE,MAAI,WAAW,SAAS,KAAM;AAC5B,UAAM,IAAI,MAAM,2BAA2B,WAAW,MAAM,mBAAmB;AAAA,EACjF;AAGA,MAAI,gBAAgB,UAAU,GAAG;AAC/B,UAAM,IAAI,MAAM,8CAA8C,WAAW,UAAU,GAAG,GAAG,CAAC,KAAK;AAAA,EACjG;AAGA,MAAI;AACF,QAAI,OAAO,UAAU;AAAA,EACvB,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,0BAA2B,MAAgB,OAAO,EAAE;AAAA,EACtE;AACF;AAKO,SAAS,iBACd,SACA,OACQ;AACR,QAAM,aAAa,OAAO,YAAY,WAAW,UAAU,QAAQ;AACnE,QAAM,aAAa,UAAU,OAAO,YAAY,WAAW,SAAY,QAAQ;AAG/E,kBAAgB,UAAU;AAE1B,SAAO,IAAI,OAAO,YAAY,UAAU;AAC1C;;;ACtIO,IAAM,gBAAN,MAAM,eAAc;AAAA,EA8CzB,YAAY,UAWR,CAAC,GAAG;AAvDR,SAAQ,mBAA4C,oBAAI,IAAI;AA6B5D,SAAQ,qBAA0C,oBAAI,IAAI;AAC1D,SAAQ,qBAA0C,oBAAI,IAAI;AA2BxD,UAAM,gBAAgB,QAAQ,SAAS,UAAU,QAAQ,MAAM,IAAI,CAAC;AAGpE,UAAM,gBAAgB;AAAA,MACpB,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,UAAU,CAAC;AAAA,MACX,YAAY,CAAC;AAAA;AAAA,MACb,gBAAgB,CAAC;AAAA,MACjB,WAAW,CAAC;AAAA,MACZ,eAAe;AAAA,MACf,eAAe;AAAA;AAAA,MACf,uBAAuB;AAAA;AAAA,MACvB,qBAAqB;AAAA;AAAA,MACrB,2BAA2B;AAAA;AAAA,MAC3B,wBAAwB;AAAA,MACxB,iBAAiB;AAAA;AAAA,MACjB,gBAAgB;AAAA;AAAA,MAChB,aAAa;AAAA;AAAA,MACb,WAAW;AAAA;AAAA,MACX,4BAA4B;AAAA;AAAA,MAC5B,OAAO;AAAA;AAAA,MACP,cAAc,KAAK,OAAO;AAAA;AAAA,MAC1B,cAAc;AAAA;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,kBAAkB;AAAA,QAChB,gBAAgB,QAAQ,kBAAkB,kBAAkB;AAAA,QAC5D,eAAe,QAAQ,kBAAkB,iBAAiB;AAAA,QAC1D,uBAAuB,QAAQ,kBAAkB,yBAAyB;AAAA,MAC5E;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,aAAa;AAC5B,WAAK,cAAc,IAAI,SAAkC,KAAK,QAAQ,SAAS;AAAA,IACjF;AAGA,QAAI,KAAK,QAAQ,iBAAiB;AAChC,WAAK,kBAAkB,sBAAsB;AAAA,QAC3C,WAAW,KAAK,QAAQ;AAAA,QACxB,uBAAuB;AAAA,MACzB,CAAC;AAAA,IACH;AAGA,SAAK,iBAAiB,QAAQ,kBAAkB;AAGhD,QAAI,KAAK,gBAAgB;AACvB,YAAM,eAAe,QAAQ,qBAAqB;AAClD,WAAK,gBAAgB,IAAI,mBAAmB,cAAc;AAAA,QACxD,UAAU;AAAA,QACV,qBAAqB;AAAA,MACvB,CAAC;AAGD,YAAM,mBAAmB,KAAK,cAAc,aAAa;AACzD,WAAK,QAAQ,YAAY,CAAC,GAAG,KAAK,QAAQ,WAAW,GAAG,gBAAgB;AAGxE,UAAI,KAAK,QAAQ,4BAA4B;AAC3C,aAAK,oBAAoB;AAAA,UACvB,KAAK;AAAA,UACL,KAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAGA,SAAK,WAAW,KAAK,iBAAiB;AAGtC,SAAK,iBAAiB;AAGtB,SAAK,mBAAmB;AAGxB,QAAI,KAAK,mBAAmB;AAC1B,WAAK,WAAW,KAAK,kBAAkB,iBAAiB,KAAK,QAAQ;AAAA,IACvE;AAGA,SAAK,qBAAqB,IAAI,mBAAmB;AAGjD,SAAK,WAAW,KAAK,mBAAmB,kBAAkB,KAAK,QAAQ;AAGvE,SAAK,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAGpD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ,eAAe,IAAI,oBAAoB;AAClE,WAAK,YAAY,QAAQ;AACzB,WAAK,iBAAiB,QAAQ;AAC9B,WAAK,gBAAgB,QAAQ;AAAA,IAC/B;AAGA,QAAI,QAAQ,eAAe;AACzB,WAAK,mBAAmB,QAAQ,oBAAoB,IAAI,yBAAyB;AAAA,IACnF;AAGA,QAAI,QAAQ,YAAY;AACtB,UAAI,QAAQ,aAAa;AACvB,aAAK,cAAc,QAAQ;AAAA,MAC7B,WAAW,QAAQ,MAAM;AAEvB,cAAM,OAAO,kBAAkB,QAAQ,IAAI;AAC3C,YAAI,MAAM;AACR,eAAK,cAAc,IAAI,YAAY,IAAI;AAAA,QACzC;AAAA,MACF,OAAO;AAEL,aAAK,cAAc,IAAI,YAAY;AAAA,MACrC;AAAA,IACF;AAGA,QAAI,QAAQ,WAAW;AACrB,WAAK,cAAc,IAAI,YAAY;AACnC,UAAI,CAAC,KAAK,YAAY,YAAY,GAAG;AACnC,gBAAQ,KAAK,mGAAmG;AAChH,gBAAQ,KAAK,uDAAuD;AACpE,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAGA,QAAI,QAAQ,uBAAuB,OAAO;AAExC,WAAK,qBAAqB,IAAI,mBAAmB,QAAQ,kBAAkB;AAAA,IAC7E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAW,YAA6C;AACnE,UAAM,SAAS,IAAI,aAAa,UAAU;AAC1C,UAAM,SAAS,MAAM,OAAO,KAAK;AAEjC,QAAI,CAAC,QAAQ;AACX,aAAO,IAAI,eAAc;AAAA,IAC3B;AAEA,UAAM,WAAW,OAAO,cAAc,MAAM;AAE5C,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG;AAAA,MACH,gBAAgB;AAAA,MAChB,mBAAmB,OAAO;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,mBAAiC;AACvC,QAAI;AAGJ,QAAI,KAAK,QAAQ,YAAY,KAAK,QAAQ,SAAS,SAAS,GAAG;AAC7D,iBAAW,YAAY;AAAA,QAAO,OAC5B,KAAK,QAAQ,SAAU,SAAS,EAAE,IAAI;AAAA,MACxC;AAAA,IACF,WAES,KAAK,QAAQ,cAAc,KAAK,QAAQ,WAAW,SAAS,GAAG;AACtE,iBAAW,CAAC;AACZ,iBAAW,YAAY,KAAK,QAAQ,YAAY;AAC9C,cAAM,mBAAmB,sBAAsB,QAAQ;AACvD,iBAAS,KAAK,GAAG,gBAAgB;AAAA,MACnC;AAEA,iBAAW,MAAM,KAAK,IAAI,IAAI,SAAS,IAAI,OAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AAEtE,UAAI,KAAK,QAAQ,OAAO;AACtB,gBAAQ,IAAI,0BAA0B,SAAS,MAAM,8BAA8B,KAAK,QAAQ,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,MACzH;AAAA,IACF,OAEK;AACH,iBAAW,YAAY,OAAO,aAAW;AAEvC,YAAI,QAAQ,SAAS,UAAU,CAAC,KAAK,QAAQ,aAAc,QAAO;AAClE,YAAI,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC,KAAK,QAAQ,cAAe,QAAO;AAC5E,YAAI,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC,KAAK,QAAQ,cAAe,QAAO;AAC5E,YAAI,QAAQ,KAAK,WAAW,SAAS,KAAK,CAAC,KAAK,QAAQ,iBAAkB,QAAO;AACjF,YAAI,QAAQ,KAAK,WAAW,UAAU,KAAK,CAAC,KAAK,QAAQ,iBAAkB,QAAO;AAClF,YAAI,QAAQ,KAAK,WAAW,KAAK,KAAK,CAAC,KAAK,QAAQ,iBAAkB,QAAO;AAE7E,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAGA,QAAI,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,SAAS,GAAG;AACzE,eAAS,KAAK,GAAG,KAAK,QAAQ,cAAc;AAAA,IAC9C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,mBAAyB;AAG/B,QAAI,CAAC,KAAK,QAAQ,kBAAkB,KAAK,QAAQ,eAAe,WAAW,GAAG;AAC5E,UAAI,KAAK,QAAQ,OAAO;AACtB,gBAAQ,IAAI,mDAAmD,KAAK,SAAS,MAAM,4BAA4B;AAAA,MACjH;AACA;AAAA,IACF;AAGA,eAAW,iBAAiB,KAAK,QAAQ,gBAAgB;AACvD,UAAI;AACF,wBAAgB,cAAc,KAAK;AAAA,MACrC,SAAS,OAAO;AACd,cAAM,WAAW,2CAA2C,cAAc,IAAI,MAAO,MAAgB,OAAO;AAC5G,cAAM,IAAI,MAAM,QAAQ;AAAA,MAC1B;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ,IAAI,6BAA6B,KAAK,QAAQ,eAAe,MAAM,qCAAqC,KAAK,SAAS,MAAM,EAAE;AAAA,IACxI;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAA2B;AACjC,SAAK,iBAAiB,MAAM;AAE5B,eAAW,WAAW,KAAK,UAAU;AACnC,YAAM,QAAQ,IAAI,OAAO,QAAQ,MAAM,QAAQ,QAAQ,MAAM,KAAK;AAClE,WAAK,iBAAiB,IAAI,SAAS,KAAK;AAAA,IAC1C;AAEA,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ,IAAI,gCAAgC,KAAK,iBAAiB,IAAI,iBAAiB;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBACN,MACA,UACA,iBACgB;AAChB,QAAI,aAA6B,CAAC;AAGlC,eAAW,WAAW,UAAU;AAE9B,YAAM,QAAQ,KAAK,iBAAiB,IAAI,OAAO;AAC/C,UAAI,CAAC,OAAO;AACV,YAAI,KAAK,QAAQ,OAAO;AACtB,kBAAQ,KAAK,4BAA4B,QAAQ,IAAI,yCAAyC;AAAA,QAChG;AACA;AAAA,MACF;AAEA,UAAI;AACJ,UAAI,aAAa;AACjB,YAAM,aAAa;AAGnB,YAAM,YAAY;AAElB,UAAI;AACF,gBAAQ,QAAQ,SAAS,OAAO,MAAM,EAAE,SAAS,KAAK,QAAQ,aAAa,CAAC,OAAO,MAAM;AACvF;AAGA,cAAI,cAAc,YAAY;AAC5B,gBAAI,KAAK,QAAQ,OAAO;AACtB,sBAAQ,KAAK,4BAA4B,QAAQ,IAAI,cAAc,UAAU,oBAAoB;AAAA,YACnG;AACA;AAAA,UACF;AAEF,gBAAM,QAAQ,MAAM,CAAC,MAAM,SAAY,MAAM,CAAC,IAAI,MAAM,CAAC;AACzD,gBAAM,YAAY,MAAM,CAAC;AAGzB,cAAI;AACJ,cAAI;AAEJ,cAAI,MAAM,CAAC,MAAM,QAAW;AAE1B,kBAAM,eAAe,UAAU,QAAQ,KAAK;AAC5C,uBAAW,MAAM,QAAQ;AACzB,qBAAS,WAAW,MAAM;AAAA,UAC5B,OAAO;AACL,uBAAW,MAAM;AACjB,qBAAS,WAAW,MAAM;AAAA,UAC5B;AAGA,cAAI,KAAK,qBAAqB,UAAU,QAAQ,eAAe,GAAG;AAChE;AAAA,UACF;AAGA,gBAAM,eAAe,KAAK,IAAI,GAAG,WAAW,EAAE;AAC9C,gBAAM,aAAa,KAAK,IAAI,KAAK,QAAQ,SAAS,EAAE;AACpD,gBAAM,UAAU,KAAK,UAAU,cAAc,UAAU;AAGvD,cAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,OAAO,OAAO,GAAG;AAC3D;AAAA,UACF;AAGA,cAAI,KAAK,QAAQ,2BAA2B;AAC1C,kBAAM,WAAW,gBAAgB,OAAO,QAAQ,MAAM,OAAO;AAC7D,gBAAI,SAAS,mBAAmB,SAAS,cAAc,KAAK,QAAQ,wBAAwB;AAE1F;AAAA,YACF;AAAA,UACF;AAGA,cAAI,aAAa;AACjB,cAAI,KAAK,QAAQ,uBAAuB;AACtC,kBAAM,kBAAkB;AAAA,cACtB;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR;AAAA,cACA;AAAA,YACF;AACA,yBAAa,gBAAgB;AAAA,UAC/B;AAGA,cAAI,KAAK,oBAAoB;AAC3B,kBAAM,WAAqB;AAAA,cACzB,MAAM,QAAQ;AAAA,cACd;AAAA,cACA,OAAO;AAAA,cACP,KAAK;AAAA,cACL;AAAA,cACA,SAAS;AAAA,gBACP,QAAQ,KAAK,UAAU,KAAK,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ;AAAA,gBAC5D,OAAO,KAAK,UAAU,QAAQ,KAAK,IAAI,KAAK,QAAQ,SAAS,GAAG,CAAC;AAAA,cACnE;AAAA,YACF;AAEA,kBAAM,WAAW,KAAK,mBAAmB,oBAAoB,UAAU,IAAI;AAC3E,yBAAa,SAAS;AAAA,UACxB;AAGA,cAAI,aAAa,KAAK,QAAQ,qBAAqB;AACjD;AAAA,UACF;AAGA,cAAI,KAAK,QAAQ,UAAU;AAAA,YAAK,UAC9B,MAAM,YAAY,EAAE,SAAS,KAAK,YAAY,CAAC;AAAA,UACjD,GAAG;AACD;AAAA,UACF;AAGA,gBAAM,cAAc,KAAK,oBAAoB,OAAO,OAAO;AAG3D,qBAAW,KAAK;AAAA,YACd,MAAM,QAAQ;AAAA,YACd;AAAA,YACA;AAAA,YACA,UAAU,CAAC,UAAU,MAAM;AAAA,YAC3B,UAAU,QAAQ,YAAY;AAAA,YAC9B;AAAA,UACF,CAAC;AAGC,0BAAgB,KAAK,CAAC,UAAU,MAAM,CAAC;AAAA,QACzC;AAAA,MACF,SAAS,OAAO;AAEd,YAAI,iBAAiB,mBAAmB;AACtC,cAAI,KAAK,QAAQ,OAAO;AACtB,oBAAQ,KAAK,mBAAmB,MAAM,OAAO,EAAE;AAAA,UACjD;AAEA;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAAA,IACF;AAGA,QAAI,KAAK,eAAe,WAAW,SAAS,GAAG;AAE7C,YAAM,aAAyB,WAAW,IAAI,UAAQ;AAAA,QACpD,MAAM,IAAI;AAAA,QACV,OAAO,IAAI;AAAA,QACX,OAAO,IAAI,SAAS,CAAC;AAAA,QACrB,KAAK,IAAI,SAAS,CAAC;AAAA,QACnB,YAAY,IAAI,cAAc;AAAA,QAC9B,SAAS;AAAA,UACP,QAAQ,KAAK,UAAU,KAAK,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;AAAA,UACzE,OAAO,KAAK,UAAU,IAAI,SAAS,CAAC,GAAG,KAAK,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;AAAA,QACpF;AAAA,MACF,EAAE;AAGF,YAAM,gBAAgB,KAAK,YAAY,gBAAgB,YAAY,IAAI;AAGvE,mBAAa,WAAW,IAAI,CAAC,KAAK,WAAW;AAAA,QAC3C,GAAG;AAAA,QACH,YAAY,cAAc,KAAK,EAAE;AAAA,MACnC,EAAE;AAAA,IACJ;AAGA,QAAI,KAAK,sBAAsB,WAAW,SAAS,GAAG;AAEpD,YAAM,aAAyB,WAAW,IAAI,UAAQ;AAAA,QACpD,MAAM,IAAI;AAAA,QACV,OAAO,IAAI;AAAA,QACX,OAAO,IAAI,SAAS,CAAC;AAAA,QACrB,KAAK,IAAI,SAAS,CAAC;AAAA,QACnB,YAAY,IAAI,cAAc;AAAA,QAC9B,SAAS;AAAA,UACP,QAAQ,KAAK,UAAU,KAAK,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;AAAA,UACzE,OAAO,KAAK,UAAU,IAAI,SAAS,CAAC,GAAG,KAAK,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;AAAA,QACpF;AAAA,MACF,EAAE;AAGF,YAAM,iBAAiB,KAAK,mBAAmB,oBAAoB,YAAY,IAAI;AAGnF,mBAAa,WAAW,IAAI,CAAC,KAAK,WAAW;AAAA,QAC3C,GAAG;AAAA,QACH,YAAY,eAAe,KAAK,EAAE;AAAA,MACpC,EAAE;AAAA,IACJ;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAA+B;AAEpC,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,kBAAkB,GAAG;AAC3E,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAEA,UAAM,YAAY,YAAY,IAAI;AAGlC,UAAM,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;AAClC,QAAI,WAAW,KAAK,QAAQ,cAAc;AACxC,YAAM,IAAI;AAAA,QACR,+BAA+B,QAAQ,yCAAyC,KAAK,QAAQ,YAAY;AAAA,MAE3G;AAAA,IACF;AAGA,QAAI,WAAW,KAAK,QAAQ,eAAe,OAAO,KAAK,QAAQ,OAAO;AACpE,cAAQ;AAAA,QACN,+BAA+B,QAAQ,yCAAyC,KAAK,QAAQ,YAAY;AAAA,MAC3G;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ,IAAI,oCAAoC,QAAQ,YAAY;AACpE,cAAQ,IAAI,oCAAoC,KAAK,SAAS,MAAM,EAAE;AACtE,cAAQ,IAAI,+BAA+B,KAAK,QAAQ,kBAAkB,YAAY,UAAU,EAAE;AAClG,cAAQ,IAAI,0BAA0B,KAAK,QAAQ,cAAc,YAAY,UAAU,EAAE;AAAA,IAC3F;AAGA,QAAI,KAAK,aAAa;AACpB,YAAM,WAAW,WAAW,IAAI;AAChC,YAAM,SAAS,KAAK,YAAY,IAAI,QAAQ;AAC5C,UAAI,QAAQ;AACV,YAAI,KAAK,QAAQ,OAAO;AACtB,kBAAQ,IAAI,oDAAoD;AAAA,QAClE;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,QAAQ,eAAe;AAC/B,WAAK,mBAAmB,MAAM;AAC9B,WAAK,mBAAmB,MAAM;AAAA,IAChC;AAEA,QAAI;AACJ,UAAM,kBAA2C,CAAC;AAGlD,QAAI,KAAK,QAAQ,mBAAmB,KAAK,iBAAiB;AAExD,YAAM,gBAAgB,oBAAoB,KAAK,UAAU,KAAK,eAAe;AAC7E,YAAM,iBAAiB,oBAAI,IAA4B;AAGvD,iBAAW,QAAQ,KAAK,iBAAiB;AACvC,cAAM,eAAe,cAAc,IAAI,KAAK,IAAI,KAAK,CAAC;AACtD,YAAI,aAAa,WAAW,EAAG;AAG/B,cAAM,oBAAoB,KAAK,gBAAgB,MAAM,cAAc,eAAe;AAGlF,uBAAe,IAAI,KAAK,MAAM,iBAAiB;AAG/C,mBAAW,aAAa,mBAAmB;AACzC,0BAAgB,KAAK,UAAU,QAAQ;AAAA,QACzC;AAAA,MACF;AAGA,mBAAa,oBAAoB,gBAAgB,KAAK,eAAe;AAAA,IACvE,OAAO;AAEL,mBAAa,KAAK,gBAAgB,MAAM,KAAK,UAAU,eAAe;AAAA,IACxE;AAGA,eAAW,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAGvD,QAAI,WAAW;AACf,UAAM,eAAuC,CAAC;AAE9C,eAAW,aAAa,YAAY;AAClC,YAAM,CAAC,OAAO,GAAG,IAAI,UAAU;AAC/B,iBAAW,SAAS,UAAU,GAAG,KAAK,IACpC,UAAU,cACV,SAAS,UAAU,GAAG;AAExB,mBAAa,UAAU,WAAW,IAAI,UAAU;AAAA,IAClD;AAEA,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,iBAAiB,KAAK,OAAO,UAAU,aAAa,GAAG,IAAI;AAEjE,UAAM,SAA0B;AAAA,MAC9B,UAAU;AAAA,MACV;AAAA,MACA,YAAY,WAAW,QAAQ;AAAA;AAAA,MAC/B;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA,UAAU,WAAW;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ,IAAI,uCAAuC,WAAW,MAAM,iBAAiB,cAAc,IAAI;AACvG,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,aAAqC,CAAC;AAC5C,mBAAW,aAAa,YAAY;AAClC,qBAAW,UAAU,IAAI,KAAK,WAAW,UAAU,IAAI,KAAK,KAAK;AAAA,QACnE;AACA,gBAAQ,IAAI,wCAAwC,UAAU;AAAA,MAChE;AAAA,IACF;AAGA,QAAI,KAAK,aAAa;AACpB,UAAI;AACF,cAAM,WAAW,CAAC,GAAG,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,IAAI,CAAC,CAAC;AACzD,aAAK,YAAY,IAAI;AAAA,UACnB,WAAW;AAAA,UACX,UAAU,WAAW;AAAA,UACrB;AAAA,UACA,YAAY,KAAK;AAAA,UACjB,kBAAkB;AAAA,UAClB,eAAe,KAAK,QAAQ;AAAA,UAC5B,SAAS;AAAA,UACT,MAAM,KAAK;AAAA,UACX,WAAW,KAAK;AAAA,UAChB,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH,SAAS,OAAO;AAEd,YAAI,KAAK,QAAQ,OAAO;AACtB,kBAAQ,MAAM,yCAAyC,KAAK;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,kBAAkB;AACzB,UAAI;AACF,aAAK,iBAAiB,gBAAgB,QAAQ,gBAAgB,KAAK,QAAQ,aAAa;AAAA,MAC1F,SAAS,OAAO;AAEd,YAAI,KAAK,QAAQ,OAAO;AACtB,kBAAQ,MAAM,6CAA6C,KAAK;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,aAAa;AACpB,YAAM,WAAW,WAAW,IAAI;AAChC,WAAK,YAAY,IAAI,UAAU,MAAM;AACrC,UAAI,KAAK,QAAQ,OAAO;AACtB,gBAAQ,IAAI,+BAA+B;AAAA,MAC7C;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,cAAsB,cAA8C;AAE1E,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,mBAAmB,GAAG;AAC5E,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACjF;AAEA,UAAM,YAAY,YAAY,IAAI;AAClC,QAAI,WAAW;AAEf,eAAW,CAAC,aAAa,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC/D,iBAAW,SAAS,QAAQ,IAAI,OAAO,KAAK,YAAY,WAAW,GAAG,GAAG,GAAG,KAAK;AAAA,IACnF;AAEA,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,iBAAiB,KAAK,OAAO,UAAU,aAAa,GAAG,IAAI;AAGjE,QAAI,KAAK,aAAa;AACpB,UAAI;AACF,aAAK,YAAY,IAAI;AAAA,UACnB,WAAW;AAAA,UACX,UAAU,OAAO,KAAK,YAAY,EAAE;AAAA,UACpC,UAAU,CAAC;AAAA;AAAA,UACX,YAAY,aAAa;AAAA,UACzB,kBAAkB;AAAA,UAClB,SAAS;AAAA,UACT,MAAM,KAAK;AAAA,UACX,WAAW,KAAK;AAAA,UAChB,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH,SAAS,OAAO;AAEd,YAAI,KAAK,QAAQ,OAAO;AACtB,kBAAQ,MAAM,yCAAyC,KAAK;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,OAAe,SAA6B;AAEtE,QAAI,KAAK,QAAQ,iBAAiB,KAAK,mBAAmB,IAAI,KAAK,GAAG;AACpE,aAAO,KAAK,mBAAmB,IAAI,KAAK;AAAA,IAC1C;AAEA,QAAI;AAGJ,QAAI,KAAK,QAAQ,kBAAkB,eAAe;AAChD,oBAAc;AAAA,QACZ;AAAA,QACA,QAAQ;AAAA,QACR,KAAK,QAAQ;AAAA,QACb,QAAQ;AAAA,MACV;AAEA,WAAK,mBAAmB,IAAI,OAAO,WAAW;AAC9C,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,QAAQ,eAAe;AAE9B,YAAM,KAAK,wBAAwB,OAAO,QAAQ,IAAI;AACtD,oBAAc,QAAQ,YAAY,QAAQ,OAAO,EAAE;AAAA,IACrD,OAAO;AAEL,YAAM,SAAS,KAAK,mBAAmB,IAAI,QAAQ,IAAI,KAAK,KAAK;AACjE,WAAK,mBAAmB,IAAI,QAAQ,MAAM,KAAK;AAC/C,oBAAc,QAAQ,YAAY,QAAQ,OAAO,MAAM,SAAS,CAAC;AAAA,IACnE;AAGA,SAAK,mBAAmB,IAAI,OAAO,WAAW;AAE9C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,qBACN,OACA,KACA,QACS;AACT,WAAO,OAAO;AAAA,MACZ,CAAC,CAAC,eAAe,WAAW,MACzB,SAAS,iBAAiB,QAAQ,eAClC,MAAM,iBAAiB,OAAO,eAC9B,SAAS,iBAAiB,OAAO;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,KAAqB;AACvC,WAAO,IAAI,QAAQ,uBAAuB,MAAM;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,cAA4B;AAC1B,WAAO,CAAC,GAAG,KAAK,QAAQ;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,MAKH;AACA,UAAM,SAAS,KAAK,OAAO,IAAI;AAE/B,WAAO;AAAA,MACL,MAAM,OAAO,WAAW,OAAO,OAAK,EAAE,aAAa,MAAM;AAAA,MACzD,QAAQ,OAAO,WAAW,OAAO,OAAK,EAAE,aAAa,QAAQ;AAAA,MAC7D,KAAK,OAAO,WAAW,OAAO,OAAK,EAAE,aAAa,KAAK;AAAA,MACvD,OAAO,OAAO,WAAW;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,WAAyB,SAAwB;AACnE,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,4BAA4B;AAAA,IACpC;AAEA,UAAM,MAAM,WAAW;AACvB,SAAK,cAAc,oBAAoB,UAAU,OAAO,UAAU,MAAM,GAAG;AAG3E,QAAI,KAAK,cAAc,cAAc,UAAU,KAAK,KAAK,MAAM;AAC7D,WAAK,QAAQ,UAAU,KAAK,UAAU,KAAK;AAAA,IAC7C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,MAAc,cAAsB,SAAwB;AAC9E,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,4BAA4B;AAAA,IACpC;AAEA,UAAM,MAAM,WAAW;AACvB,SAAK,cAAc,oBAAoB,MAAM,cAAc,GAAG;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,yBAA+B;AAC7B,QAAI,CAAC,KAAK,eAAe;AACvB;AAAA,IACF;AAEA,SAAK,cAAc,uBAAuB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB;AACjB,QAAI,CAAC,KAAK,eAAe;AACvB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,cAAc,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB;AACpB,QAAI,CAAC,KAAK,eAAe;AACvB,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,cAAc,oBAAoB;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACtB,QAAI,CAAC,KAAK,eAAe;AACvB,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,cAAc,sBAAsB;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,SAGb;AACD,QAAI,CAAC,KAAK,eAAe;AACvB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,cAAc,OAAO,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,MAAW,QAAiB,MAAY;AACtD,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,4BAA4B;AAAA,IACpC;AAEA,SAAK,cAAc,OAAO,MAAM,KAAK;AAGrC,UAAM,mBAAmB,KAAK,cAAc,aAAa;AACzD,SAAK,QAAQ,YAAY,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,QAAQ,WAAW,GAAG,gBAAgB,CAAC,CAAC;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,SAAiB,aAAqB,KAAW;AAC9D,QAAI,CAAC,KAAK,eAAe;AACvB,WAAK,QAAQ,UAAU,KAAK,OAAO;AACnC;AAAA,IACF;AAEA,SAAK,cAAc,eAAe,SAAS,UAAU;AACrD,SAAK,QAAQ,UAAU,KAAK,OAAO;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,SAAuB;AACzC,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc,oBAAoB,OAAO;AAAA,IAChD;AAEA,SAAK,QAAQ,YAAY,KAAK,QAAQ,UAAU,OAAO,OAAK,MAAM,OAAO;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmD;AACjD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAsD;AACpD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAA2B;AACzB,QAAI,CAAC,KAAK,mBAAmB;AAC3B,YAAM,gCAAgC;AAAA,IACxC;AAGA,SAAK,WAAW,KAAK,kBAAkB,iBAAiB,KAAK,QAAQ;AAGrE,SAAK,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAGpD,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,MAAM;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB;AAChB,QAAI,CAAC,KAAK,mBAAmB;AAC3B,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,kBAAkB,gBAAgB,KAAK,QAAQ;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,aAAmB;AACjB,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,MAAM;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAqE;AACnE,WAAO;AAAA,MACL,MAAM,KAAK,aAAa,QAAQ;AAAA,MAChC,SAAS,KAAK,QAAQ;AAAA,MACtB,SAAS,KAAK,QAAQ;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA2C;AAEzC,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,YAAY,GAAG;AACrE,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAqD;AAEnD,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,cAAc,GAAG;AACvE,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC5E;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA2C;AACzC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAsB;AACpB,WAAO,iBAAiB,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,QAAyB,SAAgC;AACtE,UAAM,YAAY,sBAAsB,IAAI;AAC5C,WAAO,UAAU,SAAS,QAAQ,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAIF;AACT,UAAM,EAAE,gBAAAC,gBAAe,IAAI;AAC3B,WAAOA,gBAAe,eAAe,KAAK,SAAS,UAAU,IAAI;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,SAKD;AACf,UAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,4BAAyB;AAChE,UAAM,UAAU,IAAIA,eAAc,IAAI;AACtC,WAAO,QAAQ,MAAM,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAkF;AACtF,UAAM,EAAE,eAAAA,eAAc,IAAI,MAAM,OAAO,4BAAyB;AAChE,UAAM,UAAU,IAAIA,eAAc,IAAI;AACtC,WAAO,QAAQ,WAAW;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eACJ,QACA,SACoD;AAEpD,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,kBAAkB,GAAG;AAC3E,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAEA,UAAM,EAAE,yBAAAC,yBAAwB,IAAI,MAAM,OAAO,yBAAY;AAC7D,UAAM,YAAYA,yBAAwB;AAE1C,UAAM,kBAAkB,YAAY,IAAI;AAGxC,UAAM,OAAO,MAAM,UAAU,YAAY,QAAQ,OAAO;AACxD,UAAM,WAAW,MAAM,UAAU,YAAY,QAAQ,OAAO;AAE5D,UAAM,gBAAgB,YAAY,IAAI;AACtC,UAAM,iBAAiB,KAAK,OAAO,gBAAgB,mBAAmB,GAAG,IAAI;AAG7E,UAAM,YAAY,KAAK,OAAO,IAAI;AAElC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBACJ,UACA,SACoD;AAEpD,QAAI,KAAK,eAAe,CAAC,KAAK,YAAY,cAAc,kBAAkB,GAAG;AAC3E,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAEA,UAAMC,MAAK,MAAM,OAAO,aAAa;AACrC,UAAM,SAAS,MAAMA,IAAG,SAAS,QAAQ;AAEzC,WAAO,KAAK,eAAe,QAAQ,OAAO;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,YACX,OACA,SAC4B;AAC5B,UAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM,OAAO,wBAAW;AACrD,UAAM,OAAOA,kBAAiB,EAAE,YAAY,SAAS,WAAW,CAAC;AAEjE,QAAI;AACF,YAAM,KAAK,WAAW;AAEtB,YAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,WAAW;AAAA,QACxC,MAAM;AAAA,QACN,IAAI,UAAU,KAAK;AAAA,QACnB;AAAA,QACA;AAAA,MACF,EAAE;AAEF,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,MAAM,IAAI,UAAQ,KAAK,QAAyB,IAAI,CAAC;AAAA,MACvD;AAEA,aAAO;AAAA,IACT,UAAE;AACA,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,qBACX,SACA,SACsD;AACtD,UAAM,EAAE,kBAAAA,kBAAiB,IAAI,MAAM,OAAO,wBAAW;AACrD,UAAM,OAAOA,kBAAiB,EAAE,YAAY,SAAS,WAAW,CAAC;AAEjE,QAAI;AACF,YAAM,KAAK,WAAW;AAEtB,YAAM,QAAQ,QAAQ,IAAI,CAAC,QAAQ,WAAW;AAAA,QAC5C,MAAM;AAAA,QACN,IAAI,YAAY,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF,EAAE;AAEF,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,MAAM,IAAI,UAAQ,KAAK,QAAQ,IAAI,CAAC;AAAA,MACtC;AAEA,aAAO;AAAA,IACT,UAAE;AACA,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AACF;;;ACttCO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YAAY,UAAyB,UAA4B,CAAC,GAAG;AACnE,SAAK,WAAW;AAChB,SAAK,UAAU;AAAA,MACb,WAAW,QAAQ,aAAa;AAAA,MAChC,SAAS,QAAQ,WAAW;AAAA,MAC5B,sBAAsB,QAAQ,wBAAwB;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,cAAc,MAA4D;AAC/E,UAAM,EAAE,WAAW,QAAQ,IAAI,KAAK;AACpC,UAAM,aAAa,KAAK;AACxB,QAAI,WAAW;AACf,QAAI,aAAa;AACjB,UAAM,kBAAkB,oBAAI,IAAY;AAExC,WAAO,WAAW,YAAY;AAE5B,YAAM,QAAQ,KAAK,IAAI,GAAG,WAAW,OAAO;AAC5C,YAAM,MAAM,KAAK,IAAI,YAAY,WAAW,SAAS;AACrD,YAAM,QAAQ,KAAK,UAAU,OAAO,GAAG;AACvC,YAAM,aAAa;AAGnB,YAAM,SAAS,KAAK,SAAS,OAAO,KAAK;AAGzC,YAAM,gBAAgB,OAAO,WAAW,OAAO,CAAC,cAA4B;AAC1E,cAAM,gBAAgB,aAAa,UAAU,SAAS,CAAC;AACvD,cAAM,cAAc,aAAa,UAAU,SAAS,CAAC;AACrD,cAAM,WAAW,GAAG,aAAa,IAAI,WAAW;AAGhD,YAAI,gBAAgB,IAAI,QAAQ,GAAG;AACjC,iBAAO;AAAA,QACT;AAIA,cAAM,kBAAkB;AACxB,cAAM,sBAAsB;AAC5B,cAAM,iBAAiB,eAAe,KAAK,uBAAuB;AAElE,YAAI,gBAAgB;AAClB,0BAAgB,IAAI,QAAQ;AAC5B,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT,CAAC;AAGD,YAAM,qBAAqB,cAAc,IAAI,CAAC,eAA6B;AAAA,QACzE,GAAG;AAAA,QACH,UAAU;AAAA,UACR,aAAa,UAAU,SAAS,CAAC;AAAA,UACjC,aAAa,UAAU,SAAS,CAAC;AAAA,QACnC;AAAA,MACF,EAAE;AAGF,UAAI,gBAAgB;AACpB,UAAI,KAAK,QAAQ,sBAAsB;AAErC,cAAM,mBAAmB,CAAC,GAAG,OAAO,UAAU,EAAE;AAAA,UAC9C,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC;AAAA,QACxC;AAEA,mBAAW,aAAa,kBAAkB;AACxC,gBAAM,CAACC,QAAOC,IAAG,IAAI,UAAU;AAC/B,0BACE,cAAc,UAAU,GAAGD,MAAK,IAChC,UAAU,cACV,cAAc,UAAUC,IAAG;AAAA,QAC/B;AAAA,MACF;AAEA,YAAM;AAAA,QACJ;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,QACA,eAAe;AAAA,QACf;AAAA,MACF;AAGA,kBAAY;AACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,MAAwC;AAC5D,UAAM,gBAAgC,CAAC;AACvC,QAAI,eAAe;AAEnB,qBAAiB,SAAS,KAAK,cAAc,IAAI,GAAG;AAClD,oBAAc,KAAK,GAAG,MAAM,UAAU;AAAA,IACxC;AAGA,kBAAc,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAG1D,UAAM,eAAuC,CAAC;AAE9C,eAAW,aAAa,eAAe;AACrC,YAAM,CAAC,OAAO,GAAG,IAAI,UAAU;AAC/B,qBACE,aAAa,UAAU,GAAG,KAAK,IAC/B,UAAU,cACV,aAAa,UAAU,GAAG;AAE5B,mBAAa,UAAU,WAAW,IAAI,UAAU;AAAA,IAClD;AAEA,WAAO;AAAA,MACL,UAAU;AAAA,MACV,UAAU;AAAA,MACV,YAAY,cAAc,QAAQ;AAAA;AAAA,MAClC;AAAA,MACA,OAAO;AAAA,QACL,UAAU,cAAc;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBACL,gBAC8C;AAC9C,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,UAAM,SAAS,eAAe,iBAC1B,eAAe,UAAU,IACzB;AAEJ,QAAI,QAAQ;AAEV,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAI,KAAM;AAEV,oBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,iBAAO,OAAO,UAAU,KAAK,QAAQ,WAAW;AAC9C,kBAAM,QAAQ,OAAO,UAAU,GAAG,KAAK,QAAQ,SAAS;AACxD,qBAAS,OAAO,UAAU,KAAK,QAAQ,SAAS;AAGhD,6BAAiB,UAAU,KAAK,cAAc,KAAK,GAAG;AACpD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF,UAAE;AACA,eAAO,YAAY;AAAA,MACrB;AAGA,UAAI,OAAO,SAAS,GAAG;AACrB,yBAAiB,UAAU,KAAK,cAAc,MAAM,GAAG;AACrD,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,aAAa;AAEnB,uBAAiB,SAAS,YAAY;AACpC,kBAAU,QAAQ,OAAO,OAAqB,EAAE,QAAQ,KAAK,CAAC;AAG9D,eAAO,OAAO,UAAU,KAAK,QAAQ,WAAW;AAC9C,gBAAM,YAAY,OAAO,UAAU,GAAG,KAAK,QAAQ,SAAS;AAC5D,mBAAS,OAAO,UAAU,KAAK,QAAQ,SAAS;AAGhD,2BAAiB,UAAU,KAAK,cAAc,SAAS,GAAG;AACxD,kBAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAGA,UAAI,OAAO,SAAS,GAAG;AACrB,yBAAiB,UAAU,KAAK,cAAc,MAAM,GAAG;AACrD,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,YAKZ;AACA,UAAM,YAAY,KAAK,KAAK,aAAa,KAAK,QAAQ,SAAS;AAC/D,UAAM,mBAAmB,KAAK,QAAQ,YAAY,KAAK,QAAQ,WAAW;AAE1E,WAAO;AAAA,MACL;AAAA,MACA,WAAW,KAAK,QAAQ;AAAA,MACxB,SAAS,KAAK,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,wBACd,UACA,SACmB;AACnB,SAAO,IAAI,kBAAkB,UAAU,OAAO;AAChD;;;ACzOO,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,UAAyB;AACnC,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,kBACE,WACA,UAAwB,CAAC,GACZ;AACb,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,UAA6B,CAAC;AAEpC,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,SAAS,KAAK,SAAS,OAAO,UAAU,CAAC,CAAC;AAChD,cAAQ,KAAK,MAAM;AAEnB,UAAI,QAAQ,YAAY;AACtB,gBAAQ,WAAW,IAAI,GAAG,UAAU,MAAM;AAAA,MAC5C;AAAA,IACF;AAEA,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,YAAY,UAAU;AAE5B,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,gBAAgB,UAAU;AAAA,QAC1B,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,QACxE;AAAA,QACA,oBAAoB,YAAY,UAAU;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBACJ,WACA,UAAwB,CAAC,GACH;AACtB,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,iBAAiB,QAAQ,kBAAkB;AACjD,UAAM,UAA6B,IAAI,MAAM,UAAU,MAAM;AAC7D,QAAI,YAAY;AAGhB,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,gBAAgB;AACzD,YAAM,QAAQ,UAAU,MAAM,GAAG,IAAI,cAAc;AACnD,YAAM,gBAAgB,MAAM,IAAI,CAAC,KAAK,eAAe;AACnD,eAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAClC,gBAAM,SAAS,KAAK,SAAS,OAAO,GAAG;AACvC,kBAAQ,IAAI,UAAU,IAAI;AAC1B;AAEA,cAAI,QAAQ,YAAY;AACtB,oBAAQ,WAAW,WAAW,UAAU,MAAM;AAAA,UAChD;AAEA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,CAAC;AAED,YAAM,QAAQ,IAAI,aAAa;AAAA,IACjC;AAEA,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,YAAY,UAAU;AAE5B,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,gBAAgB,UAAU;AAAA,QAC1B,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,QACxE;AAAA,QACA,oBAAoB,YAAY,UAAU;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QACJ,WACA,UAAwB,CAAC,GACH;AACtB,QAAI,QAAQ,UAAU;AACpB,aAAO,KAAK,gBAAgB,WAAW,OAAO;AAAA,IAChD,OAAO;AACL,aAAO,QAAQ,QAAQ,KAAK,kBAAkB,WAAW,OAAO,CAAC;AAAA,IACnE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,cACL,WACA,YAAoB,IAC8B;AAClD,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,WAAW;AACpD,YAAM,QAAQ,UAAU,MAAM,GAAG,IAAI,SAAS;AAE9C,iBAAW,OAAO,OAAO;AACvB,cAAM,SAAS,KAAK,SAAS,OAAO,GAAG;AACvC,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,SAKjB;AACA,UAAM,mBAA2C,CAAC;AAClD,UAAM,uBAA+C,CAAC;AACtD,QAAI,kBAAkB;AACtB,QAAI,sBAAsB;AAE1B,eAAW,UAAU,SAAS;AAC5B,iBAAW,aAAa,OAAO,YAAY;AAEzC,yBAAiB,UAAU,IAAI,KAAK,iBAAiB,UAAU,IAAI,KAAK,KAAK;AAG7E,6BAAqB,UAAU,QAAQ,KAAK,qBAAqB,UAAU,QAAQ,KAAK,KAAK;AAG7F,YAAI,UAAU,eAAe,QAAW;AACtC,6BAAmB,UAAU;AAC7B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,MACxE;AAAA,MACA;AAAA,MACA,eAAe,sBAAsB,IAAI,kBAAkB,sBAAsB;AAAA,IACnF;AAAA,EACF;AACF;AAKO,SAAS,qBAAqB,UAAyC;AAC5E,SAAO,IAAI,eAAe,QAAQ;AACpC;;;AChKO,SAAS,wBAAwB,UAA0C,CAAC,GAAG;AAEpF,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,SAAS,CAAC;AAAA,IACV,aAAa,CAAC;AAAA,IACd,gBAAgB;AAAA,IAChB;AAAA,IACA,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,GAAG;AAAA,EACL,IAAI;AAGJ,QAAM,WAAW,IAAI,cAAc,eAAe;AAElD,SAAO,CAAC,KAAc,KAAe,SAAuB;AAE1D,QAAI,WAAW,KAAK,aAAW,QAAQ,KAAK,IAAI,IAAI,CAAC,GAAG;AACtD,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,CAAC,IAAI,QAAQ,OAAO,IAAI,SAAS,UAAU;AAC7C,aAAO,KAAK;AAAA,IACd;AAEA,QAAI;AAEF,YAAM,gBAAgB,OAAO,SAAS,IAClC,SACA,OAAO,KAAK,IAAI,IAAI;AAGxB,YAAM,eAAwD,CAAC;AAE/D,iBAAW,SAAS,eAAe;AACjC,cAAM,QAAQ,IAAI,KAAK,KAAK;AAC5B,YAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAG;AACjD,uBAAa,KAAK,EAAE,OAAO,MAAM,CAAC;AAAA,QACpC;AAAA,MACF;AAGA,UAAI,kBAAkB;AACtB,YAAM,UAA2C,CAAC;AAClD,YAAM,eAAoB,EAAE,GAAG,IAAI,KAAK;AAExC,iBAAW,EAAE,OAAO,MAAM,KAAK,cAAc;AAC3C,cAAM,SAAS,SAAS,OAAO,KAAK;AAEpC,YAAI,OAAO,WAAW,SAAS,GAAG;AAChC,6BAAmB,OAAO,WAAW;AACrC,kBAAQ,KAAK,IAAI;AAGjB,cAAI,YAAY;AACd,yBAAa,KAAK,IAAI,OAAO;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,eAAe;AACjB,cAAM,SAAS;AACf,eAAO,MAAM;AAAA,UACX,UAAU,kBAAkB;AAAA,UAC5B,OAAO;AAAA,UACP,QAAQ,QAAQ,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC,KAAK;AAAA,YAC1C,UAAU;AAAA,YACV,UAAU;AAAA,YACV,YAAY,CAAC;AAAA,YACb,cAAc,CAAC;AAAA,YACf,OAAO,EAAE,UAAU,EAAE;AAAA,UACvB;AAAA,UACA,UAAU,aAAa,eAAe;AAAA,QACxC;AAAA,MACF;AAGA,UAAI,cAAc,kBAAkB,GAAG;AACrC,YAAI,OAAO;AAAA,MACb;AAGA,UAAI,cAAc,kBAAkB,GAAG;AACrC,YAAI,UAAU,kBAAkB,MAAM;AACtC,YAAI,UAAU,eAAe,gBAAgB,SAAS,CAAC;AAAA,MACzD;AAGA,UAAI,eAAe,kBAAkB,KAAK,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AACzE,oBAAY,KAAK,QAAQ,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;AAAA,MACnD;AAGA,UAAI,aAAa,kBAAkB,GAAG;AACpC,eAAO,IAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UAC1B,OAAO;AAAA,UACP,SAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAQ,OAAO,KAAK,OAAO;AAAA,QAC7B,CAAC;AAAA,MACH;AAEA,WAAK;AAAA,IACP,SAAS,OAAO;AACd,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AACF;AAKO,SAAS,UAAU,UAAgC,CAAC,GAAG;AAC5D,QAAM,WAAW,IAAI,cAAc,OAAO;AAE1C,SAAO,CAAC,KAAc,QAAwB;AAC5C,UAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM;AAEzC,QAAI,CAAC,MAAM;AACT,UAAI,OAAO,GAAG,EAAE,KAAK;AAAA,QACnB,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AACD;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,OAAO,IAAI;AAEnC,QAAI,KAAK;AAAA,MACP,UAAU,OAAO,WAAW,SAAS;AAAA,MACrC,OAAO,OAAO,WAAW;AAAA,MACzB,YAAY,OAAO;AAAA,MACnB,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AAKO,SAAS,eAAe,UAAgC,CAAC,GAAG;AACjE,QAAM,WAAW,IAAI,cAAc,OAAO;AAE1C,SAAO,CAAC,KAAc,QAAwB;AAC5C,UAAM,OAAO,IAAI,MAAM;AACvB,UAAM,SAAU,IAAI,MAAM,UAAU,IAAI,MAAM,UAAU;AAExD,QAAI,CAAC,MAAM;AACT,UAAI,OAAO,GAAG,EAAE,KAAK;AAAA,QACnB,OAAO;AAAA,MACT,CAAC;AACD;AAAA,IACF;AAEA,UAAM,SAAS,SAAS,OAAO,IAAI;AAEnC,QAAI,WAAW,QAAQ;AACrB,YAAM,OAAO,SAAS,eAAe,QAAQ;AAAA,QAC3C,QAAQ;AAAA,QACR,OAAO,IAAI,MAAM,SAAS;AAAA,MAC5B,CAAC;AACD,UAAI,UAAU,gBAAgB,WAAW;AACzC,UAAI,KAAK,IAAI;AAAA,IACf,WAAW,WAAW,YAAY;AAChC,YAAM,KAAK,SAAS,eAAe,QAAQ;AAAA,QACzC,QAAQ;AAAA,QACR,OAAO,IAAI,MAAM,SAAS;AAAA,MAC5B,CAAC;AACD,UAAI,UAAU,gBAAgB,eAAe;AAC7C,UAAI,KAAK,EAAE;AAAA,IACb,OAAO;AACL,UAAI,KAAK;AAAA,QACP,UAAU,OAAO,WAAW,SAAS;AAAA,QACrC,OAAO,OAAO,WAAW;AAAA,QACzB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC1NA,SAAS,UAAU,WAAW,SAAS,mBAAmB;AAmBnD,SAAS,iBAAiB,SAAgC;AAC/D,QAAM,WAAW,QAAQ,MAAM,IAAI,cAAc,OAAO,GAAG,CAAC,OAAO,CAAC;AACpE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AACjE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AAEpD,QAAM,SAAS,YAAY,CAAC,SAAkC;AAC5D,mBAAe,IAAI;AACnB,UAAM,YAAY,SAAS,OAAO,IAAI;AACtC,cAAU,SAAS;AACnB,mBAAe,KAAK;AACpB,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,QAAQ,YAAY,MAAM;AAC9B,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,SAAS,OAAO,WAAW,SAAS,IAAI;AAAA,IAChD,OAAO,SAAS,OAAO,WAAW,SAAS;AAAA,IAC3C;AAAA,IACA;AAAA,EACF;AACF;AAoBO,SAAS,eACd,MACA,SACA;AACA,QAAM,EAAE,WAAW,KAAK,GAAG,cAAc,IAAI,WAAW,CAAC;AACzD,QAAM,WAAW,QAAQ,MAAM,IAAI,cAAc,aAAa,GAAG,CAAC,aAAa,CAAC;AAChF,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AACjE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AAEpD,YAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,gBAAU,IAAI;AACd;AAAA,IACF;AAEA,mBAAe,IAAI;AACnB,UAAM,QAAQ,WAAW,MAAM;AAC7B,YAAM,YAAY,SAAS,OAAO,IAAI;AACtC,gBAAU,SAAS;AACnB,qBAAe,KAAK;AAAA,IACtB,GAAG,QAAQ;AAEX,WAAO,MAAM;AACX,mBAAa,KAAK;AAClB,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,QAAQ,CAAC;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,SAAS,OAAO,WAAW,SAAS,IAAI;AAAA,IAChD,OAAO,SAAS,OAAO,WAAW,SAAS;AAAA,IAC3C,YAAY,QAAQ,cAAc,CAAC;AAAA,EACrC;AACF;AAsBO,SAAS,sBAAsB,SAInC;AACD,QAAM,EAAE,YAAY,OAAO,QAAQ,CAAC,GAAG,eAAe,GAAG,cAAc,IAAI,WAAW,CAAC;AACvF,QAAM,WAAW,QAAQ,MAAM,IAAI,cAAc,aAAa,GAAG,CAAC,aAAa,CAAC;AAChF,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AAEjE,QAAM,WAAW,YAAY,CAAC,eAAuB;AACnD,aAAS,UAAU;AAEnB,QAAI,CAAC,YAAY;AACf,eAAS,IAAI;AACb,gBAAU,IAAI;AACd,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,SAAS,OAAO,UAAU;AAC5C,cAAU,SAAS;AAGnB,UAAM,qBAAqB,MAAM,SAAS,IACtC,UAAU,WAAW,OAAO,CAAC,MAAM,MAAM,SAAS,EAAE,IAAI,CAAC,IACzD,UAAU;AAEd,QAAI,mBAAmB,SAAS,GAAG;AACjC,UAAI,WAAW;AACb,iBAAS,mCAAmC,mBAAmB,CAAC,EAAE,IAAI,EAAE;AAAA,MAC1E;AAEA,UAAI,eAAe;AACjB,sBAAc,SAAS;AAAA,MACzB;AAEA,aAAO;AAAA,IACT;AAEA,aAAS,IAAI;AACb,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,WAAW,OAAO,aAAa,CAAC;AAE9C,QAAM,gBAAgB,YAAY,OAAO;AAAA,IACvC;AAAA,IACA,gBAAgB,QAAQ,SAAS;AAAA,IACjC,oBAAoB,QAAQ,cAAc;AAAA,EAC5C,IAAI,CAAC,OAAO,KAAK,CAAC;AAElB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ,SAAS,OAAO,WAAW,SAAS,IAAI;AAAA,EAClD;AACF;AAiBO,SAAS,iBAAiB,SAAgC;AAC/D,QAAM,WAAW,QAAQ,MAAM,IAAI,cAAc,OAAO,GAAG,CAAC,OAAO,CAAC;AACpE,QAAM,CAAC,SAAS,UAAU,IAAI,SAA4B,CAAC,CAAC;AAC5D,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,CAAC;AAE1C,QAAM,aAAa,YAAY,OAAO,UAAoB;AACxD,oBAAgB,IAAI;AACpB,gBAAY,CAAC;AACb,UAAM,aAAgC,CAAC;AAEvC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,SAAS,SAAS,OAAO,MAAM,CAAC,CAAC;AACvC,iBAAW,KAAK,MAAM;AACtB,mBAAc,IAAI,KAAK,MAAM,SAAU,GAAG;AAG1C,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,CAAC,CAAC;AAAA,IACrD;AAEA,eAAW,UAAU;AACrB,oBAAgB,KAAK;AACrB,gBAAY,GAAG;AAEf,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,QAAQ,YAAY,MAAM;AAC9B,eAAW,CAAC,CAAC;AACb,gBAAY,CAAC;AAAA,EACf,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkB;AAAA,IACtB,MAAM,QAAQ,OAAO,CAAC,KAAa,MAAuB,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,IACtF,CAAC,OAAO;AAAA,EACV;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAmBO,SAAS,cAAc,SAAwD;AACpF,QAAM,EAAE,WAAW,KAAK,GAAG,cAAc,IAAI,WAAW,CAAC;AACzD,QAAM,WAAW,QAAQ,MAAM,IAAI,cAAc,aAAa,GAAG,CAAC,aAAa,CAAC;AAChF,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AAEjE,YAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,gBAAU,IAAI;AACd;AAAA,IACF;AAEA,UAAM,QAAQ,WAAW,MAAM;AAC7B,YAAM,YAAY,SAAS,OAAO,IAAI;AACtC,gBAAU,SAAS;AAAA,IACrB,GAAG,QAAQ;AAEX,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,MAAM,UAAU,QAAQ,CAAC;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,QAAQ,YAAY;AAAA,IAClC,QAAQ,SAAS,OAAO,WAAW,SAAS,IAAI;AAAA,IAChD,YAAY,QAAQ,cAAc,CAAC;AAAA,IACnC,OAAO,SAAS,OAAO,WAAW,SAAS;AAAA,EAC7C;AACF;;;AC7NO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YACS,UACA,OACA,OACA,SACP;AACA,UAAM,UAAU,QAAQ,aAAa,KAAK,WAAW,OAAO,IAAI,KAAK,EAAE;AALhE;AACA;AACA;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7C,YAAmB,UAAkB;AACnC,UAAM,qBAAqB,QAAQ,EAAE;AADpB;AAEjB,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAmB,UAAkB;AACnC,UAAM,wBAAwB,QAAQ,EAAE;AADvB;AAEjB,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AACL,SAAQ,UAAqC,oBAAI,IAAI;AACrD,SAAQ,QAAkC,oBAAI,IAAI;AAClD,SAAQ,YAAwC,oBAAI,IAAI;AACxD,SAAQ,oBAA2C,oBAAI,IAAI;AAC3D,SAAQ,eAA0C,oBAAI,IAAI;AAC1D,SAAQ,oBAAoD,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpE,eAAe,QAAqE;AAClF,QAAI,KAAK,QAAQ,IAAI,OAAO,QAAQ,GAAG;AACrC,YAAM,IAAI,MAAM,0BAA0B,OAAO,QAAQ,EAAE;AAAA,IAC7D;AAEA,UAAM,aAA2B;AAAA,MAC/B,GAAG;AAAA,MACH,WAAW,oBAAI,KAAK;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,IACtB;AAEA,SAAK,QAAQ,IAAI,OAAO,UAAU,UAAU;AAG5C,SAAK,MAAM,IAAI,OAAO,UAAU;AAAA,MAC9B,UAAU,OAAO;AAAA,MACjB,mBAAmB;AAAA,MACnB,wBAAwB;AAAA,MACxB,sBAAsB;AAAA,MACtB,kBAAkB,KAAK,wBAAwB;AAAA,IACjD,CAAC;AAGD,SAAK,kBAAkB,IAAI,OAAO,UAAU,CAAC,CAAC;AAE9C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAkB,SAA8E;AAC3G,UAAM,SAAS,KAAK,gBAAgB,QAAQ;AAE5C,UAAM,UAAwB;AAAA,MAC5B,GAAG;AAAA,MACH,GAAG;AAAA,MACH,WAAW,oBAAI,KAAK;AAAA,IACtB;AAEA,SAAK,QAAQ,IAAI,UAAU,OAAO;AAGlC,SAAK,UAAU,OAAO,QAAQ;AAE9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,UAAgC;AAC9C,UAAM,SAAS,KAAK,QAAQ,IAAI,QAAQ;AACxC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,oBAAoB,QAAQ;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAiC;AAC3C,SAAK,qBAAqB,QAAQ;AAGlC,QAAI,KAAK,UAAU,IAAI,QAAQ,GAAG;AAChC,aAAO,KAAK,UAAU,IAAI,QAAQ;AAAA,IACpC;AAGA,UAAM,SAAS,KAAK,gBAAgB,QAAQ;AAC5C,UAAM,UAAgC;AAAA,MACpC,GAAG,OAAO;AAAA,MACV,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO;AAAA,MAClB,aAAa,KAAK,eAAe,QAAQ;AAAA,MACzC,kBAAkB,KAAK,oBAAoB,QAAQ;AAAA,MACnD,WAAW,OAAO;AAAA,MAClB,eAAe;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,MACrB;AAAA,IACF;AAEA,UAAM,WAAW,IAAI,cAAc,OAAO;AAC1C,SAAK,UAAU,IAAI,UAAU,QAAQ;AAErC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,UAAkB,MAA4B;AAEzD,SAAK,qBAAqB,QAAQ;AAGlC,UAAM,KAAK,YAAY,UAAU,IAAI;AAGrC,SAAK,aAAa,UAAU,IAAI;AAGhC,UAAM,WAAW,KAAK,YAAY,QAAQ;AAC1C,UAAM,SAAS,SAAS,OAAO,IAAI;AAGnC,UAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;AACrC,UAAM,wBAAwB,OAAO,WAAW;AAChD,UAAM,gBAAgB,oBAAI,KAAK;AAE/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,UAAwB;AACnD,UAAM,SAAS,KAAK,gBAAgB,QAAQ;AAG5C,QAAI,OAAO,WAAW,aAAa;AACjC,YAAM,IAAI,qBAAqB,QAAQ;AAAA,IACzC;AAGA,QAAI,OAAO,WAAW,WAAW,OAAO,gBAAgB;AACtD,UAAI,oBAAI,KAAK,IAAI,OAAO,gBAAgB;AACtC,cAAM,IAAI,qBAAqB,QAAQ;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YAAY,UAAkB,MAA6B;AACvE,UAAM,SAAS,KAAK,gBAAgB,QAAQ;AAC5C,UAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;AAGrC,QAAI,oBAAI,KAAK,IAAI,MAAM,kBAAkB;AACvC,WAAK,kBAAkB,QAAQ;AAAA,IACjC;AAEA,UAAM,SAAS,OAAO;AACtB,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAGA,QAAI,OAAO,wBAAwB,QAAW;AAC5C,UAAI,MAAM,qBAAqB,OAAO,qBAAqB;AACzD,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,kBAAkB,QAAW;AACtC,UAAI,KAAK,SAAS,OAAO,eAAe;AACtC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,cAAc,QAAW;AAClC,YAAM,uBAAuB,KAAK,wBAAwB,QAAQ;AAClE,UAAI,wBAAwB,OAAO,WAAW;AAC5C,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,gBAAgB,QAAW;AACpC,YAAM,eAAe,OAAO,gBAAgB,UAAU;AACtD,UAAI,eAAe,OAAO,aAAa;AACrC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,UAAkB,MAAoB;AACzD,UAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;AAGrC,UAAM;AACN,UAAM,0BAA0B,KAAK;AAGrC,UAAM,aAAa,KAAK,kBAAkB,IAAI,QAAQ,KAAK,CAAC;AAC5D,eAAW,KAAK,KAAK,IAAI,CAAC;AAG1B,UAAM,eAAe,KAAK,IAAI,IAAI,KAAK;AACvC,UAAM,mBAAmB,WAAW,OAAO,QAAM,KAAK,YAAY;AAClE,SAAK,kBAAkB,IAAI,UAAU,gBAAgB;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwB,UAA0B;AACxD,UAAM,aAAa,KAAK,kBAAkB,IAAI,QAAQ,KAAK,CAAC;AAC5D,UAAM,eAAe,KAAK,IAAI,IAAI,KAAK;AACvC,WAAO,WAAW,OAAO,QAAM,KAAK,YAAY,EAAE;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,UAAwB;AAChD,UAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;AACrC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,UAAM,oBAAoB;AAC1B,UAAM,yBAAyB;AAC/B,UAAM,uBAAuB;AAC7B,UAAM,mBAAmB,KAAK,wBAAwB;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAAgC;AACtC,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;AACnE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAA+B;AAC5C,SAAK,qBAAqB,QAAQ;AAElC,UAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ;AACrC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,QAAQ,EAAE;AAAA,IAChE;AAEA,WAAO,EAAE,GAAG,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgC;AAC9B,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,QAAgD;AACjE,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,QAAqC;AACxD,eAAW,UAAU,KAAK,QAAQ,OAAO,GAAG;AAC1C,UAAI,OAAO,WAAW,QAAQ;AAC5B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,UAAwB;AACpC,SAAK,aAAa,UAAU,EAAE,QAAQ,YAAY,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAAwB;AACrC,SAAK,aAAa,UAAU,EAAE,QAAQ,SAAS,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAwB;AACnC,SAAK,qBAAqB,QAAQ;AAElC,SAAK,QAAQ,OAAO,QAAQ;AAC5B,SAAK,MAAM,OAAO,QAAQ;AAC1B,SAAK,UAAU,OAAO,QAAQ;AAC9B,SAAK,kBAAkB,OAAO,QAAQ;AACtC,SAAK,aAAa,OAAO,QAAQ;AACjC,SAAK,kBAAkB,OAAO,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAAkB,QAA4B;AAC3D,SAAK,qBAAqB,QAAQ;AAClC,SAAK,aAAa,IAAI,UAAU,MAAM;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAA4C;AACzD,WAAO,KAAK,aAAa,IAAI,QAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,UAAkB,WAAoC;AACxE,SAAK,qBAAqB,QAAQ;AAClC,SAAK,kBAAkB,IAAI,UAAU,SAAS;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,UAAiD;AACnE,WAAO,KAAK,kBAAkB,IAAI,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,oBAQE;AACA,UAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC;AAChD,UAAM,SAAS,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAE7C,WAAO;AAAA,MACL,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ,OAAO,OAAK,EAAE,WAAW,QAAQ,EAAE;AAAA,MAC1D,cAAc,QAAQ,OAAO,OAAK,EAAE,WAAW,OAAO,EAAE;AAAA,MACxD,kBAAkB,QAAQ,OAAO,OAAK,EAAE,WAAW,WAAW,EAAE;AAAA,MAChE,wBAAwB,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,mBAAmB,CAAC;AAAA,MAC9E,6BAA6B,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,wBAAwB,CAAC;AAAA,MACxF,2BAA2B,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,sBAAsB,CAAC;AAAA,IACtF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,UAAwB;AACnD,QAAI,CAAC,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAC/B,YAAM,IAAI,oBAAoB,QAAQ;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,UAA0B;AAC3C,UAAM,SAAS,KAAK,gBAAgB,QAAQ;AAC5C,WAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,MAA4B;AAC7C,UAAM,SAAS,KAAK,MAAM,IAAI;AAG9B,QAAI,CAAC,OAAO,YAAY,CAAC,OAAO,QAAQ,CAAC,OAAO,QAAQ;AACtD,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAGA,QAAI,KAAK,QAAQ,IAAI,OAAO,QAAQ,GAAG;AACrC,aAAO,KAAK,aAAa,OAAO,UAAU,MAAM;AAAA,IAClD,OAAO;AACL,aAAO,KAAK,eAAe,MAAM;AAAA,IACnC;AAAA,EACF;AACF;AAKO,SAAS,sBAAqC;AACnD,SAAO,IAAI,cAAc;AAC3B;AAKO,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,IACJ,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,WAAW;AAAA;AAAA,EACb;AAAA,EACA,SAAS;AAAA,IACP,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,WAAW;AAAA,EACb;AAAA,EACA,cAAc;AAAA,IACZ,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,WAAW;AAAA,EACb;AAAA,EACA,YAAY;AAAA;AAAA,IAEV,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,WAAW;AAAA,EACb;AACF;;;ACvbO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAW1B,YAAY,SAAuC;AAVnD,SAAQ,WAAuC,oBAAI,IAAI;AACvD,SAAQ,kBAAqC,CAAC;AAC9C,SAAQ,kBAAoD,oBAAI,IAAI;AACpE,SAAQ,iBAA8C,oBAAI,IAAI;AAI9D;AAAA,SAAiB,oBAAoB;AACrC,SAAiB,mBAAmB;AAGlC,SAAK,iBAAiB,SAAS,kBAAkB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAA6B;AAC3C,QAAI,KAAK,SAAS,IAAI,OAAO,EAAE,GAAG;AAChC,YAAM,IAAI,MAAM,+BAA+B,OAAO,EAAE,EAAE;AAAA,IAC5D;AAGA,QAAI;AACF,UAAI,IAAI,OAAO,GAAG;AAAA,IACpB,QAAQ;AACN,YAAM,IAAI,MAAM,wBAAwB,OAAO,GAAG,EAAE;AAAA,IACtD;AAEA,SAAK,SAAS,IAAI,OAAO,IAAI;AAAA,MAC3B,GAAG;AAAA,MACH,SAAS,OAAO,WAAW;AAAA,MAC3B,OAAO;AAAA,QACL,aAAa,OAAO,OAAO,eAAe;AAAA,QAC1C,cAAc,OAAO,OAAO,gBAAgB;AAAA,QAC5C,UAAU,OAAO,OAAO,YAAY;AAAA,QACpC,mBAAmB,OAAO,OAAO,qBAAqB;AAAA,MACxD;AAAA,MACA,SAAS,OAAO,WAAW;AAAA,IAC7B,CAAC;AAGD,SAAK,gBAAgB,IAAI,OAAO,IAAI;AAAA,MAClC,OAAO;AAAA,MACP,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,IAAY,SAAmD;AAC3E,UAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AACpC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,sBAAsB,EAAE,EAAE;AAAA,IAC5C;AAEA,SAAK,SAAS,IAAI,IAAI;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,IAAkB;AAC9B,SAAK,SAAS,OAAO,EAAE;AACvB,SAAK,gBAAgB,OAAO,EAAE;AAG9B,UAAM,QAAQ,KAAK,eAAe,IAAI,EAAE;AACxC,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,WAAK,eAAe,OAAO,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,IAAuC;AAChD,WAAO,KAAK,SAAS,IAAI,EAAE;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAkC;AAChC,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAA8D;AAC5E,UAAM,YAA0B;AAAA,MAC9B,IAAI,KAAK,WAAW;AAAA,MACpB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,GAAG;AAAA,IACL;AAGA,UAAM,mBAAmB,KAAK,qBAAqB,SAAS;AAG5D,UAAM,QAAQ;AAAA,MACZ,iBAAiB,IAAI,aAAW,KAAK,eAAe,SAAS,WAAW,CAAC,CAAC;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,QAAyB,UAAkC;AAC/E,UAAM,qBAAqB,OAAO,WAAW;AAAA,MAC3C,OAAK,EAAE,aAAa,cAAc,EAAE,aAAa;AAAA,IACnD;AAEA,QAAI,mBAAmB,WAAW,GAAG;AACnC;AAAA,IACF;AAEA,UAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,QACJ,gBAAgB,mBAAmB;AAAA,QACnC,OAAO,CAAC,GAAG,IAAI,IAAI,mBAAmB,IAAI,OAAK,EAAE,IAAI,CAAC,CAAC;AAAA,QACvD,YAAY,CAAC,GAAG,IAAI,IAAI,mBAAmB,IAAI,OAAK,EAAE,QAAQ,CAAC,CAAC;AAAA,QAChE,YAAY,OAAO,SAAS;AAAA,MAC9B;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,QAAyB,YAAoB,IAAI,UAAkC;AACnG,QAAI,OAAO,WAAW,SAAS,WAAW;AACxC;AAAA,IACF;AAEA,UAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,QACJ,gBAAgB,OAAO,WAAW;AAAA,QAClC,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,WAAW,IAAI,OAAK,EAAE,IAAI,CAAC,CAAC;AAAA,QACtD,YAAY,OAAO,SAAS;AAAA,MAC9B;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,OAAc,UAAkC;AACxE,UAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,QACJ,OAAO,MAAM;AAAA,QACb,OAAO,MAAM;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,YAAoB,YAAoB,KAAM,UAAkC;AACvG,QAAI,aAAa,WAAW;AAC1B;AAAA,IACF;AAEA,UAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,QACJ;AAAA,QACA,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,OAAsC;AACjE,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EAAE,OAAO,aAAW;AAE1D,UAAI,CAAC,QAAQ,SAAS;AACpB,eAAO;AAAA,MACT;AAGA,UAAI,QAAQ,YAAY,MAAM,WAAW,QAAQ,UAAU;AACzD,eAAO;AAAA,MACT;AAGA,UAAI,QAAQ,UAAU,QAAQ,OAAO,SAAS,GAAG;AAC/C,YAAI,CAAC,QAAQ,OAAO,SAAS,MAAM,IAAI,GAAG;AACxC,iBAAO;AAAA,QACT;AAAA,MACF;AAGA,UAAI,QAAQ,aAAa;AACvB,cAAM,gBAAgB,CAAC,QAAQ,OAAO,UAAU,QAAQ,UAAU;AAClE,cAAM,qBAAqB,cAAc,QAAQ,MAAM,QAAQ;AAC/D,cAAM,mBAAmB,cAAc,QAAQ,QAAQ,WAAW;AAElE,YAAI,qBAAqB,kBAAkB;AACzC,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,SACA,OACA,SACe;AAEf,UAAM,eAAe,KAAK,gBAAgB,IAAI,QAAQ,EAAE;AACxD,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,QAAI,aAAa,UAAU,QAAQ;AAEjC,UAAI,aAAa,iBAAiB,oBAAI,KAAK,KAAK,aAAa,eAAe;AAC1E,qBAAa,QAAQ;AACrB,qBAAa,eAAe;AAAA,MAC9B,OAAO;AAEL,aAAK,eAAe;AAAA,UAClB,IAAI,KAAK,WAAW;AAAA,UACpB,WAAW,QAAQ;AAAA,UACnB;AAAA,UACA,QAAQ;AAAA,UACR,WAAW,oBAAI,KAAK;AAAA,UACpB;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,aAAa,KAAK,WAAW;AAEnC,QAAI;AAEF,YAAM,WAAW,MAAM,KAAK,gBAAgB,SAAS,KAAK;AAE1D,YAAM,aAAa,KAAK,IAAI,IAAI;AAGhC,WAAK,eAAe;AAAA,QAClB,IAAI;AAAA,QACJ,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR,YAAY,SAAS;AAAA,QACrB,WAAW,oBAAI,KAAK;AAAA,QACpB;AAAA,QACA,cAAc,SAAS;AAAA,QACvB;AAAA,MACF,CAAC;AAGD,UAAI,aAAa,UAAU,aAAa;AACtC,qBAAa,QAAQ;AACrB,qBAAa,eAAe;AAAA,MAC9B;AAAA,IACF,SAAS,OAAY;AACnB,YAAM,aAAa,KAAK,IAAI,IAAI;AAGhC,WAAK,eAAe;AAAA,QAClB,IAAI;AAAA,QACJ,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR,YAAY,MAAM;AAAA,QAClB,WAAW,oBAAI,KAAK;AAAA,QACpB;AAAA,QACA,OAAO,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAGD,mBAAa;AACb,mBAAa,kBAAkB,oBAAI,KAAK;AAExC,UAAI,aAAa,gBAAgB,KAAK,mBAAmB;AACvD,qBAAa,QAAQ;AACrB,qBAAa,gBAAgB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,gBAAgB;AACxE,gBAAQ,KAAK,uDAAuD,QAAQ,EAAE,EAAE;AAAA,MAClF;AAGA,YAAM,cAAc,QAAQ,MAAO;AACnC,UAAI,UAAU,aAAa;AACzB,cAAM,QAAQ,KAAK,oBAAoB,SAAS,QAAQ,KAAM;AAC9D,gBAAQ,IAAI,qCAAqC,QAAQ,EAAE,OAAO,KAAK,eAAe,UAAU,CAAC,IAAI,WAAW,GAAG;AAEnH,cAAM,UAAU,WAAW,MAAM;AAC/B,eAAK,eAAe,SAAS,OAAO,UAAU,CAAC,EAAE,MAAM,SAAO;AAC5D,oBAAQ,MAAM,6CAA6C,QAAQ,EAAE,KAAK,GAAG;AAAA,UAC/E,CAAC;AACD,eAAK,eAAe,OAAO,QAAQ,EAAE;AAAA,QACvC,GAAG,KAAK;AAER,aAAK,eAAe,IAAI,QAAQ,IAAI,OAAO;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBACZ,SACA,OAC+C;AAC/C,QAAI;AAEF,UAAI;AACJ,UAAI;AACF,gBAAQ,WAAW;AAAA,MACrB,QAAQ;AAEN,cAAM,IAAI,MAAM,mFAAmF;AAAA,MACrG;AAGA,YAAM,UAAkC;AAAA,QACtC,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,GAAG,QAAQ;AAAA,MACb;AAEA,UAAI,QAAQ,QAAQ;AAClB,cAAM,YAAY,KAAK,uBAAuB,OAAO,QAAQ,MAAM;AACnE,gBAAQ,qBAAqB,IAAI;AACjC,gBAAQ,+BAA+B,IAAI;AAAA,MAC7C;AAGA,cAAQ,YAAY,IAAI,MAAM;AAC9B,cAAQ,cAAc,IAAI,MAAM;AAChC,cAAQ,mBAAmB,IAAI,MAAM;AAErC,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,QAAQ,OAAO;AAEtE,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,QAAQ,KAAK;AAAA,UACxC,QAAQ;AAAA,UACR;AAAA,UACA,MAAM,KAAK,UAAU,KAAK;AAAA,UAC1B,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,qBAAa,SAAS;AAEtB,cAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,OAAO,OAAO,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE,GAAG;AAAA,YAChF,YAAY,SAAS;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,UACL,YAAY,SAAS;AAAA,UACrB;AAAA,QACF;AAAA,MACF,SAAS,OAAY;AACnB,qBAAa,SAAS;AACtB,cAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAY;AACnB,YAAM,OAAO,OAAO,IAAI,MAAM,4BAA4B,MAAM,OAAO,EAAE,GAAG;AAAA,QAC1E,YAAY,MAAM,cAAc;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,OAAqB,QAAwB;AAC1E,QAAI;AAEF,YAAM,SAAS,UAAQ,QAAQ;AAC/B,YAAM,UAAU,KAAK,UAAU,KAAK;AACpC,aAAO,OACJ,WAAW,UAAU,MAAM,EAC3B,OAAO,OAAO,EACd,OAAO,KAAK;AAAA,IACjB,QAAQ;AACN,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,SAAiB,aAA0D;AACrG,UAAM,EAAE,cAAc,UAAU,kBAAkB,IAAI;AACtD,UAAM,QAAQ,eAAgB,KAAK,IAAI,mBAAoB,UAAU,CAAC;AACtE,WAAO,KAAK,IAAI,OAAO,QAAS;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,UAAiC;AACtD,SAAK,gBAAgB,KAAK,QAAQ;AAGlC,QAAI,KAAK,gBAAgB,SAAS,KAAK,gBAAgB;AACrD,WAAK,gBAAgB,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,WAAmB,OAAmC;AACvE,UAAM,UAAU,KAAK,gBAAgB,OAAO,OAAK,EAAE,cAAc,SAAS;AAE1E,QAAI,OAAO;AACT,aAAO,QAAQ,MAAM,CAAC,KAAK;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,WAAiC;AAC/C,UAAM,aAAa,KAAK,gBAAgB,OAAO,OAAK,EAAE,cAAc,SAAS;AAC7E,UAAM,aAAa,WAAW,OAAO,OAAK,EAAE,WAAW,SAAS;AAChE,UAAM,SAAS,WAAW,OAAO,OAAK,EAAE,WAAW,QAAQ;AAE3D,UAAM,kBAAkB,WAAW,SAAS,IACxC,WAAW,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,cAAc,IAAI,CAAC,IAAI,WAAW,SACzE;AAEJ,UAAM,eAAe,WAAW,SAAS,IACrC,WAAW,WAAW,SAAS,CAAC,EAAE,YAClC;AAEJ,UAAM,UAAU,KAAK,gBAAgB,IAAI,SAAS;AAElD,WAAO;AAAA,MACL;AAAA,MACA,iBAAiB,WAAW;AAAA,MAC5B,sBAAsB,WAAW;AAAA,MACjC,kBAAkB,OAAO;AAAA,MACzB,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,cAAc,SAAS,SAAS;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAOE;AACA,UAAM,WAAW,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AAClD,UAAM,aAAa,KAAK,gBAAgB,OAAO,OAAK,EAAE,WAAW,SAAS;AAC1E,UAAM,SAAS,KAAK,gBAAgB,OAAO,OAAK,EAAE,WAAW,QAAQ;AAErE,UAAM,kBAAkB,KAAK,gBAAgB,SAAS,IAClD,KAAK,gBAAgB,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,cAAc,IAAI,CAAC,IAAI,KAAK,gBAAgB,SAC7F;AAEJ,WAAO;AAAA,MACL,eAAe,SAAS;AAAA,MACxB,iBAAiB,SAAS,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,MACjD,iBAAiB,KAAK,gBAAgB;AAAA,MACtC,sBAAsB,WAAW;AAAA,MACjC,kBAAkB,OAAO;AAAA,MACzB,mBAAmB;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,SAAK,kBAAkB,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAqB;AAC3B,WAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAAA,EACjE;AACF;AAKO,SAAS,qBAAqB,SAAuD;AAC1F,SAAO,IAAI,eAAe,OAAO;AACnC;AAKO,SAAS,uBACd,SACA,WACA,QACA,YAAiC,UACxB;AACT,MAAI;AAEF,UAAM,SAAS,UAAQ,QAAQ;AAC/B,UAAM,oBAAoB,OACvB,WAAW,WAAW,MAAM,EAC5B,OAAO,OAAO,EACd,OAAO,KAAK;AAEf,WAAO,OAAO;AAAA,MACZ,OAAO,KAAK,SAAS;AAAA,MACrB,OAAO,KAAK,iBAAiB;AAAA,IAC/B;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC/mBO,IAAM,YAAN,MAAgB;AAAA,EAQrB,YAAY,QAA0B;AAHtC,SAAQ,YAAqB;AAC7B,SAAQ,oBAA2C,oBAAI,IAAI;AAGzD,SAAK,SAAS;AAAA,MACZ,MAAM,QAAQ,QAAQ;AAAA,MACtB,MAAM,QAAQ,QAAQ;AAAA,MACtB,YAAY,QAAQ,cAAc;AAAA,MAClC,YAAY,QAAQ,cAAc;AAAA,MAClC,QAAQ,QAAQ;AAAA,MAChB,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,WAAW,QAAQ,aAAa;AAAA,MAChC,WAAW,QAAQ,aAAa;AAAA,MAChC,eAAe,QAAQ,iBAAiB;AAAA,MACxC,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,MACrB,kBAAkB,QAAQ;AAAA,MAC1B,gBAAgB,QAAQ;AAAA,IAC1B;AAGA,QAAI,CAAC,KAAK,OAAO,eAAe;AAC9B,WAAK,WAAW,IAAI,cAAc,KAAK,OAAO,cAAc;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAEA,QAAI;AAGF,YAAM,OAAO,UAAQ,MAAM;AAE3B,WAAK,SAAS,KAAK,aAAa,KAAK,cAAc,KAAK,IAAI,CAAC;AAE7D,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,aAAK,OAAO,OAAO,KAAK,OAAO,MAAM,KAAK,OAAO,MAAM,MAAM;AAC3D,eAAK,YAAY;AACjB,kBAAQ,IAAI,wCAAwC,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,EAAE;AAC1F,kBAAQ,IAAI,yCAAyC,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,WAAW;AACpG,kBAAQ;AAAA,QACV,CAAC;AAED,aAAK,OAAO,GAAG,SAAS,CAAC,UAAe;AACtC,iBAAO,IAAI,MAAM,uCAAuC,MAAM,OAAO,EAAE,CAAC;AAAA,QAC1E,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,OAAY;AACnB,YAAM,IAAI,MAAM,iDAAiD,MAAM,OAAO,EAAE;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAsB;AAC1B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACnC;AAAA,IACF;AAEA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,WAAK,OAAO,MAAM,CAAC,UAAe;AAChC,YAAI,OAAO;AACT,iBAAO,IAAI,MAAM,sCAAsC,MAAM,OAAO,EAAE,CAAC;AAAA,QACzE,OAAO;AACL,eAAK,YAAY;AACjB,kBAAQ,IAAI,4BAA4B;AACxC,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAc,KAAU,KAAyB;AAC7D,UAAM,YAAY,KAAK,IAAI;AAE3B,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK,aAAa,GAAG;AAG1C,UAAI,KAAK,OAAO,YAAY;AAC1B,YAAI,UAAU,+BAA+B,MAAM,QAAQ,KAAK,OAAO,UAAU,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,IAAI,KAAK,OAAO,UAAU;AAC/I,YAAI,UAAU,gCAAgC,iCAAiC;AAC/E,YAAI,UAAU,gCAAgC,qDAAqD;AAEnG,YAAI,IAAI,WAAW,WAAW;AAC5B,cAAI,UAAU,GAAG;AACjB,cAAI,IAAI;AACR;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK,OAAO,QAAQ;AACtB,cAAM,cAAc,OAAO,QAAQ,WAAW,KAAe,OAAO,QAAQ,eAAe,GAAG,SAAS,EAAE,QAAQ,WAAW,EAAE;AAC9H,YAAI,gBAAgB,KAAK,OAAO,QAAQ;AACtC,eAAK,aAAa,KAAK;AAAA,YACrB,QAAQ;AAAA,YACR,MAAM,EAAE,OAAO,gBAAgB,SAAS,kBAAkB;AAAA,UAC5D,CAAC;AACD;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK,OAAO,eAAe;AAC7B,cAAM,eAAe,OAAO,QAAQ,WAAW;AAC/C,YAAI,cAAc;AAChB,gBAAM,SAAS,KAAK,OAAO,cAAc,qBAAqB,YAAY;AAC1E,cAAI,QAAQ;AACV,mBAAO,WAAW,OAAO;AAAA,UAC3B,OAAO;AACL,iBAAK,aAAa,KAAK;AAAA,cACrB,QAAQ;AAAA,cACR,MAAM,EAAE,OAAO,gBAAgB,SAAS,yBAAyB;AAAA,YACnE,CAAC;AACD;AAAA,UACF;AAAA,QACF,OAAO;AAEL,gBAAM,WAAW,OAAO,QAAQ,aAAa;AAC7C,cAAI,CAAC,UAAU;AACb,iBAAK,aAAa,KAAK;AAAA,cACrB,QAAQ;AAAA,cACR,MAAM,EAAE,OAAO,eAAe,SAAS,oDAAoD;AAAA,YAC7F,CAAC;AACD;AAAA,UACF;AACA,iBAAO,WAAW;AAAA,QACpB;AAAA,MACF;AAGA,UAAI,KAAK,OAAO,iBAAiB;AAC/B,cAAM,YAAY,OAAO,YAAY,OAAO,MAAM;AAClD,YAAI,CAAC,KAAK,eAAe,SAAS,GAAG;AACnC,eAAK,aAAa,KAAK;AAAA,YACrB,QAAQ;AAAA,YACR,MAAM,EAAE,OAAO,qBAAqB,SAAS,wBAAwB,KAAK,OAAO,SAAS,uBAAuB;AAAA,UACnH,CAAC;AACD;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,MAAM,KAAK,aAAa,MAAM;AAG/C,UAAI,KAAK,OAAO,eAAe;AAC7B,cAAM,aAAa,KAAK,IAAI,IAAI;AAChC,gBAAQ,IAAI,eAAe,IAAI,MAAM,IAAI,IAAI,GAAG,IAAI,SAAS,MAAM,IAAI,UAAU,IAAI;AAAA,MACvF;AAEA,WAAK,aAAa,KAAK,QAAQ;AAAA,IACjC,SAAS,OAAY;AACnB,cAAQ,MAAM,sCAAsC,KAAK;AACzD,WAAK,aAAa,KAAK;AAAA,QACrB,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,yBAAyB,SAAS,MAAM,QAAQ;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,KAA+B;AAExD,UAAM,MAAM,IAAI,IAAI,IAAI,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AAGxE,QAAI,OAAY,CAAC;AACjB,QAAI,IAAI,WAAW,SAAS,IAAI,WAAW,QAAQ;AACjD,aAAO,MAAM,KAAK,UAAU,GAAG;AAAA,IACjC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,SAAS,IAAI;AAAA,MACb,OAAO,OAAO,YAAY,IAAI,YAAY;AAAA,MAC1C,QAAQ,CAAC;AAAA,MACT,IAAI,IAAI,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAU,KAAwB;AAC9C,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAe;AAC7B,gBAAQ,MAAM,SAAS;AAAA,MACzB,CAAC;AACD,UAAI,GAAG,OAAO,MAAM;AAClB,YAAI;AACF,kBAAQ,KAAK,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClC,QAAQ;AACN,kBAAQ,CAAC,CAAC;AAAA,QACZ;AAAA,MACF,CAAC;AACD,UAAI,GAAG,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,KAAuC;AAChE,UAAM,MAAM,IAAI,IAAI,IAAI,QAAQ,OAAO,UAAU,IAAI,QAAQ,IAAI,KAAK,kBAAkB;AACxF,UAAMC,QAAO,IAAI;AACjB,UAAM,SAAS,IAAI,QAAQ,SAAS,KAAK;AAGzC,QAAIA,UAAS,iBAAiB,WAAW,QAAQ;AAC/C,aAAO,KAAK,aAAa,GAAG;AAAA,IAC9B;AACA,QAAIA,UAAS,iBAAiB,WAAW,QAAQ;AAC/C,aAAO,KAAK,aAAa,GAAG;AAAA,IAC9B;AACA,QAAIA,UAAS,kBAAkB,WAAW,QAAQ;AAChD,aAAO,KAAK,cAAc,GAAG;AAAA,IAC/B;AACA,QAAIA,UAAS,qBAAqB,WAAW,OAAO;AAClD,aAAO,KAAK,gBAAgB,GAAG;AAAA,IACjC;AACA,QAAIA,UAAS,sBAAsB,WAAW,OAAO;AACnD,aAAO,KAAK,iBAAiB,GAAG;AAAA,IAClC;AACA,QAAIA,UAAS,kBAAkB,WAAW,OAAO;AAC/C,aAAO,KAAK,cAAc,GAAG;AAAA,IAC/B;AACA,QAAIA,UAAS,mBAAmB,WAAW,OAAO;AAChD,aAAO,KAAK,kBAAkB,GAAG;AAAA,IACnC;AACA,QAAIA,UAAS,iBAAiB,WAAW,OAAO;AAC9C,aAAO,KAAK,aAAa,GAAG;AAAA,IAC9B;AACA,QAAIA,UAAS,eAAe,WAAW,OAAO;AAC5C,aAAO,KAAK,WAAW,GAAG;AAAA,IAC5B;AACA,QAAIA,UAAS,OAAO,WAAW,OAAO;AACpC,aAAO,KAAK,WAAW,GAAG;AAAA,IAC5B;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,EAAE,OAAO,aAAa,SAAS,oBAAoB,MAAM,IAAIA,KAAI,GAAG;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,KAAuC;AAChE,UAAM,EAAE,KAAK,IAAI,IAAI;AAErB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,eAAe,SAAS,kCAAkC;AAAA,MAC3E;AAAA,IACF;AAEA,QAAI;AACF,UAAI;AAEJ,UAAI,IAAI,YAAY,KAAK,OAAO,eAAe;AAE7C,iBAAS,MAAM,KAAK,OAAO,cAAc,OAAO,IAAI,UAAU,IAAI;AAAA,MACpE,WAAW,KAAK,UAAU;AAExB,iBAAS,KAAK,SAAS,OAAO,IAAI;AAAA,MACpC,OAAO;AACL,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAGA,UAAI,KAAK,OAAO,gBAAgB;AAC9B,cAAM,KAAK,OAAO,eAAe,gBAAgB,QAAQ,IAAI,QAAQ;AACrE,cAAM,KAAK,OAAO,eAAe,YAAY,QAAQ,IAAI,IAAI,QAAQ;AAAA,MACvE;AAEA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,QAAQ;AAAA,YACN,YAAY,OAAO;AAAA,YACnB,OAAO,OAAO;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,oBAAoB,SAAS,MAAM,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,KAAuC;AAChE,UAAM,EAAE,KAAK,IAAI,IAAI;AAErB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,eAAe,SAAS,kCAAkC;AAAA,MAC3E;AAAA,IACF;AAEA,QAAI;AACF,UAAI;AAEJ,UAAI,IAAI,YAAY,KAAK,OAAO,eAAe;AAC7C,iBAAS,MAAM,KAAK,OAAO,cAAc,OAAO,IAAI,UAAU,IAAI;AAAA,MACpE,WAAW,KAAK,UAAU;AACxB,iBAAS,KAAK,SAAS,OAAO,IAAI;AAAA,MACpC,OAAO;AACL,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,QAAQ;AAAA,YACN,UAAU,OAAO;AAAA,YACjB,UAAU,OAAO;AAAA,YACjB,YAAY,OAAO;AAAA,YACnB,OAAO,OAAO;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,oBAAoB,SAAS,MAAM,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAc,KAAuC;AACjE,UAAM,EAAE,UAAU,aAAa,IAAI,IAAI;AAEvC,QAAI,CAAC,YAAY,CAAC,cAAc;AAC9B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,eAAe,SAAS,8CAA8C;AAAA,MACvF;AAAA,IACF;AAEA,QAAI;AACF,UAAI;AAEJ,UAAI,IAAI,YAAY,KAAK,OAAO,eAAe;AAC7C,mBAAW,KAAK,OAAO,cAAc,YAAY,IAAI,QAAQ;AAAA,MAC/D,WAAW,KAAK,UAAU;AACxB,mBAAW,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,YAAM,WAAW,SAAS,QAAQ,UAAU,YAAY;AAExD,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,QAAQ,EAAE,SAAS;AAAA,QACrB;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,kBAAkB,SAAS,MAAM,QAAQ;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAAgB,KAAuC;AACnE,QAAI,CAAC,KAAK,OAAO,aAAa;AAC5B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,mBAAmB,SAAS,+BAA+B;AAAA,MAC5E;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,SAAS,IAAI,MAAM,SAAmB,KAAK;AACzD,YAAM,OAAO,MAAM,KAAK,OAAO,YAAY,UAAU,EAAE,MAAM,CAAC;AAE9D,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,gBAAgB,SAAS,MAAM,QAAQ;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,MAAwC;AACrE,QAAI,CAAC,KAAK,OAAO,aAAa;AAC5B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,mBAAmB,SAAS,+BAA+B;AAAA,MAC5E;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,OAAO,YAAY,cAAc;AAE1D,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,gBAAgB,SAAS,MAAM,QAAQ;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAc,KAAuC;AACjE,QAAI,KAAK,UAAU;AAEjB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,SAAS,CAAC;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,iBAAiB,IAAI,UAAU;AAE7C,YAAM,QAAQ,KAAK,OAAO,cAAc,eAAe,IAAI,QAAQ;AAEnE,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,EAAE,OAAO,mBAAmB,SAAS,yBAAyB;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAkB,KAAuC;AACrE,QAAI;AACF,UAAI;AAEJ,UAAI,IAAI,YAAY,KAAK,OAAO,eAAe;AAC7C,mBAAW,KAAK,OAAO,cAAc,YAAY,IAAI,QAAQ;AAAA,MAC/D,WAAW,KAAK,UAAU;AACxB,mBAAW,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,YAAM,WAAW,SAAS,YAAY;AAEtC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,UAAU,SAAS,IAAI,QAAM;AAAA,YAC3B,MAAM,EAAE;AAAA,YACR,UAAU,EAAE;AAAA,YACZ,aAAa,EAAE;AAAA,YACf,UAAU,EAAE;AAAA,UACd,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,gBAAgB,SAAS,MAAM,QAAQ;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,MAAwC;AACjE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,QAAQ,QAAQ,OAAO;AAAA,QACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,aAAa,CAAC,CAAC,KAAK,OAAO;AAAA,QAC3B,UAAU;AAAA,UACR,OAAO,CAAC,CAAC,KAAK,OAAO;AAAA,UACrB,UAAU,CAAC,CAAC,KAAK,OAAO;AAAA,UACxB,YAAY,CAAC,CAAC,KAAK,OAAO;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,MAAwC;AAC/D,UAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBb,KAAK,OAAO,gBAAgB,gFAAgF,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBA0ElG,KAAK,OAAO,IAAI;AAAA,gBAChB,KAAK,OAAO,IAAI;AAAA,gBAChB,KAAK,OAAO,aAAa,YAAY,UAAU;AAAA,yBACtC,KAAK,OAAO,kBAAkB,GAAG,KAAK,OAAO,SAAS,aAAa,UAAU;AAAA,wBAC9E,KAAK,OAAO,gBAAgB,YAAY,UAAU;AAAA,yBACjD,KAAK,OAAO,cAAc,YAAY,UAAU;AAAA,oBACrD,KAAK,OAAO,iBAAiB,YAAY,UAAU;AAAA;AAAA;AAAA;AAAA,MAIjE,KAAK;AAEP,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS,EAAE,gBAAgB,YAAY;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,MAAwC;AAC/D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,eAAe;AAAA,QACf,QAAQ;AAAA,QACR,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,KAAU,UAA6B;AAC1D,UAAM,UAAU;AAAA,MACd,gBAAgB;AAAA,MAChB,GAAG,SAAS;AAAA,IACd;AAEA,QAAI,UAAU,SAAS,QAAQ,OAAO;AAEtC,QAAI,OAAO,SAAS,SAAS,UAAU;AACrC,UAAI,IAAI,SAAS,IAAI;AAAA,IACvB,OAAO;AACL,UAAI,IAAI,KAAK,UAAU,SAAS,IAAI,CAAC;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,WAA4B;AACjD,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,aAAa,KAAK,kBAAkB,IAAI,SAAS,KAAK,CAAC;AAG7D,UAAM,eAAe,MAAM,KAAK;AAChC,UAAM,mBAAmB,WAAW,OAAO,QAAM,KAAK,YAAY;AAElE,QAAI,iBAAiB,UAAU,KAAK,OAAO,WAAW;AACpD,aAAO;AAAA,IACT;AAEA,qBAAiB,KAAK,GAAG;AACzB,SAAK,kBAAkB,IAAI,WAAW,gBAAgB;AAEtD,WAAO;AAAA,EACT;AACF;AAKO,SAAS,gBAAgB,QAAqC;AACnE,SAAO,IAAI,UAAU,MAAM;AAC7B;;;ACjdA;","names":["fs","entries","financialPatterns","RFQ_NUMBER","SUPPLIER_ID","CONTRACT_REFERENCE","financialPatterns","first","last","fs","path","credentialPatterns","financialPatterns","result","path","match","ConfigExporter","HealthChecker","createDocumentProcessor","fs","createWorkerPool","start","end","path"]}
|