brainloper-ui 14.1.8 → 14.1.10

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 (103) hide show
  1. package/esm2020/brainloper-ui.mjs +4 -4
  2. package/esm2020/public_api.mjs +57 -56
  3. package/esm2020/src/app/modules/brainloper-ui/brainloper-ui.module.mjs +310 -310
  4. package/esm2020/src/app/modules/brainloper-ui/components/bread-crumb/bread-crumb.component.mjs +29 -29
  5. package/esm2020/src/app/modules/brainloper-ui/components/buttons/button-icon/button-icon.component.mjs +23 -23
  6. package/esm2020/src/app/modules/brainloper-ui/components/buttons/button-label/button-label.component.mjs +83 -83
  7. package/esm2020/src/app/modules/brainloper-ui/components/carousel/carousel.component.mjs +40 -40
  8. package/esm2020/src/app/modules/brainloper-ui/components/combos/combos.component.mjs +176 -176
  9. package/esm2020/src/app/modules/brainloper-ui/components/data-table/data-table.component.mjs +728 -728
  10. package/esm2020/src/app/modules/brainloper-ui/components/data-table/table-modal/table-modal.component.mjs +118 -118
  11. package/esm2020/src/app/modules/brainloper-ui/components/file-input/file-input.component.mjs +186 -186
  12. package/esm2020/src/app/modules/brainloper-ui/components/file-input/imagenes/doc.mjs +1 -1
  13. package/esm2020/src/app/modules/brainloper-ui/components/file-input/imagenes/fondoTransparente.mjs +1 -1
  14. package/esm2020/src/app/modules/brainloper-ui/components/file-input/imagenes/pdf.mjs +1 -1
  15. package/esm2020/src/app/modules/brainloper-ui/components/filters/filters.component.mjs +222 -222
  16. package/esm2020/src/app/modules/brainloper-ui/components/report/template-fuel/template-fuel.component.mjs +115 -115
  17. package/esm2020/src/app/modules/brainloper-ui/components/report/template-ot/template-ot.component.mjs +145 -145
  18. package/esm2020/src/app/modules/brainloper-ui/components/select-filter/select-filter.component.mjs +108 -108
  19. package/esm2020/src/app/modules/directives/carousel-item.directive.mjs +18 -18
  20. package/esm2020/src/app/modules/interfaces/buttons/button-icon.mjs +2 -2
  21. package/esm2020/src/app/modules/interfaces/buttons/button-lavel-edit.mjs +2 -2
  22. package/esm2020/src/app/modules/interfaces/combos/combos-configuration.mjs +2 -2
  23. package/esm2020/src/app/modules/interfaces/data-table/params.mjs +2 -2
  24. package/esm2020/src/app/modules/interfaces/data-table/rules.mjs +2 -2
  25. package/esm2020/src/app/modules/interfaces/data-table/table-columns.mjs +2 -2
  26. package/esm2020/src/app/modules/interfaces/data-table/table-configuration.mjs +2 -2
  27. package/esm2020/src/app/modules/interfaces/enum/enumActions.mjs +8 -8
  28. package/esm2020/src/app/modules/interfaces/enum/enumRules.mjs +8 -8
  29. package/esm2020/src/app/modules/interfaces/enum/httpResponseType.mjs +8 -0
  30. package/esm2020/src/app/modules/interfaces/file-forms-service/file-forms-params.mjs +2 -2
  31. package/esm2020/src/app/modules/interfaces/file-forms-service/file-input-params.mjs +2 -2
  32. package/esm2020/src/app/modules/interfaces/filters/header-filters.mjs +2 -2
  33. package/esm2020/src/app/modules/interfaces/menu-break-crumb/menu-break-crumb.mjs +8 -8
  34. package/esm2020/src/app/modules/interfaces/report/template-pdf-base.mjs +2 -2
  35. package/esm2020/src/app/modules/interfaces/report/template-pdf-ot.mjs +2 -2
  36. package/esm2020/src/app/modules/interfaces/report/template-pfd-fo.mjs +2 -2
  37. package/esm2020/src/app/modules/services/crypto.service.mjs +37 -37
  38. package/esm2020/src/app/modules/services/export-data.service.mjs +166 -166
  39. package/esm2020/src/app/modules/services/file-forms.service.mjs +24 -24
  40. package/esm2020/src/app/modules/services/fuel-order-pdf.service.mjs +528 -528
  41. package/esm2020/src/app/modules/services/functions.service.mjs +54 -54
  42. package/esm2020/src/app/modules/services/generate-pdf.service.mjs +109 -109
  43. package/esm2020/src/app/modules/services/http.service.mjs +126 -97
  44. package/esm2020/src/app/modules/services/loading/loading.component.mjs +28 -28
  45. package/esm2020/src/app/modules/services/local-storage.service.mjs +115 -115
  46. package/esm2020/src/app/modules/services/message.service.mjs +200 -200
  47. package/esm2020/src/app/modules/services/screen-size-util.mjs +6 -6
  48. package/esm2020/src/app/modules/services/session.service.mjs +42 -42
  49. package/esm2020/src/app/modules/services/work-order-pdf.service.mjs +384 -384
  50. package/fesm2015/brainloper-ui.mjs +3885 -3849
  51. package/fesm2015/brainloper-ui.mjs.map +1 -1
  52. package/fesm2020/brainloper-ui.mjs +3855 -3819
  53. package/fesm2020/brainloper-ui.mjs.map +1 -1
  54. package/index.d.ts +5 -5
  55. package/package.json +1 -1
  56. package/public_api.d.ts +56 -55
  57. package/src/app/modules/brainloper-ui/brainloper-ui.module.d.ts +62 -62
  58. package/src/app/modules/brainloper-ui/components/bread-crumb/bread-crumb.component.d.ts +13 -13
  59. package/src/app/modules/brainloper-ui/components/buttons/button-icon/button-icon.component.d.ts +10 -10
  60. package/src/app/modules/brainloper-ui/components/buttons/button-label/button-label.component.d.ts +24 -24
  61. package/src/app/modules/brainloper-ui/components/carousel/carousel.component.d.ts +16 -16
  62. package/src/app/modules/brainloper-ui/components/combos/combos.component.d.ts +46 -46
  63. package/src/app/modules/brainloper-ui/components/data-table/data-table.component.d.ts +125 -125
  64. package/src/app/modules/brainloper-ui/components/data-table/table-modal/table-modal.component.d.ts +21 -21
  65. package/src/app/modules/brainloper-ui/components/file-input/file-input.component.d.ts +42 -42
  66. package/src/app/modules/brainloper-ui/components/file-input/imagenes/doc.d.ts +2 -2
  67. package/src/app/modules/brainloper-ui/components/file-input/imagenes/fondoTransparente.d.ts +2 -2
  68. package/src/app/modules/brainloper-ui/components/file-input/imagenes/pdf.d.ts +2 -2
  69. package/src/app/modules/brainloper-ui/components/filters/filters.component.d.ts +30 -30
  70. package/src/app/modules/brainloper-ui/components/report/template-fuel/template-fuel.component.d.ts +41 -41
  71. package/src/app/modules/brainloper-ui/components/report/template-ot/template-ot.component.d.ts +40 -40
  72. package/src/app/modules/brainloper-ui/components/select-filter/select-filter.component.d.ts +26 -26
  73. package/src/app/modules/directives/carousel-item.directive.d.ts +9 -9
  74. package/src/app/modules/interfaces/buttons/button-icon.d.ts +9 -9
  75. package/src/app/modules/interfaces/buttons/button-lavel-edit.d.ts +6 -6
  76. package/src/app/modules/interfaces/combos/combos-configuration.d.ts +13 -13
  77. package/src/app/modules/interfaces/data-table/params.d.ts +7 -7
  78. package/src/app/modules/interfaces/data-table/rules.d.ts +8 -8
  79. package/src/app/modules/interfaces/data-table/table-columns.d.ts +25 -25
  80. package/src/app/modules/interfaces/data-table/table-configuration.d.ts +26 -26
  81. package/src/app/modules/interfaces/enum/enumActions.d.ts +6 -6
  82. package/src/app/modules/interfaces/enum/enumRules.d.ts +6 -6
  83. package/src/app/modules/interfaces/enum/httpResponseType.d.ts +6 -0
  84. package/src/app/modules/interfaces/file-forms-service/file-forms-params.d.ts +4 -4
  85. package/src/app/modules/interfaces/file-forms-service/file-input-params.d.ts +13 -13
  86. package/src/app/modules/interfaces/filters/header-filters.d.ts +13 -13
  87. package/src/app/modules/interfaces/menu-break-crumb/menu-break-crumb.d.ts +10 -10
  88. package/src/app/modules/interfaces/report/template-pdf-base.d.ts +17 -17
  89. package/src/app/modules/interfaces/report/template-pdf-ot.d.ts +6 -6
  90. package/src/app/modules/interfaces/report/template-pfd-fo.d.ts +7 -7
  91. package/src/app/modules/services/crypto.service.d.ts +10 -10
  92. package/src/app/modules/services/export-data.service.d.ts +18 -18
  93. package/src/app/modules/services/file-forms.service.d.ts +7 -7
  94. package/src/app/modules/services/fuel-order-pdf.service.d.ts +59 -59
  95. package/src/app/modules/services/functions.service.d.ts +13 -13
  96. package/src/app/modules/services/generate-pdf.service.d.ts +21 -21
  97. package/src/app/modules/services/http.service.d.ts +23 -22
  98. package/src/app/modules/services/loading/loading.component.d.ts +15 -15
  99. package/src/app/modules/services/local-storage.service.d.ts +49 -49
  100. package/src/app/modules/services/message.service.d.ts +23 -23
  101. package/src/app/modules/services/screen-size-util.d.ts +3 -3
  102. package/src/app/modules/services/session.service.d.ts +14 -14
  103. package/src/app/modules/services/work-order-pdf.service.d.ts +60 -60
