sequenceserver 3.1.2 → 3.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sequenceserver/blast/tasks.rb +1 -1
  3. data/lib/sequenceserver/routes.rb +1 -1
  4. data/lib/sequenceserver/version.rb +1 -1
  5. data/lib/sequenceserver.rb +1 -1
  6. data/public/css/app.min.css +1 -1
  7. data/public/css/sequenceserver.css +0 -18
  8. data/public/css/sequenceserver.min.css +2 -2
  9. data/public/js/alignment_exporter.js +16 -28
  10. data/public/js/cloud_share_modal.js +42 -42
  11. data/public/js/form.js +12 -10
  12. data/public/js/grapher.js +4 -4
  13. data/public/js/hit.js +3 -3
  14. data/public/js/hits.js +276 -0
  15. data/public/js/jquery_world.js +1 -1
  16. data/public/js/mailto.js +1 -3
  17. data/public/js/null_plugins/report_plugins.js +1 -0
  18. data/public/js/options.js +2 -6
  19. data/public/js/query.js +1 -1
  20. data/public/js/report.js +68 -252
  21. data/public/js/report_root.js +7 -5
  22. data/public/js/search.js +28 -11
  23. data/public/js/sequence.js +158 -158
  24. data/public/js/sequence_modal.js +28 -36
  25. data/public/js/sidebar.js +7 -6
  26. data/public/js/tests/alignment_exporter.spec.js +38 -0
  27. data/public/js/tests/cloud_share_modal.spec.js +75 -0
  28. data/public/js/tests/report.spec.js +37 -15
  29. data/public/packages/jquery-ui@1.13.3.js +19070 -0
  30. data/public/sequenceserver-report.min.js +3 -2481
  31. data/public/sequenceserver-report.min.js.LICENSE.txt +300 -0
  32. data/public/sequenceserver-report.min.js.map +1 -0
  33. data/public/sequenceserver-search.min.js +3 -2382
  34. data/public/sequenceserver-search.min.js.LICENSE.txt +292 -0
  35. data/public/sequenceserver-search.min.js.map +1 -0
  36. data/views/layout.erb +3 -7
  37. data/views/search.erb +1 -1
  38. data/views/search_layout.erb +1 -1
  39. metadata +11 -5
  40. data/public/config.js +0 -147
  41. data/public/packages/jquery-ui@1.11.4.js +0 -16624
@@ -9,78 +9,78 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
9
9
  * THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL
10
10
  * (https://github.com/ljgarcia/biojs-vis-sequence/blob/master/lib/index.js).
11
11
  *
12
- * Sequence component
13
- *
12
+ * Sequence component
13
+ *
14
14
  * @class
15
15
  * @extends Biojs
16
- *
16
+ *
17
17
  * @author <a href="mailto:johncar@gmail.com">John Gomez</a>, <a href="mailto:secevalliv@gmail.com">Jose Villaveces</a>
18
18
  * @version 1.0.0
19
19
  * @category 3
20
- *
20
+ *
21
21
  * @requires <a href='http://blog.jquery.com/2011/09/12/jquery-1-6-4-released/'>jQuery Core 1.6.4</a>
22
22
  * @dependency <script language="JavaScript" type="text/javascript" src="../biojs/dependencies/jquery/jquery-1.4.2.min.js"></script>
23
- *
23
+ *
24
24
  * @requires <a href='http://jqueryui.com/download'>jQuery UI 1.8.16</a>
25
25
  * @dependency <script language="JavaScript" type="text/javascript" src="../biojs/dependencies/jquery/jquery-ui-1.8.2.custom.min.js"></script>
26
26
  *
27
27
  * @requires <a href='Biojs.Tooltip.css'>Biojs.Tooltip</a>
28
28
  * @dependency <script language="JavaScript" type="text/javascript" src="src/Biojs.Tooltip.js"></script>
29
- *
29
+ *
30
30
  * @param {Object} options An object with the options for Sequence component.
31
- *
32
- * @option {string} target
31
+ *
32
+ * @option {string} target
33
33
  * Identifier of the DIV tag where the component should be displayed.
34
- *
35
- * @option {string} sequence
34
+ *
35
+ * @option {string} sequence
36
36
  * The sequence to be displayed.
37
- *
38
- * @option {string} [id]
37
+ *
38
+ * @option {string} [id]
39
39
  * Sequence identifier if apply.
40
- *
41
- * @option {string} [format="FASTA"]
40
+ *
41
+ * @option {string} [format="FASTA"]
42
42
  * The display format for the sequence representation.
43
- *
44
- * @option {Object[]} [highlights]
45
- * For highlighting multiple regions.
46
- * <pre class="brush: js" title="Syntax:">
43
+ *
44
+ * @option {Object[]} [highlights]
45
+ * For highlighting multiple regions.
46
+ * <pre class="brush: js" title="Syntax:">
47
47
  * [
48
48
  * // Highlight aminoacids from 'start' to 'end' of the current strand using the specified 'color' (optional) and 'background' (optional).
49
- * { start: &lt;startVal1&gt;, end: &lt;endVal1&gt; [, id:&lt;idVal1&gt;] [, color: &lt;HTMLColor&gt;] [, background: &lt;HTMLColor&gt;]},
49
+ * { start: &lt;startVal1&gt;, end: &lt;endVal1&gt; [, id:&lt;idVal1&gt;] [, color: &lt;HTMLColor&gt;] [, background: &lt;HTMLColor&gt;]},
50
50
  * //
51
51
  * // Any others highlights
52
- * ...,
53
- * //
52
+ * ...,
53
+ * //
54
54
  * { start: &lt;startValN&gt;, end: &lt;endValN&gt; [, id:&lt;idValN&gt;] [, color: &lt;HTMLColor&gt;] [, background: &lt;HTMLColor&gt;]}
55
55
  * ]</pre>
56
- *
57
- * <pre class="brush: js" title="Example:">
56
+ *
57
+ * <pre class="brush: js" title="Example:">
58
58
  * highlights : [
59
59
  * { start:30, end:42, color:"white", background:"green", id:"spin1" },
60
- * { start:139, end:140 },
60
+ * { start:139, end:140 },
61
61
  * { start:631, end:633, color:"white", background:"blue" }
62
62
  * ]
63
63
  * </pre>
64
- *
65
- * @option {Object} [columns={size:40,spacedEach:10}]
64
+ *
65
+ * @option {Object} [columns={size:40,spacedEach:10}]
66
66
  * Options for displaying the columns. Syntax: { size: &lt;numCols&gt;, spacedEach: &lt;numCols&gt;}
67
- *
68
- * @option {Object} [selection]
67
+ *
68
+ * @option {Object} [selection]
69
69
  * Positions for the current selected region. Syntax: { start: &lt;startValue&gt;, end: &lt;endValue&gt;}
70
- *
71
- * @option {Object[]} [annotations]
70
+ *
71
+ * @option {Object[]} [annotations]
72
72
  * Set of overlapping annotations. Must be an array of objects following the syntax:
73
73
  * <pre class="brush: js" title="Syntax:">
74
- * [
74
+ * [
75
75
  * // An annotation:
76
- * { name: &lt;name&gt;,
77
- * html: &lt;message&gt;,
78
- * color: &lt;color_code&gt;,
79
- * regions: [{ start: &lt;startVal1&gt;, end: &lt;endVal1&gt; color: &lt;HTMLColor&gt;}, ...,{ start: &lt;startValN&gt;, end: &lt;endValN&gt;, color: &lt;HTMLColor&gt;}]
80
- * },
81
- *
76
+ * { name: &lt;name&gt;,
77
+ * html: &lt;message&gt;,
78
+ * color: &lt;color_code&gt;,
79
+ * regions: [{ start: &lt;startVal1&gt;, end: &lt;endVal1&gt; color: &lt;HTMLColor&gt;}, ...,{ start: &lt;startValN&gt;, end: &lt;endValN&gt;, color: &lt;HTMLColor&gt;}]
80
+ * },
81
+ *
82
82
  * // ...
83
- * // more annotations here
83
+ * // more annotations here
84
84
  * // ...
85
85
  * ]
86
86
  * </pre>
@@ -92,19 +92,19 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
92
92
  * <li><b>regions</b> array of objects defining the intervals which belongs to the annotation.</li>
93
93
  * <li><b>regions[i].start</b> is the starting character for the i-th interval.</li>
94
94
  * <li><b>regions[i].end</b> is the ending character for the i-th interval.</li>
95
- * <li><b>regions[i].color</b> is an optional color for the i-th interval.
96
- * </ul>
97
- *
98
- * @option {Object} [formatOptions={title:true, footer:true}]
95
+ * <li><b>regions[i].color</b> is an optional color for the i-th interval.
96
+ * </ul>
97
+ *
98
+ * @option {Object} [formatOptions={title:true, footer:true}]
99
99
  * Options for displaying the title. by now just affecting the CODATA format.
100
- * <pre class="brush: js" title="Syntax:">
100
+ * <pre class="brush: js" title="Syntax:">
101
101
  * formatOptions : {
102
102
  * title:false,
103
103
  * footer:false
104
104
  * }
105
105
  * </pre>
106
- *
107
- * @example
106
+ *
107
+ * @example
108
108
  * var theSequence = "METLCQRLNVCQDKILTHYENDSTDLRDHIDYWKHMRLECAIYYKAREMGFKHINHQVVPTLAVSKNKALQAIELQLTLETIYNSQYSNEKWTLQDVSLEVYLTAPTGCIKKHGYTVEVQFDGDICNTMHYTNWTHIYICEEAojs SVTVVEGQVDYYGLYYVHEGIRTYFVQFKDDAEKYSKNKVWEVHAGGQVILCPTSVFSSNEVSSPEIIRQHLANHPAATHTKAVALGTEETQTTIQRPRSEPDTGNPCHTTKLLHRDSVDSAPILTAFNSSHKGRINCNSNTTPIVHLKGDANTLKCLRYRFKKHCTLYTAVSSTWHWTGHNVKHKSAIVTLTYDSEWQRDQFLSQVKIPKTITVSTGFMSI";
109
109
  * var mySequence = new Sequence({
110
110
  * sequence : theSequence,
@@ -112,14 +112,14 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
112
112
  * format : 'CODATA',
113
113
  * id : 'P918283',
114
114
  * annotations: [
115
- * { name:"CATH",
116
- * color:"#F0F020",
117
- * html: "Using color code #F0F020 ",
115
+ * { name:"CATH",
116
+ * color:"#F0F020",
117
+ * html: "Using color code #F0F020 ",
118
118
  * regions: [{start: 122, end: 135}]
119
119
  * },
120
- * { name:"TEST",
121
- * html:"&lt;br&gt; Example of &lt;b&gt;HTML&lt;/b&gt;",
122
- * color:"green",
120
+ * { name:"TEST",
121
+ * html:"&lt;br&gt; Example of &lt;b&gt;HTML&lt;/b&gt;",
122
+ * color:"green",
123
123
  * regions: [
124
124
  * {start: 285, end: 292},
125
125
  * {start: 293, end: 314, color: "#2E4988"}]
@@ -127,11 +127,11 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
127
127
  * ],
128
128
  * highlights : [
129
129
  * { start:30, end:42, color:"white", background:"green", id:"spin1" },
130
- * { start:139, end:140 },
130
+ * { start:139, end:140 },
131
131
  * { start:631, end:633, color:"white", background:"blue" }
132
132
  * ]
133
- * });
134
- *
133
+ * });
134
+ *
135
135
  */
136
136
 
137
137
  var Class = require('js-class');
@@ -162,8 +162,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
162
162
  // legacy: copy target id
163
163
  this.opt.target = this._container[0].id;
164
164
 
165
- // Lazy initialization
165
+ // Lazy initialization
166
166
  this._container.ready(function () {
167
+ this._ready = false;
167
168
  self._initialize();
168
169
  });
169
170
  },
@@ -184,7 +185,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
184
185
  annotations: [],
185
186
  sequenceUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/sequence',
186
187
 
187
- // Styles
188
+ // Styles
188
189
  selectionColor: 'Yellow',
189
190
  selectionFontColor: 'black',
190
191
  highlightFontColor: 'red',
@@ -209,13 +210,13 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
209
210
  * @eventData {string} type The name of the event.
210
211
  * @eventData {int} start A number indicating the start of the selection.
211
212
  * @eventData {int} end A number indicating the ending of selection.
212
- * @example
213
+ * @example
213
214
  * mySequence.onSelectionChanged(
214
215
  * function( objEvent ) {
215
216
  * alert("Selected: " + objEvent.start + ", " + objEvent.end );
216
217
  * }
217
- * );
218
- *
218
+ * );
219
+ *
219
220
  * */
220
221
  'onSelectionChanged',
221
222
 
@@ -227,14 +228,14 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
227
228
  * @eventData {string} type The name of the event.
228
229
  * @eventData {int} start A number indicating the start of the selection.
229
230
  * @eventData {int} end A number indicating the ending of selection.
230
- * @example
231
+ * @example
231
232
  * mySequence.onSelectionChange(
232
233
  * function( objEvent ) {
233
234
  * alert("Selection in progress: " + objEvent.start + ", " + objEvent.end );
234
235
  * }
235
- * );
236
- *
237
- *
236
+ * );
237
+ *
238
+ *
238
239
  * */
239
240
  'onSelectionChange',
240
241
 
@@ -246,13 +247,13 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
246
247
  * @eventData {string} type The name of the event.
247
248
  * @eventData {string} name The name of the selected annotation.
248
249
  * @eventData {int} pos A number indicating the position of the selected amino acid.
249
- * @example
250
+ * @example
250
251
  * mySequence.onAnnotationClicked(
251
252
  * function( objEvent ) {
252
253
  * alert("Clicked " + objEvent.name + " on position " + objEvent.pos );
253
254
  * }
254
- * );
255
- *
255
+ * );
256
+ *
256
257
  * */
257
258
  'onAnnotationClicked'
258
259
  ],
@@ -283,7 +284,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
283
284
  // DIV for the sequence
284
285
  this._contentDiv = jQuery('<div/>').appendTo(this._container);
285
286
 
286
- // Initialize highlighting
287
+ // Initialize highlighting
287
288
  this._highlights = this.opt.highlights;
288
289
 
289
290
  // Initialize annotations
@@ -315,6 +316,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
315
316
  this.clearSequence('No sequence available', '../biojs/css/images/warning_icon.png');
316
317
  }
317
318
 
319
+ this._ready = true;
318
320
  },
319
321
 
320
322
 
@@ -322,10 +324,10 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
322
324
  * Shows the columns indicated by the indexes array.
323
325
  * @param {string} seq The sequence strand.
324
326
  * @param {string} [identifier] Sequence identifier.
325
- *
326
- * @example
327
+ *
328
+ * @example
327
329
  * mySequence.setSequence("P99999");
328
- *
330
+ *
329
331
  */
