@bernierllc/email-manager 0.1.1
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/LICENSE +5 -0
- package/README.md +534 -0
- package/dist/email-manager.d.ts +134 -0
- package/dist/email-manager.d.ts.map +1 -0
- package/dist/email-manager.js +360 -0
- package/dist/email-manager.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/email-analytics.d.ts +92 -0
- package/dist/managers/email-analytics.d.ts.map +1 -0
- package/dist/managers/email-analytics.js +375 -0
- package/dist/managers/email-analytics.js.map +1 -0
- package/dist/managers/email-scheduler.d.ts +81 -0
- package/dist/managers/email-scheduler.d.ts.map +1 -0
- package/dist/managers/email-scheduler.js +288 -0
- package/dist/managers/email-scheduler.js.map +1 -0
- package/dist/managers/provider-manager.d.ts +104 -0
- package/dist/managers/provider-manager.d.ts.map +1 -0
- package/dist/managers/provider-manager.js +436 -0
- package/dist/managers/provider-manager.js.map +1 -0
- package/dist/managers/template-manager.d.ts +65 -0
- package/dist/managers/template-manager.d.ts.map +1 -0
- package/dist/managers/template-manager.js +314 -0
- package/dist/managers/template-manager.js.map +1 -0
- package/dist/types.d.ts +507 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +60 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/simple-template-engine.d.ts +27 -0
- package/dist/utils/simple-template-engine.d.ts.map +1 -0
- package/dist/utils/simple-template-engine.js +61 -0
- package/dist/utils/simple-template-engine.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
/**
|
|
10
|
+
* Email Scheduling System
|
|
11
|
+
* Handles queuing and scheduled delivery of emails
|
|
12
|
+
*/
|
|
13
|
+
export class EmailScheduler {
|
|
14
|
+
constructor(sendEmailCallback, config = {
|
|
15
|
+
enabled: true,
|
|
16
|
+
checkIntervalMs: 60000, // Check every minute
|
|
17
|
+
maxRetries: 3,
|
|
18
|
+
retryDelayMs: 300000 // 5 minutes
|
|
19
|
+
}) {
|
|
20
|
+
this.queue = [];
|
|
21
|
+
this.isRunning = false;
|
|
22
|
+
this.interval = null;
|
|
23
|
+
this.sendEmailCallback = sendEmailCallback;
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Schedule an email for future delivery
|
|
28
|
+
*/
|
|
29
|
+
async scheduleEmail(email, scheduleTime) {
|
|
30
|
+
try {
|
|
31
|
+
// Validate schedule time
|
|
32
|
+
if (scheduleTime <= new Date()) {
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
scheduleId: '',
|
|
36
|
+
scheduledFor: scheduleTime,
|
|
37
|
+
emailId: '',
|
|
38
|
+
status: 'cancelled'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const scheduleId = uuidv4();
|
|
42
|
+
const scheduledEmail = {
|
|
43
|
+
id: scheduleId,
|
|
44
|
+
email,
|
|
45
|
+
scheduledFor: scheduleTime,
|
|
46
|
+
status: 'scheduled',
|
|
47
|
+
createdAt: new Date()
|
|
48
|
+
};
|
|
49
|
+
// Add to queue and sort
|
|
50
|
+
this.queue.push(scheduledEmail);
|
|
51
|
+
this.sortQueue();
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
scheduleId,
|
|
55
|
+
scheduledFor: scheduleTime,
|
|
56
|
+
emailId: scheduleId,
|
|
57
|
+
status: 'scheduled'
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
scheduleId: '',
|
|
64
|
+
scheduledFor: scheduleTime,
|
|
65
|
+
emailId: '',
|
|
66
|
+
status: 'cancelled'
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Cancel a scheduled email
|
|
72
|
+
*/
|
|
73
|
+
async cancelScheduledEmail(scheduleId) {
|
|
74
|
+
try {
|
|
75
|
+
const index = this.queue.findIndex(item => item.id === scheduleId);
|
|
76
|
+
if (index === -1) {
|
|
77
|
+
return {
|
|
78
|
+
success: false,
|
|
79
|
+
error: 'Scheduled email not found'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const scheduledEmail = this.queue[index];
|
|
83
|
+
// Check if email can be cancelled (not already sent)
|
|
84
|
+
if (scheduledEmail.status === 'sent') {
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
error: 'Cannot cancel email that has already been sent'
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Update status and remove from queue
|
|
91
|
+
scheduledEmail.status = 'cancelled';
|
|
92
|
+
this.queue.splice(index, 1);
|
|
93
|
+
return {
|
|
94
|
+
success: true,
|
|
95
|
+
message: 'Scheduled email cancelled successfully'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get scheduled email by ID
|
|
107
|
+
*/
|
|
108
|
+
getScheduledEmail(scheduleId) {
|
|
109
|
+
return this.queue.find(item => item.id === scheduleId) || null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* List all scheduled emails
|
|
113
|
+
*/
|
|
114
|
+
listScheduledEmails(status) {
|
|
115
|
+
let filtered = [...this.queue];
|
|
116
|
+
if (status) {
|
|
117
|
+
filtered = filtered.filter(item => item.status === status);
|
|
118
|
+
}
|
|
119
|
+
// Sort by schedule time
|
|
120
|
+
filtered.sort((a, b) => a.scheduledFor.getTime() - b.scheduledFor.getTime());
|
|
121
|
+
return filtered;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Start the scheduler
|
|
125
|
+
*/
|
|
126
|
+
startScheduler() {
|
|
127
|
+
if (!this.config.enabled || this.isRunning) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.isRunning = true;
|
|
131
|
+
this.interval = setInterval(() => {
|
|
132
|
+
this.processQueue();
|
|
133
|
+
}, this.config.checkIntervalMs);
|
|
134
|
+
console.log('Email scheduler started');
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Stop the scheduler
|
|
138
|
+
*/
|
|
139
|
+
stopScheduler() {
|
|
140
|
+
if (!this.isRunning) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this.isRunning = false;
|
|
144
|
+
if (this.interval) {
|
|
145
|
+
clearInterval(this.interval);
|
|
146
|
+
this.interval = null;
|
|
147
|
+
}
|
|
148
|
+
console.log('Email scheduler stopped');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Process the email queue
|
|
152
|
+
*/
|
|
153
|
+
async processQueue() {
|
|
154
|
+
if (!this.config.enabled) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const now = new Date();
|
|
158
|
+
const readyEmails = this.queue.filter(item => item.status === 'scheduled' && item.scheduledFor <= now);
|
|
159
|
+
console.log(`Processing ${readyEmails.length} scheduled emails`);
|
|
160
|
+
for (const scheduledEmail of readyEmails) {
|
|
161
|
+
await this.processSingleEmail(scheduledEmail);
|
|
162
|
+
}
|
|
163
|
+
// Clean up old completed emails (keep only last 1000)
|
|
164
|
+
this.cleanupCompletedEmails();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Process a single scheduled email
|
|
168
|
+
*/
|
|
169
|
+
async processSingleEmail(scheduledEmail) {
|
|
170
|
+
try {
|
|
171
|
+
// Attempt to send email
|
|
172
|
+
const result = await this.sendEmailCallback(scheduledEmail.email);
|
|
173
|
+
// Update scheduled email status
|
|
174
|
+
scheduledEmail.status = result.success ? 'sent' : 'failed';
|
|
175
|
+
scheduledEmail.sentAt = new Date();
|
|
176
|
+
scheduledEmail.result = result;
|
|
177
|
+
// Remove from queue if sent successfully
|
|
178
|
+
if (result.success) {
|
|
179
|
+
const index = this.queue.findIndex(item => item.id === scheduledEmail.id);
|
|
180
|
+
if (index !== -1) {
|
|
181
|
+
this.queue.splice(index, 1);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Handle retry logic for failed emails
|
|
186
|
+
await this.handleFailedEmail(scheduledEmail);
|
|
187
|
+
}
|
|
188
|
+
console.log(`Scheduled email ${scheduledEmail.id} ${result.success ? 'sent successfully' : 'failed to send'}`);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.error(`Failed to send scheduled email ${scheduledEmail.id}:`, error);
|
|
192
|
+
scheduledEmail.status = 'failed';
|
|
193
|
+
scheduledEmail.error = error instanceof Error ? error.message : 'Unknown error';
|
|
194
|
+
await this.handleFailedEmail(scheduledEmail);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Handle failed email delivery with retry logic
|
|
199
|
+
*/
|
|
200
|
+
async handleFailedEmail(scheduledEmail) {
|
|
201
|
+
const retryCount = scheduledEmail.retryCount || 0;
|
|
202
|
+
if (retryCount < this.config.maxRetries) {
|
|
203
|
+
// Schedule retry
|
|
204
|
+
const retryTime = new Date(Date.now() + this.config.retryDelayMs);
|
|
205
|
+
scheduledEmail.retryCount = retryCount + 1;
|
|
206
|
+
scheduledEmail.scheduledFor = retryTime;
|
|
207
|
+
scheduledEmail.status = 'scheduled';
|
|
208
|
+
// Re-sort queue
|
|
209
|
+
this.sortQueue();
|
|
210
|
+
console.log(`Scheduled retry ${retryCount + 1}/${this.config.maxRetries} for email ${scheduledEmail.id} at ${retryTime.toISOString()}`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Max retries reached, mark as permanently failed
|
|
214
|
+
console.error(`Email ${scheduledEmail.id} failed permanently after ${this.config.maxRetries} retries`);
|
|
215
|
+
// Remove from queue
|
|
216
|
+
const index = this.queue.findIndex(item => item.id === scheduledEmail.id);
|
|
217
|
+
if (index !== -1) {
|
|
218
|
+
this.queue.splice(index, 1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Sort queue by scheduled time
|
|
224
|
+
*/
|
|
225
|
+
sortQueue() {
|
|
226
|
+
this.queue.sort((a, b) => a.scheduledFor.getTime() - b.scheduledFor.getTime());
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Clean up old completed emails to prevent memory issues
|
|
230
|
+
*/
|
|
231
|
+
cleanupCompletedEmails() {
|
|
232
|
+
const completedEmails = this.queue.filter(item => item.status === 'sent' || item.status === 'cancelled');
|
|
233
|
+
if (completedEmails.length > 1000) {
|
|
234
|
+
// Remove oldest completed emails
|
|
235
|
+
const toRemove = completedEmails
|
|
236
|
+
.sort((a, b) => (a.sentAt || a.createdAt).getTime() - (b.sentAt || b.createdAt).getTime())
|
|
237
|
+
.slice(0, completedEmails.length - 1000);
|
|
238
|
+
for (const email of toRemove) {
|
|
239
|
+
const index = this.queue.findIndex(item => item.id === email.id);
|
|
240
|
+
if (index !== -1) {
|
|
241
|
+
this.queue.splice(index, 1);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get scheduler statistics
|
|
248
|
+
*/
|
|
249
|
+
getStats() {
|
|
250
|
+
const now = new Date();
|
|
251
|
+
const scheduled = this.queue.filter(item => item.status === 'scheduled');
|
|
252
|
+
const overdue = scheduled.filter(item => item.scheduledFor <= now);
|
|
253
|
+
return {
|
|
254
|
+
isRunning: this.isRunning,
|
|
255
|
+
totalInQueue: this.queue.length,
|
|
256
|
+
scheduled: scheduled.length,
|
|
257
|
+
overdue: overdue.length,
|
|
258
|
+
nextScheduled: scheduled.length > 0
|
|
259
|
+
? scheduled.sort((a, b) => a.scheduledFor.getTime() - b.scheduledFor.getTime())[0].scheduledFor
|
|
260
|
+
: null,
|
|
261
|
+
config: this.config
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Update scheduler configuration
|
|
266
|
+
*/
|
|
267
|
+
updateConfig(config) {
|
|
268
|
+
this.config = { ...this.config, ...config };
|
|
269
|
+
// Restart scheduler if interval changed
|
|
270
|
+
if (config.checkIntervalMs && this.isRunning) {
|
|
271
|
+
this.stopScheduler();
|
|
272
|
+
this.startScheduler();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Clear all scheduled emails (for testing)
|
|
277
|
+
*/
|
|
278
|
+
clear() {
|
|
279
|
+
this.queue = [];
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get queue length
|
|
283
|
+
*/
|
|
284
|
+
getQueueLength() {
|
|
285
|
+
return this.queue.length;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=email-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-scheduler.js","sourceRoot":"","sources":["../../src/managers/email-scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { EmailSender } from '@bernierllc/email-sender';
|
|
2
|
+
import { EmailProvider, EmailData, SendResult, ProviderResult, DeleteResult, ProviderList, ProviderStatus, TestResult } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Provider Management System
|
|
5
|
+
* Handles email provider configuration, fallback, and load balancing
|
|
6
|
+
*/
|
|
7
|
+
export declare class ProviderManager {
|
|
8
|
+
private providers;
|
|
9
|
+
private emailSender;
|
|
10
|
+
private activeProviders;
|
|
11
|
+
private usageTracking;
|
|
12
|
+
constructor(emailSender: EmailSender);
|
|
13
|
+
/**
|
|
14
|
+
* Add a new email provider
|
|
15
|
+
*/
|
|
16
|
+
addProvider(provider: EmailProvider): Promise<ProviderResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a provider
|
|
19
|
+
*/
|
|
20
|
+
removeProvider(providerId: string): Promise<DeleteResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Get a provider by ID
|
|
23
|
+
*/
|
|
24
|
+
getProvider(providerId: string): Promise<EmailProvider | null>;
|
|
25
|
+
/**
|
|
26
|
+
* List all providers
|
|
27
|
+
*/
|
|
28
|
+
listProviders(): Promise<ProviderList>;
|
|
29
|
+
/**
|
|
30
|
+
* Send email with provider fallback
|
|
31
|
+
*/
|
|
32
|
+
sendEmail(email: EmailData): Promise<SendResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Get provider status
|
|
35
|
+
*/
|
|
36
|
+
getProviderStatus(providerId: string): Promise<ProviderStatus | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Test provider connection
|
|
39
|
+
*/
|
|
40
|
+
testConnection(providerId: string): Promise<TestResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Send email with specific provider
|
|
43
|
+
*/
|
|
44
|
+
private sendWithProvider;
|
|
45
|
+
/**
|
|
46
|
+
* Get available providers sorted by priority
|
|
47
|
+
*/
|
|
48
|
+
private getAvailableProviders;
|
|
49
|
+
/**
|
|
50
|
+
* Check if provider is within rate limits
|
|
51
|
+
*/
|
|
52
|
+
private checkRateLimit;
|
|
53
|
+
/**
|
|
54
|
+
* Update usage tracking for a provider
|
|
55
|
+
*/
|
|
56
|
+
private updateUsageTracking;
|
|
57
|
+
/**
|
|
58
|
+
* Initialize usage tracking for a provider
|
|
59
|
+
*/
|
|
60
|
+
private initializeUsageTracking;
|
|
61
|
+
/**
|
|
62
|
+
* Reset usage counters based on time intervals
|
|
63
|
+
*/
|
|
64
|
+
private resetUsageCounters;
|
|
65
|
+
/**
|
|
66
|
+
* Update the active providers list
|
|
67
|
+
*/
|
|
68
|
+
private updateActiveProviders;
|
|
69
|
+
/**
|
|
70
|
+
* Validate provider configuration
|
|
71
|
+
*/
|
|
72
|
+
private validateProvider;
|
|
73
|
+
/**
|
|
74
|
+
* Test provider connection
|
|
75
|
+
*/
|
|
76
|
+
private testProviderConnection;
|
|
77
|
+
/**
|
|
78
|
+
* Get provider statistics
|
|
79
|
+
*/
|
|
80
|
+
getStats(): {
|
|
81
|
+
total: number;
|
|
82
|
+
active: number;
|
|
83
|
+
inactive: number;
|
|
84
|
+
byType: Record<string, number>;
|
|
85
|
+
usageStats: Record<string, {
|
|
86
|
+
minute: number;
|
|
87
|
+
hour: number;
|
|
88
|
+
day: number;
|
|
89
|
+
}>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Group providers by type
|
|
93
|
+
*/
|
|
94
|
+
private groupByType;
|
|
95
|
+
/**
|
|
96
|
+
* Get usage statistics
|
|
97
|
+
*/
|
|
98
|
+
private getUsageStats;
|
|
99
|
+
/**
|
|
100
|
+
* Clear all providers (for testing)
|
|
101
|
+
*/
|
|
102
|
+
clear(): void;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=provider-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-manager.d.ts","sourceRoot":"","sources":["../../src/managers/provider-manager.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,EAGX,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,aAAa,CAA0F;gBAEnG,WAAW,EAAE,WAAW;IAOpC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA8CnE;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAyB/D;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAIpE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC;IAY5C;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCtD;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAuB3E;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAY7D;;OAEG;YACW,gBAAgB;IAuC9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAiBtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAS/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsDxB;;OAEG;YACW,sBAAsB;IA0BpC;;OAEG;IACH,QAAQ;;;;;;oBA4B0C,MAAM;kBAAQ,MAAM;iBAAO,MAAM;;;IAhBnF;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd"}
|