@@ -1,384 +1,384 @@
1
- import { Injectable } from '@angular/core';
2
- import { jsPDF } from 'jspdf';
3
- import 'jspdf-autotable';
4
- import * as i0 from "@angular/core";
5
- export class WorkOrderPdfService {
6
- constructor() { }
7
- /**
8
- * Genera PDF de orden de trabajo con diseño profesional
9
- * Dimensiones fijas, independiente del DOM
10
- */
11
- generateWorkOrderPDF(data, options) {
12
- return new Promise((resolve, reject) => {
13
- try {
14
- const opts = {
15
- format: 'letter',
16
- download: true,
17
- filename: 'orden_trabajo.pdf',
18
- ...options
19
- };
20
- const doc = new jsPDF('p', 'pt', opts.format);
21
- const pageWidth = doc.internal.pageSize.getWidth();
22
- const pageHeight = doc.internal.pageSize.getHeight();
23
- const margin = 40;
24
- let currentY = margin;
25
- // Colores corporativos
26
- const primaryColor = [52, 152, 219]; // Azul para órdenes de trabajo
27
- const secondaryColor = [44, 62, 80]; // Gris oscuro
28
- const accentColor = [155, 89, 182]; // Morado
29
- // === ENCABEZADO PRINCIPAL ===
30
- this.addHeader(doc, data, margin, currentY, pageWidth, primaryColor);
31
- currentY = 140;
32
- // === TÍTULO DEL DOCUMENTO ===
33
- currentY = this.addDocumentTitle(doc, data, currentY, pageWidth, accentColor);
34
- currentY += 25;
35
- // === INFORMACIÓN PRINCIPAL ===
36
- currentY = this.addMainInfo(doc, data, currentY, margin, pageWidth);
37
- currentY += 20;
38
- // === DATOS DEL PROVEEDOR ===
39
- currentY = this.addProviderInfo(doc, data, currentY, margin, pageWidth, secondaryColor);
40
- currentY += 20;
41
- // === DETALLES DEL SERVICIO ===
42
- currentY = this.addServiceDetails(doc, data, currentY, margin, pageWidth, secondaryColor);
43
- currentY += 20;
44
- // === AUTORIZACIÓN ===
45
- currentY = this.addAuthorization(doc, data, currentY, margin, pageWidth);
46
- currentY += 30;
47
- // === PIE DE PÁGINA ===
48
- this.addFooter(doc, data, pageHeight - 80, pageWidth, primaryColor);
49
- // === GENERAR/DESCARGAR ===
50
- if (opts.download) {
51
- doc.output('dataurlnewwindow', { filename: opts.filename });
52
- }
53
- resolve(doc);
54
- }
55
- catch (error) {
56
- reject(error);
57
- }
58
- });
59
- }
60
- addHeader(doc, data, margin, y, pageWidth, color) {
61
- // Fondo del encabezado
62
- doc.setFillColor(color[0], color[1], color[2]);
63
- doc.rect(margin, y, pageWidth - (margin * 2), 80, 'F');
64
- // Texto del encabezado en blanco
65
- doc.setTextColor(255, 255, 255);
66
- doc.setFont('helvetica', 'bold');
67
- doc.setFontSize(18);
68
- const companyName = (data.name || '').toUpperCase();
69
- const nameWidth = doc.getTextWidth(companyName);
70
- doc.text(companyName, (pageWidth - nameWidth) / 2, y + 25);
71
- doc.setFontSize(12);
72
- const nitText = `NIT: ${data.nit || ''}`;
73
- const nitWidth = doc.getTextWidth(nitText);
74
- doc.text(nitText, (pageWidth - nitWidth) / 2, y + 45);
75
- doc.setFontSize(10);
76
- const addressText = `${data.address || ''} - TEL: ${data.telephone || ''}`;
77
- const addressWidth = doc.getTextWidth(addressText);
78
- doc.text(addressText, (pageWidth - addressWidth) / 2, y + 65);
79
- // Resetear color de texto
80
- doc.setTextColor(0, 0, 0);
81
- }
82
- addDocumentTitle(doc, data, y, pageWidth, color) {
83
- doc.setTextColor(color[0], color[1], color[2]);
84
- doc.setFont('helvetica', 'bold');
85
- doc.setFontSize(20);
86
- const title = 'ORDEN DE TRABAJO';
87
- const titleWidth = doc.getTextWidth(title);
88
- doc.text(title, (pageWidth - titleWidth) / 2, y);
89
- doc.setFontSize(16);
90
- const numberText = `N° ${data.consecutive || ''}`;
91
- const numberWidth = doc.getTextWidth(numberText);
92
- doc.text(numberText, (pageWidth - numberWidth) / 2, y + 25);
93
- doc.setTextColor(0, 0, 0);
94
- return y + 40;
95
- }
96
- addMainInfo(doc, data, y, margin, pageWidth) {
97
- const tableData = [
98
- [
99
- { content: 'Área:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
100
- { content: data.area || '', styles: {} },
101
- { content: 'Código:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
102
- { content: data.code || '', styles: {} },
103
- { content: 'Fecha:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
104
- { content: data.date || '', styles: {} }
105
- ],
106
- [
107
- { content: 'Operario:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
108
- { content: data.responsible || '', styles: {} },
109
- { content: 'Odómetro:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
110
- { content: data.odometer || '', styles: {} },
111
- { content: 'Ref. Factura:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
112
- { content: data.invoiceReference || '-', styles: {} }
113
- ]
114
- ];
115
- doc.autoTable({
116
- startY: y,
117
- body: tableData,
118
- theme: 'grid',
119
- styles: {
120
- fontSize: 11,
121
- cellPadding: 8,
122
- lineColor: [200, 200, 200],
123
- lineWidth: 0.5
124
- },
125
- columnStyles: {
126
- 0: { cellWidth: 70 },
127
- 1: { cellWidth: 100 },
128
- 2: { cellWidth: 70 },
129
- 3: { cellWidth: 80 },
130
- 4: { cellWidth: 70 },
131
- 5: { cellWidth: 80 }
132
- },
133
- margin: { left: margin, right: margin }
134
- });
135
- return doc.lastAutoTable.finalY;
136
- }
137
- addProviderInfo(doc, data, y, margin, pageWidth, color) {
138
- // Título de sección
139
- doc.setTextColor(color[0], color[1], color[2]);
140
- doc.setFont('helvetica', 'bold');
141
- doc.setFontSize(14);
142
- const title = 'DATOS DEL PROVEEDOR';
143
- const titleWidth = doc.getTextWidth(title);
144
- doc.text(title, (pageWidth - titleWidth) / 2, y);
145
- doc.setTextColor(0, 0, 0);
146
- const tableData = [
147
- [
148
- { content: 'Nombre:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
149
- { content: data.nameProvider || '', styles: {} },
150
- { content: 'Dirección:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
151
- { content: data.addressProvider || '', styles: {} }
152
- ]
153
- ];
154
- doc.autoTable({
155
- startY: y + 20,
156
- body: tableData,
157
- theme: 'grid',
158
- styles: {
159
- fontSize: 11,
160
- cellPadding: 8,
161
- lineColor: [200, 200, 200],
162
- lineWidth: 0.5
163
- },
164
- columnStyles: {
165
- 0: { cellWidth: 80 },
166
- 1: { cellWidth: 160 },
167
- 2: { cellWidth: 80 },
168
- 3: { cellWidth: 150 }
169
- },
170
- margin: { left: margin, right: margin }
171
- });
172
- return doc.lastAutoTable.finalY;
173
- }
174
- addServiceDetails(doc, data, y, margin, pageWidth, color) {
175
- // Título de sección
176
- doc.setTextColor(color[0], color[1], color[2]);
177
- doc.setFont('helvetica', 'bold');
178
- doc.setFontSize(14);
179
- const title = 'DETALLES DEL SERVICIO';
180
- const titleWidth = doc.getTextWidth(title);
181
- doc.text(title, (pageWidth - titleWidth) / 2, y);
182
- doc.setTextColor(0, 0, 0);
183
- // Preparar texto para calcular altura necesaria
184
- const boxY = y + 20;
185
- const boxWidth = pageWidth - (margin * 2);
186
- const textMargin = margin + 15;
187
- const maxWidth = boxWidth - 30;
188
- const lineHeight = 15;
189
- const minBoxHeight = 60; // Altura mínima del contenedor
190
- const padding = 40; // Padding superior e inferior (20 arriba + 20 abajo)
191
- // Calcular líneas de texto necesarias
192
- doc.setFont('helvetica', 'normal');
193
- doc.setFontSize(11);
194
- let totalLines = 0;
195
- let currentTextY = 20; // Posición relativa dentro del box
196
- if (data.description && data.description.trim()) {
197
- const descLines = doc.splitTextToSize(data.description.trim(), maxWidth);
198
- totalLines += descLines.length;
199
- }
200
- // Calcular altura necesaria basada en el contenido
201
- const contentHeight = Math.max(totalLines * lineHeight, 30); // Mínimo 30pt para contenido
202
- const boxHeight = Math.max(minBoxHeight, contentHeight + padding);
203
- // Verificar si necesitamos una nueva página
204
- const pageHeight = doc.internal.pageSize.getHeight();
205
- const remainingSpace = pageHeight - boxY - 100; // Dejar espacio para footer
206
- let finalBoxY = boxY;
207
- if (boxHeight > remainingSpace) {
208
- // Añadir nueva página
209
- doc.addPage();
210
- finalBoxY = margin + 40; // Posición en nueva página
211
- }
212
- // Dibujar contenedor con altura dinámica
213
- // Fondo gris claro
214
- doc.setFillColor(250, 250, 250);
215
- doc.rect(margin, finalBoxY, boxWidth, boxHeight, 'F');
216
- // Borde
217
- doc.setDrawColor(200, 200, 200);
218
- doc.rect(margin, finalBoxY, boxWidth, boxHeight, 'S');
219
- // Añadir contenido de texto
220
- let textY = finalBoxY + 20;
221
- if (data.description && data.description.trim()) {
222
- const descLines = doc.splitTextToSize(data.description.trim(), maxWidth);
223
- // Si hay muchas líneas, verificar que quepan en la página actual
224
- const requiredHeight = descLines.length * lineHeight + 40;
225
- if (textY + requiredHeight > pageHeight - 60) {
226
- // El contenido es muy largo, dividir si es necesario
227
- const maxLinesPerPage = Math.floor((pageHeight - textY - 60) / lineHeight);
228
- if (descLines.length > maxLinesPerPage && maxLinesPerPage > 0) {
229
- // Mostrar líneas que caben en la página actual
230
- const currentPageLines = descLines.slice(0, maxLinesPerPage);
231
- doc.text(currentPageLines, textMargin, textY);
232
- // Continuar en nueva página si hay más contenido
233
- if (descLines.length > maxLinesPerPage) {
234
- doc.addPage();
235
- textY = margin + 20;
236
- const remainingLines = descLines.slice(maxLinesPerPage);
237
- doc.text(remainingLines, textMargin, textY);
238
- return textY + (remainingLines.length * lineHeight) + 20;
239
- }
240
- }
241
- else {
242
- doc.text(descLines, textMargin, textY);
243
- }
244
- }
245
- else {
246
- doc.text(descLines, textMargin, textY);
247
- }
248
- textY += descLines.length * lineHeight;
249
- }
250
- // Si no hay descripción, mostrar un mensaje
251
- if (!data.description || !data.description.trim()) {
252
- doc.setFont('helvetica', 'italic');
253
- doc.setFontSize(10);
254
- doc.setTextColor(150, 150, 150);
255
- doc.text('No se han especificado detalles del servicio.', textMargin, textY);
256
- doc.setTextColor(0, 0, 0);
257
- doc.setFont('helvetica', 'normal');
258
- doc.setFontSize(11);
259
- }
260
- return finalBoxY + boxHeight;
261
- }
262
- /**
263
- * Método auxiliar para manejar texto largo que puede necesitar múltiples páginas
264
- */
265
- addLongText(doc, text, x, y, maxWidth, fontSize = 11) {
266
- if (!text || !text.trim())
267
- return y;
268
- doc.setFontSize(fontSize);
269
- const lines = doc.splitTextToSize(text.trim(), maxWidth);
270
- const lineHeight = fontSize + 3;
271
- const pageHeight = doc.internal.pageSize.getHeight();
272
- const margin = 40;
273
- let currentY = y;
274
- let lineIndex = 0;
275
- while (lineIndex < lines.length) {
276
- // Verificar si necesitamos una nueva página
277
- if (currentY + lineHeight > pageHeight - margin) {
278
- doc.addPage();
279
- currentY = margin;
280
- }
281
- // Calcular cuántas líneas caben en la página actual
282
- const remainingSpace = pageHeight - currentY - margin;
283
- const maxLinesInPage = Math.floor(remainingSpace / lineHeight);
284
- if (maxLinesInPage > 0) {
285
- const linesToShow = Math.min(maxLinesInPage, lines.length - lineIndex);
286
- const pageLines = lines.slice(lineIndex, lineIndex + linesToShow);
287
- doc.text(pageLines, x, currentY);
288
- currentY += pageLines.length * lineHeight;
289
- lineIndex += linesToShow;
290
- }
291
- else {
292
- // Si no cabe ni una línea, ir a nueva página
293
- doc.addPage();
294
- currentY = margin;
295
- }
296
- }
297
- return currentY;
298
- }
299
- addAuthorization(doc, data, y, margin, pageWidth) {
300
- const tableData = [
301
- [
302
- { content: 'AUTORIZADA POR:', styles: { fontStyle: 'bold', fontSize: 12, fillColor: [240, 240, 240] } },
303
- { content: data.approved_by || '', styles: { fontSize: 12 } }
304
- ]
305
- ];
306
- doc.autoTable({
307
- startY: y,
308
- body: tableData,
309
- theme: 'grid',
310
- styles: {
311
- cellPadding: 12,
312
- lineColor: [200, 200, 200],
313
- lineWidth: 0.5
314
- },
315
- columnStyles: {
316
- 0: { cellWidth: 150 },
317
- 1: { cellWidth: 320 }
318
- },
319
- margin: { left: margin, right: margin }
320
- });
321
- return doc.lastAutoTable.finalY;
322
- }
323
- addFooter(doc, data, y, pageWidth, color) {
324
- // Fondo del pie de página
325
- doc.setFillColor(color[0], color[1], color[2]);
326
- doc.rect(40, y, pageWidth - 80, 60, 'F');
327
- // Texto en blanco
328
- doc.setTextColor(255, 255, 255);
329
- doc.setFont('helvetica', 'bold');
330
- doc.setFontSize(12);
331
- const instruction = 'Favor adjuntar la orden a la factura o cuenta de cobro';
332
- const instWidth = doc.getTextWidth(instruction);
333
- doc.text(instruction, (pageWidth - instWidth) / 2, y + 25);
334
- doc.setFontSize(10);
335
- const emailWidth = doc.getTextWidth(data.mail || '');
336
- doc.text(data.mail || '', (pageWidth - emailWidth) / 2, y + 45);
337
- // Resetear color
338
- doc.setTextColor(0, 0, 0);
339
- }
340
- /**
341
- * Genera PDF optimizado para impresión
342
- */
343
- generateForPrint(data) {
344
- return this.generateWorkOrderPDF(data, {
345
- format: 'letter',
346
- download: false
347
- });
348
- }
349
- /**
350
- * Genera PDF y lo devuelve como Blob para envío por email
351
- */
352
- generateAsBlob(data) {
353
- return new Promise((resolve, reject) => {
354
- this.generateWorkOrderPDF(data, { download: false })
355
- .then(doc => {
356
- const pdfBlob = doc.output('blob');
357
- resolve(pdfBlob);
358
- })
359
- .catch(reject);
360
- });
361
- }
362
- /**
363
- * Genera PDF y lo devuelve como base64
364
- */
365
- generateAsBase64(data) {
366
- return new Promise((resolve, reject) => {
367
- this.generateWorkOrderPDF(data, { download: false })
368
- .then(doc => {
369
- const base64 = doc.output('datauristring');
370
- resolve(base64);
371
- })
372
- .catch(reject);
373
- });
374
- }
375
- }
376
- WorkOrderPdfService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
377
- WorkOrderPdfService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, providedIn: 'root' });
378
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, decorators: [{
379
- type: Injectable,
380
- args: [{
381
- providedIn: 'root'
382
- }]
383
- }], ctorParameters: function () { return []; } });
384
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yay1vcmRlci1wZGYuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zZXJ2aWNlcy93b3JrLW9yZGVyLXBkZi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUM5QixPQUFPLGlCQUFpQixDQUFDOztBQTBCekIsTUFBTSxPQUFPLG1CQUFtQjtJQUU5QixnQkFBZ0IsQ0FBQztJQUVqQjs7O09BR0c7SUFDSCxvQkFBb0IsQ0FBQyxJQUFtQixFQUFFLE9BSXpDO1FBQ0MsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNyQyxJQUFJO2dCQUNGLE1BQU0sSUFBSSxHQUFHO29CQUNYLE1BQU0sRUFBRSxRQUFRO29CQUNoQixRQUFRLEVBQUUsSUFBSTtvQkFDZCxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixHQUFHLE9BQU87aUJBQ1gsQ0FBQztnQkFFRixNQUFNLEdBQUcsR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25ELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNyRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQztnQkFFdEIsdUJBQXVCO2dCQUN2QixNQUFNLFlBQVksR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMs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bmJVLG1CQUFtQjtvSEFBbkIsbUJBQW1CLGNBRmxCLE1BQU07MkZBRVAsbUJBQW1CO2tCQUgvQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsganNQREYgfSBmcm9tICdqc3BkZic7XHJcbmltcG9ydCAnanNwZGYtYXV0b3RhYmxlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgV29ya09yZGVyRGF0YSB7XHJcbiAgbmFtZT86IHN0cmluZztcclxuICBuaXQ/OiBzdHJpbmc7XHJcbiAgYWRkcmVzcz86IHN0cmluZztcclxuICB0ZWxlcGhvbmU/OiBzdHJpbmc7XHJcbiAgbWFpbD86IHN0cmluZztcclxuICBpbWFnZT86IHN0cmluZztcclxuICBjb2RlPzogc3RyaW5nO1xyXG4gIGRhdGU/OiBzdHJpbmc7XHJcbiAgcmVzcG9uc2libGU/OiBzdHJpbmc7XHJcbiAgdGhpcmQ/OiBzdHJpbmc7XHJcbiAgYXBwcm92ZWRfYnk/OiBzdHJpbmc7XHJcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XHJcbiAgY29uc2VjdXRpdmU/OiBzdHJpbmc7XHJcbiAgbmFtZVByb3ZpZGVyPzogc3RyaW5nO1xyXG4gIGFkZHJlc3NQcm92aWRlcj86IHN0cmluZztcclxuICBhcmVhPzogc3RyaW5nO1xyXG4gIG9kb21ldGVyPzogc3RyaW5nO1xyXG4gIGludm9pY2VSZWZlcmVuY2U/OiBzdHJpbmc7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFdvcmtPcmRlclBkZlNlcnZpY2Uge1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmEgUERGIGRlIG9yZGVuIGRlIHRyYWJham8gY29uIGRpc2XDsW8gcHJvZmVzaW9uYWxcclxuICAgKiBEaW1lbnNpb25lcyBmaWphcywgaW5kZXBlbmRpZW50ZSBkZWwgRE9NXHJcbiAgICovXHJcbiAgZ2VuZXJhdGVXb3JrT3JkZXJQREYoZGF0YTogV29ya09yZGVyRGF0YSwgb3B0aW9ucz86IHtcclxuICAgIGZvcm1hdD86ICdsZXR0ZXInIHwgJ2E0JztcclxuICAgIGRvd25sb2FkPzogYm9vbGVhbjtcclxuICAgIGZpbGVuYW1lPzogc3RyaW5nO1xyXG4gIH0pOiBQcm9taXNlPGpzUERGPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IG9wdHMgPSB7XHJcbiAgICAgICAgICBmb3JtYXQ6ICdsZXR0ZXInLFxyXG4gICAgICAgICAgZG93bmxvYWQ6IHRydWUsXHJcbiAgICAgICAgICBmaWxlbmFtZTogJ29yZGVuX3RyYWJham8ucGRmJyxcclxuICAgICAgICAgIC4uLm9wdGlvbnNcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBjb25zdCBkb2MgPSBuZXcganNQREYoJ3AnLCAncHQnLCBvcHRzLmZvcm1hdCk7XHJcbiAgICAgICAgY29uc3QgcGFnZVdpZHRoID0gZG9jLmludGVybmFsLnBhZ2VTaXplLmdldFdpZHRoKCk7XHJcbiAgICAgICAgY29uc3QgcGFnZUhlaWdodCA9IGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5nZXRIZWlnaHQoKTtcclxuICAgICAgICBjb25zdCBtYXJnaW4gPSA0MDtcclxuICAgICAgICBsZXQgY3VycmVudFkgPSBtYXJnaW47XHJcblxyXG4gICAgICAgIC8vIENvbG9yZXMgY29ycG9yYXRpdm9zXHJcbiAgICAgICAgY29uc3QgcHJpbWFyeUNvbG9yID0gWzUyLCAxNTIsIDIxOV07IC8vIEF6dWwgcGFyYSDDs3JkZW5lcyBkZSB0cmFiYWpvXHJcbiAgICAgICAgY29uc3Qgc2Vjb25kYXJ5Q29sb3IgPSBbNDQsIDYyLCA4MF07IC8vIEdyaXMgb3NjdXJvXHJcbiAgICAgICAgY29uc3QgYWNjZW50Q29sb3IgPSBbMTU1LCA4OSwgMTgyXTsgLy8gTW9yYWRvXHJcblxyXG4gICAgICAgIC8vID09PSBFTkNBQkVaQURPIFBSSU5DSVBBTCA9PT1cclxuICAgICAgICB0aGlzLmFkZEhlYWRlcihkb2MsIGRhdGEsIG1hcmdpbiwgY3VycmVudFksIHBhZ2VXaWR0aCwgcHJpbWFyeUNvbG9yKTtcclxuICAgICAgICBjdXJyZW50WSA9IDE0MDtcclxuXHJcbiAgICAgICAgLy8gPT09IFTDjVRVTE8gREVMIERPQ1VNRU5UTyA9PT1cclxuICAgICAgICBjdXJyZW50WSA9IHRoaXMuYWRkRG9jdW1lbnRUaXRsZShkb2MsIGRhdGEsIGN1cnJlbnRZLCBwYWdlV2lkdGgsIGFjY2VudENvbG9yKTtcclxuICAgICAgICBjdXJyZW50WSArPSAyNTtcclxuXHJcbiAgICAgICAgLy8gPT09IElORk9STUFDScOTTiBQUklOQ0lQQUwgPT09XHJcbiAgICAgICAgY3VycmVudFkgPSB0aGlzLmFkZE1haW5JbmZvKGRvYywgZGF0YSwgY3VycmVudFksIG1hcmdpbiwgcGFnZVdpZHRoKTtcclxuICAgICAgICBjdXJyZW50WSArPSAyMDtcclxuXHJcbiAgICAgICAgLy8gPT09IERBVE9TIERFTCBQUk9WRUVET1IgPT09XHJcbiAgICAgICAgY3VycmVudFkgPSB0aGlzLmFkZFByb3ZpZGVySW5mbyhkb2MsIGRhdGEsIGN1cnJlbnRZLCBtYXJnaW4sIHBhZ2VXaWR0aCwgc2Vjb25kYXJ5Q29sb3IpO1xyXG4gICAgICAgIGN1cnJlbnRZICs9IDIwO1xyXG5cclxuICAgICAgICAvLyA9PT0gREVUQUxMRVMgREVMIFNFUlZJQ0lPID09PVxyXG4gICAgICAgIGN1cnJlbnRZID0gdGhpcy5hZGRTZXJ2aWNlRGV0YWlscyhkb2MsIGRhdGEsIGN1cnJlbnRZLCBtYXJnaW4sIHBhZ2VXaWR0aCwgc2Vjb25kYXJ5Q29sb3IpO1xyXG4gICAgICAgIGN1cnJlbnRZICs9IDIwO1xyXG5cclxuICAgICAgICAvLyA9PT0gQVVUT1JJWkFDScOTTiA9PT1cclxuICAgICAgICBjdXJyZW50WSA9IHRoaXMuYWRkQXV0aG9yaXphdGlvbihkb2MsIGRhdGEsIGN1cnJlbnRZLCBtYXJnaW4sIHBhZ2VXaWR0aCk7XHJcbiAgICAgICAgY3VycmVudFkgKz0gMzA7XHJcblxyXG4gICAgICAgIC8vID09PSBQSUUgREUgUMOBR0lOQSA9PT1cclxuICAgICAgICB0aGlzLmFkZEZvb3Rlcihkb2MsIGRhdGEsIHBhZ2VIZWlnaHQgLSA4MCwgcGFnZVdpZHRoLCBwcmltYXJ5Q29sb3IpO1xyXG5cclxuICAgICAgICAvLyA9PT0gR0VORVJBUi9ERVNDQVJHQVIgPT09XHJcbiAgICAgICAgaWYgKG9wdHMuZG93bmxvYWQpIHtcclxuICAgICAgICAgIGRvYy5vdXRwdXQoJ2RhdGF1cmxuZXd3aW5kb3cnLCB7IGZpbGVuYW1lOiBvcHRzLmZpbGVuYW1lIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVzb2x2ZShkb2MpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRIZWFkZXIoZG9jOiBqc1BERiwgZGF0YTogV29ya09yZGVyRGF0YSwgbWFyZ2luOiBudW1iZXIsIHk6IG51bWJlciwgcGFnZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBudW1iZXJbXSk6IHZvaWQge1xyXG4gICAgLy8gRm9uZG8gZGVsIGVuY2FiZXphZG9cclxuICAgIGRvYy5zZXRGaWxsQ29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XHJcbiAgICBkb2MucmVjdChtYXJnaW4sIHksIHBhZ2VXaWR0aCAtIChtYXJnaW4gKiAyKSwgODAsICdGJyk7XHJcblxyXG4gICAgLy8gVGV4dG8gZGVsIGVuY2FiZXphZG8gZW4gYmxhbmNvXHJcbiAgICBkb2Muc2V0VGV4dENvbG9yKDI1NSwgMjU1LCAyNTUpO1xyXG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XHJcbiAgICBkb2Muc2V0Rm9udFNpemUoMTgpO1xyXG4gICAgXHJcbiAgICBjb25zdCBjb21wYW55TmFtZSA9IChkYXRhLm5hbWUgfHwgJycpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICBjb25zdCBuYW1lV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGNvbXBhbnlOYW1lKTtcclxuICAgIGRvYy50ZXh0KGNvbXBhbnlOYW1lLCAocGFnZVdpZHRoIC0gbmFtZVdpZHRoKSAvIDIsIHkgKyAyNSk7XHJcblxyXG4gICAgZG9jLnNldEZvbnRTaXplKDEyKTtcclxuICAgIGNvbnN0IG5pdFRleHQgPSBgTklUOiAke2RhdGEubml0IHx8ICcnfWA7XHJcbiAgICBjb25zdCBuaXRXaWR0aCA9IGRvYy5nZXRUZXh0V2lkdGgobml0VGV4dCk7XHJcbiAgICBkb2MudGV4dChuaXRUZXh0LCAocGFnZVdpZHRoIC0gbml0V2lkdGgpIC8gMiwgeSArIDQ1KTtcclxuXHJcbiAgICBkb2Muc2V0Rm9udFNpemUoMTApO1xyXG4gICAgY29uc3QgYWRkcmVzc1RleHQgPSBgJHtkYXRhLmFkZHJlc3MgfHwgJyd9IC0gVEVMOiAke2RhdGEudGVsZXBob25lIHx8ICcnfWA7XHJcbiAgICBjb25zdCBhZGRyZXNzV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGFkZHJlc3NUZXh0KTtcclxuICAgIGRvYy50ZXh0KGFkZHJlc3NUZXh0LCAocGFnZVdpZHRoIC0gYWRkcmVzc1dpZHRoKSAvIDIsIHkgKyA2NSk7XHJcblxyXG4gICAgLy8gUmVzZXRlYXIgY29sb3IgZGUgdGV4dG9cclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoMCwgMCwgMCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZERvY3VtZW50VGl0bGUoZG9jOiBqc1BERiwgZGF0YTogV29ya09yZGVyRGF0YSwgeTogbnVtYmVyLCBwYWdlV2lkdGg6IG51bWJlciwgY29sb3I6IG51bWJlcltdKTogbnVtYmVyIHtcclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XHJcbiAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcclxuICAgIGRvYy5zZXRGb250U2l6ZSgyMCk7XHJcbiAgICBcclxuICAgIGNvbnN0IHRpdGxlID0gJ09SREVOIERFIFRSQUJBSk8nO1xyXG4gICAgY29uc3QgdGl0bGVXaWR0aCA9IGRvYy5nZXRUZXh0V2lkdGgodGl0bGUpO1xyXG4gICAgZG9jLnRleHQodGl0bGUsIChwYWdlV2lkdGggLSB0aXRsZVdpZHRoKSAvIDIsIHkpO1xyXG5cclxuICAgIGRvYy5zZXRGb250U2l6ZSgxNik7XHJcbiAgICBjb25zdCBudW1iZXJUZXh0ID0gYE7CsCAke2RhdGEuY29uc2VjdXRpdmUgfHwgJyd9YDtcclxuICAgIGNvbnN0IG51bWJlcldpZHRoID0gZG9jLmdldFRleHRXaWR0aChudW1iZXJUZXh0KTtcclxuICAgIGRvYy50ZXh0KG51bWJlclRleHQsIChwYWdlV2lkdGggLSBudW1iZXJXaWR0aCkgLyAyLCB5ICsgMjUpO1xyXG5cclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoMCwgMCwgMCk7XHJcbiAgICByZXR1cm4geSArIDQwO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRNYWluSW5mbyhkb2M6IGpzUERGLCBkYXRhOiBXb3JrT3JkZXJEYXRhLCB5OiBudW1iZXIsIG1hcmdpbjogbnVtYmVyLCBwYWdlV2lkdGg6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICBjb25zdCB0YWJsZURhdGEgPSBbXHJcbiAgICAgIFtcclxuICAgICAgICB7IGNvbnRlbnQ6ICfDgXJlYTonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZpbGxDb2xvcjogWzI0MCwgMjQwLCAyNDBdIH0gfSxcclxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEuYXJlYSB8fCAnJywgc3R5bGVzOiB7fSB9LFxyXG4gICAgICAgIHsgY29udGVudDogJ0PDs2RpZ286Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXHJcbiAgICAgICAgeyBjb250ZW50OiBkYXRhLmNvZGUgfHwgJycsIHN0eWxlczoge30gfSxcclxuICAgICAgICB7IGNvbnRlbnQ6ICdGZWNoYTonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZpbGxDb2xvcjogWzI0MCwgMjQwLCAyNDBdIH0gfSxcclxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEuZGF0ZSB8fCAnJywgc3R5bGVzOiB7fSB9XHJcbiAgICAgIF0sXHJcbiAgICAgIFtcclxuICAgICAgICB7IGNvbnRlbnQ6ICdPcGVyYXJpbzonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZpbGxDb2xvcjogWzI0MCwgMjQwLCAyNDBdIH0gfSxcclxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEucmVzcG9uc2libGUgfHwgJycsIHN0eWxlczoge30gfSxcclxuICAgICAgICB7IGNvbnRlbnQ6ICdPZMOzbWV0cm86Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXHJcbiAgICAgICAgeyBjb250ZW50OiBkYXRhLm9kb21ldGVyIHx8ICcnLCBzdHlsZXM6IHt9IH0sXHJcbiAgICAgICAgeyBjb250ZW50OiAnUmVmLiBGYWN0dXJhOicsIHN0eWxlczogeyBmb250U3R5bGU6ICdib2xkJywgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxyXG4gICAgICAgIHsgY29udGVudDogZGF0YS5pbnZvaWNlUmVmZXJlbmNlIHx8ICctJywgc3R5bGVzOiB7fSB9XHJcbiAgICAgIF1cclxuICAgIF07XHJcblxyXG4gICAgKGRvYyBhcyBhbnkpLmF1dG9UYWJsZSh7XHJcbiAgICAgIHN0YXJ0WTogeSxcclxuICAgICAgYm9keTogdGFibGVEYXRhLFxyXG4gICAgICB0aGVtZTogJ2dyaWQnLFxyXG4gICAgICBzdHlsZXM6IHtcclxuICAgICAgICBmb250U2l6ZTogMTEsXHJcbiAgICAgICAgY2VsbFBhZGRpbmc6IDgsXHJcbiAgICAgICAgbGluZUNvbG9yOiBbMjAwLCAyMDAsIDIwMF0sXHJcbiAgICAgICAgbGluZVdpZHRoOiAwLjVcclxuICAgICAgfSxcclxuICAgICAgY29sdW1uU3R5bGVzOiB7XHJcbiAgICAgICAgMDogeyBjZWxsV2lkdGg6IDcwIH0sXHJcbiAgICAgICAgMTogeyBjZWxsV2lkdGg6IDEwMCB9LFxyXG4gICAgICAgIDI6IHsgY2VsbFdpZHRoOiA3MCB9LFxyXG4gICAgICAgIDM6IHsgY2VsbFdpZHRoOiA4MCB9LFxyXG4gICAgICAgIDQ6IHsgY2VsbFdpZHRoOiA3MCB9LFxyXG4gICAgICAgIDU6IHsgY2VsbFdpZHRoOiA4MCB9XHJcbiAgICAgIH0sXHJcbiAgICAgIG1hcmdpbjogeyBsZWZ0OiBtYXJnaW4sIHJpZ2h0OiBtYXJnaW4gfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIChkb2MgYXMgYW55KS5sYXN0QXV0b1RhYmxlLmZpbmFsWTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkUHJvdmlkZXJJbmZvKGRvYzoganNQREYsIGRhdGE6IFdvcmtPcmRlckRhdGEsIHk6IG51bWJlciwgbWFyZ2luOiBudW1iZXIsIHBhZ2VXaWR0aDogbnVtYmVyLCBjb2xvcjogbnVtYmVyW10pOiBudW1iZXIge1xyXG4gICAgLy8gVMOtdHVsbyBkZSBzZWNjacOzblxyXG4gICAgZG9jLnNldFRleHRDb2xvcihjb2xvclswXSwgY29sb3JbMV0sIGNvbG9yWzJdKTtcclxuICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnLCAnYm9sZCcpO1xyXG4gICAgZG9jLnNldEZvbnRTaXplKDE0KTtcclxuICAgIGNvbnN0IHRpdGxlID0gJ0RBVE9TIERFTCBQUk9WRUVET1InO1xyXG4gICAgY29uc3QgdGl0bGVXaWR0aCA9IGRvYy5nZXRUZXh0V2lkdGgodGl0bGUpO1xyXG4gICAgZG9jLnRleHQodGl0bGUsIChwYWdlV2lkdGggLSB0aXRsZVdpZHRoKSAvIDIsIHkpO1xyXG4gICAgZG9jLnNldFRleHRDb2xvcigwLCAwLCAwKTtcclxuXHJcbiAgICBjb25zdCB0YWJsZURhdGEgPSBbXHJcbiAgICAgIFtcclxuICAgICAgICB7IGNvbnRlbnQ6ICdOb21icmU6Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXHJcbiAgICAgICAgeyBjb250ZW50OiBkYXRhLm5hbWVQcm92aWRlciB8fCAnJywgc3R5bGVzOiB7fSB9LFxyXG4gICAgICAgIHsgY29udGVudDogJ0RpcmVjY2nDs246Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXHJcbiAgICAgICAgeyBjb250ZW50OiBkYXRhLmFkZHJlc3NQcm92aWRlciB8fCAnJywgc3R5bGVzOiB7fSB9XHJcbiAgICAgIF1cclxuICAgIF07XHJcblxyXG4gICAgKGRvYyBhcyBhbnkpLmF1dG9UYWJsZSh7XHJcbiAgICAgIHN0YXJ0WTogeSArIDIwLFxyXG4gICAgICBib2R5OiB0YWJsZURhdGEsXHJcbiAgICAgIHRoZW1lOiAnZ3JpZCcsXHJcbiAgICAgIHN0eWxlczoge1xyXG4gICAgICAgIGZvbnRTaXplOiAxMSxcclxuICAgICAgICBjZWxsUGFkZGluZzogOCxcclxuICAgICAgICBsaW5lQ29sb3I6IFsyMDAsIDIwMCwgMjAwXSxcclxuICAgICAgICBsaW5lV2lkdGg6IDAuNVxyXG4gICAgICB9LFxyXG4gICAgICBjb2x1bW5TdHlsZXM6IHtcclxuICAgICAgICAwOiB7IGNlbGxXaWR0aDogODAgfSxcclxuICAgICAgICAxOiB7IGNlbGxXaWR0aDogMTYwIH0sXHJcbiAgICAgICAgMjogeyBjZWxsV2lkdGg6IDgwIH0sXHJcbiAgICAgICAgMzogeyBjZWxsV2lkdGg6IDE1MCB9XHJcbiAgICAgIH0sXHJcbiAgICAgIG1hcmdpbjogeyBsZWZ0OiBtYXJnaW4sIHJpZ2h0OiBtYXJnaW4gfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIChkb2MgYXMgYW55KS5sYXN0QXV0b1RhYmxlLmZpbmFsWTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkU2VydmljZURldGFpbHMoZG9jOiBqc1BERiwgZGF0YTogV29ya09yZGVyRGF0YSwgeTogbnVtYmVyLCBtYXJnaW46IG51bWJlciwgcGFnZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBudW1iZXJbXSk6IG51bWJlciB7XHJcbiAgICAvLyBUw610dWxvIGRlIHNlY2Npw7NuXHJcbiAgICBkb2Muc2V0VGV4dENvbG9yKGNvbG9yWzBdLCBjb2xvclsxXSwgY29sb3JbMl0pO1xyXG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XHJcbiAgICBkb2Muc2V0Rm9udFNpemUoMTQpO1xyXG4gICAgY29uc3QgdGl0bGUgPSAnREVUQUxMRVMgREVMIFNFUlZJQ0lPJztcclxuICAgIGNvbnN0IHRpdGxlV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKHRpdGxlKTtcclxuICAgIGRvYy50ZXh0KHRpdGxlLCAocGFnZVdpZHRoIC0gdGl0bGVXaWR0aCkgLyAyLCB5KTtcclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoMCwgMCwgMCk7XHJcblxyXG4gICAgLy8gUHJlcGFyYXIgdGV4dG8gcGFyYSBjYWxjdWxhciBhbHR1cmEgbmVjZXNhcmlhXHJcbiAgICBjb25zdCBib3hZID0geSArIDIwO1xyXG4gICAgY29uc3QgYm94V2lkdGggPSBwYWdlV2lkdGggLSAobWFyZ2luICogMik7XHJcbiAgICBjb25zdCB0ZXh0TWFyZ2luID0gbWFyZ2luICsgMTU7XHJcbiAgICBjb25zdCBtYXhXaWR0aCA9IGJveFdpZHRoIC0gMzA7XHJcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gMTU7XHJcbiAgICBjb25zdCBtaW5Cb3hIZWlnaHQgPSA2MDsgLy8gQWx0dXJhIG3DrW5pbWEgZGVsIGNvbnRlbmVkb3JcclxuICAgIGNvbnN0IHBhZGRpbmcgPSA0MDsgLy8gUGFkZGluZyBzdXBlcmlvciBlIGluZmVyaW9yICgyMCBhcnJpYmEgKyAyMCBhYmFqbylcclxuXHJcbiAgICAvLyBDYWxjdWxhciBsw61uZWFzIGRlIHRleHRvIG5lY2VzYXJpYXNcclxuICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnLCAnbm9ybWFsJyk7XHJcbiAgICBkb2Muc2V0Rm9udFNpemUoMTEpO1xyXG4gICAgXHJcbiAgICBsZXQgdG90YWxMaW5lcyA9IDA7XHJcbiAgICBsZXQgY3VycmVudFRleHRZID0gMjA7IC8vIFBvc2ljacOzbiByZWxhdGl2YSBkZW50cm8gZGVsIGJveFxyXG5cclxuICAgIGlmIChkYXRhLmRlc2NyaXB0aW9uICYmIGRhdGEuZGVzY3JpcHRpb24udHJpbSgpKSB7XHJcbiAgICAgIGNvbnN0IGRlc2NMaW5lcyA9IGRvYy5zcGxpdFRleHRUb1NpemUoZGF0YS5kZXNjcmlwdGlvbi50cmltKCksIG1heFdpZHRoKTtcclxuICAgICAgdG90YWxMaW5lcyArPSBkZXNjTGluZXMubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGN1bGFyIGFsdHVyYSBuZWNlc2FyaWEgYmFzYWRhIGVuIGVsIGNvbnRlbmlkb1xyXG4gICAgY29uc3QgY29udGVudEhlaWdodCA9IE1hdGgubWF4KHRvdGFsTGluZXMgKiBsaW5lSGVpZ2h0LCAzMCk7IC8vIE3DrW5pbW8gMzBwdCBwYXJhIGNvbnRlbmlkb1xyXG4gICAgY29uc3QgYm94SGVpZ2h0ID0gTWF0aC5tYXgobWluQm94SGVpZ2h0LCBjb250ZW50SGVpZ2h0ICsgcGFkZGluZyk7XHJcblxyXG4gICAgLy8gVmVyaWZpY2FyIHNpIG5lY2VzaXRhbW9zIHVuYSBudWV2YSBww6FnaW5hXHJcbiAgICBjb25zdCBwYWdlSGVpZ2h0ID0gZG9jLmludGVybmFsLnBhZ2VTaXplLmdldEhlaWdodCgpO1xyXG4gICAgY29uc3QgcmVtYWluaW5nU3BhY2UgPSBwYWdlSGVpZ2h0IC0gYm94WSAtIDEwMDsgLy8gRGVqYXIgZXNwYWNpbyBwYXJhIGZvb3RlclxyXG4gICAgXHJcbiAgICBsZXQgZmluYWxCb3hZID0gYm94WTtcclxuICAgIGlmIChib3hIZWlnaHQgPiByZW1haW5pbmdTcGFjZSkge1xyXG4gICAgICAvLyBBw7FhZGlyIG51ZXZhIHDDoWdpbmFcclxuICAgICAgZG9jLmFkZFBhZ2UoKTtcclxuICAgICAgZmluYWxCb3hZID0gbWFyZ2luICsgNDA7IC8vIFBvc2ljacOzbiBlbiBudWV2YSBww6FnaW5hXHJcbiAgICB9XHJcblxyXG4gICAgLy8gRGlidWphciBjb250ZW5lZG9yIGNvbiBhbHR1cmEgZGluw6FtaWNhXHJcbiAgICAvLyBGb25kbyBncmlzIGNsYXJvXHJcbiAgICBkb2Muc2V0RmlsbENvbG9yKDI1MCwgMjUwLCAyNTApO1xyXG4gICAgZG9jLnJlY3QobWFyZ2luLCBmaW5hbEJveFksIGJveFdpZHRoLCBib3hIZWlnaHQsICdGJyk7XHJcbiAgICBcclxuICAgIC8vIEJvcmRlXHJcbiAgICBkb2Muc2V0RHJhd0NvbG9yKDIwMCwgMjAwLCAyMDApO1xyXG4gICAgZG9jLnJlY3QobWFyZ2luLCBmaW5hbEJveFksIGJveFdpZHRoLCBib3hIZWlnaHQsICdTJyk7XHJcblxyXG4gICAgLy8gQcOxYWRpciBjb250ZW5pZG8gZGUgdGV4dG9cclxuICAgIGxldCB0ZXh0WSA9IGZpbmFsQm94WSArIDIwO1xyXG5cclxuICAgIGlmIChkYXRhLmRlc2NyaXB0aW9uICYmIGRhdGEuZGVzY3JpcHRpb24udHJpbSgpKSB7XHJcbiAgICAgIGNvbnN0IGRlc2NMaW5lcyA9IGRvYy5zcGxpdFRleHRUb1NpemUoZGF0YS5kZXNjcmlwdGlvbi50cmltKCksIG1heFdpZHRoKTtcclxuICAgICAgXHJcbiAgICAgIC8vIFNpIGhheSBtdWNoYXMgbMOtbmVhcywgdmVyaWZpY2FyIHF1ZSBxdWVwYW4gZW4gbGEgcMOhZ2luYSBhY3R1YWxcclxuICAgICAgY29uc3QgcmVxdWlyZWRIZWlnaHQgPSBkZXNjTGluZXMubGVuZ3RoICogbGluZUhlaWdodCArIDQwO1xyXG4gICAgICBpZiAodGV4dFkgKyByZXF1aXJlZEhlaWdodCA+IHBhZ2VIZWlnaHQgLSA2MCkge1xyXG4gICAgICAgIC8vIEVsIGNvbnRlbmlkbyBlcyBtdXkgbGFyZ28sIGRpdmlkaXIgc2kgZXMgbmVjZXNhcmlvXHJcbiAgICAgICAgY29uc3QgbWF4TGluZXNQZXJQYWdlID0gTWF0aC5mbG9vcigocGFnZUhlaWdodCAtIHRleHRZIC0gNjApIC8gbGluZUhlaWdodCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGRlc2NMaW5lcy5sZW5ndGggPiBtYXhMaW5lc1BlclBhZ2UgJiYgbWF4TGluZXNQZXJQYWdlID4gMCkge1xyXG4gICAgICAgICAgLy8gTW9zdHJhciBsw61uZWFzIHF1ZSBjYWJlbiBlbiBsYSBww6FnaW5hIGFjdHVhbFxyXG4gICAgICAgICAgY29uc3QgY3VycmVudFBhZ2VMaW5lcyA9IGRlc2NMaW5lcy5zbGljZSgwLCBtYXhMaW5lc1BlclBhZ2UpO1xyXG4gICAgICAgICAgZG9jLnRleHQoY3VycmVudFBhZ2VMaW5lcywgdGV4dE1hcmdpbiwgdGV4dFkpO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyBDb250aW51YXIgZW4gbnVldmEgcMOhZ2luYSBzaSBoYXkgbcOhcyBjb250ZW5pZG9cclxuICAgICAgICAgIGlmIChkZXNjTGluZXMubGVuZ3RoID4gbWF4TGluZXNQZXJQYWdlKSB7XHJcbiAgICAgICAgICAgIGRvYy5hZGRQYWdlKCk7XHJcbiAgICAgICAgICAgIHRleHRZID0gbWFyZ2luICsgMjA7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ0xpbmVzID0gZGVzY0xpbmVzLnNsaWNlKG1heExpbmVzUGVyUGFnZSk7XHJcbiAgICAgICAgICAgIGRvYy50ZXh0KHJlbWFpbmluZ0xpbmVzLCB0ZXh0TWFyZ2luLCB0ZXh0WSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0ZXh0WSArIChyZW1haW5pbmdMaW5lcy5sZW5ndGggKiBsaW5lSGVpZ2h0KSArIDIwO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBkb2MudGV4dChkZXNjTGluZXMsIHRleHRNYXJnaW4sIHRleHRZKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZG9jLnRleHQoZGVzY0xpbmVzLCB0ZXh0TWFyZ2luLCB0ZXh0WSk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIHRleHRZICs9IGRlc2NMaW5lcy5sZW5ndGggKiBsaW5lSGVpZ2h0O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNpIG5vIGhheSBkZXNjcmlwY2nDs24sIG1vc3RyYXIgdW4gbWVuc2FqZVxyXG4gICAgaWYgKCFkYXRhLmRlc2NyaXB0aW9uIHx8ICFkYXRhLmRlc2NyaXB0aW9uLnRyaW0oKSkge1xyXG4gICAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2l0YWxpYycpO1xyXG4gICAgICBkb2Muc2V0Rm9udFNpemUoMTApO1xyXG4gICAgICBkb2Muc2V0VGV4dENvbG9yKDE1MCwgMTUwLCAxNTApO1xyXG4gICAgICBkb2MudGV4dCgnTm8gc2UgaGFuIGVzcGVjaWZpY2FkbyBkZXRhbGxlcyBkZWwgc2VydmljaW8uJywgdGV4dE1hcmdpbiwgdGV4dFkpO1xyXG4gICAgICBkb2Muc2V0VGV4dENvbG9yKDAsIDAsIDApO1xyXG4gICAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ25vcm1hbCcpO1xyXG4gICAgICBkb2Muc2V0Rm9udFNpemUoMTEpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmaW5hbEJveFkgKyBib3hIZWlnaHQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNw6l0b2RvIGF1eGlsaWFyIHBhcmEgbWFuZWphciB0ZXh0byBsYXJnbyBxdWUgcHVlZGUgbmVjZXNpdGFyIG3Dumx0aXBsZXMgcMOhZ2luYXNcclxuICAgKi9cclxuICBwcml2YXRlIGFkZExvbmdUZXh0KGRvYzoganNQREYsIHRleHQ6IHN0cmluZywgeDogbnVtYmVyLCB5OiBudW1iZXIsIG1heFdpZHRoOiBudW1iZXIsIGZvbnRTaXplOiBudW1iZXIgPSAxMSk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRleHQgfHwgIXRleHQudHJpbSgpKSByZXR1cm4geTtcclxuXHJcbiAgICBkb2Muc2V0Rm9udFNpemUoZm9udFNpemUpO1xyXG4gICAgY29uc3QgbGluZXMgPSBkb2Muc3BsaXRUZXh0VG9TaXplKHRleHQudHJpbSgpLCBtYXhXaWR0aCk7XHJcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gZm9udFNpemUgKyAzO1xyXG4gICAgY29uc3QgcGFnZUhlaWdodCA9IGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5nZXRIZWlnaHQoKTtcclxuICAgIGNvbnN0IG1hcmdpbiA9IDQwO1xyXG5cclxuICAgIGxldCBjdXJyZW50WSA9IHk7XHJcbiAgICBsZXQgbGluZUluZGV4ID0gMDtcclxuXHJcbiAgICB3aGlsZSAobGluZUluZGV4IDwgbGluZXMubGVuZ3RoKSB7XHJcbiAgICAgIC8vIFZlcmlmaWNhciBzaSBuZWNlc2l0YW1vcyB1bmEgbnVldmEgcMOhZ2luYVxyXG4gICAgICBpZiAoY3VycmVudFkgKyBsaW5lSGVpZ2h0ID4gcGFnZUhlaWdodCAtIG1hcmdpbikge1xyXG4gICAgICAgIGRvYy5hZGRQYWdlKCk7XHJcbiAgICAgICAgY3VycmVudFkgPSBtYXJnaW47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIENhbGN1bGFyIGN1w6FudGFzIGzDrW5lYXMgY2FiZW4gZW4gbGEgcMOhZ2luYSBhY3R1YWxcclxuICAgICAgY29uc3QgcmVtYWluaW5nU3BhY2UgPSBwYWdlSGVpZ2h0IC0gY3VycmVudFkgLSBtYXJnaW47XHJcbiAgICAgIGNvbnN0IG1heExpbmVzSW5QYWdlID0gTWF0aC5mbG9vcihyZW1haW5pbmdTcGFjZSAvIGxpbmVIZWlnaHQpO1xyXG4gICAgICBcclxuICAgICAgaWYgKG1heExpbmVzSW5QYWdlID4gMCkge1xyXG4gICAgICAgIGNvbnN0IGxpbmVzVG9TaG93ID0gTWF0aC5taW4obWF4TGluZXNJblBhZ2UsIGxpbmVzLmxlbmd0aCAtIGxpbmVJbmRleCk7XHJcbiAgICAgICAgY29uc3QgcGFnZUxpbmVzID0gbGluZXMuc2xpY2UobGluZUluZGV4LCBsaW5lSW5kZXggKyBsaW5lc1RvU2hvdyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgZG9jLnRleHQocGFnZUxpbmVzLCB4LCBjdXJyZW50WSk7XHJcbiAgICAgICAgY3VycmVudFkgKz0gcGFnZUxpbmVzLmxlbmd0aCAqIGxpbmVIZWlnaHQ7XHJcbiAgICAgICAgbGluZUluZGV4ICs9IGxpbmVzVG9TaG93O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIFNpIG5vIGNhYmUgbmkgdW5hIGzDrW5lYSwgaXIgYSBudWV2YSBww6FnaW5hXHJcbiAgICAgICAgZG9jLmFkZFBhZ2UoKTtcclxuICAgICAgICBjdXJyZW50WSA9IG1hcmdpbjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjdXJyZW50WTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkQXV0aG9yaXphdGlvbihkb2M6IGpzUERGLCBkYXRhOiBXb3JrT3JkZXJEYXRhLCB5OiBudW1iZXIsIG1hcmdpbjogbnVtYmVyLCBwYWdlV2lkdGg6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICBjb25zdCB0YWJsZURhdGEgPSBbXHJcbiAgICAgIFtcclxuICAgICAgICB7IGNvbnRlbnQ6ICdBVVRPUklaQURBIFBPUjonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZvbnRTaXplOiAxMiwgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxyXG4gICAgICAgIHsgY29udGVudDogZGF0YS5hcHByb3ZlZF9ieSB8fCAnJywgc3R5bGVzOiB7IGZvbnRTaXplOiAxMiB9IH1cclxuICAgICAgXVxyXG4gICAgXTtcclxuXHJcbiAgICAoZG9jIGFzIGFueSkuYXV0b1RhYmxlKHtcclxuICAgICAgc3RhcnRZOiB5LFxyXG4gICAgICBib2R5OiB0YWJsZURhdGEsXHJcbiAgICAgIHRoZW1lOiAnZ3JpZCcsXHJcbiAgICAgIHN0eWxlczoge1xyXG4gICAgICAgIGNlbGxQYWRkaW5nOiAxMixcclxuICAgICAgICBsaW5lQ29sb3I6IFsyMDAsIDIwMCwgMjAwXSxcclxuICAgICAgICBsaW5lV2lkdGg6IDAuNVxyXG4gICAgICB9LFxyXG4gICAgICBjb2x1bW5TdHlsZXM6IHtcclxuICAgICAgICAwOiB7IGNlbGxXaWR0aDogMTUwIH0sXHJcbiAgICAgICAgMTogeyBjZWxsV2lkdGg6IDMyMCB9XHJcbiAgICAgIH0sXHJcbiAgICAgIG1hcmdpbjogeyBsZWZ0OiBtYXJnaW4sIHJpZ2h0OiBtYXJnaW4gfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIChkb2MgYXMgYW55KS5sYXN0QXV0b1RhYmxlLmZpbmFsWTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkRm9vdGVyKGRvYzoganNQREYsIGRhdGE6IFdvcmtPcmRlckRhdGEsIHk6IG51bWJlciwgcGFnZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBudW1iZXJbXSk6IHZvaWQge1xyXG4gICAgLy8gRm9uZG8gZGVsIHBpZSBkZSBww6FnaW5hXHJcbiAgICBkb2Muc2V0RmlsbENvbG9yKGNvbG9yWzBdLCBjb2xvclsxXSwgY29sb3JbMl0pO1xyXG4gICAgZG9jLnJlY3QoNDAsIHksIHBhZ2VXaWR0aCAtIDgwLCA2MCwgJ0YnKTtcclxuXHJcbiAgICAvLyBUZXh0byBlbiBibGFuY29cclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoMjU1LCAyNTUsIDI1NSk7XHJcbiAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcclxuICAgIGRvYy5zZXRGb250U2l6ZSgxMik7XHJcbiAgICBcclxuICAgIGNvbnN0IGluc3RydWN0aW9uID0gJ0Zhdm9yIGFkanVudGFyIGxhIG9yZGVuIGEgbGEgZmFjdHVyYSBvIGN1ZW50YSBkZSBjb2Jybyc7XHJcbiAgICBjb25zdCBpbnN0V2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGluc3RydWN0aW9uKTtcclxuICAgIGRvYy50ZXh0KGluc3RydWN0aW9uLCAocGFnZVdpZHRoIC0gaW5zdFdpZHRoKSAvIDIsIHkgKyAyNSk7XHJcblxyXG4gICAgZG9jLnNldEZvbnRTaXplKDEwKTtcclxuICAgIGNvbnN0IGVtYWlsV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGRhdGEubWFpbCB8fCAnJyk7XHJcbiAgICBkb2MudGV4dChkYXRhLm1haWwgfHwgJycsIChwYWdlV2lkdGggLSBlbWFpbFdpZHRoKSAvIDIsIHkgKyA0NSk7XHJcblxyXG4gICAgLy8gUmVzZXRlYXIgY29sb3JcclxuICAgIGRvYy5zZXRUZXh0Q29sb3IoMCwgMCwgMCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmEgUERGIG9wdGltaXphZG8gcGFyYSBpbXByZXNpw7NuXHJcbiAgICovXHJcbiAgZ2VuZXJhdGVGb3JQcmludChkYXRhOiBXb3JrT3JkZXJEYXRhKTogUHJvbWlzZTxqc1BERj4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVXb3JrT3JkZXJQREYoZGF0YSwge1xyXG4gICAgICBmb3JtYXQ6ICdsZXR0ZXInLFxyXG4gICAgICBkb3dubG9hZDogZmFsc2VcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhIFBERiB5IGxvIGRldnVlbHZlIGNvbW8gQmxvYiBwYXJhIGVudsOtbyBwb3IgZW1haWxcclxuICAgKi9cclxuICBnZW5lcmF0ZUFzQmxvYihkYXRhOiBXb3JrT3JkZXJEYXRhKTogUHJvbWlzZTxCbG9iPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLmdlbmVyYXRlV29ya09yZGVyUERGKGRhdGEsIHsgZG93bmxvYWQ6IGZhbHNlIH0pXHJcbiAgICAgICAgLnRoZW4oZG9jID0+IHtcclxuICAgICAgICAgIGNvbnN0IHBkZkJsb2IgPSBkb2Mub3V0cHV0KCdibG9iJyk7XHJcbiAgICAgICAgICByZXNvbHZlKHBkZkJsb2IpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNhdGNoKHJlamVjdCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlbmVyYSBQREYgeSBsbyBkZXZ1ZWx2ZSBjb21vIGJhc2U2NFxyXG4gICAqL1xyXG4gIGdlbmVyYXRlQXNCYXNlNjQoZGF0YTogV29ya09yZGVyRGF0YSk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLmdlbmVyYXRlV29ya09yZGVyUERGKGRhdGEsIHsgZG93bmxvYWQ6IGZhbHNlIH0pXHJcbiAgICAgICAgLnRoZW4oZG9jID0+IHtcclxuICAgICAgICAgIGNvbnN0IGJhc2U2NCA9IGRvYy5vdXRwdXQoJ2RhdGF1cmlzdHJpbmcnKTtcclxuICAgICAgICAgIHJlc29sdmUoYmFzZTY0KTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5jYXRjaChyZWplY3QpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
1
+ import { Injectable } from '@angular/core';
2
+ import { jsPDF } from 'jspdf';
3
+ import 'jspdf-autotable';
4
+ import * as i0 from "@angular/core";
5
+ export class WorkOrderPdfService {
6
+ constructor() { }
7
+ /**
8
+ * Genera PDF de orden de trabajo con diseño profesional
9
+ * Dimensiones fijas, independiente del DOM
10
+ */
11
+ generateWorkOrderPDF(data, options) {
12
+ return new Promise((resolve, reject) => {
13
+ try {
14
+ const opts = {
15
+ format: 'letter',
16
+ download: true,
17
+ filename: 'orden_trabajo.pdf',
18
+ ...options
19
+ };
20
+ const doc = new jsPDF('p', 'pt', opts.format);
21
+ const pageWidth = doc.internal.pageSize.getWidth();
22
+ const pageHeight = doc.internal.pageSize.getHeight();
23
+ const margin = 40;
24
+ let currentY = margin;
25
+ // Colores corporativos
26
+ const primaryColor = [52, 152, 219]; // Azul para órdenes de trabajo
27
+ const secondaryColor = [44, 62, 80]; // Gris oscuro
28
+ const accentColor = [155, 89, 182]; // Morado
29
+ // === ENCABEZADO PRINCIPAL ===
30
+ this.addHeader(doc, data, margin, currentY, pageWidth, primaryColor);
31
+ currentY = 140;
32
+ // === TÍTULO DEL DOCUMENTO ===
33
+ currentY = this.addDocumentTitle(doc, data, currentY, pageWidth, accentColor);
34
+ currentY += 25;
35
+ // === INFORMACIÓN PRINCIPAL ===
36
+ currentY = this.addMainInfo(doc, data, currentY, margin, pageWidth);
37
+ currentY += 20;
38
+ // === DATOS DEL PROVEEDOR ===
39
+ currentY = this.addProviderInfo(doc, data, currentY, margin, pageWidth, secondaryColor);
40
+ currentY += 20;
41
+ // === DETALLES DEL SERVICIO ===
42
+ currentY = this.addServiceDetails(doc, data, currentY, margin, pageWidth, secondaryColor);
43
+ currentY += 20;
44
+ // === AUTORIZACIÓN ===
45
+ currentY = this.addAuthorization(doc, data, currentY, margin, pageWidth);
46
+ currentY += 30;
47
+ // === PIE DE PÁGINA ===
48
+ this.addFooter(doc, data, pageHeight - 80, pageWidth, primaryColor);
49
+ // === GENERAR/DESCARGAR ===
50
+ if (opts.download) {
51
+ doc.output('dataurlnewwindow', { filename: opts.filename });
52
+ }
53
+ resolve(doc);
54
+ }
55
+ catch (error) {
56
+ reject(error);
57
+ }
58
+ });
59
+ }
60
+ addHeader(doc, data, margin, y, pageWidth, color) {
61
+ // Fondo del encabezado
62
+ doc.setFillColor(color[0], color[1], color[2]);
63
+ doc.rect(margin, y, pageWidth - (margin * 2), 80, 'F');
64
+ // Texto del encabezado en blanco
65
+ doc.setTextColor(255, 255, 255);
66
+ doc.setFont('helvetica', 'bold');
67
+ doc.setFontSize(18);
68
+ const companyName = (data.name || '').toUpperCase();
69
+ const nameWidth = doc.getTextWidth(companyName);
70
+ doc.text(companyName, (pageWidth - nameWidth) / 2, y + 25);
71
+ doc.setFontSize(12);
72
+ const nitText = `NIT: ${data.nit || ''}`;
73
+ const nitWidth = doc.getTextWidth(nitText);
74
+ doc.text(nitText, (pageWidth - nitWidth) / 2, y + 45);
75
+ doc.setFontSize(10);
76
+ const addressText = `${data.address || ''} - TEL: ${data.telephone || ''}`;
77
+ const addressWidth = doc.getTextWidth(addressText);
78
+ doc.text(addressText, (pageWidth - addressWidth) / 2, y + 65);
79
+ // Resetear color de texto
80
+ doc.setTextColor(0, 0, 0);
81
+ }
82
+ addDocumentTitle(doc, data, y, pageWidth, color) {
83
+ doc.setTextColor(color[0], color[1], color[2]);
84
+ doc.setFont('helvetica', 'bold');
85
+ doc.setFontSize(20);
86
+ const title = 'ORDEN DE TRABAJO';
87
+ const titleWidth = doc.getTextWidth(title);
88
+ doc.text(title, (pageWidth - titleWidth) / 2, y);
89
+ doc.setFontSize(16);
90
+ const numberText = `N° ${data.consecutive || ''}`;
91
+ const numberWidth = doc.getTextWidth(numberText);
92
+ doc.text(numberText, (pageWidth - numberWidth) / 2, y + 25);
93
+ doc.setTextColor(0, 0, 0);
94
+ return y + 40;
95
+ }
96
+ addMainInfo(doc, data, y, margin, pageWidth) {
97
+ const tableData = [
98
+ [
99
+ { content: 'Área:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
100
+ { content: data.area || '', styles: {} },
101
+ { content: 'Código:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
102
+ { content: data.code || '', styles: {} },
103
+ { content: 'Fecha:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
104
+ { content: data.date || '', styles: {} }
105
+ ],
106
+ [
107
+ { content: 'Operario:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
108
+ { content: data.responsible || '', styles: {} },
109
+ { content: 'Odómetro:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
110
+ { content: data.odometer || '', styles: {} },
111
+ { content: 'Ref. Factura:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
112
+ { content: data.invoiceReference || '-', styles: {} }
113
+ ]
114
+ ];
115
+ doc.autoTable({
116
+ startY: y,
117
+ body: tableData,
118
+ theme: 'grid',
119
+ styles: {
120
+ fontSize: 11,
121
+ cellPadding: 8,
122
+ lineColor: [200, 200, 200],
123
+ lineWidth: 0.5
124
+ },
125
+ columnStyles: {
126
+ 0: { cellWidth: 70 },
127
+ 1: { cellWidth: 100 },
128
+ 2: { cellWidth: 70 },
129
+ 3: { cellWidth: 80 },
130
+ 4: { cellWidth: 70 },
131
+ 5: { cellWidth: 80 }
132
+ },
133
+ margin: { left: margin, right: margin }
134
+ });
135
+ return doc.lastAutoTable.finalY;
136
+ }
137
+ addProviderInfo(doc, data, y, margin, pageWidth, color) {
138
+ // Título de sección
139
+ doc.setTextColor(color[0], color[1], color[2]);
140
+ doc.setFont('helvetica', 'bold');
141
+ doc.setFontSize(14);
142
+ const title = 'DATOS DEL PROVEEDOR';
143
+ const titleWidth = doc.getTextWidth(title);
144
+ doc.text(title, (pageWidth - titleWidth) / 2, y);
145
+ doc.setTextColor(0, 0, 0);
146
+ const tableData = [
147
+ [
148
+ { content: 'Nombre:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
149
+ { content: data.nameProvider || '', styles: {} },
150
+ { content: 'Dirección:', styles: { fontStyle: 'bold', fillColor: [240, 240, 240] } },
151
+ { content: data.addressProvider || '', styles: {} }
152
+ ]
153
+ ];
154
+ doc.autoTable({
155
+ startY: y + 20,
156
+ body: tableData,
157
+ theme: 'grid',
158
+ styles: {
159
+ fontSize: 11,
160
+ cellPadding: 8,
161
+ lineColor: [200, 200, 200],
162
+ lineWidth: 0.5
163
+ },
164
+ columnStyles: {
165
+ 0: { cellWidth: 80 },
166
+ 1: { cellWidth: 160 },
167
+ 2: { cellWidth: 80 },
168
+ 3: { cellWidth: 150 }
169
+ },
170
+ margin: { left: margin, right: margin }
171
+ });
172
+ return doc.lastAutoTable.finalY;
173
+ }
174
+ addServiceDetails(doc, data, y, margin, pageWidth, color) {
175
+ // Título de sección
176
+ doc.setTextColor(color[0], color[1], color[2]);
177
+ doc.setFont('helvetica', 'bold');
178
+ doc.setFontSize(14);
179
+ const title = 'DETALLES DEL SERVICIO';
180
+ const titleWidth = doc.getTextWidth(title);
181
+ doc.text(title, (pageWidth - titleWidth) / 2, y);
182
+ doc.setTextColor(0, 0, 0);
183
+ // Preparar texto para calcular altura necesaria
184
+ const boxY = y + 20;
185
+ const boxWidth = pageWidth - (margin * 2);
186
+ const textMargin = margin + 15;
187
+ const maxWidth = boxWidth - 30;
188
+ const lineHeight = 15;
189
+ const minBoxHeight = 60; // Altura mínima del contenedor
190
+ const padding = 40; // Padding superior e inferior (20 arriba + 20 abajo)
191
+ // Calcular líneas de texto necesarias
192
+ doc.setFont('helvetica', 'normal');
193
+ doc.setFontSize(11);
194
+ let totalLines = 0;
195
+ let currentTextY = 20; // Posición relativa dentro del box
196
+ if (data.description && data.description.trim()) {
197
+ const descLines = doc.splitTextToSize(data.description.trim(), maxWidth);
198
+ totalLines += descLines.length;
199
+ }
200
+ // Calcular altura necesaria basada en el contenido
201
+ const contentHeight = Math.max(totalLines * lineHeight, 30); // Mínimo 30pt para contenido
202
+ const boxHeight = Math.max(minBoxHeight, contentHeight + padding);
203
+ // Verificar si necesitamos una nueva página
204
+ const pageHeight = doc.internal.pageSize.getHeight();
205
+ const remainingSpace = pageHeight - boxY - 100; // Dejar espacio para footer
206
+ let finalBoxY = boxY;
207
+ if (boxHeight > remainingSpace) {
208
+ // Añadir nueva página
209
+ doc.addPage();
210
+ finalBoxY = margin + 40; // Posición en nueva página
211
+ }
212
+ // Dibujar contenedor con altura dinámica
213
+ // Fondo gris claro
214
+ doc.setFillColor(250, 250, 250);
215
+ doc.rect(margin, finalBoxY, boxWidth, boxHeight, 'F');
216
+ // Borde
217
+ doc.setDrawColor(200, 200, 200);
218
+ doc.rect(margin, finalBoxY, boxWidth, boxHeight, 'S');
219
+ // Añadir contenido de texto
220
+ let textY = finalBoxY + 20;
221
+ if (data.description && data.description.trim()) {
222
+ const descLines = doc.splitTextToSize(data.description.trim(), maxWidth);
223
+ // Si hay muchas líneas, verificar que quepan en la página actual
224
+ const requiredHeight = descLines.length * lineHeight + 40;
225
+ if (textY + requiredHeight > pageHeight - 60) {
226
+ // El contenido es muy largo, dividir si es necesario
227
+ const maxLinesPerPage = Math.floor((pageHeight - textY - 60) / lineHeight);
228
+ if (descLines.length > maxLinesPerPage && maxLinesPerPage > 0) {
229
+ // Mostrar líneas que caben en la página actual
230
+ const currentPageLines = descLines.slice(0, maxLinesPerPage);
231
+ doc.text(currentPageLines, textMargin, textY);
232
+ // Continuar en nueva página si hay más contenido
233
+ if (descLines.length > maxLinesPerPage) {
234
+ doc.addPage();
235
+ textY = margin + 20;
236
+ const remainingLines = descLines.slice(maxLinesPerPage);
237
+ doc.text(remainingLines, textMargin, textY);
238
+ return textY + (remainingLines.length * lineHeight) + 20;
239
+ }
240
+ }
241
+ else {
242
+ doc.text(descLines, textMargin, textY);
243
+ }
244
+ }
245
+ else {
246
+ doc.text(descLines, textMargin, textY);
247
+ }
248
+ textY += descLines.length * lineHeight;
249
+ }
250
+ // Si no hay descripción, mostrar un mensaje
251
+ if (!data.description || !data.description.trim()) {
252
+ doc.setFont('helvetica', 'italic');
253
+ doc.setFontSize(10);
254
+ doc.setTextColor(150, 150, 150);
255
+ doc.text('No se han especificado detalles del servicio.', textMargin, textY);
256
+ doc.setTextColor(0, 0, 0);
257
+ doc.setFont('helvetica', 'normal');
258
+ doc.setFontSize(11);
259
+ }
260
+ return finalBoxY + boxHeight;
261
+ }
262
+ /**
263
+ * Método auxiliar para manejar texto largo que puede necesitar múltiples páginas
264
+ */
265
+ addLongText(doc, text, x, y, maxWidth, fontSize = 11) {
266
+ if (!text || !text.trim())
267
+ return y;
268
+ doc.setFontSize(fontSize);
269
+ const lines = doc.splitTextToSize(text.trim(), maxWidth);
270
+ const lineHeight = fontSize + 3;
271
+ const pageHeight = doc.internal.pageSize.getHeight();
272
+ const margin = 40;
273
+ let currentY = y;
274
+ let lineIndex = 0;
275
+ while (lineIndex < lines.length) {
276
+ // Verificar si necesitamos una nueva página
277
+ if (currentY + lineHeight > pageHeight - margin) {
278
+ doc.addPage();
279
+ currentY = margin;
280
+ }
281
+ // Calcular cuántas líneas caben en la página actual
282
+ const remainingSpace = pageHeight - currentY - margin;
283
+ const maxLinesInPage = Math.floor(remainingSpace / lineHeight);
284
+ if (maxLinesInPage > 0) {
285
+ const linesToShow = Math.min(maxLinesInPage, lines.length - lineIndex);
286
+ const pageLines = lines.slice(lineIndex, lineIndex + linesToShow);
287
+ doc.text(pageLines, x, currentY);
288
+ currentY += pageLines.length * lineHeight;
289
+ lineIndex += linesToShow;
290
+ }
291
+ else {
292
+ // Si no cabe ni una línea, ir a nueva página
293
+ doc.addPage();
294
+ currentY = margin;
295
+ }
296
+ }
297
+ return currentY;
298
+ }
299
+ addAuthorization(doc, data, y, margin, pageWidth) {
300
+ const tableData = [
301
+ [
302
+ { content: 'AUTORIZADA POR:', styles: { fontStyle: 'bold', fontSize: 12, fillColor: [240, 240, 240] } },
303
+ { content: data.approved_by || '', styles: { fontSize: 12 } }
304
+ ]
305
+ ];
306
+ doc.autoTable({
307
+ startY: y,
308
+ body: tableData,
309
+ theme: 'grid',
310
+ styles: {
311
+ cellPadding: 12,
312
+ lineColor: [200, 200, 200],
313
+ lineWidth: 0.5
314
+ },
315
+ columnStyles: {
316
+ 0: { cellWidth: 150 },
317
+ 1: { cellWidth: 320 }
318
+ },
319
+ margin: { left: margin, right: margin }
320
+ });
321
+ return doc.lastAutoTable.finalY;
322
+ }
323
+ addFooter(doc, data, y, pageWidth, color) {
324
+ // Fondo del pie de página
325
+ doc.setFillColor(color[0], color[1], color[2]);
326
+ doc.rect(40, y, pageWidth - 80, 60, 'F');
327
+ // Texto en blanco
328
+ doc.setTextColor(255, 255, 255);
329
+ doc.setFont('helvetica', 'bold');
330
+ doc.setFontSize(12);
331
+ const instruction = 'Favor adjuntar la orden a la factura o cuenta de cobro';
332
+ const instWidth = doc.getTextWidth(instruction);
333
+ doc.text(instruction, (pageWidth - instWidth) / 2, y + 25);
334
+ doc.setFontSize(10);
335
+ const emailWidth = doc.getTextWidth(data.mail || '');
336
+ doc.text(data.mail || '', (pageWidth - emailWidth) / 2, y + 45);
337
+ // Resetear color
338
+ doc.setTextColor(0, 0, 0);
339
+ }
340
+ /**
341
+ * Genera PDF optimizado para impresión
342
+ */
343
+ generateForPrint(data) {
344
+ return this.generateWorkOrderPDF(data, {
345
+ format: 'letter',
346
+ download: false
347
+ });
348
+ }
349
+ /**
350
+ * Genera PDF y lo devuelve como Blob para envío por email
351
+ */
352
+ generateAsBlob(data) {
353
+ return new Promise((resolve, reject) => {
354
+ this.generateWorkOrderPDF(data, { download: false })
355
+ .then(doc => {
356
+ const pdfBlob = doc.output('blob');
357
+ resolve(pdfBlob);
358
+ })
359
+ .catch(reject);
360
+ });
361
+ }
362
+ /**
363
+ * Genera PDF y lo devuelve como base64
364
+ */
365
+ generateAsBase64(data) {
366
+ return new Promise((resolve, reject) => {
367
+ this.generateWorkOrderPDF(data, { download: false })
368
+ .then(doc => {
369
+ const base64 = doc.output('datauristring');
370
+ resolve(base64);
371
+ })
372
+ .catch(reject);
373
+ });
374
+ }
375
+ }
376
+ WorkOrderPdfService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
377
+ WorkOrderPdfService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, providedIn: 'root' });
378
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WorkOrderPdfService, decorators: [{
379
+ type: Injectable,
380
+ args: [{
381
+ providedIn: 'root'
382
+ }]
383
+ }], ctorParameters: function () { return []; } });
384
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yay1vcmRlci1wZGYuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zZXJ2aWNlcy93b3JrLW9yZGVyLXBkZi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUM5QixPQUFPLGlCQUFpQixDQUFDOztBQTBCekIsTUFBTSxPQUFPLG1CQUFtQjtJQUU5QixnQkFBZ0IsQ0FBQztJQUVqQjs7O09BR0c7SUFDSCxvQkFBb0IsQ0FBQyxJQUFtQixFQUFFLE9BSXpDO1FBQ0MsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNyQyxJQUFJO2dCQUNGLE1BQU0sSUFBSSxHQUFHO29CQUNYLE1BQU0sRUFBRSxRQUFRO29CQUNoQixRQUFRLEVBQUUsSUFBSTtvQkFDZCxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixHQUFHLE9BQU87aUJBQ1gsQ0FBQztnQkFFRixNQUFNLEdBQUcsR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25ELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNyRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQztnQkFFdEIsdUJBQXVCO2dCQUN2QixNQUFNLFlBQVksR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMs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bmJVLG1CQUFtQjtvSEFBbkIsbUJBQW1CLGNBRmxCLE1BQU07MkZBRVAsbUJBQW1CO2tCQUgvQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGpzUERGIH0gZnJvbSAnanNwZGYnO1xuaW1wb3J0ICdqc3BkZi1hdXRvdGFibGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtPcmRlckRhdGEge1xuICBuYW1lPzogc3RyaW5nO1xuICBuaXQ/OiBzdHJpbmc7XG4gIGFkZHJlc3M/OiBzdHJpbmc7XG4gIHRlbGVwaG9uZT86IHN0cmluZztcbiAgbWFpbD86IHN0cmluZztcbiAgaW1hZ2U/OiBzdHJpbmc7XG4gIGNvZGU/OiBzdHJpbmc7XG4gIGRhdGU/OiBzdHJpbmc7XG4gIHJlc3BvbnNpYmxlPzogc3RyaW5nO1xuICB0aGlyZD86IHN0cmluZztcbiAgYXBwcm92ZWRfYnk/OiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBjb25zZWN1dGl2ZT86IHN0cmluZztcbiAgbmFtZVByb3ZpZGVyPzogc3RyaW5nO1xuICBhZGRyZXNzUHJvdmlkZXI/OiBzdHJpbmc7XG4gIGFyZWE/OiBzdHJpbmc7XG4gIG9kb21ldGVyPzogc3RyaW5nO1xuICBpbnZvaWNlUmVmZXJlbmNlPzogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBXb3JrT3JkZXJQZGZTZXJ2aWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmEgUERGIGRlIG9yZGVuIGRlIHRyYWJham8gY29uIGRpc2XDsW8gcHJvZmVzaW9uYWxcbiAgICogRGltZW5zaW9uZXMgZmlqYXMsIGluZGVwZW5kaWVudGUgZGVsIERPTVxuICAgKi9cbiAgZ2VuZXJhdGVXb3JrT3JkZXJQREYoZGF0YTogV29ya09yZGVyRGF0YSwgb3B0aW9ucz86IHtcbiAgICBmb3JtYXQ/OiAnbGV0dGVyJyB8ICdhNCc7XG4gICAgZG93bmxvYWQ/OiBib29sZWFuO1xuICAgIGZpbGVuYW1lPzogc3RyaW5nO1xuICB9KTogUHJvbWlzZTxqc1BERj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBvcHRzID0ge1xuICAgICAgICAgIGZvcm1hdDogJ2xldHRlcicsXG4gICAgICAgICAgZG93bmxvYWQ6IHRydWUsXG4gICAgICAgICAgZmlsZW5hbWU6ICdvcmRlbl90cmFiYWpvLnBkZicsXG4gICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGRvYyA9IG5ldyBqc1BERigncCcsICdwdCcsIG9wdHMuZm9ybWF0KTtcbiAgICAgICAgY29uc3QgcGFnZVdpZHRoID0gZG9jLmludGVybmFsLnBhZ2VTaXplLmdldFdpZHRoKCk7XG4gICAgICAgIGNvbnN0IHBhZ2VIZWlnaHQgPSBkb2MuaW50ZXJuYWwucGFnZVNpemUuZ2V0SGVpZ2h0KCk7XG4gICAgICAgIGNvbnN0IG1hcmdpbiA9IDQwO1xuICAgICAgICBsZXQgY3VycmVudFkgPSBtYXJnaW47XG5cbiAgICAgICAgLy8gQ29sb3JlcyBjb3Jwb3JhdGl2b3NcbiAgICAgICAgY29uc3QgcHJpbWFyeUNvbG9yID0gWzUyLCAxNTIsIDIxOV07IC8vIEF6dWwgcGFyYSDDs3JkZW5lcyBkZSB0cmFiYWpvXG4gICAgICAgIGNvbnN0IHNlY29uZGFyeUNvbG9yID0gWzQ0LCA2MiwgODBdOyAvLyBHcmlzIG9zY3Vyb1xuICAgICAgICBjb25zdCBhY2NlbnRDb2xvciA9IFsxNTUsIDg5LCAxODJdOyAvLyBNb3JhZG9cblxuICAgICAgICAvLyA9PT0gRU5DQUJFWkFETyBQUklOQ0lQQUwgPT09XG4gICAgICAgIHRoaXMuYWRkSGVhZGVyKGRvYywgZGF0YSwgbWFyZ2luLCBjdXJyZW50WSwgcGFnZVdpZHRoLCBwcmltYXJ5Q29sb3IpO1xuICAgICAgICBjdXJyZW50WSA9IDE0MDtcblxuICAgICAgICAvLyA9PT0gVMONVFVMTyBERUwgRE9DVU1FTlRPID09PVxuICAgICAgICBjdXJyZW50WSA9IHRoaXMuYWRkRG9jdW1lbnRUaXRsZShkb2MsIGRhdGEsIGN1cnJlbnRZLCBwYWdlV2lkdGgsIGFjY2VudENvbG9yKTtcbiAgICAgICAgY3VycmVudFkgKz0gMjU7XG5cbiAgICAgICAgLy8gPT09IElORk9STUFDScOTTiBQUklOQ0lQQUwgPT09XG4gICAgICAgIGN1cnJlbnRZID0gdGhpcy5hZGRNYWluSW5mbyhkb2MsIGRhdGEsIGN1cnJlbnRZLCBtYXJnaW4sIHBhZ2VXaWR0aCk7XG4gICAgICAgIGN1cnJlbnRZICs9IDIwO1xuXG4gICAgICAgIC8vID09PSBEQVRPUyBERUwgUFJPVkVFRE9SID09PVxuICAgICAgICBjdXJyZW50WSA9IHRoaXMuYWRkUHJvdmlkZXJJbmZvKGRvYywgZGF0YSwgY3VycmVudFksIG1hcmdpbiwgcGFnZVdpZHRoLCBzZWNvbmRhcnlDb2xvcik7XG4gICAgICAgIGN1cnJlbnRZICs9IDIwO1xuXG4gICAgICAgIC8vID09PSBERVRBTExFUyBERUwgU0VSVklDSU8gPT09XG4gICAgICAgIGN1cnJlbnRZID0gdGhpcy5hZGRTZXJ2aWNlRGV0YWlscyhkb2MsIGRhdGEsIGN1cnJlbnRZLCBtYXJnaW4sIHBhZ2VXaWR0aCwgc2Vjb25kYXJ5Q29sb3IpO1xuICAgICAgICBjdXJyZW50WSArPSAyMDtcblxuICAgICAgICAvLyA9PT0gQVVUT1JJWkFDScOTTiA9PT1cbiAgICAgICAgY3VycmVudFkgPSB0aGlzLmFkZEF1dGhvcml6YXRpb24oZG9jLCBkYXRhLCBjdXJyZW50WSwgbWFyZ2luLCBwYWdlV2lkdGgpO1xuICAgICAgICBjdXJyZW50WSArPSAzMDtcblxuICAgICAgICAvLyA9PT0gUElFIERFIFDDgUdJTkEgPT09XG4gICAgICAgIHRoaXMuYWRkRm9vdGVyKGRvYywgZGF0YSwgcGFnZUhlaWdodCAtIDgwLCBwYWdlV2lkdGgsIHByaW1hcnlDb2xvcik7XG5cbiAgICAgICAgLy8gPT09IEdFTkVSQVIvREVTQ0FSR0FSID09PVxuICAgICAgICBpZiAob3B0cy5kb3dubG9hZCkge1xuICAgICAgICAgIGRvYy5vdXRwdXQoJ2RhdGF1cmxuZXd3aW5kb3cnLCB7IGZpbGVuYW1lOiBvcHRzLmZpbGVuYW1lIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzb2x2ZShkb2MpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkSGVhZGVyKGRvYzoganNQREYsIGRhdGE6IFdvcmtPcmRlckRhdGEsIG1hcmdpbjogbnVtYmVyLCB5OiBudW1iZXIsIHBhZ2VXaWR0aDogbnVtYmVyLCBjb2xvcjogbnVtYmVyW10pOiB2b2lkIHtcbiAgICAvLyBGb25kbyBkZWwgZW5jYWJlemFkb1xuICAgIGRvYy5zZXRGaWxsQ29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG4gICAgZG9jLnJlY3QobWFyZ2luLCB5LCBwYWdlV2lkdGggLSAobWFyZ2luICogMiksIDgwLCAnRicpO1xuXG4gICAgLy8gVGV4dG8gZGVsIGVuY2FiZXphZG8gZW4gYmxhbmNvXG4gICAgZG9jLnNldFRleHRDb2xvcigyNTUsIDI1NSwgMjU1KTtcbiAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcbiAgICBkb2Muc2V0Rm9udFNpemUoMTgpO1xuICAgIFxuICAgIGNvbnN0IGNvbXBhbnlOYW1lID0gKGRhdGEubmFtZSB8fCAnJykudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBuYW1lV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGNvbXBhbnlOYW1lKTtcbiAgICBkb2MudGV4dChjb21wYW55TmFtZSwgKHBhZ2VXaWR0aCAtIG5hbWVXaWR0aCkgLyAyLCB5ICsgMjUpO1xuXG4gICAgZG9jLnNldEZvbnRTaXplKDEyKTtcbiAgICBjb25zdCBuaXRUZXh0ID0gYE5JVDogJHtkYXRhLm5pdCB8fCAnJ31gO1xuICAgIGNvbnN0IG5pdFdpZHRoID0gZG9jLmdldFRleHRXaWR0aChuaXRUZXh0KTtcbiAgICBkb2MudGV4dChuaXRUZXh0LCAocGFnZVdpZHRoIC0gbml0V2lkdGgpIC8gMiwgeSArIDQ1KTtcblxuICAgIGRvYy5zZXRGb250U2l6ZSgxMCk7XG4gICAgY29uc3QgYWRkcmVzc1RleHQgPSBgJHtkYXRhLmFkZHJlc3MgfHwgJyd9IC0gVEVMOiAke2RhdGEudGVsZXBob25lIHx8ICcnfWA7XG4gICAgY29uc3QgYWRkcmVzc1dpZHRoID0gZG9jLmdldFRleHRXaWR0aChhZGRyZXNzVGV4dCk7XG4gICAgZG9jLnRleHQoYWRkcmVzc1RleHQsIChwYWdlV2lkdGggLSBhZGRyZXNzV2lkdGgpIC8gMiwgeSArIDY1KTtcblxuICAgIC8vIFJlc2V0ZWFyIGNvbG9yIGRlIHRleHRvXG4gICAgZG9jLnNldFRleHRDb2xvcigwLCAwLCAwKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRG9jdW1lbnRUaXRsZShkb2M6IGpzUERGLCBkYXRhOiBXb3JrT3JkZXJEYXRhLCB5OiBudW1iZXIsIHBhZ2VXaWR0aDogbnVtYmVyLCBjb2xvcjogbnVtYmVyW10pOiBudW1iZXIge1xuICAgIGRvYy5zZXRUZXh0Q29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XG4gICAgZG9jLnNldEZvbnRTaXplKDIwKTtcbiAgICBcbiAgICBjb25zdCB0aXRsZSA9ICdPUkRFTiBERSBUUkFCQUpPJztcbiAgICBjb25zdCB0aXRsZVdpZHRoID0gZG9jLmdldFRleHRXaWR0aCh0aXRsZSk7XG4gICAgZG9jLnRleHQodGl0bGUsIChwYWdlV2lkdGggLSB0aXRsZVdpZHRoKSAvIDIsIHkpO1xuXG4gICAgZG9jLnNldEZvbnRTaXplKDE2KTtcbiAgICBjb25zdCBudW1iZXJUZXh0ID0gYE7CsCAke2RhdGEuY29uc2VjdXRpdmUgfHwgJyd9YDtcbiAgICBjb25zdCBudW1iZXJXaWR0aCA9IGRvYy5nZXRUZXh0V2lkdGgobnVtYmVyVGV4dCk7XG4gICAgZG9jLnRleHQobnVtYmVyVGV4dCwgKHBhZ2VXaWR0aCAtIG51bWJlcldpZHRoKSAvIDIsIHkgKyAyNSk7XG5cbiAgICBkb2Muc2V0VGV4dENvbG9yKDAsIDAsIDApO1xuICAgIHJldHVybiB5ICsgNDA7XG4gIH1cblxuICBwcml2YXRlIGFkZE1haW5JbmZvKGRvYzoganNQREYsIGRhdGE6IFdvcmtPcmRlckRhdGEsIHk6IG51bWJlciwgbWFyZ2luOiBudW1iZXIsIHBhZ2VXaWR0aDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCB0YWJsZURhdGEgPSBbXG4gICAgICBbXG4gICAgICAgIHsgY29udGVudDogJ8OBcmVhOicsIHN0eWxlczogeyBmb250U3R5bGU6ICdib2xkJywgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEuYXJlYSB8fCAnJywgc3R5bGVzOiB7fSB9LFxuICAgICAgICB7IGNvbnRlbnQ6ICdDw7NkaWdvOicsIHN0eWxlczogeyBmb250U3R5bGU6ICdib2xkJywgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEuY29kZSB8fCAnJywgc3R5bGVzOiB7fSB9LFxuICAgICAgICB7IGNvbnRlbnQ6ICdGZWNoYTonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZpbGxDb2xvcjogWzI0MCwgMjQwLCAyNDBdIH0gfSxcbiAgICAgICAgeyBjb250ZW50OiBkYXRhLmRhdGUgfHwgJycsIHN0eWxlczoge30gfVxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgeyBjb250ZW50OiAnT3BlcmFyaW86Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXG4gICAgICAgIHsgY29udGVudDogZGF0YS5yZXNwb25zaWJsZSB8fCAnJywgc3R5bGVzOiB7fSB9LFxuICAgICAgICB7IGNvbnRlbnQ6ICdPZMOzbWV0cm86Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXG4gICAgICAgIHsgY29udGVudDogZGF0YS5vZG9tZXRlciB8fCAnJywgc3R5bGVzOiB7fSB9LFxuICAgICAgICB7IGNvbnRlbnQ6ICdSZWYuIEZhY3R1cmE6Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXG4gICAgICAgIHsgY29udGVudDogZGF0YS5pbnZvaWNlUmVmZXJlbmNlIHx8ICctJywgc3R5bGVzOiB7fSB9XG4gICAgICBdXG4gICAgXTtcblxuICAgIChkb2MgYXMgYW55KS5hdXRvVGFibGUoe1xuICAgICAgc3RhcnRZOiB5LFxuICAgICAgYm9keTogdGFibGVEYXRhLFxuICAgICAgdGhlbWU6ICdncmlkJyxcbiAgICAgIHN0eWxlczoge1xuICAgICAgICBmb250U2l6ZTogMTEsXG4gICAgICAgIGNlbGxQYWRkaW5nOiA4LFxuICAgICAgICBsaW5lQ29sb3I6IFsyMDAsIDIwMCwgMjAwXSxcbiAgICAgICAgbGluZVdpZHRoOiAwLjVcbiAgICAgIH0sXG4gICAgICBjb2x1bW5TdHlsZXM6IHtcbiAgICAgICAgMDogeyBjZWxsV2lkdGg6IDcwIH0sXG4gICAgICAgIDE6IHsgY2VsbFdpZHRoOiAxMDAgfSxcbiAgICAgICAgMjogeyBjZWxsV2lkdGg6IDcwIH0sXG4gICAgICAgIDM6IHsgY2VsbFdpZHRoOiA4MCB9LFxuICAgICAgICA0OiB7IGNlbGxXaWR0aDogNzAgfSxcbiAgICAgICAgNTogeyBjZWxsV2lkdGg6IDgwIH1cbiAgICAgIH0sXG4gICAgICBtYXJnaW46IHsgbGVmdDogbWFyZ2luLCByaWdodDogbWFyZ2luIH1cbiAgICB9KTtcblxuICAgIHJldHVybiAoZG9jIGFzIGFueSkubGFzdEF1dG9UYWJsZS5maW5hbFk7XG4gIH1cblxuICBwcml2YXRlIGFkZFByb3ZpZGVySW5mbyhkb2M6IGpzUERGLCBkYXRhOiBXb3JrT3JkZXJEYXRhLCB5OiBudW1iZXIsIG1hcmdpbjogbnVtYmVyLCBwYWdlV2lkdGg6IG51bWJlciwgY29sb3I6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICAvLyBUw610dWxvIGRlIHNlY2Npw7NuXG4gICAgZG9jLnNldFRleHRDb2xvcihjb2xvclswXSwgY29sb3JbMV0sIGNvbG9yWzJdKTtcbiAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcbiAgICBkb2Muc2V0Rm9udFNpemUoMTQpO1xuICAgIGNvbnN0IHRpdGxlID0gJ0RBVE9TIERFTCBQUk9WRUVET1InO1xuICAgIGNvbnN0IHRpdGxlV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKHRpdGxlKTtcbiAgICBkb2MudGV4dCh0aXRsZSwgKHBhZ2VXaWR0aCAtIHRpdGxlV2lkdGgpIC8gMiwgeSk7XG4gICAgZG9jLnNldFRleHRDb2xvcigwLCAwLCAwKTtcblxuICAgIGNvbnN0IHRhYmxlRGF0YSA9IFtcbiAgICAgIFtcbiAgICAgICAgeyBjb250ZW50OiAnTm9tYnJlOicsIHN0eWxlczogeyBmb250U3R5bGU6ICdib2xkJywgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEubmFtZVByb3ZpZGVyIHx8ICcnLCBzdHlsZXM6IHt9IH0sXG4gICAgICAgIHsgY29udGVudDogJ0RpcmVjY2nDs246Jywgc3R5bGVzOiB7IGZvbnRTdHlsZTogJ2JvbGQnLCBmaWxsQ29sb3I6IFsyNDAsIDI0MCwgMjQwXSB9IH0sXG4gICAgICAgIHsgY29udGVudDogZGF0YS5hZGRyZXNzUHJvdmlkZXIgfHwgJycsIHN0eWxlczoge30gfVxuICAgICAgXVxuICAgIF07XG5cbiAgICAoZG9jIGFzIGFueSkuYXV0b1RhYmxlKHtcbiAgICAgIHN0YXJ0WTogeSArIDIwLFxuICAgICAgYm9keTogdGFibGVEYXRhLFxuICAgICAgdGhlbWU6ICdncmlkJyxcbiAgICAgIHN0eWxlczoge1xuICAgICAgICBmb250U2l6ZTogMTEsXG4gICAgICAgIGNlbGxQYWRkaW5nOiA4LFxuICAgICAgICBsaW5lQ29sb3I6IFsyMDAsIDIwMCwgMjAwXSxcbiAgICAgICAgbGluZVdpZHRoOiAwLjVcbiAgICAgIH0sXG4gICAgICBjb2x1bW5TdHlsZXM6IHtcbiAgICAgICAgMDogeyBjZWxsV2lkdGg6IDgwIH0sXG4gICAgICAgIDE6IHsgY2VsbFdpZHRoOiAxNjAgfSxcbiAgICAgICAgMjogeyBjZWxsV2lkdGg6IDgwIH0sXG4gICAgICAgIDM6IHsgY2VsbFdpZHRoOiAxNTAgfVxuICAgICAgfSxcbiAgICAgIG1hcmdpbjogeyBsZWZ0OiBtYXJnaW4sIHJpZ2h0OiBtYXJnaW4gfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIChkb2MgYXMgYW55KS5sYXN0QXV0b1RhYmxlLmZpbmFsWTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkU2VydmljZURldGFpbHMoZG9jOiBqc1BERiwgZGF0YTogV29ya09yZGVyRGF0YSwgeTogbnVtYmVyLCBtYXJnaW46IG51bWJlciwgcGFnZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgLy8gVMOtdHVsbyBkZSBzZWNjacOzblxuICAgIGRvYy5zZXRUZXh0Q29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XG4gICAgZG9jLnNldEZvbnRTaXplKDE0KTtcbiAgICBjb25zdCB0aXRsZSA9ICdERVRBTExFUyBERUwgU0VSVklDSU8nO1xuICAgIGNvbnN0IHRpdGxlV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKHRpdGxlKTtcbiAgICBkb2MudGV4dCh0aXRsZSwgKHBhZ2VXaWR0aCAtIHRpdGxlV2lkdGgpIC8gMiwgeSk7XG4gICAgZG9jLnNldFRleHRDb2xvcigwLCAwLCAwKTtcblxuICAgIC8vIFByZXBhcmFyIHRleHRvIHBhcmEgY2FsY3VsYXIgYWx0dXJhIG5lY2VzYXJpYVxuICAgIGNvbnN0IGJveFkgPSB5ICsgMjA7XG4gICAgY29uc3QgYm94V2lkdGggPSBwYWdlV2lkdGggLSAobWFyZ2luICogMik7XG4gICAgY29uc3QgdGV4dE1hcmdpbiA9IG1hcmdpbiArIDE1O1xuICAgIGNvbnN0IG1heFdpZHRoID0gYm94V2lkdGggLSAzMDtcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gMTU7XG4gICAgY29uc3QgbWluQm94SGVpZ2h0ID0gNjA7IC8vIEFsdHVyYSBtw61uaW1hIGRlbCBjb250ZW5lZG9yXG4gICAgY29uc3QgcGFkZGluZyA9IDQwOyAvLyBQYWRkaW5nIHN1cGVyaW9yIGUgaW5mZXJpb3IgKDIwIGFycmliYSArIDIwIGFiYWpvKVxuXG4gICAgLy8gQ2FsY3VsYXIgbMOtbmVhcyBkZSB0ZXh0byBuZWNlc2FyaWFzXG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdub3JtYWwnKTtcbiAgICBkb2Muc2V0Rm9udFNpemUoMTEpO1xuICAgIFxuICAgIGxldCB0b3RhbExpbmVzID0gMDtcbiAgICBsZXQgY3VycmVudFRleHRZID0gMjA7IC8vIFBvc2ljacOzbiByZWxhdGl2YSBkZW50cm8gZGVsIGJveFxuXG4gICAgaWYgKGRhdGEuZGVzY3JpcHRpb24gJiYgZGF0YS5kZXNjcmlwdGlvbi50cmltKCkpIHtcbiAgICAgIGNvbnN0IGRlc2NMaW5lcyA9IGRvYy5zcGxpdFRleHRUb1NpemUoZGF0YS5kZXNjcmlwdGlvbi50cmltKCksIG1heFdpZHRoKTtcbiAgICAgIHRvdGFsTGluZXMgKz0gZGVzY0xpbmVzLmxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBDYWxjdWxhciBhbHR1cmEgbmVjZXNhcmlhIGJhc2FkYSBlbiBlbCBjb250ZW5pZG9cbiAgICBjb25zdCBjb250ZW50SGVpZ2h0ID0gTWF0aC5tYXgodG90YWxMaW5lcyAqIGxpbmVIZWlnaHQsIDMwKTsgLy8gTcOtbmltbyAzMHB0IHBhcmEgY29udGVuaWRvXG4gICAgY29uc3QgYm94SGVpZ2h0ID0gTWF0aC5tYXgobWluQm94SGVpZ2h0LCBjb250ZW50SGVpZ2h0ICsgcGFkZGluZyk7XG5cbiAgICAvLyBWZXJpZmljYXIgc2kgbmVjZXNpdGFtb3MgdW5hIG51ZXZhIHDDoWdpbmFcbiAgICBjb25zdCBwYWdlSGVpZ2h0ID0gZG9jLmludGVybmFsLnBhZ2VTaXplLmdldEhlaWdodCgpO1xuICAgIGNvbnN0IHJlbWFpbmluZ1NwYWNlID0gcGFnZUhlaWdodCAtIGJveFkgLSAxMDA7IC8vIERlamFyIGVzcGFjaW8gcGFyYSBmb290ZXJcbiAgICBcbiAgICBsZXQgZmluYWxCb3hZID0gYm94WTtcbiAgICBpZiAoYm94SGVpZ2h0ID4gcmVtYWluaW5nU3BhY2UpIHtcbiAgICAgIC8vIEHDsWFkaXIgbnVldmEgcMOhZ2luYVxuICAgICAgZG9jLmFkZFBhZ2UoKTtcbiAgICAgIGZpbmFsQm94WSA9IG1hcmdpbiArIDQwOyAvLyBQb3NpY2nDs24gZW4gbnVldmEgcMOhZ2luYVxuICAgIH1cblxuICAgIC8vIERpYnVqYXIgY29udGVuZWRvciBjb24gYWx0dXJhIGRpbsOhbWljYVxuICAgIC8vIEZvbmRvIGdyaXMgY2xhcm9cbiAgICBkb2Muc2V0RmlsbENvbG9yKDI1MCwgMjUwLCAyNTApO1xuICAgIGRvYy5yZWN0KG1hcmdpbiwgZmluYWxCb3hZLCBib3hXaWR0aCwgYm94SGVpZ2h0LCAnRicpO1xuICAgIFxuICAgIC8vIEJvcmRlXG4gICAgZG9jLnNldERyYXdDb2xvcigyMDAsIDIwMCwgMjAwKTtcbiAgICBkb2MucmVjdChtYXJnaW4sIGZpbmFsQm94WSwgYm94V2lkdGgsIGJveEhlaWdodCwgJ1MnKTtcblxuICAgIC8vIEHDsWFkaXIgY29udGVuaWRvIGRlIHRleHRvXG4gICAgbGV0IHRleHRZID0gZmluYWxCb3hZICsgMjA7XG5cbiAgICBpZiAoZGF0YS5kZXNjcmlwdGlvbiAmJiBkYXRhLmRlc2NyaXB0aW9uLnRyaW0oKSkge1xuICAgICAgY29uc3QgZGVzY0xpbmVzID0gZG9jLnNwbGl0VGV4dFRvU2l6ZShkYXRhLmRlc2NyaXB0aW9uLnRyaW0oKSwgbWF4V2lkdGgpO1xuICAgICAgXG4gICAgICAvLyBTaSBoYXkgbXVjaGFzIGzDrW5lYXMsIHZlcmlmaWNhciBxdWUgcXVlcGFuIGVuIGxhIHDDoWdpbmEgYWN0dWFsXG4gICAgICBjb25zdCByZXF1aXJlZEhlaWdodCA9IGRlc2NMaW5lcy5sZW5ndGggKiBsaW5lSGVpZ2h0ICsgNDA7XG4gICAgICBpZiAodGV4dFkgKyByZXF1aXJlZEhlaWdodCA+IHBhZ2VIZWlnaHQgLSA2MCkge1xuICAgICAgICAvLyBFbCBjb250ZW5pZG8gZXMgbXV5IGxhcmdvLCBkaXZpZGlyIHNpIGVzIG5lY2VzYXJpb1xuICAgICAgICBjb25zdCBtYXhMaW5lc1BlclBhZ2UgPSBNYXRoLmZsb29yKChwYWdlSGVpZ2h0IC0gdGV4dFkgLSA2MCkgLyBsaW5lSGVpZ2h0KTtcbiAgICAgICAgXG4gICAgICAgIGlmIChkZXNjTGluZXMubGVuZ3RoID4gbWF4TGluZXNQZXJQYWdlICYmIG1heExpbmVzUGVyUGFnZSA+IDApIHtcbiAgICAgICAgICAvLyBNb3N0cmFyIGzDrW5lYXMgcXVlIGNhYmVuIGVuIGxhIHDDoWdpbmEgYWN0dWFsXG4gICAgICAgICAgY29uc3QgY3VycmVudFBhZ2VMaW5lcyA9IGRlc2NMaW5lcy5zbGljZSgwLCBtYXhMaW5lc1BlclBhZ2UpO1xuICAgICAgICAgIGRvYy50ZXh0KGN1cnJlbnRQYWdlTGluZXMsIHRleHRNYXJnaW4sIHRleHRZKTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBDb250aW51YXIgZW4gbnVldmEgcMOhZ2luYSBzaSBoYXkgbcOhcyBjb250ZW5pZG9cbiAgICAgICAgICBpZiAoZGVzY0xpbmVzLmxlbmd0aCA+IG1heExpbmVzUGVyUGFnZSkge1xuICAgICAgICAgICAgZG9jLmFkZFBhZ2UoKTtcbiAgICAgICAgICAgIHRleHRZID0gbWFyZ2luICsgMjA7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdMaW5lcyA9IGRlc2NMaW5lcy5zbGljZShtYXhMaW5lc1BlclBhZ2UpO1xuICAgICAgICAgICAgZG9jLnRleHQocmVtYWluaW5nTGluZXMsIHRleHRNYXJnaW4sIHRleHRZKTtcbiAgICAgICAgICAgIHJldHVybiB0ZXh0WSArIChyZW1haW5pbmdMaW5lcy5sZW5ndGggKiBsaW5lSGVpZ2h0KSArIDIwO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb2MudGV4dChkZXNjTGluZXMsIHRleHRNYXJnaW4sIHRleHRZKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9jLnRleHQoZGVzY0xpbmVzLCB0ZXh0TWFyZ2luLCB0ZXh0WSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHRleHRZICs9IGRlc2NMaW5lcy5sZW5ndGggKiBsaW5lSGVpZ2h0O1xuICAgIH1cblxuICAgIC8vIFNpIG5vIGhheSBkZXNjcmlwY2nDs24sIG1vc3RyYXIgdW4gbWVuc2FqZVxuICAgIGlmICghZGF0YS5kZXNjcmlwdGlvbiB8fCAhZGF0YS5kZXNjcmlwdGlvbi50cmltKCkpIHtcbiAgICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnLCAnaXRhbGljJyk7XG4gICAgICBkb2Muc2V0Rm9udFNpemUoMTApO1xuICAgICAgZG9jLnNldFRleHRDb2xvcigxNTAsIDE1MCwgMTUwKTtcbiAgICAgIGRvYy50ZXh0KCdObyBzZSBoYW4gZXNwZWNpZmljYWRvIGRldGFsbGVzIGRlbCBzZXJ2aWNpby4nLCB0ZXh0TWFyZ2luLCB0ZXh0WSk7XG4gICAgICBkb2Muc2V0VGV4dENvbG9yKDAsIDAsIDApO1xuICAgICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdub3JtYWwnKTtcbiAgICAgIGRvYy5zZXRGb250U2l6ZSgxMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbmFsQm94WSArIGJveEhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNw6l0b2RvIGF1eGlsaWFyIHBhcmEgbWFuZWphciB0ZXh0byBsYXJnbyBxdWUgcHVlZGUgbmVjZXNpdGFyIG3Dumx0aXBsZXMgcMOhZ2luYXNcbiAgICovXG4gIHByaXZhdGUgYWRkTG9uZ1RleHQoZG9jOiBqc1BERiwgdGV4dDogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlciwgbWF4V2lkdGg6IG51bWJlciwgZm9udFNpemU6IG51bWJlciA9IDExKTogbnVtYmVyIHtcbiAgICBpZiAoIXRleHQgfHwgIXRleHQudHJpbSgpKSByZXR1cm4geTtcblxuICAgIGRvYy5zZXRGb250U2l6ZShmb250U2l6ZSk7XG4gICAgY29uc3QgbGluZXMgPSBkb2Muc3BsaXRUZXh0VG9TaXplKHRleHQudHJpbSgpLCBtYXhXaWR0aCk7XG4gICAgY29uc3QgbGluZUhlaWdodCA9IGZvbnRTaXplICsgMztcbiAgICBjb25zdCBwYWdlSGVpZ2h0ID0gZG9jLmludGVybmFsLnBhZ2VTaXplLmdldEhlaWdodCgpO1xuICAgIGNvbnN0IG1hcmdpbiA9IDQwO1xuXG4gICAgbGV0IGN1cnJlbnRZID0geTtcbiAgICBsZXQgbGluZUluZGV4ID0gMDtcblxuICAgIHdoaWxlIChsaW5lSW5kZXggPCBsaW5lcy5sZW5ndGgpIHtcbiAgICAgIC8vIFZlcmlmaWNhciBzaSBuZWNlc2l0YW1vcyB1bmEgbnVldmEgcMOhZ2luYVxuICAgICAgaWYgKGN1cnJlbnRZICsgbGluZUhlaWdodCA+IHBhZ2VIZWlnaHQgLSBtYXJnaW4pIHtcbiAgICAgICAgZG9jLmFkZFBhZ2UoKTtcbiAgICAgICAgY3VycmVudFkgPSBtYXJnaW47XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGN1bGFyIGN1w6FudGFzIGzDrW5lYXMgY2FiZW4gZW4gbGEgcMOhZ2luYSBhY3R1YWxcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1NwYWNlID0gcGFnZUhlaWdodCAtIGN1cnJlbnRZIC0gbWFyZ2luO1xuICAgICAgY29uc3QgbWF4TGluZXNJblBhZ2UgPSBNYXRoLmZsb29yKHJlbWFpbmluZ1NwYWNlIC8gbGluZUhlaWdodCk7XG4gICAgICBcbiAgICAgIGlmIChtYXhMaW5lc0luUGFnZSA+IDApIHtcbiAgICAgICAgY29uc3QgbGluZXNUb1Nob3cgPSBNYXRoLm1pbihtYXhMaW5lc0luUGFnZSwgbGluZXMubGVuZ3RoIC0gbGluZUluZGV4KTtcbiAgICAgICAgY29uc3QgcGFnZUxpbmVzID0gbGluZXMuc2xpY2UobGluZUluZGV4LCBsaW5lSW5kZXggKyBsaW5lc1RvU2hvdyk7XG4gICAgICAgIFxuICAgICAgICBkb2MudGV4dChwYWdlTGluZXMsIHgsIGN1cnJlbnRZKTtcbiAgICAgICAgY3VycmVudFkgKz0gcGFnZUxpbmVzLmxlbmd0aCAqIGxpbmVIZWlnaHQ7XG4gICAgICAgIGxpbmVJbmRleCArPSBsaW5lc1RvU2hvdztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFNpIG5vIGNhYmUgbmkgdW5hIGzDrW5lYSwgaXIgYSBudWV2YSBww6FnaW5hXG4gICAgICAgIGRvYy5hZGRQYWdlKCk7XG4gICAgICAgIGN1cnJlbnRZID0gbWFyZ2luO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50WTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQXV0aG9yaXphdGlvbihkb2M6IGpzUERGLCBkYXRhOiBXb3JrT3JkZXJEYXRhLCB5OiBudW1iZXIsIG1hcmdpbjogbnVtYmVyLCBwYWdlV2lkdGg6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgdGFibGVEYXRhID0gW1xuICAgICAgW1xuICAgICAgICB7IGNvbnRlbnQ6ICdBVVRPUklaQURBIFBPUjonLCBzdHlsZXM6IHsgZm9udFN0eWxlOiAnYm9sZCcsIGZvbnRTaXplOiAxMiwgZmlsbENvbG9yOiBbMjQwLCAyNDAsIDI0MF0gfSB9LFxuICAgICAgICB7IGNvbnRlbnQ6IGRhdGEuYXBwcm92ZWRfYnkgfHwgJycsIHN0eWxlczogeyBmb250U2l6ZTogMTIgfSB9XG4gICAgICBdXG4gICAgXTtcblxuICAgIChkb2MgYXMgYW55KS5hdXRvVGFibGUoe1xuICAgICAgc3RhcnRZOiB5LFxuICAgICAgYm9keTogdGFibGVEYXRhLFxuICAgICAgdGhlbWU6ICdncmlkJyxcbiAgICAgIHN0eWxlczoge1xuICAgICAgICBjZWxsUGFkZGluZzogMTIsXG4gICAgICAgIGxpbmVDb2xvcjogWzIwMCwgMjAwLCAyMDBdLFxuICAgICAgICBsaW5lV2lkdGg6IDAuNVxuICAgICAgfSxcbiAgICAgIGNvbHVtblN0eWxlczoge1xuICAgICAgICAwOiB7IGNlbGxXaWR0aDogMTUwIH0sXG4gICAgICAgIDE6IHsgY2VsbFdpZHRoOiAzMjAgfVxuICAgICAgfSxcbiAgICAgIG1hcmdpbjogeyBsZWZ0OiBtYXJnaW4sIHJpZ2h0OiBtYXJnaW4gfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIChkb2MgYXMgYW55KS5sYXN0QXV0b1RhYmxlLmZpbmFsWTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRm9vdGVyKGRvYzoganNQREYsIGRhdGE6IFdvcmtPcmRlckRhdGEsIHk6IG51bWJlciwgcGFnZVdpZHRoOiBudW1iZXIsIGNvbG9yOiBudW1iZXJbXSk6IHZvaWQge1xuICAgIC8vIEZvbmRvIGRlbCBwaWUgZGUgcMOhZ2luYVxuICAgIGRvYy5zZXRGaWxsQ29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG4gICAgZG9jLnJlY3QoNDAsIHksIHBhZ2VXaWR0aCAtIDgwLCA2MCwgJ0YnKTtcblxuICAgIC8vIFRleHRvIGVuIGJsYW5jb1xuICAgIGRvYy5zZXRUZXh0Q29sb3IoMjU1LCAyNTUsIDI1NSk7XG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XG4gICAgZG9jLnNldEZvbnRTaXplKDEyKTtcbiAgICBcbiAgICBjb25zdCBpbnN0cnVjdGlvbiA9ICdGYXZvciBhZGp1bnRhciBsYSBvcmRlbiBhIGxhIGZhY3R1cmEgbyBjdWVudGEgZGUgY29icm8nO1xuICAgIGNvbnN0IGluc3RXaWR0aCA9IGRvYy5nZXRUZXh0V2lkdGgoaW5zdHJ1Y3Rpb24pO1xuICAgIGRvYy50ZXh0KGluc3RydWN0aW9uLCAocGFnZVdpZHRoIC0gaW5zdFdpZHRoKSAvIDIsIHkgKyAyNSk7XG5cbiAgICBkb2Muc2V0Rm9udFNpemUoMTApO1xuICAgIGNvbnN0IGVtYWlsV2lkdGggPSBkb2MuZ2V0VGV4dFdpZHRoKGRhdGEubWFpbCB8fCAnJyk7XG4gICAgZG9jLnRleHQoZGF0YS5tYWlsIHx8ICcnLCAocGFnZVdpZHRoIC0gZW1haWxXaWR0aCkgLyAyLCB5ICsgNDUpO1xuXG4gICAgLy8gUmVzZXRlYXIgY29sb3JcbiAgICBkb2Muc2V0VGV4dENvbG9yKDAsIDAsIDApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYSBQREYgb3B0aW1pemFkbyBwYXJhIGltcHJlc2nDs25cbiAgICovXG4gIGdlbmVyYXRlRm9yUHJpbnQoZGF0YTogV29ya09yZGVyRGF0YSk6IFByb21pc2U8anNQREY+IHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZVdvcmtPcmRlclBERihkYXRhLCB7XG4gICAgICBmb3JtYXQ6ICdsZXR0ZXInLFxuICAgICAgZG93bmxvYWQ6IGZhbHNlXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhIFBERiB5IGxvIGRldnVlbHZlIGNvbW8gQmxvYiBwYXJhIGVudsOtbyBwb3IgZW1haWxcbiAgICovXG4gIGdlbmVyYXRlQXNCbG9iKGRhdGE6IFdvcmtPcmRlckRhdGEpOiBQcm9taXNlPEJsb2I+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZVdvcmtPcmRlclBERihkYXRhLCB7IGRvd25sb2FkOiBmYWxzZSB9KVxuICAgICAgICAudGhlbihkb2MgPT4ge1xuICAgICAgICAgIGNvbnN0IHBkZkJsb2IgPSBkb2Mub3V0cHV0KCdibG9iJyk7XG4gICAgICAgICAgcmVzb2x2ZShwZGZCbG9iKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhIFBERiB5IGxvIGRldnVlbHZlIGNvbW8gYmFzZTY0XG4gICAqL1xuICBnZW5lcmF0ZUFzQmFzZTY0KGRhdGE6IFdvcmtPcmRlckRhdGEpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdlbmVyYXRlV29ya09yZGVyUERGKGRhdGEsIHsgZG93bmxvYWQ6IGZhbHNlIH0pXG4gICAgICAgIC50aGVuKGRvYyA9PiB7XG4gICAgICAgICAgY29uc3QgYmFzZTY0ID0gZG9jLm91dHB1dCgnZGF0YXVyaXN0cmluZycpO1xuICAgICAgICAgIHJlc29sdmUoYmFzZTY0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKHJlamVjdCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==