330
332
  setSequence: function (seq, identifier) {
331
333
 
@@ -353,23 +355,18 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
353
355
  jQuery.ajax({
354
356
  url: self.opt.sequenceUrl,
355
357
  dataType: 'xml',
356
- data: { segment: accession },
357
- success: function (xml) {
358
- try {
359
-
360
- var sequenceNode = jQuery(xml).find('SEQUENCE:first');
361
- self.setSequence(sequenceNode.text(), sequenceNode.attr('id'), sequenceNode.attr('label'));
362
-
363
- } catch (e) {
364
- console.log('Error decoding response data: ' + e.message);
365
- self.clearSequence('No sequence available', '../biojs/css/images/warning_icon.png');
366
- }
367
-
368
- },
369
- error: function (jqXHR, textStatus, errorThrown) {
370
- console.log('Error decoding response data: ' + textStatus);
371
- self.clearSequence('Error requesting the sequence to the server ' + this.url, '../biojs/css/images/warning_icon.png');
358
+ data: { segment: accession }
359
+ }).done(function(xml) {
360
+ try {
361
+ var sequenceNode = jQuery(xml).find('SEQUENCE:first');
362
+ self.setSequence(sequenceNode.text(), sequenceNode.attr('id'), sequenceNode.attr('label'));
363
+ } catch (e) {
364
+ console.log('Error decoding response data: ' + e.message);
365
+ self.clearSequence('No sequence available', '../biojs/css/images/warning_icon.png');
372
366
  }
367
+ }).fail(function(jqXHR, textStatus, errorThrown) {
368
+ console.log('Error requesting the sequence: ' + textStatus);
369
+ self.clearSequence('Error requesting the sequence to the server ' + this.url, '../biojs/css/images/warning_icon.png');
373
370
  });
374
371
  },
375
372
 
@@ -377,10 +374,10 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
377
374
  * Shows the columns indicated by the indexes array.
378
375
  * @param {string} [showMessage] Message to be showed.
379
376
  * @param {string} [icon] Icon to be showed a side of the message
380
- *
381
- * @example
377
+ *
378
+ * @example
382
379
  * mySequence.clearSequence("No sequence available", "../biojs/css/images/warning_icon.png");
383
- *
380
+ *
384
381
  */
385
382
  clearSequence: function (showMessage, icon) {
386
383
 
@@ -414,9 +411,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
414
411
  * Set the current selection in the sequence causing the event {@link Sequence#onSelectionChanged}
415
412
  *
416
413
  * @example
417
- * // set selection from the position 100 to 150
414
+ * // set selection from the position 100 to 150
418
415
  * mySequence.setSelection(100, 150);
419
- *
416
+ *
420
417
  * @param {int} start The starting character of the selection.
421
418
  * @param {int} end The ending character of the selection
422
419
  */
@@ -440,6 +437,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
440
437
  _buildFormatSelector: function () {
441
438
  var self = this;
442
439
 
440
+ console.log('build format selector container', this._container);
443
441
  this._headerDiv = jQuery('<div></div>').appendTo(this._container);
444
442
  this._headerDiv.append('Format: ');
445
443
 
@@ -465,11 +463,11 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
465
463
  * @example
466
464
  * // highlight the characters within the position 100 to 150, included.
467
465
  * mySequence.addHighlight( { "start": 100, "end": 150, "color": "white", "background": "red", "id": "aaa" } );
468
- *
466
+ *
469
467
  * @param {Object} h The highlight defined as follows:
470
- *
471
- *
472
- * @return {int} representing the id of the highlight on the internal array. Returns -1 on failure
468
+ *
469
+ *
470
+ * @return {int} representing the id of the highlight on the internal array. Returns -1 on failure
473
471
  */
474
472
  addHighlight: function (h) {
475
473
  var id = '-1';
@@ -492,14 +490,17 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
492
490
 
493
491
  return id;
494
492
  },
495
- /*
493
+ /*
496
494
  * Function: Sequence._applyHighlight
497
495
  * Purpose: Apply the specified color and background to a region between 'start' and 'end'.
498
496
  * Returns: -
499
- * Inputs: highlight -> {Object} An object containing the fields start (int), end (int),
497
+ * Inputs: highlight -> {Object} An object containing the fields start (int), end (int),
500
498
  * color (HTML color string) and background (HTML color string).
501
499
  */
502
500
  _applyHighlight: function (highlight) {
501
+ var zindex = 0,
502
+ z = 0,
503
+ o = 0;
503
504
  var seq = this._contentDiv.find('.sequence');
504
505
  for (var i = highlight.start - 1; i < highlight.end; i++) {
505
506
  zindex = jQuery(seq[i]).css('z-index');
@@ -521,7 +522,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
521
522
  .addClass('highlighted');
522
523
  }
523
524
  },
524
- /*
525
+ /*
525
526
  * Function: Sequence._applyHighlights
526
527
  * Purpose: Apply the specified highlights.
527
528
  * Returns: -
@@ -532,7 +533,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
532
533
  this._applyHighlight(highlights[i]);
533
534
  }
534
535
  },
535
- /*
536
+ /*
536
537
  * Function: Sequence._restoreHighlights
537
538
  * Purpose: Repaint the highlights in the specified region.
538
539
  * Returns: -
@@ -563,10 +564,10 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
563
564
  }
564
565
  }
565
566
  },
566
- /*
567
+ /*
567
568
  * Function: Sequence._restoreSelection
568
- * Purpose: Repaint the current selection in the specified region.
569
- * It is used in the case of any highlight do overriding of the current selection.
569
+ * Purpose: Repaint the current selection in the specified region.
570
+ * It is used in the case of any highlight do overriding of the current selection.
570
571
  * Returns: -
571
572
  * Inputs: start -> {int} Start of the region to be restored.
572
573
  * end -> {int} End of the region to be restored.
@@ -594,7 +595,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
594
595
  * @example
595
596
  * // Clear the highlighted characters within the position 100 to 150, included.
596
597
  * mySequence.removeHighlight("spin1");
597
- *
598
+ *
598
599
  * @param {string} id The id of the highlight on the internal array. This value is returned by method highlight.
599
600
  */
600
601
  removeHighlight: function (id) {
@@ -631,7 +632,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
631
632
  * @example
632
633
  * // Set format to 'FASTA'.
633
634
  * mySequence.setFormat('FASTA');
634
- *
635
+ *
635
636
  * @param {string} format The format for the sequence to be displayed.
636
637
  */
637
638
  setFormat: function (format) {
@@ -655,7 +656,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
655
656
  * @example
656
657
  * // Set the number of columns to 70.
657
658
  * mySequence.setNumCols(70);
658
- *
659
+ *
659
660
  * @param {int} numCols The number of columns.
660
661
  */
661
662
  setNumCols: function (numCols) {
@@ -665,7 +666,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
665
666
 
666
667
  /**
667
668
  * Set the visibility of the drop-down list of formats.
668
- *
669
+ *
669
670
  * @param {boolean} visible true: show; false: hide.
670
671
  */
671
672
  formatSelectorVisible: function (visible) {
@@ -682,7 +683,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
682
683
  * @example
683
684
  * // Shows the format selector.
684
685
  * mySequence.showFormatSelector();
685
- *
686
+ *
686
687
  */
687
688
  showFormatSelector: function () {
688
689
  this._headerDiv.show();
@@ -690,11 +691,11 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
690
691
 
691
692
  /**
692
693
  * This is similar to a {Biojs.Protein3D#formatSelectorVisible} with the 'false' argument.
693
- *
694
+ *
694
695
  * @example
695
696
  * // Hides the format selector.
696
697
  * mySequence.hideFormatSelector();
697
- *
698
+ *
698
699
  */
699
700
  hideFormatSelector: function () {
700
701
  this._headerDiv.hide();
@@ -702,7 +703,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
702
703
 
703
704
  /**
704
705
  * Hides the whole component.
705
- *
706
+ *
706
707
  */
707
708
  hide: function () {
708
709
  this._headerDiv.hide();
@@ -711,15 +712,15 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
711
712
 
712
713
  /**
713
714
  * Shows the whole component.
714
- *
715
+ *
715
716
  */
716
717
  show: function () {
717
718
  this._headerDiv.show();
718
719
  this._contentDiv.show();
719
720
  },
720
- /*
721
+ /*
721
722
  * Function: Sequence._setSelection
722
- * Purpose: Update the current selection.
723
+ * Purpose: Update the current selection.
723
724
  * Returns: -
724
725
  * Inputs: start -> {int} Start of the region to be selected.
725
726
  * end -> {int} End of the region to be selected.
@@ -757,9 +758,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
757
758
  current.end = end;
758
759
  },
759
760
 
760
- /*
761
+ /*
761
762
  * Function: Sequence._repaintSelection
762
- * Purpose: Repaint the whole current selection.
763
+ * Purpose: Repaint the whole current selection.
763
764
  * Returns: -
764
765
  * Inputs: -
765
766
  */
@@ -769,9 +770,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
769
770
  this._setSelection(s.start, s.end);
770
771
  },
771
772
 
772
- /*
773
+ /*
773
774
  * Function: Sequence._redraw
774
- * Purpose: Repaint the current sequence.
775
+ * Purpose: Repaint the current sequence.
775
776
  * Returns: -
776
777
  * Inputs: -
777
778
  */
@@ -783,7 +784,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
783
784
  //this._contentDiv.text('');
784
785
  this._contentDiv.children().remove();
785
786
 
786
- // Rebuild the spans of the sequence
787
+ // Rebuild the spans of the sequence
787
788
  // according to format
788
789
  if (this.opt.format == 'RAW') {
789
790
  this._drawRaw();
@@ -801,9 +802,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
801
802
  this._repaintSelection();
802
803
  this._addSpanEvents();
803
804
  },
804
- /*
805
+ /*
805
806
  * Function: Sequence._drawFasta
806
- * Purpose: Repaint the current sequence using FASTA format.
807
+ * Purpose: Repaint the current sequence using FASTA format.
807
808
  * Returns: -
808
809
  * Inputs: -
809
810
  */
@@ -832,9 +833,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
832
833
 
833
834
  this._drawAnnotations(opt);
834
835
  },
835
- /*
836
+ /*
836
837
  * Function: Sequence._drawCodata
837
- * Purpose: Repaint the current sequence using CODATA format.
838
+ * Purpose: Repaint the current sequence using CODATA format.
838
839
  * Returns: -
839
840
  * Inputs: -
840
841
  */
@@ -884,11 +885,11 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
884
885
 
885
886
  this._drawAnnotations(opt);
886
887
  },
887
- /*
888
+ /*
888
889
  * Function: Sequence._drawAnnotations
889
- * Purpose: Paint the annotations on the sequence.
890
+ * Purpose: Paint the annotations on the sequence.
890
891
  * Returns: -
891
- * Inputs: settings -> {object}
892
+ * Inputs: settings -> {object}
892
893
  */
893
894
  _drawAnnotations: function (settings) {
894
895
 
@@ -961,9 +962,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
961
962
  });
962
963
 
963
964
  },
964
- /*
965
+ /*
965
966
  * Function: Sequence._getAnnotationString
966
- * Purpose: Get the annotation text message for the tooltip
967
+ * Purpose: Get the annotation text message for the tooltip
967
968
  * Returns: {string} Annotation text for the annotation
968
969
  * Inputs: id -> {int} index of the internal annotation array
969
970
  */
@@ -972,12 +973,12 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
972
973
  return annotation.name + '<br/>' + ((annotation.html) ? annotation.html : '');
973
974
  },
974
975
 
975
- /*
976
+ /*
976
977
  * Function: Sequence._getHTMLRowAnnot
977
978
  * Purpose: Build an annotation
978
979
  * Returns: HTML of the annotation
979
980
  * Inputs: currentPos -> {int}
980
- * annotation -> {Object}
981
+ * annotation -> {Object}
981
982
  * settings -> {Object}
982
983
  */
983
984
  _getHTMLRowAnnot: function (currentPos, annotation, settings) {
@@ -1030,9 +1031,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1030
1031
 
1031
1032
  return (str.indexOf('span') == -1) ? '' : str;
1032
1033
  },
1033
- /*
1034
+ /*
1034
1035
  * Function: Sequence._drawRaw
1035
- * Purpose: Repaint the current sequence using RAW format.
1036
+ * Purpose: Repaint the current sequence using RAW format.
1036
1037
  * Returns: -
1037
1038
  * Inputs: -
1038
1039
  */
@@ -1059,9 +1060,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1059
1060
 
1060
1061
  this._drawAnnotations(opt);
1061
1062
  },
1062
- /*
1063
+ /*
1063
1064
  * Function: Sequence._drawPride
1064
- * Purpose: Repaint the current sequence using PRIDE format.
1065
+ * Purpose: Repaint the current sequence using PRIDE format.
1065
1066
  * Returns: -
1066
1067
  * Inputs: -
1067
1068
  */
@@ -1087,9 +1088,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1087
1088
  this._drawSequence(seq, opt);
1088
1089
  this._drawAnnotations(opt);
1089
1090
  },
1090
- /*
1091
+ /*
1091
1092
  * Function: Sequence._drawSequence
1092
- * Purpose: Repaint the current sequence using CUSTOM format.
1093
+ * Purpose: Repaint the current sequence using CUSTOM format.
1093
1094
  * Returns: -
1094
1095
  * Inputs: a -> {char[]} a The sequence strand.
1095
1096
  * opt -> {Object} opt The CUSTOM format.
@@ -1216,11 +1217,11 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1216
1217
 
1217
1218
  return str;
1218
1219
  },
1219
- /*
1220
+ /*
1220
1221
  * Function: Sequence._formatIndex
1221
1222
  * Purpose: Build the HTML corresponding to counting numbers (top, left, right) in the strand.
1222
1223
  * Returns: -
1223
- * Inputs: number -> {int} The number
1224
+ * Inputs: number -> {int} The number
1224
1225
  * size -> {int} Number of bins to suit the number.
1225
1226
  * fillingChar -> {char} Character to be used for filling out blank bins.
1226
1227
  * alignLeft -> {bool} Tell if aligned to the left.
@@ -1241,7 +1242,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1241
1242
  }
1242
1243
  return str;
1243
1244
  },
1244
- /*
1245
+ /*
1245
1246
  * Function: Sequence._addSpanEvents
1246
1247
  * Purpose: Add the event handlers to the strand.
1247
1248
  * Returns: -
@@ -1313,7 +1314,7 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1313
1314
  })
1314
1315
  .css('cursor', 'pointer');
1315
1316
  },
1316
- /*
1317
+ /*
1317
1318
  * Function: Sequence._addTooltip
1318
1319
  * Purpose: Add a tooltip around the target DOM element provided as argument
1319
1320
  * Returns: -
@@ -1349,22 +1350,22 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1349
1350
 
1350
1351
  /**
1351
1352
  * Annotate a set of intervals provided in the argument.
1352
- *
1353
+ *
1353
1354
  * @example
1354
1355
  * // Annotations using regions with different colors.
1355
1356
  * mySequence.addAnnotation({
1356
- * name:"UNIPROT",
1357
- * html:"&lt;br&gt; Example of &lt;b&gt;HTML&lt;/b&gt;",
1358
- * color:"green",
1357
+ * name:"UNIPROT",
1358
+ * html:"&lt;br&gt; Example of &lt;b&gt;HTML&lt;/b&gt;",
1359
+ * color:"green",
1359
1360
  * regions: [
1360
1361
  * {start: 540, end: 560},
1361
- * {start: 561, end:580, color: "#FFA010"},
1362
- * {start: 581, end:590, color: "red"},
1362
+ * {start: 561, end:580, color: "#FFA010"},
1363
+ * {start: 581, end:590, color: "red"},
1363
1364
  * {start: 690, end:710}]
1364
1365
  * });
1365
- *
1366
- *
1367
- * @param {Object} annotation The intervals belonging to the same annotation.
1366
+ *
1367
+ *
1368
+ * @param {Object} annotation The intervals belonging to the same annotation.
1368
1369
  * Syntax: { name: &lt;value&gt;, color: &lt;HTMLColorCode&gt;, html: &lt;HTMLString&gt;, regions: [{ start: &lt;startVal1&gt;, end: &lt;endVal1&gt;}, ..., { start: &lt;startValN&gt;, end: &lt;endValN&gt;}] }
1369
1370
  */
1370
1371
  addAnnotation: function (annotation) {
@@ -1374,13 +1375,13 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1374
1375
 
1375
1376
  /**
1376
1377
  * Removes an annotation by means of its name.
1377
- *
1378
- * @example
1378
+ *
1379
+ * @example
1379
1380
  * // Remove the UNIPROT annotation.
1380
- * mySequence.removeAnnotation('UNIPROT');
1381
- *
1381
+ * mySequence.removeAnnotation('UNIPROT');
1382
+ *
1382
1383
  * @param {string} name The name of the annotation to be removed.
1383
- *
1384
+ *
1384
1385
  */
1385
1386
  removeAnnotation: function (name) {
1386
1387
  for (var i = 0; i < this._annotations.length; i++) {
@@ -1393,10 +1394,10 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
1393
1394
  },
1394
1395
  /**
1395
1396
  * Removes all the current annotations.
1396
- *
1397
- * @example
1398
- * mySequence.removeAllAnnotations();
1399
- *
1397
+ *
1398
+ * @example
1399
+ * mySequence.removeAllAnnotations();
1400
+ *
1400
1401
  */
1401
1402
  removeAllAnnotations: function () {
1402
1403
  this._annotations = [];
@@ -2454,4 +2455,3 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
2454
2455
 
2455
2456
  }, { './lib/index': 1 }]
2456
2457
  }, {}, ['biojs-vis-sequence']);
2457
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2UvbGliL2luZGV4LmpzIiwiL1VzZXJzL3ByaXlhbS9zZXF1ZW5jZXNlcnZlci9ub2RlX21vZHVsZXMvYmlvanMtdmlzLXNlcXVlbmNlL25vZGVfbW9kdWxlcy9iaW9qcy1ldmVudHMvaW5kZXguanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWV2ZW50cy9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUuanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWV2ZW50cy9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvaW5kZXguanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi9nZW5lcmljX3JlYWRlci5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL3BhcnNlci5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL3N0cmluZ3MuanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi91dGlscy5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL3dyaXRlci5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL2Jpb2pzLW1vZGVsL3NyYy9pbmRleC5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL2Jpb2pzLW1vZGVsL3NyYy9zZXEuanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL25vZGVfbW9kdWxlcy9uZXRzL2luZGV4LmpzIiwiL1VzZXJzL3ByaXlhbS9zZXF1ZW5jZXNlcnZlci9ub2RlX21vZHVsZXMvYmlvanMtdmlzLXNlcXVlbmNlL25vZGVfbW9kdWxlcy9iaW9qcy1pby1mYXN0YS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL2dsb2JhbC93aW5kb3cuanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL29uY2Uvb25jZS5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL25ldHMvbm9kZV9tb2R1bGVzL3hoci9ub2RlX21vZHVsZXMvcGFyc2UtaGVhZGVycy9ub2RlX21vZHVsZXMvZm9yLWVhY2gvaW5kZXguanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL3BhcnNlLWhlYWRlcnMvbm9kZV9tb2R1bGVzL2Zvci1lYWNoL25vZGVfbW9kdWxlcy9pcy1mdW5jdGlvbi9pbmRleC5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL25ldHMvbm9kZV9tb2R1bGVzL3hoci9ub2RlX21vZHVsZXMvcGFyc2UtaGVhZGVycy9ub2RlX21vZHVsZXMvdHJpbS9pbmRleC5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL25ldHMvbm9kZV9tb2R1bGVzL3hoci9ub2RlX21vZHVsZXMvcGFyc2UtaGVhZGVycy9wYXJzZS1oZWFkZXJzLmpzIiwiL1VzZXJzL3ByaXlhbS9zZXF1ZW5jZXNlcnZlci9ub2RlX21vZHVsZXMvYmlvanMtdmlzLXNlcXVlbmNlL25vZGVfbW9kdWxlcy9qcXVlcnktYnJvd3Nlci1wbHVnaW4vaW5kZXguanMiLCIvVXNlcnMvcHJpeWFtL3NlcXVlbmNlc2VydmVyL25vZGVfbW9kdWxlcy9iaW9qcy12aXMtc2VxdWVuY2Uvbm9kZV9tb2R1bGVzL2pxdWVyeS1icm93c2VyLXBsdWdpbi9qcXVlcnkuYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9qcy1jbGFzcy9jbGFzcy5qcyIsIi9Vc2Vycy9wcml5YW0vc2VxdWVuY2VzZXJ2ZXIvbm9kZV9tb2R1bGVzL2Jpb2pzLXZpcy1zZXF1ZW5jZS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL2luZGV4LmpzIiwiLi9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzc1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLy8gbGVnYWN5ISFcbiQuYnJvd3NlciA9IHJlcXVpcmUoXCJqcXVlcnktYnJvd3Nlci1wbHVnaW5cIik7XG5cbi8qKiBcbiAqIFNlcXVlbmNlIGNvbXBvbmVudCBcbiAqIFxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBCaW9qc1xuICogXG4gKiBAYXV0aG9yIDxhIGhyZWY9XCJtYWlsdG86am9obmNhckBnbWFpbC5jb21cIj5Kb2huIEdvbWV6PC9hPiwgPGEgaHJlZj1cIm1haWx0bzpzZWNldmFsbGl2QGdtYWlsLmNvbVwiPkpvc2UgVmlsbGF2ZWNlczwvYT5cbiAqIEB2ZXJzaW9uIDEuMC4wXG4gKiBAY2F0ZWdvcnkgM1xuICogXG4gKiBAcmVxdWlyZXMgPGEgaHJlZj0naHR0cDovL2Jsb2cuanF1ZXJ5LmNvbS8yMDExLzA5LzEyL2pxdWVyeS0xLTYtNC1yZWxlYXNlZC8nPmpRdWVyeSBDb3JlIDEuNi40PC9hPlxuICogQGRlcGVuZGVuY3kgPHNjcmlwdCBsYW5ndWFnZT1cIkphdmFTY3JpcHRcIiB0eXBlPVwidGV4dC9qYXZhc2NyaXB0XCIgc3JjPVwiLi4vYmlvanMvZGVwZW5kZW5jaWVzL2pxdWVyeS9qcXVlcnktMS40LjIubWluLmpzXCI+PC9zY3JpcHQ+XG4gKiBcbiAqIEByZXF1aXJlcyA8YSBocmVmPSdodHRwOi8vanF1ZXJ5dWkuY29tL2Rvd25sb2FkJz5qUXVlcnkgVUkgMS44LjE2PC9hPlxuICogQGRlcGVuZGVuY3kgPHNjcmlwdCBsYW5ndWFnZT1cIkphdmFTY3JpcHRcIiB0eXBlPVwidGV4dC9qYXZhc2NyaXB0XCIgc3JjPVwiLi4vYmlvanMvZGVwZW5kZW5jaWVzL2pxdWVyeS9qcXVlcnktdWktMS44LjIuY3VzdG9tLm1pbi5qc1wiPjwvc2NyaXB0PlxuICpcbiAqIEByZXF1aXJlcyA8YSBocmVmPSdCaW9qcy5Ub29sdGlwLmNzcyc+QmlvanMuVG9vbHRpcDwvYT5cbiAqIEBkZXBlbmRlbmN5IDxzY3JpcHQgbGFuZ3VhZ2U9XCJKYXZhU2NyaXB0XCIgdHlwZT1cInRleHQvamF2YXNjcmlwdFwiIHNyYz1cInNyYy9CaW9qcy5Ub29sdGlwLmpzXCI+PC9zY3JpcHQ+XG4gKiBcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIEFuIG9iamVjdCB3aXRoIHRoZSBvcHRpb25zIGZvciBTZXF1ZW5jZSBjb21wb25lbnQuXG4gKiAgICBcbiAqIEBvcHRpb24ge3N0cmluZ30gdGFyZ2V0IFxuICogICAgSWRlbnRpZmllciBvZiB0aGUgRElWIHRhZyB3aGVyZSB0aGUgY29tcG9uZW50IHNob3VsZCBiZSBkaXNwbGF5ZWQuXG4gKiAgICBcbiAqIEBvcHRpb24ge3N0cmluZ30gc2VxdWVuY2UgXG4gKiAgICBUaGUgc2VxdWVuY2UgdG8gYmUgZGlzcGxheWVkLlxuICogICAgXG4gKiBAb3B0aW9uIHtzdHJpbmd9IFtpZF0gXG4gKiAgICBTZXF1ZW5jZSBpZGVudGlmaWVyIGlmIGFwcGx5LlxuICogICAgXG4gKiBAb3B0aW9uIHtzdHJpbmd9IFtmb3JtYXQ9XCJGQVNUQVwiXSBcbiAqICAgIFRoZSBkaXNwbGF5IGZvcm1hdCBmb3IgdGhlIHNlcXVlbmNlIHJlcHJlc2VudGF0aW9uLlxuICogICAgXG4gKiBAb3B0aW9uIHtPYmplY3RbXX0gW2hpZ2hsaWdodHNdIFxuICogXHQgIEZvciBoaWdobGlnaHRpbmcgbXVsdGlwbGUgcmVnaW9ucy4gXG4gKiAgICA8cHJlIGNsYXNzPVwiYnJ1c2g6IGpzXCIgdGl0bGU9XCJTeW50YXg6XCI+IFxuICogICAgW1xuICogICAgXHQvLyBIaWdobGlnaHQgYW1pbm9hY2lkcyBmcm9tICdzdGFydCcgdG8gJ2VuZCcgb2YgdGhlIGN1cnJlbnQgc3RyYW5kIHVzaW5nIHRoZSBzcGVjaWZpZWQgJ2NvbG9yJyAob3B0aW9uYWwpIGFuZCAnYmFja2dyb3VuZCcgKG9wdGlvbmFsKS5cbiAqICAgIFx0eyBzdGFydDogJmx0O3N0YXJ0VmFsMSZndDssIGVuZDogJmx0O2VuZFZhbDEmZ3Q7IFssIGlkOiZsdDtpZFZhbDEmZ3Q7XSBbLCBjb2xvcjogJmx0O0hUTUxDb2xvciZndDtdIFssIGJhY2tncm91bmQ6ICZsdDtIVE1MQ29sb3ImZ3Q7XX0sIFxuICogICAgXHQvL1xuICogICAgXHQvLyBBbnkgb3RoZXJzIGhpZ2hsaWdodHNcbiAqICAgIFx0Li4uLCAgXG4gKiAgICBcdC8vIFxuICogICAgXHR7IHN0YXJ0OiAmbHQ7c3RhcnRWYWxOJmd0OywgZW5kOiAmbHQ7ZW5kVmFsTiZndDsgWywgaWQ6Jmx0O2lkVmFsTiZndDtdIFssIGNvbG9yOiAmbHQ7SFRNTENvbG9yJmd0O10gWywgYmFja2dyb3VuZDogJmx0O0hUTUxDb2xvciZndDtdfVxuICogICAgXTwvcHJlPlxuICogXG4gKiA8cHJlIGNsYXNzPVwiYnJ1c2g6IGpzXCIgdGl0bGU9XCJFeGFtcGxlOlwiPiBcbiAqIGhpZ2hsaWdodHMgOiBbXG4gKiBcdFx0eyBzdGFydDozMCwgZW5kOjQyLCBjb2xvcjpcIndoaXRlXCIsIGJhY2tncm91bmQ6XCJncmVlblwiLCBpZDpcInNwaW4xXCIgfSxcbiAqXHRcdHsgc3RhcnQ6MTM5LCBlbmQ6MTQwIH0sIFxuICpcdFx0eyBzdGFydDo2MzEsIGVuZDo2MzMsIGNvbG9yOlwid2hpdGVcIiwgYmFja2dyb3VuZDpcImJsdWVcIiB9XG4gKlx0XVxuICogPC9wcmU+XG4gKiBcbiAqIEBvcHRpb24ge09iamVjdH0gW2NvbHVtbnM9e3NpemU6NDAsc3BhY2VkRWFjaDoxMH1dIFxuICogXHQgIE9wdGlvbnMgZm9yIGRpc3BsYXlpbmcgdGhlIGNvbHVtbnMuIFN5bnRheDogeyBzaXplOiAmbHQ7bnVtQ29scyZndDssIHNwYWNlZEVhY2g6ICZsdDtudW1Db2xzJmd0O31cbiAqIFxuICogQG9wdGlvbiB7T2JqZWN0fSBbc2VsZWN0aW9uXSBcbiAqIFx0ICBQb3NpdGlvbnMgZm9yIHRoZSBjdXJyZW50IHNlbGVjdGVkIHJlZ2lvbi4gU3ludGF4OiB7IHN0YXJ0OiAmbHQ7c3RhcnRWYWx1ZSZndDssIGVuZDogJmx0O2VuZFZhbHVlJmd0O31cbiAqIFxuICogQG9wdGlvbiB7T2JqZWN0W119IFthbm5vdGF0aW9uc10gXG4gKiAgICBTZXQgb2Ygb3ZlcmxhcHBpbmcgYW5ub3RhdGlvbnMuIE11c3QgYmUgYW4gYXJyYXkgb2Ygb2JqZWN0cyBmb2xsb3dpbmcgdGhlIHN5bnRheDpcbiAqICAgICBcdFx0PHByZSBjbGFzcz1cImJydXNoOiBqc1wiIHRpdGxlPVwiU3ludGF4OlwiPlxuICogICAgICAgICAgICBbIFxuICogICAgICAgICAgICAgIC8vIEFuIGFubm90YXRpb246XG4gKiAgICAgICAgICAgICAgeyBuYW1lOiAmbHQ7bmFtZSZndDssIFxuICogICAgICAgICAgICAgICAgaHRtbDogJmx0O21lc3NhZ2UmZ3Q7LCBcbiAqICAgICAgICAgICAgICAgIGNvbG9yOiAmbHQ7Y29sb3JfY29kZSZndDssIFxuICogICAgICAgICAgICAgICAgcmVnaW9uczogW3sgc3RhcnQ6ICZsdDtzdGFydFZhbDEmZ3Q7LCBlbmQ6ICZsdDtlbmRWYWwxJmd0OyBjb2xvcjogJmx0O0hUTUxDb2xvciZndDt9LCAuLi4seyBzdGFydDogJmx0O3N0YXJ0VmFsTiZndDssIGVuZDogJmx0O2VuZFZhbE4mZ3Q7LCBjb2xvcjogJmx0O0hUTUxDb2xvciZndDt9XSBcbiAqICAgICAgICAgICAgICB9LCBcbiAqICAgICAgICAgICAgICBcbiAqICAgICAgICAgICAgICAvLyAuLi5cbiAqICAgICAgICAgICAgICAvLyBtb3JlIGFubm90YXRpb25zIGhlcmUgXG4gKiAgICAgICAgICAgICAgLy8gLi4uXG4gKiAgICAgICAgICAgIF1cbiAqICAgIFx0XHQgPC9wcmU+XG4gKiAgICB3aGVyZTpcbiAqICAgICAgPHVsPlxuICogICAgICAgIDxsaT48Yj5uYW1lPC9iPiBpcyB0aGUgdW5pcXVlIG5hbWUgZm9yIHRoZSBhbm5vdGF0aW9uPC9saT5cbiAqICAgICAgICA8bGk+PGI+aHRtbDwvYj4gaXMgdGhlIG1lc3NhZ2UgKGNhbiBiZSBIVE1MKSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHRvb2wgdGlwLjwvbGk+XG4gKiAgICAgICAgPGxpPjxiPmNvbG9yPC9iPiBpcyB0aGUgZGVmYXVsdCBIVE1MIGNvbG9yIGNvZGUgZm9yIGFsbCB0aGUgcmVnaW9ucy48L2xpPlxuICogICAgICAgIDxsaT48Yj5yZWdpb25zPC9iPiBhcnJheSBvZiBvYmplY3RzIGRlZmluaW5nIHRoZSBpbnRlcnZhbHMgd2hpY2ggYmVsb25ncyB0byB0aGUgYW5ub3RhdGlvbi48L2xpPlxuICogICAgICAgIDxsaT48Yj5yZWdpb25zW2ldLnN0YXJ0PC9iPiBpcyB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIGZvciB0aGUgaS10aCBpbnRlcnZhbC48L2xpPlxuICogICAgICAgIDxsaT48Yj5yZWdpb25zW2ldLmVuZDwvYj4gaXMgdGhlIGVuZGluZyBjaGFyYWN0ZXIgZm9yIHRoZSBpLXRoIGludGVydmFsLjwvbGk+XG4gKiAgICAgICAgPGxpPjxiPnJlZ2lvbnNbaV0uY29sb3I8L2I+IGlzIGFuIG9wdGlvbmFsIGNvbG9yIGZvciB0aGUgaS10aCBpbnRlcnZhbC4gICBcbiAqICAgICAgPC91bD4gXG4gKiAgICAgIFxuICogQG9wdGlvbiB7T2JqZWN0fSBbZm9ybWF0T3B0aW9ucz17dGl0bGU6dHJ1ZSwgZm9vdGVyOnRydWV9XSBcbiAqIFx0ICBPcHRpb25zIGZvciBkaXNwbGF5aW5nIHRoZSB0aXRsZS4gYnkgbm93IGp1c3QgYWZmZWN0aW5nIHRoZSBDT0RBVEEgZm9ybWF0LlxuICogICAgPHByZSBjbGFzcz1cImJydXNoOiBqc1wiIHRpdGxlPVwiU3ludGF4OlwiPiBcbiAqIFx0XHRmb3JtYXRPcHRpb25zIDoge1xuICogXHRcdFx0dGl0bGU6ZmFsc2UsXG4gKiBcdFx0XHRmb290ZXI6ZmFsc2VcbiAqIFx0XHR9XG4gKiAgICA8L3ByZT5cbiAqICAgIFxuICogQGV4YW1wbGUgXG4gKiB2YXIgdGhlU2VxdWVuY2UgPSBcIk1FVExDUVJMTlZDUURLSUxUSFlFTkRTVERMUkRISURZV0tITVJMRUNBSVlZS0FSRU1HRktISU5IUVZWUFRMQVZTS05LQUxRQUlFTFFMVExFVElZTlNRWVNORUtXVExRRFZTTEVWWUxUQVBUR0NJS0tIR1lUVkVWUUZER0RJQ05UTUhZVE5XVEhJWUlDRUVBb2pzIFNWVFZWRUdRVkRZWUdMWVlWSEVHSVJUWUZWUUZLRERBRUtZU0tOS1ZXRVZIQUdHUVZJTENQVFNWRlNTTkVWU1NQRUlJUlFITEFOSFBBQVRIVEtBVkFMR1RFRVRRVFRJUVJQUlNFUERUR05QQ0hUVEtMTEhSRFNWRFNBUElMVEFGTlNTSEtHUklOQ05TTlRUUElWSExLR0RBTlRMS0NMUllSRktLSENUTFlUQVZTU1RXSFdUR0hOVktIS1NBSVZUTFRZRFNFV1FSRFFGTFNRVktJUEtUSVRWU1RHRk1TSVwiO1xuICogdmFyIG15U2VxdWVuY2UgPSBuZXcgU2VxdWVuY2Uoe1xuICogXHRcdHNlcXVlbmNlIDogdGhlU2VxdWVuY2UsXG4gKiBcdFx0dGFyZ2V0IDogXCJZb3VyT3duRGl2SWRcIixcbiAqIFx0XHRmb3JtYXQgOiAnQ09EQVRBJyxcbiAqIFx0XHRpZCA6ICdQOTE4MjgzJyxcbiAqIFx0XHRhbm5vdGF0aW9uczogW1xuICogICAgICAgIHsgbmFtZTpcIkNBVEhcIiwgXG4gKiBcdCAgXHRcdGNvbG9yOlwiI0YwRjAyMFwiLCBcbiAqIFx0ICBcdFx0aHRtbDogXCJVc2luZyBjb2xvciBjb2RlICNGMEYwMjAgXCIsIFxuICogXHQgIFx0XHRyZWdpb25zOiBbe3N0YXJ0OiAxMjIsIGVuZDogMTM1fV1cbiAqIFx0XHQgIH0sXG4gKiAgICAgICAgeyBuYW1lOlwiVEVTVFwiLCBcbiAqICAgICAgICAgIGh0bWw6XCImbHQ7YnImZ3Q7IEV4YW1wbGUgb2YgJmx0O2ImZ3Q7SFRNTCZsdDsvYiZndDtcIiwgXG4gKiAgICAgICAgICBjb2xvcjpcImdyZWVuXCIsIFxuICogICAgICAgICAgcmVnaW9uczogW1xuICogICAgICAgICAgICB7c3RhcnQ6IDI4NSwgZW5kOiAyOTJ9LFxuICogICAgICAgICAgICB7c3RhcnQ6IDI5MywgZW5kOiAzMTQsIGNvbG9yOiBcIiMyRTQ5ODhcIn1dXG4gKiAgICAgICAgfVxuICogICAgICBdLFxuICogICAgICBoaWdobGlnaHRzIDogW1xuICogICAgICBcdHsgc3RhcnQ6MzAsIGVuZDo0MiwgY29sb3I6XCJ3aGl0ZVwiLCBiYWNrZ3JvdW5kOlwiZ3JlZW5cIiwgaWQ6XCJzcGluMVwiIH0sXG4gKiAgICAgIFx0eyBzdGFydDoxMzksIGVuZDoxNDAgfSwgXG4gKiAgICAgIFx0eyBzdGFydDo2MzEsIGVuZDo2MzMsIGNvbG9yOlwid2hpdGVcIiwgYmFja2dyb3VuZDpcImJsdWVcIiB9XG4gKiAgICAgIF1cbiAqIH0pO1x0XG4gKiBcbiAqL1xuXG52YXIgQ2xhc3MgPSByZXF1aXJlKCdqcy1jbGFzcycpO1xuXG52YXIgRVZUX09OX1NFTEVDVElPTl9DSEFOR0U9IFwib25TZWxlY3Rpb25DaGFuZ2VcIjtcbnZhciBFVlRfT05fU0VMRUNUSU9OX0NIQU5HRUQ9IFwib25TZWxlY3Rpb25DaGFuZ2VkXCI7XG52YXIgRVZUX09OX0FOTk9UQVRJT05fQ0xJQ0tFRD0gXCJvbkFubm90YXRpb25DbGlja2VkXCI7XG5cblNlcXVlbmNlID0gQ2xhc3MoXG4vKiogQGxlbmRzIFNlcXVlbmNlIyAqL1xue1x0XG5cdGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAob3B0aW9ucykge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblxuICAgIHRoaXMub3B0ID0galF1ZXJ5LmV4dGVuZCh0aGlzLm9wdCxvcHRpb25zKTtcblxuICAgIHRoaXMuX2NvbnRhaW5lciA9IGpRdWVyeSh0aGlzLm9wdC50YXJnZXQgKTtcbiAgICBcbiAgICAvLyBsZWdhY3kgc3VwcG9ydCAodGFyZ2V0IGlkIHdpdGhvdXQgJyMnKVxuICAgIGlmKHRoaXMuX2NvbnRhaW5lci5sZW5ndGggPT0gMCl7XG4gICAgICB0aGlzLl9jb250YWluZXIgPSBqUXVlcnkoIFwiI1wiICsgdGhpcy5vcHQudGFyZ2V0IClcbiAgICB9XG5cbiAgICBpZih0aGlzLl9jb250YWluZXIubGVuZ3RoID09IDApe1xuICAgICAgY29uc29sZS5sb2coXCJlbXB0eSB0YXJnZXQgY29udGFpbmVyXCIpO1xuICAgIH1cblxuICAgIC8vIGxlZ2FjeTogY29weSB0YXJnZXQgaWRcbiAgICB0aGlzLm9wdC50YXJnZXQgPSB0aGlzLl9jb250YWluZXJbMF0uaWQ7XG5cdFx0XG5cdFx0Ly8gTGF6eSBpbml0aWFsaXphdGlvbiBcblx0XHR0aGlzLl9jb250YWluZXIucmVhZHkoZnVuY3Rpb24oKSB7XG5cdFx0XHRzZWxmLl9pbml0aWFsaXplKCk7XG5cdFx0fSk7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRGVmYXVsdCB2YWx1ZXMgZm9yIHRoZSBvcHRpb25zXG5cdCAqIEBuYW1lIFNlcXVlbmNlLW9wdFxuXHQgKi9cblx0b3B0IDoge1xuXHRcdFxuXHRcdHNlcXVlbmNlIDogXCJcIixcblx0XHRpZCA6IFwiXCIsXG5cdFx0dGFyZ2V0IDogXCJcIixcblx0XHRmb3JtYXQgOiBcIkZBU1RBXCIsXG5cdFx0c2VsZWN0aW9uOiB7IHN0YXJ0OiAwLCBlbmQ6IDAgfSxcblx0XHRjb2x1bW5zOiB7IHNpemU6IDM1LCBzcGFjZWRFYWNoOiAxMCB9LFxuXHRcdGhpZ2hsaWdodHMgOiBbXSxcblx0XHRhbm5vdGF0aW9uczogW10sXG5cdFx0c2VxdWVuY2VVcmw6ICdodHRwOi8vd3d3LmViaS5hYy51ay9kYXMtc3J2L3VuaXByb3QvZGFzL3VuaXByb3Qvc2VxdWVuY2UnLFxuXHRcdFxuXHRcdC8vIFN0eWxlcyBcblx0XHRzZWxlY3Rpb25Db2xvciA6ICdZZWxsb3cnLFxuXHRcdHNlbGVjdGlvbkZvbnRDb2xvciA6ICdibGFjaycsXG5cdFx0aGlnaGxpZ2h0Rm9udENvbG9yIDogJ3JlZCcsXG5cdFx0aGlnaGxpZ2h0QmFja2dyb3VuZENvbG9yIDogJ3doaXRlJyxcblx0XHRmb250RmFtaWx5OiAnXCJBbmRhbGUgbW9ub1wiLCBjb3VyaWVyLCBtb25vc3BhY2UnLFxuXHRcdGZvbnRTaXplOiAnMTJweCcsXG5cdFx0Zm9udENvbG9yIDogJ2luaGVyaXQnLFxuXHRcdGJhY2tncm91bmRDb2xvciA6ICdpbmhlcml0Jyxcblx0XHR3aWR0aDogdW5kZWZpbmVkLFxuXHRcdGhlaWdodDogdW5kZWZpbmVkLFxuXHRcdGZvcm1hdFNlbGVjdG9yVmlzaWJsZTogdHJ1ZVxuXHR9LFxuXHRcblx0LyoqXG5cdCAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIHN1cHBvcnRlZCBldmVudCBuYW1lc1xuXHQgKiBAbmFtZSBTZXF1ZW5jZS1ldmVudFR5cGVzXG5cdCAqL1xuXHRldmVudFR5cGVzIDogW1xuXHRcdC8qKlxuXHRcdCAqIEBuYW1lIFNlcXVlbmNlI29uU2VsZWN0aW9uQ2hhbmdlZFxuXHRcdCAqIEBldmVudFxuXHRcdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGFjdGlvblBlcmZvcm1lZCBBbiBmdW5jdGlvbiB3aGljaCByZWNlaXZlcyBhbiB7QGxpbmsgQmlvanMuRXZlbnR9IG9iamVjdCBhcyBhcmd1bWVudC5cblx0XHQgKiBAZXZlbnREYXRhIHtPYmplY3R9IHNvdXJjZSBUaGUgY29tcG9uZW50IHdoaWNoIGRpZCB0cmlnZ2VyZWQgdGhlIGV2ZW50LlxuXHRcdCAqIEBldmVudERhdGEge3N0cmluZ30gdHlwZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXG5cdFx0ICogQGV2ZW50RGF0YSB7aW50fSBzdGFydCBBIG51bWJlciBpbmRpY2F0aW5nIHRoZSBzdGFydCBvZiB0aGUgc2VsZWN0aW9uLlxuXHRcdCAqIEBldmVudERhdGEge2ludH0gZW5kIEEgbnVtYmVyIGluZGljYXRpbmcgdGhlIGVuZGluZyBvZiBzZWxlY3Rpb24uXG5cdFx0ICogQGV4YW1wbGUgXG5cdFx0ICogbXlTZXF1ZW5jZS5vblNlbGVjdGlvbkNoYW5nZWQoXG5cdFx0ICogICAgZnVuY3Rpb24oIG9iakV2ZW50ICkge1xuXHRcdCAqICAgICAgIGFsZXJ0KFwiU2VsZWN0ZWQ6IFwiICsgb2JqRXZlbnQuc3RhcnQgKyBcIiwgXCIgKyBvYmpFdmVudC5lbmQgKTtcblx0XHQgKiAgICB9XG5cdFx0ICogKTsgXG5cdFx0ICogXG5cdFx0ICogKi9cblx0XHRcIm9uU2VsZWN0aW9uQ2hhbmdlZFwiLFxuXHRcdFxuXHRcdC8qKlxuXHRcdCAqIEBuYW1lIFNlcXVlbmNlI29uU2VsZWN0aW9uQ2hhbmdlXG5cdFx0ICogQGV2ZW50XG5cdFx0ICogQHBhcmFtIHtmdW5jdGlvbn0gYWN0aW9uUGVyZm9ybWVkIEFuIGZ1bmN0aW9uIHdoaWNoIHJlY2VpdmVzIGFuIHtAbGluayBCaW9qcy5FdmVudH0gb2JqZWN0IGFzIGFyZ3VtZW50LlxuXHRcdCAqIEBldmVudERhdGEge09iamVjdH0gc291cmNlIFRoZSBjb21wb25lbnQgd2hpY2ggZGlkIHRyaWdnZXJlZCB0aGUgZXZlbnQuXG5cdFx0ICogQGV2ZW50RGF0YSB7c3RyaW5nfSB0eXBlIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cblx0XHQgKiBAZXZlbnREYXRhIHtpbnR9IHN0YXJ0IEEgbnVtYmVyIGluZGljYXRpbmcgdGhlIHN0YXJ0IG9mIHRoZSBzZWxlY3Rpb24uXG5cdFx0ICogQGV2ZW50RGF0YSB7aW50fSBlbmQgQSBudW1iZXIgaW5kaWNhdGluZyB0aGUgZW5kaW5nIG9mIHNlbGVjdGlvbi5cblx0XHQgKiBAZXhhbXBsZSBcblx0XHQgKiBteVNlcXVlbmNlLm9uU2VsZWN0aW9uQ2hhbmdlKFxuXHRcdCAqICAgIGZ1bmN0aW9uKCBvYmpFdmVudCApIHtcblx0XHQgKiAgICAgICBhbGVydChcIlNlbGVjdGlvbiBpbiBwcm9ncmVzczogXCIgKyBvYmpFdmVudC5zdGFydCArIFwiLCBcIiArIG9iakV2ZW50LmVuZCApO1xuXHRcdCAqICAgIH1cblx0XHQgKiApOyAgXG5cdFx0ICogXG5cdFx0ICogXG5cdFx0ICogKi9cblx0XHRcIm9uU2VsZWN0aW9uQ2hhbmdlXCIsXG5cdFx0XG5cdFx0LyoqXG5cdFx0ICogQG5hbWUgU2VxdWVuY2Ujb25Bbm5vdGF0aW9uQ2xpY2tlZFxuXHRcdCAqIEBldmVudFxuXHRcdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGFjdGlvblBlcmZvcm1lZCBBbiBmdW5jdGlvbiB3aGljaCByZWNlaXZlcyBhbiB7QGxpbmsgQmlvanMuRXZlbnR9IG9iamVjdCBhcyBhcmd1bWVudC5cblx0XHQgKiBAZXZlbnREYXRhIHtPYmplY3R9IHNvdXJjZSBUaGUgY29tcG9uZW50IHdoaWNoIGRpZCB0cmlnZ2VyZWQgdGhlIGV2ZW50LlxuXHRcdCAqIEBldmVudERhdGEge3N0cmluZ30gdHlwZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXG5cdFx0ICogQGV2ZW50RGF0YSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBzZWxlY3RlZCBhbm5vdGF0aW9uLlxuXHRcdCAqIEBldmVudERhdGEge2ludH0gcG9zIEEgbnVtYmVyIGluZGljYXRpbmcgdGhlIHBvc2l0aW9uIG9mIHRoZSBzZWxlY3RlZCBhbWlubyBhY2lkLlxuXHRcdCAqIEBleGFtcGxlIFxuXHRcdCAqIG15U2VxdWVuY2Uub25Bbm5vdGF0aW9uQ2xpY2tlZChcblx0XHQgKiAgICBmdW5jdGlvbiggb2JqRXZlbnQgKSB7XG5cdFx0ICogICAgICAgYWxlcnQoXCJDbGlja2VkIFwiICsgb2JqRXZlbnQubmFtZSArIFwiIG9uIHBvc2l0aW9uIFwiICsgb2JqRXZlbnQucG9zICk7XG5cdFx0ICogICAgfVxuXHRcdCAqICk7ICBcblx0XHQgKiBcblx0XHQgKiAqL1xuXHRcdFwib25Bbm5vdGF0aW9uQ2xpY2tlZFwiXG5cdF0sXG5cbiAgZ2V0SWQgOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0LmlkO1xuICB9LFxuXG5cdC8vIGludGVybmFsIG1lbWJlcnNcblx0X2hlYWRlckRpdiA6IG51bGwsXG5cdF9jb250ZW50RGl2IDogbnVsbCxcblx0XG5cdC8vIE1ldGhvZHNcblxuXHRfaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuXHRcdFxuXHRcdGlmICggdGhpcy5vcHQud2lkdGggIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuX2NvbnRhaW5lci53aWR0aCggdGhpcy5vcHQud2lkdGggKTtcblx0XHR9XG5cdFx0XG5cdFx0aWYgKCB0aGlzLm9wdC5oZWlnaHQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuX2NvbnRhaW5lci5oZWlnaHQoIHRoaXMub3B0LmhlaWdodCApO1xuXHRcdH1cblx0XHRcblx0XHQvLyBEaXNhYmxlIHRleHQgc2VsZWN0aW9uXG5cdFx0XG5cdFx0dGhpcy5fY29udGFpbmVyLmNzcyh7XG5cdFx0XHQnLW1vei11c2VyLXNlbGVjdCc6J25vbmUnLFxuXHRcdFx0Jy13ZWJraXQtdXNlci1zZWxlY3QnOidub25lJyxcblx0XHRcdCd1c2VyLXNlbGVjdCc6J25vbmUnXG4gICAgICAgIH0pO1xuXHRcdFxuXHRcdC8vIERJViBmb3IgdGhlIGZvcm1hdCBzZWxlY3RvclxuXHRcdHRoaXMuX2J1aWxkRm9ybWF0U2VsZWN0b3IoKTtcblx0XHRcblx0XHQvLyBESVYgZm9yIHRoZSBzZXF1ZW5jZVxuXHRcdHRoaXMuX2NvbnRlbnREaXYgPSBqUXVlcnkoJzxkaXY+PC9kaXY+JykuYXBwZW5kVG8odGhpcy5fY29udGFpbmVyKTtcblx0XHR0aGlzLl9jb250ZW50RGl2LmNzcyh7XG5cdFx0XHRcdCdmb250LWZhbWlseSc6IHRoaXMub3B0LmZvbnRGYW1pbHksXG5cdFx0XHRcdCdmb250LXNpemUnOiB0aGlzLm9wdC5mb250U2l6ZSxcblx0XHRcdFx0J3RleHQtYWxpZ24nOiAnbGVmdCdcblx0XHRcdH0pO1xuXHRcdFxuXHRcdC8vIEluaXRpYWxpemUgaGlnaGxpZ2h0aW5nIFxuXHRcdHRoaXMuX2hpZ2hsaWdodHMgPSB0aGlzLm9wdC5oaWdobGlnaHRzO1xuXHRcdFxuXHRcdC8vIEluaXRpYWxpemUgYW5ub3RhdGlvbnNcblx0XHR0aGlzLl9hbm5vdGF0aW9ucyA9IHRoaXMub3B0LmFubm90YXRpb25zO1xuXHRcdFxuXHRcdC8vSW5pdGlhbGl6ZSB0b29sdGlwXG5cdFx0dmFyIHRvb2x0aXAgPSBcInNlcXVlbmNlVGlwXCIgKyB0aGlzLm9wdC50YXJnZXQgO1xuXHRcdGpRdWVyeSgnPGRpdiBpZD1cIicgKyB0b29sdGlwICsgJ1wiPjwvZGl2PicpIFxuXHQgICAgICAgIC5jc3Moe1x0XG5cdCAgICAgICAgXHQncG9zaXRpb24nOiBcImFic29sdXRlXCIsXG5cdCAgICAgICAgXHQnei1pbmRleCc6IFwiOTk5OTk5XCIsXG5cdCAgICAgICAgXHQnY29sb3InOiBcIiNmZmZcIixcblx0ICAgICAgICBcdCdmb250LXNpemUnOiBcIjEycHhcIixcblx0ICAgICAgICBcdCd3aWR0aCc6IFwiYXV0b1wiLFxuXHQgICAgICAgIFx0J2Rpc3BsYXknOiAnbm9uZSdcblx0ICAgICAgICB9KVxuXHQgICAgICAgIC5hZGRDbGFzcyhcInRvb2x0aXBcIilcblx0ICAgICAgICAuYXBwZW5kVG8oXCJib2R5XCIpXG5cdCAgICAgICAgLmhpZGUoKTtcblx0XHR0aGlzLm9wdC5fdG9vbHRpcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRvb2x0aXApO1xuXG5cdFx0aWYgKCAodGhpcy5vcHQuc2VxdWVuY2UpICkge1xuXHRcdFx0dGhpcy5fcmVkcmF3KCk7XG5cdFx0XHRcblx0XHR9IGVsc2UgaWYgKCAgKHRoaXMub3B0LmlkKSApIHtcblx0XHRcdHRoaXMuX3JlcXVlc3RTZXF1ZW5jZSggdGhpcy5vcHQuaWQgKTtcblx0XHRcdFxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmNsZWFyU2VxdWVuY2UoXCJObyBzZXF1ZW5jZSBhdmFpbGFibGVcIiwgXCIuLi9iaW9qcy9jc3MvaW1hZ2VzL3dhcm5pbmdfaWNvbi5wbmdcIik7XG5cdFx0fVxuXHRcdFxuXHR9LFxuXHRcblx0XG5cdC8qKlxuXHQgKiBTaG93cyB0aGUgY29sdW1ucyBpbmRpY2F0ZWQgYnkgdGhlIGluZGV4ZXMgYXJyYXkuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzZXEgVGhlIHNlcXVlbmNlIHN0cmFuZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IFtpZGVudGlmaWVyXSBTZXF1ZW5jZSBpZGVudGlmaWVyLlxuXHQgKiBcblx0ICogQGV4YW1wbGUgXG5cdCAqIG15U2VxdWVuY2Uuc2V0U2VxdWVuY2UoXCJQOTk5OTlcIik7XG5cdCAqIFxuXHQgKi9cbiAgICBzZXRTZXF1ZW5jZTogZnVuY3Rpb24gKCBzZXEsIGlkZW50aWZpZXIgKSB7XG5cbiAgICBcdGlmICggc2VxLm1hdGNoKC9eKFtBLU4sUi1aXVswLTldW0EtWl1bQS1aLCAwLTldW0EtWiwgMC05XVswLTldKXwoW08sUCxRXVswLTldW0EtWiwgMC05XVtBLVosIDAtOV1bQS1aLCAwLTldWzAtOV0pKFxcLlxcZCspPyQvaSkgKSB7XG4gICAgXHRcdHRoaXMuX3JlcXVlc3RTZXF1ZW5jZSggYXJndW1lbnRzWzBdICk7XG4gICAgXHRcdFxuICAgIFx0fSBlbHNlIHtcbiAgICBcdFx0dGhpcy5vcHQuc2VxdWVuY2UgPSBzZXE7XG4gICAgICAgIFx0dGhpcy5vcHQuaWQgPSBpZGVudGlmaWVyOyBcbiAgICAgICAgXHR0aGlzLl9oaWdobGlnaHRzID0gW107XG4gICAgXHRcdHRoaXMuX2hpZ2hsaWdodHNDb3VudCA9IDA7XG4gICAgXHRcdHRoaXMub3B0LnNlbGVjdGlvbiA9IHsgc3RhcnQ6IDAsIGVuZDogMCB9O1xuICAgIFx0XHR0aGlzLl9hbm5vdGF0aW9ucyA9IFtdO1xuICAgIFx0XHRcbiAgICBcdFx0dGhpcy5fY29udGVudERpdi5jaGlsZHJlbigpLnJlbW92ZSgpO1xuICAgIFx0XHR0aGlzLl9yZWRyYXcoKTtcbiAgICBcdH1cbiAgICB9LFxuICAgIFxuICAgIF9yZXF1ZXN0U2VxdWVuY2U6IGZ1bmN0aW9uICggYWNjZXNzaW9uICkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcbiAgICBcdFxuICAgIFx0Y29uc29sZS5sb2coXCJSZXF1ZXN0aW5nIHNlcXVlbmNlIGZvcjogXCIgKyBhY2Nlc3Npb24gKTtcblxuXHRcdGpRdWVyeS5hamF4KHsgXG5cdFx0XHR1cmw6IHNlbGYub3B0LnNlcXVlbmNlVXJsLFxuXHRcdFx0ZGF0YVR5cGU6IFwieG1sXCIsXG5cdFx0XHRkYXRhOiB7IHNlZ21lbnQ6IGFjY2Vzc2lvbiB9LFxuXHRcdFx0c3VjY2VzczogZnVuY3Rpb24gKCB4bWwgICkge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdHZhciBzZXF1ZW5jZU5vZGUgPSBqUXVlcnkoeG1sKS5maW5kKCdTRVFVRU5DRTpmaXJzdCcpO1xuXHRcdFx0XHRcdHNlbGYuc2V0U2VxdWVuY2UoIHNlcXVlbmNlTm9kZS50ZXh0KCksIHNlcXVlbmNlTm9kZS5hdHRyKFwiaWRcIiksIHNlcXVlbmNlTm9kZS5hdHRyKFwibGFiZWxcIikgKTtcblx0XHRcdFx0XHRcblx0XHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiRXJyb3IgZGVjb2RpbmcgcmVzcG9uc2UgZGF0YTogXCIgKyBlLm1lc3NhZ2UgKTtcblx0XHRcdFx0XHRzZWxmLmNsZWFyU2VxdWVuY2UoXCJObyBzZXF1ZW5jZSBhdmFpbGFibGVcIiwgXCIuLi9iaW9qcy9jc3MvaW1hZ2VzL3dhcm5pbmdfaWNvbi5wbmdcIik7XG5cdFx0XHRcdH1cblxuXHRcdFx0fSxcblx0XHRcdGVycm9yOiBmdW5jdGlvbiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XG5cdFx0XHRcdGNvbnNvbGUubG9nKFwiRXJyb3IgZGVjb2RpbmcgcmVzcG9uc2UgZGF0YTogXCIgKyB0ZXh0U3RhdHVzICk7XG5cdFx0XHRcdHNlbGYuY2xlYXJTZXF1ZW5jZShcIkVycm9yIHJlcXVlc3RpbmcgdGhlIHNlcXVlbmNlIHRvIHRoZSBzZXJ2ZXIgXCIgKyB0aGlzLnVybCAsIFwiLi4vYmlvanMvY3NzL2ltYWdlcy93YXJuaW5nX2ljb24ucG5nXCIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuICAgIH0sXG5cdFxuICAgIC8qKlxuXHQgKiBTaG93cyB0aGUgY29sdW1ucyBpbmRpY2F0ZWQgYnkgdGhlIGluZGV4ZXMgYXJyYXkuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbc2hvd01lc3NhZ2VdIE1lc3NhZ2UgdG8gYmUgc2hvd2VkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW2ljb25dIEljb24gdG8gYmUgc2hvd2VkIGEgc2lkZSBvZiB0aGUgbWVzc2FnZVxuXHQgKiBcblx0ICogQGV4YW1wbGUgXG5cdCAqIG15U2VxdWVuY2UuY2xlYXJTZXF1ZW5jZShcIk5vIHNlcXVlbmNlIGF2YWlsYWJsZVwiLCBcIi4uL2Jpb2pzL2Nzcy9pbWFnZXMvd2FybmluZ19pY29uLnBuZ1wiKTtcblx0ICogXG5cdCAqL1xuICAgIGNsZWFyU2VxdWVuY2U6IGZ1bmN0aW9uICggc2hvd01lc3NhZ2UsIGljb24gKSB7XG4gICAgXHRcbiAgICBcdHZhciBtZXNzYWdlID0gdW5kZWZpbmVkO1xuICAgIFx0XHRcbiAgICBcdHRoaXMub3B0LnNlcXVlbmNlID0gXCJcIjtcbiAgICBcdHRoaXMub3B0LmlkID0gXCJcIjsgXG4gICAgXHR0aGlzLl9oaWdobGlnaHRzID0gW107XG5cdFx0dGhpcy5faGlnaGxpZ2h0c0NvdW50ID0gMDtcblx0XHR0aGlzLm9wdC5zZWxlY3Rpb24gPSB7IHN0YXJ0OiAwLCBlbmQ6IDAgfTtcblx0XHR0aGlzLl9hbm5vdGF0aW9ucyA9IFtdO1xuXHRcdHRoaXMuX2NvbnRlbnREaXYuY2hpbGRyZW4oKS5yZW1vdmUoKTtcblx0XHRcblx0XHR0aGlzLl9oZWFkZXJEaXYuaGlkZSgpO1xuXHRcdFxuXHRcdGlmICggdW5kZWZpbmVkICE9PSBzaG93TWVzc2FnZSApIHtcblx0XHRcdG1lc3NhZ2UgPSBqUXVlcnkoJzxkaXY+JyArIHNob3dNZXNzYWdlICsgJzwvZGl2PicpXG5cdFx0XHRcdC5hcHBlbmRUbyh0aGlzLl9jb250ZW50RGl2KVxuXHRcdFx0XHQuYWRkQ2xhc3MoXCJtZXNzYWdlXCIpO1xuXHRcdFx0XG5cdFx0XHRpZiAoIHVuZGVmaW5lZCAhPT0gaWNvbiApIHtcblx0XHRcdFx0bWVzc2FnZS5jc3Moe1xuXHRcdFx0XHRcdCdiYWNrZ3JvdW5kJzogJ3RyYW5zcGFyZW50IHVybChcIicgKyBpY29uICsgJ1wiKSBuby1yZXBlYXQgY2VudGVyIGxlZnQnLFxuXHRcdFx0XHRcdCdwYWRkaW5nLWxlZnQnOiAnMjBweCdcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuICAgIH0sXG5cdFxuXHQvKipcbiAgICAqIFNldCB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIHNlcXVlbmNlIGNhdXNpbmcgdGhlIGV2ZW50IHtAbGluayBTZXF1ZW5jZSNvblNlbGVjdGlvbkNoYW5nZWR9XG4gICAgKlxuICAgICogQGV4YW1wbGVcbiAgICAqIC8vIHNldCBzZWxlY3Rpb24gZnJvbSB0aGUgcG9zaXRpb24gMTAwIHRvIDE1MCBcbiAgICAqIG15U2VxdWVuY2Uuc2V0U2VsZWN0aW9uKDEwMCwgMTUwKTtcbiAgICAqIFxuICAgICogQHBhcmFtIHtpbnR9IHN0YXJ0IFRoZSBzdGFydGluZyBjaGFyYWN0ZXIgb2YgdGhlIHNlbGVjdGlvbi5cbiAgICAqIEBwYXJhbSB7aW50fSBlbmQgVGhlIGVuZGluZyBjaGFyYWN0ZXIgb2YgdGhlIHNlbGVjdGlvblxuICAgICovXG5cdHNldFNlbGVjdGlvbiA6IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcblx0XHRpZihzdGFydCA+IGVuZCkge1xuXHRcdFx0dmFyIGF1eCA9IGVuZDtcblx0XHRcdGVuZCA9IHN0YXJ0O1xuXHRcdFx0c3RhcnQgPSBhdXg7XG5cblx0XHR9XG5cblx0XHRpZihzdGFydCAhPSB0aGlzLm9wdC5zZWxlY3Rpb24uc3RhcnQgfHwgZW5kICE9IHRoaXMub3B0LnNlbGVjdGlvbi5lbmQpIHtcblx0XHRcdHRoaXMuX3NldFNlbGVjdGlvbihzdGFydCwgZW5kKTtcblx0XHRcdHRoaXMudHJpZ2dlcihcblx0XHRcdFx0XHRFVlRfT05fU0VMRUNUSU9OX0NIQU5HRUQsIFxuXHRcdFx0XHRcdHsgXCJzdGFydFwiIDogc3RhcnQsIFwiZW5kXCIgOiBlbmQgfVxuXHRcdFx0KTtcblx0XHR9XG5cdH0sXG5cdFxuXHRfYnVpbGRGb3JtYXRTZWxlY3RvcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRcblx0XHR0aGlzLl9oZWFkZXJEaXYgPSBqUXVlcnkoJzxkaXY+PC9kaXY+JykuYXBwZW5kVG8odGhpcy5fY29udGFpbmVyKTtcblx0XHR0aGlzLl9oZWFkZXJEaXYuY3NzKHtcblx0XHRcdCdmb250LWZhbWlseSc6ICdcIkhldmVsdGljYSBOZXVlXCIsIEFyaWFsLCBcInNhbnMgc2VyaWZcIicsXG5cdFx0XHQnZm9udC1zaXplJzogJzE0cHgnXHRcblx0XHR9KS5hcHBlbmQoJ0Zvcm1hdDogJyk7XG5cdFx0XG5cdFx0dGhpcy5fZm9ybWF0U2VsZWN0b3IgPSBqUXVlcnkoJzxzZWxlY3Q+ICcrXG5cdFx0XHRcdCc8b3B0aW9uIHZhbHVlPVwiRkFTVEFcIj5GQVNUQTwvb3B0aW9uPicrXG5cdFx0XHRcdCc8b3B0aW9uIHZhbHVlPVwiQ09EQVRBXCI+Q09EQVRBPC9vcHRpb24+Jytcblx0XHRcdFx0JzxvcHRpb24gdmFsdWU9XCJQUklERVwiPlBSSURFPC9vcHRpb24+Jytcblx0XHRcdFx0JzxvcHRpb24gdmFsdWU9XCJSQVdcIj5SQVc8L29wdGlvbj48L3NlbGVjdD4nKS5hcHBlbmRUbyhzZWxmLl9oZWFkZXJEaXYpO1xuXG5cdFx0dGhpcy5fZm9ybWF0U2VsZWN0b3IuY2hhbmdlKGZ1bmN0aW9uKGUpIHtcblx0XHRcdHNlbGYub3B0LmZvcm1hdCA9IGpRdWVyeSh0aGlzKS52YWwoKTtcblx0XHRcdHNlbGYuX3JlZHJhdygpO1xuXHRcdH0pO1xuXHRcdFxuXHRcdHRoaXMuX2Zvcm1hdFNlbGVjdG9yLnZhbChzZWxmLm9wdC5mb3JtYXQpO1x0XG5cdFx0XG5cdFx0dGhpcy5mb3JtYXRTZWxlY3RvclZpc2libGUoIHRoaXMub3B0LmZvcm1hdFNlbGVjdG9yVmlzaWJsZSApO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBIaWdobGlnaHRzIGEgcmVnaW9uIHVzaW5nIHRoZSBmb250IGNvbG9yIGRlZmluZWQgaW4ge0Jpb2pzLlByb3RlaW4zRCNoaWdobGlnaHRGb250Q29sb3J9IGJ5IGRlZmF1bHQgaXMgcmVkLlxuICAgICpcbiAgICAqIEBkZXByZWNhdGVkIHVzZSBhZGRIaWdobGlnaHQgaW5zdGVhZC5cbiAgICAqIFxuICAgICogQHBhcmFtIHtpbnR9IHN0YXJ0IFRoZSBzdGFydGluZyBjaGFyYWN0ZXIgb2YgdGhlIGhpZ2hsaWdodGluZy5cbiAgICAqIEBwYXJhbSB7aW50fSBlbmQgVGhlIGVuZGluZyBjaGFyYWN0ZXIgb2YgdGhlIGhpZ2hsaWdodGluZy5cbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY29sb3JdIEhUTUwgY29sb3IgY29kZS5cbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBbYmFja2dyb3VuZF0gSFRNTCBjb2xvciBjb2RlLlxuICAgICogQHBhcmFtIHtzdHJpbmd9IFtpZF0gQ3VzdG9tIGlkZW50aWZpZXIuXG4gICAgKiBcbiAgICAqIEByZXR1cm4ge2ludH0gcmVwcmVzZW50aW5nIHRoZSBpZCBvZiB0aGUgaGlnaGxpZ2h0IG9uIHRoZSBpbnRlcm5hbCBhcnJheS4gUmV0dXJucyAtMSBvbiBmYWlsdXJlICBcbiAgICAqL1xuXHRoaWdobGlnaHQgOiBmdW5jdGlvbiAoc3RhcnQsIGVuZCwgY29sb3IsIGJhY2tncm91bmQsIGlkICkge1xuXHRcdHJldHVybiB0aGlzLmFkZEhpZ2hsaWdodCh7IFwic3RhcnRcIjogc3RhcnQsIFwiZW5kXCI6IGVuZCwgXCJjb2xvclwiOiBjb2xvciwgXCJiYWNrZ3JvdW5kXCI6IGJhY2tncm91bmQsIFwiaWRcIjogaWQgfSk7XG5cdH0sXG5cdFxuXHQvKipcbiAgICAqIEhpZ2hsaWdodHMgYSByZWdpb24gdXNpbmcgdGhlIGZvbnQgY29sb3IgZGVmaW5lZCBpbiB7U2VxdWVuY2UjaGlnaGxpZ2h0Rm9udENvbG9yfSBieSBkZWZhdWx0IGlzIHJlZC5cbiAgICAqXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gaGlnaGxpZ2h0IHRoZSBjaGFyYWN0ZXJzIHdpdGhpbiB0aGUgcG9zaXRpb24gMTAwIHRvIDE1MCwgaW5jbHVkZWQuXG4gICAgKiBteVNlcXVlbmNlLmFkZEhpZ2hsaWdodCggeyBcInN0YXJ0XCI6IDEwMCwgXCJlbmRcIjogMTUwLCBcImNvbG9yXCI6IFwid2hpdGVcIiwgXCJiYWNrZ3JvdW5kXCI6IFwicmVkXCIsIFwiaWRcIjogXCJhYWFcIiB9ICk7XG4gICAgKiBcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBoIFRoZSBoaWdobGlnaHQgZGVmaW5lZCBhcyBmb2xsb3dzOlxuICAgICogXHRcbiAgICAqIFxuICAgICogQHJldHVybiB7aW50fSByZXByZXNlbnRpbmcgdGhlIGlkIG9mIHRoZSBoaWdobGlnaHQgb24gdGhlIGludGVybmFsIGFycmF5LiBSZXR1cm5zIC0xIG9uIGZhaWx1cmUgIFxuICAgICovXG5cdGFkZEhpZ2hsaWdodCA6IGZ1bmN0aW9uICggaCApIHtcblx0XHR2YXIgaWQgPSAnLTEnO1xuXHRcdHZhciBjb2xvciA9IFwiXCI7XG5cdFx0dmFyIGJhY2tncm91bmQgPSBcIlwiO1xuXHRcdHZhciBoaWdobGlnaHQgPSB7fTtcblx0XHRcblx0XHRpZiAoIGggaW5zdGFuY2VvZiBPYmplY3QgJiYgaC5zdGFydCA8PSBoLmVuZCApIHtcblx0XHRcdFxuXHRcdFx0Y29sb3IgPSAoIFwic3RyaW5nXCIgPT0gdHlwZW9mIGguY29sb3IgKT8gaC5jb2xvciA6IHRoaXMub3B0LmhpZ2hsaWdodEZvbnRDb2xvcjtcblx0XHRcdGJhY2tncm91bmQgPSAoIFwic3RyaW5nXCIgPT0gdHlwZW9mIGguYmFja2dyb3VuZCApPyBoLmJhY2tncm91bmQgOiB0aGlzLm9wdC5oaWdobGlnaHRCYWNrZ3JvdW5kQ29sb3I7XG5cdFx0XHRpZCA9ICggXCJzdHJpbmdcIiA9PSB0eXBlb2YgaC5pZCApPyBoLmlkIDogKG5ldyBOdW1iZXIodGhpcy5faGlnaGxpZ2h0c0NvdW50KyspKS50b1N0cmluZygpO1xuXHRcdFx0XG5cdFx0XHRoaWdobGlnaHQgPSB7IFwic3RhcnRcIjogaC5zdGFydCwgXCJlbmRcIjogaC5lbmQsIFwiY29sb3JcIjogY29sb3IsIFwiYmFja2dyb3VuZFwiOiBiYWNrZ3JvdW5kLCBcImlkXCI6IGlkIH07XG5cdFx0XHRcblx0XHRcdHRoaXMuX2hpZ2hsaWdodHMucHVzaChoaWdobGlnaHQpO1xuXHRcdFx0dGhpcy5fYXBwbHlIaWdobGlnaHQoaGlnaGxpZ2h0KTtcblx0XHRcdHRoaXMuX3Jlc3RvcmVTZWxlY3Rpb24oaC5zdGFydCxoLmVuZCk7XG5cdFx0fSBcblx0XHRcblx0XHRyZXR1cm4gaWQ7XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fYXBwbHlIaWdobGlnaHRcbiAgICAgKiBQdXJwb3NlOiAgQXBwbHkgdGhlIHNwZWNpZmllZCBjb2xvciBhbmQgYmFja2dyb3VuZCB0byBhIHJlZ2lvbiBiZXR3ZWVuICdzdGFydCcgYW5kICdlbmQnLlxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiBoaWdobGlnaHQgLT4ge09iamVjdH0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkcyBzdGFydCAoaW50KSwgZW5kIChpbnQpLCBcbiAgICAgKiBcdFx0XHRcdFx0XHRjb2xvciAoSFRNTCBjb2xvciBzdHJpbmcpIGFuZCBiYWNrZ3JvdW5kIChIVE1MIGNvbG9yIHN0cmluZykuXG4gICAgICovXG5cdF9hcHBseUhpZ2hsaWdodDogZnVuY3Rpb24gKCBoaWdobGlnaHQgKSB7XHRcdFxuXHRcdHZhciBzZXEgPSB0aGlzLl9jb250ZW50RGl2LmZpbmQoJy5zZXF1ZW5jZScpO1xuXHRcdGZvciAoIHZhciBpID0gaGlnaGxpZ2h0LnN0YXJ0IC0gMTsgaSA8IGhpZ2hsaWdodC5lbmQ7IGkrKyApe1xuXHRcdFx0emluZGV4ID0galF1ZXJ5KHNlcVtpXSkuY3NzKFwiei1pbmRleFwiKTtcblx0XHRcdGlmICh6aW5kZXg9PVwiYXV0b1wiKXtcblx0XHRcdFx0IHogPSAxO1xuXHRcdFx0XHQgbyA9IDE7XG5cdFx0XHQgfVxuXHRcdFx0IGVsc2V7XG5cdFx0XHRcdCB6ID0gMDtcblx0XHRcdFx0IG8gPSAwLjU7XG5cdFx0XHQgfVxuXHRcdFx0alF1ZXJ5KHNlcVtpXSlcblx0XHRcdFx0LmNzcyh7IFxuXHRcdFx0XHRcdFwiY29sb3JcIjogaGlnaGxpZ2h0LmNvbG9yLFxuXHRcdFx0XHRcdFwiYmFja2dyb3VuZC1jb2xvclwiOiBoaWdobGlnaHQuYmFja2dyb3VuZCxcblx0XHRcdFx0XHRcInotaW5kZXhcIjogeixcblx0XHRcdFx0XHRcIm9wYWNpdHlcIjogb1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGRDbGFzcyhcImhpZ2hsaWdodGVkXCIpO1xuXHRcdH1cblx0fSxcblx0LyogXG4gICAgICogRnVuY3Rpb246IFNlcXVlbmNlLl9hcHBseUhpZ2hsaWdodHNcbiAgICAgKiBQdXJwb3NlOiAgQXBwbHkgdGhlIHNwZWNpZmllZCBoaWdobGlnaHRzLlxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiBoaWdobGlnaHRzIC0+IHtPYmplY3RbXX0gQW4gYXJyYXkgY29udGFpbmluZyB0aGUgaGlnaGxpZ2h0cyB0byBiZSBhcHBsaWVkLlxuICAgICAqL1xuXHRfYXBwbHlIaWdobGlnaHRzOiBmdW5jdGlvbiAoIGhpZ2hsaWdodHMgKSB7XG5cdFx0Zm9yICggdmFyIGkgaW4gaGlnaGxpZ2h0cyApIHtcblx0XHRcdHRoaXMuX2FwcGx5SGlnaGxpZ2h0KGhpZ2hsaWdodHNbaV0pO1xuXHRcdH1cblx0fSxcblx0LyogXG4gICAgICogRnVuY3Rpb246IFNlcXVlbmNlLl9yZXN0b3JlSGlnaGxpZ2h0c1xuICAgICAqIFB1cnBvc2U6ICBSZXBhaW50IHRoZSBoaWdobGlnaHRzIGluIHRoZSBzcGVjaWZpZWQgcmVnaW9uLlxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiBzdGFydCAtPiB7aW50fSBTdGFydCBvZiB0aGUgcmVnaW9uIHRvIGJlIHJlc3RvcmVkLlxuICAgICAqIFx0XHQgICBlbmQgLT4ge2ludH0gRW5kIG9mIHRoZSByZWdpb24gdG8gYmUgcmVzdG9yZWQuXG4gICAgICovXG5cdF9yZXN0b3JlSGlnaGxpZ2h0czogZnVuY3Rpb24gKCBzdGFydCwgZW5kICkge1xuXHRcdHZhciBoID0gdGhpcy5faGlnaGxpZ2h0cztcblx0XHQvLyBwYWludCB0aGUgcmVnaW9uIHVzaW5nIGRlZmF1bHQgYmxhbmsgc2V0dGluZ3Ncblx0XHR0aGlzLl9hcHBseUhpZ2hsaWdodCh7XG5cdFx0XHRcInN0YXJ0XCI6IHN0YXJ0LCBcblx0XHRcdFwiZW5kXCI6IGVuZCwgXG5cdFx0XHRcImNvbG9yXCI6IHRoaXMub3B0LmZvbnRDb2xvciwgXG5cdFx0XHRcImJhY2tncm91bmRcIjogdGhpcy5vcHQuYmFja2dyb3VuZENvbG9yIFxuXHRcdH0pO1xuXHRcdC8vIHJlc3RvcmUgaGlnaGxpZ2h0cyBpbiB0aGF0IHJlZ2lvblxuXHRcdGZvciAoIHZhciBpIGluIGggKSB7XG5cdFx0XHQvLyBpbnRlcnZhbCBpbnRlcnNlY3RzIHdpdGggaGlnaGxpZ2h0IGkgP1xuXHRcdFx0aWYgKCAhKCBoW2ldLnN0YXJ0ID4gZW5kIHx8IGhbaV0uZW5kIDwgc3RhcnQgKSApIHtcblx0XHRcdFx0YSA9ICggaFtpXS5zdGFydCA8IHN0YXJ0ICkgPyBzdGFydCA6IGhbaV0uc3RhcnQ7XG5cdFx0XHRcdGIgPSAoIGhbaV0uZW5kID4gZW5kICkgPyBlbmQgOiBoW2ldLmVuZDtcblx0XHRcdFx0dGhpcy5fYXBwbHlIaWdobGlnaHQoe1xuXHRcdFx0XHRcdFwic3RhcnRcIjogYSwgXG5cdFx0XHRcdFx0XCJlbmRcIjogYiwgXG5cdFx0XHRcdFx0XCJjb2xvclwiOiBoW2ldLmNvbG9yLCBcblx0XHRcdFx0XHRcImJhY2tncm91bmRcIjogaFtpXS5iYWNrZ3JvdW5kIFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fcmVzdG9yZVNlbGVjdGlvblxuICAgICAqIFB1cnBvc2U6ICBSZXBhaW50IHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbiB0aGUgc3BlY2lmaWVkIHJlZ2lvbi4gXG4gICAgICogXHRcdFx0IEl0IGlzIHVzZWQgaW4gdGhlIGNhc2Ugb2YgYW55IGhpZ2hsaWdodCBkbyBvdmVycmlkaW5nIG9mIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IHN0YXJ0IC0+IHtpbnR9IFN0YXJ0IG9mIHRoZSByZWdpb24gdG8gYmUgcmVzdG9yZWQuXG4gICAgICogXHRcdCAgIGVuZCAtPiB7aW50fSBFbmQgb2YgdGhlIHJlZ2lvbiB0byBiZSByZXN0b3JlZC5cbiAgICAgKi9cblx0X3Jlc3RvcmVTZWxlY3Rpb246IGZ1bmN0aW9uICggc3RhcnQsIGVuZCApIHtcblx0XHR2YXIgc2VsID0gdGhpcy5vcHQuc2VsZWN0aW9uO1xuXHRcdC8vIGludGVydmFsIGludGVyc2VjdHMgd2l0aCBjdXJyZW50IHNlbGVjdGlvbiA/XG5cdFx0Ly8gcmVzdG9yZSBzZWxlY3Rpb25cblx0XHRpZiAoICEoIHN0YXJ0ID4gc2VsLmVuZCB8fCBlbmQgPCBzZWwuc3RhcnQgKSApIHtcblx0XHRcdGEgPSAoIHN0YXJ0IDwgc2VsLnN0YXJ0ICkgPyBzZWwuc3RhcnQgOiBzdGFydDtcblx0XHRcdGIgPSAoIGVuZCA+IHNlbC5lbmQgKSA/IHNlbC5lbmQgOiBlbmQ7XG5cdFx0XHRcblx0XHRcdHRoaXMuX2FwcGx5SGlnaGxpZ2h0KHtcblx0XHRcdFx0XCJzdGFydFwiOiBhLCBcblx0XHRcdFx0XCJlbmRcIjogYiwgXG5cdFx0XHRcdFwiY29sb3JcIjogdGhpcy5vcHQuc2VsZWN0aW9uRm9udENvbG9yLCBcblx0XHRcdFx0XCJiYWNrZ3JvdW5kXCI6IHRoaXMub3B0LnNlbGVjdGlvbkNvbG9yLFxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBDbGVhciBhIGhpZ2hsaWdodGVkIHJlZ2lvbiB1c2luZy5cbiAgICAqXG4gICAgKiBAZGVwcmVjYXRlZCB1c2UgcmVtb3ZlSGlnaGxpZ2h0IGluc3RlYWQuXG4gICAgKiBcbiAgICAqIEBwYXJhbSB7aW50fSBpZCBUaGUgaWQgb2YgdGhlIGhpZ2hsaWdodCBvbiB0aGUgaW50ZXJuYWwgYXJyYXkuIFRoaXMgdmFsdWUgaXMgcmV0dXJuZWQgYnkgbWV0aG9kIGhpZ2hsaWdodC5cbiAgICAqL1xuXHR1bkhpZ2hsaWdodCA6IGZ1bmN0aW9uIChpZCkge1x0XG5cdFx0dGhpcy5yZW1vdmVIaWdobGlnaHQoaWQpO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBSZW1vdmUgYSBoaWdobGlnaHQuXG4gICAgKlxuICAgICogQGV4YW1wbGVcbiAgICAqIC8vIENsZWFyIHRoZSBoaWdobGlnaHRlZCBjaGFyYWN0ZXJzIHdpdGhpbiB0aGUgcG9zaXRpb24gMTAwIHRvIDE1MCwgaW5jbHVkZWQuXG4gICAgKiBteVNlcXVlbmNlLnJlbW92ZUhpZ2hsaWdodChcInNwaW4xXCIpO1xuICAgICogXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIGlkIG9mIHRoZSBoaWdobGlnaHQgb24gdGhlIGludGVybmFsIGFycmF5LiBUaGlzIHZhbHVlIGlzIHJldHVybmVkIGJ5IG1ldGhvZCBoaWdobGlnaHQuXG4gICAgKi9cblx0cmVtb3ZlSGlnaGxpZ2h0IDogZnVuY3Rpb24gKGlkKSB7XHRcblx0XHR2YXIgaCA9IHRoaXMuX2hpZ2hsaWdodHM7XG5cdFx0Zm9yICggaSBpbiBoICkge1xuXHRcdFx0aWYgKCBoW2ldLmlkID09IGlkICkge1xuXHRcdFx0XHRzdGFydCA9IGhbaV0uc3RhcnQ7XG5cdFx0XHRcdGVuZCA9IGhbaV0uZW5kO1xuXHRcdFx0XHRoLnNwbGljZShpLDEpO1xuXHRcdFx0XHRcblx0XHRcdFx0dGhpcy5fcmVzdG9yZUhpZ2hsaWdodHMoc3RhcnQsZW5kKTtcblx0XHRcdFx0dGhpcy5fcmVzdG9yZVNlbGVjdGlvbihzdGFydCxlbmQpO1xuXHRcdFx0XHRcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBDbGVhciB0aGUgaGlnaGxpZ2h0cyBvZiB3aG9sZSBzZXF1ZW5jZS5cbiAgICAqIEBkZXByZWNhdGVkIHVzZSByZW1vdmVBbGxIaWdobGlnaHRzIGluc3RlYWQuXG4gICAgKi9cblx0dW5IaWdobGlnaHRBbGwgOiBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5yZW1vdmVBbGxIaWdobGlnaHRzKCk7XG5cdH0sXG5cdFxuXHQvKipcbiAgICAqIFJlbW92ZSBhbGwgdGhlIGhpZ2hsaWdodHMgb2Ygd2hvbGUgc2VxdWVuY2UuXG4gICAgKlxuICAgICogQGV4YW1wbGVcbiAgICAqIG15U2VxdWVuY2UucmVtb3ZlQWxsSGlnaGxpZ2h0cygpO1xuICAgICovXG5cdHJlbW92ZUFsbEhpZ2hsaWdodHMgOiBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5faGlnaGxpZ2h0cyA9IFtdO1xuXHRcdHRoaXMuX3Jlc3RvcmVIaWdobGlnaHRzKDEsdGhpcy5vcHQuc2VxdWVuY2UubGVuZ3RoKTtcblx0XHR0aGlzLl9yZXN0b3JlU2VsZWN0aW9uKDEsdGhpcy5vcHQuc2VxdWVuY2UubGVuZ3RoKTtcblx0fSxcblx0XG5cdC8qKlxuICAgICogQ2hhbmdlcyB0aGUgY3VycmVudCBkaXNwbGF5aW5nIGZvcm1hdCBvZiB0aGUgc2VxdWVuY2UuXG4gICAgKlxuICAgICogQGV4YW1wbGVcbiAgICAqIC8vIFNldCBmb3JtYXQgdG8gJ0ZBU1RBJy5cbiAgICAqIG15U2VxdWVuY2Uuc2V0Rm9ybWF0KCdGQVNUQScpO1xuICAgICogXG4gICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IFRoZSBmb3JtYXQgZm9yIHRoZSBzZXF1ZW5jZSB0byBiZSBkaXNwbGF5ZWQuXG4gICAgKi9cblx0c2V0Rm9ybWF0IDogZnVuY3Rpb24oZm9ybWF0KSB7XG5cdFx0aWYgKCB0aGlzLm9wdC5mb3JtYXQgIT0gZm9ybWF0LnRvVXBwZXJDYXNlKCkgKSB7XG5cdFx0XHR0aGlzLm9wdC5mb3JtYXQgPSBmb3JtYXQudG9VcHBlckNhc2UoKTtcblx0XHRcdHRoaXMuX3JlZHJhdygpO1xuXHRcdH1cblxuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHQvLyBDaGFuZ2VzIHRoZSBvcHRpb24gaW4gdGhlIGNvbWJvIGJveFxuXHRcdHRoaXMuX2hlYWRlckRpdi5maW5kKCdvcHRpb24nKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYoalF1ZXJ5KHRoaXMpLnZhbCgpID09IHNlbGYub3B0LmZvcm1hdC50b1VwcGVyQ2FzZSgpKSB7XG5cdFx0XHRcdGpRdWVyeSh0aGlzKS5hdHRyKCdzZWxlY3RlZCcsICdzZWxlY3RlZCcpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBDaGFuZ2VzIHRoZSBjdXJyZW50IG51bWJlciBvZiBjb2x1bW5zIGluIHRoZSBkaXNwbGF5ZWQgc2VxdWVuY2UuXG4gICAgKlxuICAgICogQGV4YW1wbGVcbiAgICAqIC8vIFNldCB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgdG8gNzAuXG4gICAgKiBteVNlcXVlbmNlLnNldE51bUNvbHMoNzApO1xuICAgICogXG4gICAgKiBAcGFyYW0ge2ludH0gbnVtQ29scyBUaGUgbnVtYmVyIG9mIGNvbHVtbnMuXG4gICAgKi9cblx0c2V0TnVtQ29scyA6IGZ1bmN0aW9uKG51bUNvbHMpIHtcblx0XHR0aGlzLm9wdC5jb2x1bW5zLnNpemUgPSBudW1Db2xzO1xuXHRcdHRoaXMuX3JlZHJhdygpO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBTZXQgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGRyb3AtZG93biBsaXN0IG9mIGZvcm1hdHMuXG4gICAgKiBcbiAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdmlzaWJsZSB0cnVlOiBzaG93OyBmYWxzZTogaGlkZS5cbiAgICAqL1xuXHRmb3JtYXRTZWxlY3RvclZpc2libGUgOiBmdW5jdGlvbiAodmlzaWJsZSl7XG5cdFx0aWYgKHZpc2libGUpIHtcblx0XHRcdHRoaXMuX2hlYWRlckRpdi5zaG93KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX2hlYWRlckRpdi5oaWRlKCk7XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBUaGlzIGlzIHNpbWlsYXIgdG8gYSB7QmlvanMuUHJvdGVpbjNEI2Zvcm1hdFNlbGVjdG9yVmlzaWJsZX0gd2l0aCB0aGUgJ3RydWUnIGFyZ3VtZW50LlxuICAgICpcbiAgICAqIEBleGFtcGxlXG4gICAgKiAvLyBTaG93cyB0aGUgZm9ybWF0IHNlbGVjdG9yLlxuICAgICogbXlTZXF1ZW5jZS5zaG93Rm9ybWF0U2VsZWN0b3IoKTtcbiAgICAqIFxuICAgICovXG5cdHNob3dGb3JtYXRTZWxlY3RvciA6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuX2hlYWRlckRpdi5zaG93KCk7XG5cdH0sXG5cdFxuXHQvKipcbiAgICAqIFRoaXMgaXMgc2ltaWxhciB0byBhIHtCaW9qcy5Qcm90ZWluM0QjZm9ybWF0U2VsZWN0b3JWaXNpYmxlfSB3aXRoIHRoZSAnZmFsc2UnIGFyZ3VtZW50LlxuICAgICogXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gSGlkZXMgdGhlIGZvcm1hdCBzZWxlY3Rvci5cbiAgICAqIG15U2VxdWVuY2UuaGlkZUZvcm1hdFNlbGVjdG9yKCk7XG4gICAgKiBcbiAgICAqL1xuXHRoaWRlRm9ybWF0U2VsZWN0b3IgOiBmdW5jdGlvbigpIHtcblx0XHR0aGlzLl9oZWFkZXJEaXYuaGlkZSgpO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBIaWRlcyB0aGUgd2hvbGUgY29tcG9uZW50LlxuICAgICogXG4gICAgKi9cblx0aGlkZSA6IGZ1bmN0aW9uICgpIHtcblx0XHR0aGlzLl9oZWFkZXJEaXYuaGlkZSgpO1xuXHRcdHRoaXMuX2NvbnRlbnREaXYuaGlkZSgpO1xuXHR9LFxuXG5cdC8qKlxuICAgICogU2hvd3MgdGhlIHdob2xlIGNvbXBvbmVudC5cbiAgICAqIFxuICAgICovXG5cdHNob3cgOiBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5faGVhZGVyRGl2LnNob3coKTtcblx0XHR0aGlzLl9jb250ZW50RGl2LnNob3coKTtcblx0fSxcblx0LyogXG4gICAgICogRnVuY3Rpb246IFNlcXVlbmNlLl9zZXRTZWxlY3Rpb25cbiAgICAgKiBQdXJwb3NlOiAgVXBkYXRlIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IHN0YXJ0IC0+IHtpbnR9IFN0YXJ0IG9mIHRoZSByZWdpb24gdG8gYmUgc2VsZWN0ZWQuXG4gICAgICogXHRcdCAgIGVuZCAtPiB7aW50fSBFbmQgb2YgdGhlIHJlZ2lvbiB0byBiZSBzZWxlY3RlZC5cbiAgICAgKi9cblx0X3NldFNlbGVjdGlvbiA6IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcblx0XHQvL2FsZXJ0KFwiYWRzYXNcIik7XG5cdFx0XG5cdFx0dmFyIGN1cnJlbnQgPSB0aGlzLm9wdC5zZWxlY3Rpb247XG5cdFx0dmFyIGNoYW5nZSA9IHt9O1xuXHRcdFxuXHRcdC8vIFdoaWNoIGlzIHRoZSBjaGFuZ2Ugb24gc2VsZWN0aW9uP1xuXHRcdGlmICggY3VycmVudC5zdGFydCA9PSBzdGFydCApIHtcblx0XHRcdC8vIGZvcndhcmQ/XG5cdFx0XHRpZiAoIGN1cnJlbnQuZW5kIDwgZW5kICkge1xuXHRcdFx0XHRjaGFuZ2Uuc3RhcnQgPSBjdXJyZW50LmVuZDtcblx0XHRcdFx0Y2hhbmdlLmVuZCA9IGVuZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX3Jlc3RvcmVIaWdobGlnaHRzKGVuZCsxLCBjdXJyZW50LmVuZCk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICggY3VycmVudC5lbmQgPT0gZW5kICkge1xuXHRcdFx0Ly8gZm9yd2FyZD9cblx0XHRcdGlmICggY3VycmVudC5zdGFydCA+IHN0YXJ0ICkge1xuXHRcdFx0XHRjaGFuZ2Uuc3RhcnQgPSBzdGFydDtcblx0XHRcdFx0Y2hhbmdlLmVuZCA9IGN1cnJlbnQuc3RhcnQ7XHRcdFx0XHRcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX3Jlc3RvcmVIaWdobGlnaHRzKGN1cnJlbnQuc3RhcnQsIHN0YXJ0LTEpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9yZXN0b3JlSGlnaGxpZ2h0cyhjdXJyZW50LnN0YXJ0LCBjdXJyZW50LmVuZCk7XG5cdFx0XHRjaGFuZ2Uuc3RhcnQgPSBzdGFydDtcblx0XHRcdGNoYW5nZS5lbmQgPSBlbmQ7XG5cdFx0fVxuXG5cdFx0Y3VycmVudC5zdGFydCA9IHN0YXJ0O1xuXHRcdGN1cnJlbnQuZW5kID0gZW5kO1xuXG5cdFx0aWYgKCBjaGFuZ2Uuc3RhcnQgIT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dGhpcy5fYXBwbHlIaWdobGlnaHQoe1xuXHRcdFx0XHRcInN0YXJ0XCI6IGNoYW5nZS5zdGFydCwgXG5cdFx0XHRcdFwiZW5kXCI6IGNoYW5nZS5lbmQsIFxuXHRcdFx0XHRcImNvbG9yXCI6IHRoaXMub3B0LnNlbGVjdGlvbkZvbnRDb2xvciwgXG5cdFx0XHRcdFwiYmFja2dyb3VuZFwiOiB0aGlzLm9wdC5zZWxlY3Rpb25Db2xvciBcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRcblx0fSxcblx0XG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fcmVwYWludFNlbGVjdGlvblxuICAgICAqIFB1cnBvc2U6ICBSZXBhaW50IHRoZSB3aG9sZSBjdXJyZW50IHNlbGVjdGlvbi4gXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IC1cbiAgICAgKi9cblx0X3JlcGFpbnRTZWxlY3Rpb246IGZ1bmN0aW9uKCl7XG5cdFx0dmFyIHMgPSB0aGlzLm9wdC5zZWxlY3Rpb247XG5cdFx0dGhpcy5fc2V0U2VsZWN0aW9uKDAsMCk7XG5cdFx0dGhpcy5fc2V0U2VsZWN0aW9uKHMuc3RhcnQscy5lbmQpO1xuXHR9LFxuXHRcblx0LyogXG4gICAgICogRnVuY3Rpb246IFNlcXVlbmNlLl9yZWRyYXdcbiAgICAgKiBQdXJwb3NlOiAgUmVwYWludCB0aGUgY3VycmVudCBzZXF1ZW5jZS4gXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IC1cbiAgICAgKi9cblx0X3JlZHJhdyA6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBpID0gMDtcdFxuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRcblx0XHQvLyBSZXNldCB0aGUgY29udGVudFxuXHRcdC8vdGhpcy5fY29udGVudERpdi50ZXh0KCcnKTtcblx0XHR0aGlzLl9jb250ZW50RGl2LmNoaWxkcmVuKCkucmVtb3ZlKCk7XG5cdFx0XG5cdFx0Ly8gUmVidWlsZCB0aGUgc3BhbnMgb2YgdGhlIHNlcXVlbmNlIFxuXHRcdC8vIGFjY29yZGluZyB0byBmb3JtYXRcblx0XHRpZih0aGlzLm9wdC5mb3JtYXQgPT0gJ1JBVycpIHtcblx0XHRcdHRoaXMuX2RyYXdSYXcoKTtcblx0XHR9IGVsc2UgaWYodGhpcy5vcHQuZm9ybWF0ID09ICdDT0RBVEEnKSB7XG5cdFx0XHR0aGlzLl9kcmF3Q29kYXRhKCk7XG5cdFx0fSBlbHNlIGlmICh0aGlzLm9wdC5mb3JtYXQgPT0gJ0ZBU1RBJyl7XG5cdFx0XHR0aGlzLl9kcmF3RmFzdGEoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5vcHQuZm9ybWF0ID0gJ1BSSURFJztcblx0XHRcdHRoaXMuX2RyYXdQcmlkZSgpO1xuXHRcdH1cblx0XHRcblx0XHQvLyBSZXN0b3JlIHRoZSBoaWdobGlnaHRlZCByZWdpb25zXG5cdFx0dGhpcy5fYXBwbHlIaWdobGlnaHRzKHRoaXMuX2hpZ2hsaWdodHMpO1xuXHRcdHRoaXMuX3JlcGFpbnRTZWxlY3Rpb24oKTtcblx0XHR0aGlzLl9hZGRTcGFuRXZlbnRzKCk7XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZHJhd0Zhc3RhXG4gICAgICogUHVycG9zZTogIFJlcGFpbnQgdGhlIGN1cnJlbnQgc2VxdWVuY2UgdXNpbmcgRkFTVEEgZm9ybWF0LiAgXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IC1cbiAgICAgKi9cblx0X2RyYXdGYXN0YSA6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgYSA9IHRoaXMub3B0LnNlcXVlbmNlLnRvVXBwZXJDYXNlKCkuc3BsaXQoJycpO1xuXHRcdHZhciBwcmUgPSBqUXVlcnkoJzxwcmU+PC9wcmU+JykuYXBwZW5kVG8odGhpcy5fY29udGVudERpdik7XG5cblx0XHR2YXIgaSA9IDE7XG5cdFx0dmFyIGFyciA9IFtdO1xuXHQgICAgdmFyIHN0ciA9ICc+JyArIHRoaXMub3B0LmlkICsgJyAnICsgYS5sZW5ndGggKyAnIGJwPGJyLz4nO1xuXHRcdFxuXHRcdC8qIENvcnJlY3QgY29sdW1uIHNpemUgaW4gY2FzZSB0aGUgc2VxdWVuY2UgaXMgYXMgc21hbGwgcGVwdGlkZSAqL1xuXHRcdHZhciBudW1Db2xzID0gdGhpcy5vcHQuY29sdW1ucy5zaXplO1xuXHRcdGlmICggdGhpcy5vcHQuc2VxdWVuY2UubGVuZ3RoIDwgdGhpcy5vcHQuY29sdW1ucy5zaXplICkge1xuXHRcdFx0bnVtQ29scyA9IHRoaXMub3B0LnNlcXVlbmNlLmxlbmd0aDtcdFxuXHRcdH1cblx0XHRcblx0ICAgIHZhciBvcHQgPSB7XG5cdFx0XHRudW1Db2xzOiBudW1Db2xzLFxuXHRcdCAgICBudW1Db2xzRm9yU3BhY2U6IDBcblx0XHR9O1xuXG5cdFx0c3RyICs9IHRoaXMuX2RyYXdTZXF1ZW5jZShhLCBvcHQpO1xuXHRcdHByZS5odG1sKHN0cik7XG5cdFx0XG5cdFx0dGhpcy5fZHJhd0Fubm90YXRpb25zKG9wdCk7XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZHJhd0NvZGF0YVxuICAgICAqIFB1cnBvc2U6ICBSZXBhaW50IHRoZSBjdXJyZW50IHNlcXVlbmNlIHVzaW5nIENPREFUQSBmb3JtYXQuICBcbiAgICAgKiBSZXR1cm5zOiAgLVxuICAgICAqIElucHV0czogLVxuICAgICAqL1xuXHRfZHJhd0NvZGF0YSA6IGZ1bmN0aW9uKCkge1xuXHRcdFxuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgYSA9IHRoaXMub3B0LnNlcXVlbmNlLnRvVXBwZXJDYXNlKCkuc3BsaXQoJycpO1xuXHRcdHZhciBwcmUgPSBqUXVlcnkoJzxwcmUgc3R5bGU9XCJ3aGl0ZS1zcGFjZTpwcmVcIj48L3ByZT4nKS5hcHBlbmRUbyh0aGlzLl9jb250ZW50RGl2KTtcblxuXHRcdHZhciBpID0gMDtcblx0XHR2YXIgc3RyID0gJ0VOVFJZICAgICAgICAgICAnICsgdGhpcy5vcHQuaWQgKyAnPGJyLz4nO1xuXHRcdHN0ciArPSAnU0VRVUVOQ0U8YnIvPic7XG5cdFx0aWYgKCB0aGlzLm9wdC5mb3JtYXRPcHRpb25zICE9PSB1bmRlZmluZWQgKXtcblx0XHRcdGlmKHRoaXMub3B0LmZvcm1hdE9wdGlvbnMudGl0bGUgIT09IHVuZGVmaW5lZCApe1xuXHRcdFx0XHRpZiAodGhpcy5vcHQuZm9ybWF0T3B0aW9ucy50aXRsZSA9PSBmYWxzZSkge1xuXHRcdFx0XHRcdHN0ciA9ICcnO1xuXHRcdFx0XHR9XHRcdFx0XG5cdFx0XHR9XG5cdFx0fSBcblx0XHRcblx0XHQvKiBDb3JyZWN0IGNvbHVtbiBzaXplIGluIGNhc2UgdGhlIHNlcXVlbmNlIGlzIGFzIHNtYWxsIHBlcHRpZGUgKi9cblx0XHR2YXIgbnVtQ29scyA9IHRoaXMub3B0LmNvbHVtbnMuc2l6ZTtcblx0XHRpZiAoIHRoaXMub3B0LnNlcXVlbmNlLmxlbmd0aCA8IHRoaXMub3B0LmNvbHVtbnMuc2l6ZSApIHtcblx0XHRcdG51bUNvbHMgPSB0aGlzLm9wdC5zZXF1ZW5jZS5sZW5ndGg7XHRcblx0XHR9XG5cdFx0XG5cdFx0dmFyIG9wdCA9IHtcblx0XHRcdFx0bnVtTGVmdDogdHJ1ZSxcblx0XHRcdFx0bnVtTGVmdFNpemU6IDcsXG5cdFx0XHRcdG51bUxlZnRQYWQ6JyAnLFxuXHRcdFx0XHRudW1Ub3A6IHRydWUsXG5cdFx0XHRcdG51bVRvcEVhY2g6IDUsXG5cdFx0XHRcdG51bUNvbHM6IG51bUNvbHMsXG5cdFx0XHQgICAgbnVtQ29sc0ZvclNwYWNlOiAwLFxuXHRcdFx0ICAgIHNwYWNlQmV0d2VlbkNoYXJzOiB0cnVlXG5cdFx0fTtcblx0XHRcblx0XHRzdHIgKz0gdGhpcy5fZHJhd1NlcXVlbmNlKGEsIG9wdCk7XG5cdFx0XG5cdFx0dmFyIGZvb3RlciA9ICc8YnIvPi8vLyc7XG5cdFx0aWYgKHRoaXMub3B0LmZvcm1hdE9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0aWYgKHRoaXMub3B0LmZvcm1hdE9wdGlvbnMuZm9vdGVyICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0aWYgKHRoaXMub3B0LmZvcm1hdE9wdGlvbnMuZm9vdGVyID09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Zm9vdGVyID0gJyc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0c3RyICs9IGZvb3Rlcjtcblx0XHRwcmUuaHRtbChzdHIpO1xuXHRcdFxuXHRcdHRoaXMuX2RyYXdBbm5vdGF0aW9ucyhvcHQpO1xuXHR9LFxuXHQvKiBcbiAgICAgKiBGdW5jdGlvbjogU2VxdWVuY2UuX2RyYXdBbm5vdGF0aW9uc1xuICAgICAqIFB1cnBvc2U6ICBQYWludCB0aGUgYW5ub3RhdGlvbnMgb24gdGhlIHNlcXVlbmNlLiAgXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IHNldHRpbmdzIC0+IHtvYmplY3R9IFxuICAgICAqL1xuICAgIF9kcmF3QW5ub3RhdGlvbnM6IGZ1bmN0aW9uICggc2V0dGluZ3MgKXsgXG4gICAgXHRcbiAgICBcdHZhciBzZWxmID0gdGhpcztcbiAgICBcdHZhciBhID0gdGhpcy5vcHQuc2VxdWVuY2UudG9Mb3dlckNhc2UoKS5zcGxpdCgnJyk7ICAgIFx0XG4gICAgXHR2YXIgYW5ub3RhdGlvbnMgPSB0aGlzLl9hbm5vdGF0aW9ucztcbiAgICBcdHZhciBsZWZ0U3BhY2VzID0gJyc7XG4gICAgXHR2YXIgcm93ID0gJyc7XG4gICAgXHR2YXIgYW5ub3QgPSAnJztcbiAgICBcdFxuICAgIFx0Ly8gSW5kZXggYXQgdGhlIGxlZnQ/XG5cdFx0aWYgKCBzZXR0aW5ncy5udW1MZWZ0ICkge1xuXHRcdFx0bGVmdFNwYWNlcyArPSB0aGlzLl9mb3JtYXRJbmRleCgnICcsIHNldHRpbmdzLm51bUxlZnRTaXplKzIsICcgJyk7XG5cdFx0fVxuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkgKz0gc2V0dGluZ3MubnVtQ29scyApe1xuXHRcdFx0cm93ID0gJyc7XG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIGFubm90YXRpb25zICl7XG5cdFx0XHRcdGFubm90YXRpb25zW2tleV0uaWQgPSB0aGlzLmdldElkKCkgKyBcIl9cIiArIGtleTtcblx0XHRcdFx0YW5ub3QgPSB0aGlzLl9nZXRIVE1MUm93QW5ub3QoaSsxLCBhbm5vdGF0aW9uc1trZXldLCBzZXR0aW5ncyk7XHRcdFx0XHRcblx0XHRcdFx0aWYgKGFubm90Lmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRyb3cgKz0gJzxici8+Jztcblx0XHRcdFx0XHRyb3cgKz0gbGVmdFNwYWNlcztcblx0XHRcdFx0XHRyb3cgKz0gYW5ub3Q7XG5cdFx0XHRcdFx0cm93ICs9ICc8YnIvPic7XG5cdFx0XHRcdH0gXG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdHZhciBudW1Db2xzID0gc2V0dGluZ3MubnVtQ29scztcblx0XHRcdHZhciBjaGFyUmVtYWluaW5nID0gYS5sZW5ndGgtaTtcblx0XHRcdGlmKGNoYXJSZW1haW5pbmcgPCBudW1Db2xzKXtcblx0XHRcdFx0bnVtQ29sc1x0PSBjaGFyUmVtYWluaW5nO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHRpZiAoIHNldHRpbmdzLm51bVJpZ2h0ICkge1xuXHRcdFx0XHRqUXVlcnkocm93KS5pbnNlcnRBZnRlcignZGl2Iycrc2VsZi5vcHQudGFyZ2V0KycgZGl2IHByZSBzcGFuI251bVJpZ2h0XycgKyB0aGlzLmdldElkKCkgKyAnXycgKyAoaSArIG51bUNvbHMpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRqUXVlcnkocm93KS5pbnNlcnRBZnRlcignZGl2Iycrc2VsZi5vcHQudGFyZ2V0KycgZGl2IHByZSBzcGFuIycrIHRoaXMuZ2V0SWQoKSArICdfJyArIChpICsgbnVtQ29scykgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0XG5cdFx0Ly8gYWRkIHRvb2wgdGlwcyBhbmQgYmFja2dyb3VuZCcgY29sb3JpbmcgZWZmZWN0XG5cdFx0alF1ZXJ5KHRoaXMuX2NvbnRlbnREaXYpLmZpbmQoJy5hbm5vdGF0aW9uJykuZWFjaCggZnVuY3Rpb24oKXtcblx0XHRcdHNlbGYuX2FkZFRvb2xUaXAoIHRoaXMsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gc2VsZi5fZ2V0QW5ub3RhdGlvblN0cmluZyggalF1ZXJ5KHRoaXMpLmF0dHIoXCJpZFwiKSApO1xuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdGpRdWVyeSh0aGlzKS5tb3VzZW92ZXIoZnVuY3Rpb24oZSkge1xuXHRcdFx0XHRqUXVlcnkoJy5hbm5vdGF0aW9uLicralF1ZXJ5KGUudGFyZ2V0KS5hdHRyKFwiaWRcIikpLmVhY2goZnVuY3Rpb24oKXtcblx0XHRcdFx0XHRqUXVlcnkodGhpcykuY3NzKFwiYmFja2dyb3VuZC1jb2xvclwiLCBqUXVlcnkodGhpcykuYXR0cihcImNvbG9yXCIpICk7XG5cdFx0XHRcdH0pO1xuXHRcdCAgICB9KS5tb3VzZW91dChmdW5jdGlvbigpIHtcblx0XHQgICAgXHRqUXVlcnkoJy5hbm5vdGF0aW9uJykuY3NzKFwiYmFja2dyb3VuZC1jb2xvclwiLCBcInRyYW5zcGFyZW50XCIpOyBcblx0XHQgICAgXHRcblx0XHQgICAgfSkuY2xpY2soZnVuY3Rpb24oZSkge1xuXHRcdCAgICBcdFx0dmFyIG5hbWUgPSB1bmRlZmluZWQ7XG5cdFx0ICAgIFx0XHR2YXIgaWQgPSBqUXVlcnkoZS50YXJnZXQpLmF0dHIoXCJpZFwiKTtcblx0XHQgICAgXHRcdGZvcih2YXIgaSA9MDsgaSA8IHNlbGYuX2Fubm90YXRpb25zLmxlbmd0aDtpKyspe1xuICAgICAgICAgICAgICBpZihzZWxmLl9hbm5vdGF0aW9uc1tpXS5pZCA9PSBpZCl7XG4gICAgICAgICAgICAgICAgbmFtZSA9IHNlbGYuX2Fubm90YXRpb25zW2ldLm5hbWU7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblx0XHQgICAgXHRzZWxmLnRyaWdnZXIoIEVWVF9PTl9BTk5PVEFUSU9OX0NMSUNLRUQsIHtcblx0ICAgIFx0XHRcIm5hbWVcIjogbmFtZSxcblx0XHQgICAgXHRcdC8vXCJwb3NcIjogcGFyc2VJbnQoIGpRdWVyeShlLnRhcmdldCkuYXR0cihcInBvc1wiKSApXG5cdFx0ICAgIFx0fSk7XG5cdFx0ICAgIH0pO1xuXHRcdFx0XG5cdFx0fSk7XG5cbiAgICB9LFxuICAgIC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZ2V0QW5ub3RhdGlvblN0cmluZ1xuICAgICAqIFB1cnBvc2U6ICBHZXQgdGhlIGFubm90YXRpb24gdGV4dCBtZXNzYWdlIGZvciB0aGUgdG9vbHRpcCBcbiAgICAgKiBSZXR1cm5zOiAge3N0cmluZ30gQW5ub3RhdGlvbiB0ZXh0IGZvciB0aGUgYW5ub3RhdGlvblxuICAgICAqIElucHV0czogICBpZCAtPiB7aW50fSBpbmRleCBvZiB0aGUgaW50ZXJuYWwgYW5ub3RhdGlvbiBhcnJheVxuICAgICAqL1xuICAgIF9nZXRBbm5vdGF0aW9uU3RyaW5nOiBmdW5jdGlvbiAoIGlkICkge1xuXHRcdHZhciBhbm5vdGF0aW9uID0gdGhpcy5fYW5ub3RhdGlvbnNbaWQuc3Vic3RyKGlkLmluZGV4T2YoXCJfXCIpICsgMSldO1xuXHRcdHJldHVybiBhbm5vdGF0aW9uLm5hbWUgKyBcIjxici8+XCIgKyAoKGFubm90YXRpb24uaHRtbCk/IGFubm90YXRpb24uaHRtbCA6ICcnKTtcbiAgICB9LFxuICAgIFxuICAgIC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZ2V0SFRNTFJvd0Fubm90XG4gICAgICogUHVycG9zZTogIEJ1aWxkIGFuIGFubm90YXRpb25cbiAgICAgKiBSZXR1cm5zOiAgSFRNTCBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIElucHV0czogICBjdXJyZW50UG9zIC0+IHtpbnR9XG4gICAgICogXHRcdFx0IGFubm90YXRpb24gLT4ge09iamVjdH0gXG4gICAgICogIFx0XHQgc2V0dGluZ3MgLT4ge09iamVjdH1cbiAgICAgKi9cbiAgICBfZ2V0SFRNTFJvd0Fubm90IDogZnVuY3Rpb24gKGN1cnJlbnRQb3MsIGFubm90YXRpb24sIHNldHRpbmdzKSB7XG4gICAgXHR2YXIgc3R5bGVCZWdpbiA9ICdib3JkZXItbGVmdDoxcHggc29saWQ7IGJvcmRlci1ib3R0b206MXB4IHNvbGlkOyBib3JkZXItY29sb3I6JztcbiAgICBcdHZhciBzdHlsZU9uID0gJ2JvcmRlci1ib3R0b206MXB4IHNvbGlkOyBib3JkZXItY29sb3I6JztcbiAgICBcdHZhciBzdHlsZUVuZCA9ICdib3JkZXItYm90dG9tOjFweCBzb2xpZDsgYm9yZGVyLXJpZ2h0OjFweCBzb2xpZDsgYm9yZGVyLWNvbG9yOic7XG5cdFx0dmFyIHN0eWxlQmVnaW5BbmRFbmQgPSAnYm9yZGVyLWxlZnQ6MXB4IHNvbGlkOyBib3JkZXItcmlnaHQ6MXB4IHNvbGlkOyBib3JkZXItYm90dG9tOjFweCBzb2xpZDsgYm9yZGVyLWNvbG9yOic7XG4gICAgXHRcbiAgICBcdHZhciByb3cgPSBbXTtcbiAgICBcdHZhciBlbmQgPSAoY3VycmVudFBvcyArIHNldHRpbmdzLm51bUNvbHMpO1xuICAgIFx0dmFyIHNwYWNlQmV0d2VlbkNoYXJzID0gKHNldHRpbmdzLnNwYWNlQmV0d2VlbkNoYXJzKT8gJyAnIDogJyc7ICAgIFx0XG4gICAgXHR2YXIgZGVmYXVsdENvbG9yID0gYW5ub3RhdGlvbi5jb2xvcjtcbiAgICBcdHZhciBpZCA9IGFubm90YXRpb24uaWQ7XG4gICAgXHRmb3IgKCB2YXIgcG9zPWN1cnJlbnRQb3M7IHBvcyA8IGVuZCA7IHBvcysrICkge1xuXHRcdFx0Ly8gcmVnaW9uc1xuXHRcdFx0Zm9yICggdmFyIHIgaW4gYW5ub3RhdGlvbi5yZWdpb25zICkge1xuXHRcdFx0XHRyZWdpb24gPSBhbm5vdGF0aW9uLnJlZ2lvbnNbcl07XG5cdFx0XHRcdFxuXHRcdFx0XHRzcGFjZUFmdGVyID0gJyc7XG5cdFx0XHRcdHNwYWNlQWZ0ZXIgKz0gKHBvcyAlIHNldHRpbmdzLm51bUNvbHNGb3JTcGFjZSA9PSAwICk/ICcgJyA6ICcnO1xuXHRcdFx0XHRzcGFjZUFmdGVyICs9IHNwYWNlQmV0d2VlbkNoYXJzO1xuXHRcdFx0XHRcblx0XHRcdFx0Y29sb3IgPSAoKHJlZ2lvbi5jb2xvcik/IHJlZ2lvbi5jb2xvciA6IGRlZmF1bHRDb2xvcik7XG5cdFx0XHRcdGRhdGEgPSAnY2xhc3M9XCJhbm5vdGF0aW9uICcraWQrJ1wiIGlkPVwiJytpZCsnXCIgY29sb3I9XCInK2NvbG9yKydcIiBwb3M9XCInK3BvcysnXCInO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKCBwb3MgPT0gcmVnaW9uLnN0YXJ0ICYmIHBvcyA9PSByZWdpb24uZW5kKSB7XG5cdFx0XHRcdFx0cm93W3Bvc10gPSAnPHNwYW4gc3R5bGU9XCInK3N0eWxlQmVnaW5BbmRFbmQrY29sb3IrJ1wiICcrZGF0YSsnPiAnO1xuXHRcdFx0XHRcdHJvd1twb3NdICs9IHNwYWNlQWZ0ZXI7XG5cdFx0XHRcdFx0cm93W3Bvc10gKz0gJzwvc3Bhbj4nO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBwb3MgPT0gcmVnaW9uLnN0YXJ0ICkge1xuXHRcdFx0XHRcdHJvd1twb3NdID0gJzxzcGFuIHN0eWxlPVwiJytzdHlsZUJlZ2luK2NvbG9yKydcIiAnK2RhdGErJz4gJztcblx0XHRcdFx0XHRyb3dbcG9zXSArPSBzcGFjZUFmdGVyO1xuXHRcdFx0XHRcdHJvd1twb3NdICs9ICc8L3NwYW4+Jztcblx0XHRcdFx0fSBlbHNlIGlmICggcG9zID09IHJlZ2lvbi5lbmQgKSB7XG5cdFx0XHRcdFx0cm93W3Bvc10gPSAnPHNwYW4gc3R5bGU9XCInK3N0eWxlRW5kK2NvbG9yKycgXCIgJytkYXRhKyc+ICc7XG5cdFx0XHRcdFx0Ly9yb3dbcG9zXSArPSBzcGFjZUFmdGVyO1xuXHRcdFx0XHRcdHJvd1twb3NdICs9ICc8L3NwYW4+Jztcblx0XHRcdFx0fSBlbHNlIGlmICggcG9zID4gcmVnaW9uLnN0YXJ0ICYmIHBvcyA8IHJlZ2lvbi5lbmQgKSB7XG5cdFx0XHRcdFx0cm93W3Bvc10gPSAnPHNwYW4gc3R5bGU9XCInK3N0eWxlT24rY29sb3IrJ1wiICcrZGF0YSsnPiAnO1xuXHRcdFx0XHRcdHJvd1twb3NdICs9IHNwYWNlQWZ0ZXI7XG5cdFx0XHRcdFx0cm93W3Bvc10gKz0gJzwvc3Bhbj4nO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCFyb3dbcG9zXSkge1xuXHRcdFx0XHRcdHJvd1twb3NdID0gJyAnO1xuXHRcdFx0XHRcdHJvd1twb3NdICs9IHNwYWNlQWZ0ZXI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cbiAgICAgICBcdHZhciBzdHIgPSByb3cuam9pbihcIlwiKTtcbiAgICBcdFxuICAgIFx0cmV0dXJuICggc3RyLmluZGV4T2YoXCJzcGFuXCIpID09IC0xICk/IFwiXCIgOiBzdHI7XG4gICAgfSxcbiAgICAvKiBcbiAgICAgKiBGdW5jdGlvbjogU2VxdWVuY2UuX2RyYXdSYXdcbiAgICAgKiBQdXJwb3NlOiAgUmVwYWludCB0aGUgY3VycmVudCBzZXF1ZW5jZSB1c2luZyBSQVcgZm9ybWF0LiAgXG4gICAgICogUmV0dXJuczogIC1cbiAgICAgKiBJbnB1dHM6IC1cbiAgICAgKi9cblx0X2RyYXdSYXcgOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0dmFyIGEgPSB0aGlzLm9wdC5zZXF1ZW5jZS50b0xvd2VyQ2FzZSgpLnNwbGl0KCcnKTtcblx0XHR2YXIgaSA9IDA7XG5cdFx0dmFyIGFyciA9IFtdO1xuXHRcdHZhciBwcmUgPSBqUXVlcnkoJzxwcmU+PC9wcmU+JykuYXBwZW5kVG8odGhpcy5fY29udGVudERpdik7XG5cdFx0XG5cdFx0LyogQ29ycmVjdCBjb2x1bW4gc2l6ZSBpbiBjYXNlIHRoZSBzZXF1ZW5jZSBpcyBhcyBzbWFsbCBwZXB0aWRlICovXG5cdFx0dmFyIG51bUNvbHMgPSB0aGlzLm9wdC5jb2x1bW5zLnNpemU7XG5cdFx0aWYgKCB0aGlzLm9wdC5zZXF1ZW5jZS5sZW5ndGggPCB0aGlzLm9wdC5jb2x1bW5zLnNpemUgKSB7XG5cdFx0XHRudW1Db2xzID0gdGhpcy5vcHQuc2VxdWVuY2UubGVuZ3RoO1x0XG5cdFx0fVxuXG5cdFx0dmFyIG9wdCA9IHtcblx0XHRcdG51bUNvbHM6IG51bUNvbHNcblx0XHR9O1xuXHRcdFxuXHRcdHByZS5odG1sKFxuXHRcdFx0dGhpcy5fZHJhd1NlcXVlbmNlKGEsIG9wdClcblx0XHQpO1xuXHRcdFxuXHRcdHRoaXMuX2RyYXdBbm5vdGF0aW9ucyhvcHQpO1xuXHR9LFxuXHQvKiBcbiAgICAgKiBGdW5jdGlvbjogU2VxdWVuY2UuX2RyYXdQcmlkZVxuICAgICAqIFB1cnBvc2U6ICBSZXBhaW50IHRoZSBjdXJyZW50IHNlcXVlbmNlIHVzaW5nIFBSSURFIGZvcm1hdC4gIFxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiAtXG4gICAgICovXG5cdF9kcmF3UHJpZGUgOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0dmFyIGEgPSB0aGlzLm9wdC5zZXF1ZW5jZS50b1VwcGVyQ2FzZSgpLnNwbGl0KCcnKTtcblx0XHR2YXIgcHJlID0galF1ZXJ5KCc8cHJlPjwvcHJlPicpLmFwcGVuZFRvKHRoaXMuX2NvbnRlbnREaXYpO1xuXHRcdFxuXHRcdC8qIENvcnJlY3QgY29sdW1uIHNpemUgaW4gY2FzZSB0aGUgc2VxdWVuY2UgaXMgYXMgc21hbGwgcGVwdGlkZSAqL1xuXHRcdHZhciBudW1Db2xzID0gdGhpcy5vcHQuY29sdW1ucy5zaXplO1xuXHRcdGlmICggdGhpcy5vcHQuc2VxdWVuY2UubGVuZ3RoIDwgdGhpcy5vcHQuY29sdW1ucy5zaXplICkge1xuXHRcdFx0bnVtQ29scyA9IHRoaXMub3B0LnNlcXVlbmNlLmxlbmd0aDtcdFxuXHRcdH1cblx0XG5cdFx0b3B0ID0ge1xuXHRcdFx0bnVtTGVmdDogdHJ1ZSxcblx0XHRcdG51bUxlZnRTaXplOiA1LFxuXHRcdFx0bnVtTGVmdFBhZDonMCcsXG5cdFx0XHRudW1SaWdodDogdHJ1ZSxcblx0XHRcdG51bVJpZ2h0U2l6ZTogNSxcblx0XHRcdG51bVJpZ2h0UGFkOiAnMCcsXG5cdFx0XHRudW1Db2xzOiBudW1Db2xzLFxuXHRcdCAgICBudW1Db2xzRm9yU3BhY2U6IHNlbGYub3B0LmNvbHVtbnMuc3BhY2VkRWFjaFxuXHRcdH07XG5cdFx0XG5cdFx0cHJlLmh0bWwoXG5cdFx0XHR0aGlzLl9kcmF3U2VxdWVuY2UoYSwgb3B0KVxuXHRcdCk7XG5cdFx0XG5cdFx0dGhpcy5fZHJhd0Fubm90YXRpb25zKG9wdCk7XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZHJhd1NlcXVlbmNlXG4gICAgICogUHVycG9zZTogIFJlcGFpbnQgdGhlIGN1cnJlbnQgc2VxdWVuY2UgdXNpbmcgQ1VTVE9NIGZvcm1hdC4gIFxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiAgIGEgLT4ge2NoYXJbXX0gYSBUaGUgc2VxdWVuY2Ugc3RyYW5kLlxuICAgICAqIFx0XHRcdCBvcHQgLT4ge09iamVjdH0gb3B0IFRoZSBDVVNUT00gZm9ybWF0LlxuICAgICAqL1xuXHRfZHJhd1NlcXVlbmNlIDogZnVuY3Rpb24oYSwgb3B0KSB7XG5cdFx0dmFyIHN0ciA9ICcnO1xuXG5cdFx0dmFyIHNwYWNlU3R5bGUgPSAgXCJ3aGl0ZS1zcGFjZTogcHJlO1wiO1xuXHRcdFxuXHRcdC8vIEluZGV4IGF0IHRvcD9cblx0XHRpZiggb3B0Lm51bVRvcCApXG5cdFx0e1xuXHRcdFx0c3RyICs9ICc8c3BhbiBzdHlsZT1cIicrc3BhY2VTdHlsZSsnXCIgY2xhc3M9XCJudW1Ub3BcIj4nXG5cdFx0XHR2YXIgc2l6ZSA9IChvcHQuc3BhY2VCZXR3ZWVuQ2hhcnMpPyBvcHQubnVtVG9wRWFjaCoyOiBvcHQubnVtVG9wRWFjaDtcblx0XHRcdFxuXHRcdFx0aWYgKG9wdC5udW1MZWZ0KSB7XG5cdFx0XHRcdHN0ciArPSB0aGlzLl9mb3JtYXRJbmRleCgnICcsIG9wdC5udW1MZWZ0U2l6ZSwgJyAnKTtcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0c3RyICs9IHRoaXMuX2Zvcm1hdEluZGV4KCcgJywgc2l6ZSwgJyAnKTtcblx0XHRcdFxuXHRcdFx0Zm9yKHZhciB4ID0gb3B0Lm51bVRvcEVhY2g7IHggPCBvcHQubnVtQ29sczsgeCArPSBvcHQubnVtVG9wRWFjaCkge1xuXHRcdFx0XHRzdHIgKz0gdGhpcy5fZm9ybWF0SW5kZXgoeCwgc2l6ZSwgJyAnLCB0cnVlKTtcblx0XHRcdH1cblx0XHRcdHN0ciArPSAnPC9zcGFuPjxici8+J1xuXHRcdH1cblx0XHRcblx0XHRcblx0XHQvLyBJbmRleCBhdCB0aGUgbGVmdD9cblx0XHRpZiAob3B0Lm51bUxlZnQpIHtcblx0XHRcdHN0ciArPSB0aGlzLl9mb3JtYXRJbmRleCgxLCBvcHQubnVtTGVmdFNpemUsIG9wdC5udW1MZWZ0UGFkKTtcblx0XHRcdHN0ciArPSAnICAnO1xuXHRcdH1cblxuXHRcdHZhciBqPTE7XG5cdFx0Zm9yICh2YXIgaT0xOyBpIDw9IGEubGVuZ3RoOyBpKyspIHtcblxuXHRcdFx0aWYoIGkgJSBvcHQubnVtQ29scyA9PSAwKSB7XHRcblx0XHRcdFx0c3RyICs9ICc8c3BhbiBjbGFzcz1cInNlcXVlbmNlXCIgaWQ9XCInICsgdGhpcy5nZXRJZCgpICsgJ18nICsgaSArICdcIj4nICsgYVtpLTFdICsgJzwvc3Bhbj4nO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKG9wdC5udW1SaWdodCkge1xuXHRcdFx0XHRcdHN0ciArPSAnPHNwYW4gc3R5bGU9XCInK3NwYWNlU3R5bGUrJ1wiIGlkPVwibnVtUmlnaHRfJyArIHRoaXMuZ2V0SWQoKSArICdfJyArIGkgKyAnXCI+Jztcblx0XHRcdFx0XHRzdHIgKz0gJyAgJztcblx0XHRcdFx0XHRzdHIgKz0gdGhpcy5fZm9ybWF0SW5kZXgoaSwgb3B0Lm51bVJpZ2h0U2l6ZSwgb3B0Lm51bVJpZ2h0UGFkKTtcdFxuXHRcdFx0XHRcdHN0ciArPSAnPC9zcGFuPic7XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdHN0ciArPSAnPGJyLz4nO1xuXHRcdFx0XHRcblx0XHRcdFx0dmFyIGFhUmVtYWluaW5nID0gYS5sZW5ndGggLSBpO1xuXHRcdFx0XHRpZiAob3B0Lm51bUxlZnQgJiYgYWFSZW1haW5pbmcgPiAwKSB7XG5cdFx0XHRcdFx0c3RyICs9ICc8c3BhbiBpZD1cIm51bUxlZnRfJyArIHRoaXMuZ2V0SWQoKSArICdfJyArIGkgKyAnXCI+Jztcblx0XHRcdFx0XHRzdHIgKz0gdGhpcy5fZm9ybWF0SW5kZXgoaSsxLCBvcHQubnVtTGVmdFNpemUsIG9wdC5udW1MZWZ0UGFkKTtcblx0XHRcdFx0XHRzdHIgKz0gJyAgJztcblx0XHRcdFx0XHRzdHIgKz0gJzwvc3Bhbj4nO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRqID0gMTtcblx0XHRcdFx0XG5cdFx0XHR9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0ciArPSAnPHNwYW4gY2xhc3M9XCJzZXF1ZW5jZVwiIHN0eWxlPVwiJytzcGFjZVN0eWxlKydcIiBpZD1cIicgKyB0aGlzLmdldElkKCkgKyAnXycgKyBpICsgJ1wiPicgKyBhW2ktMV07XG5cdFx0XHRcdHN0ciArPSAoIGogJSBvcHQubnVtQ29sc0ZvclNwYWNlID09IDApPyAnICcgOiAnJztcblx0XHRcdFx0c3RyICs9IChvcHQuc3BhY2VCZXR3ZWVuQ2hhcnMpPyAnICcgOiAnJztcblx0XHRcdFx0c3RyICs9ICc8L3NwYW4+Jztcblx0XHRcdFx0aisrO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0XHRzdHIgKz0gJzxici8+J1x0XG5cdFx0XHRcblx0XHRpZiAoalF1ZXJ5LmJyb3dzZXIubXNpZSkge1xuXHRcdFx0c3RyID0gXCI8cHJlPlwiICsgc3RyICsgXCI8L3ByZT5cIjtcblx0XHR9XHRcblx0XHRcdFxuXHRcdHJldHVybiBzdHI7XG5cdH0sXG5cdC8qIFxuICAgICAqIEZ1bmN0aW9uOiBTZXF1ZW5jZS5fZm9ybWF0SW5kZXhcbiAgICAgKiBQdXJwb3NlOiAgQnVpbGQgdGhlIEhUTUwgY29ycmVzcG9uZGluZyB0byBjb3VudGluZyBudW1iZXJzICh0b3AsIGxlZnQsIHJpZ2h0KSBpbiB0aGUgc3RyYW5kLlxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiAgIG51bWJlciAtPiB7aW50fSBUaGUgbnVtYmVyIFxuICAgICAqIFx0XHRcdCBzaXplIC0+IHtpbnR9IE51bWJlciBvZiBiaW5zIHRvIHN1aXQgdGhlIG51bWJlci5cbiAgICAgKiBcdFx0XHQgZmlsbGluZ0NoYXIgLT4ge2NoYXJ9IENoYXJhY3RlciB0byBiZSB1c2VkIGZvciBmaWxsaW5nIG91dCBibGFuayBiaW5zLlxuICAgICAqIFx0XHRcdCBhbGlnbkxlZnQgLT4ge2Jvb2x9IFRlbGwgaWYgYWxpZ25lZCB0byB0aGUgbGVmdC5cbiAgICAgKi9cblx0X2Zvcm1hdEluZGV4IDogZnVuY3Rpb24oIG51bWJlciwgc2l6ZSwgZmlsbGluZ0NoYXIsIGFsaWduTGVmdCkge1xuXHRcdHZhciBzdHIgPSBudW1iZXIudG9TdHJpbmcoKTtcblx0XHR2YXIgZmlsbGluZyA9ICcnO1xuXHRcdHZhciBwYWRkaW5nID0gc2l6ZSAtIHN0ci5sZW5ndGg7XHRcblx0XHRpZiAoIHBhZGRpbmcgPiAwICkge1xuXHRcdFx0d2hpbGUgKCBwYWRkaW5nLS0gPiAwICkge1xuXHRcdFx0XHRmaWxsaW5nICs9IChcIjxzcGFuPlwiK2ZpbGxpbmdDaGFyK1wiPC9zcGFuPlwiKTtcblx0XHRcdH1cblx0XHRcdGlmIChhbGlnbkxlZnQpe1xuXHRcdFx0XHRzdHIgPSBudW1iZXIrZmlsbGluZztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHN0ciA9IGZpbGxpbmcrbnVtYmVyO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gc3RyO1xuXHR9LFxuXHQvKiBcbiAgICAgKiBGdW5jdGlvbjogU2VxdWVuY2UuX2FkZFNwYW5FdmVudHNcbiAgICAgKiBQdXJwb3NlOiAgQWRkIHRoZSBldmVudCBoYW5kbGVycyB0byB0aGUgc3RyYW5kLlxuICAgICAqIFJldHVybnM6ICAtXG4gICAgICogSW5wdXRzOiAgIC1cbiAgICAgKi9cblx0X2FkZFNwYW5FdmVudHMgOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0dmFyIGlzTW91c2VEb3duID0gZmFsc2U7XG5cdFx0dmFyIGN1cnJlbnRQb3M7XG5cblx0XHRzZWxmLl9jb250ZW50RGl2LmZpbmQoJy5zZXF1ZW5jZScpLmVhY2goIGZ1bmN0aW9uICgpIHtcdFxuXHRcdFx0XG5cdFx0XHQvLyBSZWdpc3RlciB0aGUgc3RhcnRpbmcgcG9zaXRpb25cblx0XHRcdGpRdWVyeSh0aGlzKS5tb3VzZWRvd24oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBpZCA9IGpRdWVyeSh0aGlzKS5hdHRyKCdpZCcpO1xuXHRcdFx0XHRjdXJyZW50UG9zID0gcGFyc2VJbnQoaWQuc3Vic3RyKGlkLmluZGV4T2YoXCJfXCIpICsgMSkpO1xuXHRcdFx0XHRjbGlja1BvcyA9IGN1cnJlbnRQb3M7XG5cdFx0XHRcdHNlbGYuX3NldFNlbGVjdGlvbihjbGlja1BvcyxjdXJyZW50UG9zKTtcblx0XHRcdFx0aXNNb3VzZURvd24gPSB0cnVlO1xuXHRcdFx0XHRcblx0XHRcdFx0Ly8gU2VsZWN0aW9uIGlzIGhhcHBlbmluZywgcmFpc2UgYW4gZXZlbnRcblx0XHRcdFx0c2VsZi50cmlnZ2VyKFxuXHRcdFx0XHRcdEVWVF9PTl9TRUxFQ1RJT05fQ0hBTkdFLCBcblx0XHRcdFx0XHR7IFxuXHRcdFx0XHRcdFx0XCJzdGFydFwiIDogc2VsZi5vcHQuc2VsZWN0aW9uLnN0YXJ0LCBcblx0XHRcdFx0XHRcdFwiZW5kXCIgOiBzZWxmLm9wdC5zZWxlY3Rpb24uZW5kIFxuXHRcdFx0XHRcdH1cblx0XHRcdFx0KTtcblx0XHRcdFxuXHRcdFx0fSkubW91c2VvdmVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBVcGRhdGUgc2VsZWN0aW9uXG5cdFx0XHRcdC8vIFNob3cgdG9vbHRpcCBjb250YWluaW5nIHRoZSBwb3NpdGlvblxuXHRcdFx0XHR2YXIgaWQgPSBqUXVlcnkodGhpcykuYXR0cignaWQnKTtcblx0XHRcdFx0Y3VycmVudFBvcyA9IHBhcnNlSW50KGlkLnN1YnN0cihpZC5pbmRleE9mKFwiX1wiKSArIDEpKTtcblx0XHRcdFx0XG5cdFx0XHRcdGlmKGlzTW91c2VEb3duKSB7XG5cdFx0XHRcdFx0aWYoIGN1cnJlbnRQb3MgPiBjbGlja1BvcyApIHtcblx0XHRcdFx0XHRcdHNlbGYuX3NldFNlbGVjdGlvbihjbGlja1BvcywgY3VycmVudFBvcyk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHNlbGYuX3NldFNlbGVjdGlvbihjdXJyZW50UG9zLCBjbGlja1Bvcyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdC8vIFNlbGVjdGlvbiBpcyBoYXBwZW5pbmcsIHJhaXNlIGFuIGV2ZW50XG5cdFx0XHRcdFx0c2VsZi50cmlnZ2VyKCBFVlRfT05fU0VMRUNUSU9OX0NIQU5HRSwgeyBcblx0XHRcdFx0XHRcdFwic3RhcnRcIiA6IHNlbGYub3B0LnNlbGVjdGlvbi5zdGFydCwgXG5cdFx0XHRcdFx0XHRcImVuZFwiIDogc2VsZi5vcHQuc2VsZWN0aW9uLmVuZCBcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSBcblx0XHRcdFx0XG5cdFx0XHR9KS5tb3VzZXVwKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpc01vdXNlRG93biA9IGZhbHNlO1xuXHRcdFx0XHQvLyBTZWxlY3Rpb24gaXMgZG9uZSwgcmFpc2UgYW4gZXZlbnRcblx0XHRcdFx0c2VsZi50cmlnZ2VyKCBFVlRfT05fU0VMRUNUSU9OX0NIQU5HRUQsIHsgXG5cdFx0XHRcdFx0XCJzdGFydFwiIDogc2VsZi5vcHQuc2VsZWN0aW9uLnN0YXJ0LCBcblx0XHRcdFx0XHRcImVuZFwiIDogc2VsZi5vcHQuc2VsZWN0aW9uLmVuZCBcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHRcdFxuXHRcdFx0Ly8gQWRkIGEgdG9vbHRpcCBmb3IgdGhpcyBzZXF1ZW5jZSBiYXNlLlxuXHRcdFx0c2VsZi5fYWRkVG9vbFRpcC5jYWxsKCBzZWxmLCB0aGlzLCBmdW5jdGlvbiggKSB7XG5cdFx0XHRcdGlmIChpc01vdXNlRG93bikge1xuXHQgICAgIFx0XHRcdHJldHVybiBcIltcIiArIHNlbGYub3B0LnNlbGVjdGlvbi5zdGFydCArXCIsIFwiICsgc2VsZi5vcHQuc2VsZWN0aW9uLmVuZCArIFwiXVwiO1xuXHQgICAgIFx0XHR9IGVsc2Uge1xuXHQgICAgIFx0XHRcdHJldHVybiBjdXJyZW50UG9zO1xuXHQgICAgIFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdFxuXHRcdH0pXG5cdFx0LmNzcygnY3Vyc29yJywgJ3BvaW50ZXInKTtcblx0fSxcblx0LyogXG4gICAgICogRnVuY3Rpb246IFNlcXVlbmNlLl9hZGRUb29sdGlwXG4gICAgICogUHVycG9zZTogIEFkZCBhIHRvb2x0aXAgYXJvdW5kIHRoZSB0YXJnZXQgRE9NIGVsZW1lbnQgcHJvdmlkZWQgYXMgYXJndW1lbnRcbiAgICAgKiBSZXR1cm5zOiAgLVxuICAgICAqIElucHV0czogICB0YXJnZXQgLT4ge0VsZW1lbnR9IERPTSBlbGVtZW50IHdpY2ggaXMgdGhlIHRhcmdldGVkIGZvY3VzIGZvciB0aGUgdG9vbHRpcC5cbiAgICAgKiBcdFx0XHQgY2JHZXRNZXNzYWdlRnVuY3Rpb24gLT4ge2Z1bmN0aW9ufSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHdpY2ggcmV0dXJucyB0aGUgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHRpcC5cbiAgICAgKi9cblx0X2FkZFRvb2xUaXAgOiBmdW5jdGlvbiAoIHRhcmdldCwgY2JHZXRNZXNzYWdlRnVuY3Rpb24gKSB7XG5cdFx0XG4gXHRcdHZhciB0aXBJZCA9IHRoaXMub3B0Ll90b29sdGlwO1xuXHRcdFxuXHRcdGpRdWVyeSh0YXJnZXQpLm1vdXNlb3ZlcihmdW5jdGlvbihlKSB7XG5cdFx0XHRcblx0IFx0XHR2YXIgb2Zmc2V0ID0galF1ZXJ5KGUudGFyZ2V0KS5vZmZzZXQoKTtcblxuXHRcdFx0aWYgKCAhIGpRdWVyeSggdGlwSWQgKS5pcygnOnZpc2libGUnKSApIHtcblx0XHQgICAgICAgIGpRdWVyeSggdGlwSWQgKSBcblx0XHQgICAgICAgIFx0LmNzcyh7XG5cdFx0ICAgICAgICBcdFx0J2JhY2tncm91bmQtY29sb3InOiBcIiMwMDBcIixcblx0XHQgICAgICAgIFx0XHQncGFkZGluZyc6IFwiM3B4IDEwcHggM3B4IDEwcHhcIixcblx0XHQgICAgICAgIFx0XHQndG9wJzogb2Zmc2V0LnRvcCArIGpRdWVyeShlLnRhcmdldCkuaGVpZ2h0KCkgKyBcInB4XCIsXG5cdFx0ICAgICAgICBcdFx0J2xlZnQnOiBvZmZzZXQubGVmdCArIGpRdWVyeShlLnRhcmdldCkud2lkdGgoKSArIFwicHhcIlxuXHRcdCAgICAgICAgXHR9KVxuXHRcdFx0ICAgICAgICAuYW5pbWF0ZSgge29wYWNpdHk6ICcwLjg1J30sIDEwKVxuXHRcdFx0ICAgICAgICAuaHRtbCggY2JHZXRNZXNzYWdlRnVuY3Rpb24uY2FsbCggdGFyZ2V0ICkgKVxuXHRcdFx0ICAgICAgICAuc2hvdygpO1xuXHRcdFx0fVxuXG5cdCAgICB9KS5tb3VzZW91dChmdW5jdGlvbigpIHtcblx0ICAgICAgICAvL1JlbW92ZSB0aGUgYXBwZW5kZWQgdG9vbHRpcCB0ZW1wbGF0ZVxuXHQgICAgICAgIGpRdWVyeSggdGlwSWQgKS5oaWRlKCk7XHQgICAgICAgICBcblx0ICAgIH0pO1xuXHR9LFxuXHRcbiAgIC8qKlxuICAgICogQW5ub3RhdGUgYSBzZXQgb2YgaW50ZXJ2YWxzIHByb3ZpZGVkIGluIHRoZSBhcmd1bWVudC5cblx0KiBcblx0KiBAZGVwcmVjYXRlZCBVc2UgYWRkQW5ub3RhdGlvbigpIGluc3RlYWQuXG4gICAgKiBcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBhbm5vdGF0aW9uIFRoZSBpbnRlcnZhbHMgYmVsb25naW5nIHRvIHRoZSBzYW1lIGFubm90YXRpb24uIFxuICAgICogU3ludGF4OiB7IG5hbWU6ICZsdDt2YWx1ZSZndDssIGNvbG9yOiAmbHQ7SFRNTENvbG9yQ29kZSZndDssIGh0bWw6ICZsdDtIVE1MU3RyaW5nJmd0OywgcmVnaW9uczogW3sgc3RhcnQ6ICZsdDtzdGFydFZhbDEmZ3Q7LCBlbmQ6ICZsdDtlbmRWYWwxJmd0O30sIC4uLiwgIHsgc3RhcnQ6ICZsdDtzdGFydFZhbE4mZ3Q7LCBlbmQ6ICZsdDtlbmRWYWxOJmd0O31dIH1cbiAgICAqL1xuXHRzZXRBbm5vdGF0aW9uOiBmdW5jdGlvbiAoIGFubm90YXRpb24gKSB7XG5cdFx0dGhpcy5hZGRBbm5vdGF0aW9uKGFubm90YXRpb24pO1xuXHR9LFxuXHRcblx0LyoqXG4gICAgKiBBbm5vdGF0ZSBhIHNldCBvZiBpbnRlcnZhbHMgcHJvdmlkZWQgaW4gdGhlIGFyZ3VtZW50LlxuICAgICogXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gQW5ub3RhdGlvbnMgdXNpbmcgcmVnaW9ucyB3aXRoIGRpZmZlcmVudCBjb2xvcnMuXG4gICAgKiBteVNlcXVlbmNlLmFkZEFubm90YXRpb24oe1xuXHQqICAgIG5hbWU6XCJVTklQUk9UXCIsIFxuXHQqICAgIGh0bWw6XCImbHQ7YnImZ3Q7IEV4YW1wbGUgb2YgJmx0O2ImZ3Q7SFRNTCZsdDsvYiZndDtcIiwgXG5cdCogICAgY29sb3I6XCJncmVlblwiLCBcblx0KiAgICByZWdpb25zOiBbXG5cdCogICAgICAge3N0YXJ0OiA1NDAsIGVuZDogNTYwfSxcblx0KiAgICAgICB7c3RhcnQ6IDU2MSwgZW5kOjU4MCwgY29sb3I6IFwiI0ZGQTAxMFwifSwgXG5cdCogICAgICAge3N0YXJ0OiA1ODEsIGVuZDo1OTAsIGNvbG9yOiBcInJlZFwifSwgXG5cdCogICAgICAge3N0YXJ0OiA2OTAsIGVuZDo3MTB9XVxuXHQqIH0pO1xuXHQqIFxuICAgICogXG4gICAgKiBAcGFyYW0ge09iamVjdH0gYW5ub3RhdGlvbiBUaGUgaW50ZXJ2YWxzIGJlbG9uZ2luZyB0byB0aGUgc2FtZSBhbm5vdGF0aW9uLiBcbiAgICAqIFN5bnRheDogeyBuYW1lOiAmbHQ7dmFsdWUmZ3Q7LCBjb2xvcjogJmx0O0hUTUxDb2xvckNvZGUmZ3Q7LCBodG1sOiAmbHQ7SFRNTFN0cmluZyZndDssIHJlZ2lvbnM6IFt7IHN0YXJ0OiAmbHQ7c3RhcnRWYWwxJmd0OywgZW5kOiAmbHQ7ZW5kVmFsMSZndDt9LCAuLi4sICB7IHN0YXJ0OiAmbHQ7c3RhcnRWYWxOJmd0OywgZW5kOiAmbHQ7ZW5kVmFsTiZndDt9XSB9XG4gICAgKi9cblx0YWRkQW5ub3RhdGlvbjogZnVuY3Rpb24gKCBhbm5vdGF0aW9uICkge1xuXHRcdHRoaXMuX2Fubm90YXRpb25zLnB1c2goYW5ub3RhdGlvbik7XG5cdFx0dGhpcy5fcmVkcmF3KCk7XG5cdH0sXG5cdFxuXHQvKipcbiAgICAqIFJlbW92ZXMgYW4gYW5ub3RhdGlvbiBieSBtZWFucyBvZiBpdHMgbmFtZS5cbiAgICAqIFxuICAgICogQGV4YW1wbGUgXG4gICAgKiAvLyBSZW1vdmUgdGhlIFVOSVBST1QgYW5ub3RhdGlvbi5cbiAgICAqIG15U2VxdWVuY2UucmVtb3ZlQW5ub3RhdGlvbignVU5JUFJPVCcpOyBcbiAgICAqIFxuICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIGFubm90YXRpb24gdG8gYmUgcmVtb3ZlZC5cbiAgICAqIFxuICAgICovXG5cdHJlbW92ZUFubm90YXRpb246IGZ1bmN0aW9uICggbmFtZSApIHtcblx0XHRmb3IgKHZhciBpPTA7IGkgPCB0aGlzLl9hbm5vdGF0aW9ucy5sZW5ndGggOyBpKysgKXtcblx0XHRcdGlmKG5hbWUgIT0gdGhpcy5fYW5ub3RhdGlvbnNbaV0ubmFtZSl7XG5cdFx0XHRcdHRoaXMuX2Fubm90YXRpb25zLnNwbGljZShpLDEpO1xuXHRcdFx0XHR0aGlzLl9yZWRyYXcoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHQvKipcbiAgICAqIFJlbW92ZXMgYWxsIHRoZSBjdXJyZW50IGFubm90YXRpb25zLlxuICAgICogXG4gICAgKiBAZXhhbXBsZSBcbiAgICAqIG15U2VxdWVuY2UucmVtb3ZlQWxsQW5ub3RhdGlvbnMoKTsgXG4gICAgKiBcbiAgICAqL1xuXHRyZW1vdmVBbGxBbm5vdGF0aW9uczogZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMuX2Fubm90YXRpb25zID0gW107XG5cdFx0dGhpcy5fcmVkcmF3KCk7XG5cdH0sXG5cblx0XG59KTtcblxucmVxdWlyZShcImJpb2pzLWV2ZW50c1wiKS5taXhpbihTZXF1ZW5jZS5wcm90b3R5cGUpO1xubW9kdWxlLmV4cG9ydHMgPSBTZXF1ZW5jZTtcbiIsInZhciBldmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG5cbmV2ZW50cy5vbkFsbCA9IGZ1bmN0aW9uKGNhbGxiYWNrLGNvbnRleHQpe1xuICB0aGlzLm9uKFwiYWxsXCIsIGNhbGxiYWNrLGNvbnRleHQpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE1peGluIHV0aWxpdHlcbmV2ZW50cy5vbGRNaXhpbiA9IGV2ZW50cy5taXhpbjtcbmV2ZW50cy5taXhpbiA9IGZ1bmN0aW9uKHByb3RvKSB7XG4gIGV2ZW50cy5vbGRNaXhpbihwcm90byk7XG4gIC8vIGFkZCBjdXN0b20gb25BbGxcbiAgdmFyIGV4cG9ydHMgPSBbJ29uQWxsJ107XG4gIGZvcih2YXIgaT0wOyBpIDwgZXhwb3J0cy5sZW5ndGg7aSsrKXtcbiAgICB2YXIgbmFtZSA9IGV4cG9ydHNbaV07XG4gICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICB9XG4gIHJldHVybiBwcm90bztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXZlbnRzO1xuIiwiLyoqXG4gKiBTdGFuZGFsb25lIGV4dHJhY3Rpb24gb2YgQmFja2JvbmUuRXZlbnRzLCBubyBleHRlcm5hbCBkZXBlbmRlbmN5IHJlcXVpcmVkLlxuICogRGVncmFkZXMgbmljZWx5IHdoZW4gQmFja29uZS91bmRlcnNjb3JlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudFxuICogZ2xvYmFsIGNvbnRleHQuXG4gKlxuICogTm90ZSB0aGF0IGRvY3Mgc3VnZ2VzdCB0byB1c2UgdW5kZXJzY29yZSdzIGBfLmV4dGVuZCgpYCBtZXRob2QgdG8gYWRkIEV2ZW50c1xuICogc3VwcG9ydCB0byBzb21lIGdpdmVuIG9iamVjdC4gQSBgbWl4aW4oKWAgbWV0aG9kIGhhcyBiZWVuIGFkZGVkIHRvIHRoZSBFdmVudHNcbiAqIHByb3RvdHlwZSB0byBhdm9pZCB1c2luZyB1bmRlcnNjb3JlIGZvciB0aGF0IHNvbGUgcHVycG9zZTpcbiAqXG4gKiAgICAgdmFyIG15RXZlbnRFbWl0dGVyID0gQmFja2JvbmVFdmVudHMubWl4aW4oe30pO1xuICpcbiAqIE9yIGZvciBhIGZ1bmN0aW9uIGNvbnN0cnVjdG9yOlxuICpcbiAqICAgICBmdW5jdGlvbiBNeUNvbnN0cnVjdG9yKCl7fVxuICogICAgIE15Q29uc3RydWN0b3IucHJvdG90eXBlLmZvbyA9IGZ1bmN0aW9uKCl7fVxuICogICAgIEJhY2tib25lRXZlbnRzLm1peGluKE15Q29uc3RydWN0b3IucHJvdG90eXBlKTtcbiAqXG4gKiAoYykgMjAwOS0yMDEzIEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBJbmMuXG4gKiAoYykgMjAxMyBOaWNvbGFzIFBlcnJpYXVsdFxuICovXG4vKiBnbG9iYWwgZXhwb3J0czp0cnVlLCBkZWZpbmUsIG1vZHVsZSAqL1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgcm9vdCA9IHRoaXMsXG4gICAgICBicmVha2VyID0ge30sXG4gICAgICBuYXRpdmVGb3JFYWNoID0gQXJyYXkucHJvdG90eXBlLmZvckVhY2gsXG4gICAgICBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksXG4gICAgICBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZSxcbiAgICAgIGlkQ291bnRlciA9IDA7XG5cbiAgLy8gUmV0dXJucyBhIHBhcnRpYWwgaW1wbGVtZW50YXRpb24gbWF0Y2hpbmcgdGhlIG1pbmltYWwgQVBJIHN1YnNldCByZXF1aXJlZFxuICAvLyBieSBCYWNrYm9uZS5FdmVudHNcbiAgZnVuY3Rpb24gbWluaXNjb3JlKCkge1xuICAgIHJldHVybiB7XG4gICAgICBrZXlzOiBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmogIT09IFwiZnVuY3Rpb25cIiB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5cygpIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGtleSwga2V5cyA9IFtdO1xuICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGtleXNba2V5cy5sZW5ndGhdID0ga2V5O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgIH0sXG5cbiAgICAgIHVuaXF1ZUlkOiBmdW5jdGlvbihwcmVmaXgpIHtcbiAgICAgICAgdmFyIGlkID0gKytpZENvdW50ZXIgKyAnJztcbiAgICAgICAgcmV0dXJuIHByZWZpeCA/IHByZWZpeCArIGlkIDogaWQ7XG4gICAgICB9LFxuXG4gICAgICBoYXM6IGZ1bmN0aW9uKG9iaiwga2V5KSB7XG4gICAgICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbiAgICAgIH0sXG5cbiAgICAgIGVhY2g6IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICAgICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm47XG4gICAgICAgIGlmIChuYXRpdmVGb3JFYWNoICYmIG9iai5mb3JFYWNoID09PSBuYXRpdmVGb3JFYWNoKSB7XG4gICAgICAgICAgb2JqLmZvckVhY2goaXRlcmF0b3IsIGNvbnRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoKSB7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBvYmoubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpba2V5XSwga2V5LCBvYmopID09PSBicmVha2VyKSByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICBvbmNlOiBmdW5jdGlvbihmdW5jKSB7XG4gICAgICAgIHZhciByYW4gPSBmYWxzZSwgbWVtbztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChyYW4pIHJldHVybiBtZW1vO1xuICAgICAgICAgIHJhbiA9IHRydWU7XG4gICAgICAgICAgbWVtbyA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICBmdW5jID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgdmFyIF8gPSBtaW5pc2NvcmUoKSwgRXZlbnRzO1xuXG4gIC8vIEJhY2tib25lLkV2ZW50c1xuICAvLyAtLS0tLS0tLS0tLS0tLS1cblxuICAvLyBBIG1vZHVsZSB0aGF0IGNhbiBiZSBtaXhlZCBpbiB0byAqYW55IG9iamVjdCogaW4gb3JkZXIgdG8gcHJvdmlkZSBpdCB3aXRoXG4gIC8vIGN1c3RvbSBldmVudHMuIFlvdSBtYXkgYmluZCB3aXRoIGBvbmAgb3IgcmVtb3ZlIHdpdGggYG9mZmAgY2FsbGJhY2tcbiAgLy8gZnVuY3Rpb25zIHRvIGFuIGV2ZW50OyBgdHJpZ2dlcmAtaW5nIGFuIGV2ZW50IGZpcmVzIGFsbCBjYWxsYmFja3MgaW5cbiAgLy8gc3VjY2Vzc2lvbi5cbiAgLy9cbiAgLy8gICAgIHZhciBvYmplY3QgPSB7fTtcbiAgLy8gICAgIF8uZXh0ZW5kKG9iamVjdCwgQmFja2JvbmUuRXZlbnRzKTtcbiAgLy8gICAgIG9iamVjdC5vbignZXhwYW5kJywgZnVuY3Rpb24oKXsgYWxlcnQoJ2V4cGFuZGVkJyk7IH0pO1xuICAvLyAgICAgb2JqZWN0LnRyaWdnZXIoJ2V4cGFuZCcpO1xuICAvL1xuICBFdmVudHMgPSB7XG5cbiAgICAvLyBCaW5kIGFuIGV2ZW50IHRvIGEgYGNhbGxiYWNrYCBmdW5jdGlvbi4gUGFzc2luZyBgXCJhbGxcImAgd2lsbCBiaW5kXG4gICAgLy8gdGhlIGNhbGxiYWNrIHRvIGFsbCBldmVudHMgZmlyZWQuXG4gICAgb246IGZ1bmN0aW9uKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICBpZiAoIWV2ZW50c0FwaSh0aGlzLCAnb24nLCBuYW1lLCBbY2FsbGJhY2ssIGNvbnRleHRdKSB8fCAhY2FsbGJhY2spIHJldHVybiB0aGlzO1xuICAgICAgdGhpcy5fZXZlbnRzIHx8ICh0aGlzLl9ldmVudHMgPSB7fSk7XG4gICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdIHx8ICh0aGlzLl9ldmVudHNbbmFtZV0gPSBbXSk7XG4gICAgICBldmVudHMucHVzaCh7Y2FsbGJhY2s6IGNhbGxiYWNrLCBjb250ZXh0OiBjb250ZXh0LCBjdHg6IGNvbnRleHQgfHwgdGhpc30pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIEJpbmQgYW4gZXZlbnQgdG8gb25seSBiZSB0cmlnZ2VyZWQgYSBzaW5nbGUgdGltZS4gQWZ0ZXIgdGhlIGZpcnN0IHRpbWVcbiAgICAvLyB0aGUgY2FsbGJhY2sgaXMgaW52b2tlZCwgaXQgd2lsbCBiZSByZW1vdmVkLlxuICAgIG9uY2U6IGZ1bmN0aW9uKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICBpZiAoIWV2ZW50c0FwaSh0aGlzLCAnb25jZScsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pIHx8ICFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgb25jZSA9IF8ub25jZShmdW5jdGlvbigpIHtcbiAgICAgICAgc2VsZi5vZmYobmFtZSwgb25jZSk7XG4gICAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9KTtcbiAgICAgIG9uY2UuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICByZXR1cm4gdGhpcy5vbihuYW1lLCBvbmNlLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgLy8gUmVtb3ZlIG9uZSBvciBtYW55IGNhbGxiYWNrcy4gSWYgYGNvbnRleHRgIGlzIG51bGwsIHJlbW92ZXMgYWxsXG4gICAgLy8gY2FsbGJhY2tzIHdpdGggdGhhdCBmdW5jdGlvbi4gSWYgYGNhbGxiYWNrYCBpcyBudWxsLCByZW1vdmVzIGFsbFxuICAgIC8vIGNhbGxiYWNrcyBmb3IgdGhlIGV2ZW50LiBJZiBgbmFtZWAgaXMgbnVsbCwgcmVtb3ZlcyBhbGwgYm91bmRcbiAgICAvLyBjYWxsYmFja3MgZm9yIGFsbCBldmVudHMuXG4gICAgb2ZmOiBmdW5jdGlvbihuYW1lLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgICAgdmFyIHJldGFpbiwgZXYsIGV2ZW50cywgbmFtZXMsIGksIGwsIGosIGs7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhZXZlbnRzQXBpKHRoaXMsICdvZmYnLCBuYW1lLCBbY2FsbGJhY2ssIGNvbnRleHRdKSkgcmV0dXJuIHRoaXM7XG4gICAgICBpZiAoIW5hbWUgJiYgIWNhbGxiYWNrICYmICFjb250ZXh0KSB7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbmFtZXMgPSBuYW1lID8gW25hbWVdIDogXy5rZXlzKHRoaXMuX2V2ZW50cyk7XG4gICAgICBmb3IgKGkgPSAwLCBsID0gbmFtZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lc1tpXTtcbiAgICAgICAgaWYgKGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXSkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50c1tuYW1lXSA9IHJldGFpbiA9IFtdO1xuICAgICAgICAgIGlmIChjYWxsYmFjayB8fCBjb250ZXh0KSB7XG4gICAgICAgICAgICBmb3IgKGogPSAwLCBrID0gZXZlbnRzLmxlbmd0aDsgaiA8IGs7IGorKykge1xuICAgICAgICAgICAgICBldiA9IGV2ZW50c1tqXTtcbiAgICAgICAgICAgICAgaWYgKChjYWxsYmFjayAmJiBjYWxsYmFjayAhPT0gZXYuY2FsbGJhY2sgJiYgY2FsbGJhY2sgIT09IGV2LmNhbGxiYWNrLl9jYWxsYmFjaykgfHxcbiAgICAgICAgICAgICAgICAgIChjb250ZXh0ICYmIGNvbnRleHQgIT09IGV2LmNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgcmV0YWluLnB1c2goZXYpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghcmV0YWluLmxlbmd0aCkgZGVsZXRlIHRoaXMuX2V2ZW50c1tuYW1lXTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gVHJpZ2dlciBvbmUgb3IgbWFueSBldmVudHMsIGZpcmluZyBhbGwgYm91bmQgY2FsbGJhY2tzLiBDYWxsYmFja3MgYXJlXG4gICAgLy8gcGFzc2VkIHRoZSBzYW1lIGFyZ3VtZW50cyBhcyBgdHJpZ2dlcmAgaXMsIGFwYXJ0IGZyb20gdGhlIGV2ZW50IG5hbWVcbiAgICAvLyAodW5sZXNzIHlvdSdyZSBsaXN0ZW5pbmcgb24gYFwiYWxsXCJgLCB3aGljaCB3aWxsIGNhdXNlIHlvdXIgY2FsbGJhY2sgdG9cbiAgICAvLyByZWNlaXZlIHRoZSB0cnVlIG5hbWUgb2YgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBhcmd1bWVudCkuXG4gICAgdHJpZ2dlcjogZnVuY3Rpb24obmFtZSkge1xuICAgICAgaWYgKCF0aGlzLl9ldmVudHMpIHJldHVybiB0aGlzO1xuICAgICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICBpZiAoIWV2ZW50c0FwaSh0aGlzLCAndHJpZ2dlcicsIG5hbWUsIGFyZ3MpKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV07XG4gICAgICB2YXIgYWxsRXZlbnRzID0gdGhpcy5fZXZlbnRzLmFsbDtcbiAgICAgIGlmIChldmVudHMpIHRyaWdnZXJFdmVudHMoZXZlbnRzLCBhcmdzKTtcbiAgICAgIGlmIChhbGxFdmVudHMpIHRyaWdnZXJFdmVudHMoYWxsRXZlbnRzLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIFRlbGwgdGhpcyBvYmplY3QgdG8gc3RvcCBsaXN0ZW5pbmcgdG8gZWl0aGVyIHNwZWNpZmljIGV2ZW50cyAuLi4gb3JcbiAgICAvLyB0byBldmVyeSBvYmplY3QgaXQncyBjdXJyZW50bHkgbGlzdGVuaW5nIHRvLlxuICAgIHN0b3BMaXN0ZW5pbmc6IGZ1bmN0aW9uKG9iaiwgbmFtZSwgY2FsbGJhY2spIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgICBpZiAoIWxpc3RlbmVycykgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgZGVsZXRlTGlzdGVuZXIgPSAhbmFtZSAmJiAhY2FsbGJhY2s7XG4gICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnKSBjYWxsYmFjayA9IHRoaXM7XG4gICAgICBpZiAob2JqKSAobGlzdGVuZXJzID0ge30pW29iai5fbGlzdGVuZXJJZF0gPSBvYmo7XG4gICAgICBmb3IgKHZhciBpZCBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgbGlzdGVuZXJzW2lkXS5vZmYobmFtZSwgY2FsbGJhY2ssIHRoaXMpO1xuICAgICAgICBpZiAoZGVsZXRlTGlzdGVuZXIpIGRlbGV0ZSB0aGlzLl9saXN0ZW5lcnNbaWRdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gIH07XG5cbiAgLy8gUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gc3BsaXQgZXZlbnQgc3RyaW5ncy5cbiAgdmFyIGV2ZW50U3BsaXR0ZXIgPSAvXFxzKy87XG5cbiAgLy8gSW1wbGVtZW50IGZhbmN5IGZlYXR1cmVzIG9mIHRoZSBFdmVudHMgQVBJIHN1Y2ggYXMgbXVsdGlwbGUgZXZlbnRcbiAgLy8gbmFtZXMgYFwiY2hhbmdlIGJsdXJcImAgYW5kIGpRdWVyeS1zdHlsZSBldmVudCBtYXBzIGB7Y2hhbmdlOiBhY3Rpb259YFxuICAvLyBpbiB0ZXJtcyBvZiB0aGUgZXhpc3RpbmcgQVBJLlxuICB2YXIgZXZlbnRzQXBpID0gZnVuY3Rpb24ob2JqLCBhY3Rpb24sIG5hbWUsIHJlc3QpIHtcbiAgICBpZiAoIW5hbWUpIHJldHVybiB0cnVlO1xuXG4gICAgLy8gSGFuZGxlIGV2ZW50IG1hcHMuXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0Jykge1xuICAgICAgZm9yICh2YXIga2V5IGluIG5hbWUpIHtcbiAgICAgICAgb2JqW2FjdGlvbl0uYXBwbHkob2JqLCBba2V5LCBuYW1lW2tleV1dLmNvbmNhdChyZXN0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHNwYWNlIHNlcGFyYXRlZCBldmVudCBuYW1lcy5cbiAgICBpZiAoZXZlbnRTcGxpdHRlci50ZXN0KG5hbWUpKSB7XG4gICAgICB2YXIgbmFtZXMgPSBuYW1lLnNwbGl0KGV2ZW50U3BsaXR0ZXIpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBuYW1lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgb2JqW2FjdGlvbl0uYXBwbHkob2JqLCBbbmFtZXNbaV1dLmNvbmNhdChyZXN0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gQSBkaWZmaWN1bHQtdG8tYmVsaWV2ZSwgYnV0IG9wdGltaXplZCBpbnRlcm5hbCBkaXNwYXRjaCBmdW5jdGlvbiBmb3JcbiAgLy8gdHJpZ2dlcmluZyBldmVudHMuIFRyaWVzIHRvIGtlZXAgdGhlIHVzdWFsIGNhc2VzIHNwZWVkeSAobW9zdCBpbnRlcm5hbFxuICAvLyBCYWNrYm9uZSBldmVudHMgaGF2ZSAzIGFyZ3VtZW50cykuXG4gIHZhciB0cmlnZ2VyRXZlbnRzID0gZnVuY3Rpb24oZXZlbnRzLCBhcmdzKSB7XG4gICAgdmFyIGV2LCBpID0gLTEsIGwgPSBldmVudHMubGVuZ3RoLCBhMSA9IGFyZ3NbMF0sIGEyID0gYXJnc1sxXSwgYTMgPSBhcmdzWzJdO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgpOyByZXR1cm47XG4gICAgICBjYXNlIDE6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmNhbGwoZXYuY3R4LCBhMSk7IHJldHVybjtcbiAgICAgIGNhc2UgMjogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgsIGExLCBhMik7IHJldHVybjtcbiAgICAgIGNhc2UgMzogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgsIGExLCBhMiwgYTMpOyByZXR1cm47XG4gICAgICBkZWZhdWx0OiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5hcHBseShldi5jdHgsIGFyZ3MpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgbGlzdGVuTWV0aG9kcyA9IHtsaXN0ZW5UbzogJ29uJywgbGlzdGVuVG9PbmNlOiAnb25jZSd9O1xuXG4gIC8vIEludmVyc2lvbi1vZi1jb250cm9sIHZlcnNpb25zIG9mIGBvbmAgYW5kIGBvbmNlYC4gVGVsbCAqdGhpcyogb2JqZWN0IHRvXG4gIC8vIGxpc3RlbiB0byBhbiBldmVudCBpbiBhbm90aGVyIG9iamVjdCAuLi4ga2VlcGluZyB0cmFjayBvZiB3aGF0IGl0J3NcbiAgLy8gbGlzdGVuaW5nIHRvLlxuICBfLmVhY2gobGlzdGVuTWV0aG9kcywgZnVuY3Rpb24oaW1wbGVtZW50YXRpb24sIG1ldGhvZCkge1xuICAgIEV2ZW50c1ttZXRob2RdID0gZnVuY3Rpb24ob2JqLCBuYW1lLCBjYWxsYmFjaykge1xuICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycyB8fCAodGhpcy5fbGlzdGVuZXJzID0ge30pO1xuICAgICAgdmFyIGlkID0gb2JqLl9saXN0ZW5lcklkIHx8IChvYmouX2xpc3RlbmVySWQgPSBfLnVuaXF1ZUlkKCdsJykpO1xuICAgICAgbGlzdGVuZXJzW2lkXSA9IG9iajtcbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcpIGNhbGxiYWNrID0gdGhpcztcbiAgICAgIG9ialtpbXBsZW1lbnRhdGlvbl0obmFtZSwgY2FsbGJhY2ssIHRoaXMpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gQWxpYXNlcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG4gIEV2ZW50cy5iaW5kICAgPSBFdmVudHMub247XG4gIEV2ZW50cy51bmJpbmQgPSBFdmVudHMub2ZmO1xuXG4gIC8vIE1peGluIHV0aWxpdHlcbiAgRXZlbnRzLm1peGluID0gZnVuY3Rpb24ocHJvdG8pIHtcbiAgICB2YXIgZXhwb3J0cyA9IFsnb24nLCAnb25jZScsICdvZmYnLCAndHJpZ2dlcicsICdzdG9wTGlzdGVuaW5nJywgJ2xpc3RlblRvJyxcbiAgICAgICAgICAgICAgICAgICAnbGlzdGVuVG9PbmNlJywgJ2JpbmQnLCAndW5iaW5kJ107XG4gICAgXy5lYWNoKGV4cG9ydHMsIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHByb3RvW25hbWVdID0gdGhpc1tuYW1lXTtcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gcHJvdG87XG4gIH07XG5cbiAgLy8gRXhwb3J0IEV2ZW50cyBhcyBCYWNrYm9uZUV2ZW50cyBkZXBlbmRpbmcgb24gY3VycmVudCBjb250ZXh0XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gRXZlbnRzO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gRXZlbnRzO1xuICAgIH1cbiAgICBleHBvcnRzLkJhY2tib25lRXZlbnRzID0gRXZlbnRzO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuQmFja2JvbmVFdmVudHMgPSBFdmVudHM7XG4gIH1cbn0pKHRoaXMpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2JhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lJyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgR2VuZXJpY1JlYWRlciwgeGhyO1xuXG54aHIgPSByZXF1aXJlKCduZXRzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gR2VuZXJpY1JlYWRlciA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gR2VuZXJpY1JlYWRlcigpIHt9XG5cbiAgR2VuZXJpY1JlYWRlci5yZWFkID0gZnVuY3Rpb24odXJsLCBjYWxsYmFjaykge1xuICAgIHZhciBvbnJldDtcbiAgICBvbnJldCA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVyciwgcmVzcG9uc2UsIHRleHQpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzLl9vblJldHJpZXZhbCh0ZXh0LCBjYWxsYmFjayk7XG4gICAgICB9O1xuICAgIH0pKHRoaXMpO1xuICAgIHJldHVybiB4aHIodXJsLCBvbnJldCk7XG4gIH07XG5cbiAgR2VuZXJpY1JlYWRlci5fb25SZXRyaWV2YWwgPSBmdW5jdGlvbih0ZXh0LCBjYWxsYmFjaykge1xuICAgIHZhciByVGV4dDtcbiAgICByVGV4dCA9IHRoaXMucGFyc2UodGV4dCk7XG4gICAgcmV0dXJuIGNhbGxiYWNrKHJUZXh0KTtcbiAgfTtcblxuICByZXR1cm4gR2VuZXJpY1JlYWRlcjtcblxufSkoKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbnZhciBGYXN0YSwgR2VuZXJpY1JlYWRlciwgU2VxLCBTdHIsXG4gIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuU3RyID0gcmVxdWlyZShcIi4vc3RyaW5nc1wiKTtcblxuR2VuZXJpY1JlYWRlciA9IHJlcXVpcmUoXCIuL2dlbmVyaWNfcmVhZGVyXCIpO1xuXG5TZXEgPSByZXF1aXJlKFwiYmlvanMtbW9kZWxcIikuc2VxO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhc3RhID0gKGZ1bmN0aW9uKF9zdXBlcikge1xuICBfX2V4dGVuZHMoRmFzdGEsIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gRmFzdGEoKSB7XG4gICAgcmV0dXJuIEZhc3RhLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgRmFzdGEucGFyc2UgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIGN1cnJlbnRTZXEsIGRhdGFiYXNlLCBkYXRhYmFzZUlELCBpZGVudGlmaWVycywgaywgbGFiZWwsIGxpbmUsIHNlcXMsIF9pLCBfbGVuO1xuICAgIHNlcXMgPSBbXTtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRleHQpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICB0ZXh0ID0gdGV4dC5zcGxpdChcIlxcblwiKTtcbiAgICB9XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSB0ZXh0Lmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICBsaW5lID0gdGV4dFtfaV07XG4gICAgICBpZiAobGluZVswXSA9PT0gXCI+XCIgfHwgbGluZVswXSA9PT0gXCI7XCIpIHtcbiAgICAgICAgbGFiZWwgPSBsaW5lLnNsaWNlKDEpO1xuICAgICAgICBjdXJyZW50U2VxID0gbmV3IFNlcShcIlwiLCBsYWJlbCwgc2Vxcy5sZW5ndGgpO1xuICAgICAgICBzZXFzLnB1c2goY3VycmVudFNlcSk7XG4gICAgICAgIGlmIChTdHIuY29udGFpbnMoXCJ8XCIsIGxpbmUpKSB7XG4gICAgICAgICAgaWRlbnRpZmllcnMgPSBsYWJlbC5zcGxpdChcInxcIik7XG4gICAgICAgICAgayA9IDE7XG4gICAgICAgICAgd2hpbGUgKGsgPCBpZGVudGlmaWVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRhdGFiYXNlID0gaWRlbnRpZmllcnNba107XG4gICAgICAgICAgICBkYXRhYmFzZUlEID0gaWRlbnRpZmllcnNbayArIDFdO1xuICAgICAgICAgICAgY3VycmVudFNlcS5tZXRhW2RhdGFiYXNlXSA9IGRhdGFiYXNlSUQ7XG4gICAgICAgICAgICBrICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnRTZXEubmFtZSA9IGlkZW50aWZpZXJzW2lkZW50aWZpZXJzLmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50U2VxLnNlcSArPSBsaW5lO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2VxcztcbiAgfTtcblxuICByZXR1cm4gRmFzdGE7XG5cbn0pKEdlbmVyaWNSZWFkZXIpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIHN0cmluZ3M7XG5cbnN0cmluZ3MgPSB7XG4gIGNvbnRhaW5zOiBmdW5jdGlvbih0ZXh0LCBzZWFyY2gpIHtcbiAgICByZXR1cm4gJycuaW5kZXhPZi5jYWxsKHRleHQsIHNlYXJjaCwgMCkgIT09IC0xO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmluZ3M7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgVXRpbHM7XG5cblV0aWxzID0ge307XG5cblV0aWxzLnNwbGl0TkNoYXJzID0gZnVuY3Rpb24odHh0LCBudW0pIHtcbiAgdmFyIGksIHJlc3VsdCwgX2ksIF9yZWY7XG4gIHJlc3VsdCA9IFtdO1xuICBmb3IgKGkgPSBfaSA9IDAsIF9yZWYgPSB0eHQubGVuZ3RoIC0gMTsgbnVtID4gMCA/IF9pIDw9IF9yZWYgOiBfaSA+PSBfcmVmOyBpID0gX2kgKz0gbnVtKSB7XG4gICAgcmVzdWx0LnB1c2godHh0LnN1YnN0cihpLCBudW0pKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBVdGlscztcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbnZhciBGYXN0YUV4cG9ydGVyLCBVdGlscztcblxuVXRpbHMgPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGYXN0YUV4cG9ydGVyID0gKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBGYXN0YUV4cG9ydGVyKCkge31cblxuICBGYXN0YUV4cG9ydGVyW1wiZXhwb3J0XCJdID0gZnVuY3Rpb24oc2VxcywgYWNjZXNzKSB7XG4gICAgdmFyIHNlcSwgdGV4dCwgX2ksIF9sZW47XG4gICAgdGV4dCA9IFwiXCI7XG4gICAgZm9yIChfaSA9IDAsIF9sZW4gPSBzZXFzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICBzZXEgPSBzZXFzW19pXTtcbiAgICAgIGlmIChhY2Nlc3MgIT0gbnVsbCkge1xuICAgICAgICBzZXEgPSBhY2Nlc3Moc2VxKTtcbiAgICAgIH1cbiAgICAgIHRleHQgKz0gXCI+XCIgKyBzZXEubmFtZSArIFwiXFxuXCI7XG4gICAgICB0ZXh0ICs9IChVdGlscy5zcGxpdE5DaGFycyhzZXEuc2VxLCA4MCkpLmpvaW4oXCJcXG5cIik7XG4gICAgICB0ZXh0ICs9IFwiXFxuXCI7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0O1xuICB9O1xuXG4gIHJldHVybiBGYXN0YUV4cG9ydGVyO1xuXG59KSgpO1xuIiwibW9kdWxlLmV4cG9ydHMuc2VxID0gcmVxdWlyZShcIi4vc2VxXCIpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzZXEsIG5hbWUsIGlkKSB7XG4gICAgdGhpcy5zZXEgPSBzZXE7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy5tZXRhID0ge307XG59O1xuIiwidmFyIHJlcSA9IHJlcXVpcmUoJ3JlcXVlc3QnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IE5ldHNcblxuZnVuY3Rpb24gTmV0cyh1cmksIG9wdHMsIGNiKSB7XG4gIHJlcSh1cmksIG9wdHMsIGNiKVxufSIsInZhciB3aW5kb3cgPSByZXF1aXJlKFwiZ2xvYmFsL3dpbmRvd1wiKVxudmFyIG9uY2UgPSByZXF1aXJlKFwib25jZVwiKVxudmFyIHBhcnNlSGVhZGVycyA9IHJlcXVpcmUoJ3BhcnNlLWhlYWRlcnMnKVxuXG52YXIgbWVzc2FnZXMgPSB7XG4gICAgXCIwXCI6IFwiSW50ZXJuYWwgWE1MSHR0cFJlcXVlc3QgRXJyb3JcIixcbiAgICBcIjRcIjogXCI0eHggQ2xpZW50IEVycm9yXCIsXG4gICAgXCI1XCI6IFwiNXh4IFNlcnZlciBFcnJvclwiXG59XG5cbnZhciBYSFIgPSB3aW5kb3cuWE1MSHR0cFJlcXVlc3QgfHwgbm9vcFxudmFyIFhEUiA9IFwid2l0aENyZWRlbnRpYWxzXCIgaW4gKG5ldyBYSFIoKSkgPyBYSFIgOiB3aW5kb3cuWERvbWFpblJlcXVlc3RcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVYSFJcblxuZnVuY3Rpb24gY3JlYXRlWEhSKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7IHVyaTogb3B0aW9ucyB9XG4gICAgfVxuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2spXG5cbiAgICB2YXIgeGhyID0gb3B0aW9ucy54aHIgfHwgbnVsbFxuXG4gICAgaWYgKCF4aHIpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY29ycyB8fCBvcHRpb25zLnVzZVhEUikge1xuICAgICAgICAgICAgeGhyID0gbmV3IFhEUigpXG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgeGhyID0gbmV3IFhIUigpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdXJpID0geGhyLnVybCA9IG9wdGlvbnMudXJpIHx8IG9wdGlvbnMudXJsXG4gICAgdmFyIG1ldGhvZCA9IHhoci5tZXRob2QgPSBvcHRpb25zLm1ldGhvZCB8fCBcIkdFVFwiXG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHkgfHwgb3B0aW9ucy5kYXRhXG4gICAgdmFyIGhlYWRlcnMgPSB4aHIuaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fVxuICAgIHZhciBzeW5jID0gISFvcHRpb25zLnN5bmNcbiAgICB2YXIgaXNKc29uID0gZmFsc2VcbiAgICB2YXIga2V5XG4gICAgdmFyIGxvYWQgPSBvcHRpb25zLnJlc3BvbnNlID8gbG9hZFJlc3BvbnNlIDogbG9hZFhoclxuXG4gICAgaWYgKFwianNvblwiIGluIG9wdGlvbnMpIHtcbiAgICAgICAgaXNKc29uID0gdHJ1ZVxuICAgICAgICBoZWFkZXJzW1wiQWNjZXB0XCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gXCJHRVRcIiAmJiBtZXRob2QgIT09IFwiSEVBRFwiKSB7XG4gICAgICAgICAgICBoZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zLmpzb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gcmVhZHlzdGF0ZWNoYW5nZVxuICAgIHhoci5vbmxvYWQgPSBsb2FkXG4gICAgeGhyLm9uZXJyb3IgPSBlcnJvclxuICAgIC8vIElFOSBtdXN0IGhhdmUgb25wcm9ncmVzcyBiZSBzZXQgdG8gYSB1bmlxdWUgZnVuY3Rpb24uXG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIElFIG11c3QgZGllXG4gICAgfVxuICAgIC8vIGhhdGUgSUVcbiAgICB4aHIub250aW1lb3V0ID0gbm9vcFxuICAgIHhoci5vcGVuKG1ldGhvZCwgdXJpLCAhc3luYylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgIGlmIChvcHRpb25zLndpdGhDcmVkZW50aWFscyB8fCAob3B0aW9ucy5jb3JzICYmIG9wdGlvbnMud2l0aENyZWRlbnRpYWxzICE9PSBmYWxzZSkpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWVcbiAgICB9XG5cbiAgICAvLyBDYW5ub3Qgc2V0IHRpbWVvdXQgd2l0aCBzeW5jIHJlcXVlc3RcbiAgICBpZiAoIXN5bmMpIHtcbiAgICAgICAgeGhyLnRpbWVvdXQgPSBcInRpbWVvdXRcIiBpbiBvcHRpb25zID8gb3B0aW9ucy50aW1lb3V0IDogNTAwMFxuICAgIH1cblxuICAgIGlmICh4aHIuc2V0UmVxdWVzdEhlYWRlcikge1xuICAgICAgICBmb3Ioa2V5IGluIGhlYWRlcnMpe1xuICAgICAgICAgICAgaWYoaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKXtcbiAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkhlYWRlcnMgY2Fubm90IGJlIHNldCBvbiBhbiBYRG9tYWluUmVxdWVzdCBvYmplY3RcIilcbiAgICB9XG5cbiAgICBpZiAoXCJyZXNwb25zZVR5cGVcIiBpbiBvcHRpb25zKSB7XG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSBvcHRpb25zLnJlc3BvbnNlVHlwZVxuICAgIH1cbiAgICBcbiAgICBpZiAoXCJiZWZvcmVTZW5kXCIgaW4gb3B0aW9ucyAmJiBcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuYmVmb3JlU2VuZCA9PT0gXCJmdW5jdGlvblwiXG4gICAgKSB7XG4gICAgICAgIG9wdGlvbnMuYmVmb3JlU2VuZCh4aHIpXG4gICAgfVxuXG4gICAgeGhyLnNlbmQoYm9keSlcblxuICAgIHJldHVybiB4aHJcblxuICAgIGZ1bmN0aW9uIHJlYWR5c3RhdGVjaGFuZ2UoKSB7XG4gICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgbG9hZCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRCb2R5KCkge1xuICAgICAgICAvLyBDaHJvbWUgd2l0aCByZXF1ZXN0VHlwZT1ibG9iIHRocm93cyBlcnJvcnMgYXJyb3VuZCB3aGVuIGV2ZW4gdGVzdGluZyBhY2Nlc3MgdG8gcmVzcG9uc2VUZXh0XG4gICAgICAgIHZhciBib2R5ID0gbnVsbFxuXG4gICAgICAgIGlmICh4aHIucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VcbiAgICAgICAgfSBlbHNlIGlmICh4aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcgfHwgIXhoci5yZXNwb25zZVR5cGUpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VUZXh0IHx8IHhoci5yZXNwb25zZVhNTFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSnNvbikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBib2R5XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZSgpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzXG4gICAgfVxuXG4gICAgLy8gaWYgd2UncmUgZ2V0dGluZyBhIG5vbmUtb2sgc3RhdHVzQ29kZSwgYnVpbGQgJiByZXR1cm4gYW4gZXJyb3JcbiAgICBmdW5jdGlvbiBlcnJvckZyb21TdGF0dXNDb2RlKHN0YXR1cywgYm9keSkge1xuICAgICAgICB2YXIgZXJyb3IgPSBudWxsXG4gICAgICAgIGlmIChzdGF0dXMgPT09IDAgfHwgKHN0YXR1cyA+PSA0MDAgJiYgc3RhdHVzIDwgNjAwKSkge1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSAodHlwZW9mIGJvZHkgPT09IFwic3RyaW5nXCIgPyBib2R5IDogZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgbWVzc2FnZXNbU3RyaW5nKHN0YXR1cykuY2hhckF0KDApXVxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgICAgICAgICAgIGVycm9yLnN0YXR1c0NvZGUgPSBzdGF0dXNcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvclxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSAmIHByb2Nlc3MgdGhlIHJlc3BvbnNlIGluIGEgc3BlY2lhbCByZXNwb25zZSBvYmplY3RcbiAgICBmdW5jdGlvbiBsb2FkUmVzcG9uc2UoKSB7XG4gICAgICAgIHZhciBzdGF0dXMgPSBnZXRTdGF0dXNDb2RlKClcbiAgICAgICAgdmFyIGJvZHkgPSBnZXRCb2R5KClcbiAgICAgICAgdmFyIGVycm9yID0gZXJyb3JGcm9tU3RhdHVzQ29kZShzdGF0dXMsIGJvZHkpXG4gICAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGJvZHk6IGJvZHksXG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBzdGF0dXMsXG4gICAgICAgICAgICBzdGF0dXNUZXh0OiB4aHIuc3RhdHVzVGV4dCxcbiAgICAgICAgICAgIHJhdzogeGhyXG4gICAgICAgIH1cbiAgICAgICAgaWYoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycyl7IC8vcmVtZW1iZXIgeGhyIGNhbiBpbiBmYWN0IGJlIFhEUiBmb3IgQ09SUyBpbiBJRVxuICAgICAgICAgICAgcmVzcG9uc2UuaGVhZGVycyA9IHBhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzID0ge31cbiAgICAgICAgfVxuXG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXNwb25zZSwgcmVzcG9uc2UuYm9keSlcbiAgICB9XG5cbiAgICAvLyB3aWxsIGxvYWQgdGhlIGRhdGEgYW5kIGFkZCBzb21lIHJlc3BvbnNlIHByb3BlcnRpZXMgdG8gdGhlIHNvdXJjZSB4aHJcbiAgICAvLyBhbmQgdGhlbiByZXNwb25kIHdpdGggdGhhdFxuICAgIGZ1bmN0aW9uIGxvYWRYaHIoKSB7XG4gICAgICAgIHZhciBzdGF0dXMgPSBnZXRTdGF0dXNDb2RlKClcbiAgICAgICAgdmFyIGVycm9yID0gZXJyb3JGcm9tU3RhdHVzQ29kZShzdGF0dXMpXG5cbiAgICAgICAgeGhyLnN0YXR1cyA9IHhoci5zdGF0dXNDb2RlID0gc3RhdHVzXG4gICAgICAgIHhoci5ib2R5ID0gZ2V0Qm9keSgpXG4gICAgICAgIHhoci5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSlcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgeGhyLCB4aHIuYm9keSlcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlcnJvcihldnQpIHtcbiAgICAgICAgY2FsbGJhY2soZXZ0LCB4aHIpXG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuIiwiaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzZWxmO1xufSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHt9O1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBvbmNlXG5cbm9uY2UucHJvdG8gPSBvbmNlKGZ1bmN0aW9uICgpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEZ1bmN0aW9uLnByb3RvdHlwZSwgJ29uY2UnLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBvbmNlKHRoaXMpXG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSlcbn0pXG5cbmZ1bmN0aW9uIG9uY2UgKGZuKSB7XG4gIHZhciBjYWxsZWQgPSBmYWxzZVxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmIChjYWxsZWQpIHJldHVyblxuICAgIGNhbGxlZCA9IHRydWVcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICB9XG59XG4iLCJ2YXIgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJ2lzLWZ1bmN0aW9uJylcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoXG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gZm9yRWFjaChsaXN0LCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGlmICghaXNGdW5jdGlvbihpdGVyYXRvcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJylcbiAgICB9XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgY29udGV4dCA9IHRoaXNcbiAgICB9XG4gICAgXG4gICAgaWYgKHRvU3RyaW5nLmNhbGwobGlzdCkgPT09ICdbb2JqZWN0IEFycmF5XScpXG4gICAgICAgIGZvckVhY2hBcnJheShsaXN0LCBpdGVyYXRvciwgY29udGV4dClcbiAgICBlbHNlIGlmICh0eXBlb2YgbGlzdCA9PT0gJ3N0cmluZycpXG4gICAgICAgIGZvckVhY2hTdHJpbmcobGlzdCwgaXRlcmF0b3IsIGNvbnRleHQpXG4gICAgZWxzZVxuICAgICAgICBmb3JFYWNoT2JqZWN0KGxpc3QsIGl0ZXJhdG9yLCBjb250ZXh0KVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoQXJyYXkoYXJyYXksIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCBpKSkge1xuICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBhcnJheVtpXSwgaSwgYXJyYXkpXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2hTdHJpbmcoc3RyaW5nLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzdHJpbmcubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgLy8gbm8gc3VjaCB0aGluZyBhcyBhIHNwYXJzZSBzdHJpbmcuXG4gICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgc3RyaW5nLmNoYXJBdChpKSwgaSwgc3RyaW5nKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaE9iamVjdChvYmplY3QsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgZm9yICh2YXIgayBpbiBvYmplY3QpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrKSkge1xuICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmplY3Rba10sIGssIG9iamVjdClcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvblxuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24gKGZuKSB7XG4gIHZhciBzdHJpbmcgPSB0b1N0cmluZy5jYWxsKGZuKVxuICByZXR1cm4gc3RyaW5nID09PSAnW29iamVjdCBGdW5jdGlvbl0nIHx8XG4gICAgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiBzdHJpbmcgIT09ICdbb2JqZWN0IFJlZ0V4cF0nKSB8fFxuICAgICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAvLyBJRTggYW5kIGJlbG93XG4gICAgIChmbiA9PT0gd2luZG93LnNldFRpbWVvdXQgfHxcbiAgICAgIGZuID09PSB3aW5kb3cuYWxlcnQgfHxcbiAgICAgIGZuID09PSB3aW5kb3cuY29uZmlybSB8fFxuICAgICAgZm4gPT09IHdpbmRvdy5wcm9tcHQpKVxufTtcbiIsIlxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gdHJpbTtcblxuZnVuY3Rpb24gdHJpbShzdHIpe1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMqfFxccyokL2csICcnKTtcbn1cblxuZXhwb3J0cy5sZWZ0ID0gZnVuY3Rpb24oc3RyKXtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKi8sICcnKTtcbn07XG5cbmV4cG9ydHMucmlnaHQgPSBmdW5jdGlvbihzdHIpe1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL1xccyokLywgJycpO1xufTtcbiIsInZhciB0cmltID0gcmVxdWlyZSgndHJpbScpXG4gICwgZm9yRWFjaCA9IHJlcXVpcmUoJ2Zvci1lYWNoJylcbiAgLCBpc0FycmF5ID0gZnVuY3Rpb24oYXJnKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gICAgfVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChoZWFkZXJzKSB7XG4gIGlmICghaGVhZGVycylcbiAgICByZXR1cm4ge31cblxuICB2YXIgcmVzdWx0ID0ge31cblxuICBmb3JFYWNoKFxuICAgICAgdHJpbShoZWFkZXJzKS5zcGxpdCgnXFxuJylcbiAgICAsIGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gcm93LmluZGV4T2YoJzonKVxuICAgICAgICAgICwga2V5ID0gdHJpbShyb3cuc2xpY2UoMCwgaW5kZXgpKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgLCB2YWx1ZSA9IHRyaW0ocm93LnNsaWNlKGluZGV4ICsgMSkpXG5cbiAgICAgICAgaWYgKHR5cGVvZihyZXN1bHRba2V5XSkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZVxuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkocmVzdWx0W2tleV0pKSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHRba2V5XSA9IFsgcmVzdWx0W2tleV0sIHZhbHVlIF1cbiAgICAgICAgfVxuICAgICAgfVxuICApXG5cbiAgcmV0dXJuIHJlc3VsdFxufSIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9qcXVlcnkuYnJvd3NlcicpO1xuIiwiLyohXG4gKiBqUXVlcnkgQnJvd3NlciBQbHVnaW4gdjAuMC42XG4gKiBodHRwczovL2dpdGh1Yi5jb20vZ2FiY2ViL2pxdWVyeS1icm93c2VyLXBsdWdpblxuICpcbiAqIE9yaWdpbmFsIGpxdWVyeS1icm93c2VyIGNvZGUgQ29weXJpZ2h0IDIwMDUsIDIwMTMgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIE1vZGlmaWNhdGlvbnMgQ29weXJpZ2h0IDIwMTMgR2FicmllbCBDZWJyaWFuXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZ2FiY2ViXG4gKlxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKlxuICogRGF0ZTogMjAxMy0wNy0yOVQxNzoyMzoyNy0wNzowMFxuICovXG5cblxudmFyIG1hdGNoZWQsIGJyb3dzZXI7XG5cbnZhciB1YU1hdGNoID0gZnVuY3Rpb24oIHVhICkge1xuICB1YSA9IHVhLnRvTG93ZXJDYXNlKCk7XG5cbiAgdmFyIG1hdGNoID0gLyhvcHIpW1xcL10oW1xcdy5dKykvLmV4ZWMoIHVhICkgfHxcbiAgICAvKGNocm9tZSlbIFxcL10oW1xcdy5dKykvLmV4ZWMoIHVhICkgfHxcbiAgICAvKHZlcnNpb24pWyBcXC9dKFtcXHcuXSspLiooc2FmYXJpKVsgXFwvXShbXFx3Ll0rKS8uZXhlYyggdWEgKSB8fFxuICAgIC8od2Via2l0KVsgXFwvXShbXFx3Ll0rKS8uZXhlYyggdWEgKSB8fFxuICAgIC8ob3BlcmEpKD86Lip2ZXJzaW9ufClbIFxcL10oW1xcdy5dKykvLmV4ZWMoIHVhICkgfHxcbiAgICAvKG1zaWUpIChbXFx3Ll0rKS8uZXhlYyggdWEgKSB8fFxuICAgIHVhLmluZGV4T2YoXCJ0cmlkZW50XCIpID49IDAgJiYgLyhydikoPzo6fCApKFtcXHcuXSspLy5leGVjKCB1YSApIHx8XG4gICAgdWEuaW5kZXhPZihcImNvbXBhdGlibGVcIikgPCAwICYmIC8obW96aWxsYSkoPzouKj8gcnY6KFtcXHcuXSspfCkvLmV4ZWMoIHVhICkgfHxcbiAgICBbXTtcblxuICB2YXIgcGxhdGZvcm1fbWF0Y2ggPSAvKGlwYWQpLy5leGVjKCB1YSApIHx8XG4gICAgLyhpcGhvbmUpLy5leGVjKCB1YSApIHx8XG4gICAgLyhhbmRyb2lkKS8uZXhlYyggdWEgKSB8fFxuICAgIC8od2luZG93cyBwaG9uZSkvLmV4ZWMoIHVhICkgfHxcbiAgICAvKHdpbikvLmV4ZWMoIHVhICkgfHxcbiAgICAvKG1hYykvLmV4ZWMoIHVhICkgfHxcbiAgICAvKGxpbnV4KS8uZXhlYyggdWEgKSB8fFxuICAgIC8oY3JvcykvaS5leGVjKCB1YSApIHx8XG4gICAgW107XG5cbiAgcmV0dXJuIHtcbiAgICBicm93c2VyOiBtYXRjaFsgMyBdIHx8IG1hdGNoWyAxIF0gfHwgXCJcIixcbiAgICB2ZXJzaW9uOiBtYXRjaFsgMiBdIHx8IFwiMFwiLFxuICAgIHBsYXRmb3JtOiBwbGF0Zm9ybV9tYXRjaFsgMCBdIHx8IFwiXCJcbiAgfTtcbn07XG5cbm1hdGNoZWQgPSB1YU1hdGNoKCB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCApO1xuYnJvd3NlciA9IHt9O1xuYnJvd3Nlci51YU1hdGNoID0gdWFNYXRjaDtcblxuaWYgKCBtYXRjaGVkLmJyb3dzZXIgKSB7XG4gIGJyb3dzZXJbIG1hdGNoZWQuYnJvd3NlciBdID0gdHJ1ZTtcbiAgYnJvd3Nlci52ZXJzaW9uID0gbWF0Y2hlZC52ZXJzaW9uO1xuICBicm93c2VyLnZlcnNpb25OdW1iZXIgPSBwYXJzZUludChtYXRjaGVkLnZlcnNpb24pO1xufVxuXG5pZiAoIG1hdGNoZWQucGxhdGZvcm0gKSB7XG4gIGJyb3dzZXJbIG1hdGNoZWQucGxhdGZvcm0gXSA9IHRydWU7XG59XG5cbi8vIFRoZXNlIGFyZSBhbGwgY29uc2lkZXJlZCBtb2JpbGUgcGxhdGZvcm1zLCBtZWFuaW5nIHRoZXkgcnVuIGEgbW9iaWxlIGJyb3dzZXJcbmlmICggYnJvd3Nlci5hbmRyb2lkIHx8IGJyb3dzZXIuaXBhZCB8fCBicm93c2VyLmlwaG9uZSB8fCBicm93c2VyWyBcIndpbmRvd3MgcGhvbmVcIiBdICkge1xuICBicm93c2VyLm1vYmlsZSA9IHRydWU7XG59XG5cbi8vIFRoZXNlIGFyZSBhbGwgY29uc2lkZXJlZCBkZXNrdG9wIHBsYXRmb3JtcywgbWVhbmluZyB0aGV5IHJ1biBhIGRlc2t0b3AgYnJvd3NlclxuaWYgKCBicm93c2VyLmNyb3MgfHwgYnJvd3Nlci5tYWMgfHwgYnJvd3Nlci5saW51eCB8fCBicm93c2VyLndpbiApIHtcbiAgYnJvd3Nlci5kZXNrdG9wID0gdHJ1ZTtcbn1cblxuLy8gQ2hyb21lLCBPcGVyYSAxNSsgYW5kIFNhZmFyaSBhcmUgd2Via2l0IGJhc2VkIGJyb3dzZXJzXG5pZiAoIGJyb3dzZXIuY2hyb21lIHx8IGJyb3dzZXIub3ByIHx8IGJyb3dzZXIuc2FmYXJpICkge1xuICBicm93c2VyLndlYmtpdCA9IHRydWU7XG59XG5cbi8vIElFMTEgaGFzIGEgbmV3IHRva2VuIHNvIHdlIHdpbGwgYXNzaWduIGl0IG1zaWUgdG8gYXZvaWQgYnJlYWtpbmcgY2hhbmdlc1xuaWYgKCBicm93c2VyLnJ2IClcbntcbiAgdmFyIGllID0gXCJtc2llXCI7XG5cbiAgbWF0Y2hlZC5icm93c2VyID0gaWU7XG4gIGJyb3dzZXJbaWVdID0gdHJ1ZTtcbn1cblxuLy8gT3BlcmEgMTUrIGFyZSBpZGVudGlmaWVkIGFzIG9wclxuaWYgKCBicm93c2VyLm9wciApXG57XG4gIHZhciBvcGVyYSA9IFwib3BlcmFcIjtcblxuICBtYXRjaGVkLmJyb3dzZXIgPSBvcGVyYTtcbiAgYnJvd3NlcltvcGVyYV0gPSB0cnVlO1xufVxuXG4vLyBTdG9jayBBbmRyb2lkIGJyb3dzZXJzIGFyZSBtYXJrZWQgYXMgU2FmYXJpIG9uIEFuZHJvaWQuXG5pZiAoIGJyb3dzZXIuc2FmYXJpICYmIGJyb3dzZXIuYW5kcm9pZCApXG57XG4gIHZhciBhbmRyb2lkID0gXCJhbmRyb2lkXCI7XG5cbiAgbWF0Y2hlZC5icm93c2VyID0gYW5kcm9pZDtcbiAgYnJvd3NlclthbmRyb2lkXSA9IHRydWU7XG59XG5cbi8vIEFzc2lnbiB0aGUgbmFtZSBhbmQgcGxhdGZvcm0gdmFyaWFibGVcbmJyb3dzZXIubmFtZSA9IG1hdGNoZWQuYnJvd3NlcjtcbmJyb3dzZXIucGxhdGZvcm0gPSBtYXRjaGVkLnBsYXRmb3JtO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gYnJvd3NlcjtcbiIsIi8qKiBAcHJlc2VydmUgaHR0cDovL2dpdGh1Yi5jb20vZWFzZXdheS9qcy1jbGFzcyAqL1xuXG4vLyBDbGFzcyBEZWZpbml0aW9uIHVzaW5nIEVDTUE1IHByb3RvdHlwZSBjaGFpblxuXG5mdW5jdGlvbiBpbmhlcml0KGRlc3QsIHNyYywgbm9QYXJlbnQpIHtcbiAgICB3aGlsZSAoc3JjICYmIHNyYyAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzcmMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIGlmIChuYW1lICE9ICcuY2xhc3MnICYmICFkZXN0Lmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNyYywgbmFtZSk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRlc3QsIG5hbWUsIGRlc2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG5vUGFyZW50KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzcmMgPSBzcmMuX19wcm90b19fO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbn1cblxudmFyIENsYXNzID0gZnVuY3Rpb24gKGJhc2UsIHByb3RvLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZihiYXNlKSAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG9wdGlvbnMgPSBwcm90bztcbiAgICAgICAgcHJvdG8gPSBiYXNlO1xuICAgICAgICBiYXNlID0gT2JqZWN0O1xuICAgIH1cbiAgICBpZiAoIXByb3RvKSB7XG4gICAgICAgIHByb3RvID0ge307XG4gICAgfVxuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0ge307XG4gICAgfVxuICAgIFxuICAgIHZhciBtZXRhID0ge1xuICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICAgIGJhc2U6IGJhc2UsXG4gICAgICAgIGltcGxlbWVudHM6IFtdXG4gICAgfVxuICAgIHZhciBjbGFzc1Byb3RvID0gQ2xhc3MuY2xvbmUocHJvdG8pO1xuICAgIGlmIChvcHRpb25zLmltcGxlbWVudHMpIHtcbiAgICAgICAgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5pbXBsZW1lbnRzKSA/IG9wdGlvbnMuaW1wbGVtZW50cyA6IFtvcHRpb25zLmltcGxlbWVudHNdKVxuICAgICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGltcGxlbWVudGVkVHlwZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YoaW1wbGVtZW50ZWRUeXBlKSA9PSAnZnVuY3Rpb24nICYmIGltcGxlbWVudGVkVHlwZS5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0YS5pbXBsZW1lbnRzLnB1c2goaW1wbGVtZW50ZWRUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgQ2xhc3MuZXh0ZW5kKGNsYXNzUHJvdG8sIGltcGxlbWVudGVkVHlwZS5wcm90b3R5cGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH1cbiAgICBjbGFzc1Byb3RvLl9fcHJvdG9fXyA9IGJhc2UucHJvdG90eXBlO1xuICAgIHZhciB0aGVDbGFzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZih0aGlzLmNvbnN0cnVjdG9yKSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIG1ldGEudHlwZSA9IHRoZUNsYXNzO1xuICAgIHRoZUNsYXNzLnByb3RvdHlwZSA9IGNsYXNzUHJvdG87XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoZUNsYXNzLCAnLmNsYXNzLm1ldGEnLCB7IHZhbHVlOiBtZXRhLCBlbnVtZXJhYmxlOiBmYWxzZSwgY29uZmlndXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IGZhbHNlIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjbGFzc1Byb3RvLCAnLmNsYXNzJywgeyB2YWx1ZTogdGhlQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCBjb25maWd1cmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UgfSk7XG4gICAgaWYgKG9wdGlvbnMuc3RhdGljcykge1xuICAgICAgICBDbGFzcy5leHRlbmQodGhlQ2xhc3MsIG9wdGlvbnMuc3RhdGljcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGVDbGFzcztcbn07XG5cbkNsYXNzLmV4dGVuZCA9IGluaGVyaXQ7XG5cbkNsYXNzLmNsb25lID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBpbmhlcml0KHt9LCBvYmplY3QpO1xufTtcblxuZnVuY3Rpb24gZmluZFR5cGUobWV0YSwgdHlwZSkge1xuICAgIHdoaWxlIChtZXRhKSB7XG4gICAgICAgIGlmIChtZXRhLnR5cGUucHJvdG90eXBlID09PSB0eXBlLnByb3RvdHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSBpbiBtZXRhLmltcGxlbWVudHMpIHtcbiAgICAgICAgICAgIHZhciBpbXBsVHlwZSA9IG1ldGEuaW1wbGVtZW50c1tpXTtcbiAgICAgICAgICAgIHZhciBpbXBsTWV0YSA9IGltcGxUeXBlWycuY2xhc3MubWV0YSddO1xuICAgICAgICAgICAgaWYgKGltcGxNZXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpbmRUeXBlKGltcGxNZXRhLCB0eXBlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3RvID0gaW1wbFR5cGUucHJvdG90eXBlOyBwcm90bzsgcHJvdG8gPSBwcm90by5fX3Byb3RvX18pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3RvID09PSB0eXBlLnByb3RvdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWV0YSA9IG1ldGEuYmFzZSA/IG1ldGEuYmFzZVsnLmNsYXNzLm1ldGEnXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG52YXIgQ2hlY2tlciA9IENsYXNzKHtcbiAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgICB0aGlzLm9iamVjdCA9IG9iamVjdDtcbiAgICB9LFxuICAgIFxuICAgIHR5cGVPZjogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMub2JqZWN0IGluc3RhbmNlb2YgdHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1ldGEgPSBDbGFzcy50eXBlSW5mbyh0aGlzLm9iamVjdCk7XG4gICAgICAgIHJldHVybiBtZXRhICYmIGZpbmRUeXBlKG1ldGEsIHR5cGUpO1xuICAgIH1cbn0pO1xuXG4vLyBhbGlhc2VzXG5DaGVja2VyLnByb3RvdHlwZS5hID0gQ2hlY2tlci5wcm90b3R5cGUudHlwZU9mO1xuQ2hlY2tlci5wcm90b3R5cGUuYW4gPSBDaGVja2VyLnByb3RvdHlwZS50eXBlT2Y7XG5cbkNsYXNzLmlzID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBuZXcgQ2hlY2tlcihvYmplY3QpO1xufTtcblxuQ2xhc3MudHlwZUluZm8gPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgdmFyIHRoZUNsYXNzID0gb2JqZWN0Ll9fcHJvdG9fX1snLmNsYXNzJ107XG4gICAgcmV0dXJuIHRoZUNsYXNzID8gdGhlQ2xhc3NbJy5jbGFzcy5tZXRhJ10gOiB1bmRlZmluZWQ7XG59O1xuXG5DbGFzcy5WRVJTSU9OID0gWzAsIDAsIDJdO1xuXG5pZiAobW9kdWxlKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBDbGFzcztcbn0gZWxzZSB7XG4gICAgZ2xvYmFsLkNsYXNzID0gQ2xhc3M7ICAgLy8gZm9yIGJyb3dzZXJcbn0iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG5tb2R1bGUuZXhwb3J0cy5wYXJzZSA9IHJlcXVpcmUoXCIuL3BhcnNlclwiKTtcblxubW9kdWxlLmV4cG9ydHMud3JpdGVyID0gcmVxdWlyZShcIi4vd3JpdGVyXCIpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvaW5kZXhcIik7XG4iXX0=