medusajs-documents-plugin 0.0.0-stage → 1.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.
Files changed (39) hide show
  1. package/.medusa/server/src/admin/index.js +2427 -0
  2. package/.medusa/server/src/admin/index.mjs +2428 -0
  3. package/.medusa/server/src/api/admin/documents/[id]/document/route.js +36 -0
  4. package/.medusa/server/src/api/admin/documents/[id]/send/route.js +41 -0
  5. package/.medusa/server/src/api/admin/documents/[id]/sync-zoho/route.js +68 -0
  6. package/.medusa/server/src/api/admin/documents/custom/route.js +48 -0
  7. package/.medusa/server/src/api/admin/documents/manual/route.js +46 -0
  8. package/.medusa/server/src/api/admin/documents/route.js +36 -0
  9. package/.medusa/server/src/api/admin/documents/settings/route.js +44 -0
  10. package/.medusa/server/src/api/admin/documents/templates/preview/route.js +159 -0
  11. package/.medusa/server/src/api/admin/documents/zoho/list/route.js +51 -0
  12. package/.medusa/server/src/api/documents/[id]/document/route.js +36 -0
  13. package/.medusa/server/src/api/documents/r/[code]/route.js +29 -0
  14. package/.medusa/server/src/api/documents/templates/preview/route.js +159 -0
  15. package/.medusa/server/src/api/store/documents/r/[code]/route.js +22 -0
  16. package/.medusa/server/src/index.js +27 -0
  17. package/.medusa/server/src/modules/documents/index.js +13 -0
  18. package/.medusa/server/src/modules/documents/migrations/Migration20261012164601.js +23 -0
  19. package/.medusa/server/src/modules/documents/migrations/Migration20261014150000.js +20 -0
  20. package/.medusa/server/src/modules/documents/models/document-link.js +12 -0
  21. package/.medusa/server/src/modules/documents/models/document-record.js +33 -0
  22. package/.medusa/server/src/modules/documents/models/document-settings.js +61 -0
  23. package/.medusa/server/src/modules/documents/service.js +456 -0
  24. package/.medusa/server/src/services/notification-sender.js +293 -0
  25. package/.medusa/server/src/services/pdf-post-processor.js +64 -0
  26. package/.medusa/server/src/services/pdfkit-generator.js +438 -0
  27. package/.medusa/server/src/services/zoho-books.js +221 -0
  28. package/.medusa/server/src/subscribers/order-documents.js +178 -0
  29. package/.medusa/server/src/subscribers/repair-documents.js +162 -0
  30. package/.medusa/server/src/utils/integrate.js +37 -0
  31. package/.medusa/server/src/utils/payment-link.js +69 -0
  32. package/.medusa/server/src/workflows/create-manual-document.js +27 -0
  33. package/.medusa/server/src/workflows/generate-document.js +24 -0
  34. package/.medusa/server/src/workflows/index.js +20 -0
  35. package/.medusa/server/src/workflows/send-document-notification.js +41 -0
  36. package/CHANGELOG.md +87 -0
  37. package/LICENSE +21 -0
  38. package/README.md +201 -2
  39. package/package.json +86 -4
