@firestitch/report 18.8.1 → 18.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/app/reports/anchor-at-point.d.ts +14 -0
  2. package/app/reports/canvas-landing-page.d.ts +2 -0
  3. package/app/reports/components/component-chart/component-chart.component.d.ts +18 -2
  4. package/app/reports/components/component-kpi/component-kpi.component.d.ts +4 -1
  5. package/app/reports/components/component-text/component-text.component.d.ts +47 -2
  6. package/app/reports/components/component-text/value-embed.plugin.d.ts +67 -0
  7. package/app/reports/components/report-canvas/report-canvas.component.d.ts +37 -9
  8. package/app/reports/components/report-component/report-component.component.d.ts +45 -2
  9. package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
  10. package/app/reports/data/report.data.d.ts +18 -2
  11. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +25 -2
  12. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +15 -6
  13. package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
  14. package/app/reports/drill-crumbs.d.ts +12 -0
  15. package/app/reports/enums/report-value-formula.enum.d.ts +6 -0
  16. package/app/reports/export/report-export-collector.service.d.ts +35 -4
  17. package/app/reports/export/report-export.service.d.ts +3 -1
  18. package/app/reports/export/report-filter-lines.d.ts +18 -0
  19. package/app/reports/export/report-pdf.service.d.ts +18 -2
  20. package/app/reports/export/report-pptx.service.d.ts +15 -2
  21. package/app/reports/export/report-text-layout.service.d.ts +35 -0
  22. package/app/reports/filter-settings-rules.d.ts +33 -0
  23. package/app/reports/format.d.ts +2 -1
  24. package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
  25. package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
  26. package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
  27. package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
  28. package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
  29. package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
  30. package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
  31. package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
  32. package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
  33. package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
  34. package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
  35. package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
  36. package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
  37. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
  38. package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
  39. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
  40. package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
  41. package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
  42. package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
  43. package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
  44. package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
  45. package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
  46. package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
  47. package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
  48. package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
  49. package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
  50. package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
  51. package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
  52. package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
  53. package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
  54. package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
  55. package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
  56. package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
  57. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
  58. package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
  59. package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
  60. package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
  61. package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
  62. package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
  63. package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
  64. package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
  65. package/app/reports/interfaces/report-url-link.interface.d.ts +4 -0
  66. package/app/reports/interfaces/report-url-value-name.type.d.ts +1 -0
  67. package/app/reports/interfaces/report-url-write.interface.d.ts +4 -0
  68. package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
  69. package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
  70. package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
  71. package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
  72. package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
  73. package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
  74. package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
  75. package/app/reports/interfaces/report-view.interface.d.ts +7 -0
  76. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
  77. package/app/reports/interfaces/report-views.interface.d.ts +7 -0
  78. package/app/reports/interfaces/report.interface.d.ts +48 -5
  79. package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
  80. package/app/reports/layout.d.ts +2 -0
  81. package/app/reports/mark-click.d.ts +20 -0
  82. package/app/reports/option-builder.d.ts +12 -1
  83. package/app/reports/report-chat-viewer-state.d.ts +8 -0
  84. package/app/reports/report-date-presets.d.ts +2 -0
  85. package/app/reports/report-filter-items.d.ts +27 -22
  86. package/app/reports/report-tile.d.ts +2 -0
  87. package/app/reports/report-url-state.d.ts +27 -10
  88. package/app/reports/report-view-config.d.ts +36 -0
  89. package/app/reports/report-view-menu.d.ts +15 -0
  90. package/app/reports/report-viewer-features.d.ts +5 -0
  91. package/app/reports/services/report-filter-options.service.d.ts +26 -0
  92. package/app/reports/services/report-filter-state.service.d.ts +65 -2
  93. package/app/reports/services/report-view.service.d.ts +51 -0
  94. package/app/reports/text.d.ts +50 -0
  95. package/app/reports/tile-data-state.d.ts +7 -0
  96. package/app/reports/tile-loads.d.ts +4 -0
  97. package/app/reports/values.d.ts +17 -0
  98. package/app/reports/views/report/fs-ai-report.component.d.ts +9 -1
  99. package/app/reports/views/report/report.component.d.ts +6 -0
  100. package/esm2022/app/reports/anchor-at-point.mjs +49 -0
  101. package/esm2022/app/reports/canvas-landing-page.mjs +25 -0
  102. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
  103. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
  104. package/esm2022/app/reports/components/component-list/component-list.component.mjs +7 -1
  105. package/esm2022/app/reports/components/component-text/component-text.component.mjs +213 -16
  106. package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +484 -0
  107. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +296 -55
  108. package/esm2022/app/reports/components/report-component/report-component.component.mjs +318 -76
  109. package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
  110. package/esm2022/app/reports/data/report.data.mjs +103 -8
  111. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +210 -44
  112. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +86 -90
  113. package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
  114. package/esm2022/app/reports/drill-crumbs.mjs +73 -0
  115. package/esm2022/app/reports/enums/report-value-formula.enum.mjs +14 -0
  116. package/esm2022/app/reports/export/report-export-collector.service.mjs +299 -125
  117. package/esm2022/app/reports/export/report-export.service.mjs +57 -19
  118. package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
  119. package/esm2022/app/reports/export/report-pdf.service.mjs +315 -71
  120. package/esm2022/app/reports/export/report-pptx.service.mjs +293 -71
  121. package/esm2022/app/reports/export/report-text-layout.service.mjs +241 -0
  122. package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
  123. package/esm2022/app/reports/format.mjs +13 -30
  124. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
  125. package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
  126. package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
  127. package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
  128. package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
  129. package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
  130. package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
  131. package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
  132. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
  133. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
  134. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
  135. package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
  136. package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
  137. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  138. package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
  139. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  140. package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
  141. package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
  142. package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
  143. package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
  144. package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
  145. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
  146. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
  147. package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
  148. package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
  149. package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
  150. package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
  151. package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
  152. package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
  153. package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
  154. package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
  155. package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
  156. package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
  157. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
  158. package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
  159. package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
  160. package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
  161. package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
  162. package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
  163. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
  164. package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
  165. package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +2 -0
  166. package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +2 -0
  167. package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +2 -0
  168. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
  169. package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
  170. package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
  171. package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
  172. package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
  173. package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
  174. package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
  175. package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
  176. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
  177. package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
  178. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  179. package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
  180. package/esm2022/app/reports/layout.mjs +11 -1
  181. package/esm2022/app/reports/mark-click.mjs +193 -0
  182. package/esm2022/app/reports/option-builder.mjs +159 -15
  183. package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
  184. package/esm2022/app/reports/report-date-presets.mjs +18 -0
  185. package/esm2022/app/reports/report-filter-items.mjs +343 -72
  186. package/esm2022/app/reports/report-tile.mjs +12 -0
  187. package/esm2022/app/reports/report-url-state.mjs +596 -108
  188. package/esm2022/app/reports/report-view-config.mjs +697 -0
  189. package/esm2022/app/reports/report-view-menu.mjs +119 -0
  190. package/esm2022/app/reports/report-viewer-features.mjs +42 -0
  191. package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
  192. package/esm2022/app/reports/services/report-filter-state.service.mjs +715 -71
  193. package/esm2022/app/reports/services/report-view.service.mjs +358 -0
  194. package/esm2022/app/reports/text.mjs +293 -85
  195. package/esm2022/app/reports/tile-data-state.mjs +127 -0
  196. package/esm2022/app/reports/tile-loads.mjs +38 -0
  197. package/esm2022/app/reports/values.mjs +183 -0
  198. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +180 -46
  199. package/esm2022/app/reports/views/report/report.component.mjs +106 -23
  200. package/esm2022/public_api.mjs +24 -1
  201. package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
  202. package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
  203. package/fesm2022/{firestitch-report-firestitch-report-CSylkyko.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +11315 -4201
  204. package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +1 -0
  205. package/fesm2022/firestitch-report.mjs +1 -1
  206. package/package.json +1 -1
  207. package/public_api.d.ts +23 -0
  208. package/fesm2022/firestitch-report-firestitch-report-CSylkyko.mjs.map +0 -1
@@ -2,14 +2,22 @@ import { Injectable, inject } from '@angular/core';
2
2
  import { forkJoin, from, map, of } from 'rxjs';
3
3
  import { catchError, mergeMap, toArray } from 'rxjs/operators';
4
4
  import { ReportData } from '../data/report.data';
5
+ import { crumbedTitle, drillCrumbLabels } from '../drill-crumbs';
5
6
  import { ReportListColumnFormat } from '../enums/report-list-column-format.enum';
6
7
  import { DAY_LONG, formatLocalDate, formatNumber, formatOutputValue, formatReportDate, hasNumberFormat, resolveReportTimezone, } from '../format';
7
- import { GRANULARITY_OPTIONS, } from '../interfaces/report.interface';
8
8
  import { LIST_TOTAL_LABEL, listHiddenColumns, listOutputColumns, listTotalsLabelColumn, } from '../list-config';
9
9
  import { pivotColumnSpecs } from '../option-builder';
10
10
  import { componentNoteLines, componentWindowsLine } from '../output-notes';
11
- import { dateBoundLabel, loadGroupOptions, resolveOptionValues } from '../report-filter-items';
11
+ import { loadGroupOptions, resolveOptionValues } from '../report-filter-items';
12
+ import { isTile } from '../report-tile';
13
+ import { offeredViewerFeatures } from '../report-viewer-features';
14
+ import { ReportFilterOptionsService } from '../services/report-filter-options.service';
12
15
  import { ReportFilterStateService } from '../services/report-filter-state.service';
16
+ import { ReportViewService } from '../services/report-view.service';
17
+ import { textPlain } from '../text';
18
+ import { tileDataState, valuesMatchAnyGroupIds } from '../tile-data-state';
19
+ import { failedValueKeys, reportComponents, shownValues, textValues, valueKeys, } from '../values';
20
+ import { exportLines, matchLineText, viewLineText } from './report-filter-lines';
13
21
  import * as i0 from "@angular/core";
14
22
  // How far a KPI card's rows shrink to fit a short tile. A tile shorter still
15
23
  // lets the card run past its foot rather than print it unreadably small.
@@ -25,6 +33,13 @@ const KPI_EXPORT_MIN_SCALE = 0.5;
25
33
  // where the queries start taking it back off each other, and past that it buys
26
34
  // failures.
27
35
  const EXPORT_CONCURRENCY = 3;
36
+ // What the export gates call the header and footer: when a value they show
37
+ // came back without its number, and when one of their text blocks does not
38
+ // fit its box.
39
+ export const HEADER_FOOTER_NAME = 'Header & footer';
40
+ // How much of a text block's words the export gates quote to name a block that
41
+ // does not fit its box.
42
+ const OVERFLOW_SNIPPET_LENGTH = 40;
28
43
  // What a component with nothing to draw prints in the exported file.
29
44
  //
30
45
  // The two cases must not read alike. A tile that returned no rows is a finding
@@ -36,12 +51,14 @@ const EXPORT_CONCURRENCY = 3;
36
51
  export function emptyLabel(item) {
37
52
  return item.data ? 'No data' : 'Could not be generated';
38
53
  }
39
- // A component's title as an exported file prints it. A searched list says so,
40
- // since its table holds only the matching rows: 'Orders (matching "north")'.
41
- // An untitled one reads 'Matching "north"'. '' when there is nothing to print.
42
- // Shared by the PDF and the deck, continuation pages included.
43
- export function exportTitle(component, search) {
44
- const title = component.title ?? '';
54
+ // A component's title as an exported file prints it. A drilled chart's title
55
+ // is followed by its breadcrumb, `crumbs` (drillCrumbLabels): 'Orders by
56
+ // Period › 2026 › Q3'. A searched list says so, since its table holds only
57
+ // the matching rows: 'Orders (matching "north")'. An untitled one reads
58
+ // 'Matching "north"'. '' when there is nothing to print. Shared by the PDF
59
+ // and the deck, continuation pages included.
60
+ export function exportTitle(component, search, crumbs) {
61
+ const title = crumbedTitle(component.title, crumbs ?? []);
45
62
  if (!search) {
46
63
  return title;
47
64
  }
@@ -51,6 +68,17 @@ export function exportTitle(component, search) {
51
68
  export function isFailed(item) {
52
69
  return !item.data && item.component.type !== 'text';
53
70
  }
71
+ // A text block that does not fit its box in a built file, as the overflow gate
72
+ // names it: under its page (HEADER_FOOTER_NAME for a header or footer block)
73
+ // and by the start of its words, on one line. Shared by the PDF and the deck.
74
+ export function textOverflow(component, page, tokens) {
75
+ const text = textPlain(component.config?.html ?? '', tokens).replace(/\s+/g, ' ').trim();
76
+ return {
77
+ componentId: component.id,
78
+ page,
79
+ snippet: text.length > OVERFLOW_SNIPPET_LENGTH ? `${text.slice(0, OVERFLOW_SNIPPET_LENGTH).trimEnd()}…` : text,
80
+ };
81
+ }
54
82
  // The lines under the report's name on the PDF title page and the title slide:
55
83
  // the export date, the active filters, then what the numbers are measured in.
56
84
  // The date always leads (the PowerPoint marks that line as written in the
@@ -234,140 +262,289 @@ export function moreRowsNotice(remaining) {
234
262
  return `… ${remaining} more row(s) — use the component's CSV export for the full dataset`;
235
263
  }
236
264
  // The pages of a collected report that have at least one tile whose query
237
- // failed — what the export gate names to the user, and what makes "some of this
238
- // file is missing" a fact the caller can act on rather than a thing they notice
239
- // in the PDF afterwards.
265
+ // failed, or whose text shows a value that came back without its number, then
266
+ // HEADER_FOOTER_NAME when the header or footer shows one on a page that shows
267
+ // the master — what the failure gate names to the user, and what makes "some
268
+ // of this file is missing" a fact the caller can act on rather than a thing
269
+ // they notice in the PDF afterwards.
240
270
  export function failedPageNames(collected) {
241
271
  // Numbered before the filter — an unnamed page 4 that failed has to read
242
272
  // "Page 4", not "Page 1" because it happened to be the first failure.
243
- return collected.pages
273
+ const names = collected.pages
244
274
  .map((page, index) => ({ page, number: index + 1 }))
245
- .filter(({ page }) => page.components.some(isFailed))
275
+ .filter(({ page }) => page.components.some(isFailed)
276
+ || showsFailedValue(page.components.map((item) => item.component), page.failedValues))
246
277
  .map(({ page, number }) => page.page.name || `Page ${number}`);
278
+ const master = collected.report.master;
279
+ const showsMaster = collected.pages.some(({ page }) => !page.masterHidden);
280
+ if (master && showsMaster && showsFailedValue(master.components, collected.masterFailedValues)) {
281
+ names.push(HEADER_FOOTER_NAME);
282
+ }
283
+ return names;
284
+ }
285
+ // Whether any of the text blocks shows one of the failed value keys.
286
+ function showsFailedValue(components, failed) {
287
+ const shown = new Set(components
288
+ .filter((component) => component.type === 'text')
289
+ .flatMap((component) => valueKeys(component.config?.html)));
290
+ return failed.some((key) => shown.has(key));
291
+ }
292
+ // The cover's filter lines: the open view, the export's filter lines, then
293
+ // the match while the report bar's filters match any. A drilled chart's line
294
+ // is its title and the crumbs of the path its answer applied (the ones its
295
+ // title prints), not the path the screen asked for: the server may have cut
296
+ // that path short or refused it.
297
+ export function coverFilterLines(snapshot, lines, pages) {
298
+ const match = snapshot.features.includes('matchAny') ? matchLineText(snapshot.view.match, 'line') : null;
299
+ const drilled = pages
300
+ .flatMap((page) => page.components)
301
+ .filter((item) => !!item.crumbs?.length)
302
+ .map((item) => crumbedTitle(item.component.title, item.crumbs));
303
+ return [
304
+ snapshot.viewLine,
305
+ ...lines.filter((line) => line.kind !== 'drill').map((line) => line.text),
306
+ ...drilled,
307
+ match,
308
+ ]
309
+ .filter((line) => !!line);
310
+ }
311
+ // Whether a PDF or PowerPoint export lays a component out: every tile, and
312
+ // every text block, which has nothing to fetch and rides through with no
313
+ // data. Any other type (an inline value, or a type this viewer does not
314
+ // know) never is: a value is read only through its layer's values job.
315
+ export function isExportSlot(component) {
316
+ return isTile(component) || component.type === 'text';
247
317
  }
248
318
  // Gathers everything an export needs: every component's data across ALL pages
249
319
  // (the canvas only renders the active page, so exports can't scrape the
250
- // screen), fetched fresh with the viewer's current filter state.
320
+ // screen), and the numbers of the values their text reads, fetched fresh with
321
+ // the viewer's current filter state.
251
322
  //
252
- // A failed component resolves to a null `data` rather than failing the whole
253
- // collection — but that is so the caller can REPORT what failed, not so it can
254
- // be ignored: see failedPageNames() and the export gate that uses it.
323
+ // A failed component resolves to a null `data`, and a failed value to a key in
324
+ // its page's failedValues, rather than failing the whole collection — but that
325
+ // is so the caller can REPORT what failed, not so it can be ignored: see
326
+ // failedPageNames() and the failure gate that uses it.
255
327
  export class ReportExportCollectorService {
256
328
  _reportData = inject(ReportData);
257
329
  _filterState = inject(ReportFilterStateService);
330
+ _filterOptions = inject(ReportFilterOptionsService);
331
+ // The open saved view, for the cover's view line. Only a view that keeps
332
+ // saved views provides it.
333
+ _views = inject(ReportViewService, { optional: true });
258
334
  // listRows is how many rows each list fetches: the renderer's own cap, since
259
335
  // a PDF table continues onto extra pages and a slide table cannot.
336
+ //
337
+ // The screen is read once, when the export starts (snapshot): every tile,
338
+ // every values job, the filter lines and the cover read that copy, so a
339
+ // filter changed while the tiles are fetched reaches none of them. A retry
340
+ // collects again, and so reads the screen as it is then.
260
341
  collect(report, listRows) {
261
- const slots = [];
262
- report.pages.forEach((page, pageIndex) => {
263
- for (const component of page.components) {
264
- slots.push({ pageIndex, component });
265
- }
266
- });
267
- // Text blocks have nothing to fetch — they ride through with no data. The
268
- // header/footer (report.master) is read by the renderers straight off the
269
- // report for the same reason.
270
- // Released a few at a time rather than all at once. mergeMap completes out
271
- // of order, so each result carries the slot it came from and the rows are
272
- // filed by index — the deck's page order can't depend on which query
273
- // happened to finish first.
274
- const all$ = slots.length
275
- ? from(slots.map((slot, index) => ({ slot, index })))
276
- .pipe(mergeMap(({ slot, index }) => this._componentData(report, slot.component, listRows)
277
- .pipe(map((item) => ({ item, index }))), EXPORT_CONCURRENCY), toArray())
342
+ const jobs = this._jobs(report);
343
+ const snapshot = this.snapshot(report);
344
+ const formatContext = snapshot.formatContext;
345
+ // Released a few at a time rather than all at once, a page's values in the
346
+ // same queue as the tiles, so they never add to the queries already
347
+ // running. mergeMap completes out of order, so each result carries the job
348
+ // it came from and the rows are filed by index — the deck's page order
349
+ // can't depend on which query happened to finish first.
350
+ const all$ = jobs.length
351
+ ? from(jobs.map((job, index) => ({ job, index })))
352
+ .pipe(mergeMap(({ job, index }) => this._runJob(report, job, listRows, snapshot)
353
+ .pipe(map((result) => ({ result, index }))), EXPORT_CONCURRENCY), toArray())
278
354
  : of([]);
279
- // The summary rides alongside the component data rather than being built at
355
+ // The lines ride alongside the component data rather than being built at
280
356
  // the end, because naming a select filter's values is itself a request.
281
- return forkJoin({ collected: all$, filterSummary: this.getFilterSummary(report) })
282
- .pipe(map(({ collected, filterSummary }) => {
283
- const pages = report.pages.map((page) => ({ page, components: [] }));
284
- [...collected]
285
- .sort((a, b) => a.index - b.index)
286
- .forEach(({ item, index }) => {
287
- pages[slots[index].pageIndex].components.push(item);
288
- });
357
+ return forkJoin({ collected: all$, lines: this.filterLines(report, snapshot) })
358
+ .pipe(map(({ collected, lines }) => {
359
+ const file = this._file(report, collected, formatContext);
289
360
  return {
290
361
  report,
291
- pages,
292
- filterSummary,
362
+ ...file,
363
+ filterSummary: coverFilterLines(snapshot, lines, file.pages),
293
364
  contextLines: this._contextLines(report),
294
- formatContext: this._filterState.formatContext(),
365
+ formatContext,
295
366
  };
296
367
  }));
297
368
  }
298
- // "Report Period: Jun 12, 2025 – Jun 12, 2026", "Region: North, East" — one
299
- // line per filter group that has an active session value, then the group-by
300
- // line. The filter bar as the viewer reads it: the PDF and PowerPoint covers
301
- // print it, and the report zip export sends it for its notes file. Dates are
302
- // written in the report's locale, so the notes name the period as the cover
303
- // does.
304
- //
305
- // A select group stores ids, so its line has to be named off the option list
306
- // before it can be printed; a date or keyword group already holds its own
307
- // display value and resolves synchronously.
308
- getFilterSummary(report) {
309
- const lines = [];
310
- for (const group of report.filterGroups ?? []) {
311
- const value = this._filterState.value(group.id);
312
- if (!value) {
313
- continue;
314
- }
315
- const label = group.label || 'Filter';
316
- if (value.start || value.end) {
317
- lines.push(of(`${label}: ${this._date(value.start)} – ${this._date(value.end)}`));
318
- }
319
- else if (value.values?.length) {
320
- lines.push(this._selectLine(label, group, report.id, value.values));
321
- }
322
- else if (value.value?.trim()) {
323
- lines.push(of(`${label}: "${value.value.trim()}"`));
324
- }
369
+ // The screen as one export reads it: the view document, each group's value
370
+ // and live preset, each tile's filter entries and state (tileDataState),
371
+ // each value's filter entries, the grain, the features served, the format
372
+ // and the open view's line. A value's entries are read here too, so the
373
+ // numbers in a file's text are filtered as its tiles are, whatever the bar
374
+ // does while the export runs.
375
+ snapshot(report) {
376
+ const view = this._filterState.snapshot();
377
+ const tiles = (report.pages ?? [])
378
+ .flatMap((page) => page.components ?? [])
379
+ .filter((component) => isTile(component));
380
+ const values = reportComponents(report)
381
+ .filter((component) => component.type === 'value');
382
+ return {
383
+ view,
384
+ ...this._groupValues(report),
385
+ filters: Object.fromEntries(tiles.map((tile) => [tile.id, this._filterState.resolveForComponent(tile)])),
386
+ valueFilters: Object.fromEntries(values
387
+ .map((value) => [value.id, this._filterState.resolveForComponent(value)])),
388
+ states: Object.fromEntries(tiles.map((tile) => [tile.id, tileDataState(report, tile, view)])),
389
+ frequency: this._filterState.frequency(),
390
+ features: offeredViewerFeatures(report.viewerFeatures),
391
+ formatContext: this._filterState.formatContext(),
392
+ viewLine: viewLineText(this._views?.openView(), !!this._views?.viewChanged()),
393
+ };
394
+ }
395
+ // The export's filter lines (exportLines) over a snapshot: the cover's, and
396
+ // the zip's filterLines (`pageId` for a This Page zip). A select's picks
397
+ // are named as the report bar names them.
398
+ filterLines(report, snapshot, pageId = null) {
399
+ return exportLines({
400
+ report,
401
+ snapshot,
402
+ pageId,
403
+ names: (group, values) => this._pickNames(group, report.id, values),
404
+ });
405
+ }
406
+ // Every request the export makes, in page order: each page's tiles, then the
407
+ // values its text shows; the header and footer's values last, when some page
408
+ // shows the master. Text blocks have nothing to fetch of their own — they
409
+ // ride through with no data, and their tokens are filled from their layer's
410
+ // values. A value is read only through its layer's request, never as a tile
411
+ // (isExportSlot). The header/footer blocks (report.master) are read by the
412
+ // renderers straight off the report.
413
+ _jobs(report) {
414
+ const jobs = [];
415
+ report.pages.forEach((page, pageIndex) => {
416
+ page.components
417
+ .filter(isExportSlot)
418
+ .forEach((component) => jobs.push({ kind: 'component', pageIndex, component }));
419
+ jobs.push(...this._valuesJobs(page, pageIndex));
420
+ });
421
+ if (report.master && report.pages.some((page) => !page.masterHidden)) {
422
+ jobs.push(...this._valuesJobs(report.master, null));
325
423
  }
326
- // The group-by grain, under the report's own name for the control — a cover
327
- // sheet reading "Frequency" when the report calls it "Period" describes a
328
- // control the reader cannot find on screen.
329
- const granularity = this._filterState.frequency();
330
- if (granularity) {
331
- const option = GRANULARITY_OPTIONS.find((item) => item.value === granularity);
332
- const label = report.config?.groupBy?.label || 'Group By';
333
- lines.push(of(`${label}: ${option?.name ?? granularity}`));
424
+ return jobs;
425
+ }
426
+ // A layer's one values job, or none when its text shows no value.
427
+ _valuesJobs(layer, pageIndex) {
428
+ const texts = layer.components.filter((component) => component.type === 'text');
429
+ const values = layer.values ?? [];
430
+ const shown = shownValues(values, texts);
431
+ return shown.length
432
+ ? [{ kind: 'values', pageIndex, pageId: layer.id, values, components: shown }]
433
+ : [];
434
+ }
435
+ // One queued job, its result tagged with the page it is filed under.
436
+ _runJob(report, job, listRows, snapshot) {
437
+ if (job.kind === 'component') {
438
+ return this._componentData(report, job.component, listRows, snapshot)
439
+ .pipe(map((item) => ({ kind: 'component', pageIndex: job.pageIndex, item })));
334
440
  }
335
- return lines.length ? forkJoin(lines) : of([]);
441
+ return this._pageValues(report, job.pageId, job.values, job.components, snapshot)
442
+ .pipe(map((collected) => ({ kind: 'values', pageIndex: job.pageIndex, collected })));
336
443
  }
337
- _componentData(report, component, listRows) {
444
+ _componentData(report, component, listRows, snapshot) {
338
445
  if (component.type === 'text') {
339
446
  return of({ component, data: null, hiddenColumns: [] });
340
447
  }
341
- const filters = this._filterState.resolveForComponent(component);
342
- // A time-series chart carries the viewer's group-by grain so the export
343
- // re-buckets exactly as the screen does; lists carry their export paging
344
- // and the viewer's header sort and search, so the table reads in the
345
- // screen's order and holds the screen's rows.
346
- //
347
- // The time-series check deliberately mirrors the server's canonical
348
- // ReportQueryRunner::_isTimeSeriesChart, so a product pinned to an older
349
- // framework does not re-bucket a non-time chart.
350
- const frequency = this._filterState.frequency();
351
- const isTimeSeries = component.type === 'chart' && component.config?.xAxis?.kind === 'time';
352
- const search = component.type === 'list'
353
- ? this._filterState.listSearch(component.id) ?? undefined
354
- : undefined;
448
+ const filters = snapshot.filters[component.id] ?? [];
449
+ // The tile's own state, the one its screen and its CSV carry
450
+ // (tileDataState): a time-series chart re-buckets at the viewer's grain
451
+ // and keeps its drill path, a list reads in the screen's order and holds
452
+ // the screen's rows. A list adds its export paging.
453
+ const tileState = snapshot.states[component.id] ?? {};
355
454
  const state = component.type === 'list'
356
- ? { page: 1, pageSize: listRows, sort: this._filterState.listSort(component.id) ?? undefined, search }
357
- : (isTimeSeries && frequency ? { frequency } : {});
455
+ ? { ...tileState, page: 1, pageSize: listRows }
456
+ : { ...tileState };
358
457
  // The table leaves out the columns the viewer hid. The rows are fetched
359
- // whole, as the screen fetches them, and the renderers drop the cells.
360
- const hiddenColumns = [...this._filterState.hiddenColumns(component.id)];
458
+ // whole, as the screen fetches them (the server reads hiddenColumns for a
459
+ // CSV only), and the renderers drop the cells.
460
+ const hiddenColumns = [...(state.hiddenColumns ?? [])];
361
461
  // handlers: false keeps the app's global error dialog out of this. A failed
362
- // tile is reported once, by the export gate, naming the pages it cost —
462
+ // tile is reported once, by the failure gate, naming the pages it cost —
363
463
  // never as ten stacked modals carrying the database's own wording.
364
- //
365
- // A search the server could not apply (searchNote: the list has no text
366
- // column) narrowed nothing, so the item does not carry it.
367
464
  return this._reportData.componentData(report.id, component.id, filters, state, true, { handlers: false })
368
- .pipe(map((data) => (search && !data?.searchNote
369
- ? { component, data, search, hiddenColumns }
370
- : { component, data, hiddenColumns })), catchError(() => of({ component, data: null, hiddenColumns })));
465
+ .pipe(map((data) => this._collected(component, data, state.search, hiddenColumns, snapshot)), catchError(() => of({ component, data: null, hiddenColumns })));
466
+ }
467
+ // One tile's answer as the renderers take it. A search the server could
468
+ // not apply (searchNote: the list has no text column) narrowed nothing, so
469
+ // the item does not carry it. A drilled chart carries the breadcrumb of the
470
+ // path its answer applied, which is what its numbers were read at.
471
+ _collected(component, data, search, hiddenColumns, snapshot) {
472
+ const path = data?.drill?.path ?? [];
473
+ return {
474
+ component,
475
+ data,
476
+ ...(search && !data?.searchNote ? { search } : {}),
477
+ hiddenColumns,
478
+ ...(path.length ? { crumbs: drillCrumbLabels(path, snapshot.formatContext) } : {}),
479
+ };
480
+ }
481
+ // Each group's value as the bar holds it now, with the relative range a
482
+ // date value still is. The picks are copied, so the snapshot keeps them
483
+ // whatever the bar does next.
484
+ _groupValues(report) {
485
+ const values = {};
486
+ const presets = {};
487
+ (report.filterGroups ?? []).forEach((group) => {
488
+ const value = this._filterState.value(group.id);
489
+ const preset = this._filterState.livePreset(group.id);
490
+ if (value) {
491
+ values[group.id] = {
492
+ ...value,
493
+ ...(value.values ? { values: [...value.values] } : {}),
494
+ ...(value.excludeValues ? { excludeValues: [...value.excludeValues] } : {}),
495
+ };
496
+ }
497
+ if (preset) {
498
+ presets[group.id] = preset;
499
+ }
500
+ });
501
+ return { values, presets };
502
+ }
503
+ // One layer's values, read in one request, as its text's tokens print them.
504
+ // The request carries the filter values of every value on the layer, as the
505
+ // canvas's does, read from the export's snapshot like every tile's, and
506
+ // while the groups match 'any' the groups that combine
507
+ // (valuesMatchAnyGroupIds): the server decides which values it reads (the
508
+ // shown ones and the operands of the formulas among them) and applies to
509
+ // each only the entries naming its own filters. handlers: false keeps the
510
+ // error dialog out of it, as for a tile. A failed request reads as no rows,
511
+ // so every value the text shows failed and the failure gate names its page;
512
+ // one value's own error fails only that value, and a failed operand fails
513
+ // the formula that reads it.
514
+ _pageValues(report, pageId, values, shown, snapshot) {
515
+ const formatContext = snapshot.formatContext;
516
+ const filters = values.flatMap((component) => snapshot.valueFilters[component.id] ?? []);
517
+ const matchAnyGroupIds = valuesMatchAnyGroupIds(report, pageId, snapshot.view);
518
+ return this._reportData.pageValues(report.id, pageId, filters, true, { handlers: false }, matchAnyGroupIds)
519
+ .pipe(map((rows) => new Map((rows ?? []).map((row) => [row.id, row]))), catchError(() => of(new Map())), map((rows) => ({
520
+ values: textValues(values, { rows }, formatContext),
521
+ failedValues: failedValueKeys(shown, rows),
522
+ })));
523
+ }
524
+ // The results filed by page in job order. A layer with no values job (its
525
+ // text shows no value) has no numbers to wait for: its values read as the
526
+ // em dash, and none of them failed.
527
+ _file(report, results, formatContext) {
528
+ const unread = (values) => ({
529
+ values: textValues(values ?? [], { rows: new Map() }, formatContext),
530
+ failedValues: [],
531
+ });
532
+ const pages = report.pages.map((page) => ({ page, components: [], ...unread(page.values) }));
533
+ let master = unread(report.master?.values);
534
+ [...results]
535
+ .sort((a, b) => a.index - b.index)
536
+ .forEach(({ result }) => {
537
+ if (result.kind === 'component') {
538
+ pages[result.pageIndex].components.push(result.item);
539
+ }
540
+ else if (result.pageIndex === null) {
541
+ master = result.collected;
542
+ }
543
+ else {
544
+ Object.assign(pages[result.pageIndex], result.collected);
545
+ }
546
+ });
547
+ return { pages, masterValues: master.values, masterFailedValues: master.failedValues };
371
548
  }
372
549
  // The zone the server resolved, as its IANA id, and the currency it says
373
550
  // the report's money is in (a label: nothing is converted). Only the
@@ -380,23 +557,20 @@ export class ReportExportCollectorService {
380
557
  ...(report.effectiveCurrency ? [`Currency: ${report.effectiveCurrency}`] : []),
381
558
  ];
382
559
  }
383
- // One select group's line, with its stored ids resolved to the same names the
384
- // on-screen chips show — a cover reading "Organization: 8774, 8777" tells the
385
- // reader nothing about what the report covers.
560
+ // One select group's picks (kept or left out), its stored ids resolved to
561
+ // the same names the on-screen chips show — a cover reading "Organization:
562
+ // 8774, 8777" tells the reader nothing about what the report covers.
386
563
  //
387
- // Uses the report bar's own loader and resolver so the two can't drift, which
388
- // also means a value whose entity was deleted keeps showing its raw id rather
389
- // than dropping off the cover and silently understating the filter. A failed
390
- // option fetch degrades the whole line to ids for the same reason: an export
391
- // must never fail on a cosmetic lookup.
392
- _selectLine(label, group, reportId, values) {
393
- return resolveOptionValues(loadGroupOptions(group, this._reportData, reportId), values)
394
- .pipe(map((resolved) => `${label}: ${resolved.map((item) => item.name).join(', ')}`), catchError(() => of(`${label}: ${values.map((item) => String(item)).join(', ')}`)));
395
- }
396
- // Rendered off the same calendar day the filter sends to the server, so the
397
- // cover's period is the period the numbers behind it were queried for.
398
- _date(value) {
399
- return dateBoundLabel(value, this._filterState.formatContext().locale) ?? '…';
564
+ // Uses the report bar's own names and resolver so the two can't drift: a
565
+ // name the bar's lists taught (ReportFilterOptionsService.label) comes first,
566
+ // so a pick a cut or narrowed list leaves out reads as its chip does, and
567
+ // the full list names the rest. A value whose entity was deleted keeps
568
+ // showing its raw id rather than dropping off the cover and silently
569
+ // understating the filter. A failed option fetch degrades the whole line to
570
+ // ids for the same reason: an export must never fail on a cosmetic lookup.
571
+ _pickNames(group, reportId, values) {
572
+ return resolveOptionValues(loadGroupOptions(group, this._reportData, reportId), values, (value) => this._filterOptions.label(group.id, value))
573
+ .pipe(map((resolved) => resolved.map((item) => item.name)), catchError(() => of(values.map((item) => String(item)))));
400
574
  }
401
575
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
402
576
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService });
@@ -404,4 +578,4 @@ export class ReportExportCollectorService {
404
578
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService, decorators: [{
405
579
  type: Injectable
406
580
  }] });
407
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9leHBvcnQvcmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQWMsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNqRixPQUFPLEVBQ0wsUUFBUSxFQUNSLGVBQWUsRUFDZixZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YscUJBQXFCLEdBQ3RCLE1BQU0sV0FBVyxDQUFDO0FBQ25CLE9BQU8sRUFHTCxtQkFBbUIsR0FTcEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV4QyxPQUFPLEVBQ0wsZ0JBQWdCLEVBRWhCLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIscUJBQXFCLEdBQ3RCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9GLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHlD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LElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQzlFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEtBQUssTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUNuRixDQUFDO0lBQ04sQ0FBQztJQUVELDRFQUE0RTtJQUM1RSx1RUFBdUU7SUFDL0QsS0FBSyxDQUFDLEtBQXVDO1FBQ25ELE9BQU8sY0FBYyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUNoRixDQUFDO3dHQXRMVSw0QkFBNEI7NEdBQTVCLDRCQUE0Qjs7NEZBQTVCLDRCQUE0QjtrQkFEeEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmb3JrSm9pbiwgZnJvbSwgbWFwLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgbWVyZ2VNYXAsIHRvQXJyYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuLi9kYXRhL3JlcG9ydC5kYXRhJztcbmltcG9ydCB7IFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQgfSBmcm9tICcuLi9lbnVtcy9yZXBvcnQtbGlzdC1jb2x1bW4tZm9ybWF0LmVudW0nO1xuaW1wb3J0IHtcbiAgREFZX0xPTkcsXG4gIGZvcm1hdExvY2FsRGF0ZSxcbiAgZm9ybWF0TnVtYmVyLFxuICBmb3JtYXRPdXRwdXRWYWx1ZSxcbiAgZm9ybWF0UmVwb3J0RGF0ZSxcbiAgaGFzTnVtYmVyRm9ybWF0LFxuICByZXNvbHZlUmVwb3J0VGltZXpvbmUsXG59IGZyb20gJy4uL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBDb21wb25lbnREYXRhLFxuICBDb21wb25lbnREYXRhU3RhdGUsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIExpc3RDb2x1bW4sXG4gIExpc3RDb25maWcsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgUmVwb3J0TG9jYWxlVGFnLFxuICBSZXBvcnRQYWdlLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgS3BpQ2FyZFZpZXcgfSBmcm9tICcuLi9rcGktY2FyZCc7XG5pbXBvcnQge1xuICBMSVNUX1RPVEFMX0xBQkVMLFxuICBMaXN0T3V0cHV0Q29sdW1uLFxuICBsaXN0SGlkZGVuQ29sdW1ucyxcbiAgbGlzdE91dHB1dENvbHVtbnMsXG4gIGxpc3RUb3RhbHNMYWJlbENvbHVtbixcbn0gZnJvbSAnLi4vbGlzdC1jb25maWcnO1xuaW1wb3J0IHsgcGl2b3RDb2x1bW5TcGVjcyB9IGZyb20gJy4uL29wdGlvbi1idWlsZGVyJztcbmltcG9ydCB7IGNvbXBvbmVudE5vdGVMaW5lcywgY29tcG9uZW50V2luZG93c0xpbmUgfSBmcm9tICcuLi9vdXRwdXQtbm90ZXMnO1xuaW1wb3J0IHsgZGF0ZUJvdW5kTGFiZWwsIGxvYWRHcm91cE9wdGlvbnMsIHJlc29sdmVPcHRpb25WYWx1ZXMgfSBmcm9tICcuLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZSc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0ZWRDb21wb25lbnQge1xuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudDtcbiAgLy8gbnVsbCA9IGl0cyBxdWVyeSBmYWlsZWQ7IGV4cG9ydHMgc2hvdyBhIG5vdGUuIEFsd2F5cyBudWxsIGZvciBhIHRleHRcbiAgLy8gYmxvY2ssIHdoaWNoIGhhcyBubyBxdWVyeSDigJQgc2VlIGlzRmFpbGVkKCkuXG4gIGRhdGE6IENvbXBvbmVudERhdGEgfCBudWxsO1xuICAvLyBUaGUgdGV4dCBhIGxpc3Qgd2FzIHNlYXJjaGVkIGJ5IHdoZW4gaXQgd2FzIGZldGNoZWQ7IGFic2VudCB3aGVuIGl0c1xuICAvLyBzZWFyY2ggYm94IHdhcyBlbXB0eSwgYW5kIGZvciBldmVyeSBvdGhlciBjb21wb25lbnQuXG4gIHNlYXJjaD86IHN0cmluZztcbiAgLy8gVGhlIGNvbmZpZyBjb2x1bW5zIGEgdmlld2VyIGhpZCBvbiBhIHBsYWluIGxpc3QsIHdoaWNoIGl0cyB0YWJsZSBsZWF2ZXNcbiAgLy8gb3V0IChsaXN0Q29sdW1ucyk7IGVtcHR5IGZvciBldmVyeSBvdGhlciBjb21wb25lbnQuXG4gIGhpZGRlbkNvbHVtbnM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3RlZFBhZ2Uge1xuICBwYWdlOiBSZXBvcnRQYWdlO1xuICBjb21wb25lbnRzOiBDb2xsZWN0ZWRDb21wb25lbnRbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0ZWRSZXBvcnQge1xuICByZXBvcnQ6IFJlcG9ydDtcbiAgcGFnZXM6IENvbGxlY3RlZFBhZ2VbXTtcbiAgLy8gSHVtYW4tcmVhZGFibGUgbGluZXMgZGVzY3JpYmluZyB0aGUgYWN0aXZlIGZpbHRlcnMsIGZvciB0aGUgdGl0bGUgc2xpZGUvcGFnZS5cbiAgZmlsdGVyU3VtbWFyeTogc3RyaW5nW107XG4gIC8vIFdoYXQgdGhlIG51bWJlcnMgYXJlIG1lYXN1cmVkIGluLCBmb3IgdGhlIHRpdGxlIHNsaWRlL3BhZ2U6IHRoZSB6b25lIGFuZFxuICAvLyB0aGUgY3VycmVuY3kgdGhlIHNlcnZlciByZXNvbHZlZCBmb3IgdGhlIHJlcG9ydC4gRWFjaCBpcyBsZWZ0IG91dCB3aGVuIHRoZVxuICAvLyBzZXJ2ZXIgZG9lcyBub3Qgc2VuZCBpdCwgcmF0aGVyIHRoYW4gYSBndWVzcyB0aGF0IHdvdWxkIGJlIHdyb25nIHdoZW5ldmVyXG4gIC8vIHRoZSBkZWZhdWx0IGFwcGxpZXMuXG4gIGNvbnRleHRMaW5lczogc3RyaW5nW107XG4gIC8vIEhvdyB0aGUgb3BlbiByZXBvcnQgd3JpdGVzIGl0cyBudW1iZXJzIGFuZCBkYXRlcyAoaXRzIGxvY2FsZSwgY3VycmVuY3lcbiAgLy8gYW5kIHBlcmNlbnQgZm9ybSksIHJlYWQgb25jZSBzbyBldmVyeSBwYWdlIG9mIHRoZSBmaWxlIGFncmVlcy5cbiAgZm9ybWF0Q29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dDtcbn1cblxuLy8gT25lIGV4cG9ydGVkIGxpc3QgY29sdW1uOiB0aGUgY2VsbCBrZXksIGl0cyBoZWFkaW5nIGFuZCBpdHMgZm9ybWF0LCBhbmRcbi8vIHdoZXRoZXIgaXRzIGNlbGxzIGFyZSBmb3JtYXR0ZWQgbnVtYmVycywgd2hpY2ggZXZlcnkgZXhwb3J0IHJpZ2h0LWFsaWduc1xuLy8gKGhlYWRlciBpbmNsdWRlZCkgYXMgdGhlIHNjcmVlbiBkb2VzLiBBIGNvbHVtbiB0aGF0IGhvbGRzIGEgY29tcGFyZWQsXG4vLyB3aW5kb3dlZCwgcmFua2VkIG9yIHNoYXJlZCBvdXRwdXQgY2FycmllcyBob3cgaXQgaXMgd3JpdHRlbiAob3V0cHV0KSwgYW5kXG4vLyBob2xkcyBudW1iZXJzIHdoZXRoZXIgb3Igbm90IGl0IG5hbWVzIGEgZm9ybWF0LlxuZXhwb3J0IHR5cGUgRXhwb3J0TGlzdENvbHVtbiA9IExpc3RDb2x1bW4gJiB7IG51bWVyaWM6IGJvb2xlYW47IG91dHB1dD86IExpc3RPdXRwdXRDb2x1bW4gfTtcblxuLy8gSG93IHRhbGwgZWFjaCBwYXJ0IG9mIGFuIGV4cG9ydGVkIEtQSSBjYXJkIGlzLCBpbiB0aGUgcmVuZGVyZXIncyB1bml0XG4vLyAocG9pbnRzIGluIHRoZSBQREYsIGluY2hlcyBpbiB0aGUgZGVjaykuIEEgbm90ZSBpcyBvbmUgbGluZS5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpRXhwb3J0SGVpZ2h0cyB7XG4gIHZhbHVlOiBudW1iZXI7XG4gIGxhYmVsOiBudW1iZXI7XG4gIGRlbHRhOiBudW1iZXI7XG4gIHdpbmRvdzogbnVtYmVyO1xuICB0YXJnZXQ6IG51bWJlcjtcbiAgc3BhcmtsaW5lOiBudW1iZXI7XG4gIG5vdGU6IG51bWJlcjtcbn1cblxuLy8gVGhlIHBhcnRzIG9mIGEgS1BJIGNhcmQgYW4gZXhwb3J0IGRyYXdzOiB0aGUgdmFsdWUgYW5kIGl0cyBsYWJlbCBhbHdheXMsXG4vLyB0aGUgcmVzdCB3aGVuIHRoZSBjYXJkIGhhcyB0aGVtIGFuZCB0aGUgdGlsZSBoYXMgcm9vbSAoa3BpRXhwb3J0UGFydHMpLlxuLy8gc2NhbGUgc2hyaW5rcyB0aGUgcm93cyBhbmQgdGhlaXIgdGV4dCB3aGVuIHRoZSBwYXJ0cyB0aGF0IGFsd2F5cyBzdGF5IHN0aWxsXG4vLyBzdGFuZCB0YWxsZXIgdGhhbiB0aGUgdGlsZSAoc2NhbGVkS3BpSGVpZ2h0cyk6IDEgd2hlbiB0aGV5IGZpdC5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpRXhwb3J0UGFydHMge1xuICBkZWx0YTogYm9vbGVhbjtcbiAgd2luZG93OiBib29sZWFuO1xuICB0YXJnZXQ6IGJvb2xlYW47XG4gIHNwYXJrbGluZTogYm9vbGVhbjtcbiAgbm90ZXM6IHN0cmluZ1tdO1xuICBzY2FsZTogbnVtYmVyO1xufVxuXG4vLyBIb3cgZmFyIGEgS1BJIGNhcmQncyByb3dzIHNocmluayB0byBmaXQgYSBzaG9ydCB0aWxlLiBBIHRpbGUgc2hvcnRlciBzdGlsbFxuLy8gbGV0cyB0aGUgY2FyZCBydW4gcGFzdCBpdHMgZm9vdCByYXRoZXIgdGhhbiBwcmludCBpdCB1bnJlYWRhYmx5IHNtYWxsLlxuY29uc3QgS1BJX0VYUE9SVF9NSU5fU0NBTEUgPSAwLjU7XG5cbi8vIEhvdyBtYW55IHRpbGUgcXVlcmllcyBhbiBleHBvcnQgcnVucyBhdCBvbmNlLlxuLy9cbi8vIE5vdCBhIHBvbGl0ZW5lc3Mgc2V0dGluZyDigJQgaXQgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBhIGRlY2sgYW5kIGEgYnJva2VuXG4vLyBvbmUuIFRoZXNlIHF1ZXJpZXMgYXJlIGhlYXZ5IGFuZCByZWFkIHRoZSBzYW1lIHRhYmxlcywgc28gZmlyaW5nIGFsbCBvZiB0aGVtXG4vLyB0b2dldGhlciBwdXRzIGV2ZXJ5IG9uZSBpbiBjb250ZW50aW9uIGZvciB0aGUgc2FtZSBkYXRhYmFzZSBhdCB0aGUgc2FtZVxuLy8gbW9tZW50IGFuZCB0aGV5IGNyb3NzIHRoZSBzdGF0ZW1lbnQgY2VpbGluZyBhcyBhIGdyb3VwOiBtZWFzdXJlZCBvbiByZXBvcnRcbi8vIDI4LCB0ZW4gdGlsZXMgdGhhdCBlYWNoIGFuc3dlciBpbiA5LTI0cyBydW4gb25lIGFmdGVyIGFub3RoZXIgYWxsIGZhaWxlZCBhdFxuLy8gfjMwcyB3aGVuIHJlbGVhc2VkIHRvZ2V0aGVyLiBDb25jdXJyZW5jeSBidXlzIHdhbGwtY2xvY2sgb25seSB1cCB0byB0aGUgcG9pbnRcbi8vIHdoZXJlIHRoZSBxdWVyaWVzIHN0YXJ0IHRha2luZyBpdCBiYWNrIG9mZiBlYWNoIG90aGVyLCBhbmQgcGFzdCB0aGF0IGl0IGJ1eXNcbi8vIGZhaWx1cmVzLlxuY29uc3QgRVhQT1JUX0NPTkNVUlJFTkNZID0gMztcblxuLy8gV2hhdCBhIGNvbXBvbmVudCB3aXRoIG5vdGhpbmcgdG8gZHJhdyBwcmludHMgaW4gdGhlIGV4cG9ydGVkIGZpbGUuXG4vL1xuLy8gVGhlIHR3byBjYXNlcyBtdXN0IG5vdCByZWFkIGFsaWtlLiBBIHRpbGUgdGhhdCByZXR1cm5lZCBubyByb3dzIGlzIGEgZmluZGluZ1xuLy8gYWJvdXQgdGhlIHBlcmlvZCDigJQgdGhlIHJlcG9ydCB3b3JrZWQgYW5kIHRoZSBhbnN3ZXIgaXMgXCJub25lXCIuIEEgdGlsZSB3aG9zZVxuLy8gcXVlcnkgZmFpbGVkIGlzIGEgaG9sZSBpbiB0aGUgZmlsZSwgYW5kIGNhbGxpbmcgdGhhdCBcIkRhdGEgdW5hdmFpbGFibGVcIiB0ZWxsc1xuLy8gdGhlIHJlYWRlciB0aGUgZGF0YSBkb2VzIG5vdCBleGlzdCB3aGVuIHdoYXQgaGFwcGVuZWQgaXMgdGhhdCBub2JvZHkgbWFuYWdlZFxuLy8gdG8gYXNrIGZvciBpdC4gU2hhcmVkIGJ5IGJvdGggcmVuZGVyZXJzIHNvIHRoZSBQREYgYW5kIHRoZSBkZWNrIGNhbm5vdCBlbmQgdXBcbi8vIGRlc2NyaWJpbmcgdGhlIHNhbWUgaG9sZSB0d28gZGlmZmVyZW50IHdheXMuXG5leHBvcnQgZnVuY3Rpb24gZW1wdHlMYWJlbChpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQpOiBzdHJpbmcge1xuICByZXR1cm4gaXRlbS5kYXRhID8gJ05vIGRhdGEnIDogJ0NvdWxkIG5vdCBiZSBnZW5lcmF0ZWQnO1xufVxuXG4vLyBBIGNvbXBvbmVudCdzIHRpdGxlIGFzIGFuIGV4cG9ydGVkIGZpbGUgcHJpbnRzIGl0LiBBIHNlYXJjaGVkIGxpc3Qgc2F5cyBzbyxcbi8vIHNpbmNlIGl0cyB0YWJsZSBob2xkcyBvbmx5IHRoZSBtYXRjaGluZyByb3dzOiAnT3JkZXJzIChtYXRjaGluZyBcIm5vcnRoXCIpJy5cbi8vIEFuIHVudGl0bGVkIG9uZSByZWFkcyAnTWF0Y2hpbmcgXCJub3J0aFwiJy4gJycgd2hlbiB0aGVyZSBpcyBub3RoaW5nIHRvIHByaW50LlxuLy8gU2hhcmVkIGJ5IHRoZSBQREYgYW5kIHRoZSBkZWNrLCBjb250aW51YXRpb24gcGFnZXMgaW5jbHVkZWQuXG5leHBvcnQgZnVuY3Rpb24gZXhwb3J0VGl0bGUoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHNlYXJjaD86IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xuICBjb25zdCB0aXRsZSA9IGNvbXBvbmVudC50aXRsZSA/PyAnJztcblxuICBpZiAoIXNlYXJjaCkge1xuICAgIHJldHVybiB0aXRsZTtcbiAgfVxuXG4gIHJldHVybiB0aXRsZSA/IGAke3RpdGxlfSAobWF0Y2hpbmcgXCIke3NlYXJjaH1cIilgIDogYE1hdGNoaW5nIFwiJHtzZWFyY2h9XCJgO1xufVxuXG4vLyBXaGV0aGVyIGEgdGlsZSdzIHF1ZXJ5IGZhaWxlZC4gQSB0ZXh0IGJsb2NrIGhhcyBubyBxdWVyeSwgc28gaXQgbmV2ZXIgZGlkLlxuZXhwb3J0IGZ1bmN0aW9uIGlzRmFpbGVkKGl0ZW06IENvbGxlY3RlZENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gIWl0ZW0uZGF0YSAmJiBpdGVtLmNvbXBvbmVudC50eXBlICE9PSAndGV4dCc7XG59XG5cbi8vIFRoZSBsaW5lcyB1bmRlciB0aGUgcmVwb3J0J3MgbmFtZSBvbiB0aGUgUERGIHRpdGxlIHBhZ2UgYW5kIHRoZSB0aXRsZSBzbGlkZTpcbi8vIHRoZSBleHBvcnQgZGF0ZSwgdGhlIGFjdGl2ZSBmaWx0ZXJzLCB0aGVuIHdoYXQgdGhlIG51bWJlcnMgYXJlIG1lYXN1cmVkIGluLlxuLy8gVGhlIGRhdGUgYWx3YXlzIGxlYWRzICh0aGUgUG93ZXJQb2ludCBtYXJrcyB0aGF0IGxpbmUgYXMgd3JpdHRlbiBpbiB0aGVcbi8vIHJlcG9ydCdzIGxvY2FsZSkuIEl0IGlzIHRvZGF5IGluIHRoZSByZXBvcnQncyB6b25lLCB0aGUgc2FtZSBkYXkgaXRzIGZpbHRlcnNcbi8vIHJlc29sdmUgXCJ0b2RheVwiIHRvLCB3cml0dGVuIGluIHRoZSByZXBvcnQncyBsb2NhbGUuXG5leHBvcnQgZnVuY3Rpb24gY292ZXJMaW5lcyhjb2xsZWN0ZWQ6IENvbGxlY3RlZFJlcG9ydCk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIFtcbiAgICBmb3JtYXRMb2NhbERhdGUoXG4gICAgICBuZXcgRGF0ZSgpLFxuICAgICAgY29sbGVjdGVkLmZvcm1hdENvbnRleHQubG9jYWxlLFxuICAgICAgREFZX0xPTkcsXG4gICAgICByZXNvbHZlUmVwb3J0VGltZXpvbmUoY29sbGVjdGVkLnJlcG9ydCksXG4gICAgKSxcbiAgICAuLi5jb2xsZWN0ZWQuZmlsdGVyU3VtbWFyeSxcbiAgICAuLi5jb2xsZWN0ZWQuY29udGV4dExpbmVzLFxuICBdO1xufVxuXG4vLyBBbiBleHBvcnRlZCBsaXN0IGNlbGwsIHJlYWRpbmcgbGlrZSB0aGUgb24tc2NyZWVuIGNlbGwsIHRocm91Z2ggdGhlIHNhbWVcbi8vIGZ1bmN0aW9ucyBhcyB0aGUgc2NyZWVuOiBhIGRhdGUgY29sdW1uIHJlbmRlcnMgaW4gdGhlIHJlcG9ydCdzIHpvbmUgYW5kXG4vLyBsb2NhbGUsIGFuZCBhIGNvbHVtbiB3aXRoIG51bWJlci1mb3JtYXQga2V5cyAoYSBjcm9zcy10YWIncyBjZWxscyB0aHJvdWdoXG4vLyBpdHMgY2VsbEZvcm1hdCkgaW4gdGhlIHJlcG9ydCdzIGxvY2FsZSBhbmQgY3VycmVuY3kuIEFueSBvdGhlciB2YWx1ZSBnb2VzXG4vLyBvdXQgdmVyYmF0aW0sIGFuZCBhbiBlbXB0eSBvbmUgYXMgJycuIENTViBuZXZlciBjb21lcyB0aHJvdWdoIGhlcmU6IGl0c1xuLy8gdmFsdWVzIHN0YXkgcmF3LlxuLy9cbi8vIEFuIG91dHB1dCBjb2x1bW4gaXMgd3JpdHRlbiBieSB3aGF0IGl0IGhvbGRzLCBhcyB0aGUgc2NyZWVuJ3MgY2VsbCBpc1xuLy8gKGZvcm1hdE91dHB1dFZhbHVlKTogYSBzaWduZWQgY2hhbmdlLCBhIHBlcmNlbnQgY2hhbmdlLCBhIGNoYW5nZSBvZiBhIHJhdGVcbi8vIGluIHBvaW50cywgYSByYW5rLCBhIHNoYXJlLiBJdHMgcm93IGdpdmVzIGEgY2hhbmdlIHRoZSBwcmlvciBiZXNpZGUgaXQsIHNvXG4vLyBhIG1pc3NpbmcgYmFzZWxpbmUgKCfigJQnKSByZWFkcyBhcGFydCBmcm9tIGEgemVybyBvbmUgKCduL2EnKS5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRDZWxsKFxuICB2YWx1ZTogdW5rbm93bixcbiAgY29sdW1uOiBMaXN0Q29sdW1uICYgeyBvdXRwdXQ/OiBMaXN0T3V0cHV0Q29sdW1uIH0sXG4gIHRpbWV6b25lOiBzdHJpbmcsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4gIHJvdz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IG91dHB1dCA9IGNvbHVtbi5vdXRwdXQ7XG5cbiAgaWYgKG91dHB1dCkge1xuICAgIHJldHVybiBmb3JtYXRPdXRwdXRWYWx1ZSh2YWx1ZSwgb3V0cHV0Lm91dHB1dCwgY29sdW1uLCBjb250ZXh0LCB7XG4gICAgICBtZWFzdXJlU3BlYzogb3V0cHV0Lm1lYXN1cmVTcGVjLFxuICAgICAgcHJpb3I6IG91dHB1dC5wcmlvckFsaWFzICYmIHJvdyA/IHJvd1tvdXRwdXQucHJpb3JBbGlhc10gOiB1bmRlZmluZWQsXG4gICAgICBmbG9vcjogb3V0cHV0LmZsb29yLFxuICAgICAgZW1wdHk6ICcnLFxuICAgIH0pLnRleHQ7XG4gIH1cblxuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmIChjb2x1bW4uZm9ybWF0ID09PSBSZXBvcnRMaXN0Q29sdW1uRm9ybWF0LkRhdGUpIHtcbiAgICByZXR1cm4gZm9ybWF0UmVwb3J0RGF0ZSh2YWx1ZSwgdGltZXpvbmUsIGNvbnRleHQubG9jYWxlKTtcbiAgfVxuXG4gIHJldHVybiBoYXNOdW1iZXJGb3JtYXQoY29sdW1uKSA/IGZvcm1hdE51bWJlcih2YWx1ZSwgY29sdW1uLCBjb250ZXh0LCB7IGVtcHR5OiAnJyB9KSA6IFN0cmluZyh2YWx1ZSk7XG59XG5cbi8vIFRoZSBjb2x1bW5zIGFuIGV4cG9ydGVkIGxpc3QgdGFibGUgZHJhd3MuIEEgY3Jvc3MtdGFiJ3MgYXJyaXZlIHdpdGggaXRzXG4vLyByb3dzICh0aGUgcm93IGtleSBmaXJzdCwgdGhlbiBvbmUgcGVyIHBpdm90IHZhbHVlKSwgc2luY2Ugb25seSB0aGUgcmVzdWx0XG4vLyBrbm93cyB0aGUgcGl2b3QgdmFsdWVzLCBhbmQgYXJlIGJ1aWx0IGJ5IHBpdm90Q29sdW1uU3BlY3MoKSBhcyBvbiBzY3JlZW46XG4vLyBoZWFkZWQgYnkgaXRzIHBlcmlvZHMgaW4gdGhlIHJlcG9ydCdzIGxvY2FsZSwgZWFjaCBwaXZvdCB2YWx1ZSBmb3JtYXR0ZWQgYnlcbi8vIGNlbGxGb3JtYXQuIEEgcGxhaW4gbGlzdCBkcmF3cyBpdHMgY29uZmlndXJlZCBjb2x1bW5zIGJ1dCB0aGUgb25lcyB0aGVcbi8vIHZpZXdlciBoaWQgKGBoaWRkZW5gLCBrZXB0IHRvIGxpc3RIaWRkZW5Db2x1bW5zLCBzbyBuZXZlciBhbGwgb2YgdGhlbSksXG4vLyBlbHNlIGV2ZXJ5IGNvbHVtbiB0aGUgcXVlcnkgcmV0dXJuZWQsIGFzIGl0IGNhbWUuIE91dHB1dCBjb2x1bW5zICh0aGVcbi8vIGRhdGEncyBvdXRwdXRzLCBhIGNyb3NzLXRhYiBjZWxsIHRocm91Z2ggY2VsbE1lYXN1cmVzKSBjYXJyeSBob3cgdGhleSBhcmVcbi8vIHdyaXR0ZW47IHdpdGhvdXQgdGhvc2Uga2V5cyB0aGUgY29sdW1ucyBhcmUgZXhhY3RseSBhcyBiZWZvcmUuXG5leHBvcnQgZnVuY3Rpb24gbGlzdENvbHVtbnMoXG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgaGlkZGVuOiByZWFkb25seSBzdHJpbmdbXSA9IFtdLFxuKTogRXhwb3J0TGlzdENvbHVtbltdIHtcbiAgY29uc3QgY29uZmlnID0gKGNvbXBvbmVudC5jb25maWcgPz8ge30pIGFzIExpc3RDb25maWc7XG5cbiAgaWYgKGNvbmZpZy5waXZvdEJ5Py5jb2x1bW4pIHtcbiAgICByZXR1cm4gd2l0aE91dHB1dENvbHVtbnMocGl2b3RDb2x1bW5TcGVjcyhjb25maWcsIGRhdGEsIGxvY2FsZSksIGRhdGEsIFtdKTtcbiAgfVxuXG4gIGlmIChjb25maWcuY29sdW1ucz8ubGVuZ3RoKSB7XG4gICAgY29uc3QgaGlkZGVuTmFtZXMgPSBsaXN0SGlkZGVuQ29sdW1ucyhjb25maWcsIGhpZGRlbik7XG5cbiAgICByZXR1cm4gd2l0aE91dHB1dENvbHVtbnMoXG4gICAgICBjb25maWcuY29sdW1uc1xuICAgICAgICAuZmlsdGVyKChjb2x1bW4pID0+ICFoaWRkZW5OYW1lcy5pbmNsdWRlcyhjb2x1bW4uY29sdW1uKSlcbiAgICAgICAgLm1hcCgoY29sdW1uKSA9PiAoeyAuLi5jb2x1bW4sIG51bWVyaWM6IGhhc051bWJlckZvcm1hdChjb2x1bW4pIH0pKSxcbiAgICAgIGRhdGEsXG4gICAgICBjb25maWcuY29sdW1ucyxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHdpdGhPdXRwdXRDb2x1bW5zKGRhdGEuY29sdW1ucy5tYXAoKGNvbHVtbikgPT4gKHsgY29sdW1uLCBudW1lcmljOiBmYWxzZSB9KSksIGRhdGEsIFtdKTtcbn1cblxuLy8gVGhlIGNvbHVtbnMgd2l0aCB0aGVpciBvdXRwdXQgbWV0YWRhdGEgYXR0YWNoZWQgKGxpc3RPdXRwdXRDb2x1bW5zLCBhcyB0aGVcbi8vIHNjcmVlbidzIGxpc3QgcmVzb2x2ZXMgaXQpOiBhbiBvdXRwdXQgY29sdW1uIGhvbGRzIG51bWJlcnMgYW5kIGlzIHdyaXR0ZW5cbi8vIGJ5IHdoYXQgaXQgaG9sZHMuIFVuY2hhbmdlZCB3aGVuIHRoZSBkYXRhIGhhcyBubyBvdXRwdXRzLlxuZnVuY3Rpb24gd2l0aE91dHB1dENvbHVtbnMoXG4gIGNvbHVtbnM6IEV4cG9ydExpc3RDb2x1bW5bXSxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgYXV0aG9yZWQ6IHJlYWRvbmx5IExpc3RDb2x1bW5bXSxcbik6IEV4cG9ydExpc3RDb2x1bW5bXSB7XG4gIGlmICghZGF0YS5vdXRwdXRzKSB7XG4gICAgcmV0dXJuIGNvbHVtbnM7XG4gIH1cblxuICBjb25zdCBvdXRwdXRzID0gbGlzdE91dHB1dENvbHVtbnMoY29sdW1ucywgZGF0YSwgYXV0aG9yZWQpO1xuXG4gIHJldHVybiBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiAob3V0cHV0c1tjb2x1bW4uY29sdW1uXVxuICAgID8geyAuLi5jb2x1bW4sIG51bWVyaWM6IHRydWUsIG91dHB1dDogb3V0cHV0c1tjb2x1bW4uY29sdW1uXSB9XG4gICAgOiBjb2x1bW4pKTtcbn1cblxuLy8gVGhlIGhlYWRpbmcgb3ZlciBlYWNoIGNvbHVtbiBvZiBsaXN0Q29sdW1ucygpOiBhIHBsYWluIGxpc3QncyBjb25maWd1cmVkXG4vLyBsYWJlbCwgZWxzZSBpdHMgY29sdW1uOyBhIGNyb3NzLXRhYidzIGhlYWRpbmcgZnJvbSBwaXZvdENvbHVtblNwZWNzKCkuXG5leHBvcnQgZnVuY3Rpb24gbGlzdEhlYWRpbmdzKFxuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4gIGhpZGRlbjogcmVhZG9ubHkgc3RyaW5nW10gPSBbXSxcbik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGxpc3RDb2x1bW5zKGNvbXBvbmVudCwgZGF0YSwgbG9jYWxlLCBoaWRkZW4pLm1hcCgoY29sdW1uKSA9PiBjb2x1bW4ubGFiZWwgfHwgY29sdW1uLmNvbHVtbik7XG59XG5cbi8vIEFuIGV4cG9ydGVkIGxpc3QncyB0b3RhbHMgcm93LCBvbmUgY2VsbCBwZXIgY29sdW1uIG9mIGxpc3RDb2x1bW5zKCk6IGVhY2hcbi8vIHRvdGFsIHdyaXR0ZW4gbGlrZSBpdHMgY29sdW1uJ3MgY2VsbHMsIGFuZCBMSVNUX1RPVEFMX0xBQkVMIGluIHRoZSBmaXJzdFxuLy8gY29sdW1uIHdoZW4gdGhhdCBjb2x1bW4gaG9sZHMgbm8gdG90YWwgKGEgY3Jvc3MtdGFiJ3Mgcm93IGtleSkuIG51bGwgd2hlblxuLy8gdGhlIGxpc3QgaGFzIG5vIHRvdGFscy4gVGhlIENTViBuZXZlciBjYXJyaWVzIG9uZTogaXRzIHJvd3Mgc3RheSByYXcuXG5leHBvcnQgZnVuY3Rpb24gbGlzdFRvdGFsc1JvdyhcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgY29sdW1uczogcmVhZG9ubHkgRXhwb3J0TGlzdENvbHVtbltdLFxuICB0aW1lem9uZTogc3RyaW5nLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogc3RyaW5nW10gfCBudWxsIHtcbiAgY29uc3QgdG90YWxzID0gZGF0YS50b3RhbHM7XG5cbiAgaWYgKCF0b3RhbHMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGxhYmVsID0gbGlzdFRvdGFsc0xhYmVsQ29sdW1uKGNvbHVtbnMsIHRvdGFscyk7XG5cbiAgcmV0dXJuIGNvbHVtbnMubWFwKChjb2x1bW4pID0+IChjb2x1bW4uY29sdW1uID09PSBsYWJlbFxuICAgID8gTElTVF9UT1RBTF9MQUJFTFxuICAgIDogZXhwb3J0Q2VsbCh0b3RhbHNbY29sdW1uLmNvbHVtbl0sIGNvbHVtbiwgdGltZXpvbmUsIGNvbnRleHQsIHRvdGFscykpKTtcbn1cblxuLy8gVGhlIHN1YnRpdGxlIHVuZGVyIGEgY2hhcnQncyBvciBhIGxpc3QncyB0aXRsZTogdGhlIGRheXMgaXQgcmVhZHMsIGFuZCB0aGVcbi8vIGRheXMgZWFjaCBjb21wYXJpc29uIGxhbmUgcmVhZHMgKCdTZXAgMSDigJMgMTUsIDIwMjYgwrcgdnMgcHJldmlvdXMgbW9udGg6XG4vLyBBdWcgMSDigJMgMTUsIDIwMjYnKSwgYXMgdGhlIHNjcmVlbidzIG5vdGUgb3BlbnMgd2l0aC4gJycgd2l0aG91dCBhXG4vLyBjb21wYXJpc29uIG9yIGEgdGltZWZyYW1lLCBhbmQgZm9yIGEgS1BJLCB3aG9zZSBjYXJkIHByaW50cyBpdHMgb3duIHdpbmRvd1xuLy8gbGluZS5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRXaW5kb3dzTGluZShpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQsIHRpbWV6b25lOiBzdHJpbmcsIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnKTogc3RyaW5nIHtcbiAgaWYgKCFpdGVtLmRhdGEgfHwgaXRlbS5jb21wb25lbnQudHlwZSA9PT0gJ2twaScpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICByZXR1cm4gY29tcG9uZW50V2luZG93c0xpbmUoaXRlbS5kYXRhLCB7IGxvY2FsZSwgdGltZXpvbmUgfSk7XG59XG5cbi8vIFRoZSBub3RlIGxpbmVzIHVuZGVyIGEgY29tcG9uZW50J3MgYm94OiB3aHkgYSBjb21wYXJpc29uIHJlYWRzIGFzIGl0IGRvZXMsXG4vLyBhIEtQSSdzIGRlbHRhIG5vdGUsIGFuZCB3aGF0IGVhY2ggd2luZG93ZWQgdmFsdWUgaXMgYW5kIHdoeS4gVGhlIGRheXMgYXJlXG4vLyBsZWZ0IG91dCAodGhlIHN1YnRpdGxlIG9yIHRoZSBLUEkgY2FyZCBwcmludHMgdGhlbSksIGFuZCB0aGUgd2luZG93XG4vLyBkZXNjcmlwdGlvbnMgYXJlIGluLCBzaW5jZSBhIGZpbGUgaGFzIG5vIHRvb2x0aXAgb3IgaGVhZGVyIHRvIGNhcnJ5IHRoZW0uXG4vLyBFbXB0eSB3aGVuIHRoZSBkYXRhIGhhcyBub25lIG9mIHRoZSBrZXlzLlxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydE5vdGVMaW5lcyhpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQsIHRpbWV6b25lOiBzdHJpbmcsIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnKTogc3RyaW5nW10ge1xuICByZXR1cm4gY29tcG9uZW50Tm90ZUxpbmVzKGl0ZW0uZGF0YSwgeyBsb2NhbGUsIHRpbWV6b25lIH0sIHsgd2luZG93czogZmFsc2UsIHdpbmRvd0Rlc2NyaXB0aW9uczogdHJ1ZSB9KTtcbn1cblxuLy8gV2hldGhlciBhIEtQSSBjYXJkIGhhcyBtb3JlIHRvIGRyYXcgdGhhbiBpdHMgdmFsdWUgYW5kIGxhYmVsLiBXaXRob3V0LCBib3RoXG4vLyBleHBvcnRzIGRyYXcgdGhlIHRpbGUgZXhhY3RseSBhcyB0aGV5IGFsd2F5cyBoYXZlLlxuZXhwb3J0IGZ1bmN0aW9uIGtwaUNhcmRIYXNFeHRyYXModmlldzogS3BpQ2FyZFZpZXcsIG5vdGVzOiByZWFkb25seSBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gISEodmlldy5kZWx0YSB8fCB2aWV3LndpbmRvdyB8fCB2aWV3LnRhcmdldCB8fCB2aWV3LnNwYXJrbGluZSB8fCBub3Rlcy5sZW5ndGgpO1xufVxuXG4vLyBXaGljaCBwYXJ0cyBvZiBhIEtQSSBjYXJkIGZpdCBhIHRpbGUgYGF2YWlsYWJsZWAgdGFsbC4gQSBzaG9ydCB0aWxlIHNoZWRzIHRoZVxuLy8gc3BhcmtsaW5lIGZpcnN0LCB0aGVuIHRoZSB0YXJnZXQgbGluZSwgdGhlbiB0aGUgbm90ZXM7IHRoZSB2YWx1ZSwgaXRzIGxhYmVsXG4vLyBhbmQgdGhlIGRlbHRhIHJvdyBhbHdheXMgc3RheSwgYW5kIHRoZSB3aW5kb3cgbGluZSBzdGF5cyB3aGVuZXZlciB0aGUgY2FyZFxuLy8gc2hvd3MgYSBjb21wYXJpc29uIChpdHMgZGF5cyBhcmUgd2hhdCB0aGUgZGVsdGEgaXMgbWVhc3VyZWQgb3ZlcikuIFRoZVxuLy8gc3BhcmtsaW5lIG5lZWRzIHZhbHVlcyB0byBkcmF3LiBXaGVuIHdoYXQgc3RheXMgaXMgc3RpbGwgdG9vIHRhbGwsIGV2ZXJ5XG4vLyByb3cgc2hyaW5rcyBieSB0aGUgc2FtZSBzY2FsZSwgZG93biB0byBLUElfRVhQT1JUX01JTl9TQ0FMRTsgYnkgdGhlbiB0aGVcbi8vIHNwYXJrbGluZSwgdGhlIHRhcmdldCBhbmQgdGhlIG5vdGVzIGFyZSBnb25lLlxuZXhwb3J0IGZ1bmN0aW9uIGtwaUV4cG9ydFBhcnRzKFxuICB2aWV3OiBLcGlDYXJkVmlldyxcbiAgbm90ZXM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBhdmFpbGFibGU6IG51bWJlcixcbiAgaGVpZ2h0czogS3BpRXhwb3J0SGVpZ2h0cyxcbik6IEtwaUV4cG9ydFBhcnRzIHtcbiAgY29uc3QgcGFydHM6IEtwaUV4cG9ydFBhcnRzID0ge1xuICAgIGRlbHRhOiAhIXZpZXcuZGVsdGEsXG4gICAgd2luZG93OiAhIXZpZXcud2luZG93LFxuICAgIHRhcmdldDogISF2aWV3LnRhcmdldCxcbiAgICBzcGFya2xpbmU6ICEhdmlldy5zcGFya2xpbmU/LnZhbHVlcy5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgIT09IG51bGwpLFxuICAgIG5vdGVzOiBbLi4ubm90ZXNdLFxuICAgIHNjYWxlOiAxLFxuICB9O1xuICBjb25zdCBoZWlnaHQgPSAoKSA9PiBrcGlFeHBvcnRIZWlnaHQodmlldywgcGFydHMsIGhlaWdodHMpO1xuXG4gIGlmIChoZWlnaHQoKSA+IGF2YWlsYWJsZSkge1xuICAgIHBhcnRzLnNwYXJrbGluZSA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGhlaWdodCgpID4gYXZhaWxhYmxlKSB7XG4gICAgcGFydHMudGFyZ2V0ID0gZmFsc2U7XG4gIH1cblxuICB3aGlsZSAoaGVpZ2h0KCkgPiBhdmFpbGFibGUgJiYgcGFydHMubm90ZXMubGVuZ3RoKSB7XG4gICAgcGFydHMubm90ZXMucG9wKCk7XG4gIH1cblxuICBpZiAoaGVpZ2h0KCkgPiBhdmFpbGFibGUgJiYgIXBhcnRzLmRlbHRhKSB7XG4gICAgcGFydHMud2luZG93ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaGVpZ2h0KCkgPiBhdmFpbGFibGUpIHtcbiAgICBwYXJ0cy5zY2FsZSA9IE1hdGgubWF4KEtQSV9FWFBPUlRfTUlOX1NDQUxFLCBNYXRoLm1heCgwLCBhdmFpbGFibGUpIC8gaGVpZ2h0KCkpO1xuICB9XG5cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG4vLyBUaGUgaGVpZ2h0cyBzY2FsZWQgYnkgdGhlIHBhcnRzJyBzY2FsZTogd2hhdCB0aGUgcmVuZGVyZXIgbGF5cyB0aGUgY2FyZFxuLy8gb3V0IHdpdGgsIGl0cyB0ZXh0IHNpemVkIGJ5IHRoZSBzYW1lIHNjYWxlLlxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlZEtwaUhlaWdodHMoaGVpZ2h0czogS3BpRXhwb3J0SGVpZ2h0cywgc2NhbGU6IG51bWJlcik6IEtwaUV4cG9ydEhlaWdodHMge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiBoZWlnaHRzLnZhbHVlICogc2NhbGUsXG4gICAgbGFiZWw6IGhlaWdodHMubGFiZWwgKiBzY2FsZSxcbiAgICBkZWx0YTogaGVpZ2h0cy5kZWx0YSAqIHNjYWxlLFxuICAgIHdpbmRvdzogaGVpZ2h0cy53aW5kb3cgKiBzY2FsZSxcbiAgICB0YXJnZXQ6IGhlaWdodHMudGFyZ2V0ICogc2NhbGUsXG4gICAgc3BhcmtsaW5lOiBoZWlnaHRzLnNwYXJrbGluZSAqIHNjYWxlLFxuICAgIG5vdGU6IGhlaWdodHMubm90ZSAqIHNjYWxlLFxuICB9O1xufVxuXG4vLyBIb3cgdGFsbCB0aGUgY2FyZCdzIGRyYXduIHBhcnRzIHN0YW5kIHRvZ2V0aGVyLCBpbiB0aGUgaGVpZ2h0cycgdW5pdC5cbmV4cG9ydCBmdW5jdGlvbiBrcGlFeHBvcnRIZWlnaHQodmlldzogS3BpQ2FyZFZpZXcsIHBhcnRzOiBLcGlFeHBvcnRQYXJ0cywgaGVpZ2h0czogS3BpRXhwb3J0SGVpZ2h0cyk6IG51bWJlciB7XG4gIHJldHVybiBoZWlnaHRzLnZhbHVlXG4gICAgKyAodmlldy5sYWJlbCA/IGhlaWdodHMubGFiZWwgOiAwKVxuICAgICsgKHBhcnRzLmRlbHRhID8gaGVpZ2h0cy5kZWx0YSA6IDApXG4gICAgKyAocGFydHMud2luZG93ID8gaGVpZ2h0cy53aW5kb3cgOiAwKVxuICAgICsgKHBhcnRzLnRhcmdldCA/IGhlaWdodHMudGFyZ2V0IDogMClcbiAgICArIChwYXJ0cy5zcGFya2xpbmUgPyBoZWlnaHRzLnNwYXJrbGluZSA6IDApXG4gICAgKyBwYXJ0cy5ub3Rlcy5sZW5ndGggKiBoZWlnaHRzLm5vdGU7XG59XG5cbi8vIFRoZSBsYXN0IHJvdyBvZiBhbiBleHBvcnRlZCBsaXN0IHRhYmxlIHRoYXQgc3RvcHMgc2hvcnQgb2YgaXRzIHJlc3VsdDogaG93XG4vLyBtYW55IHJvd3MgdGhlIGZpbGUgbGVhdmVzIG91dCBhbmQgd2hlcmUgdGhlIHdob2xlIHNldCBjYW4gYmUgaGFkLiBFYWNoXG4vLyBmb3JtYXQgZmV0Y2hlcyBpdHMgb3duIG51bWJlciBvZiByb3dzIChQREZfTElTVF9ST1dTLCBQUFRYX0xJU1RfUk9XUyksIGFuZFxuLy8gYm90aCBuYW1lIHdoYXQgaXMgbGVmdCB3aXRoIHRoaXMgb25lIHNlbnRlbmNlLlxuZXhwb3J0IGZ1bmN0aW9uIG1vcmVSb3dzTm90aWNlKHJlbWFpbmluZzogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGDigKYgJHtyZW1haW5pbmd9IG1vcmUgcm93KHMpIOKAlCB1c2UgdGhlIGNvbXBvbmVudCdzIENTViBleHBvcnQgZm9yIHRoZSBmdWxsIGRhdGFzZXRgO1xufVxuXG4vLyBUaGUgcGFnZXMgb2YgYSBjb2xsZWN0ZWQgcmVwb3J0IHRoYXQgaGF2ZSBhdCBsZWFzdCBvbmUgdGlsZSB3aG9zZSBxdWVyeVxuLy8gZmFpbGVkIOKAlCB3aGF0IHRoZSBleHBvcnQgZ2F0ZSBuYW1lcyB0byB0aGUgdXNlciwgYW5kIHdoYXQgbWFrZXMgXCJzb21lIG9mIHRoaXNcbi8vIGZpbGUgaXMgbWlzc2luZ1wiIGEgZmFjdCB0aGUgY2FsbGVyIGNhbiBhY3Qgb24gcmF0aGVyIHRoYW4gYSB0aGluZyB0aGV5IG5vdGljZVxuLy8gaW4gdGhlIFBERiBhZnRlcndhcmRzLlxuZXhwb3J0IGZ1bmN0aW9uIGZhaWxlZFBhZ2VOYW1lcyhjb2xsZWN0ZWQ6IENvbGxlY3RlZFJlcG9ydCk6IHN0cmluZ1tdIHtcbiAgLy8gTnVtYmVyZWQgYmVmb3JlIHRoZSBmaWx0ZXIg4oCUIGFuIHVubmFtZWQgcGFnZSA0IHRoYXQgZmFpbGVkIGhhcyB0byByZWFkXG4gIC8vIFwiUGFnZSA0XCIsIG5vdCBcIlBhZ2UgMVwiIGJlY2F1c2UgaXQgaGFwcGVuZWQgdG8gYmUgdGhlIGZpcnN0IGZhaWx1cmUuXG4gIHJldHVybiBjb2xsZWN0ZWQucGFnZXNcbiAgICAubWFwKChwYWdlLCBpbmRleCkgPT4gKHsgcGFnZSwgbnVtYmVyOiBpbmRleCArIDEgfSkpXG4gICAgLmZpbHRlcigoeyBwYWdlIH0pID0+IHBhZ2UuY29tcG9uZW50cy5zb21lKGlzRmFpbGVkKSlcbiAgICAubWFwKCh7IHBhZ2UsIG51bWJlciB9KSA9PiBwYWdlLnBhZ2UubmFtZSB8fCBgUGFnZSAke251bWJlcn1gKTtcbn1cblxuLy8gR2F0aGVycyBldmVyeXRoaW5nIGFuIGV4cG9ydCBuZWVkczogZXZlcnkgY29tcG9uZW50J3MgZGF0YSBhY3Jvc3MgQUxMIHBhZ2VzXG4vLyAodGhlIGNhbnZhcyBvbmx5IHJlbmRlcnMgdGhlIGFjdGl2ZSBwYWdlLCBzbyBleHBvcnRzIGNhbid0IHNjcmFwZSB0aGVcbi8vIHNjcmVlbiksIGZldGNoZWQgZnJlc2ggd2l0aCB0aGUgdmlld2VyJ3MgY3VycmVudCBmaWx0ZXIgc3RhdGUuXG4vL1xuLy8gQSBmYWlsZWQgY29tcG9uZW50IHJlc29sdmVzIHRvIGEgbnVsbCBgZGF0YWAgcmF0aGVyIHRoYW4gZmFpbGluZyB0aGUgd2hvbGVcbi8vIGNvbGxlY3Rpb24g4oCUIGJ1dCB0aGF0IGlzIHNvIHRoZSBjYWxsZXIgY2FuIFJFUE9SVCB3aGF0IGZhaWxlZCwgbm90IHNvIGl0IGNhblxuLy8gYmUgaWdub3JlZDogc2VlIGZhaWxlZFBhZ2VOYW1lcygpIGFuZCB0aGUgZXhwb3J0IGdhdGUgdGhhdCB1c2VzIGl0LlxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2Uge1xuXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG5cbiAgLy8gbGlzdFJvd3MgaXMgaG93IG1hbnkgcm93cyBlYWNoIGxpc3QgZmV0Y2hlczogdGhlIHJlbmRlcmVyJ3Mgb3duIGNhcCwgc2luY2VcbiAgLy8gYSBQREYgdGFibGUgY29udGludWVzIG9udG8gZXh0cmEgcGFnZXMgYW5kIGEgc2xpZGUgdGFibGUgY2Fubm90LlxuICBwdWJsaWMgY29sbGVjdChyZXBvcnQ6IFJlcG9ydCwgbGlzdFJvd3M6IG51bWJlcik6IE9ic2VydmFibGU8Q29sbGVjdGVkUmVwb3J0PiB7XG4gICAgY29uc3Qgc2xvdHM6IHsgcGFnZUluZGV4OiBudW1iZXI7IGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50IH1bXSA9IFtdO1xuXG4gICAgcmVwb3J0LnBhZ2VzLmZvckVhY2goKHBhZ2UsIHBhZ2VJbmRleCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGFnZS5jb21wb25lbnRzKSB7XG4gICAgICAgIHNsb3RzLnB1c2goeyBwYWdlSW5kZXgsIGNvbXBvbmVudCB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFRleHQgYmxvY2tzIGhhdmUgbm90aGluZyB0byBmZXRjaCDigJQgdGhleSByaWRlIHRocm91Z2ggd2l0aCBubyBkYXRhLiBUaGVcbiAgICAvLyBoZWFkZXIvZm9vdGVyIChyZXBvcnQubWFzdGVyKSBpcyByZWFkIGJ5IHRoZSByZW5kZXJlcnMgc3RyYWlnaHQgb2ZmIHRoZVxuICAgIC8vIHJlcG9ydCBmb3IgdGhlIHNhbWUgcmVhc29uLlxuXG4gICAgLy8gUmVsZWFzZWQgYSBmZXcgYXQgYSB0aW1lIHJhdGhlciB0aGFuIGFsbCBhdCBvbmNlLiBtZXJnZU1hcCBjb21wbGV0ZXMgb3V0XG4gICAgLy8gb2Ygb3JkZXIsIHNvIGVhY2ggcmVzdWx0IGNhcnJpZXMgdGhlIHNsb3QgaXQgY2FtZSBmcm9tIGFuZCB0aGUgcm93cyBhcmVcbiAgICAvLyBmaWxlZCBieSBpbmRleCDigJQgdGhlIGRlY2sncyBwYWdlIG9yZGVyIGNhbid0IGRlcGVuZCBvbiB3aGljaCBxdWVyeVxuICAgIC8vIGhhcHBlbmVkIHRvIGZpbmlzaCBmaXJzdC5cbiAgICBjb25zdCBhbGwkID0gc2xvdHMubGVuZ3RoXG4gICAgICA/IGZyb20oc2xvdHMubWFwKChzbG90LCBpbmRleCkgPT4gKHsgc2xvdCwgaW5kZXggfSkpKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBtZXJnZU1hcChcbiAgICAgICAgICAgICh7IHNsb3QsIGluZGV4IH0pID0+IHRoaXMuX2NvbXBvbmVudERhdGEocmVwb3J0LCBzbG90LmNvbXBvbmVudCwgbGlzdFJvd3MpXG4gICAgICAgICAgICAgIC5waXBlKG1hcCgoaXRlbSkgPT4gKHsgaXRlbSwgaW5kZXggfSkpKSxcbiAgICAgICAgICAgIEVYUE9SVF9DT05DVVJSRU5DWSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHRvQXJyYXkoKSxcbiAgICAgICAgKVxuICAgICAgOiBvZihbXSBhcyB7IGl0ZW06IENvbGxlY3RlZENvbXBvbmVudDsgaW5kZXg6IG51bWJlciB9W10pO1xuXG4gICAgLy8gVGhlIHN1bW1hcnkgcmlkZXMgYWxvbmdzaWRlIHRoZSBjb21wb25lbnQgZGF0YSByYXRoZXIgdGhhbiBiZWluZyBidWlsdCBhdFxuICAgIC8vIHRoZSBlbmQsIGJlY2F1c2UgbmFtaW5nIGEgc2VsZWN0IGZpbHRlcidzIHZhbHVlcyBpcyBpdHNlbGYgYSByZXF1ZXN0LlxuICAgIHJldHVybiBmb3JrSm9pbih7IGNvbGxlY3RlZDogYWxsJCwgZmlsdGVyU3VtbWFyeTogdGhpcy5nZXRGaWx0ZXJTdW1tYXJ5KHJlcG9ydCkgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKHsgY29sbGVjdGVkLCBmaWx0ZXJTdW1tYXJ5IH0pID0+IHtcbiAgICAgICAgICBjb25zdCBwYWdlczogQ29sbGVjdGVkUGFnZVtdID0gcmVwb3J0LnBhZ2VzLm1hcCgocGFnZSkgPT4gKHsgcGFnZSwgY29tcG9uZW50czogW10gfSkpO1xuXG4gICAgICAgICAgWy4uLmNvbGxlY3RlZF1cbiAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmluZGV4IC0gYi5pbmRleClcbiAgICAgICAgICAgIC5mb3JFYWNoKCh7IGl0ZW0sIGluZGV4IH0pID0+IHtcbiAgICAgICAgICAgICAgcGFnZXNbc2xvdHNbaW5kZXhdLnBhZ2VJbmRleF0uY29tcG9uZW50cy5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVwb3J0LFxuICAgICAgICAgICAgcGFnZXMsXG4gICAgICAgICAgICBmaWx0ZXJTdW1tYXJ5LFxuICAgICAgICAgICAgY29udGV4dExpbmVzOiB0aGlzLl9jb250ZXh0TGluZXMocmVwb3J0KSxcbiAgICAgICAgICAgIGZvcm1hdENvbnRleHQ6IHRoaXMuX2ZpbHRlclN0YXRlLmZvcm1hdENvbnRleHQoKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBcIlJlcG9ydCBQZXJpb2Q6IEp1biAxMiwgMjAyNSDigJMgSnVuIDEyLCAyMDI2XCIsIFwiUmVnaW9uOiBOb3J0aCwgRWFzdFwiIOKAlCBvbmVcbiAgLy8gbGluZSBwZXIgZmlsdGVyIGdyb3VwIHRoYXQgaGFzIGFuIGFjdGl2ZSBzZXNzaW9uIHZhbHVlLCB0aGVuIHRoZSBncm91cC1ieVxuICAvLyBsaW5lLiBUaGUgZmlsdGVyIGJhciBhcyB0aGUgdmlld2VyIHJlYWRzIGl0OiB0aGUgUERGIGFuZCBQb3dlclBvaW50IGNvdmVyc1xuICAvLyBwcmludCBpdCwgYW5kIHRoZSByZXBvcnQgemlwIGV4cG9ydCBzZW5kcyBpdCBmb3IgaXRzIG5vdGVzIGZpbGUuIERhdGVzIGFyZVxuICAvLyB3cml0dGVuIGluIHRoZSByZXBvcnQncyBsb2NhbGUsIHNvIHRoZSBub3RlcyBuYW1lIHRoZSBwZXJpb2QgYXMgdGhlIGNvdmVyXG4gIC8vIGRvZXMuXG4gIC8vXG4gIC8vIEEgc2VsZWN0IGdyb3VwIHN0b3JlcyBpZHMsIHNvIGl0cyBsaW5lIGhhcyB0byBiZSBuYW1lZCBvZmYgdGhlIG9wdGlvbiBsaXN0XG4gIC8vIGJlZm9yZSBpdCBjYW4gYmUgcHJpbnRlZDsgYSBkYXRlIG9yIGtleXdvcmQgZ3JvdXAgYWxyZWFkeSBob2xkcyBpdHMgb3duXG4gIC8vIGRpc3BsYXkgdmFsdWUgYW5kIHJlc29sdmVzIHN5bmNocm9ub3VzbHkuXG4gIHB1YmxpYyBnZXRGaWx0ZXJTdW1tYXJ5KHJlcG9ydDogUmVwb3J0KTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IGxpbmVzOiBPYnNlcnZhYmxlPHN0cmluZz5bXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiByZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKTtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxhYmVsID0gZ3JvdXAubGFiZWwgfHwgJ0ZpbHRlcic7XG5cbiAgICAgIGlmICh2YWx1ZS5zdGFydCB8fCB2YWx1ZS5lbmQpIHtcbiAgICAgICAgbGluZXMucHVzaChvZihgJHtsYWJlbH06ICR7dGhpcy5fZGF0ZSh2YWx1ZS5zdGFydCl9IOKAkyAke3RoaXMuX2RhdGUodmFsdWUuZW5kKX1gKSk7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICAgIGxpbmVzLnB1c2godGhpcy5fc2VsZWN0TGluZShsYWJlbCwgZ3JvdXAsIHJlcG9ydC5pZCwgdmFsdWUudmFsdWVzKSk7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlLnZhbHVlPy50cmltKCkpIHtcbiAgICAgICAgbGluZXMucHVzaChvZihgJHtsYWJlbH06IFwiJHt2YWx1ZS52YWx1ZS50cmltKCl9XCJgKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhlIGdyb3VwLWJ5IGdyYWluLCB1bmRlciB0aGUgcmVwb3J0J3Mgb3duIG5hbWUgZm9yIHRoZSBjb250cm9sIOKAlCBhIGNvdmVyXG4gICAgLy8gc2hlZXQgcmVhZGluZyBcIkZyZXF1ZW5jeVwiIHdoZW4gdGhlIHJlcG9ydCBjYWxscyBpdCBcIlBlcmlvZFwiIGRlc2NyaWJlcyBhXG4gICAgLy8gY29udHJvbCB0aGUgcmVhZGVyIGNhbm5vdCBmaW5kIG9uIHNjcmVlbi5cbiAgICBjb25zdCBncmFudWxhcml0eSA9IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpO1xuICAgIGlmIChncmFudWxhcml0eSkge1xuICAgICAgY29uc3Qgb3B0aW9uID0gR1JBTlVMQVJJVFlfT1BUSU9OUy5maW5kKChpdGVtKSA9PiBpdGVtLnZhbHVlID09PSBncmFudWxhcml0eSk7XG4gICAgICBjb25zdCBsYWJlbCA9IHJlcG9ydC5jb25maWc/Lmdyb3VwQnk/LmxhYmVsIHx8ICdHcm91cCBCeSc7XG4gICAgICBsaW5lcy5wdXNoKG9mKGAke2xhYmVsfTogJHtvcHRpb24/Lm5hbWUgPz8gZ3JhbnVsYXJpdHl9YCkpO1xuICAgIH1cblxuICAgIHJldHVybiBsaW5lcy5sZW5ndGggPyBmb3JrSm9pbihsaW5lcykgOiBvZihbXSk7XG4gIH1cblxuICBwcml2YXRlIF9jb21wb25lbnREYXRhKHJlcG9ydDogUmVwb3J0LCBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgbGlzdFJvd3M6IG51bWJlcik6IE9ic2VydmFibGU8Q29sbGVjdGVkQ29tcG9uZW50PiB7XG4gICAgaWYgKGNvbXBvbmVudC50eXBlID09PSAndGV4dCcpIHtcbiAgICAgIHJldHVybiBvZih7IGNvbXBvbmVudCwgZGF0YTogbnVsbCwgaGlkZGVuQ29sdW1uczogW10gfSk7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsdGVycyA9IHRoaXMuX2ZpbHRlclN0YXRlLnJlc29sdmVGb3JDb21wb25lbnQoY29tcG9uZW50KTtcbiAgICAvLyBBIHRpbWUtc2VyaWVzIGNoYXJ0IGNhcnJpZXMgdGhlIHZpZXdlcidzIGdyb3VwLWJ5IGdyYWluIHNvIHRoZSBleHBvcnRcbiAgICAvLyByZS1idWNrZXRzIGV4YWN0bHkgYXMgdGhlIHNjcmVlbiBkb2VzOyBsaXN0cyBjYXJyeSB0aGVpciBleHBvcnQgcGFnaW5nXG4gICAgLy8gYW5kIHRoZSB2aWV3ZXIncyBoZWFkZXIgc29ydCBhbmQgc2VhcmNoLCBzbyB0aGUgdGFibGUgcmVhZHMgaW4gdGhlXG4gICAgLy8gc2NyZWVuJ3Mgb3JkZXIgYW5kIGhvbGRzIHRoZSBzY3JlZW4ncyByb3dzLlxuICAgIC8vXG4gICAgLy8gVGhlIHRpbWUtc2VyaWVzIGNoZWNrIGRlbGliZXJhdGVseSBtaXJyb3JzIHRoZSBzZXJ2ZXIncyBjYW5vbmljYWxcbiAgICAvLyBSZXBvcnRRdWVyeVJ1bm5lcjo6X2lzVGltZVNlcmllc0NoYXJ0LCBzbyBhIHByb2R1Y3QgcGlubmVkIHRvIGFuIG9sZGVyXG4gICAgLy8gZnJhbWV3b3JrIGRvZXMgbm90IHJlLWJ1Y2tldCBhIG5vbi10aW1lIGNoYXJ0LlxuICAgIGNvbnN0IGZyZXF1ZW5jeSA9IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpO1xuICAgIGNvbnN0IGlzVGltZVNlcmllcyA9IGNvbXBvbmVudC50eXBlID09PSAnY2hhcnQnICYmIGNvbXBvbmVudC5jb25maWc/LnhBeGlzPy5raW5kID09PSAndGltZSc7XG4gICAgY29uc3Qgc2VhcmNoID0gY29tcG9uZW50LnR5cGUgPT09ICdsaXN0J1xuICAgICAgPyB0aGlzLl9maWx0ZXJTdGF0ZS5saXN0U2VhcmNoKGNvbXBvbmVudC5pZCkgPz8gdW5kZWZpbmVkXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBzdGF0ZTogQ29tcG9uZW50RGF0YVN0YXRlID0gY29tcG9uZW50LnR5cGUgPT09ICdsaXN0J1xuICAgICAgPyB7IHBhZ2U6IDEsIHBhZ2VTaXplOiBsaXN0Um93cywgc29ydDogdGhpcy5fZmlsdGVyU3RhdGUubGlzdFNvcnQoY29tcG9uZW50LmlkKSA/PyB1bmRlZmluZWQsIHNlYXJjaCB9XG4gICAgICA6IChpc1RpbWVTZXJpZXMgJiYgZnJlcXVlbmN5ID8geyBmcmVxdWVuY3kgfSA6IHt9KTtcbiAgICAvLyBUaGUgdGFibGUgbGVhdmVzIG91dCB0aGUgY29sdW1ucyB0aGUgdmlld2VyIGhpZC4gVGhlIHJvd3MgYXJlIGZldGNoZWRcbiAgICAvLyB3aG9sZSwgYXMgdGhlIHNjcmVlbiBmZXRjaGVzIHRoZW0sIGFuZCB0aGUgcmVuZGVyZXJzIGRyb3AgdGhlIGNlbGxzLlxuICAgIGNvbnN0IGhpZGRlbkNvbHVtbnMgPSBbLi4udGhpcy5fZmlsdGVyU3RhdGUuaGlkZGVuQ29sdW1ucyhjb21wb25lbnQuaWQpXTtcblxuICAgIC8vIGhhbmRsZXJzOiBmYWxzZSBrZWVwcyB0aGUgYXBwJ3MgZ2xvYmFsIGVycm9yIGRpYWxvZyBvdXQgb2YgdGhpcy4gQSBmYWlsZWRcbiAgICAvLyB0aWxlIGlzIHJlcG9ydGVkIG9uY2UsIGJ5IHRoZSBleHBvcnQgZ2F0ZSwgbmFtaW5nIHRoZSBwYWdlcyBpdCBjb3N0IOKAlFxuICAgIC8vIG5ldmVyIGFzIHRlbiBzdGFja2VkIG1vZGFscyBjYXJyeWluZyB0aGUgZGF0YWJhc2UncyBvd24gd29yZGluZy5cbiAgICAvL1xuICAgIC8vIEEgc2VhcmNoIHRoZSBzZXJ2ZXIgY291bGQgbm90IGFwcGx5IChzZWFyY2hOb3RlOiB0aGUgbGlzdCBoYXMgbm8gdGV4dFxuICAgIC8vIGNvbHVtbikgbmFycm93ZWQgbm90aGluZywgc28gdGhlIGl0ZW0gZG9lcyBub3QgY2FycnkgaXQuXG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydERhdGEuY29tcG9uZW50RGF0YShyZXBvcnQuaWQsIGNvbXBvbmVudC5pZCwgZmlsdGVycywgc3RhdGUsIHRydWUsIHsgaGFuZGxlcnM6IGZhbHNlIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChkYXRhOiBDb21wb25lbnREYXRhKTogQ29sbGVjdGVkQ29tcG9uZW50ID0+IChzZWFyY2ggJiYgIWRhdGE/LnNlYXJjaE5vdGVcbiAgICAgICAgICA/IHsgY29tcG9uZW50LCBkYXRhLCBzZWFyY2gsIGhpZGRlbkNvbHVtbnMgfVxuICAgICAgICAgIDogeyBjb21wb25lbnQsIGRhdGEsIGhpZGRlbkNvbHVtbnMgfSkpLFxuICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKHsgY29tcG9uZW50LCBkYXRhOiBudWxsLCBoaWRkZW5Db2x1bW5zIH0pKSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgem9uZSB0aGUgc2VydmVyIHJlc29sdmVkLCBhcyBpdHMgSUFOQSBpZCwgYW5kIHRoZSBjdXJyZW5jeSBpdCBzYXlzXG4gIC8vIHRoZSByZXBvcnQncyBtb25leSBpcyBpbiAoYSBsYWJlbDogbm90aGluZyBpcyBjb252ZXJ0ZWQpLiBPbmx5IHRoZVxuICAvLyBzZXJ2ZXIncyB2YWx1ZXMgYXJlIHByaW50ZWQ6IHRoZSBicm93c2VyJ3Mgem9uZSAocmVzb2x2ZVJlcG9ydFRpbWV6b25lJ3NcbiAgLy8gZmFsbGJhY2sgZm9yIGFuIG9sZGVyIHNlcnZlcikgaXMgbm90IHdoYXQgdGhlIG51bWJlcnMgd2VyZSBtZWFzdXJlZCBpbixcbiAgLy8gYW5kIGFuIG9sZGVyIHNlcnZlciBuYW1lcyBubyBjdXJyZW5jeSBhdCBhbGwuXG4gIHByaXZhdGUgX2NvbnRleHRMaW5lcyhyZXBvcnQ6IFJlcG9ydCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4uKHJlcG9ydC5lZmZlY3RpdmVUaW1lem9uZSA/IFtgVGltZXpvbmU6ICR7cmVwb3J0LmVmZmVjdGl2ZVRpbWV6b25lfWBdIDogW10pLFxuICAgICAgLi4uKHJlcG9ydC5lZmZlY3RpdmVDdXJyZW5jeSA/IFtgQ3VycmVuY3k6ICR7cmVwb3J0LmVmZmVjdGl2ZUN1cnJlbmN5fWBdIDogW10pLFxuICAgIF07XG4gIH1cblxuICAvLyBPbmUgc2VsZWN0IGdyb3VwJ3MgbGluZSwgd2l0aCBpdHMgc3RvcmVkIGlkcyByZXNvbHZlZCB0byB0aGUgc2FtZSBuYW1lcyB0aGVcbiAgLy8gb24tc2NyZWVuIGNoaXBzIHNob3cg4oCUIGEgY292ZXIgcmVhZGluZyBcIk9yZ2FuaXphdGlvbjogODc3NCwgODc3N1wiIHRlbGxzIHRoZVxuICAvLyByZWFkZXIgbm90aGluZyBhYm91dCB3aGF0IHRoZSByZXBvcnQgY292ZXJzLlxuICAvL1xuICAvLyBVc2VzIHRoZSByZXBvcnQgYmFyJ3Mgb3duIGxvYWRlciBhbmQgcmVzb2x2ZXIgc28gdGhlIHR3byBjYW4ndCBkcmlmdCwgd2hpY2hcbiAgLy8gYWxzbyBtZWFucyBhIHZhbHVlIHdob3NlIGVudGl0eSB3YXMgZGVsZXRlZCBrZWVwcyBzaG93aW5nIGl0cyByYXcgaWQgcmF0aGVyXG4gIC8vIHRoYW4gZHJvcHBpbmcgb2ZmIHRoZSBjb3ZlciBhbmQgc2lsZW50bHkgdW5kZXJzdGF0aW5nIHRoZSBmaWx0ZXIuIEEgZmFpbGVkXG4gIC8vIG9wdGlvbiBmZXRjaCBkZWdyYWRlcyB0aGUgd2hvbGUgbGluZSB0byBpZHMgZm9yIHRoZSBzYW1lIHJlYXNvbjogYW4gZXhwb3J0XG4gIC8vIG11c3QgbmV2ZXIgZmFpbCBvbiBhIGNvc21ldGljIGxvb2t1cC5cbiAgcHJpdmF0ZSBfc2VsZWN0TGluZShcbiAgICBsYWJlbDogc3RyaW5nLFxuICAgIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgICByZXBvcnRJZDogbnVtYmVyLFxuICAgIHZhbHVlczogdW5rbm93bltdLFxuICApOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiByZXNvbHZlT3B0aW9uVmFsdWVzKGxvYWRHcm91cE9wdGlvbnMoZ3JvdXAsIHRoaXMuX3JlcG9ydERhdGEsIHJlcG9ydElkKSwgdmFsdWVzKVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcCgocmVzb2x2ZWQpID0+IGAke2xhYmVsfTogJHtyZXNvbHZlZC5tYXAoKGl0ZW0pID0+IGl0ZW0ubmFtZSkuam9pbignLCAnKX1gKSxcbiAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihgJHtsYWJlbH06ICR7dmFsdWVzLm1hcCgoaXRlbSkgPT4gU3RyaW5nKGl0ZW0pKS5qb2luKCcsICcpfWApKSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBSZW5kZXJlZCBvZmYgdGhlIHNhbWUgY2FsZW5kYXIgZGF5IHRoZSBmaWx0ZXIgc2VuZHMgdG8gdGhlIHNlcnZlciwgc28gdGhlXG4gIC8vIGNvdmVyJ3MgcGVyaW9kIGlzIHRoZSBwZXJpb2QgdGhlIG51bWJlcnMgYmVoaW5kIGl0IHdlcmUgcXVlcmllZCBmb3IuXG4gIHByaXZhdGUgX2RhdGUodmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF0ZUJvdW5kTGFiZWwodmFsdWUsIHRoaXMuX2ZpbHRlclN0YXRlLmZvcm1hdENvbnRleHQoKS5sb2NhbGUpID8/ICfigKYnO1xuICB9XG59XG4iXX0=
581
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9leHBvcnQvcmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQWMsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxFQUNMLFFBQVEsRUFDUixlQUFlLEVBQ2YsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLHFCQUFxQixHQUN0QixNQUFNLFdBQVcsQ0FBQztBQW9CbkIsT0FBTyxFQUNMLGdCQUFnQixFQUVoQixpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLHFCQUFxQixHQUN0QixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9FLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN2RixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRSxPQUFPLEVBQStCLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsYUFBYSxFQUFFLHNCQUFzQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDM0UsT0FBTyxFQUNMLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFNBQVMsR0FDdEUsTUFBTSxXQUFXLENBQUM7QUFFbkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7O0FBcUdqRiw2RUFBNkU7QUFDN0UseUVBQXlFO0FBQ3pFLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxDQUFDO0FBRWpDLGdEQUFnRDtBQUNoRCxFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSxnRkFBZ0Y7QUFDaEYsK0VBQStFO0FBQy9FLFlBQVk7QUFDWixNQUFNLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUU3QiwyRUFBMkU7QUFDM0UsMkVBQTJFO0FBQzNFLGVBQWU7QUFDZixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQztBQUVwRCwrRUFBK0U7QUFDL0Usd0JBQXdCO0FBQ3hCLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBMEJuQyxxRUFBcUU7QUFDckUsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsZ0ZBQWdGO0FBQ2hGLCtFQUErRTtBQUMvRSxnRkFBZ0Y7QUFDaEYsK0NBQStDO0FBQy9DLE1BQU0sVUFBVSxVQUFVLENBQUMsSUFBd0I7SUFDakQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDO0FBQzFELENBQUM7QUFFRCw2RUFBNkU7QUFDN0UseUVBQXlFO0FBQ3pFLDJFQUEyRTtBQUMzRSx3RUFBd0U7QUFDeEUsMkVBQTJFO0FBQzNFLDZDQUE2QztBQUM3QyxNQUFNLFVBQVUsV0FBVyxDQUN6QixTQUEwQixFQUMxQixNQUFzQixFQUN0QixNQUFpQztJQUVqQyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDLENBQUM7SUFFMUQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxlQUFlLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLE1BQU0sR0FBRyxDQUFDO0FBQzVFLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsTUFBTSxVQUFVLFFBQVEsQ0FBQyxJQUF3QjtJQUMvQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUM7QUFDdEQsQ0FBQztBQUVELCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSxZQUFZLENBQUMsU0FBMEIsRUFBRSxJQUFZLEVBQUUsTUFBd0I7SUFDN0YsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxJQUFJLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRXpGLE9BQU87UUFDTCxXQUFXLEVBQUUsU0FBUyxDQUFDLEVBQUU7UUFDekIsSUFBSTtRQUNKLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLHVCQUF1QixDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSTtLQUMvRyxDQUFDO0FBQ0osQ0FBQztBQUVELCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBQzFFLCtFQUErRTtBQUMvRSxzREFBc0Q7QUFDdEQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxTQUEwQjtJQUNuRCxPQUFPO1FBQ0wsZUFBZSxDQUNiLElBQUksSUFBSSxFQUFFLEVBQ1YsU0FBUyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQzlCLFFBQVEsRUFDUixxQkFBcUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQ3hDO1FBQ0QsR0FBRyxTQUFTLENBQUMsYUFBYTtRQUMxQixHQUFHLFNBQVMsQ0FBQyxZQUFZO0tBQzFCLENBQUM7QUFDSixDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLDBFQUEwRTtBQUMxRSw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSxtQkFBbUI7QUFDbkIsRUFBRTtBQUNGLHdFQUF3RTtBQUN4RSw2RUFBNkU7QUFDN0UsNkVBQTZFO0FBQzdFLGdFQUFnRTtBQUNoRSxNQUFNLFVBQVUsVUFBVSxDQUN4QixLQUFjLEVBQ2QsTUFBa0QsRUFDbEQsUUFBZ0IsRUFDaEIsT0FBNEIsRUFDNUIsR0FBb0M7SUFFcEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUU3QixJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO1lBQzlELFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztZQUMvQixLQUFLLEVBQUUsTUFBTSxDQUFDLFVBQVUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDcEUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO1lBQ25CLEtBQUssRUFBRSxFQUFFO1NBQ1YsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNWLENBQUM7SUFFRCxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsRCxPQUFPLGdCQUFnQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxPQUFPLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2RyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLHlFQUF5RTtBQUN6RSwwRUFBMEU7QUFDMUUsd0VBQXdFO0FBQ3hFLDRFQUE0RTtBQUM1RSxpRUFBaUU7QUFDakUsTUFBTSxVQUFVLFdBQVcsQ0FDekIsU0FBMEIsRUFDMUIsSUFBbUIsRUFDbkIsTUFBdUIsRUFDdkIsU0FBNEIsRUFBRTtJQUU5QixNQUFNLE1BQU0sR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFlLENBQUM7SUFFdEQsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQzNCLE9BQU8saUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUMzQixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFdEQsT0FBTyxpQkFBaUIsQ0FDdEIsTUFBTSxDQUFDLE9BQU87YUFDWCxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDeEQsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsT0FBTyxFQUFFLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDckUsSUFBSSxFQUNKLE1BQU0sQ0FBQyxPQUFPLENBQ2YsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ2pHLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLDREQUE0RDtBQUM1RCxTQUFTLGlCQUFpQixDQUN4QixPQUEyQixFQUMzQixJQUFtQixFQUNuQixRQUErQjtJQUUvQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xCLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRTNELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNwRCxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQzlELENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ2YsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLFlBQVksQ0FDMUIsU0FBMEIsRUFDMUIsSUFBbUIsRUFDbkIsTUFBdUIsRUFDdkIsU0FBNEIsRUFBRTtJQUU5QixPQUFPLFdBQVcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3JHLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSx3RUFBd0U7QUFDeEUsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsSUFBbUIsRUFDbkIsT0FBb0MsRUFDcEMsUUFBZ0IsRUFDaEIsT0FBNEI7SUFFNUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUUzQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFckQsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssS0FBSztRQUNyRCxDQUFDLENBQUMsZ0JBQWdCO1FBQ2xCLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0UsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSwwRUFBMEU7QUFDMUUsb0VBQW9FO0FBQ3BFLDZFQUE2RTtBQUM3RSxRQUFRO0FBQ1IsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQXdCLEVBQUUsUUFBZ0IsRUFBRSxNQUF1QjtJQUNuRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUNoRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxPQUFPLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSxzRUFBc0U7QUFDdEUsNEVBQTRFO0FBQzVFLDRDQUE0QztBQUM1QyxNQUFNLFVBQVUsZUFBZSxDQUFDLElBQXdCLEVBQUUsUUFBZ0IsRUFBRSxNQUF1QjtJQUNqRyxPQUFPLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDM0csQ0FBQztBQUVELDhFQUE4RTtBQUM5RSxxREFBcUQ7QUFDckQsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQWlCLEVBQUUsS0FBd0I7SUFDMUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4RixDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLDhFQUE4RTtBQUM5RSw2RUFBNkU7QUFDN0UseUVBQXlFO0FBQ3pFLDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0UsZ0RBQWdEO0FBQ2hELE1BQU0sVUFBVSxjQUFjLENBQzVCLElBQWlCLEVBQ2pCLEtBQXdCLEVBQ3hCLFNBQWlCLEVBQ2pCLE9BQXlCO0lBRXpCLE1BQU0sS0FBSyxHQUFtQjtRQUM1QixLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLO1FBQ25CLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU07UUFDckIsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTTtRQUNyQixTQUFTLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQztRQUNuRSxLQUFLLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUNqQixLQUFLLEVBQUUsQ0FBQztLQUNULENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUUzRCxJQUFJLE1BQU0sRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLEtBQUssQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRCxJQUFJLE1BQU0sRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxPQUFPLE1BQU0sRUFBRSxHQUFHLFNBQVMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xELEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVELElBQUksTUFBTSxFQUFFLEdBQUcsU0FBUyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pDLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxJQUFJLE1BQU0sRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQ3pCLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2xGLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCwwRUFBMEU7QUFDMUUsOENBQThDO0FBQzlDLE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUF5QixFQUFFLEtBQWE7SUFDdkUsT0FBTztRQUNMLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxHQUFHLEtBQUs7UUFDNUIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLEdBQUcsS0FBSztRQUM1QixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssR0FBRyxLQUFLO1FBQzVCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxHQUFHLEtBQUs7UUFDOUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSztRQUM5QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsR0FBRyxLQUFLO1FBQ3BDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxHQUFHLEtBQUs7S0FDM0IsQ0FBQztBQUNKLENBQUM7QUFFRCx3RUFBd0U7QUFDeEUsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUFpQixFQUFFLEtBQXFCLEVBQUUsT0FBeUI7SUFDakcsT0FBTyxPQUFPLENBQUMsS0FBSztVQUNoQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUNoQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUNqQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUNuQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUNuQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztVQUN6QyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO0FBQ3hDLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UseUVBQXlFO0FBQ3pFLDZFQUE2RTtBQUM3RSxpREFBaUQ7QUFDakQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxTQUFpQjtJQUM5QyxPQUFPLEtBQUssU0FBUyxvRUFBb0UsQ0FBQztBQUM1RixDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSxxQ0FBcUM7QUFDckMsTUFBTSxVQUFVLGVBQWUsQ0FBQyxTQUEwQjtJQUN4RCx5RUFBeUU7SUFDekUsc0VBQXNFO0lBQ3RFLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxLQUFLO1NBQzFCLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ25ELE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztXQUMvQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUN2RixHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksUUFBUSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFFM0UsSUFBSSxNQUFNLElBQUksV0FBVyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQztRQUMvRixLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELHFFQUFxRTtBQUNyRSxTQUFTLGdCQUFnQixDQUFDLFVBQTZCLEVBQUUsTUFBeUI7SUFDaEYsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVTtTQUM3QixNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDO1NBQ2hELE9BQU8sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRTlELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsNkVBQTZFO0FBQzdFLDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUsaUNBQWlDO0FBQ2pDLE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsUUFBOEIsRUFDOUIsS0FBa0MsRUFDbEMsS0FBbUQ7SUFFbkQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3pHLE1BQU0sT0FBTyxHQUFHLEtBQUs7U0FDbEIsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1NBQ2xDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO1NBQ3ZDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBRWxFLE9BQU87UUFDTCxRQUFRLENBQUMsUUFBUTtRQUNqQixHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3pFLEdBQUcsT0FBTztRQUNWLEtBQUs7S0FDTjtTQUNFLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLHlFQUF5RTtBQUN6RSx3RUFBd0U7QUFDeEUsdUVBQXVFO0FBQ3ZFLE1BQU0sVUFBVSxZQUFZLENBQUMsU0FBMEI7SUFDckQsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUM7QUFDeEQsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSx3RUFBd0U7QUFDeEUsOEVBQThFO0FBQzlFLHFDQUFxQztBQUNyQyxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLCtFQUErRTtBQUMvRSx5RUFBeUU7QUFDekUsdURBQXVEO0FBRXZELE1BQU0sT0FBTyw0QkFBNEI7SUFFL0IsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqQyxZQUFZLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDaEQsY0FBYyxHQUFHLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0lBQzVELHlFQUF5RTtJQUN6RSwyQkFBMkI7SUFDbkIsTUFBTSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRS9ELDZFQUE2RTtJQUM3RSxtRUFBbUU7SUFDbkUsRUFBRTtJQUNGLDBFQUEwRTtJQUMxRSx3RUFBd0U7SUFDeEUsMkVBQTJFO0lBQzNFLHlEQUF5RDtJQUNsRCxPQUFPLENBQUMsTUFBYyxFQUFFLFFBQWdCO1FBQzdDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDO1FBRTdDLDJFQUEyRTtRQUMzRSxvRUFBb0U7UUFDcEUsMkVBQTJFO1FBQzNFLHVFQUF1RTtRQUN2RSx3REFBd0Q7UUFDeEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU07WUFDdEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQy9DLElBQUksQ0FDSCxRQUFRLENBQ04sQ0FBQyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUM7aUJBQzlELElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQzdDLGtCQUFrQixDQUNuQixFQUNELE9BQU8sRUFBRSxDQUNWO1lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFnRCxDQUFDLENBQUM7UUFFekQseUVBQXlFO1FBQ3pFLHdFQUF3RTtRQUN4RSxPQUFPLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUM7YUFDNUUsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDM0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBRTFELE9BQU87Z0JBQ0wsTUFBTTtnQkFDTixHQUFHLElBQUk7Z0JBQ1AsYUFBYSxFQUFFLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDNUQsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO2dCQUN4QyxhQUFhO2FBQ2QsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDTixDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLHlFQUF5RTtJQUN6RSwwRUFBMEU7SUFDMUUsd0VBQXdFO0lBQ3hFLDJFQUEyRTtJQUMzRSw4QkFBOEI7SUFDdkIsUUFBUSxDQUFDLE1BQWM7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMxQyxNQUFNLEtBQUssR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO2FBQy9CLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7YUFDeEMsTUFBTSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7YUFDcEMsTUFBTSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDO1FBRXJELE9BQU87WUFDTCxJQUFJO1lBQ0osR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztZQUM1QixPQUFPLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEcsWUFBWSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTTtpQkFDcEMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3RixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUU7WUFDeEMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUM7WUFDdEQsYUFBYSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFO1lBQ2hELFFBQVEsRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQztTQUM5RSxDQUFDO0lBQ0osQ0FBQztJQUVELDRFQUE0RTtJQUM1RSx5RUFBeUU7SUFDekUsMENBQTBDO0lBQ25DLFdBQVcsQ0FDaEIsTUFBYyxFQUNkLFFBQThCLEVBQzlCLFNBQXdCLElBQUk7UUFFNUIsT0FBTyxXQUFXLENBQUM7WUFDakIsTUFBTTtZQUNOLFFBQVE7WUFDUixNQUFNO1lBQ04sS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUM7U0FDcEUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSw2RUFBNkU7SUFDN0UsMEVBQTBFO0lBQzFFLDRFQUE0RTtJQUM1RSw0RUFBNEU7SUFDNUUsMkVBQTJFO0lBQzNFLHFDQUFxQztJQUM3QixLQUFLLENBQUMsTUFBYztRQUMxQixNQUFNLElBQUksR0FBaUIsRUFBRSxDQUFDO1FBRTlCLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxVQUFVO2lCQUNaLE1BQU0sQ0FBQyxZQUFZLENBQUM7aUJBQ3BCLE9BQU8sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNsRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGtFQUFrRTtJQUMxRCxXQUFXLENBQUMsS0FBZ0MsRUFBRSxTQUF3QjtRQUM1RSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUNsQyxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXpDLE9BQU8sS0FBSyxDQUFDLE1BQU07WUFDakIsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQzlFLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDVCxDQUFDO0lBRUQscUVBQXFFO0lBQzdELE9BQU8sQ0FDYixNQUFjLEVBQ2QsR0FBZSxFQUNmLFFBQWdCLEVBQ2hCLFFBQThCO1FBRTlCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQztpQkFDbEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBaUIsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQzthQUM5RSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFpQixFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVPLGNBQWMsQ0FDcEIsTUFBYyxFQUNkLFNBQTBCLEVBQzFCLFFBQWdCLEVBQ2hCLFFBQThCO1FBRTlCLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUM5QixPQUFPLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckQsNkRBQTZEO1FBQzdELHdFQUF3RTtRQUN4RSx5RUFBeUU7UUFDekUsb0RBQW9EO1FBQ3BELE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0RCxNQUFNLEtBQUssR0FBdUIsU0FBUyxDQUFDLElBQUksS0FBSyxNQUFNO1lBQ3pELENBQUMsQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRTtZQUMvQyxDQUFDLENBQUMsRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQ3JCLHdFQUF3RTtRQUN4RSwwRUFBMEU7UUFDMUUsK0NBQStDO1FBQy9DLE1BQU0sYUFBYSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV2RCw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLG1FQUFtRTtRQUNuRSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQzthQUN0RyxJQUFJLENBQ0gsR0FBRyxDQUFDLENBQUMsSUFBbUIsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQ3JHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQy9ELENBQUM7SUFDTixDQUFDO0lBRUQsd0VBQXdFO0lBQ3hFLDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsbUVBQW1FO0lBQzNELFVBQVUsQ0FDaEIsU0FBMEIsRUFDMUIsSUFBbUIsRUFDbkIsTUFBMEIsRUFDMUIsYUFBdUIsRUFDdkIsUUFBOEI7UUFFOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO1FBRXJDLE9BQU87WUFDTCxTQUFTO1lBQ1QsSUFBSTtZQUNKLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDbEQsYUFBYTtZQUNiLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUNuRixDQUFDO0lBQ0osQ0FBQztJQUVELHdFQUF3RTtJQUN4RSx3RUFBd0U7SUFDeEUsOEJBQThCO0lBQ3RCLFlBQVksQ0FBQyxNQUFjO1FBQ2pDLE1BQU0sTUFBTSxHQUFxQyxFQUFFLENBQUM7UUFDcEQsTUFBTSxPQUFPLEdBQXdDLEVBQUUsQ0FBQztRQUV4RCxDQUFDLE1BQU0sQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDNUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUV0RCxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUNWLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUc7b0JBQ2pCLEdBQUcsS0FBSztvQkFDUixHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3RELEdBQUcsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztpQkFDNUUsQ0FBQztZQUNKLENBQUM7WUFDRCxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1lBQzdCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSw0RUFBNEU7SUFDNUUsd0VBQXdFO0lBQ3hFLHVEQUF1RDtJQUN2RCwwRUFBMEU7SUFDMUUseUVBQXlFO0lBQ3pFLDBFQUEwRTtJQUMxRSw0RUFBNEU7SUFDNUUsNEVBQTRFO0lBQzVFLDBFQUEwRTtJQUMxRSw2QkFBNkI7SUFDckIsV0FBVyxDQUNqQixNQUFjLEVBQ2QsTUFBYyxFQUNkLE1BQXlCLEVBQ3pCLEtBQXdCLEVBQ3hCLFFBQThCO1FBRTlCLE1BQU0sYUFBYSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUM7UUFDN0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDekYsTUFBTSxnQkFBZ0IsR0FBRyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvRSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsZ0JBQWdCLENBQUM7YUFDeEcsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLEVBQTJCLENBQUMsQ0FBQyxFQUN4RCxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDYixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsQ0FBQztZQUNuRCxZQUFZLEVBQUUsZUFBZSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUM7U0FDM0MsQ0FBQyxDQUFDLENBQ0osQ0FBQztJQUNOLENBQUM7SUFFRCwwRUFBMEU7SUFDMUUsMEVBQTBFO0lBQzFFLG9DQUFvQztJQUM1QixLQUFLLENBQ1gsTUFBYyxFQUNkLE9BQW1ELEVBQ25ELGFBQWtDO1FBRWxDLE1BQU0sTUFBTSxHQUFHLENBQUMsTUFBcUMsRUFBbUIsRUFBRSxDQUFDLENBQUM7WUFDMUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsRUFBRSxhQUFhLENBQUM7WUFDcEUsWUFBWSxFQUFFLEVBQUU7U0FDakIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQW9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlHLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTNDLENBQUMsR0FBRyxPQUFPLENBQUM7YUFDVCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7YUFDakMsT0FBTyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFO1lBQ3RCLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDaEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN2RCxDQUFDO2lCQUFNLElBQUksTUFBTSxDQUFDLFNBQVMsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDNUIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDM0QsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUwsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekYsQ0FBQztJQUVELHlFQUF5RTtJQUN6RSxxRUFBcUU7SUFDckUsMkVBQTJFO0lBQzNFLDBFQUEwRTtJQUMxRSxnREFBZ0Q7SUFDeEMsYUFBYSxDQUFDLE1BQWM7UUFDbEMsT0FBTztZQUNMLEdBQUcsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUMvRSxDQUFDO0lBQ0osQ0FBQztJQUVELDBFQUEwRTtJQUMxRSwyRUFBMkU7SUFDM0UscUVBQXFFO0lBQ3JFLEVBQUU7SUFDRix5RUFBeUU7SUFDekUsOEVBQThFO0lBQzlFLDBFQUEwRTtJQUMxRSx1RUFBdUU7SUFDdkUscUVBQXFFO0lBQ3JFLDRFQUE0RTtJQUM1RSwyRUFBMkU7SUFDbkUsVUFBVSxDQUFDLEtBQXdCLEVBQUUsUUFBZ0IsRUFBRSxNQUFpQjtRQUM5RSxPQUFPLG1CQUFtQixDQUN4QixnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsRUFDbkQsTUFBTSxFQUNOLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUN0RDthQUNFLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUNwRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDekQsQ0FBQztJQUNOLENBQUM7d0dBelVVLDRCQUE0Qjs0R0FBNUIsNEJBQTRCOzs0RkFBNUIsNEJBQTRCO2tCQUR4QyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luLCBmcm9tLCBtYXAsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtZXJnZU1hcCwgdG9BcnJheSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgY3J1bWJlZFRpdGxlLCBkcmlsbENydW1iTGFiZWxzIH0gZnJvbSAnLi4vZHJpbGwtY3J1bWJzJztcbmltcG9ydCB7IFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQgfSBmcm9tICcuLi9lbnVtcy9yZXBvcnQtbGlzdC1jb2x1bW4tZm9ybWF0LmVudW0nO1xuaW1wb3J0IHtcbiAgREFZX0xPTkcsXG4gIGZvcm1hdExvY2FsRGF0ZSxcbiAgZm9ybWF0TnVtYmVyLFxuICBmb3JtYXRPdXRwdXRWYWx1ZSxcbiAgZm9ybWF0UmVwb3J0RGF0ZSxcbiAgaGFzTnVtYmVyRm9ybWF0LFxuICByZXNvbHZlUmVwb3J0VGltZXpvbmUsXG59IGZyb20gJy4uL2Zvcm1hdCc7XG5pbXBvcnQgeyBSZXBvcnRFeHBvcnRMaW5lIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZXhwb3J0LWxpbmUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEV4cG9ydFNuYXBzaG90IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZXhwb3J0LXNuYXBzaG90LmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBDb21wb25lbnREYXRhLFxuICBDb21wb25lbnREYXRhU3RhdGUsXG4gIEZpbHRlckdyb3VwVmFsdWUsXG4gIExpc3RDb2x1bW4sXG4gIExpc3RDb25maWcsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgUmVwb3J0TG9jYWxlVGFnLFxuICBSZXBvcnRNYXN0ZXIsXG4gIFJlcG9ydFBhZ2UsXG4gIFJlcG9ydFBhZ2VWYWx1ZSxcbiAgUmVwb3J0UmVsYXRpdmVSYW5nZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IEtwaUNhcmRWaWV3IH0gZnJvbSAnLi4va3BpLWNhcmQnO1xuaW1wb3J0IHtcbiAgTElTVF9UT1RBTF9MQUJFTCxcbiAgTGlzdE91dHB1dENvbHVtbixcbiAgbGlzdEhpZGRlbkNvbHVtbnMsXG4gIGxpc3RPdXRwdXRDb2x1bW5zLFxuICBsaXN0VG90YWxzTGFiZWxDb2x1bW4sXG59IGZyb20gJy4uL2xpc3QtY29uZmlnJztcbmltcG9ydCB7IHBpdm90Q29sdW1uU3BlY3MgfSBmcm9tICcuLi9vcHRpb24tYnVpbGRlcic7XG5pbXBvcnQgeyBjb21wb25lbnROb3RlTGluZXMsIGNvbXBvbmVudFdpbmRvd3NMaW5lIH0gZnJvbSAnLi4vb3V0cHV0LW5vdGVzJztcbmltcG9ydCB7IGxvYWRHcm91cE9wdGlvbnMsIHJlc29sdmVPcHRpb25WYWx1ZXMgfSBmcm9tICcuLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7IGlzVGlsZSB9IGZyb20gJy4uL3JlcG9ydC10aWxlJztcbmltcG9ydCB7IG9mZmVyZWRWaWV3ZXJGZWF0dXJlcyB9IGZyb20gJy4uL3JlcG9ydC12aWV3ZXItZmVhdHVyZXMnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9yZXBvcnQtdmlldy5zZXJ2aWNlJztcbmltcG9ydCB7IFRleHRUb2tlbkNvbnRleHQsIFRleHRWYWx1ZSwgdGV4dFBsYWluIH0gZnJvbSAnLi4vdGV4dCc7XG5pbXBvcnQgeyB0aWxlRGF0YVN0YXRlLCB2YWx1ZXNNYXRjaEFueUdyb3VwSWRzIH0gZnJvbSAnLi4vdGlsZS1kYXRhLXN0YXRlJztcbmltcG9ydCB7XG4gIGZhaWxlZFZhbHVlS2V5cywgcmVwb3J0Q29tcG9uZW50cywgc2hvd25WYWx1ZXMsIHRleHRWYWx1ZXMsIHZhbHVlS2V5cyxcbn0gZnJvbSAnLi4vdmFsdWVzJztcblxuaW1wb3J0IHsgZXhwb3J0TGluZXMsIG1hdGNoTGluZVRleHQsIHZpZXdMaW5lVGV4dCB9IGZyb20gJy4vcmVwb3J0LWZpbHRlci1saW5lcyc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0ZWRDb21wb25lbnQge1xuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudDtcbiAgLy8gbnVsbCA9IGl0cyBxdWVyeSBmYWlsZWQ7IGV4cG9ydHMgc2hvdyBhIG5vdGUuIEFsd2F5cyBudWxsIGZvciBhIHRleHRcbiAgLy8gYmxvY2ssIHdoaWNoIGhhcyBubyBxdWVyeSDigJQgc2VlIGlzRmFpbGVkKCkuXG4gIGRhdGE6IENvbXBvbmVudERhdGEgfCBudWxsO1xuICAvLyBUaGUgdGV4dCBhIGxpc3Qgd2FzIHNlYXJjaGVkIGJ5IHdoZW4gaXQgd2FzIGZldGNoZWQ7IGFic2VudCB3aGVuIGl0c1xuICAvLyBzZWFyY2ggYm94IHdhcyBlbXB0eSwgYW5kIGZvciBldmVyeSBvdGhlciBjb21wb25lbnQuXG4gIHNlYXJjaD86IHN0cmluZztcbiAgLy8gVGhlIGNvbmZpZyBjb2x1bW5zIGEgdmlld2VyIGhpZCBvbiBhIHBsYWluIGxpc3QsIHdoaWNoIGl0cyB0YWJsZSBsZWF2ZXNcbiAgLy8gb3V0IChsaXN0Q29sdW1ucyk7IGVtcHR5IGZvciBldmVyeSBvdGhlciBjb21wb25lbnQuXG4gIGhpZGRlbkNvbHVtbnM6IHN0cmluZ1tdO1xuICAvLyBUaGUgYnJlYWRjcnVtYiBvZiB0aGUgZHJpbGwgcGF0aCBhIGNoYXJ0IHdhcyByZWFkIGF0ICh0aGUgcGF0aCBpdHNcbiAgLy8gYW5zd2VyIGFwcGxpZWQpLCBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlOyBhYnNlbnQgYXQgdGhlIGNoYXJ0J3MgdG9wLlxuICBjcnVtYnM/OiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0ZWRQYWdlIHtcbiAgcGFnZTogUmVwb3J0UGFnZTtcbiAgY29tcG9uZW50czogQ29sbGVjdGVkQ29tcG9uZW50W107XG4gIC8vIFdoYXQgdGhlIHBhZ2UncyB0ZXh0IGJsb2NrcyBmaWxsIHRoZWlyIHt7dmFsdWUuPGtleT59fSB0b2tlbnMgd2l0aCwgYnkga2V5XG4gIC8vICh0ZXh0VmFsdWVzKSwgYW5kIHRoZSBrZXlzIG9mIHRoZSB2YWx1ZXMgaXRzIHRleHQgc2hvd3Mgd2hvc2UgbnVtYmVycyBkaWRcbiAgLy8gbm90IGNvbWUgYmFjazogdGhlIHJlcXVlc3QgZmFpbGVkLCBvciB0aGUgdmFsdWUncyBvd24gcXVlcnkgZGlkLlxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIFRleHRWYWx1ZT47XG4gIGZhaWxlZFZhbHVlczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sbGVjdGVkUmVwb3J0IHtcbiAgcmVwb3J0OiBSZXBvcnQ7XG4gIHBhZ2VzOiBDb2xsZWN0ZWRQYWdlW107XG4gIC8vIFRoZSBoZWFkZXIgYW5kIGZvb3RlcidzIHZhbHVlcywgYXMgYSBwYWdlJ3M6IHJlYWQgb25jZSBmb3IgdGhlIHdob2xlXG4gIC8vIGZpbGUsIHNpbmNlIGV2ZXJ5IHBhZ2UgdGhhdCBzaG93cyB0aGUgbWFzdGVyIHNob3dzIHRoZSBzYW1lIG51bWJlcnMuXG4gIG1hc3RlclZhbHVlczogUmVjb3JkPHN0cmluZywgVGV4dFZhbHVlPjtcbiAgbWFzdGVyRmFpbGVkVmFsdWVzOiBzdHJpbmdbXTtcbiAgLy8gVGhlIGZpbHRlciBsaW5lcyBvZiB0aGUgdGl0bGUgc2xpZGUvcGFnZSwgaW4gb3JkZXI6IHRoZSBvcGVuIHZpZXcsIHRoZVxuICAvLyBleHBvcnQncyBmaWx0ZXIgbGluZXMgKGNvdmVyRmlsdGVyTGluZXMpLCB0aGVuIHRoZSBtYXRjaCB3aGlsZSBpdCBpc1xuICAvLyAnYW55Jy5cbiAgZmlsdGVyU3VtbWFyeTogc3RyaW5nW107XG4gIC8vIFdoYXQgdGhlIG51bWJlcnMgYXJlIG1lYXN1cmVkIGluLCBmb3IgdGhlIHRpdGxlIHNsaWRlL3BhZ2U6IHRoZSB6b25lIGFuZFxuICAvLyB0aGUgY3VycmVuY3kgdGhlIHNlcnZlciByZXNvbHZlZCBmb3IgdGhlIHJlcG9ydC4gRWFjaCBpcyBsZWZ0IG91dCB3aGVuIHRoZVxuICAvLyBzZXJ2ZXIgZG9lcyBub3Qgc2VuZCBpdCwgcmF0aGVyIHRoYW4gYSBndWVzcyB0aGF0IHdvdWxkIGJlIHdyb25nIHdoZW5ldmVyXG4gIC8vIHRoZSBkZWZhdWx0IGFwcGxpZXMuXG4gIGNvbnRleHRMaW5lczogc3RyaW5nW107XG4gIC8vIEhvdyB0aGUgb3BlbiByZXBvcnQgd3JpdGVzIGl0cyBudW1iZXJzIGFuZCBkYXRlcyAoaXRzIGxvY2FsZSwgY3VycmVuY3lcbiAgLy8gYW5kIHBlcmNlbnQgZm9ybSksIHJlYWQgb25jZSBzbyBldmVyeSBwYWdlIG9mIHRoZSBmaWxlIGFncmVlcy5cbiAgZm9ybWF0Q29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dDtcbn1cblxuLy8gQSB0ZXh0IGJsb2NrIHdob3NlIHdvcmRzIGRvIG5vdCBmaXQgaXRzIGJveCBpbiBhIGJ1aWx0IGZpbGU6IHRoZSBibG9jaywgdGhlXG4vLyBwYWdlIHRoZSBvdmVyZmxvdyBnYXRlIG5hbWVzIGl0IHVuZGVyIChIRUFERVJfRk9PVEVSX05BTUUgZm9yIGEgaGVhZGVyIG9yXG4vLyBmb290ZXIgYmxvY2spIGFuZCB0aGUgc3RhcnQgb2YgaXRzIHRleHQsIHNvIHRoZSByZWFkZXIgY2FuIGZpbmQgaXQuXG5leHBvcnQgaW50ZXJmYWNlIFRleHRPdmVyZmxvdyB7XG4gIGNvbXBvbmVudElkOiBudW1iZXI7XG4gIHBhZ2U6IHN0cmluZztcbiAgc25pcHBldDogc3RyaW5nO1xufVxuXG4vLyBBIGZpbGUgYnVpbHQgYW5kIG5vdCB5ZXQgc2F2ZWQuIFdoZXRoZXIgdGV4dCBmaXRzIGl0cyBib3ggaXMga25vd24gb25seSBvbmNlXG4vLyB0aGUgZmlsZSBpcyBidWlsdCwgc28gdGhlIGV4cG9ydCBhc2tzIGFib3V0IHRoZSBvdmVyZmxvd3MgYmV0d2VlbiB0aGUgYnVpbGRcbi8vIGFuZCB0aGUgc2F2ZTogYG92ZXJmbG93Tm90ZWAgc2F5cyB3aGF0IHRoaXMgZm9ybWF0IGRvZXMgd2l0aCBzdWNoIHRleHQsIGFuZFxuLy8gYHNhdmVgIHdyaXRlcyB0aGUgZmlsZS5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbHRFeHBvcnQge1xuICBvdmVyZmxvd3M6IFRleHRPdmVyZmxvd1tdO1xuICBvdmVyZmxvd05vdGU6IHN0cmluZztcbiAgc2F2ZTogKCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG59XG5cbi8vIE9uZSBleHBvcnRlZCBsaXN0IGNvbHVtbjogdGhlIGNlbGwga2V5LCBpdHMgaGVhZGluZyBhbmQgaXRzIGZvcm1hdCwgYW5kXG4vLyB3aGV0aGVyIGl0cyBjZWxscyBhcmUgZm9ybWF0dGVkIG51bWJlcnMsIHdoaWNoIGV2ZXJ5IGV4cG9ydCByaWdodC1hbGlnbnNcbi8vIChoZWFkZXIgaW5jbHVkZWQpIGFzIHRoZSBzY3JlZW4gZG9lcy4gQSBjb2x1bW4gdGhhdCBob2xkcyBhIGNvbXBhcmVkLFxuLy8gd2luZG93ZWQsIHJhbmtlZCBvciBzaGFyZWQgb3V0cHV0IGNhcnJpZXMgaG93IGl0IGlzIHdyaXR0ZW4gKG91dHB1dCksIGFuZFxuLy8gaG9sZHMgbnVtYmVycyB3aGV0aGVyIG9yIG5vdCBpdCBuYW1lcyBhIGZvcm1hdC5cbmV4cG9ydCB0eXBlIEV4cG9ydExpc3RDb2x1bW4gPSBMaXN0Q29sdW1uICYgeyBudW1lcmljOiBib29sZWFuOyBvdXRwdXQ/OiBMaXN0T3V0cHV0Q29sdW1uIH07XG5cbi8vIEhvdyB0YWxsIGVhY2ggcGFydCBvZiBhbiBleHBvcnRlZCBLUEkgY2FyZCBpcywgaW4gdGhlIHJlbmRlcmVyJ3MgdW5pdFxuLy8gKHBvaW50cyBpbiB0aGUgUERGLCBpbmNoZXMgaW4gdGhlIGRlY2spLiBBIG5vdGUgaXMgb25lIGxpbmUuXG5leHBvcnQgaW50ZXJmYWNlIEtwaUV4cG9ydEhlaWdodHMge1xuICB2YWx1ZTogbnVtYmVyO1xuICBsYWJlbDogbnVtYmVyO1xuICBkZWx0YTogbnVtYmVyO1xuICB3aW5kb3c6IG51bWJlcjtcbiAgdGFyZ2V0OiBudW1iZXI7XG4gIHNwYXJrbGluZTogbnVtYmVyO1xuICBub3RlOiBudW1iZXI7XG59XG5cbi8vIFRoZSBwYXJ0cyBvZiBhIEtQSSBjYXJkIGFuIGV4cG9ydCBkcmF3czogdGhlIHZhbHVlIGFuZCBpdHMgbGFiZWwgYWx3YXlzLFxuLy8gdGhlIHJlc3Qgd2hlbiB0aGUgY2FyZCBoYXMgdGhlbSBhbmQgdGhlIHRpbGUgaGFzIHJvb20gKGtwaUV4cG9ydFBhcnRzKS5cbi8vIHNjYWxlIHNocmlua3MgdGhlIHJvd3MgYW5kIHRoZWlyIHRleHQgd2hlbiB0aGUgcGFydHMgdGhhdCBhbHdheXMgc3RheSBzdGlsbFxuLy8gc3RhbmQgdGFsbGVyIHRoYW4gdGhlIHRpbGUgKHNjYWxlZEtwaUhlaWdodHMpOiAxIHdoZW4gdGhleSBmaXQuXG5leHBvcnQgaW50ZXJmYWNlIEtwaUV4cG9ydFBhcnRzIHtcbiAgZGVsdGE6IGJvb2xlYW47XG4gIHdpbmRvdzogYm9vbGVhbjtcbiAgdGFyZ2V0OiBib29sZWFuO1xuICBzcGFya2xpbmU6IGJvb2xlYW47XG4gIG5vdGVzOiBzdHJpbmdbXTtcbiAgc2NhbGU6IG51bWJlcjtcbn1cblxuLy8gSG93IGZhciBhIEtQSSBjYXJkJ3Mgcm93cyBzaHJpbmsgdG8gZml0IGEgc2hvcnQgdGlsZS4gQSB0aWxlIHNob3J0ZXIgc3RpbGxcbi8vIGxldHMgdGhlIGNhcmQgcnVuIHBhc3QgaXRzIGZvb3QgcmF0aGVyIHRoYW4gcHJpbnQgaXQgdW5yZWFkYWJseSBzbWFsbC5cbmNvbnN0IEtQSV9FWFBPUlRfTUlOX1NDQUxFID0gMC41O1xuXG4vLyBIb3cgbWFueSB0aWxlIHF1ZXJpZXMgYW4gZXhwb3J0IHJ1bnMgYXQgb25jZS5cbi8vXG4vLyBOb3QgYSBwb2xpdGVuZXNzIHNldHRpbmcg4oCUIGl0IGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYSBkZWNrIGFuZCBhIGJyb2tlblxuLy8gb25lLiBUaGVzZSBxdWVyaWVzIGFyZSBoZWF2eSBhbmQgcmVhZCB0aGUgc2FtZSB0YWJsZXMsIHNvIGZpcmluZyBhbGwgb2YgdGhlbVxuLy8gdG9nZXRoZXIgcHV0cyBldmVyeSBvbmUgaW4gY29udGVudGlvbiBmb3IgdGhlIHNhbWUgZGF0YWJhc2UgYXQgdGhlIHNhbWVcbi8vIG1vbWVudCBhbmQgdGhleSBjcm9zcyB0aGUgc3RhdGVtZW50IGNlaWxpbmcgYXMgYSBncm91cDogbWVhc3VyZWQgb24gcmVwb3J0XG4vLyAyOCwgdGVuIHRpbGVzIHRoYXQgZWFjaCBhbnN3ZXIgaW4gOS0yNHMgcnVuIG9uZSBhZnRlciBhbm90aGVyIGFsbCBmYWlsZWQgYXRcbi8vIH4zMHMgd2hlbiByZWxlYXNlZCB0b2dldGhlci4gQ29uY3VycmVuY3kgYnV5cyB3YWxsLWNsb2NrIG9ubHkgdXAgdG8gdGhlIHBvaW50XG4vLyB3aGVyZSB0aGUgcXVlcmllcyBzdGFydCB0YWtpbmcgaXQgYmFjayBvZmYgZWFjaCBvdGhlciwgYW5kIHBhc3QgdGhhdCBpdCBidXlzXG4vLyBmYWlsdXJlcy5cbmNvbnN0IEVYUE9SVF9DT05DVVJSRU5DWSA9IDM7XG5cbi8vIFdoYXQgdGhlIGV4cG9ydCBnYXRlcyBjYWxsIHRoZSBoZWFkZXIgYW5kIGZvb3Rlcjogd2hlbiBhIHZhbHVlIHRoZXkgc2hvd1xuLy8gY2FtZSBiYWNrIHdpdGhvdXQgaXRzIG51bWJlciwgYW5kIHdoZW4gb25lIG9mIHRoZWlyIHRleHQgYmxvY2tzIGRvZXMgbm90XG4vLyBmaXQgaXRzIGJveC5cbmV4cG9ydCBjb25zdCBIRUFERVJfRk9PVEVSX05BTUUgPSAnSGVhZGVyICYgZm9vdGVyJztcblxuLy8gSG93IG11Y2ggb2YgYSB0ZXh0IGJsb2NrJ3Mgd29yZHMgdGhlIGV4cG9ydCBnYXRlcyBxdW90ZSB0byBuYW1lIGEgYmxvY2sgdGhhdFxuLy8gZG9lcyBub3QgZml0IGl0cyBib3guXG5jb25zdCBPVkVSRkxPV19TTklQUEVUX0xFTkdUSCA9IDQwO1xuXG4vLyBPbmUgcmVxdWVzdCBpbiBhbiBleHBvcnQncyBxdWV1ZTogYSB0aWxlJ3MgZGF0YSwgb3IgdGhlIG51bWJlcnMgb2YgdGhlXG4vLyB2YWx1ZXMgb25lIGxheWVyJ3MgdGV4dCByZWFkcywgcmVhZCB0b2dldGhlci4gQSB2YWx1ZXMgam9iJ3MgcGFnZUluZGV4IGlzXG4vLyBudWxsIGZvciB0aGUgaGVhZGVyIGFuZCBmb290ZXIgKHRoZSBtYXN0ZXIpOyBgdmFsdWVzYCBpcyBldmVyeSB2YWx1ZSBvZiB0aGVcbi8vIGxheWVyLCB3aGljaCBuYW1lcyBpdHMgdG9rZW5zIGFuZCB3aG9zZSBmaWx0ZXIgdmFsdWVzIHRoZSByZXF1ZXN0IGNhcnJpZXMsXG4vLyBhbmQgYGNvbXBvbmVudHNgIHRoZSBvbmVzIGl0cyB0ZXh0IHNob3dzLCB3aG9zZSBudW1iZXJzIHRoZSBmYWlsdXJlIGdhdGVcbi8vIHJlcXVpcmVzLlxudHlwZSBDb2xsZWN0Sm9iID1cbiAgfCB7IGtpbmQ6ICdjb21wb25lbnQnOyBwYWdlSW5kZXg6IG51bWJlcjsgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQgfVxuICB8IHtcbiAgICBraW5kOiAndmFsdWVzJztcbiAgICBwYWdlSW5kZXg6IG51bWJlciB8IG51bGw7XG4gICAgcGFnZUlkOiBudW1iZXI7XG4gICAgdmFsdWVzOiBSZXBvcnRDb21wb25lbnRbXTtcbiAgICBjb21wb25lbnRzOiBSZXBvcnRDb21wb25lbnRbXTtcbiAgfTtcblxuLy8gT25lIGxheWVyJ3MgdmFsdWVzIGFzIHRoZSBmaWxlIHByaW50cyB0aGVtLlxudHlwZSBDb2xsZWN0ZWRWYWx1ZXMgPSBQaWNrPENvbGxlY3RlZFBhZ2UsICd2YWx1ZXMnIHwgJ2ZhaWxlZFZhbHVlcyc+O1xuXG4vLyBXaGF0IGEgam9iIGNhbWUgYmFjayB3aXRoLCBhbmQgdGhlIHBhZ2UgaXQgaXMgZmlsZWQgdW5kZXIuXG50eXBlIENvbGxlY3RSZXN1bHQgPVxuICB8IHsga2luZDogJ2NvbXBvbmVudCc7IHBhZ2VJbmRleDogbnVtYmVyOyBpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQgfVxuICB8IHsga2luZDogJ3ZhbHVlcyc7IHBhZ2VJbmRleDogbnVtYmVyIHwgbnVsbDsgY29sbGVjdGVkOiBDb2xsZWN0ZWRWYWx1ZXMgfTtcblxuLy8gV2hhdCBhIGNvbXBvbmVudCB3aXRoIG5vdGhpbmcgdG8gZHJhdyBwcmludHMgaW4gdGhlIGV4cG9ydGVkIGZpbGUuXG4vL1xuLy8gVGhlIHR3byBjYXNlcyBtdXN0IG5vdCByZWFkIGFsaWtlLiBBIHRpbGUgdGhhdCByZXR1cm5lZCBubyByb3dzIGlzIGEgZmluZGluZ1xuLy8gYWJvdXQgdGhlIHBlcmlvZCDigJQgdGhlIHJlcG9ydCB3b3JrZWQgYW5kIHRoZSBhbnN3ZXIgaXMgXCJub25lXCIuIEEgdGlsZSB3aG9zZVxuLy8gcXVlcnkgZmFpbGVkIGlzIGEgaG9sZSBpbiB0aGUgZmlsZSwgYW5kIGNhbGxpbmcgdGhhdCBcIkRhdGEgdW5hdmFpbGFibGVcIiB0ZWxsc1xuLy8gdGhlIHJlYWRlciB0aGUgZGF0YSBkb2VzIG5vdCBleGlzdCB3aGVuIHdoYXQgaGFwcGVuZWQgaXMgdGhhdCBub2JvZHkgbWFuYWdlZFxuLy8gdG8gYXNrIGZvciBpdC4gU2hhcmVkIGJ5IGJvdGggcmVuZGVyZXJzIHNvIHRoZSBQREYgYW5kIHRoZSBkZWNrIGNhbm5vdCBlbmQgdXBcbi8vIGRlc2NyaWJpbmcgdGhlIHNhbWUgaG9sZSB0d28gZGlmZmVyZW50IHdheXMuXG5leHBvcnQgZnVuY3Rpb24gZW1wdHlMYWJlbChpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQpOiBzdHJpbmcge1xuICByZXR1cm4gaXRlbS5kYXRhID8gJ05vIGRhdGEnIDogJ0NvdWxkIG5vdCBiZSBnZW5lcmF0ZWQnO1xufVxuXG4vLyBBIGNvbXBvbmVudCdzIHRpdGxlIGFzIGFuIGV4cG9ydGVkIGZpbGUgcHJpbnRzIGl0LiBBIGRyaWxsZWQgY2hhcnQncyB0aXRsZVxuLy8gaXMgZm9sbG93ZWQgYnkgaXRzIGJyZWFkY3J1bWIsIGBjcnVtYnNgIChkcmlsbENydW1iTGFiZWxzKTogJ09yZGVycyBieVxuLy8gUGVyaW9kIOKAuiAyMDI2IOKAuiBRMycuIEEgc2VhcmNoZWQgbGlzdCBzYXlzIHNvLCBzaW5jZSBpdHMgdGFibGUgaG9sZHMgb25seVxuLy8gdGhlIG1hdGNoaW5nIHJvd3M6ICdPcmRlcnMgKG1hdGNoaW5nIFwibm9ydGhcIiknLiBBbiB1bnRpdGxlZCBvbmUgcmVhZHNcbi8vICdNYXRjaGluZyBcIm5vcnRoXCInLiAnJyB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgdG8gcHJpbnQuIFNoYXJlZCBieSB0aGUgUERGXG4vLyBhbmQgdGhlIGRlY2ssIGNvbnRpbnVhdGlvbiBwYWdlcyBpbmNsdWRlZC5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRUaXRsZShcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIHNlYXJjaD86IHN0cmluZyB8IG51bGwsXG4gIGNydW1icz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHRpdGxlID0gY3J1bWJlZFRpdGxlKGNvbXBvbmVudC50aXRsZSwgY3J1bWJzID8/IFtdKTtcblxuICBpZiAoIXNlYXJjaCkge1xuICAgIHJldHVybiB0aXRsZTtcbiAgfVxuXG4gIHJldHVybiB0aXRsZSA/IGAke3RpdGxlfSAobWF0Y2hpbmcgXCIke3NlYXJjaH1cIilgIDogYE1hdGNoaW5nIFwiJHtzZWFyY2h9XCJgO1xufVxuXG4vLyBXaGV0aGVyIGEgdGlsZSdzIHF1ZXJ5IGZhaWxlZC4gQSB0ZXh0IGJsb2NrIGhhcyBubyBxdWVyeSwgc28gaXQgbmV2ZXIgZGlkLlxuZXhwb3J0IGZ1bmN0aW9uIGlzRmFpbGVkKGl0ZW06IENvbGxlY3RlZENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gIWl0ZW0uZGF0YSAmJiBpdGVtLmNvbXBvbmVudC50eXBlICE9PSAndGV4dCc7XG59XG5cbi8vIEEgdGV4dCBibG9jayB0aGF0IGRvZXMgbm90IGZpdCBpdHMgYm94IGluIGEgYnVpbHQgZmlsZSwgYXMgdGhlIG92ZXJmbG93IGdhdGVcbi8vIG5hbWVzIGl0OiB1bmRlciBpdHMgcGFnZSAoSEVBREVSX0ZPT1RFUl9OQU1FIGZvciBhIGhlYWRlciBvciBmb290ZXIgYmxvY2spXG4vLyBhbmQgYnkgdGhlIHN0YXJ0IG9mIGl0cyB3b3Jkcywgb24gb25lIGxpbmUuIFNoYXJlZCBieSB0aGUgUERGIGFuZCB0aGUgZGVjay5cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0T3ZlcmZsb3coY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHBhZ2U6IHN0cmluZywgdG9rZW5zOiBUZXh0VG9rZW5Db250ZXh0KTogVGV4dE92ZXJmbG93IHtcbiAgY29uc3QgdGV4dCA9IHRleHRQbGFpbihjb21wb25lbnQuY29uZmlnPy5odG1sID8/ICcnLCB0b2tlbnMpLnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG5cbiAgcmV0dXJuIHtcbiAgICBjb21wb25lbnRJZDogY29tcG9uZW50LmlkLFxuICAgIHBhZ2UsXG4gICAgc25pcHBldDogdGV4dC5sZW5ndGggPiBPVkVSRkxPV19TTklQUEVUX0xFTkdUSCA/IGAke3RleHQuc2xpY2UoMCwgT1ZFUkZMT1dfU05JUFBFVF9MRU5HVEgpLnRyaW1FbmQoKX3igKZgIDogdGV4dCxcbiAgfTtcbn1cblxuLy8gVGhlIGxpbmVzIHVuZGVyIHRoZSByZXBvcnQncyBuYW1lIG9uIHRoZSBQREYgdGl0bGUgcGFnZSBhbmQgdGhlIHRpdGxlIHNsaWRlOlxuLy8gdGhlIGV4cG9ydCBkYXRlLCB0aGUgYWN0aXZlIGZpbHRlcnMsIHRoZW4gd2hhdCB0aGUgbnVtYmVycyBhcmUgbWVhc3VyZWQgaW4uXG4vLyBUaGUgZGF0ZSBhbHdheXMgbGVhZHMgKHRoZSBQb3dlclBvaW50IG1hcmtzIHRoYXQgbGluZSBhcyB3cml0dGVuIGluIHRoZVxuLy8gcmVwb3J0J3MgbG9jYWxlKS4gSXQgaXMgdG9kYXkgaW4gdGhlIHJlcG9ydCdzIHpvbmUsIHRoZSBzYW1lIGRheSBpdHMgZmlsdGVyc1xuLy8gcmVzb2x2ZSBcInRvZGF5XCIgdG8sIHdyaXR0ZW4gaW4gdGhlIHJlcG9ydCdzIGxvY2FsZS5cbmV4cG9ydCBmdW5jdGlvbiBjb3ZlckxpbmVzKGNvbGxlY3RlZDogQ29sbGVjdGVkUmVwb3J0KTogc3RyaW5nW10ge1xuICByZXR1cm4gW1xuICAgIGZvcm1hdExvY2FsRGF0ZShcbiAgICAgIG5ldyBEYXRlKCksXG4gICAgICBjb2xsZWN0ZWQuZm9ybWF0Q29udGV4dC5sb2NhbGUsXG4gICAgICBEQVlfTE9ORyxcbiAgICAgIHJlc29sdmVSZXBvcnRUaW1lem9uZShjb2xsZWN0ZWQucmVwb3J0KSxcbiAgICApLFxuICAgIC4uLmNvbGxlY3RlZC5maWx0ZXJTdW1tYXJ5LFxuICAgIC4uLmNvbGxlY3RlZC5jb250ZXh0TGluZXMsXG4gIF07XG59XG5cbi8vIEFuIGV4cG9ydGVkIGxpc3QgY2VsbCwgcmVhZGluZyBsaWtlIHRoZSBvbi1zY3JlZW4gY2VsbCwgdGhyb3VnaCB0aGUgc2FtZVxuLy8gZnVuY3Rpb25zIGFzIHRoZSBzY3JlZW46IGEgZGF0ZSBjb2x1bW4gcmVuZGVycyBpbiB0aGUgcmVwb3J0J3Mgem9uZSBhbmRcbi8vIGxvY2FsZSwgYW5kIGEgY29sdW1uIHdpdGggbnVtYmVyLWZvcm1hdCBrZXlzIChhIGNyb3NzLXRhYidzIGNlbGxzIHRocm91Z2hcbi8vIGl0cyBjZWxsRm9ybWF0KSBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlIGFuZCBjdXJyZW5jeS4gQW55IG90aGVyIHZhbHVlIGdvZXNcbi8vIG91dCB2ZXJiYXRpbSwgYW5kIGFuIGVtcHR5IG9uZSBhcyAnJy4gQ1NWIG5ldmVyIGNvbWVzIHRocm91Z2ggaGVyZTogaXRzXG4vLyB2YWx1ZXMgc3RheSByYXcuXG4vL1xuLy8gQW4gb3V0cHV0IGNvbHVtbiBpcyB3cml0dGVuIGJ5IHdoYXQgaXQgaG9sZHMsIGFzIHRoZSBzY3JlZW4ncyBjZWxsIGlzXG4vLyAoZm9ybWF0T3V0cHV0VmFsdWUpOiBhIHNpZ25lZCBjaGFuZ2UsIGEgcGVyY2VudCBjaGFuZ2UsIGEgY2hhbmdlIG9mIGEgcmF0ZVxuLy8gaW4gcG9pbnRzLCBhIHJhbmssIGEgc2hhcmUuIEl0cyByb3cgZ2l2ZXMgYSBjaGFuZ2UgdGhlIHByaW9yIGJlc2lkZSBpdCwgc29cbi8vIGEgbWlzc2luZyBiYXNlbGluZSAoJ+KAlCcpIHJlYWRzIGFwYXJ0IGZyb20gYSB6ZXJvIG9uZSAoJ24vYScpLlxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydENlbGwoXG4gIHZhbHVlOiB1bmtub3duLFxuICBjb2x1bW46IExpc3RDb2x1bW4gJiB7IG91dHB1dD86IExpc3RPdXRwdXRDb2x1bW4gfSxcbiAgdGltZXpvbmU6IHN0cmluZyxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgcm93PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsLFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgb3V0cHV0ID0gY29sdW1uLm91dHB1dDtcblxuICBpZiAob3V0cHV0KSB7XG4gICAgcmV0dXJuIGZvcm1hdE91dHB1dFZhbHVlKHZhbHVlLCBvdXRwdXQub3V0cHV0LCBjb2x1bW4sIGNvbnRleHQsIHtcbiAgICAgIG1lYXN1cmVTcGVjOiBvdXRwdXQubWVhc3VyZVNwZWMsXG4gICAgICBwcmlvcjogb3V0cHV0LnByaW9yQWxpYXMgJiYgcm93ID8gcm93W291dHB1dC5wcmlvckFsaWFzXSA6IHVuZGVmaW5lZCxcbiAgICAgIGZsb29yOiBvdXRwdXQuZmxvb3IsXG4gICAgICBlbXB0eTogJycsXG4gICAgfSkudGV4dDtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgaWYgKGNvbHVtbi5mb3JtYXQgPT09IFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQuRGF0ZSkge1xuICAgIHJldHVybiBmb3JtYXRSZXBvcnREYXRlKHZhbHVlLCB0aW1lem9uZSwgY29udGV4dC5sb2NhbGUpO1xuICB9XG5cbiAgcmV0dXJuIGhhc051bWJlckZvcm1hdChjb2x1bW4pID8gZm9ybWF0TnVtYmVyKHZhbHVlLCBjb2x1bW4sIGNvbnRleHQsIHsgZW1wdHk6ICcnIH0pIDogU3RyaW5nKHZhbHVlKTtcbn1cblxuLy8gVGhlIGNvbHVtbnMgYW4gZXhwb3J0ZWQgbGlzdCB0YWJsZSBkcmF3cy4gQSBjcm9zcy10YWIncyBhcnJpdmUgd2l0aCBpdHNcbi8vIHJvd3MgKHRoZSByb3cga2V5IGZpcnN0LCB0aGVuIG9uZSBwZXIgcGl2b3QgdmFsdWUpLCBzaW5jZSBvbmx5IHRoZSByZXN1bHRcbi8vIGtub3dzIHRoZSBwaXZvdCB2YWx1ZXMsIGFuZCBhcmUgYnVpbHQgYnkgcGl2b3RDb2x1bW5TcGVjcygpIGFzIG9uIHNjcmVlbjpcbi8vIGhlYWRlZCBieSBpdHMgcGVyaW9kcyBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlLCBlYWNoIHBpdm90IHZhbHVlIGZvcm1hdHRlZCBieVxuLy8gY2VsbEZvcm1hdC4gQSBwbGFpbiBsaXN0IGRyYXdzIGl0cyBjb25maWd1cmVkIGNvbHVtbnMgYnV0IHRoZSBvbmVzIHRoZVxuLy8gdmlld2VyIGhpZCAoYGhpZGRlbmAsIGtlcHQgdG8gbGlzdEhpZGRlbkNvbHVtbnMsIHNvIG5ldmVyIGFsbCBvZiB0aGVtKSxcbi8vIGVsc2UgZXZlcnkgY29sdW1uIHRoZSBxdWVyeSByZXR1cm5lZCwgYXMgaXQgY2FtZS4gT3V0cHV0IGNvbHVtbnMgKHRoZVxuLy8gZGF0YSdzIG91dHB1dHMsIGEgY3Jvc3MtdGFiIGNlbGwgdGhyb3VnaCBjZWxsTWVhc3VyZXMpIGNhcnJ5IGhvdyB0aGV5IGFyZVxuLy8gd3JpdHRlbjsgd2l0aG91dCB0aG9zZSBrZXlzIHRoZSBjb2x1bW5zIGFyZSBleGFjdGx5IGFzIGJlZm9yZS5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0Q29sdW1ucyhcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuICBoaWRkZW46IHJlYWRvbmx5IHN0cmluZ1tdID0gW10sXG4pOiBFeHBvcnRMaXN0Q29sdW1uW10ge1xuICBjb25zdCBjb25maWcgPSAoY29tcG9uZW50LmNvbmZpZyA/PyB7fSkgYXMgTGlzdENvbmZpZztcblxuICBpZiAoY29uZmlnLnBpdm90Qnk/LmNvbHVtbikge1xuICAgIHJldHVybiB3aXRoT3V0cHV0Q29sdW1ucyhwaXZvdENvbHVtblNwZWNzKGNvbmZpZywgZGF0YSwgbG9jYWxlKSwgZGF0YSwgW10pO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5jb2x1bW5zPy5sZW5ndGgpIHtcbiAgICBjb25zdCBoaWRkZW5OYW1lcyA9IGxpc3RIaWRkZW5Db2x1bW5zKGNvbmZpZywgaGlkZGVuKTtcblxuICAgIHJldHVybiB3aXRoT3V0cHV0Q29sdW1ucyhcbiAgICAgIGNvbmZpZy5jb2x1bW5zXG4gICAgICAgIC5maWx0ZXIoKGNvbHVtbikgPT4gIWhpZGRlbk5hbWVzLmluY2x1ZGVzKGNvbHVtbi5jb2x1bW4pKVxuICAgICAgICAubWFwKChjb2x1bW4pID0+ICh7IC4uLmNvbHVtbiwgbnVtZXJpYzogaGFzTnVtYmVyRm9ybWF0KGNvbHVtbikgfSkpLFxuICAgICAgZGF0YSxcbiAgICAgIGNvbmZpZy5jb2x1bW5zLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gd2l0aE91dHB1dENvbHVtbnMoZGF0YS5jb2x1bW5zLm1hcCgoY29sdW1uKSA9PiAoeyBjb2x1bW4sIG51bWVyaWM6IGZhbHNlIH0pKSwgZGF0YSwgW10pO1xufVxuXG4vLyBUaGUgY29sdW1ucyB3aXRoIHRoZWlyIG91dHB1dCBtZXRhZGF0YSBhdHRhY2hlZCAobGlzdE91dHB1dENvbHVtbnMsIGFzIHRoZVxuLy8gc2NyZWVuJ3MgbGlzdCByZXNvbHZlcyBpdCk6IGFuIG91dHB1dCBjb2x1bW4gaG9sZHMgbnVtYmVycyBhbmQgaXMgd3JpdHRlblxuLy8gYnkgd2hhdCBpdCBob2xkcy4gVW5jaGFuZ2VkIHdoZW4gdGhlIGRhdGEgaGFzIG5vIG91dHB1dHMuXG5mdW5jdGlvbiB3aXRoT3V0cHV0Q29sdW1ucyhcbiAgY29sdW1uczogRXhwb3J0TGlzdENvbHVtbltdLFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBhdXRob3JlZDogcmVhZG9ubHkgTGlzdENvbHVtbltdLFxuKTogRXhwb3J0TGlzdENvbHVtbltdIHtcbiAgaWYgKCFkYXRhLm91dHB1dHMpIHtcbiAgICByZXR1cm4gY29sdW1ucztcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHMgPSBsaXN0T3V0cHV0Q29sdW1ucyhjb2x1bW5zLCBkYXRhLCBhdXRob3JlZCk7XG5cbiAgcmV0dXJuIGNvbHVtbnMubWFwKChjb2x1bW4pID0+IChvdXRwdXRzW2NvbHVtbi5jb2x1bW5dXG4gICAgPyB7IC4uLmNvbHVtbiwgbnVtZXJpYzogdHJ1ZSwgb3V0cHV0OiBvdXRwdXRzW2NvbHVtbi5jb2x1bW5dIH1cbiAgICA6IGNvbHVtbikpO1xufVxuXG4vLyBUaGUgaGVhZGluZyBvdmVyIGVhY2ggY29sdW1uIG9mIGxpc3RDb2x1bW5zKCk6IGEgcGxhaW4gbGlzdCdzIGNvbmZpZ3VyZWRcbi8vIGxhYmVsLCBlbHNlIGl0cyBjb2x1bW47IGEgY3Jvc3MtdGFiJ3MgaGVhZGluZyBmcm9tIHBpdm90Q29sdW1uU3BlY3MoKS5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0SGVhZGluZ3MoXG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgaGlkZGVuOiByZWFkb25seSBzdHJpbmdbXSA9IFtdLFxuKTogc3RyaW5nW10ge1xuICByZXR1cm4gbGlzdENvbHVtbnMoY29tcG9uZW50LCBkYXRhLCBsb2NhbGUsIGhpZGRlbikubWFwKChjb2x1bW4pID0+IGNvbHVtbi5sYWJlbCB8fCBjb2x1bW4uY29sdW1uKTtcbn1cblxuLy8gQW4gZXhwb3J0ZWQgbGlzdCdzIHRvdGFscyByb3csIG9uZSBjZWxsIHBlciBjb2x1bW4gb2YgbGlzdENvbHVtbnMoKTogZWFjaFxuLy8gdG90YWwgd3JpdHRlbiBsaWtlIGl0cyBjb2x1bW4ncyBjZWxscywgYW5kIExJU1RfVE9UQUxfTEFCRUwgaW4gdGhlIGZpcnN0XG4vLyBjb2x1bW4gd2hlbiB0aGF0IGNvbHVtbiBob2xkcyBubyB0b3RhbCAoYSBjcm9zcy10YWIncyByb3cga2V5KS4gbnVsbCB3aGVuXG4vLyB0aGUgbGlzdCBoYXMgbm8gdG90YWxzLiBUaGUgQ1NWIG5ldmVyIGNhcnJpZXMgb25lOiBpdHMgcm93cyBzdGF5IHJhdy5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0VG90YWxzUm93KFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBjb2x1bW5zOiByZWFkb25seSBFeHBvcnRMaXN0Q29sdW1uW10sXG4gIHRpbWV6b25lOiBzdHJpbmcsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBzdHJpbmdbXSB8IG51bGwge1xuICBjb25zdCB0b3RhbHMgPSBkYXRhLnRvdGFscztcblxuICBpZiAoIXRvdGFscykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgbGFiZWwgPSBsaXN0VG90YWxzTGFiZWxDb2x1bW4oY29sdW1ucywgdG90YWxzKTtcblxuICByZXR1cm4gY29sdW1ucy5tYXAoKGNvbHVtbikgPT4gKGNvbHVtbi5jb2x1bW4gPT09IGxhYmVsXG4gICAgPyBMSVNUX1RPVEFMX0xBQkVMXG4gICAgOiBleHBvcnRDZWxsKHRvdGFsc1tjb2x1bW4uY29sdW1uXSwgY29sdW1uLCB0aW1lem9uZSwgY29udGV4dCwgdG90YWxzKSkpO1xufVxuXG4vLyBUaGUgc3VidGl0bGUgdW5kZXIgYSBjaGFydCdzIG9yIGEgbGlzdCdzIHRpdGxlOiB0aGUgZGF5cyBpdCByZWFkcywgYW5kIHRoZVxuLy8gZGF5cyBlYWNoIGNvbXBhcmlzb24gbGFuZSByZWFkcyAoJ1NlcCAxIOKAkyAxNSwgMjAyNiDCtyB2cyBwcmV2aW91cyBtb250aDpcbi8vIEF1ZyAxIOKAkyAxNSwgMjAyNicpLCBhcyB0aGUgc2NyZWVuJ3Mgbm90ZSBvcGVucyB3aXRoLiAnJyB3aXRob3V0IGFcbi8vIGNvbXBhcmlzb24gb3IgYSB0aW1lZnJhbWUsIGFuZCBmb3IgYSBLUEksIHdob3NlIGNhcmQgcHJpbnRzIGl0cyBvd24gd2luZG93XG4vLyBsaW5lLlxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydFdpbmRvd3NMaW5lKGl0ZW06IENvbGxlY3RlZENvbXBvbmVudCwgdGltZXpvbmU6IHN0cmluZywgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcpOiBzdHJpbmcge1xuICBpZiAoIWl0ZW0uZGF0YSB8fCBpdGVtLmNvbXBvbmVudC50eXBlID09PSAna3BpJykge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRXaW5kb3dzTGluZShpdGVtLmRhdGEsIHsgbG9jYWxlLCB0aW1lem9uZSB9KTtcbn1cblxuLy8gVGhlIG5vdGUgbGluZXMgdW5kZXIgYSBjb21wb25lbnQncyBib3g6IHdoeSBhIGNvbXBhcmlzb24gcmVhZHMgYXMgaXQgZG9lcyxcbi8vIGEgS1BJJ3MgZGVsdGEgbm90ZSwgYW5kIHdoYXQgZWFjaCB3aW5kb3dlZCB2YWx1ZSBpcyBhbmQgd2h5LiBUaGUgZGF5cyBhcmVcbi8vIGxlZnQgb3V0ICh0aGUgc3VidGl0bGUgb3IgdGhlIEtQSSBjYXJkIHByaW50cyB0aGVtKSwgYW5kIHRoZSB3aW5kb3dcbi8vIGRlc2NyaXB0aW9ucyBhcmUgaW4sIHNpbmNlIGEgZmlsZSBoYXMgbm8gdG9vbHRpcCBvciBoZWFkZXIgdG8gY2FycnkgdGhlbS5cbi8vIEVtcHR5IHdoZW4gdGhlIGRhdGEgaGFzIG5vbmUgb2YgdGhlIGtleXMuXG5leHBvcnQgZnVuY3Rpb24gZXhwb3J0Tm90ZUxpbmVzKGl0ZW06IENvbGxlY3RlZENvbXBvbmVudCwgdGltZXpvbmU6IHN0cmluZywgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBjb21wb25lbnROb3RlTGluZXMoaXRlbS5kYXRhLCB7IGxvY2FsZSwgdGltZXpvbmUgfSwgeyB3aW5kb3dzOiBmYWxzZSwgd2luZG93RGVzY3JpcHRpb25zOiB0cnVlIH0pO1xufVxuXG4vLyBXaGV0aGVyIGEgS1BJIGNhcmQgaGFzIG1vcmUgdG8gZHJhdyB0aGFuIGl0cyB2YWx1ZSBhbmQgbGFiZWwuIFdpdGhvdXQsIGJvdGhcbi8vIGV4cG9ydHMgZHJhdyB0aGUgdGlsZSBleGFjdGx5IGFzIHRoZXkgYWx3YXlzIGhhdmUuXG5leHBvcnQgZnVuY3Rpb24ga3BpQ2FyZEhhc0V4dHJhcyh2aWV3OiBLcGlDYXJkVmlldywgbm90ZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gIHJldHVybiAhISh2aWV3LmRlbHRhIHx8IHZpZXcud2luZG93IHx8IHZpZXcudGFyZ2V0IHx8IHZpZXcuc3BhcmtsaW5lIHx8IG5vdGVzLmxlbmd0aCk7XG59XG5cbi8vIFdoaWNoIHBhcnRzIG9mIGEgS1BJIGNhcmQgZml0IGEgdGlsZSBgYXZhaWxhYmxlYCB0YWxsLiBBIHNob3J0IHRpbGUgc2hlZHMgdGhlXG4vLyBzcGFya2xpbmUgZmlyc3QsIHRoZW4gdGhlIHRhcmdldCBsaW5lLCB0aGVuIHRoZSBub3RlczsgdGhlIHZhbHVlLCBpdHMgbGFiZWxcbi8vIGFuZCB0aGUgZGVsdGEgcm93IGFsd2F5cyBzdGF5LCBhbmQgdGhlIHdpbmRvdyBsaW5lIHN0YXlzIHdoZW5ldmVyIHRoZSBjYXJkXG4vLyBzaG93cyBhIGNvbXBhcmlzb24gKGl0cyBkYXlzIGFyZSB3aGF0IHRoZSBkZWx0YSBpcyBtZWFzdXJlZCBvdmVyKS4gVGhlXG4vLyBzcGFya2xpbmUgbmVlZHMgdmFsdWVzIHRvIGRyYXcuIFdoZW4gd2hhdCBzdGF5cyBpcyBzdGlsbCB0b28gdGFsbCwgZXZlcnlcbi8vIHJvdyBzaHJpbmtzIGJ5IHRoZSBzYW1lIHNjYWxlLCBkb3duIHRvIEtQSV9FWFBPUlRfTUlOX1NDQUxFOyBieSB0aGVuIHRoZVxuLy8gc3BhcmtsaW5lLCB0aGUgdGFyZ2V0IGFuZCB0aGUgbm90ZXMgYXJlIGdvbmUuXG5leHBvcnQgZnVuY3Rpb24ga3BpRXhwb3J0UGFydHMoXG4gIHZpZXc6IEtwaUNhcmRWaWV3LFxuICBub3RlczogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGF2YWlsYWJsZTogbnVtYmVyLFxuICBoZWlnaHRzOiBLcGlFeHBvcnRIZWlnaHRzLFxuKTogS3BpRXhwb3J0UGFydHMge1xuICBjb25zdCBwYXJ0czogS3BpRXhwb3J0UGFydHMgPSB7XG4gICAgZGVsdGE6ICEhdmlldy5kZWx0YSxcbiAgICB3aW5kb3c6ICEhdmlldy53aW5kb3csXG4gICAgdGFyZ2V0OiAhIXZpZXcudGFyZ2V0LFxuICAgIHNwYXJrbGluZTogISF2aWV3LnNwYXJrbGluZT8udmFsdWVzLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSAhPT0gbnVsbCksXG4gICAgbm90ZXM6IFsuLi5ub3Rlc10sXG4gICAgc2NhbGU6IDEsXG4gIH07XG4gIGNvbnN0IGhlaWdodCA9ICgpID0+IGtwaUV4cG9ydEhlaWdodCh2aWV3LCBwYXJ0cywgaGVpZ2h0cyk7XG5cbiAgaWYgKGhlaWdodCgpID4gYXZhaWxhYmxlKSB7XG4gICAgcGFydHMuc3BhcmtsaW5lID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaGVpZ2h0KCkgPiBhdmFpbGFibGUpIHtcbiAgICBwYXJ0cy50YXJnZXQgPSBmYWxzZTtcbiAgfVxuXG4gIHdoaWxlIChoZWlnaHQoKSA+IGF2YWlsYWJsZSAmJiBwYXJ0cy5ub3Rlcy5sZW5ndGgpIHtcbiAgICBwYXJ0cy5ub3Rlcy5wb3AoKTtcbiAgfVxuXG4gIGlmIChoZWlnaHQoKSA+IGF2YWlsYWJsZSAmJiAhcGFydHMuZGVsdGEpIHtcbiAgICBwYXJ0cy53aW5kb3cgPSBmYWxzZTtcbiAgfVxuXG4gIGlmIChoZWlnaHQoKSA+IGF2YWlsYWJsZSkge1xuICAgIHBhcnRzLnNjYWxlID0gTWF0aC5tYXgoS1BJX0VYUE9SVF9NSU5fU0NBTEUsIE1hdGgubWF4KDAsIGF2YWlsYWJsZSkgLyBoZWlnaHQoKSk7XG4gIH1cblxuICByZXR1cm4gcGFydHM7XG59XG5cbi8vIFRoZSBoZWlnaHRzIHNjYWxlZCBieSB0aGUgcGFydHMnIHNjYWxlOiB3aGF0IHRoZSByZW5kZXJlciBsYXlzIHRoZSBjYXJkXG4vLyBvdXQgd2l0aCwgaXRzIHRleHQgc2l6ZWQgYnkgdGhlIHNhbWUgc2NhbGUuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVkS3BpSGVpZ2h0cyhoZWlnaHRzOiBLcGlFeHBvcnRIZWlnaHRzLCBzY2FsZTogbnVtYmVyKTogS3BpRXhwb3J0SGVpZ2h0cyB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IGhlaWdodHMudmFsdWUgKiBzY2FsZSxcbiAgICBsYWJlbDogaGVpZ2h0cy5sYWJlbCAqIHNjYWxlLFxuICAgIGRlbHRhOiBoZWlnaHRzLmRlbHRhICogc2NhbGUsXG4gICAgd2luZG93OiBoZWlnaHRzLndpbmRvdyAqIHNjYWxlLFxuICAgIHRhcmdldDogaGVpZ2h0cy50YXJnZXQgKiBzY2FsZSxcbiAgICBzcGFya2xpbmU6IGhlaWdodHMuc3BhcmtsaW5lICogc2NhbGUsXG4gICAgbm90ZTogaGVpZ2h0cy5ub3RlICogc2NhbGUsXG4gIH07XG59XG5cbi8vIEhvdyB0YWxsIHRoZSBjYXJkJ3MgZHJhd24gcGFydHMgc3RhbmQgdG9nZXRoZXIsIGluIHRoZSBoZWlnaHRzJyB1bml0LlxuZXhwb3J0IGZ1bmN0aW9uIGtwaUV4cG9ydEhlaWdodCh2aWV3OiBLcGlDYXJkVmlldywgcGFydHM6IEtwaUV4cG9ydFBhcnRzLCBoZWlnaHRzOiBLcGlFeHBvcnRIZWlnaHRzKTogbnVtYmVyIHtcbiAgcmV0dXJuIGhlaWdodHMudmFsdWVcbiAgICArICh2aWV3LmxhYmVsID8gaGVpZ2h0cy5sYWJlbCA6IDApXG4gICAgKyAocGFydHMuZGVsdGEgPyBoZWlnaHRzLmRlbHRhIDogMClcbiAgICArIChwYXJ0cy53aW5kb3cgPyBoZWlnaHRzLndpbmRvdyA6IDApXG4gICAgKyAocGFydHMudGFyZ2V0ID8gaGVpZ2h0cy50YXJnZXQgOiAwKVxuICAgICsgKHBhcnRzLnNwYXJrbGluZSA/IGhlaWdodHMuc3BhcmtsaW5lIDogMClcbiAgICArIHBhcnRzLm5vdGVzLmxlbmd0aCAqIGhlaWdodHMubm90ZTtcbn1cblxuLy8gVGhlIGxhc3Qgcm93IG9mIGFuIGV4cG9ydGVkIGxpc3QgdGFibGUgdGhhdCBzdG9wcyBzaG9ydCBvZiBpdHMgcmVzdWx0OiBob3dcbi8vIG1hbnkgcm93cyB0aGUgZmlsZSBsZWF2ZXMgb3V0IGFuZCB3aGVyZSB0aGUgd2hvbGUgc2V0IGNhbiBiZSBoYWQuIEVhY2hcbi8vIGZvcm1hdCBmZXRjaGVzIGl0cyBvd24gbnVtYmVyIG9mIHJvd3MgKFBERl9MSVNUX1JPV1MsIFBQVFhfTElTVF9ST1dTKSwgYW5kXG4vLyBib3RoIG5hbWUgd2hhdCBpcyBsZWZ0IHdpdGggdGhpcyBvbmUgc2VudGVuY2UuXG5leHBvcnQgZnVuY3Rpb24gbW9yZVJvd3NOb3RpY2UocmVtYWluaW5nOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYOKApiAke3JlbWFpbmluZ30gbW9yZSByb3cocykg4oCUIHVzZSB0aGUgY29tcG9uZW50J3MgQ1NWIGV4cG9ydCBmb3IgdGhlIGZ1bGwgZGF0YXNldGA7XG59XG5cbi8vIFRoZSBwYWdlcyBvZiBhIGNvbGxlY3RlZCByZXBvcnQgdGhhdCBoYXZlIGF0IGxlYXN0IG9uZSB0aWxlIHdob3NlIHF1ZXJ5XG4vLyBmYWlsZWQsIG9yIHdob3NlIHRleHQgc2hvd3MgYSB2YWx1ZSB0aGF0IGNhbWUgYmFjayB3aXRob3V0IGl0cyBudW1iZXIsIHRoZW5cbi8vIEhFQURFUl9GT09URVJfTkFNRSB3aGVuIHRoZSBoZWFkZXIgb3IgZm9vdGVyIHNob3dzIG9uZSBvbiBhIHBhZ2UgdGhhdCBzaG93c1xuLy8gdGhlIG1hc3RlciDigJQgd2hhdCB0aGUgZmFpbHVyZSBnYXRlIG5hbWVzIHRvIHRoZSB1c2VyLCBhbmQgd2hhdCBtYWtlcyBcInNvbWVcbi8vIG9mIHRoaXMgZmlsZSBpcyBtaXNzaW5nXCIgYSBmYWN0IHRoZSBjYWxsZXIgY2FuIGFjdCBvbiByYXRoZXIgdGhhbiBhIHRoaW5nXG4vLyB0aGV5IG5vdGljZSBpbiB0aGUgUERGIGFmdGVyd2FyZHMuXG5leHBvcnQgZnVuY3Rpb24gZmFpbGVkUGFnZU5hbWVzKGNvbGxlY3RlZDogQ29sbGVjdGVkUmVwb3J0KTogc3RyaW5nW10ge1xuICAvLyBOdW1iZXJlZCBiZWZvcmUgdGhlIGZpbHRlciDigJQgYW4gdW5uYW1lZCBwYWdlIDQgdGhhdCBmYWlsZWQgaGFzIHRvIHJlYWRcbiAgLy8gXCJQYWdlIDRcIiwgbm90IFwiUGFnZSAxXCIgYmVjYXVzZSBpdCBoYXBwZW5lZCB0byBiZSB0aGUgZmlyc3QgZmFpbHVyZS5cbiAgY29uc3QgbmFtZXMgPSBjb2xsZWN0ZWQucGFnZXNcbiAgICAubWFwKChwYWdlLCBpbmRleCkgPT4gKHsgcGFnZSwgbnVtYmVyOiBpbmRleCArIDEgfSkpXG4gICAgLmZpbHRlcigoeyBwYWdlIH0pID0+IHBhZ2UuY29tcG9uZW50cy5zb21lKGlzRmFpbGVkKVxuICAgICAgfHwgc2hvd3NGYWlsZWRWYWx1ZShwYWdlLmNvbXBvbmVudHMubWFwKChpdGVtKSA9PiBpdGVtLmNvbXBvbmVudCksIHBhZ2UuZmFpbGVkVmFsdWVzKSlcbiAgICAubWFwKCh7IHBhZ2UsIG51bWJlciB9KSA9PiBwYWdlLnBhZ2UubmFtZSB8fCBgUGFnZSAke251bWJlcn1gKTtcbiAgY29uc3QgbWFzdGVyID0gY29sbGVjdGVkLnJlcG9ydC5tYXN0ZXI7XG4gIGNvbnN0IHNob3dzTWFzdGVyID0gY29sbGVjdGVkLnBhZ2VzLnNvbWUoKHsgcGFnZSB9KSA9PiAhcGFnZS5tYXN0ZXJIaWRkZW4pO1xuXG4gIGlmIChtYXN0ZXIgJiYgc2hvd3NNYXN0ZXIgJiYgc2hvd3NGYWlsZWRWYWx1ZShtYXN0ZXIuY29tcG9uZW50cywgY29sbGVjdGVkLm1hc3RlckZhaWxlZFZhbHVlcykpIHtcbiAgICBuYW1lcy5wdXNoKEhFQURFUl9GT09URVJfTkFNRSk7XG4gIH1cblxuICByZXR1cm4gbmFtZXM7XG59XG5cbi8vIFdoZXRoZXIgYW55IG9mIHRoZSB0ZXh0IGJsb2NrcyBzaG93cyBvbmUgb2YgdGhlIGZhaWxlZCB2YWx1ZSBrZXlzLlxuZnVuY3Rpb24gc2hvd3NGYWlsZWRWYWx1ZShjb21wb25lbnRzOiBSZXBvcnRDb21wb25lbnRbXSwgZmFpbGVkOiByZWFkb25seSBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICBjb25zdCBzaG93biA9IG5ldyBTZXQoY29tcG9uZW50c1xuICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LnR5cGUgPT09ICd0ZXh0JylcbiAgICAuZmxhdE1hcCgoY29tcG9uZW50KSA9PiB2YWx1ZUtleXMoY29tcG9uZW50LmNvbmZpZz8uaHRtbCkpKTtcblxuICByZXR1cm4gZmFpbGVkLnNvbWUoKGtleSkgPT4gc2hvd24uaGFzKGtleSkpO1xufVxuXG4vLyBUaGUgY292ZXIncyBmaWx0ZXIgbGluZXM6IHRoZSBvcGVuIHZpZXcsIHRoZSBleHBvcnQncyBmaWx0ZXIgbGluZXMsIHRoZW5cbi8vIHRoZSBtYXRjaCB3aGlsZSB0aGUgcmVwb3J0IGJhcidzIGZpbHRlcnMgbWF0Y2ggYW55LiBBIGRyaWxsZWQgY2hhcnQncyBsaW5lXG4vLyBpcyBpdHMgdGl0bGUgYW5kIHRoZSBjcnVtYnMgb2YgdGhlIHBhdGggaXRzIGFuc3dlciBhcHBsaWVkICh0aGUgb25lcyBpdHNcbi8vIHRpdGxlIHByaW50cyksIG5vdCB0aGUgcGF0aCB0aGUgc2NyZWVuIGFza2VkIGZvcjogdGhlIHNlcnZlciBtYXkgaGF2ZSBjdXRcbi8vIHRoYXQgcGF0aCBzaG9ydCBvciByZWZ1c2VkIGl0LlxuZXhwb3J0IGZ1bmN0aW9uIGNvdmVyRmlsdGVyTGluZXMoXG4gIHNuYXBzaG90OiBSZXBvcnRFeHBvcnRTbmFwc2hvdCxcbiAgbGluZXM6IHJlYWRvbmx5IFJlcG9ydEV4cG9ydExpbmVbXSxcbiAgcGFnZXM6IHJlYWRvbmx5IFBpY2s8Q29sbGVjdGVkUGFnZSwgJ2NvbXBvbmVudHMnPltdLFxuKTogc3RyaW5nW10ge1xuICBjb25zdCBtYXRjaCA9IHNuYXBzaG90LmZlYXR1cmVzLmluY2x1ZGVzKCdtYXRjaEFueScpID8gbWF0Y2hMaW5lVGV4dChzbmFwc2hvdC52aWV3Lm1hdGNoLCAnbGluZScpIDogbnVsbDtcbiAgY29uc3QgZHJpbGxlZCA9IHBhZ2VzXG4gICAgLmZsYXRNYXAoKHBhZ2UpID0+IHBhZ2UuY29tcG9uZW50cylcbiAgICAuZmlsdGVyKChpdGVtKSA9PiAhIWl0ZW0uY3J1bWJzPy5sZW5ndGgpXG4gICAgLm1hcCgoaXRlbSkgPT4gY3J1bWJlZFRpdGxlKGl0ZW0uY29tcG9uZW50LnRpdGxlLCBpdGVtLmNydW1icykpO1xuXG4gIHJldHVybiBbXG4gICAgc25hcHNob3Qudmlld0xpbmUsXG4gICAgLi4ubGluZXMuZmlsdGVyKChsaW5lKSA9PiBsaW5lLmtpbmQgIT09ICdkcmlsbCcpLm1hcCgobGluZSkgPT4gbGluZS50ZXh0KSxcbiAgICAuLi5kcmlsbGVkLFxuICAgIG1hdGNoLFxuICBdXG4gICAgLmZpbHRlcigobGluZSk6IGxpbmUgaXMgc3RyaW5nID0+ICEhbGluZSk7XG59XG5cbi8vIFdoZXRoZXIgYSBQREYgb3IgUG93ZXJQb2ludCBleHBvcnQgbGF5cyBhIGNvbXBvbmVudCBvdXQ6IGV2ZXJ5IHRpbGUsIGFuZFxuLy8gZXZlcnkgdGV4dCBibG9jaywgd2hpY2ggaGFzIG5vdGhpbmcgdG8gZmV0Y2ggYW5kIHJpZGVzIHRocm91Z2ggd2l0aCBub1xuLy8gZGF0YS4gQW55IG90aGVyIHR5cGUgKGFuIGlubGluZSB2YWx1ZSwgb3IgYSB0eXBlIHRoaXMgdmlld2VyIGRvZXMgbm90XG4vLyBrbm93KSBuZXZlciBpczogYSB2YWx1ZSBpcyByZWFkIG9ubHkgdGhyb3VnaCBpdHMgbGF5ZXIncyB2YWx1ZXMgam9iLlxuZXhwb3J0IGZ1bmN0aW9uIGlzRXhwb3J0U2xvdChjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNUaWxlKGNvbXBvbmVudCkgfHwgY29tcG9uZW50LnR5cGUgPT09ICd0ZXh0Jztcbn1cblxuLy8gR2F0aGVycyBldmVyeXRoaW5nIGFuIGV4cG9ydCBuZWVkczogZXZlcnkgY29tcG9uZW50J3MgZGF0YSBhY3Jvc3MgQUxMIHBhZ2VzXG4vLyAodGhlIGNhbnZhcyBvbmx5IHJlbmRlcnMgdGhlIGFjdGl2ZSBwYWdlLCBzbyBleHBvcnRzIGNhbid0IHNjcmFwZSB0aGVcbi8vIHNjcmVlbiksIGFuZCB0aGUgbnVtYmVycyBvZiB0aGUgdmFsdWVzIHRoZWlyIHRleHQgcmVhZHMsIGZldGNoZWQgZnJlc2ggd2l0aFxuLy8gdGhlIHZpZXdlcidzIGN1cnJlbnQgZmlsdGVyIHN0YXRlLlxuLy9cbi8vIEEgZmFpbGVkIGNvbXBvbmVudCByZXNvbHZlcyB0byBhIG51bGwgYGRhdGFgLCBhbmQgYSBmYWlsZWQgdmFsdWUgdG8gYSBrZXkgaW5cbi8vIGl0cyBwYWdlJ3MgZmFpbGVkVmFsdWVzLCByYXRoZXIgdGhhbiBmYWlsaW5nIHRoZSB3aG9sZSBjb2xsZWN0aW9uIOKAlCBidXQgdGhhdFxuLy8gaXMgc28gdGhlIGNhbGxlciBjYW4gUkVQT1JUIHdoYXQgZmFpbGVkLCBub3Qgc28gaXQgY2FuIGJlIGlnbm9yZWQ6IHNlZVxuLy8gZmFpbGVkUGFnZU5hbWVzKCkgYW5kIHRoZSBmYWlsdXJlIGdhdGUgdGhhdCB1c2VzIGl0LlxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2Uge1xuXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgX2ZpbHRlck9wdGlvbnMgPSBpbmplY3QoUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UpO1xuICAvLyBUaGUgb3BlbiBzYXZlZCB2aWV3LCBmb3IgdGhlIGNvdmVyJ3MgdmlldyBsaW5lLiBPbmx5IGEgdmlldyB0aGF0IGtlZXBzXG4gIC8vIHNhdmVkIHZpZXdzIHByb3ZpZGVzIGl0LlxuICBwcml2YXRlIF92aWV3cyA9IGluamVjdChSZXBvcnRWaWV3U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICAvLyBsaXN0Um93cyBpcyBob3cgbWFueSByb3dzIGVhY2ggbGlzdCBmZXRjaGVzOiB0aGUgcmVuZGVyZXIncyBvd24gY2FwLCBzaW5jZVxuICAvLyBhIFBERiB0YWJsZSBjb250aW51ZXMgb250byBleHRyYSBwYWdlcyBhbmQgYSBzbGlkZSB0YWJsZSBjYW5ub3QuXG4gIC8vXG4gIC8vIFRoZSBzY3JlZW4gaXMgcmVhZCBvbmNlLCB3aGVuIHRoZSBleHBvcnQgc3RhcnRzIChzbmFwc2hvdCk6IGV2ZXJ5IHRpbGUsXG4gIC8vIGV2ZXJ5IHZhbHVlcyBqb2IsIHRoZSBmaWx0ZXIgbGluZXMgYW5kIHRoZSBjb3ZlciByZWFkIHRoYXQgY29weSwgc28gYVxuICAvLyBmaWx0ZXIgY2hhbmdlZCB3aGlsZSB0aGUgdGlsZXMgYXJlIGZldGNoZWQgcmVhY2hlcyBub25lIG9mIHRoZW0uIEEgcmV0cnlcbiAgLy8gY29sbGVjdHMgYWdhaW4sIGFuZCBzbyByZWFkcyB0aGUgc2NyZWVuIGFzIGl0IGlzIHRoZW4uXG4gIHB1YmxpYyBjb2xsZWN0KHJlcG9ydDogUmVwb3J0LCBsaXN0Um93czogbnVtYmVyKTogT2JzZXJ2YWJsZTxDb2xsZWN0ZWRSZXBvcnQ+IHtcbiAgICBjb25zdCBqb2JzID0gdGhpcy5fam9icyhyZXBvcnQpO1xuICAgIGNvbnN0IHNuYXBzaG90ID0gdGhpcy5zbmFwc2hvdChyZXBvcnQpO1xuICAgIGNvbnN0IGZvcm1hdENvbnRleHQgPSBzbmFwc2hvdC5mb3JtYXRDb250ZXh0O1xuXG4gICAgLy8gUmVsZWFzZWQgYSBmZXcgYXQgYSB0aW1lIHJhdGhlciB0aGFuIGFsbCBhdCBvbmNlLCBhIHBhZ2UncyB2YWx1ZXMgaW4gdGhlXG4gICAgLy8gc2FtZSBxdWV1ZSBhcyB0aGUgdGlsZXMsIHNvIHRoZXkgbmV2ZXIgYWRkIHRvIHRoZSBxdWVyaWVzIGFscmVhZHlcbiAgICAvLyBydW5uaW5nLiBtZXJnZU1hcCBjb21wbGV0ZXMgb3V0IG9mIG9yZGVyLCBzbyBlYWNoIHJlc3VsdCBjYXJyaWVzIHRoZSBqb2JcbiAgICAvLyBpdCBjYW1lIGZyb20gYW5kIHRoZSByb3dzIGFyZSBmaWxlZCBieSBpbmRleCDigJQgdGhlIGRlY2sncyBwYWdlIG9yZGVyXG4gICAgLy8gY2FuJ3QgZGVwZW5kIG9uIHdoaWNoIHF1ZXJ5IGhhcHBlbmVkIHRvIGZpbmlzaCBmaXJzdC5cbiAgICBjb25zdCBhbGwkID0gam9icy5sZW5ndGhcbiAgICAgID8gZnJvbShqb2JzLm1hcCgoam9iLCBpbmRleCkgPT4gKHsgam9iLCBpbmRleCB9KSkpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIG1lcmdlTWFwKFxuICAgICAgICAgICAgKHsgam9iLCBpbmRleCB9KSA9PiB0aGlzLl9ydW5Kb2IocmVwb3J0LCBqb2IsIGxpc3RSb3dzLCBzbmFwc2hvdClcbiAgICAgICAgICAgICAgLnBpcGUobWFwKChyZXN1bHQpID0+ICh7IHJlc3VsdCwgaW5kZXggfSkpKSxcbiAgICAgICAgICAgIEVYUE9SVF9DT05DVVJSRU5DWSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHRvQXJyYXkoKSxcbiAgICAgICAgKVxuICAgICAgOiBvZihbXSBhcyB7IHJlc3VsdDogQ29sbGVjdFJlc3VsdDsgaW5kZXg6IG51bWJlciB9W10pO1xuXG4gICAgLy8gVGhlIGxpbmVzIHJpZGUgYWxvbmdzaWRlIHRoZSBjb21wb25lbnQgZGF0YSByYXRoZXIgdGhhbiBiZWluZyBidWlsdCBhdFxuICAgIC8vIHRoZSBlbmQsIGJlY2F1c2UgbmFtaW5nIGEgc2VsZWN0IGZpbHRlcidzIHZhbHVlcyBpcyBpdHNlbGYgYSByZXF1ZXN0LlxuICAgIHJldHVybiBmb3JrSm9pbih7IGNvbGxlY3RlZDogYWxsJCwgbGluZXM6IHRoaXMuZmlsdGVyTGluZXMocmVwb3J0LCBzbmFwc2hvdCkgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKHsgY29sbGVjdGVkLCBsaW5lcyB9KSA9PiB7XG4gICAgICAgICAgY29uc3QgZmlsZSA9IHRoaXMuX2ZpbGUocmVwb3J0LCBjb2xsZWN0ZWQsIGZvcm1hdENvbnRleHQpO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlcG9ydCxcbiAgICAgICAgICAgIC4uLmZpbGUsXG4gICAgICAgICAgICBmaWx0ZXJTdW1tYXJ5OiBjb3ZlckZpbHRlckxpbmVzKHNuYXBzaG90LCBsaW5lcywgZmlsZS5wYWdlcyksXG4gICAgICAgICAgICBjb250ZXh0TGluZXM6IHRoaXMuX2NvbnRleHRMaW5lcyhyZXBvcnQpLFxuICAgICAgICAgICAgZm9ybWF0Q29udGV4dCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgc2NyZWVuIGFzIG9uZSBleHBvcnQgcmVhZHMgaXQ6IHRoZSB2aWV3IGRvY3VtZW50LCBlYWNoIGdyb3VwJ3MgdmFsdWVcbiAgLy8gYW5kIGxpdmUgcHJlc2V0LCBlYWNoIHRpbGUncyBmaWx0ZXIgZW50cmllcyBhbmQgc3RhdGUgKHRpbGVEYXRhU3RhdGUpLFxuICAvLyBlYWNoIHZhbHVlJ3MgZmlsdGVyIGVudHJpZXMsIHRoZSBncmFpbiwgdGhlIGZlYXR1cmVzIHNlcnZlZCwgdGhlIGZvcm1hdFxuICAvLyBhbmQgdGhlIG9wZW4gdmlldydzIGxpbmUuIEEgdmFsdWUncyBlbnRyaWVzIGFyZSByZWFkIGhlcmUgdG9vLCBzbyB0aGVcbiAgLy8gbnVtYmVycyBpbiBhIGZpbGUncyB0ZXh0IGFyZSBmaWx0ZXJlZCBhcyBpdHMgdGlsZXMgYXJlLCB3aGF0ZXZlciB0aGUgYmFyXG4gIC8vIGRvZXMgd2hpbGUgdGhlIGV4cG9ydCBydW5zLlxuICBwdWJsaWMgc25hcHNob3QocmVwb3J0OiBSZXBvcnQpOiBSZXBvcnRFeHBvcnRTbmFwc2hvdCB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuX2ZpbHRlclN0YXRlLnNuYXBzaG90KCk7XG4gICAgY29uc3QgdGlsZXMgPSAocmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLmZsYXRNYXAoKHBhZ2UpID0+IHBhZ2UuY29tcG9uZW50cyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gaXNUaWxlKGNvbXBvbmVudCkpO1xuICAgIGNvbnN0IHZhbHVlcyA9IHJlcG9ydENvbXBvbmVudHMocmVwb3J0KVxuICAgICAgLmZpbHRlcigoY29tcG9uZW50KSA9PiBjb21wb25lbnQudHlwZSA9PT0gJ3ZhbHVlJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmlldyxcbiAgICAgIC4uLnRoaXMuX2dyb3VwVmFsdWVzKHJlcG9ydCksXG4gICAgICBmaWx0ZXJzOiBPYmplY3QuZnJvbUVudHJpZXModGlsZXMubWFwKCh0aWxlKSA9PiBbdGlsZS5pZCwgdGhpcy5fZmlsdGVyU3RhdGUucmVzb2x2ZUZvckNvbXBvbmVudCh0aWxlKV0pKSxcbiAgICAgIHZhbHVlRmlsdGVyczogT2JqZWN0LmZyb21FbnRyaWVzKHZhbHVlc1xuICAgICAgICAubWFwKCh2YWx1ZSkgPT4gW3ZhbHVlLmlkLCB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KHZhbHVlKV0pKSxcbiAgICAgIHN0YXRlczogT2JqZWN0LmZyb21FbnRyaWVzKHRpbGVzLm1hcCgodGlsZSkgPT4gW3RpbGUuaWQsIHRpbGVEYXRhU3RhdGUocmVwb3J0LCB0aWxlLCB2aWV3KV0pKSxcbiAgICAgIGZyZXF1ZW5jeTogdGhpcy5fZmlsdGVyU3RhdGUuZnJlcXVlbmN5KCksXG4gICAgICBmZWF0dXJlczogb2ZmZXJlZFZpZXdlckZlYXR1cmVzKHJlcG9ydC52aWV3ZXJGZWF0dXJlcyksXG4gICAgICBmb3JtYXRDb250ZXh0OiB0aGlzLl9maWx0ZXJTdGF0ZS5mb3JtYXRDb250ZXh0KCksXG4gICAgICB2aWV3TGluZTogdmlld0xpbmVUZXh0KHRoaXMuX3ZpZXdzPy5vcGVuVmlldygpLCAhIXRoaXMuX3ZpZXdzPy52aWV3Q2hhbmdlZCgpKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gVGhlIGV4cG9ydCdzIGZpbHRlciBsaW5lcyAoZXhwb3J0TGluZXMpIG92ZXIgYSBzbmFwc2hvdDogdGhlIGNvdmVyJ3MsIGFuZFxuICAvLyB0aGUgemlwJ3MgZmlsdGVyTGluZXMgKGBwYWdlSWRgIGZvciBhIFRoaXMgUGFnZSB6aXApLiBBIHNlbGVjdCdzIHBpY2tzXG4gIC8vIGFyZSBuYW1lZCBhcyB0aGUgcmVwb3J0IGJhciBuYW1lcyB0aGVtLlxuICBwdWJsaWMgZmlsdGVyTGluZXMoXG4gICAgcmVwb3J0OiBSZXBvcnQsXG4gICAgc25hcHNob3Q6IFJlcG9ydEV4cG9ydFNuYXBzaG90LFxuICAgIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGwsXG4gICk6IE9ic2VydmFibGU8UmVwb3J0RXhwb3J0TGluZVtdPiB7XG4gICAgcmV0dXJuIGV4cG9ydExpbmVzKHtcbiAgICAgIHJlcG9ydCxcbiAgICAgIHNuYXBzaG90LFxuICAgICAgcGFnZUlkLFxuICAgICAgbmFtZXM6IChncm91cCwgdmFsdWVzKSA9PiB0aGlzLl9waWNrTmFtZXMoZ3JvdXAsIHJlcG9ydC5pZCwgdmFsdWVzKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEV2ZXJ5IHJlcXVlc3QgdGhlIGV4cG9ydCBtYWtlcywgaW4gcGFnZSBvcmRlcjogZWFjaCBwYWdlJ3MgdGlsZXMsIHRoZW4gdGhlXG4gIC8vIHZhbHVlcyBpdHMgdGV4dCBzaG93czsgdGhlIGhlYWRlciBhbmQgZm9vdGVyJ3MgdmFsdWVzIGxhc3QsIHdoZW4gc29tZSBwYWdlXG4gIC8vIHNob3dzIHRoZSBtYXN0ZXIuIFRleHQgYmxvY2tzIGhhdmUgbm90aGluZyB0byBmZXRjaCBvZiB0aGVpciBvd24g4oCUIHRoZXlcbiAgLy8gcmlkZSB0aHJvdWdoIHdpdGggbm8gZGF0YSwgYW5kIHRoZWlyIHRva2VucyBhcmUgZmlsbGVkIGZyb20gdGhlaXIgbGF5ZXInc1xuICAvLyB2YWx1ZXMuIEEgdmFsdWUgaXMgcmVhZCBvbmx5IHRocm91Z2ggaXRzIGxheWVyJ3MgcmVxdWVzdCwgbmV2ZXIgYXMgYSB0aWxlXG4gIC8vIChpc0V4cG9ydFNsb3QpLiBUaGUgaGVhZGVyL2Zvb3RlciBibG9ja3MgKHJlcG9ydC5tYXN0ZXIpIGFyZSByZWFkIGJ5IHRoZVxuICAvLyByZW5kZXJlcnMgc3RyYWlnaHQgb2ZmIHRoZSByZXBvcnQuXG4gIHByaXZhdGUgX2pvYnMocmVwb3J0OiBSZXBvcnQpOiBDb2xsZWN0Sm9iW10ge1xuICAgIGNvbnN0IGpvYnM6IENvbGxlY3RKb2JbXSA9IFtdO1xuXG4gICAgcmVwb3J0LnBhZ2VzLmZvckVhY2goKHBhZ2UsIHBhZ2VJbmRleCkgPT4ge1xuICAgICAgcGFnZS5jb21wb25lbnRzXG4gICAgICAgIC5maWx0ZXIoaXNFeHBvcnRTbG90KVxuICAgICAgICAuZm9yRWFjaCgoY29tcG9uZW50KSA9PiBqb2JzLnB1c2goeyBraW5kOiAnY29tcG9uZW50JywgcGFnZUluZGV4LCBjb21wb25lbnQgfSkpO1xuICAgICAgam9icy5wdXNoKC4uLnRoaXMuX3ZhbHVlc0pvYnMocGFnZSwgcGFnZUluZGV4KSk7XG4gICAgfSk7XG5cbiAgICBpZiAocmVwb3J0Lm1hc3RlciAmJiByZXBvcnQucGFnZXMuc29tZSgocGFnZSkgPT4gIXBhZ2UubWFzdGVySGlkZGVuKSkge1xuICAgICAgam9icy5wdXNoKC4uLnRoaXMuX3ZhbHVlc0pvYnMocmVwb3J0Lm1hc3RlciwgbnVsbCkpO1xuICAgIH1cblxuICAgIHJldHVybiBqb2JzO1xuICB9XG5cbiAgLy8gQSBsYXllcidzIG9uZSB2YWx1ZXMgam9iLCBvciBub25lIHdoZW4gaXRzIHRleHQgc2hvd3Mgbm8gdmFsdWUuXG4gIHByaXZhdGUgX3ZhbHVlc0pvYnMobGF5ZXI6IFJlcG9ydFBhZ2UgfCBSZXBvcnRNYXN0ZXIsIHBhZ2VJbmRleDogbnVtYmVyIHwgbnVsbCk6IENvbGxlY3RKb2JbXSB7XG4gICAgY29uc3QgdGV4dHMgPSBsYXllci5jb21wb25lbnRzLmZpbHRlcigoY29tcG9uZW50KSA9PiBjb21wb25lbnQudHlwZSA9PT0gJ3RleHQnKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBsYXllci52YWx1ZXMgPz8gW107XG4gICAgY29uc3Qgc2hvd24gPSBzaG93blZhbHVlcyh2YWx1ZXMsIHRleHRzKTtcblxuICAgIHJldHVybiBzaG93bi5sZW5ndGhcbiAgICAgID8gW3sga2luZDogJ3ZhbHVlcycsIHBhZ2VJbmRleCwgcGFnZUlkOiBsYXllci5pZCwgdmFsdWVzLCBjb21wb25lbnRzOiBzaG93biB9XVxuICAgICAgOiBbXTtcbiAgfVxuXG4gIC8vIE9uZSBxdWV1ZWQgam9iLCBpdHMgcmVzdWx0IHRhZ2dlZCB3aXRoIHRoZSBwYWdlIGl0IGlzIGZpbGVkIHVuZGVyLlxuICBwcml2YXRlIF9ydW5Kb2IoXG4gICAgcmVwb3J0OiBSZXBvcnQsXG4gICAgam9iOiBDb2xsZWN0Sm9iLFxuICAgIGxpc3RSb3dzOiBudW1iZXIsXG4gICAgc25hcHNob3Q6IFJlcG9ydEV4cG9ydFNuYXBzaG90LFxuICApOiBPYnNlcnZhYmxlPENvbGxlY3RSZXN1bHQ+IHtcbiAgICBpZiAoam9iLmtpbmQgPT09ICdjb21wb25lbnQnKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29tcG9uZW50RGF0YShyZXBvcnQsIGpvYi5jb21wb25lbnQsIGxpc3RSb3dzLCBzbmFwc2hvdClcbiAgICAgICAgLnBpcGUobWFwKChpdGVtKTogQ29sbGVjdFJlc3VsdCA9PiAoeyBraW5kOiAnY29tcG9uZW50JywgcGFnZUluZGV4OiBqb2IucGFnZUluZGV4LCBpdGVtIH0pKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VWYWx1ZXMocmVwb3J0LCBqb2IucGFnZUlkLCBqb2IudmFsdWVzLCBqb2IuY29tcG9uZW50cywgc25hcHNob3QpXG4gICAgICAucGlwZShtYXAoKGNvbGxlY3RlZCk6IENvbGxlY3RSZXN1bHQgPT4gKHsga2luZDogJ3ZhbHVlcycsIHBhZ2VJbmRleDogam9iLnBhZ2VJbmRleCwgY29sbGVjdGVkIH0pKSk7XG4gIH1cblxuICBwcml2YXRlIF9jb21wb25lbnREYXRhKFxuICAgIHJlcG9ydDogUmVwb3J0LFxuICAgIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICAgIGxpc3RSb3dzOiBudW1iZXIsXG4gICAgc25hcHNob3Q6IFJlcG9ydEV4cG9ydFNuYXBzaG90LFxuICApOiBPYnNlcnZhYmxlPENvbGxlY3RlZENvbXBvbmVudD4ge1xuICAgIGlmIChjb21wb25lbnQudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICByZXR1cm4gb2YoeyBjb21wb25lbnQsIGRhdGE6IG51bGwsIGhpZGRlbkNvbHVtbnM6IFtdIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbHRlcnMgPSBzbmFwc2hvdC5maWx0ZXJzW2NvbXBvbmVudC5pZF0gPz8gW107XG4gICAgLy8gVGhlIHRpbGUncyBvd24gc3RhdGUsIHRoZSBvbmUgaXRzIHNjcmVlbiBhbmQgaXRzIENTViBjYXJyeVxuICAgIC8vICh0aWxlRGF0YVN0YXRlKTogYSB0aW1lLXNlcmllcyBjaGFydCByZS1idWNrZXRzIGF0IHRoZSB2aWV3ZXIncyBncmFpblxuICAgIC8vIGFuZCBrZWVwcyBpdHMgZHJpbGwgcGF0aCwgYSBsaXN0IHJlYWRzIGluIHRoZSBzY3JlZW4ncyBvcmRlciBhbmQgaG9sZHNcbiAgICAvLyB0aGUgc2NyZWVuJ3Mgcm93cy4gQSBsaXN0IGFkZHMgaXRzIGV4cG9ydCBwYWdpbmcuXG4gICAgY29uc3QgdGlsZVN0YXRlID0gc25hcHNob3Quc3RhdGVzW2NvbXBvbmVudC5pZF0gPz8ge307XG4gICAgY29uc3Qgc3RhdGU6IENvbXBvbmVudERhdGFTdGF0ZSA9IGNvbXBvbmVudC50eXBlID09PSAnbGlzdCdcbiAgICAgID8geyAuLi50aWxlU3RhdGUsIHBhZ2U6IDEsIHBhZ2VTaXplOiBsaXN0Um93cyB9XG4gICAgICA6IHsgLi4udGlsZVN0YXRlIH07XG4gICAgLy8gVGhlIHRhYmxlIGxlYXZlcyBvdXQgdGhlIGNvbHVtbnMgdGhlIHZpZXdlciBoaWQuIFRoZSByb3dzIGFyZSBmZXRjaGVkXG4gICAgLy8gd2hvbGUsIGFzIHRoZSBzY3JlZW4gZmV0Y2hlcyB0aGVtICh0aGUgc2VydmVyIHJlYWRzIGhpZGRlbkNvbHVtbnMgZm9yIGFcbiAgICAvLyBDU1Ygb25seSksIGFuZCB0aGUgcmVuZGVyZXJzIGRyb3AgdGhlIGNlbGxzLlxuICAgIGNvbnN0IGhpZGRlbkNvbHVtbnMgPSBbLi4uKHN0YXRlLmhpZGRlbkNvbHVtbnMgPz8gW10pXTtcblxuICAgIC8vIGhhbmRsZXJzOiBmYWxzZSBrZWVwcyB0aGUgYXBwJ3MgZ2xvYmFsIGVycm9yIGRpYWxvZyBvdXQgb2YgdGhpcy4gQSBmYWlsZWRcbiAgICAvLyB0aWxlIGlzIHJlcG9ydGVkIG9uY2UsIGJ5IHRoZSBmYWlsdXJlIGdhdGUsIG5hbWluZyB0aGUgcGFnZXMgaXQgY29zdCDigJRcbiAgICAvLyBuZXZlciBhcyB0ZW4gc3RhY2tlZCBtb2RhbHMgY2FycnlpbmcgdGhlIGRhdGFiYXNlJ3Mgb3duIHdvcmRpbmcuXG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydERhdGEuY29tcG9uZW50RGF0YShyZXBvcnQuaWQsIGNvbXBvbmVudC5pZCwgZmlsdGVycywgc3RhdGUsIHRydWUsIHsgaGFuZGxlcnM6IGZhbHNlIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChkYXRhOiBDb21wb25lbnREYXRhKSA9PiB0aGlzLl9jb2xsZWN0ZWQoY29tcG9uZW50LCBkYXRhLCBzdGF0ZS5zZWFyY2gsIGhpZGRlbkNvbHVtbnMsIHNuYXBzaG90KSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YoeyBjb21wb25lbnQsIGRhdGE6IG51bGwsIGhpZGRlbkNvbHVtbnMgfSkpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIE9uZSB0aWxlJ3MgYW5zd2VyIGFzIHRoZSByZW5kZXJlcnMgdGFrZSBpdC4gQSBzZWFyY2ggdGhlIHNlcnZlciBjb3VsZFxuICAvLyBub3QgYXBwbHkgKHNlYXJjaE5vdGU6IHRoZSBsaXN0IGhhcyBubyB0ZXh0IGNvbHVtbikgbmFycm93ZWQgbm90aGluZywgc29cbiAgLy8gdGhlIGl0ZW0gZG9lcyBub3QgY2FycnkgaXQuIEEgZHJpbGxlZCBjaGFydCBjYXJyaWVzIHRoZSBicmVhZGNydW1iIG9mIHRoZVxuICAvLyBwYXRoIGl0cyBhbnN3ZXIgYXBwbGllZCwgd2hpY2ggaXMgd2hhdCBpdHMgbnVtYmVycyB3ZXJlIHJlYWQgYXQuXG4gIHByaXZhdGUgX2NvbGxlY3RlZChcbiAgICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgICBkYXRhOiBDb21wb25lbnREYXRhLFxuICAgIHNlYXJjaDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIGhpZGRlbkNvbHVtbnM6IHN0cmluZ1tdLFxuICAgIHNuYXBzaG90OiBSZXBvcnRFeHBvcnRTbmFwc2hvdCxcbiAgKTogQ29sbGVjdGVkQ29tcG9uZW50IHtcbiAgICBjb25zdCBwYXRoID0gZGF0YT8uZHJpbGw/LnBhdGggPz8gW107XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcG9uZW50LFxuICAgICAgZGF0YSxcbiAgICAgIC4uLihzZWFyY2ggJiYgIWRhdGE/LnNlYXJjaE5vdGUgPyB7IHNlYXJjaCB9IDoge30pLFxuICAgICAgaGlkZGVuQ29sdW1ucyxcbiAgICAgIC4uLihwYXRoLmxlbmd0aCA/IHsgY3J1bWJzOiBkcmlsbENydW1iTGFiZWxzKHBhdGgsIHNuYXBzaG90LmZvcm1hdENvbnRleHQpIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8vIEVhY2ggZ3JvdXAncyB2YWx1ZSBhcyB0aGUgYmFyIGhvbGRzIGl0IG5vdywgd2l0aCB0aGUgcmVsYXRpdmUgcmFuZ2UgYVxuICAvLyBkYXRlIHZhbHVlIHN0aWxsIGlzLiBUaGUgcGlja3MgYXJlIGNvcGllZCwgc28gdGhlIHNuYXBzaG90IGtlZXBzIHRoZW1cbiAgLy8gd2hhdGV2ZXIgdGhlIGJhciBkb2VzIG5leHQuXG4gIHByaXZhdGUgX2dyb3VwVmFsdWVzKHJlcG9ydDogUmVwb3J0KTogUGljazxSZXBvcnRFeHBvcnRTbmFwc2hvdCwgJ3ZhbHVlcycgfCAncHJlc2V0cyc+IHtcbiAgICBjb25zdCB2YWx1ZXM6IFJlY29yZDxudW1iZXIsIEZpbHRlckdyb3VwVmFsdWU+ID0ge307XG4gICAgY29uc3QgcHJlc2V0czogUmVjb3JkPG51bWJlciwgUmVwb3J0UmVsYXRpdmVSYW5nZT4gPSB7fTtcblxuICAgIChyZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKS5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9maWx0ZXJTdGF0ZS52YWx1ZShncm91cC5pZCk7XG4gICAgICBjb25zdCBwcmVzZXQgPSB0aGlzLl9maWx0ZXJTdGF0ZS5saXZlUHJlc2V0KGdyb3VwLmlkKTtcblxuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhbHVlc1tncm91cC5pZF0gPSB7XG4gICAgICAgICAgLi4udmFsdWUsXG4gICAgICAgICAgLi4uKHZhbHVlLnZhbHVlcyA/IHsgdmFsdWVzOiBbLi4udmFsdWUudmFsdWVzXSB9IDoge30pLFxuICAgICAgICAgIC4uLih2YWx1ZS5leGNsdWRlVmFsdWVzID8geyBleGNsdWRlVmFsdWVzOiBbLi4udmFsdWUuZXhjbHVkZVZhbHVlc10gfSA6IHt9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChwcmVzZXQpIHtcbiAgICAgICAgcHJlc2V0c1tncm91cC5pZF0gPSBwcmVzZXQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyB2YWx1ZXMsIHByZXNldHMgfTtcbiAgfVxuXG4gIC8vIE9uZSBsYXllcidzIHZhbHVlcywgcmVhZCBpbiBvbmUgcmVxdWVzdCwgYXMgaXRzIHRleHQncyB0b2tlbnMgcHJpbnQgdGhlbS5cbiAgLy8gVGhlIHJlcXVlc3QgY2FycmllcyB0aGUgZmlsdGVyIHZhbHVlcyBvZiBldmVyeSB2YWx1ZSBvbiB0aGUgbGF5ZXIsIGFzIHRoZVxuICAvLyBjYW52YXMncyBkb2VzLCByZWFkIGZyb20gdGhlIGV4cG9ydCdzIHNuYXBzaG90IGxpa2UgZXZlcnkgdGlsZSdzLCBhbmRcbiAgLy8gd2hpbGUgdGhlIGdyb3VwcyBtYXRjaCAnYW55JyB0aGUgZ3JvdXBzIHRoYXQgY29tYmluZVxuICAvLyAodmFsdWVzTWF0Y2hBbnlHcm91cElkcyk6IHRoZSBzZXJ2ZXIgZGVjaWRlcyB3aGljaCB2YWx1ZXMgaXQgcmVhZHMgKHRoZVxuICAvLyBzaG93biBvbmVzIGFuZCB0aGUgb3BlcmFuZHMgb2YgdGhlIGZvcm11bGFzIGFtb25nIHRoZW0pIGFuZCBhcHBsaWVzIHRvXG4gIC8vIGVhY2ggb25seSB0aGUgZW50cmllcyBuYW1pbmcgaXRzIG93biBmaWx0ZXJzLiBoYW5kbGVyczogZmFsc2Uga2VlcHMgdGhlXG4gIC8vIGVycm9yIGRpYWxvZyBvdXQgb2YgaXQsIGFzIGZvciBhIHRpbGUuIEEgZmFpbGVkIHJlcXVlc3QgcmVhZHMgYXMgbm8gcm93cyxcbiAgLy8gc28gZXZlcnkgdmFsdWUgdGhlIHRleHQgc2hvd3MgZmFpbGVkIGFuZCB0aGUgZmFpbHVyZSBnYXRlIG5hbWVzIGl0cyBwYWdlO1xuICAvLyBvbmUgdmFsdWUncyBvd24gZXJyb3IgZmFpbHMgb25seSB0aGF0IHZhbHVlLCBhbmQgYSBmYWlsZWQgb3BlcmFuZCBmYWlsc1xuICAvLyB0aGUgZm9ybXVsYSB0aGF0IHJlYWRzIGl0LlxuICBwcml2YXRlIF9wYWdlVmFsdWVzKFxuICAgIHJlcG9ydDogUmVwb3J0LFxuICAgIHBhZ2VJZDogbnVtYmVyLFxuICAgIHZhbHVlczogUmVwb3J0Q29tcG9uZW50W10sXG4gICAgc2hvd246IFJlcG9ydENvbXBvbmVudFtdLFxuICAgIHNuYXBzaG90OiBSZXBvcnRFeHBvcnRTbmFwc2hvdCxcbiAgKTogT2JzZXJ2YWJsZTxDb2xsZWN0ZWRWYWx1ZXM+IHtcbiAgICBjb25zdCBmb3JtYXRDb250ZXh0ID0gc25hcHNob3QuZm9ybWF0Q29udGV4dDtcbiAgICBjb25zdCBmaWx0ZXJzID0gdmFsdWVzLmZsYXRNYXAoKGNvbXBvbmVudCkgPT4gc25hcHNob3QudmFsdWVGaWx0ZXJzW2NvbXBvbmVudC5pZF0gPz8gW10pO1xuICAgIGNvbnN0IG1hdGNoQW55R3JvdXBJZHMgPSB2YWx1ZXNNYXRjaEFueUdyb3VwSWRzKHJlcG9ydCwgcGFnZUlkLCBzbmFwc2hvdC52aWV3KTtcblxuICAgIHJldHVybiB0aGlzLl9yZXBvcnREYXRhLnBhZ2VWYWx1ZXMocmVwb3J0LmlkLCBwYWdlSWQsIGZpbHRlcnMsIHRydWUsIHsgaGFuZGxlcnM6IGZhbHNlIH0sIG1hdGNoQW55R3JvdXBJZHMpXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChyb3dzKSA9PiBuZXcgTWFwKChyb3dzID8/IFtdKS5tYXAoKHJvdykgPT4gW3Jvdy5pZCwgcm93XSkpKSxcbiAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihuZXcgTWFwPG51bWJlciwgUmVwb3J0UGFnZVZhbHVlPigpKSksXG4gICAgICAgIG1hcCgocm93cykgPT4gKHtcbiAgICAgICAgICB2YWx1ZXM6IHRleHRWYWx1ZXModmFsdWVzLCB7IHJvd3MgfSwgZm9ybWF0Q29udGV4dCksXG4gICAgICAgICAgZmFpbGVkVmFsdWVzOiBmYWlsZWRWYWx1ZUtleXMoc2hvd24sIHJvd3MpLFxuICAgICAgICB9KSksXG4gICAgICApO1xuICB9XG5cbiAgLy8gVGhlIHJlc3VsdHMgZmlsZWQgYnkgcGFnZSBpbiBqb2Igb3JkZXIuIEEgbGF5ZXIgd2l0aCBubyB2YWx1ZXMgam9iIChpdHNcbiAgLy8gdGV4dCBzaG93cyBubyB2YWx1ZSkgaGFzIG5vIG51bWJlcnMgdG8gd2FpdCBmb3I6IGl0cyB2YWx1ZXMgcmVhZCBhcyB0aGVcbiAgLy8gZW0gZGFzaCwgYW5kIG5vbmUgb2YgdGhlbSBmYWlsZWQuXG4gIHByaXZhdGUgX2ZpbGUoXG4gICAgcmVwb3J0OiBSZXBvcnQsXG4gICAgcmVzdWx0czogeyByZXN1bHQ6IENvbGxlY3RSZXN1bHQ7IGluZGV4OiBudW1iZXIgfVtdLFxuICAgIGZvcm1hdENvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4gICk6IFBpY2s8Q29sbGVjdGVkUmVwb3J0LCAncGFnZXMnIHwgJ21hc3RlclZhbHVlcycgfCAnbWFzdGVyRmFpbGVkVmFsdWVzJz4ge1xuICAgIGNvbnN0IHVucmVhZCA9ICh2YWx1ZXM6IFJlcG9ydENvbXBvbmVudFtdIHwgdW5kZWZpbmVkKTogQ29sbGVjdGVkVmFsdWVzID0+ICh7XG4gICAgICB2YWx1ZXM6IHRleHRWYWx1ZXModmFsdWVzID8/IFtdLCB7IHJvd3M6IG5ldyBNYXAoKSB9LCBmb3JtYXRDb250ZXh0KSxcbiAgICAgIGZhaWxlZFZhbHVlczogW10sXG4gICAgfSk7XG4gICAgY29uc3QgcGFnZXM6IENvbGxlY3RlZFBhZ2VbXSA9IHJlcG9ydC5wYWdlcy5tYXAoKHBhZ2UpID0+ICh7IHBhZ2UsIGNvbXBvbmVudHM6IFtdLCAuLi51bnJlYWQocGFnZS52YWx1ZXMpIH0pKTtcbiAgICBsZXQgbWFzdGVyID0gdW5yZWFkKHJlcG9ydC5tYXN0ZXI/LnZhbHVlcyk7XG5cbiAgICBbLi4ucmVzdWx0c11cbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmluZGV4IC0gYi5pbmRleClcbiAgICAgIC5mb3JFYWNoKCh7IHJlc3VsdCB9KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQua2luZCA9PT0gJ2NvbXBvbmVudCcpIHtcbiAgICAgICAgICBwYWdlc1tyZXN1bHQucGFnZUluZGV4XS5jb21wb25lbnRzLnB1c2gocmVzdWx0Lml0ZW0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5wYWdlSW5kZXggPT09IG51bGwpIHtcbiAgICAgICAgICBtYXN0ZXIgPSByZXN1bHQuY29sbGVjdGVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24ocGFnZXNbcmVzdWx0LnBhZ2VJbmRleF0sIHJlc3VsdC5jb2xsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHJldHVybiB7IHBhZ2VzLCBtYXN0ZXJWYWx1ZXM6IG1hc3Rlci52YWx1ZXMsIG1hc3RlckZhaWxlZFZhbHVlczogbWFzdGVyLmZhaWxlZFZhbHVlcyB9O1xuICB9XG5cbiAgLy8gVGhlIHpvbmUgdGhlIHNlcnZlciByZXNvbHZlZCwgYXMgaXRzIElBTkEgaWQsIGFuZCB0aGUgY3VycmVuY3kgaXQgc2F5c1xuICAvLyB0aGUgcmVwb3J0J3MgbW9uZXkgaXMgaW4gKGEgbGFiZWw6IG5vdGhpbmcgaXMgY29udmVydGVkKS4gT25seSB0aGVcbiAgLy8gc2VydmVyJ3MgdmFsdWVzIGFyZSBwcmludGVkOiB0aGUgYnJvd3NlcidzIHpvbmUgKHJlc29sdmVSZXBvcnRUaW1lem9uZSdzXG4gIC8vIGZhbGxiYWNrIGZvciBhbiBvbGRlciBzZXJ2ZXIpIGlzIG5vdCB3aGF0IHRoZSBudW1iZXJzIHdlcmUgbWVhc3VyZWQgaW4sXG4gIC8vIGFuZCBhbiBvbGRlciBzZXJ2ZXIgbmFtZXMgbm8gY3VycmVuY3kgYXQgYWxsLlxuICBwcml2YXRlIF9jb250ZXh0TGluZXMocmVwb3J0OiBSZXBvcnQpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLihyZXBvcnQuZWZmZWN0aXZlVGltZXpvbmUgPyBbYFRpbWV6b25lOiAke3JlcG9ydC5lZmZlY3RpdmVUaW1lem9uZX1gXSA6IFtdKSxcbiAgICAgIC4uLihyZXBvcnQuZWZmZWN0aXZlQ3VycmVuY3kgPyBbYEN1cnJlbmN5OiAke3JlcG9ydC5lZmZlY3RpdmVDdXJyZW5jeX1gXSA6IFtdKSxcbiAgICBdO1xuICB9XG5cbiAgLy8gT25lIHNlbGVjdCBncm91cCdzIHBpY2tzIChrZXB0IG9yIGxlZnQgb3V0KSwgaXRzIHN0b3JlZCBpZHMgcmVzb2x2ZWQgdG9cbiAgLy8gdGhlIHNhbWUgbmFtZXMgdGhlIG9uLXNjcmVlbiBjaGlwcyBzaG93IOKAlCBhIGNvdmVyIHJlYWRpbmcgXCJPcmdhbml6YXRpb246XG4gIC8vIDg3NzQsIDg3NzdcIiB0ZWxscyB0aGUgcmVhZGVyIG5vdGhpbmcgYWJvdXQgd2hhdCB0aGUgcmVwb3J0IGNvdmVycy5cbiAgLy9cbiAgLy8gVXNlcyB0aGUgcmVwb3J0IGJhcidzIG93biBuYW1lcyBhbmQgcmVzb2x2ZXIgc28gdGhlIHR3byBjYW4ndCBkcmlmdDogYVxuICAvLyBuYW1lIHRoZSBiYXIncyBsaXN0cyB0YXVnaHQgKFJlcG9ydEZpbHRlck9wdGlvbnNTZXJ2aWNlLmxhYmVsKSBjb21lcyBmaXJzdCxcbiAgLy8gc28gYSBwaWNrIGEgY3V0IG9yIG5hcnJvd2VkIGxpc3QgbGVhdmVzIG91dCByZWFkcyBhcyBpdHMgY2hpcCBkb2VzLCBhbmRcbiAgLy8gdGhlIGZ1bGwgbGlzdCBuYW1lcyB0aGUgcmVzdC4gQSB2YWx1ZSB3aG9zZSBlbnRpdHkgd2FzIGRlbGV0ZWQga2VlcHNcbiAgLy8gc2hvd2luZyBpdHMgcmF3IGlkIHJhdGhlciB0aGFuIGRyb3BwaW5nIG9mZiB0aGUgY292ZXIgYW5kIHNpbGVudGx5XG4gIC8vIHVuZGVyc3RhdGluZyB0aGUgZmlsdGVyLiBBIGZhaWxlZCBvcHRpb24gZmV0Y2ggZGVncmFkZXMgdGhlIHdob2xlIGxpbmUgdG9cbiAgLy8gaWRzIGZvciB0aGUgc2FtZSByZWFzb246IGFuIGV4cG9ydCBtdXN0IG5ldmVyIGZhaWwgb24gYSBjb3NtZXRpYyBsb29rdXAuXG4gIHByaXZhdGUgX3BpY2tOYW1lcyhncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsIHJlcG9ydElkOiBudW1iZXIsIHZhbHVlczogdW5rbm93bltdKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgIHJldHVybiByZXNvbHZlT3B0aW9uVmFsdWVzKFxuICAgICAgbG9hZEdyb3VwT3B0aW9ucyhncm91cCwgdGhpcy5fcmVwb3J0RGF0YSwgcmVwb3J0SWQpLFxuICAgICAgdmFsdWVzLFxuICAgICAgKHZhbHVlKSA9PiB0aGlzLl9maWx0ZXJPcHRpb25zLmxhYmVsKGdyb3VwLmlkLCB2YWx1ZSksXG4gICAgKVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcCgocmVzb2x2ZWQpID0+IHJlc29sdmVkLm1hcCgoaXRlbSkgPT4gaXRlbS5uYW1lKSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YodmFsdWVzLm1hcCgoaXRlbSkgPT4gU3RyaW5nKGl0ZW0pKSkpLFxuICAgICAgKTtcbiAgfVxufVxuIl19