@@ -0,0 +1,456 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DocumentModuleService = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const document_settings_1 = require("./models/document-settings");
6
+ const document_record_1 = require("./models/document-record");
7
+ const document_link_1 = require("./models/document-link");
8
+ const zoho_books_1 = require("../../services/zoho-books");
9
+ const pdfkit_generator_1 = require("../../services/pdfkit-generator");
10
+ const pdf_post_processor_1 = require("../../services/pdf-post-processor");
11
+ const notification_sender_1 = require("../../services/notification-sender");
12
+ class DocumentModuleService extends (0, utils_1.MedusaService)({
13
+ DocumentSettings: document_settings_1.DocumentSettings,
14
+ DocumentRecord: document_record_1.DocumentRecord,
15
+ DocumentLink: document_link_1.DocumentLink,
16
+ }) {
17
+ /**
18
+ * Retrieves or initializes default plugin settings
19
+ */
20
+ async getSettings() {
21
+ const [settings] = await this.listDocumentSettings({});
22
+ if (settings) {
23
+ return settings;
24
+ }
25
+ return await this.createDocumentSettings({
26
+ company_name: "Store",
27
+ email_notifications_enabled: true,
28
+ sms_notifications_enabled: true,
29
+ whatsapp_notifications_enabled: true,
30
+ invoice_template: "modern",
31
+ packing_slip_template: "modern",
32
+ receipt_template: "modern",
33
+ estimate_template: "modern",
34
+ job_card_template: "modern",
35
+ custom_doc_template: "modern",
36
+ email_subject_template: null,
37
+ email_body_template: null,
38
+ sms_body_template: null,
39
+ whatsapp_body_template: null,
40
+ });
41
+ }
42
+ /**
43
+ * Creates or returns an existing short URL
44
+ */
45
+ async getOrGenerateShortUrl(url, baseUrl) {
46
+ if (!url)
47
+ return url;
48
+ try {
49
+ const existing = await this.listDocumentLinks({ url });
50
+ let root = (baseUrl || process.env.STORE_URL || "http://localhost:3000").replace(/\/$/, "");
51
+ if (existing && existing.length > 0) {
52
+ return `${root}/api/store/documents/r/${existing[0].shortcode}`;
53
+ }
54
+ const shortcode = Math.random().toString(36).substring(2, 8);
55
+ await this.createDocumentLinks({
56
+ shortcode,
57
+ url,
58
+ });
59
+ return `${root}/api/store/documents/r/${shortcode}`;
60
+ }
61
+ catch (e) {
62
+ return url;
63
+ }
64
+ }
65
+ /**
66
+ * High-level document generation engine:
67
+ * Handles Zoho Books routing, PDFKit fallback, QR code embedding, shortlinks, and auto-notification.
68
+ */
69
+ async generateDocument(input, container) {
70
+ const settings = await this.getSettings();
71
+ const storeUrl = (settings.storefront_url || process.env.STORE_URL || "http://localhost:3000").replace(/\/$/, "");
72
+ // 0. Auto-hydrate repair ticket data if needed
73
+ if (input.repair_ticket_id && (!input.customer || !input.items || input.items.length === 0)) {
74
+ try {
75
+ const query = container?.resolve?.(utils_1.ContainerRegistrationKeys.QUERY);
76
+ if (query) {
77
+ const { data: tickets } = await query.graph({
78
+ entity: "repair_ticket",
79
+ fields: ["*", "device.*", "product_variants.*"],
80
+ filters: { id: input.repair_ticket_id },
81
+ });
82
+ if (tickets && tickets.length > 0) {
83
+ const ticket = tickets[0];
84
+ input.display_id = input.display_id || (input.type === "job_card" ? `JOB-${ticket.ticket_number}` : `RT-${ticket.ticket_number}`);
85
+ input.title = input.title || (input.type === "job_card" ? "Repair Job Card" : "Repair Document");
86
+ let customerName = "Valued Customer";
87
+ let customerEmail = undefined;
88
+ let customerPhone = undefined;
89
+ if (ticket.customer_id) {
90
+ const custMod = container.resolve("customer", { allowUnregistered: true });
91
+ if (custMod) {
92
+ const c = await custMod.retrieveCustomer(ticket.customer_id);
93
+ if (c) {
94
+ customerName = c.first_name ? `${c.first_name} ${c.last_name || ""}`.trim() : c.email || customerName;
95
+ customerEmail = c.email || undefined;
96
+ customerPhone = c.phone || undefined;
97
+ }
98
+ }
99
+ }
100
+ if (!input.customer) {
101
+ input.customer = {
102
+ name: customerName,
103
+ email: customerEmail,
104
+ phone: customerPhone,
105
+ };
106
+ }
107
+ if (!input.items || input.items.length === 0) {
108
+ input.items = [];
109
+ if (ticket.product_variants) {
110
+ for (const pv of ticket.product_variants) {
111
+ input.items.push({
112
+ title: pv.title || "Replacement Part",
113
+ description: pv.sku ? `SKU: ${pv.sku}` : "",
114
+ quantity: 1,
115
+ unit_price: 0,
116
+ });
117
+ }
118
+ }
119
+ if (input.items.length === 0) {
120
+ input.items.push({
121
+ title: `Diagnostic / Repair Inspection (#${ticket.ticket_number})`,
122
+ description: ticket.issue_description || "Standard device repair service",
123
+ quantity: 1,
124
+ unit_price: Number(ticket.total_estimate || 0),
125
+ total: Number(ticket.total_estimate || 0),
126
+ });
127
+ }
128
+ }
129
+ input.custom_fields = {
130
+ "Device Model": ticket.device?.model_name || "N/A",
131
+ "Brand": ticket.device?.brand || "N/A",
132
+ "Serial / IMEI": ticket.device?.serial_number || ticket.device?.imei || "N/A",
133
+ "Condition": ticket.device?.condition || "Not specified",
134
+ "Accessories": ticket.accessories || "None",
135
+ "Technician": ticket.technician_name || "Unassigned",
136
+ "Reported Issue": ticket.issue_description || "Standard Repair",
137
+ ...(input.custom_fields || {}),
138
+ };
139
+ if (input.type === "job_card" && ticket.approval_token) {
140
+ input.payment_link = `${storeUrl}/repairs/track?token=${ticket.approval_token}`;
141
+ }
142
+ }
143
+ }
144
+ }
145
+ catch (err) { }
146
+ }
147
+ if (!input.customer) {
148
+ input.customer = { name: "Customer" };
149
+ }
150
+ if (!input.items) {
151
+ input.items = [];
152
+ }
153
+ // Generate unique display ID if not given
154
+ const prefix = input.type === "job_card" ? "JOB-" : (settings.zoho_invoice_prefix || "DOC-");
155
+ const displayId = input.display_id || `${prefix}${Math.floor(100000 + Math.random() * 900000)}`;
156
+ // Prepare short payment link if payment link is present
157
+ let shortPaymentLink = undefined;
158
+ if (input.payment_link) {
159
+ shortPaymentLink = await this.getOrGenerateShortUrl(input.payment_link, storeUrl);
160
+ }
161
+ let source = "pdfkit";
162
+ let zohoDocumentId = null;
163
+ let pdfBuffer = null;
164
+ // Check if Zoho Books should be used
165
+ const canUseZoho = input.force_source !== "pdfkit" &&
166
+ settings.zoho_books_enabled &&
167
+ settings.zoho_client_id &&
168
+ settings.zoho_client_secret &&
169
+ settings.zoho_refresh_token &&
170
+ settings.zoho_organization_id &&
171
+ (input.type === "invoice" || input.type === "estimate" || input.type === "receipt");
172
+ if (canUseZoho) {
173
+ try {
174
+ const logger = container?.resolve("logger");
175
+ const zoho = new zoho_books_1.ZohoBooksService({
176
+ client_id: settings.zoho_client_id,
177
+ client_secret: settings.zoho_client_secret,
178
+ refresh_token: settings.zoho_refresh_token,
179
+ organization_id: settings.zoho_organization_id,
180
+ domain: settings.zoho_domain || "com",
181
+ }, logger);
182
+ // 1. Sync Contact in Zoho
183
+ const contactId = await zoho.syncContact({
184
+ first_name: input.customer.name,
185
+ email: input.customer.email,
186
+ phone: input.customer.phone,
187
+ });
188
+ // 2. Prepare Zoho Notes & Terms (including payment link if unpaid)
189
+ let zohoNotes = input.notes || settings.zoho_invoice_notes || "Thank you for your business.";
190
+ if (shortPaymentLink) {
191
+ zohoNotes += `\n\nPay Online: ${shortPaymentLink}`;
192
+ }
193
+ const zohoTerms = settings.zoho_invoice_terms || "";
194
+ const zohoLineItems = (input.items || []).map((it) => ({
195
+ name: it.title,
196
+ description: it.description || "",
197
+ rate: Number(it.unit_price || 0).toFixed(2),
198
+ quantity: it.quantity || 1,
199
+ }));
200
+ const customFields = [];
201
+ if (shortPaymentLink || input.payment_link) {
202
+ customFields.push({
203
+ label: settings.zoho_custom_field_payment_link || "Payment Link",
204
+ value: (shortPaymentLink || input.payment_link),
205
+ });
206
+ }
207
+ if (input.type === "invoice") {
208
+ const res = await zoho.createInvoice(contactId, {
209
+ reference_number: displayId,
210
+ line_items: zohoLineItems,
211
+ notes: zohoNotes,
212
+ terms: zohoTerms,
213
+ payment_terms: settings.zoho_payment_terms_days || 0,
214
+ is_inclusive_tax: settings.zoho_tax_inclusive ?? false,
215
+ custom_fields: customFields,
216
+ });
217
+ zohoDocumentId = res.invoice_id;
218
+ source = "zoho";
219
+ const rawBuffer = await zoho.getDocumentPdf(res.invoice_id, "invoice");
220
+ const qrUrlToEmbed = settings.zoho_include_payment_qr !== false ? (shortPaymentLink || input.payment_link) : undefined;
221
+ pdfBuffer = await (0, pdf_post_processor_1.postProcessPdf)(Buffer.from(rawBuffer), {
222
+ qrUrl: qrUrlToEmbed,
223
+ obscureZohoFooter: true,
224
+ });
225
+ }
226
+ else if (input.type === "estimate") {
227
+ const res = await zoho.createEstimate(contactId, {
228
+ reference_number: displayId,
229
+ line_items: zohoLineItems,
230
+ notes: zohoNotes,
231
+ terms: zohoTerms,
232
+ is_inclusive_tax: settings.zoho_tax_inclusive ?? false,
233
+ });
234
+ zohoDocumentId = res.estimate_id;
235
+ source = "zoho";
236
+ const rawBuffer = await zoho.getDocumentPdf(res.estimate_id, "estimate");
237
+ pdfBuffer = await (0, pdf_post_processor_1.postProcessPdf)(Buffer.from(rawBuffer), {
238
+ qrUrl: shortPaymentLink || input.payment_link,
239
+ obscureZohoFooter: true,
240
+ });
241
+ }
242
+ }
243
+ catch (zohoErr) {
244
+ container?.resolve("logger")?.warn(`[Documents-Module] Zoho Books generation failed (${zohoErr.message}). Falling back to PDFKit.`);
245
+ source = "pdfkit";
246
+ zohoDocumentId = null;
247
+ pdfBuffer = null;
248
+ }
249
+ }
250
+ // -------------------------------------------------------------
251
+ // PDFKit Fallback / Primary Generation
252
+ // -------------------------------------------------------------
253
+ if (!pdfBuffer) {
254
+ source = "pdfkit";
255
+ let templateName = settings.invoice_template || "modern";
256
+ if (input.type === "packing_slip")
257
+ templateName = settings.packing_slip_template || "modern";
258
+ else if (input.type === "receipt")
259
+ templateName = settings.receipt_template || "modern";
260
+ else if (input.type === "estimate")
261
+ templateName = settings.estimate_template || "modern";
262
+ else if (input.type === "job_card")
263
+ templateName = settings.job_card_template || "modern";
264
+ else if (input.type === "custom")
265
+ templateName = settings.custom_doc_template || "modern";
266
+ const docData = {
267
+ display_id: displayId,
268
+ title: input.title,
269
+ type: input.type,
270
+ date: new Date().toISOString().split("T")[0],
271
+ customer: {
272
+ name: input.customer.name,
273
+ email: input.customer.email,
274
+ phone: input.customer.phone,
275
+ address: input.customer.address,
276
+ },
277
+ company: {
278
+ name: settings.company_name || "Store",
279
+ logo_url: settings.pdf_logo_url,
280
+ address: settings.pdf_address,
281
+ phone: settings.pdf_phone,
282
+ email: settings.pdf_email,
283
+ website: settings.pdf_website,
284
+ payment_details: settings.pdf_payment_details,
285
+ terms: settings.pdf_terms,
286
+ },
287
+ items: input.items,
288
+ subtotal: input.subtotal,
289
+ tax_total: input.tax_total,
290
+ shipping_total: input.shipping_total,
291
+ discount_total: input.discount_total,
292
+ total: input.total != null ? input.total : 0,
293
+ currency_code: input.currency_code || "usd",
294
+ payment_status: input.payment_status || "unpaid",
295
+ payment_link: shortPaymentLink || input.payment_link,
296
+ qr_url: shortPaymentLink || input.payment_link,
297
+ notes: input.notes,
298
+ body_text: input.body_text,
299
+ custom_fields: input.custom_fields,
300
+ };
301
+ const rawBuffer = await pdfkit_generator_1.PDFKitGenerator.generate(docData, templateName);
302
+ pdfBuffer = await (0, pdf_post_processor_1.postProcessPdf)(rawBuffer, {
303
+ qrUrl: shortPaymentLink || input.payment_link,
304
+ });
305
+ }
306
+ // Save Record to Database
307
+ const initialPdfUrl = `${storeUrl}/api/admin/documents/temp/document`;
308
+ const record = await this.createDocumentRecords({
309
+ display_id: displayId,
310
+ title: input.title || (input.type === "invoice" ? "Tax Invoice" :
311
+ input.type === "receipt" ? "Payment Receipt" :
312
+ input.type === "packing_slip" ? "Packing Slip" :
313
+ input.type === "estimate" ? "Quotation" : "Document"),
314
+ type: input.type,
315
+ source: source,
316
+ status: input.payment_status === "paid" ? "paid" : "sent",
317
+ customer_name: input.customer.name,
318
+ customer_email: input.customer.email,
319
+ customer_phone: input.customer.phone,
320
+ order_id: input.order_id,
321
+ repair_ticket_id: input.repair_ticket_id,
322
+ zoho_document_id: zohoDocumentId,
323
+ total_amount: input.total,
324
+ currency_code: input.currency_code,
325
+ payment_status: input.payment_status || "unpaid",
326
+ payment_link: input.payment_link,
327
+ short_payment_link: shortPaymentLink,
328
+ pdf_url: `${storeUrl}/api/admin/documents/${displayId}/document`,
329
+ metadata: {
330
+ items: input.items,
331
+ notes: input.notes,
332
+ body_text: input.body_text,
333
+ custom_fields: input.custom_fields,
334
+ },
335
+ });
336
+ // Update with real short URL for document
337
+ const realPdfUrl = `${storeUrl}/api/admin/documents/${record.id}/document`;
338
+ const shortPdfLink = await this.getOrGenerateShortUrl(realPdfUrl, storeUrl);
339
+ await this.updateDocumentRecords({
340
+ id: record.id,
341
+ pdf_url: realPdfUrl,
342
+ short_pdf_link: shortPdfLink,
343
+ });
344
+ record.pdf_url = realPdfUrl;
345
+ record.short_pdf_link = shortPdfLink;
346
+ // Multi-channel notification auto-dispatch
347
+ if (input.auto_send && container) {
348
+ await notification_sender_1.NotificationSender.send({
349
+ container,
350
+ document: {
351
+ id: record.id,
352
+ display_id: record.display_id,
353
+ title: record.title,
354
+ type: record.type,
355
+ customer_name: record.customer_name,
356
+ customer_email: record.customer_email,
357
+ customer_phone: record.customer_phone,
358
+ total_amount: record.total_amount,
359
+ currency_code: record.currency_code,
360
+ payment_status: record.payment_status,
361
+ payment_link: record.payment_link,
362
+ short_payment_link: record.short_payment_link,
363
+ pdf_url: record.pdf_url,
364
+ short_pdf_link: record.short_pdf_link,
365
+ custom_message: input.custom_email_message,
366
+ subject: input.email_subject,
367
+ },
368
+ channels: input.notification_channels,
369
+ settings,
370
+ });
371
+ }
372
+ return { record, pdfBuffer };
373
+ }
374
+ /**
375
+ * Fetches or regenerates the PDF buffer for an existing DocumentRecord
376
+ */
377
+ async getPdfForRecord(recordId, container) {
378
+ const record = await this.retrieveDocumentRecord(recordId);
379
+ const settings = await this.getSettings();
380
+ // If source is Zoho and zoho_document_id exists, fetch from Zoho API
381
+ if (record.source === "zoho" &&
382
+ record.zoho_document_id &&
383
+ settings.zoho_books_enabled &&
384
+ settings.zoho_client_id) {
385
+ try {
386
+ const logger = container?.resolve("logger");
387
+ const zoho = new zoho_books_1.ZohoBooksService({
388
+ client_id: settings.zoho_client_id,
389
+ client_secret: settings.zoho_client_secret,
390
+ refresh_token: settings.zoho_refresh_token,
391
+ organization_id: settings.zoho_organization_id,
392
+ domain: settings.zoho_domain || "com",
393
+ }, logger);
394
+ const docType = record.type === "estimate" ? "estimate" : "invoice";
395
+ const rawBuf = await zoho.getDocumentPdf(record.zoho_document_id, docType);
396
+ return await (0, pdf_post_processor_1.postProcessPdf)(Buffer.from(rawBuf), {
397
+ qrUrl: record.short_payment_link || record.payment_link,
398
+ obscureZohoFooter: true,
399
+ });
400
+ }
401
+ catch (err) {
402
+ container?.resolve("logger")?.warn(`[Documents-Module] Failed to fetch PDF from Zoho (${err.message}). Regenerating via PDFKit.`);
403
+ }
404
+ }
405
+ // PDFKit Fallback Generation
406
+ let templateName = settings.invoice_template || "modern";
407
+ if (record.type === "packing_slip")
408
+ templateName = settings.packing_slip_template || "modern";
409
+ else if (record.type === "receipt")
410
+ templateName = settings.receipt_template || "modern";
411
+ else if (record.type === "estimate")
412
+ templateName = settings.estimate_template || "modern";
413
+ else if (record.type === "job_card")
414
+ templateName = settings.job_card_template || "modern";
415
+ else if (record.type === "custom")
416
+ templateName = settings.custom_doc_template || "modern";
417
+ const meta = (record.metadata || {});
418
+ const docData = {
419
+ display_id: record.display_id,
420
+ title: record.title,
421
+ type: record.type,
422
+ date: new Date().toISOString().split("T")[0],
423
+ customer: {
424
+ name: record.customer_name || "Valued Customer",
425
+ email: record.customer_email || undefined,
426
+ phone: record.customer_phone || undefined,
427
+ },
428
+ company: {
429
+ name: settings.company_name || "Store",
430
+ logo_url: settings.pdf_logo_url,
431
+ address: settings.pdf_address,
432
+ phone: settings.pdf_phone,
433
+ email: settings.pdf_email,
434
+ website: settings.pdf_website,
435
+ payment_details: settings.pdf_payment_details,
436
+ terms: settings.pdf_terms,
437
+ },
438
+ items: meta.items || [],
439
+ total: record.total_amount || 0,
440
+ currency_code: record.currency_code || "usd",
441
+ payment_status: record.payment_status,
442
+ payment_link: record.short_payment_link || record.payment_link,
443
+ qr_url: record.short_payment_link || record.payment_link,
444
+ notes: meta.notes,
445
+ body_text: meta.body_text,
446
+ custom_fields: meta.custom_fields,
447
+ };
448
+ const rawBuffer = await pdfkit_generator_1.PDFKitGenerator.generate(docData, templateName);
449
+ return await (0, pdf_post_processor_1.postProcessPdf)(rawBuffer, {
450
+ qrUrl: record.short_payment_link || record.payment_link,
451
+ });
452
+ }
453
+ }
454
+ exports.DocumentModuleService = DocumentModuleService;
455
+ exports.default = DocumentModuleService;
456
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2RvY3VtZW50cy9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUFxRjtBQUNyRixrRUFBOEQ7QUFDOUQsOERBQTBEO0FBQzFELDBEQUFzRDtBQUN0RCwwREFBNkQ7QUFDN0Qsc0VBQTBGO0FBQzFGLDBFQUFtRTtBQUNuRSw0RUFBd0U7QUFpQ3hFLE1BQWEscUJBQXNCLFNBQVEsSUFBQSxxQkFBYSxFQUFDO0lBQ3ZELGdCQUFnQixFQUFoQixvQ0FBZ0I7SUFDaEIsY0FBYyxFQUFkLGdDQUFjO0lBQ2QsWUFBWSxFQUFaLDRCQUFZO0NBQ2IsQ0FBQztJQUNBOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFdBQVc7UUFDZixNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDO1lBQ3ZDLFlBQVksRUFBRSxPQUFPO1lBQ3JCLDJCQUEyQixFQUFFLElBQUk7WUFDakMseUJBQXlCLEVBQUUsSUFBSTtZQUMvQiw4QkFBOEIsRUFBRSxJQUFJO1lBQ3BDLGdCQUFnQixFQUFFLFFBQVE7WUFDMUIscUJBQXFCLEVBQUUsUUFBUTtZQUMvQixnQkFBZ0IsRUFBRSxRQUFRO1lBQzFCLGlCQUFpQixFQUFFLFFBQVE7WUFDM0IsaUJBQWlCLEVBQUUsUUFBUTtZQUMzQixtQkFBbUIsRUFBRSxRQUFRO1lBQzdCLHNCQUFzQixFQUFFLElBQUk7WUFDNUIsbUJBQW1CLEVBQUUsSUFBSTtZQUN6QixpQkFBaUIsRUFBRSxJQUFJO1lBQ3ZCLHNCQUFzQixFQUFFLElBQUk7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FB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