@seniorsistemas/angular-components 19.0.9 → 19.1.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 (123) hide show
  1. package/breadcrumb/lib/breadcrumb/breadcrumb-models.d.ts +2 -0
  2. package/button/lib/button/button.component.d.ts +8 -2
  3. package/checkbox/lib/checkbox/checkbox.component.d.ts +5 -1
  4. package/dialog/lib/src/dialog/dialog.component.d.ts +7 -1
  5. package/esm2022/accordion/lib/accordion/components/accordion-panel/accordion-panel.component.mjs +2 -2
  6. package/esm2022/breadcrumb/lib/breadcrumb/breadcrumb-models.mjs +1 -1
  7. package/esm2022/breadcrumb/lib/breadcrumb/breadcrumb.component.mjs +3 -3
  8. package/esm2022/breadcrumb/lib/dynamic-breadcrumb/dynamic-breadcrumb.component.mjs +8 -6
  9. package/esm2022/button/lib/button/button.component.mjs +20 -8
  10. package/esm2022/checkbox/lib/checkbox/checkbox.component.mjs +8 -5
  11. package/esm2022/confirm-dialog/lib/popup-confirm-dialog/popup-confirm-dialog.component.mjs +2 -2
  12. package/esm2022/content-generator/lib/content-generator/content-generator.component.mjs +1 -1
  13. package/esm2022/dialog/lib/src/dialog/dialog.component.mjs +9 -3
  14. package/esm2022/dynamic-form/dynamic-form/components/grid/row/row.component.mjs +1 -1
  15. package/esm2022/dynamic-form/dynamic-form/components/lookup/lookup.component.mjs +2 -2
  16. package/esm2022/dynamic-form/dynamic-form/form-field/fields/bignumber/bignumber-field.component.mjs +1 -1
  17. package/esm2022/dynamic-form/dynamic-form/form-field/fields/boolean/boolean-radio-field/boolean-field.component.mjs +1 -1
  18. package/esm2022/dynamic-form/dynamic-form/form-field/fields/boolean/boolean-switch-field/boolean-switch-field.component.mjs +2 -2
  19. package/esm2022/dynamic-form/dynamic-form/form-field/fields/button-field/button-field.component.mjs +1 -1
  20. package/esm2022/dynamic-form/dynamic-form/form-field/fields/number/number-field.component.mjs +1 -1
  21. package/esm2022/dynamic-form/dynamic-form/form-field/fields/password/password-field.component.mjs +1 -1
  22. package/esm2022/dynamic-form/dynamic-form/form-field/fields/radio-button/radio-button-field.component.mjs +1 -1
  23. package/esm2022/dynamic-form/dynamic-form/form-field/fields/select/select-field.component.mjs +2 -2
  24. package/esm2022/dynamic-form/dynamic-form/form-field/fields/text/text-field.component.mjs +1 -1
  25. package/esm2022/empty-state/lib/empty-state/empty-state.component.mjs +1 -1
  26. package/esm2022/file-picker/lib/file-picker/file-picker.component.mjs +1 -1
  27. package/esm2022/global-search/lib/global-search/components/dropdown/global-search-dropdown-item.component.mjs +1 -1
  28. package/esm2022/global-search/lib/global-search/global-search.component.mjs +1 -1
  29. package/esm2022/help-popover/lib/help-popover/help-popover/help-popover.component.mjs +1 -1
  30. package/esm2022/image-cropper/lib/image-cropper/image-cropper.component.mjs +1 -1
  31. package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +1 -1
  32. package/esm2022/inline-edit/lib/inline-edit/components/inline-edit-item/inline-edit-item.component.mjs +1 -1
  33. package/esm2022/kanban/lib/kanban/components/kanban-column/kanban-column.component.mjs +1 -1
  34. package/esm2022/kanban/lib/kanban/components/kanban-item/kanban-item.component.mjs +1 -1
  35. package/esm2022/lib/locale/fallback.mjs +13 -2
  36. package/esm2022/navigation-button/lib/navigation-button/navigation-button.component.mjs +1 -1
  37. package/esm2022/object-card/lib/object-card/elements/field/object-card-field.component.mjs +1 -1
  38. package/esm2022/object-card/lib/object-card/elements/main/object-card-main.component.mjs +1 -1
  39. package/esm2022/paginator/lib/paginator/paginator.component.mjs +2 -2
  40. package/esm2022/picklist/lib/picklist/picklist.component.mjs +1 -1
  41. package/esm2022/profile-picture-picker/lib/profile-picture-picker/profile-picture-picker.component.mjs +1 -1
  42. package/esm2022/select/lib/select/components/select-option/select-option.component.mjs +3 -3
  43. package/esm2022/select/lib/select/select.component.mjs +132 -20
  44. package/esm2022/shared/lib/accessibility/paginator-accessibility.directive.mjs +182 -0
  45. package/esm2022/shared/lib/accessibility/table-checkbox-accessibility.directive.mjs +174 -0
  46. package/esm2022/shared/public-api.mjs +6 -4
  47. package/esm2022/switch/lib/switch/switch.component.mjs +19 -8
  48. package/esm2022/table/lib/table/table-paging/table-paging.component.mjs +1 -1
  49. package/esm2022/tiered-menu/lib/tiered-menu/components/tiered-menu/tiered-menu.component.mjs +18 -8
  50. package/esm2022/tiered-menu/lib/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.mjs +1 -1
  51. package/esm2022/tiered-menu/lib/tiered-menu/services/tiered-menu.service.mjs +1 -1
  52. package/esm2022/tiered-menu/lib/tiered-menu/tiered-menu.directive.mjs +11 -3
  53. package/esm2022/tooltip/lib/tooltip/tooltip.component.mjs +17 -11
  54. package/esm2022/tooltip/lib/tooltip/tooltip.directive.mjs +108 -241
  55. package/esm2022/tooltip/lib/tooltip/tooltip.module.mjs +4 -6
  56. package/esm2022/topbar/lib/topbar/topbar.component.mjs +2 -2
  57. package/fesm2022/seniorsistemas-angular-components-accordion.mjs +1 -1
  58. package/fesm2022/seniorsistemas-angular-components-accordion.mjs.map +1 -1
  59. package/fesm2022/seniorsistemas-angular-components-breadcrumb.mjs +9 -7
  60. package/fesm2022/seniorsistemas-angular-components-breadcrumb.mjs.map +1 -1
  61. package/fesm2022/seniorsistemas-angular-components-button.mjs +19 -7
  62. package/fesm2022/seniorsistemas-angular-components-button.mjs.map +1 -1
  63. package/fesm2022/seniorsistemas-angular-components-checkbox.mjs +7 -4
  64. package/fesm2022/seniorsistemas-angular-components-checkbox.mjs.map +1 -1
  65. package/fesm2022/seniorsistemas-angular-components-confirm-dialog.mjs +1 -1
  66. package/fesm2022/seniorsistemas-angular-components-confirm-dialog.mjs.map +1 -1
  67. package/fesm2022/seniorsistemas-angular-components-content-generator.mjs +1 -1
  68. package/fesm2022/seniorsistemas-angular-components-content-generator.mjs.map +1 -1
  69. package/fesm2022/seniorsistemas-angular-components-dialog.mjs +8 -2
  70. package/fesm2022/seniorsistemas-angular-components-dialog.mjs.map +1 -1
  71. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +11 -11
  72. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  73. package/fesm2022/seniorsistemas-angular-components-empty-state.mjs +1 -1
  74. package/fesm2022/seniorsistemas-angular-components-empty-state.mjs.map +1 -1
  75. package/fesm2022/seniorsistemas-angular-components-file-picker.mjs +1 -1
  76. package/fesm2022/seniorsistemas-angular-components-file-picker.mjs.map +1 -1
  77. package/fesm2022/seniorsistemas-angular-components-global-search.mjs +2 -2
  78. package/fesm2022/seniorsistemas-angular-components-global-search.mjs.map +1 -1
  79. package/fesm2022/seniorsistemas-angular-components-help-popover.mjs +1 -1
  80. package/fesm2022/seniorsistemas-angular-components-help-popover.mjs.map +1 -1
  81. package/fesm2022/seniorsistemas-angular-components-image-cropper.mjs +1 -1
  82. package/fesm2022/seniorsistemas-angular-components-image-cropper.mjs.map +1 -1
  83. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs +2 -2
  84. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs.map +1 -1
  85. package/fesm2022/seniorsistemas-angular-components-kanban.mjs +2 -2
  86. package/fesm2022/seniorsistemas-angular-components-kanban.mjs.map +1 -1
  87. package/fesm2022/seniorsistemas-angular-components-navigation-button.mjs +1 -1
  88. package/fesm2022/seniorsistemas-angular-components-navigation-button.mjs.map +1 -1
  89. package/fesm2022/seniorsistemas-angular-components-object-card.mjs +2 -2
  90. package/fesm2022/seniorsistemas-angular-components-object-card.mjs.map +1 -1
  91. package/fesm2022/seniorsistemas-angular-components-paginator.mjs +1 -1
  92. package/fesm2022/seniorsistemas-angular-components-paginator.mjs.map +1 -1
  93. package/fesm2022/seniorsistemas-angular-components-picklist.mjs +1 -1
  94. package/fesm2022/seniorsistemas-angular-components-picklist.mjs.map +1 -1
  95. package/fesm2022/seniorsistemas-angular-components-profile-picture-picker.mjs +1 -1
  96. package/fesm2022/seniorsistemas-angular-components-profile-picture-picker.mjs.map +1 -1
  97. package/fesm2022/seniorsistemas-angular-components-select.mjs +133 -21
  98. package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
  99. package/fesm2022/seniorsistemas-angular-components-shared.mjs +354 -2
  100. package/fesm2022/seniorsistemas-angular-components-shared.mjs.map +1 -1
  101. package/fesm2022/seniorsistemas-angular-components-switch.mjs +18 -7
  102. package/fesm2022/seniorsistemas-angular-components-switch.mjs.map +1 -1
  103. package/fesm2022/seniorsistemas-angular-components-table.mjs +1 -1
  104. package/fesm2022/seniorsistemas-angular-components-table.mjs.map +1 -1
  105. package/fesm2022/seniorsistemas-angular-components-tiered-menu.mjs +26 -8
  106. package/fesm2022/seniorsistemas-angular-components-tiered-menu.mjs.map +1 -1
  107. package/fesm2022/seniorsistemas-angular-components-tooltip.mjs +125 -254
  108. package/fesm2022/seniorsistemas-angular-components-tooltip.mjs.map +1 -1
  109. package/fesm2022/seniorsistemas-angular-components-topbar.mjs +2 -2
  110. package/fesm2022/seniorsistemas-angular-components-topbar.mjs.map +1 -1
  111. package/fesm2022/seniorsistemas-angular-components.mjs +12 -1
  112. package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
  113. package/package.json +1 -1
  114. package/select/lib/select/select.component.d.ts +23 -2
  115. package/shared/lib/accessibility/paginator-accessibility.directive.d.ts +30 -0
  116. package/shared/lib/accessibility/table-checkbox-accessibility.directive.d.ts +46 -0
  117. package/shared/public-api.d.ts +7 -5
  118. package/switch/lib/switch/switch.component.d.ts +9 -5
  119. package/tiered-menu/lib/tiered-menu/components/tiered-menu/tiered-menu.component.d.ts +1 -0
  120. package/tiered-menu/lib/tiered-menu/tiered-menu.directive.d.ts +4 -2
  121. package/tooltip/lib/tooltip/tooltip.component.d.ts +13 -7
  122. package/tooltip/lib/tooltip/tooltip.directive.d.ts +27 -40
  123. package/tooltip/lib/tooltip/tooltip.module.d.ts +3 -4
@@ -1,11 +1,12 @@
1
- import { Directive, HostListener, input, Input, } from '@angular/core';
2
- import { getElementLeftoverContentAvailable, getElementPositionInfo, isNullOrUndefined, } from '@seniorsistemas/angular-components/utils';
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { ComponentPortal } from '@angular/cdk/portal';
3
+ import { Directive, ElementRef, HostListener, Renderer2, inject, input, } from '@angular/core';
4
+ import { DebounceUtils } from '@seniorsistemas/angular-components/common';
3
5
  import { TooltipComponent } from './tooltip.component';
4
6
  import * as i0 from "@angular/core";
5
- import * as i1 from "@seniorsistemas/angular-components/common";
6
7
  /**
7
8
  * @description Diretiva que exibe um tooltip (dica de ferramenta) flutuante ao interagir com o elemento hospedeiro.
8
- * Posiciona-se automaticamente considerando o espaço disponível na tela.
9
+ * Posiciona-se automaticamente considerando o espaço disponível na tela, utilizando o CDK Overlay.
9
10
  * Suporta eventos de hover, click e focus, além de comportamentos customizados para mobile.
10
11
  *
11
12
  * @example
@@ -16,33 +17,28 @@ import * as i1 from "@seniorsistemas/angular-components/common";
16
17
  * @category Overlay
17
18
  */
18
19
  export class TooltipDirective {
19
- elementRef;
20
- appRef;
21
- debounceUtils;
22
- renderer;
23
- viewContainerRef;
24
20
  /**
25
21
  * @description Texto exibido no tooltip. Quando vazio ou `undefined`, o tooltip não é renderizado.
26
22
  */
27
- tooltip;
23
+ tooltip = input(undefined, { alias: 'sTooltip' });
28
24
  /**
29
25
  * @description Posição preferencial do tooltip em relação ao elemento hospedeiro.
30
26
  * O tooltip se reposiciona automaticamente se não houver espaço suficiente.
31
27
  *
32
28
  * @default 'top'
33
29
  */
34
- tooltipPosition = 'top';
30
+ tooltipPosition = input('top');
35
31
  /**
36
32
  * @description Tempo em milissegundos antes do tooltip aparecer após o evento de ativação.
37
33
  *
38
34
  * @default 500
39
35
  */
40
- showDelay = 500;
36
+ showDelay = input(500);
41
37
  /**
42
38
  * @description Tempo em milissegundos que o tooltip permanece visível após aparecer.
43
39
  * Quando não informado, o tooltip permanece até o usuário sair do elemento.
44
40
  */
45
- displayTime;
41
+ displayTime = input(undefined);
46
42
  /**
47
43
  * @description Evento do elemento hospedeiro que dispara a exibição do tooltip.
48
44
  * - `'hover'`: exibe ao passar o mouse (padrão).
@@ -51,20 +47,20 @@ export class TooltipDirective {
51
47
  *
52
48
  * @default 'hover'
53
49
  */
54
- tooltipEvent = 'hover';
50
+ tooltipEvent = input('hover');
55
51
  /**
56
52
  * @description Quando `true`, o conteúdo HTML do tooltip é escapado antes de ser renderizado.
57
53
  *
58
54
  * @default false
59
55
  */
60
- escape = false;
56
+ escape = input(false);
61
57
  /**
62
58
  * @description Quando `false`, o tooltip nunca é exibido, mesmo que haja interação do usuário.
63
59
  * Útil para desabilitar tooltips dinamicamente.
64
60
  *
65
61
  * @default true
66
62
  */
67
- visible = true;
63
+ visible = input(true);
68
64
  /**
69
65
  * @description Comportamento do tooltip em dispositivos móveis (touch).
70
66
  * - `'pressing'`: exibe ao pressionar e manter o toque (padrão).
@@ -72,11 +68,11 @@ export class TooltipDirective {
72
68
  *
73
69
  * @default 'pressing'
74
70
  */
75
- mobileBehavior = 'pressing';
71
+ mobileBehavior = input('pressing');
76
72
  /**
77
73
  * @description Referência a um input HTML para sincronizar a exibição do tooltip com o foco no campo.
78
74
  */
79
- focusedInputRef = null;
75
+ focusedInputRef = input(null);
80
76
  /**
81
77
  * @description Quando `true`, o tooltip só é exibido se o texto do elemento estiver truncado (overflow).
82
78
  * Útil para cells de tabela ou elementos com `text-overflow: ellipsis`.
@@ -84,20 +80,17 @@ export class TooltipDirective {
84
80
  * @default false
85
81
  */
86
82
  checkTruncatedText = input(false);
83
+ elementRef = inject(ElementRef);
84
+ overlay = inject(Overlay);
85
+ debounceUtils = inject(DebounceUtils);
86
+ renderer = inject(Renderer2);
87
+ overlayRef = null;
87
88
  componentRef = null;
89
+ positionChangeSubscription = null;
88
90
  showTimeout;
89
91
  touchTimeout;
90
- tooltipDivElement = null;
91
- debounceCreateTooltipFunction;
92
92
  tooltipCreatedByFocus = false;
93
- constructor(elementRef, appRef, debounceUtils, renderer, viewContainerRef) {
94
- this.elementRef = elementRef;
95
- this.appRef = appRef;
96
- this.debounceUtils = debounceUtils;
97
- this.renderer = renderer;
98
- this.viewContainerRef = viewContainerRef;
99
- this.debounceCreateTooltipFunction = this.debounceUtils.debounceLeading(() => this._createTooltip(true, true));
100
- }
93
+ debounceCreateTooltipFunction = this.debounceUtils.debounceLeading(() => this._createTooltip(true, true));
101
94
  ngOnInit() {
102
95
  this.validatePosition();
103
96
  this.updateTooltipVisibilityWhenFocusOnInput();
@@ -105,254 +98,147 @@ export class TooltipDirective {
105
98
  ngOnDestroy() {
106
99
  this.destroy();
107
100
  }
108
- /**
109
- * Manipula a visibilidade do tooltip quando houver uma referência de input.
110
- */
111
- updateTooltipVisibilityWhenFocusOnInput() {
112
- if (this.focusedInputRef) {
113
- const inputFocus = this.focusedInputRef;
114
- const icon = this.getIconFromFocusedInput();
115
- this.renderer.listen(inputFocus, 'focus', () => {
116
- if (icon) {
117
- this._createTooltip(false, false);
118
- this.tooltipCreatedByFocus = true;
119
- }
120
- });
121
- this.renderer.listen(inputFocus, 'blur', () => {
122
- if (icon) {
123
- this.removeTooltip(icon);
124
- this.destroy();
125
- this.tooltipCreatedByFocus = false;
126
- }
127
- });
128
- }
129
- }
130
- /**
131
- * Obtém o elemento do ícone associado ao label do input em focus.
132
- * @returns O ícone do input em focus.
133
- */
134
- getIconFromFocusedInput() {
135
- return this.elementRef.nativeElement;
136
- }
137
- /**
138
- * Remove o tooltip associado ao ícone do input em focus.
139
- * @param icon O ícone do input em focus.
140
- */
141
- removeTooltip(icon) {
142
- const tooltip = icon.querySelector('.tooltip');
143
- if (tooltip) {
144
- tooltip.remove();
145
- }
146
- }
147
101
  // whenever the component with the tooltip is clicked I destroy the tooltip.
148
102
  // whenever a key is pressed on the component with the tooltip I destroy the tooltip.
149
103
  onClick() {
150
- if (this.tooltipEvent === 'hover' &&
104
+ if (this.tooltipEvent() === 'hover' &&
151
105
  !navigator.userAgent.match(/Android/i) &&
152
106
  !navigator.userAgent.match(/iPhone/i)) {
153
107
  this.destroy();
154
108
  }
155
109
  }
156
110
  onFocus() {
157
- if (this.tooltipEvent === 'focus') {
111
+ if (this.tooltipEvent() === 'focus') {
158
112
  this._createTooltip(true, true);
159
113
  }
160
114
  }
161
115
  onBlur() {
162
- if (this.tooltipEvent === 'focus') {
116
+ if (this.tooltipEvent() === 'focus') {
163
117
  this.destroy();
164
118
  }
165
119
  }
166
120
  onMouseEnter() {
167
- if (this.tooltipEvent === 'hover' || this.focusedInputRef) {
121
+ if (this.tooltipEvent() === 'hover' || this.focusedInputRef()) {
168
122
  this.debounceCreateTooltipFunction();
169
123
  }
170
124
  }
171
125
  onMouseLeave() {
172
- if ((this.tooltipEvent === 'hover' || this.focusedInputRef) && !this.tooltipCreatedByFocus) {
126
+ if ((this.tooltipEvent() === 'hover' || this.focusedInputRef()) && !this.tooltipCreatedByFocus) {
173
127
  this.destroy();
174
128
  }
175
129
  }
176
130
  onTouchStart() {
177
- if (this.tooltipEvent === 'hover') {
131
+ if (this.tooltipEvent() === 'hover') {
178
132
  window.clearTimeout(this.touchTimeout);
179
- const _delay = this.mobileBehavior === 'pressing' ? this.showDelay : 0;
133
+ const delay = this.mobileBehavior() === 'pressing' ? this.showDelay() : 0;
180
134
  this.touchTimeout = window.setTimeout(() => {
181
135
  this._createTooltip(true, true);
182
- }, _delay);
136
+ }, delay);
183
137
  }
184
138
  }
185
139
  onTouchEnd() {
186
- if (this.tooltipEvent === 'hover') {
187
- if (this.mobileBehavior === 'pressing') {
188
- window.clearTimeout(this.touchTimeout);
189
- this.destroy();
190
- }
140
+ if (this.tooltipEvent() === 'hover' && this.mobileBehavior() === 'pressing') {
141
+ window.clearTimeout(this.touchTimeout);
142
+ this.destroy();
191
143
  }
192
144
  }
193
145
  validatePosition() {
194
- const containsPosition = ['top', 'right', 'bottom', 'left'].includes(this.tooltipPosition);
146
+ const containsPosition = ['top', 'right', 'bottom', 'left'].includes(this.tooltipPosition());
195
147
  if (!containsPosition) {
196
- this.tooltipPosition = 'top';
197
- throw new Error(`Tooltip ${this.tooltipPosition} position is unexpected`);
148
+ throw new Error(`Tooltip position "${this.tooltipPosition()}" is unexpected`);
198
149
  }
199
150
  }
200
- getDomElement() {
201
- this.componentRef = this.viewContainerRef.createComponent(TooltipComponent);
202
- return this.componentRef.location.nativeElement;
151
+ /**
152
+ * Manipula a visibilidade do tooltip quando houver uma referência de input.
153
+ */
154
+ updateTooltipVisibilityWhenFocusOnInput() {
155
+ const inputRef = this.focusedInputRef();
156
+ if (!inputRef)
157
+ return;
158
+ this.renderer.listen(inputRef, 'focus', () => {
159
+ this._createTooltip(false, false);
160
+ this.tooltipCreatedByFocus = true;
161
+ });
162
+ this.renderer.listen(inputRef, 'blur', () => {
163
+ this.destroy();
164
+ this.tooltipCreatedByFocus = false;
165
+ });
203
166
  }
204
167
  _createTooltip(useShowDelay = false, autoDestroy = true) {
205
- const hasText = (this.tooltip || '').length > 0;
206
- const hasComponentRef = this.componentRef !== null;
207
- if (!hasText || hasComponentRef) {
168
+ const tooltipText = this.tooltip() ?? '';
169
+ if (!tooltipText.length || this.overlayRef !== null)
208
170
  return;
209
- }
210
- const blockIfIsNotTruncatedContent = this.checkTruncatedText() ? !this.contentIsTruncated : false;
211
- if (blockIfIsNotTruncatedContent) {
171
+ if (this.checkTruncatedText() && !this.contentIsTruncated)
212
172
  return;
213
- }
214
- const domElement = this.getDomElement();
215
- document.body.appendChild(domElement);
216
- this.tooltipDivElement = domElement.querySelector('.tooltip');
217
- this.setTooltipComponentProperties();
218
- const _showDelay = useShowDelay ? this.showDelay : 0;
219
- setTimeout(() => {
220
- this.showTooltip();
221
- }, _showDelay);
222
- this.renderer.listen(window, 'scroll', () => {
223
- this.setTooltipPositionProperty();
173
+ const positionStrategy = this.buildPositionStrategy();
174
+ const scrollStrategy = this.overlay.scrollStrategies.reposition();
175
+ this.overlayRef = this.overlay.create({ positionStrategy, scrollStrategy });
176
+ const portal = new ComponentPortal(TooltipComponent);
177
+ this.componentRef = this.overlayRef.attach(portal);
178
+ this.componentRef.setInput('tooltip', tooltipText);
179
+ this.componentRef.setInput('escape', this.escape());
180
+ this.componentRef.setInput('position', this.tooltipPosition());
181
+ this.positionChangeSubscription = positionStrategy.positionChanges.subscribe((change) => {
182
+ const mappedPosition = this.mapCdkPositionToTooltipPosition(change.connectionPair);
183
+ this.componentRef?.setInput('position', mappedPosition);
224
184
  });
225
- if (autoDestroy && this.displayTime) {
226
- setTimeout(() => {
185
+ const delay = useShowDelay ? this.showDelay() : 0;
186
+ this.showTimeout = window.setTimeout(() => {
187
+ this.componentRef?.setInput('visible', this.visible());
188
+ }, delay);
189
+ if (autoDestroy && this.displayTime()) {
190
+ window.setTimeout(() => {
227
191
  this.destroy();
228
- }, this.displayTime);
192
+ }, this.displayTime());
229
193
  }
230
194
  }
231
- showTooltip() {
232
- if (this.componentRef) {
233
- this.componentRef.instance.visible = this.visible;
234
- this.setTooltipPositionProperty();
235
- }
195
+ buildPositionStrategy() {
196
+ const preferred = this.tooltipPosition();
197
+ const allPositions = ['top', 'bottom', 'left', 'right'];
198
+ const orderedPositions = [preferred, ...allPositions.filter((p) => p !== preferred)];
199
+ return this.overlay
200
+ .position()
201
+ .flexibleConnectedTo(this.elementRef)
202
+ .withPositions(orderedPositions.map((p) => this.getConnectedPosition(p)))
203
+ .withFlexibleDimensions(false)
204
+ .withPush(false);
236
205
  }
237
- setTooltipPositionProperty() {
238
- if (!this.componentRef) {
239
- return;
240
- }
241
- const anchorSize = 5;
242
- const { left, right } = this.elementRef.nativeElement.getBoundingClientRect();
243
- const tooltipElementPosition = getElementPositionInfo(this.tooltipDivElement);
244
- const elementLeftover = getElementLeftoverContentAvailable(this.elementRef.nativeElement);
245
- const elementTriggerPosition = getElementPositionInfo(this.elementRef.nativeElement);
246
- const horizontalPositions = ['left', 'right'];
247
- const isPositionHorizontal = horizontalPositions.includes(this.tooltipPosition);
248
- const distanceToBorders = isPositionHorizontal
249
- ? tooltipElementPosition.elementWidth
250
- : tooltipElementPosition.elementHorizontalCenter;
251
- const canSetAtTop = elementLeftover.freeDistanceToTop > tooltipElementPosition.elementHeight;
252
- const canSetAtLeft = elementLeftover.freeDistanceToLeft > distanceToBorders;
253
- const canSetAtRight = elementLeftover.freeDistanceToRight > distanceToBorders;
254
- const canSetAtBottom = elementLeftover.freeDistanceToBottom > tooltipElementPosition.elementHeight;
255
- const topVertical = elementTriggerPosition.top + elementTriggerPosition.elementVerticalCenter;
256
- const checkTopPosition = () => {
257
- return canSetAtTop && canSetAtLeft && canSetAtRight;
206
+ getConnectedPosition(pos) {
207
+ const offset = 10;
208
+ const positionMap = {
209
+ top: { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -offset },
210
+ bottom: { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: offset },
211
+ left: { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -offset },
212
+ right: { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: offset },
258
213
  };
259
- const checkBottomPosition = () => {
260
- return canSetAtBottom && canSetAtLeft && canSetAtRight;
261
- };
262
- const checkLeftPosition = () => {
263
- return canSetAtLeft && canSetAtTop && canSetAtBottom;
264
- };
265
- const checkRightPosition = () => {
266
- return canSetAtRight && canSetAtTop && canSetAtBottom;
267
- };
268
- const setTopPosition = () => {
269
- return {
270
- left: left + (right - left) / 2,
271
- top: elementTriggerPosition.top - anchorSize,
272
- };
273
- };
274
- const setBottomPosition = () => {
275
- return {
276
- left: left + (right - left) / 2,
277
- top: elementTriggerPosition.top + elementTriggerPosition.elementHeight,
278
- };
279
- };
280
- const setLeftPosition = () => {
281
- return {
282
- left: left,
283
- top: topVertical,
284
- };
285
- };
286
- const setRightPosition = () => {
287
- return {
288
- left: right,
289
- top: topVertical,
290
- };
291
- };
292
- const positions = [
293
- {
294
- pos: 'top',
295
- check: checkTopPosition,
296
- set: setTopPosition,
297
- },
298
- {
299
- pos: 'bottom',
300
- check: checkBottomPosition,
301
- set: setBottomPosition,
302
- },
303
- {
304
- pos: 'left',
305
- check: checkLeftPosition,
306
- set: setLeftPosition,
307
- },
308
- {
309
- pos: 'right',
310
- check: checkRightPosition,
311
- set: setRightPosition,
312
- },
313
- ];
314
- const positionDefined = positions.find((position) => position.pos === this.tooltipPosition);
315
- let validPosition = positionDefined;
316
- const canUseDefinedPosition = positionDefined?.check();
317
- if (canUseDefinedPosition) {
318
- validPosition = positionDefined;
319
- }
320
- else if (!canUseDefinedPosition) {
321
- const validAlternativePosition = positions.find((position) => position.check());
322
- if (validAlternativePosition) {
323
- validPosition = validAlternativePosition;
324
- }
325
- }
326
- const _position = validPosition.set();
327
- const positionLeft = _position.left;
328
- const positionTop = _position.top;
329
- this.componentRef.instance.left = Math.round(positionLeft);
330
- this.componentRef.instance.top = Math.round(positionTop);
331
- this.componentRef.instance.position = validPosition.pos;
214
+ return positionMap[pos];
332
215
  }
333
- setTooltipComponentProperties() {
334
- if (!this.componentRef)
335
- return;
336
- this.componentRef.instance.tooltip = this.tooltip;
337
- this.componentRef.instance.escape = this.escape;
216
+ mapCdkPositionToTooltipPosition(pair) {
217
+ if (pair.overlayY === 'bottom')
218
+ return 'top';
219
+ if (pair.overlayY === 'top')
220
+ return 'bottom';
221
+ if (pair.overlayX === 'end')
222
+ return 'left';
223
+ return 'right';
338
224
  }
339
225
  destroy() {
340
- if (!isNullOrUndefined(this.componentRef)) {
341
- window.clearTimeout(this.showTimeout);
342
- this.appRef.detachView(this.componentRef.hostView);
343
- this.componentRef.destroy();
226
+ window.clearTimeout(this.showTimeout);
227
+ window.clearTimeout(this.touchTimeout);
228
+ this.positionChangeSubscription?.unsubscribe();
229
+ this.positionChangeSubscription = null;
230
+ if (this.overlayRef) {
231
+ this.overlayRef.dispose();
232
+ this.overlayRef = null;
344
233
  this.componentRef = null;
345
- this.tooltipDivElement = null;
346
234
  }
347
235
  }
348
236
  get contentIsTruncated() {
349
237
  const element = this.elementRef.nativeElement;
350
- const truncatedByVertical = element.scrollHeight > element.clientHeight;
351
- const truncatedByHorizontal = element.scrollWidth > element.clientWidth;
352
- return truncatedByHorizontal || truncatedByVertical;
238
+ return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
353
239
  }
354
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i1.DebounceUtils }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
355
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: TooltipDirective, isStandalone: true, selector: "[sTooltip]", inputs: { tooltip: { classPropertyName: "tooltip", publicName: "sTooltip", isSignal: false, isRequired: false, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: false, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "showDelay", isSignal: false, isRequired: false, transformFunction: null }, displayTime: { classPropertyName: "displayTime", publicName: "displayTime", isSignal: false, isRequired: false, transformFunction: null }, tooltipEvent: { classPropertyName: "tooltipEvent", publicName: "tooltipEvent", isSignal: false, isRequired: false, transformFunction: null }, escape: { classPropertyName: "escape", publicName: "escape", isSignal: false, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: false, isRequired: false, transformFunction: null }, mobileBehavior: { classPropertyName: "mobileBehavior", publicName: "mobileBehavior", isSignal: false, isRequired: false, transformFunction: null }, focusedInputRef: { classPropertyName: "focusedInputRef", publicName: "focusedInputRef", isSignal: false, isRequired: false, transformFunction: null }, checkTruncatedText: { classPropertyName: "checkTruncatedText", publicName: "checkTruncatedText", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown": "onClick()", "focus": "onFocus()", "blur": "onBlur()", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "wheel": "onMouseLeave()", "touchstart": "onTouchStart()", "touchend": "onTouchEnd()" } }, ngImport: i0 });
240
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
241
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: TooltipDirective, isStandalone: true, selector: "[sTooltip]", inputs: { tooltip: { classPropertyName: "tooltip", publicName: "sTooltip", isSignal: true, isRequired: false, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "showDelay", isSignal: true, isRequired: false, transformFunction: null }, displayTime: { classPropertyName: "displayTime", publicName: "displayTime", isSignal: true, isRequired: false, transformFunction: null }, tooltipEvent: { classPropertyName: "tooltipEvent", publicName: "tooltipEvent", isSignal: true, isRequired: false, transformFunction: null }, escape: { classPropertyName: "escape", publicName: "escape", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, mobileBehavior: { classPropertyName: "mobileBehavior", publicName: "mobileBehavior", isSignal: true, isRequired: false, transformFunction: null }, focusedInputRef: { classPropertyName: "focusedInputRef", publicName: "focusedInputRef", isSignal: true, isRequired: false, transformFunction: null }, checkTruncatedText: { classPropertyName: "checkTruncatedText", publicName: "checkTruncatedText", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown": "onClick()", "focus": "onFocus()", "blur": "onBlur()", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "wheel": "onMouseLeave()", "touchstart": "onTouchStart()", "touchend": "onTouchEnd()" } }, ngImport: i0 });
356
242
  }
357
243
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TooltipDirective, decorators: [{
358
244
  type: Directive,
@@ -360,26 +246,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
360
246
  selector: '[sTooltip]',
361
247
  standalone: true,
362
248
  }]
363
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ApplicationRef }, { type: i1.DebounceUtils }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }], propDecorators: { tooltip: [{
364
- type: Input,
365
- args: ['sTooltip']
366
- }], tooltipPosition: [{
367
- type: Input
368
- }], showDelay: [{
369
- type: Input
370
- }], displayTime: [{
371
- type: Input
372
- }], tooltipEvent: [{
373
- type: Input
374
- }], escape: [{
375
- type: Input
376
- }], visible: [{
377
- type: Input
378
- }], mobileBehavior: [{
379
- type: Input
380
- }], focusedInputRef: [{
381
- type: Input
382
- }], onClick: [{
249
+ }], propDecorators: { onClick: [{
383
250
  type: HostListener,
384
251
  args: ['click']
385
252
  }, {
@@ -407,4 +274,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
407
274
  type: HostListener,
408
275
  args: ['touchend']
409
276
  }] } });
410
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvdG9vbHRpcC9zcmMvbGliL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdILFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUNMLEtBQUssR0FLUixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0gsa0NBQWtDLEVBQ2xDLHNCQUFzQixFQUN0QixpQkFBaUIsR0FDcEIsTUFBTSwwQ0FBMEMsQ0FBQztBQUlsRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBRXZEOzs7Ozs7Ozs7OztHQVdHO0FBS0gsTUFBTSxPQUFPLGdCQUFnQjtJQTJGSjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBOUZyQjs7T0FFRztJQUVJLE9BQU8sQ0FBVTtJQUV4Qjs7Ozs7T0FLRztJQUVJLGVBQWUsR0FBcUIsS0FBSyxDQUFDO0lBRWpEOzs7O09BSUc7SUFFSSxTQUFTLEdBQUcsR0FBRyxDQUFDO0lBRXZCOzs7T0FHRztJQUVJLFdBQVcsQ0FBVTtJQUU1Qjs7Ozs7OztPQU9HO0lBRUksWUFBWSxHQUFpQixPQUFPLENBQUM7SUFFNUM7Ozs7T0FJRztJQUVJLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFFdEI7Ozs7O09BS0c7SUFFSSxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBRXRCOzs7Ozs7T0FNRztJQUVJLGNBQWMsR0FBbUIsVUFBVSxDQUFDO0lBRW5EOztPQUVHO0lBRUksZUFBZSxHQUE0QixJQUFJLENBQUM7SUFFdkQ7Ozs7O09BS0c7SUFDSCxrQkFBa0IsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFMUIsWUFBWSxHQUEwQyxJQUFJLENBQUM7SUFDM0QsV0FBVyxDQUFVO0lBQ3JCLFlBQVksQ0FBVTtJQUN0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QUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDeEUsT0FBTyxxQkFBcUIsSUFBSSxtQkFBbUIsQ0FBQztJQUN4RCxDQUFDO3dHQS9ZUSxnQkFBZ0I7NEZBQWhCLGdCQUFnQjs7NEZBQWhCLGdCQUFnQjtrQkFKNUIsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsWUFBWTtvQkFDdEIsVUFBVSxFQUFFLElBQUk7aUJBQ25COytMQU1VLE9BQU87c0JBRGIsS0FBSzt1QkFBQyxVQUFVO2dCQVVWLGVBQWU7c0JBRHJCLEtBQUs7Z0JBU0MsU0FBUztzQkFEZixLQUFLO2dCQVFDLFdBQVc7c0JBRGpCLEtBQUs7Z0JBWUMsWUFBWTtzQkFEbEIsS0FBSztnQkFTQyxNQUFNO3NCQURaLEtBQUs7Z0JBVUMsT0FBTztzQkFEYixLQUFLO2dCQVdDLGNBQWM7c0JBRHBCLEtBQUs7Z0JBT0MsZUFBZTtzQkFEckIsS0FBSztnQkFtRkMsT0FBTztzQkFGYixZQUFZO3VCQUFDLE9BQU87O3NCQUNwQixZQUFZO3VCQUFDLFNBQVM7Z0JBWWhCLE9BQU87c0JBRGIsWUFBWTt1QkFBQyxPQUFPO2dCQVFkLE1BQU07c0JBRFosWUFBWTt1QkFBQyxNQUFNO2dCQVFiLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsWUFBWTtnQkFTbkIsWUFBWTtzQkFGbEIsWUFBWTt1QkFBQyxZQUFZOztzQkFDekIsWUFBWTt1QkFBQyxPQUFPO2dCQVFkLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsWUFBWTtnQkFZbkIsVUFBVTtzQkFEaEIsWUFBWTt1QkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBcHBsaWNhdGlvblJlZixcbiAgICBDb21wb25lbnRSZWYsXG4gICAgRGlyZWN0aXZlLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIGlucHV0LFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgUmVuZGVyZXIyLFxuICAgIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGVib3VuY2VVdGlscyB9IGZyb20gJ0BzZW5pb3JzaXN0ZW1hcy9hbmd1bGFyLWNvbXBvbmVudHMvY29tbW9uJztcbmltcG9ydCB7XG4gICAgZ2V0RWxlbWVudExlZnRvdmVyQ29udGVudEF2YWlsYWJsZSxcbiAgICBnZXRFbGVtZW50UG9zaXRpb25JbmZvLFxuICAgIGlzTnVsbE9yVW5kZWZpbmVkLFxufSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL3V0aWxzJztcbmltcG9ydCB7IE1vYmlsZUJlaGF2aW9yIH0gZnJvbSAnLi9tb2RlbHMvbW9iaWxlLWJlaGF2aW9yJztcbmltcG9ydCB7IFRvb2x0aXBFdmVudCB9IGZyb20gJy4vbW9kZWxzL3Rvb2x0aXAtZXZlbnQnO1xuaW1wb3J0IHsgVG9vbHRpcFBvc2l0aW9ucyB9IGZyb20gJy4vbW9kZWxzL3Rvb2x0aXAtcG9zaXRpb24nO1xuaW1wb3J0IHsgVG9vbHRpcENvbXBvbmVudCB9IGZyb20gJy4vdG9vbHRpcC5jb21wb25lbnQnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEaXJldGl2YSBxdWUgZXhpYmUgdW0gdG9vbHRpcCAoZGljYSBkZSBmZXJyYW1lbnRhKSBmbHV0dWFudGUgYW8gaW50ZXJhZ2lyIGNvbSBvIGVsZW1lbnRvIGhvc3BlZGVpcm8uXG4gKiBQb3NpY2lvbmEtc2UgYXV0b21hdGljYW1lbnRlIGNvbnNpZGVyYW5kbyBvIGVzcGHDp28gZGlzcG9uw612ZWwgbmEgdGVsYS5cbiAqIFN1cG9ydGEgZXZlbnRvcyBkZSBob3ZlciwgY2xpY2sgZSBmb2N1cywgYWzDqW0gZGUgY29tcG9ydGFtZW50b3MgY3VzdG9taXphZG9zIHBhcmEgbW9iaWxlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8YnV0dG9uIHNUb29sdGlwPVwiQ2xpcXVlIGFxdWlcIiB0b29sdGlwUG9zaXRpb249XCJ0b3BcIj5Bw6fDo288L2J1dHRvbj5cbiAqIGBgYFxuICpcbiAqIEBjYXRlZ29yeSBPdmVybGF5XG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW3NUb29sdGlwXScsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgVG9vbHRpcERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gVGV4dG8gZXhpYmlkbyBubyB0b29sdGlwLiBRdWFuZG8gdmF6aW8gb3UgYHVuZGVmaW5lZGAsIG8gdG9vbHRpcCBuw6NvIMOpIHJlbmRlcml6YWRvLlxuICAgICAqL1xuICAgIEBJbnB1dCgnc1Rvb2x0aXAnKVxuICAgIHB1YmxpYyB0b29sdGlwPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIFBvc2nDp8OjbyBwcmVmZXJlbmNpYWwgZG8gdG9vbHRpcCBlbSByZWxhw6fDo28gYW8gZWxlbWVudG8gaG9zcGVkZWlyby5cbiAgICAgKiBPIHRvb2x0aXAgc2UgcmVwb3NpY2lvbmEgYXV0b21hdGljYW1lbnRlIHNlIG7Do28gaG91dmVyIGVzcGHDp28gc3VmaWNpZW50ZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICd0b3AnXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgdG9vbHRpcFBvc2l0aW9uOiBUb29sdGlwUG9zaXRpb25zID0gJ3RvcCc7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gVGVtcG8gZW0gbWlsaXNzZWd1bmRvcyBhbnRlcyBkbyB0b29sdGlwIGFwYXJlY2VyIGFww7NzIG8gZXZlbnRvIGRlIGF0aXZhw6fDo28uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCA1MDBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzaG93RGVsYXkgPSA1MDA7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gVGVtcG8gZW0gbWlsaXNzZWd1bmRvcyBxdWUgbyB0b29sdGlwIHBlcm1hbmVjZSB2aXPDrXZlbCBhcMOzcyBhcGFyZWNlci5cbiAgICAgKiBRdWFuZG8gbsOjbyBpbmZvcm1hZG8sIG8gdG9vbHRpcCBwZXJtYW5lY2UgYXTDqSBvIHVzdcOhcmlvIHNhaXIgZG8gZWxlbWVudG8uXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZGlzcGxheVRpbWU/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gRXZlbnRvIGRvIGVsZW1lbnRvIGhvc3BlZGVpcm8gcXVlIGRpc3BhcmEgYSBleGliacOnw6NvIGRvIHRvb2x0aXAuXG4gICAgICogLSBgJ2hvdmVyJ2A6IGV4aWJlIGFvIHBhc3NhciBvIG1vdXNlIChwYWRyw6NvKS5cbiAgICAgKiAtIGAnY2xpY2snYDogZXhpYmUgYW8gY2xpY2FyLlxuICAgICAqIC0gYCdmb2N1cydgOiBleGliZSBhbyBmb2NhciBubyBlbGVtZW50by5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdob3ZlcidcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyB0b29sdGlwRXZlbnQ6IFRvb2x0aXBFdmVudCA9ICdob3Zlcic7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gUXVhbmRvIGB0cnVlYCwgbyBjb250ZcO6ZG8gSFRNTCBkbyB0b29sdGlwIMOpIGVzY2FwYWRvIGFudGVzIGRlIHNlciByZW5kZXJpemFkby5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZXNjYXBlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gUXVhbmRvIGBmYWxzZWAsIG8gdG9vbHRpcCBudW5jYSDDqSBleGliaWRvLCBtZXNtbyBxdWUgaGFqYSBpbnRlcmHDp8OjbyBkbyB1c3XDoXJpby5cbiAgICAgKiDDmnRpbCBwYXJhIGRlc2FiaWxpdGFyIHRvb2x0aXBzIGRpbmFtaWNhbWVudGUuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgdmlzaWJsZSA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ29tcG9ydGFtZW50byBkbyB0b29sdGlwIGVtIGRpc3Bvc2l0aXZvcyBtw7N2ZWlzICh0b3VjaCkuXG4gICAgICogLSBgJ3ByZXNzaW5nJ2A6IGV4aWJlIGFvIHByZXNzaW9uYXIgZSBtYW50ZXIgbyB0b3F1ZSAocGFkcsOjbykuXG4gICAgICogLSBgJ25vbmUnYDogZGVzYWJpbGl0YSBvIHRvb2x0aXAgZW0gZGlzcG9zaXRpdm9zIHTDoXRlaXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAncHJlc3NpbmcnXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgbW9iaWxlQmVoYXZpb3I6IE1vYmlsZUJlaGF2aW9yID0gJ3ByZXNzaW5nJztcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBSZWZlcsOqbmNpYSBhIHVtIGlucHV0IEhUTUwgcGFyYSBzaW5jcm9uaXphciBhIGV4aWJpw6fDo28gZG8gdG9vbHRpcCBjb20gbyBmb2NvIG5vIGNhbXBvLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGZvY3VzZWRJbnB1dFJlZjogSFRNTElucHV0RWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIFF1YW5kbyBgdHJ1ZWAsIG8gdG9vbHRpcCBzw7Mgw6kgZXhpYmlkbyBzZSBvIHRleHRvIGRvIGVsZW1lbnRvIGVzdGl2ZXIgdHJ1bmNhZG8gKG92ZXJmbG93KS5cbiAgICAgKiDDmnRpbCBwYXJhIGNlbGxzIGRlIHRhYmVsYSBvdSBlbGVtZW50b3MgY29tIGB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpc2AuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIGNoZWNrVHJ1bmNhdGVkVGV4dCA9IGlucHV0KGZhbHNlKTtcblxuICAgIHByaXZhdGUgY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8VG9vbHRpcENvbXBvbmVudD4gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHNob3dUaW1lb3V0PzogbnVtYmVyO1xuICAgIHByaXZhdGUgdG91Y2hUaW1lb3V0PzogbnVtYmVyO1xuICAgIHByaXZhdGUgdG9vbHRpcERpdkVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWJvdW5jZUNyZWF0ZVRvb2x0aXBGdW5jdGlvbjogKCkgPT4gdm9pZDtcbiAgICBwcml2YXRlIHRvb2x0aXBDcmVhdGVkQnlGb2N1cyA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGRlYm91bmNlVXRpbHM6IERlYm91bmNlVXRpbHMsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgICkge1xuICAgICAgICB0aGlzLmRlYm91bmNlQ3JlYXRlVG9vbHRpcEZ1bmN0aW9uID0gdGhpcy5kZWJvdW5jZVV0aWxzLmRlYm91bmNlTGVhZGluZygoKSA9PiB0aGlzLl9jcmVhdGVUb29sdGlwKHRydWUsIHRydWUpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVQb3NpdGlvbigpO1xuICAgICAgICB0aGlzLnVwZGF0ZVRvb2x0aXBWaXNpYmlsaXR5V2hlbkZvY3VzT25JbnB1dCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFuaXB1bGEgYSB2aXNpYmlsaWRhZGUgZG8gdG9vbHRpcCBxdWFuZG8gaG91dmVyIHVtYSByZWZlcsOqbmNpYSBkZSBpbnB1dC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZVRvb2x0aXBWaXNpYmlsaXR5V2hlbkZvY3VzT25JbnB1dCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9jdXNlZElucHV0UmVmKSB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dEZvY3VzID0gdGhpcy5mb2N1c2VkSW5wdXRSZWY7XG4gICAgICAgICAgICBjb25zdCBpY29uID0gdGhpcy5nZXRJY29uRnJvbUZvY3VzZWRJbnB1dCgpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oaW5wdXRGb2N1cywgJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpY29uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRvb2x0aXAoZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b29sdGlwQ3JlYXRlZEJ5Rm9jdXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oaW5wdXRGb2N1cywgJ2JsdXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGljb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVUb29sdGlwKGljb24pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b29sdGlwQ3JlYXRlZEJ5Rm9jdXMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9idMOpbSBvIGVsZW1lbnRvIGRvIMOtY29uZSBhc3NvY2lhZG8gYW8gbGFiZWwgZG8gaW5wdXQgZW0gZm9jdXMuXG4gICAgICogQHJldHVybnMgTyDDrWNvbmUgZG8gaW5wdXQgZW0gZm9jdXMuXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRJY29uRnJvbUZvY3VzZWRJbnB1dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgbyB0b29sdGlwIGFzc29jaWFkbyBhbyDDrWNvbmUgZG8gaW5wdXQgZW0gZm9jdXMuXG4gICAgICogQHBhcmFtIGljb24gTyDDrWNvbmUgZG8gaW5wdXQgZW0gZm9jdXMuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZW1vdmVUb29sdGlwKGljb246IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSBpY29uLnF1ZXJ5U2VsZWN0b3IoJy50b29sdGlwJykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGlmICh0b29sdGlwKSB7XG4gICAgICAgICAgICB0b29sdGlwLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2hlbmV2ZXIgdGhlIGNvbXBvbmVudCB3aXRoIHRoZSB0b29sdGlwIGlzIGNsaWNrZWQgSSBkZXN0cm95IHRoZSB0b29sdGlwLlxuICAgIC8vIHdoZW5ldmVyIGEga2V5IGlzIHByZXNzZWQgb24gdGhlIGNvbXBvbmVudCB3aXRoIHRoZSB0b29sdGlwIEkgZGVzdHJveSB0aGUgdG9vbHRpcC5cbiAgICBASG9zdExpc3RlbmVyKCdjbGljaycpXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicpXG4gICAgcHVibGljIG9uQ2xpY2soKTogdm9pZCB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcEV2ZW50ID09PSAnaG92ZXInICYmXG4gICAgICAgICAgICAhbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSAmJlxuICAgICAgICAgICAgIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZS9pKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignZm9jdXMnKVxuICAgIHB1YmxpYyBvbkZvY3VzKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50b29sdGlwRXZlbnQgPT09ICdmb2N1cycpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRvb2x0aXAodHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdibHVyJylcbiAgICBwdWJsaWMgb25CbHVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50b29sdGlwRXZlbnQgPT09ICdmb2N1cycpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2VlbnRlcicpXG4gICAgcHVibGljIG9uTW91c2VFbnRlcigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudG9vbHRpcEV2ZW50ID09PSAnaG92ZXInIHx8IHRoaXMuZm9jdXNlZElucHV0UmVmKSB7XG4gICAgICAgICAgICB0aGlzLmRlYm91bmNlQ3JlYXRlVG9vbHRpcEZ1bmN0aW9uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJylcbiAgICBASG9zdExpc3RlbmVyKCd3aGVlbCcpXG4gICAgcHVibGljIG9uTW91c2VMZWF2ZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCh0aGlzLnRvb2x0aXBFdmVudCA9PT0gJ2hvdmVyJyB8fCB0aGlzLmZvY3VzZWRJbnB1dFJlZikgJiYgIXRoaXMudG9vbHRpcENyZWF0ZWRCeUZvY3VzKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnKVxuICAgIHB1YmxpYyBvblRvdWNoU3RhcnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXBFdmVudCA9PT0gJ2hvdmVyJykge1xuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLnRvdWNoVGltZW91dCk7XG4gICAgICAgICAgICBjb25zdCBfZGVsYXkgPSB0aGlzLm1vYmlsZUJlaGF2aW9yID09PSAncHJlc3NpbmcnID8gdGhpcy5zaG93RGVsYXkgOiAwO1xuICAgICAgICAgICAgdGhpcy50b3VjaFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlVG9vbHRpcCh0cnVlLCB0cnVlKTtcbiAgICAgICAgICAgIH0sIF9kZWxheSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCd0b3VjaGVuZCcpXG4gICAgcHVibGljIG9uVG91Y2hFbmQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXBFdmVudCA9PT0gJ2hvdmVyJykge1xuICAgICAgICAgICAgaWYgKHRoaXMubW9iaWxlQmVoYXZpb3IgPT09ICdwcmVzc2luZycpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMudG91Y2hUaW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdmFsaWRhdGVQb3NpdGlvbigpIHtcbiAgICAgICAgY29uc3QgY29udGFpbnNQb3NpdGlvbiA9IFsndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsICdsZWZ0J10uaW5jbHVkZXModGhpcy50b29sdGlwUG9zaXRpb24pO1xuXG4gICAgICAgIGlmICghY29udGFpbnNQb3NpdGlvbikge1xuICAgICAgICAgICAgdGhpcy50b29sdGlwUG9zaXRpb24gPSAndG9wJztcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9vbHRpcCAke3RoaXMudG9vbHRpcFBvc2l0aW9ufSBwb3NpdGlvbiBpcyB1bmV4cGVjdGVkYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERvbUVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoVG9vbHRpcENvbXBvbmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudFJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIHByaXZhdGUgX2NyZWF0ZVRvb2x0aXAodXNlU2hvd0RlbGF5ID0gZmFsc2UsIGF1dG9EZXN0cm95ID0gdHJ1ZSkge1xuICAgICAgICBjb25zdCBoYXNUZXh0ID0gKHRoaXMudG9vbHRpcCB8fCAnJykubGVuZ3RoID4gMDtcbiAgICAgICAgY29uc3QgaGFzQ29tcG9uZW50UmVmID0gdGhpcy5jb21wb25lbnRSZWYgIT09IG51bGw7XG4gICAgICAgIGlmICghaGFzVGV4dCB8fCBoYXNDb21wb25lbnRSZWYpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBibG9ja0lmSXNOb3RUcnVuY2F0ZWRDb250ZW50ID0gdGhpcy5jaGVja1RydW5jYXRlZFRleHQoKSA/ICF0aGlzLmNvbnRlbnRJc1RydW5jYXRlZCA6IGZhbHNlO1xuICAgICAgICBpZiAoYmxvY2tJZklzTm90VHJ1bmNhdGVkQ29udGVudCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSB0aGlzLmdldERvbUVsZW1lbnQoKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb21FbGVtZW50KTtcbiAgICAgICAgdGhpcy50b29sdGlwRGl2RWxlbWVudCA9IGRvbUVsZW1lbnQucXVlcnlTZWxlY3RvcignLnRvb2x0aXAnKTtcbiAgICAgICAgdGhpcy5zZXRUb29sdGlwQ29tcG9uZW50UHJvcGVydGllcygpO1xuICAgICAgICBjb25zdCBfc2hvd0RlbGF5ID0gdXNlU2hvd0RlbGF5ID8gdGhpcy5zaG93RGVsYXkgOiAwO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2hvd1Rvb2x0aXAoKTtcbiAgICAgICAgfSwgX3Nob3dEZWxheSk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4od2luZG93LCAnc2Nyb2xsJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXRUb29sdGlwUG9zaXRpb25Qcm9wZXJ0eSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYXV0b0Rlc3Ryb3kgJiYgdGhpcy5kaXNwbGF5VGltZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICAgICAgICB9LCB0aGlzLmRpc3BsYXlUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2hvd1Rvb2x0aXAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbXBvbmVudFJlZikge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UudmlzaWJsZSA9IHRoaXMudmlzaWJsZTtcblxuICAgICAgICAgICAgdGhpcy5zZXRUb29sdGlwUG9zaXRpb25Qcm9wZXJ0eSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRUb29sdGlwUG9zaXRpb25Qcm9wZXJ0eSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbXBvbmVudFJlZikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFuY2hvclNpemUgPSA1O1xuICAgICAgICBjb25zdCB7IGxlZnQsIHJpZ2h0IH0gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICBjb25zdCB0b29sdGlwRWxlbWVudFBvc2l0aW9uID0gZ2V0RWxlbWVudFBvc2l0aW9uSW5mbyh0aGlzLnRvb2x0aXBEaXZFbGVtZW50ISk7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRMZWZ0b3ZlciA9IGdldEVsZW1lbnRMZWZ0b3ZlckNvbnRlbnRBdmFpbGFibGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICBjb25zdCBlbGVtZW50VHJpZ2dlclBvc2l0aW9uID0gZ2V0RWxlbWVudFBvc2l0aW9uSW5mbyh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIGNvbnN0IGhvcml6b250YWxQb3NpdGlvbnM6IFRvb2x0aXBQb3NpdGlvbnNbXSA9IFsnbGVmdCcsICdyaWdodCddO1xuICAgICAgICBjb25zdCBpc1Bvc2l0aW9uSG9yaXpvbnRhbCA9IGhvcml6b250YWxQb3NpdGlvbnMuaW5jbHVkZXModGhpcy50b29sdGlwUG9zaXRpb24pO1xuICAgICAgICBjb25zdCBkaXN0YW5jZVRvQm9yZGVycyA9IGlzUG9zaXRpb25Ib3Jpem9udGFsXG4gICAgICAgICAgICA/IHRvb2x0aXBFbGVtZW50UG9zaXRpb24uZWxlbWVudFdpZHRoXG4gICAgICAgICAgICA6IHRvb2x0aXBFbGVtZW50UG9zaXRpb24uZWxlbWVudEhvcml6b250YWxDZW50ZXI7XG4gICAgICAgIGNvbnN0IGNhblNldEF0VG9wID0gZWxlbWVudExlZnRvdmVyLmZyZWVEaXN0YW5jZVRvVG9wID4gdG9vbHRpcEVsZW1lbnRQb3NpdGlvbi5lbGVtZW50SGVpZ2h0O1xuICAgICAgICBjb25zdCBjYW5TZXRBdExlZnQgPSBlbGVtZW50TGVmdG92ZXIuZnJlZURpc3RhbmNlVG9MZWZ0ID4gZGlzdGFuY2VUb0JvcmRlcnM7XG4gICAgICAgIGNvbnN0IGNhblNldEF0UmlnaHQgPSBlbGVtZW50TGVmdG92ZXIuZnJlZURpc3RhbmNlVG9SaWdodCA+IGRpc3RhbmNlVG9Cb3JkZXJzO1xuICAgICAgICBjb25zdCBjYW5TZXRBdEJvdHRvbSA9IGVsZW1lbnRMZWZ0b3Zlci5mcmVlRGlzdGFuY2VUb0JvdHRvbSA+IHRvb2x0aXBFbGVtZW50UG9zaXRpb24uZWxlbWVudEhlaWdodDtcbiAgICAgICAgY29uc3QgdG9wVmVydGljYWwgPSBlbGVtZW50VHJpZ2dlclBvc2l0aW9uLnRvcCArIGVsZW1lbnRUcmlnZ2VyUG9zaXRpb24uZWxlbWVudFZlcnRpY2FsQ2VudGVyO1xuICAgICAgICBjb25zdCBjaGVja1RvcFBvc2l0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNhblNldEF0VG9wICYmIGNhblNldEF0TGVmdCAmJiBjYW5TZXRBdFJpZ2h0O1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjaGVja0JvdHRvbVBvc2l0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNhblNldEF0Qm90dG9tICYmIGNhblNldEF0TGVmdCAmJiBjYW5TZXRBdFJpZ2h0O1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjaGVja0xlZnRQb3NpdGlvbiA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBjYW5TZXRBdExlZnQgJiYgY2FuU2V0QXRUb3AgJiYgY2FuU2V0QXRCb3R0b207XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgY2hlY2tSaWdodFBvc2l0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNhblNldEF0UmlnaHQgJiYgY2FuU2V0QXRUb3AgJiYgY2FuU2V0QXRCb3R0b207XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc2V0VG9wUG9zaXRpb24gPSAoKTogeyBsZWZ0OiBudW1iZXI7IHRvcDogbnVtYmVyIH0gPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBsZWZ0OiBsZWZ0ICsgKHJpZ2h0IC0gbGVmdCkgLyAyLFxuICAgICAgICAgICAgICAgIHRvcDogZWxlbWVudFRyaWdnZXJQb3NpdGlvbi50b3AgLSBhbmNob3JTaXplLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzZXRCb3R0b21Qb3NpdGlvbiA9ICgpOiB7IGxlZnQ6IG51bWJlcjsgdG9wOiBudW1iZXIgfSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGxlZnQ6IGxlZnQgKyAocmlnaHQgLSBsZWZ0KSAvIDIsXG4gICAgICAgICAgICAgICAgdG9wOiBlbGVtZW50VHJpZ2dlclBvc2l0aW9uLnRvcCArIGVsZW1lbnRUcmlnZ2VyUG9zaXRpb24uZWxlbWVudEhlaWdodCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc2V0TGVmdFBvc2l0aW9uID0gKCk6IHsgbGVmdDogbnVtYmVyOyB0b3A6IG51bWJlciB9ID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgICAgICAgICB0b3A6IHRvcFZlcnRpY2FsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzZXRSaWdodFBvc2l0aW9uID0gKCk6IHsgbGVmdDogbnVtYmVyOyB0b3A6IG51bWJlciB9ID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbGVmdDogcmlnaHQsXG4gICAgICAgICAgICAgICAgdG9wOiB0b3BWZXJ0aWNhbCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgdHlwZSBQb3NpdGlvbiA9IHtcbiAgICAgICAgICAgIHBvczogVG9vbHRpcFBvc2l0aW9ucztcbiAgICAgICAgICAgIGNoZWNrOiAoKSA9PiBib29sZWFuO1xuICAgICAgICAgICAgc2V0OiAoKSA9PiB7IGxlZnQ6IG51bWJlcjsgdG9wOiBudW1iZXIgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBwb3NpdGlvbnM6IFBvc2l0aW9uW10gPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcG9zOiAndG9wJyxcbiAgICAgICAgICAgICAgICBjaGVjazogY2hlY2tUb3BQb3NpdGlvbixcbiAgICAgICAgICAgICAgICBzZXQ6IHNldFRvcFBvc2l0aW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwb3M6ICdib3R0b20nLFxuICAgICAgICAgICAgICAgIGNoZWNrOiBjaGVja0JvdHRvbVBvc2l0aW9uLFxuICAgICAgICAgICAgICAgIHNldDogc2V0Qm90dG9tUG9zaXRpb24sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHBvczogJ2xlZnQnLFxuICAgICAgICAgICAgICAgIGNoZWNrOiBjaGVja0xlZnRQb3NpdGlvbixcbiAgICAgICAgICAgICAgICBzZXQ6IHNldExlZnRQb3NpdGlvbixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcG9zOiAncmlnaHQnLFxuICAgICAgICAgICAgICAgIGNoZWNrOiBjaGVja1JpZ2h0UG9zaXRpb24sXG4gICAgICAgICAgICAgICAgc2V0OiBzZXRSaWdodFBvc2l0aW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwb3NpdGlvbkRlZmluZWQgPSBwb3NpdGlvbnMuZmluZCgocG9zaXRpb24pID0+IHBvc2l0aW9uLnBvcyA9PT0gdGhpcy50b29sdGlwUG9zaXRpb24pO1xuICAgICAgICBsZXQgdmFsaWRQb3NpdGlvbjogUG9zaXRpb24gfCB1bmRlZmluZWQgPSBwb3NpdGlvbkRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGNhblVzZURlZmluZWRQb3NpdGlvbiA9IHBvc2l0aW9uRGVmaW5lZD8uY2hlY2soKTtcbiAgICAgICAgaWYgKGNhblVzZURlZmluZWRQb3NpdGlvbikge1xuICAgICAgICAgICAgdmFsaWRQb3NpdGlvbiA9IHBvc2l0aW9uRGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIGlmICghY2FuVXNlRGVmaW5lZFBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCB2YWxpZEFsdGVybmF0aXZlUG9zaXRpb24gPSBwb3NpdGlvbnMuZmluZCgocG9zaXRpb24pID0+IHBvc2l0aW9uLmNoZWNrKCkpO1xuICAgICAgICAgICAgaWYgKHZhbGlkQWx0ZXJuYXRpdmVQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIHZhbGlkUG9zaXRpb24gPSB2YWxpZEFsdGVybmF0aXZlUG9zaXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgX3Bvc2l0aW9uID0gdmFsaWRQb3NpdGlvbiEuc2V0KCk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uTGVmdCA9IF9wb3NpdGlvbi5sZWZ0O1xuICAgICAgICBjb25zdCBwb3NpdGlvblRvcCA9IF9wb3NpdGlvbi50b3A7XG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLmxlZnQgPSBNYXRoLnJvdW5kKHBvc2l0aW9uTGVmdCk7XG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLnRvcCA9IE1hdGgucm91bmQocG9zaXRpb25Ub3ApO1xuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5wb3NpdGlvbiA9IHZhbGlkUG9zaXRpb24hLnBvcztcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldFRvb2x0aXBDb21wb25lbnRQcm9wZXJ0aWVzKCkge1xuICAgICAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVmKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UudG9vbHRpcCA9IHRoaXMudG9vbHRpcCBhcyBzdHJpbmc7XG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLmVzY2FwZSA9IHRoaXMuZXNjYXBlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZCh0aGlzLmNvbXBvbmVudFJlZikpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5zaG93VGltZW91dCk7XG4gICAgICAgICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UmVmID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcERpdkVsZW1lbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXQgY29udGVudElzVHJ1bmNhdGVkKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHRydW5jYXRlZEJ5VmVydGljYWwgPSBlbGVtZW50LnNjcm9sbEhlaWdodCA+IGVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgICAgICBjb25zdCB0cnVuY2F0ZWRCeUhvcml6b250YWwgPSBlbGVtZW50LnNjcm9sbFdpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICAgICAgcmV0dXJuIHRydW5jYXRlZEJ5SG9yaXpvbnRhbCB8fCB0cnVuY2F0ZWRCeVZlcnRpY2FsO1xuICAgIH1cbn1cblxuIl19
277
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvdG9vbHRpcC9zcmMvbGliL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUF3RCxPQUFPLEVBQWMsTUFBTSxzQkFBc0IsQ0FBQztBQUNqSCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUVILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUdaLFNBQVMsRUFDVCxNQUFNLEVBQ04sS0FBSyxHQUNSLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUkxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7QUFFdkQ7Ozs7Ozs7Ozs7O0dBV0c7QUFLSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQ3pCOztPQUVHO0lBQ2EsT0FBTyxHQUFHLEtBQUssQ0FBcUIsU0FBUyxFQUFFLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFFdEY7Ozs7O09BS0c7SUFDYSxlQUFlLEdBQUcsS0FBSyxDQUFtQixLQUFLLENBQUMsQ0FBQztJQUVqRTs7OztPQUlHO0lBQ2EsU0FBUyxHQUFHLEtBQUssQ0FBUyxHQUFHLENBQUMsQ0FBQztJQUUvQzs7O09BR0c7SUFDYSxXQUFXLEdBQUcsS0FBSyxDQUFxQixTQUFTLENBQUMsQ0FBQztJQUVuRTs7Ozs7OztPQU9HO0lBQ2EsWUFBWSxHQUFHLEtBQUssQ0FBZSxPQUFPLENBQUMsQ0FBQztJQUU1RDs7OztPQUlHO0lBQ2EsTUFBTSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUUvQzs7Ozs7T0FLRztJQUNhLE9BQU8sR0FBRyxLQUFLLENBQVUsSUFBSSxDQUFDLENBQUM7SUFFL0M7Ozs7OztPQU1HO0lBQ2EsY0FBYyxHQUFHLEtBQUssQ0FBaUIsVUFBVSxDQUFDLENBQUM7SUFFbkU7O09BRUc7SUFDYSxlQUFlLEdBQUcsS0FBSyxDQUEwQixJQUFJLENBQUMsQ0FBQztJQUV2RTs7Ozs7T0FLRztJQUNhLGtCQUFrQixHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUUxQyxVQUFVLEdBQUcsTUFBTSxDQUEwQixVQUFVLENBQUMsQ0FBQztJQUN6RCxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFCLGFBQWEsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdEMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV0QyxVQUFVLEdBQXNCLElBQUksQ0FBQztJQUNyQyxZQUFZLEdBQTBDLElBQUksQ0FBQztJQUMzRCwwQkFBMEIsR0FBd0IsSUFBSSxDQUFDO0lBQ3ZELFdBQVcsQ0FBVTtJQUNyQixZQUFZLENBQVU7SUFDdEIscUJBQXFCLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLDZCQUE2QixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUNyRixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FDbEMsQ0FBQztJQUVLLFFBQVE7UUFDWCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsdUNBQXVDLEVBQUUsQ0FBQztJQUNuRCxDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLHFGQUFxRjtJQUc5RSxPQUFPO1FBQ1YsSUFDSSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssT0FBTztZQUMvQixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztZQUN0QyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUN2QyxDQUFDO1lBQ0MsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25CLENBQUM7SUFDTCxDQUFDO0lBR00sT0FBTztRQUNWLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDTCxDQUFDO0lBR00sTUFBTTtRQUNULElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuQixDQUFDO0lBQ0wsQ0FBQztJQUdNLFlBQVk7UUFDZixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDNUQsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7UUFDekMsQ0FBQztJQUNMLENBQUM7SUFJTSxZQUFZO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUM3RixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsQ0FBQztJQUNMLENBQUM7SUFHTSxZQUFZO1FBQ2YsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDbEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUUsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDdkMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2QsQ0FBQztJQUNMLENBQUM7SUFHTSxVQUFVO1FBQ2IsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUMxRSxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsQ0FBQztJQUNMLENBQUM7SUFFTyxnQkFBZ0I7UUFDcEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUM3RixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixJQUFJLENBQUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFDbEYsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLHVDQUF1QztRQUMzQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRXRCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ3pDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRTtZQUN4QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLGNBQWMsQ0FBQyxZQUFZLEdBQUcsS0FBSyxFQUFFLFdBQVcsR0FBRyxJQUFJO1FBQzNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJO1lBQUUsT0FBTztRQUU1RCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQjtZQUFFLE9BQU87UUFFbEUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUN0RCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWxFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUUvRCxJQUFJLENBQUMsMEJBQTBCLEdBQUcsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3BGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDbkYsSUFBSSxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3RDLElBQUksQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFVixJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUNwQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25CLENBQUMsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFHLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0wsQ0FBQztJQUVPLHFCQUFxQjtRQUN6QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDekMsTUFBTSxZQUFZLEdBQXVCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDNUUsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBRXJGLE9BQU8sSUFBSSxDQUFDLE9BQU87YUFDZCxRQUFRLEVBQUU7YUFDVixtQkFBbUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2FBQ3BDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3hFLHNCQUFzQixDQUFDLEtBQUssQ0FBQzthQUM3QixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLEdBQXFCO1FBQzlDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNsQixNQUFNLFdBQVcsR0FBZ0Q7WUFDN0QsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUU7WUFDcEcsTUFBTSxFQUFFLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFO1lBQ3RHLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFO1lBQ3BHLEtBQUssRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRTtTQUN2RyxDQUFDO1FBQ0YsT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVPLCtCQUErQixDQUFDLElBQTRDO1FBQ2hGLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDN0MsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUs7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM3QyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSztZQUFFLE9BQU8sTUFBTSxDQUFDO1FBQzNDLE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFTyxPQUFPO1FBQ1gsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQywwQkFBMEIsR0FBRyxJQUFJLENBQUM7UUFDdkMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO0lBQ0wsQ0FBQztJQUVELElBQVksa0JBQWtCO1FBQzFCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBNEIsQ0FBQztRQUM3RCxPQUFPLE9BQU8sQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7SUFDcEcsQ0FBQzt3R0F6UVEsZ0JBQWdCOzRGQUFoQixnQkFBZ0I7OzRGQUFoQixnQkFBZ0I7a0JBSjVCLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLFlBQVk7b0JBQ3RCLFVBQVUsRUFBRSxJQUFJO2lCQUNuQjs4QkF1R1UsT0FBTztzQkFGYixZQUFZO3VCQUFDLE9BQU87O3NCQUNwQixZQUFZO3VCQUFDLFNBQVM7Z0JBWWhCLE9BQU87c0JBRGIsWUFBWTt1QkFBQyxPQUFPO2dCQVFkLE1BQU07c0JBRFosWUFBWTt1QkFBQyxNQUFNO2dCQVFiLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsWUFBWTtnQkFTbkIsWUFBWTtzQkFGbEIsWUFBWTt1QkFBQyxZQUFZOztzQkFDekIsWUFBWTt1QkFBQyxPQUFPO2dCQVFkLFlBQVk7c0JBRGxCLFlBQVk7dUJBQUMsWUFBWTtnQkFZbkIsVUFBVTtzQkFEaEIsWUFBWTt1QkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29ubmVjdGVkUG9zaXRpb24sIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSwgT3ZlcmxheSwgT3ZlcmxheVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHtcbiAgICBDb21wb25lbnRSZWYsXG4gICAgRGlyZWN0aXZlLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgUmVuZGVyZXIyLFxuICAgIGluamVjdCxcbiAgICBpbnB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERlYm91bmNlVXRpbHMgfSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL2NvbW1vbic7XG5pbXBvcnQgeyBNb2JpbGVCZWhhdmlvciB9IGZyb20gJy4vbW9kZWxzL21vYmlsZS1iZWhhdmlvcic7XG5pbXBvcnQgeyBUb29sdGlwRXZlbnQgfSBmcm9tICcuL21vZGVscy90b29sdGlwLWV2ZW50JztcbmltcG9ydCB7IFRvb2x0aXBQb3NpdGlvbnMgfSBmcm9tICcuL21vZGVscy90b29sdGlwLXBvc2l0aW9uJztcbmltcG9ydCB7IFRvb2x0aXBDb21wb25lbnQgfSBmcm9tICcuL3Rvb2x0aXAuY29tcG9uZW50JztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGlyZXRpdmEgcXVlIGV4aWJlIHVtIHRvb2x0aXAgKGRpY2EgZGUgZmVycmFtZW50YSkgZmx1dHVhbnRlIGFvIGludGVyYWdpciBjb20gbyBlbGVtZW50byBob3NwZWRlaXJvLlxuICogUG9zaWNpb25hLXNlIGF1dG9tYXRpY2FtZW50ZSBjb25zaWRlcmFuZG8gbyBlc3Bhw6dvIGRpc3BvbsOtdmVsIG5hIHRlbGEsIHV0aWxpemFuZG8gbyBDREsgT3ZlcmxheS5cbiAqIFN1cG9ydGEgZXZlbnRvcyBkZSBob3ZlciwgY2xpY2sgZSBmb2N1cywgYWzDqW0gZGUgY29tcG9ydGFtZW50b3MgY3VzdG9taXphZG9zIHBhcmEgbW9iaWxlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8YnV0dG9uIHNUb29sdGlwPVwiQ2xpcXVlIGFxdWlcIiB0b29sdGlwUG9zaXRpb249XCJ0b3BcIj5Bw6fDo288L2J1dHRvbj5cbiAqIGBgYFxuICpcbiAqIEBjYXRlZ29yeSBPdmVybGF5XG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW3NUb29sdGlwXScsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgVG9vbHRpcERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gVGV4dG8gZXhpYmlkbyBubyB0b29sdGlwLiBRdWFuZG8gdmF6aW8gb3UgYHVuZGVmaW5lZGAsIG8gdG9vbHRpcCBuw6NvIMOpIHJlbmRlcml6YWRvLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0b29sdGlwID0gaW5wdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQsIHsgYWxpYXM6ICdzVG9vbHRpcCcgfSk7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gUG9zacOnw6NvIHByZWZlcmVuY2lhbCBkbyB0b29sdGlwIGVtIHJlbGHDp8OjbyBhbyBlbGVtZW50byBob3NwZWRlaXJvLlxuICAgICAqIE8gdG9vbHRpcCBzZSByZXBvc2ljaW9uYSBhdXRvbWF0aWNhbWVudGUgc2UgbsOjbyBob3V2ZXIgZXNwYcOnbyBzdWZpY2llbnRlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgJ3RvcCdcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdG9vbHRpcFBvc2l0aW9uID0gaW5wdXQ8VG9vbHRpcFBvc2l0aW9ucz4oJ3RvcCcpO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIFRlbXBvIGVtIG1pbGlzc2VndW5kb3MgYW50ZXMgZG8gdG9vbHRpcCBhcGFyZWNlciBhcMOzcyBvIGV2ZW50byBkZSBhdGl2YcOnw6NvLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgNTAwXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNob3dEZWxheSA9IGlucHV0PG51bWJlcj4oNTAwKTtcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBUZW1wbyBlbSBtaWxpc3NlZ3VuZG9zIHF1ZSBvIHRvb2x0aXAgcGVybWFuZWNlIHZpc8OtdmVsIGFww7NzIGFwYXJlY2VyLlxuICAgICAqIFF1YW5kbyBuw6NvIGluZm9ybWFkbywgbyB0b29sdGlwIHBlcm1hbmVjZSBhdMOpIG8gdXN1w6FyaW8gc2FpciBkbyBlbGVtZW50by5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGlzcGxheVRpbWUgPSBpbnB1dDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gRXZlbnRvIGRvIGVsZW1lbnRvIGhvc3BlZGVpcm8gcXVlIGRpc3BhcmEgYSBleGliacOnw6NvIGRvIHRvb2x0aXAuXG4gICAgICogLSBgJ2hvdmVyJ2A6IGV4aWJlIGFvIHBhc3NhciBvIG1vdXNlIChwYWRyw6NvKS5cbiAgICAgKiAtIGAnY2xpY2snYDogZXhpYmUgYW8gY2xpY2FyLlxuICAgICAqIC0gYCdmb2N1cydgOiBleGliZSBhbyBmb2NhciBubyBlbGVtZW50by5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdob3ZlcidcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdG9vbHRpcEV2ZW50ID0gaW5wdXQ8VG9vbHRpcEV2ZW50PignaG92ZXInKTtcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBRdWFuZG8gYHRydWVgLCBvIGNvbnRlw7pkbyBIVE1MIGRvIHRvb2x0aXAgw6kgZXNjYXBhZG8gYW50ZXMgZGUgc2VyIHJlbmRlcml6YWRvLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZXNjYXBlID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIFF1YW5kbyBgZmFsc2VgLCBvIHRvb2x0aXAgbnVuY2Egw6kgZXhpYmlkbywgbWVzbW8gcXVlIGhhamEgaW50ZXJhw6fDo28gZG8gdXN1w6FyaW8uXG4gICAgICogw5p0aWwgcGFyYSBkZXNhYmlsaXRhciB0b29sdGlwcyBkaW5hbWljYW1lbnRlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB2aXNpYmxlID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ29tcG9ydGFtZW50byBkbyB0b29sdGlwIGVtIGRpc3Bvc2l0aXZvcyBtw7N2ZWlzICh0b3VjaCkuXG4gICAgICogLSBgJ3ByZXNzaW5nJ2A6IGV4aWJlIGFvIHByZXNzaW9uYXIgZSBtYW50ZXIgbyB0b3F1ZSAocGFkcsOjbykuXG4gICAgICogLSBgJ25vbmUnYDogZGVzYWJpbGl0YSBvIHRvb2x0aXAgZW0gZGlzcG9zaXRpdm9zIHTDoXRlaXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAncHJlc3NpbmcnXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IG1vYmlsZUJlaGF2aW9yID0gaW5wdXQ8TW9iaWxlQmVoYXZpb3I+KCdwcmVzc2luZycpO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIFJlZmVyw6puY2lhIGEgdW0gaW5wdXQgSFRNTCBwYXJhIHNpbmNyb25pemFyIGEgZXhpYmnDp8OjbyBkbyB0b29sdGlwIGNvbSBvIGZvY28gbm8gY2FtcG8uXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGZvY3VzZWRJbnB1dFJlZiA9IGlucHV0PEhUTUxJbnB1dEVsZW1lbnQgfCBudWxsPihudWxsKTtcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBRdWFuZG8gYHRydWVgLCBvIHRvb2x0aXAgc8OzIMOpIGV4aWJpZG8gc2UgbyB0ZXh0byBkbyBlbGVtZW50byBlc3RpdmVyIHRydW5jYWRvIChvdmVyZmxvdykuXG4gICAgICogw5p0aWwgcGFyYSBjZWxscyBkZSB0YWJlbGEgb3UgZWxlbWVudG9zIGNvbSBgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXNgLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgY2hlY2tUcnVuY2F0ZWRUZXh0ID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG92ZXJsYXkgPSBpbmplY3QoT3ZlcmxheSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWJvdW5jZVV0aWxzID0gaW5qZWN0KERlYm91bmNlVXRpbHMpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcblxuICAgIHByaXZhdGUgb3ZlcmxheVJlZjogT3ZlcmxheVJlZiB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8VG9vbHRpcENvbXBvbmVudD4gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHBvc2l0aW9uQ2hhbmdlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHNob3dUaW1lb3V0PzogbnVtYmVyO1xuICAgIHByaXZhdGUgdG91Y2hUaW1lb3V0PzogbnVtYmVyO1xuICAgIHByaXZhdGUgdG9vbHRpcENyZWF0ZWRCeUZvY3VzID0gZmFsc2U7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWJvdW5jZUNyZWF0ZVRvb2x0aXBGdW5jdGlvbiA9IHRoaXMuZGVib3VuY2VVdGlscy5kZWJvdW5jZUxlYWRpbmcoKCkgPT5cbiAgICAgICAgdGhpcy5fY3JlYXRlVG9vbHRpcCh0cnVlLCB0cnVlKSxcbiAgICApO1xuXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnZhbGlkYXRlUG9zaXRpb24oKTtcbiAgICAgICAgdGhpcy51cGRhdGVUb29sdGlwVmlzaWJpbGl0eVdoZW5Gb2N1c09uSW5wdXQoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIC8vIHdoZW5ldmVyIHRoZSBjb21wb25lbnQgd2l0aCB0aGUgdG9vbHRpcCBpcyBjbGlja2VkIEkgZGVzdHJveSB0aGUgdG9vbHRpcC5cbiAgICAvLyB3aGVuZXZlciBhIGtleSBpcyBwcmVzc2VkIG9uIHRoZSBjb21wb25lbnQgd2l0aCB0aGUgdG9vbHRpcCBJIGRlc3Ryb3kgdGhlIHRvb2x0aXAuXG4gICAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nKVxuICAgIHB1YmxpYyBvbkNsaWNrKCk6IHZvaWQge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnRvb2x0aXBFdmVudCgpID09PSAnaG92ZXInICYmXG4gICAgICAgICAgICAhbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSAmJlxuICAgICAgICAgICAgIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZS9pKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignZm9jdXMnKVxuICAgIHB1YmxpYyBvbkZvY3VzKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50b29sdGlwRXZlbnQoKSA9PT0gJ2ZvY3VzJykge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVG9vbHRpcCh0cnVlLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2JsdXInKVxuICAgIHB1YmxpYyBvbkJsdXIoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXBFdmVudCgpID09PSAnZm9jdXMnKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInKVxuICAgIHB1YmxpYyBvbk1vdXNlRW50ZXIoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXBFdmVudCgpID09PSAnaG92ZXInIHx8IHRoaXMuZm9jdXNlZElucHV0UmVmKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2VDcmVhdGVUb29sdGlwRnVuY3Rpb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxuICAgIEBIb3N0TGlzdGVuZXIoJ3doZWVsJylcbiAgICBwdWJsaWMgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgICAgICBpZiAoKHRoaXMudG9vbHRpcEV2ZW50KCkgPT09ICdob3ZlcicgfHwgdGhpcy5mb2N1c2VkSW5wdXRSZWYoKSkgJiYgIXRoaXMudG9vbHRpcENyZWF0ZWRCeUZvY3VzKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnKVxuICAgIHB1YmxpYyBvblRvdWNoU3RhcnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXBFdmVudCgpID09PSAnaG92ZXInKSB7XG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMudG91Y2hUaW1lb3V0KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbGF5ID0gdGhpcy5tb2JpbGVCZWhhdmlvcigpID09PSAncHJlc3NpbmcnID8gdGhpcy5zaG93RGVsYXkoKSA6IDA7XG4gICAgICAgICAgICB0aGlzLnRvdWNoVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVUb29sdGlwKHRydWUsIHRydWUpO1xuICAgICAgICAgICAgfSwgZGVsYXkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcigndG91Y2hlbmQnKVxuICAgIHB1YmxpYyBvblRvdWNoRW5kKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50b29sdGlwRXZlbnQoKSA9PT0gJ2hvdmVyJyAmJiB0aGlzLm1vYmlsZUJlaGF2aW9yKCkgPT09ICdwcmVzc2luZycpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy50b3VjaFRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHZhbGlkYXRlUG9zaXRpb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5zUG9zaXRpb24gPSBbJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCddLmluY2x1ZGVzKHRoaXMudG9vbHRpcFBvc2l0aW9uKCkpO1xuICAgICAgICBpZiAoIWNvbnRhaW5zUG9zaXRpb24pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9vbHRpcCBwb3NpdGlvbiBcIiR7dGhpcy50b29sdGlwUG9zaXRpb24oKX1cIiBpcyB1bmV4cGVjdGVkYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYW5pcHVsYSBhIHZpc2liaWxpZGFkZSBkbyB0b29sdGlwIHF1YW5kbyBob3V2ZXIgdW1hIHJlZmVyw6puY2lhIGRlIGlucHV0LlxuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlVG9vbHRpcFZpc2liaWxpdHlXaGVuRm9jdXNPbklucHV0KCk6IHZvaWQge1xuICAgICAgICBjb25zdCBpbnB1dFJlZiA9IHRoaXMuZm9jdXNlZElucHV0UmVmKCk7XG4gICAgICAgIGlmICghaW5wdXRSZWYpIHJldHVybjtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLmxpc3RlbihpbnB1dFJlZiwgJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVG9vbHRpcChmYWxzZSwgZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy50b29sdGlwQ3JlYXRlZEJ5Rm9jdXMgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oaW5wdXRSZWYsICdibHVyJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLnRvb2x0aXBDcmVhdGVkQnlGb2N1cyA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jcmVhdGVUb29sdGlwKHVzZVNob3dEZWxheSA9IGZhbHNlLCBhdXRvRGVzdHJveSA9IHRydWUpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdG9vbHRpcFRleHQgPSB0aGlzLnRvb2x0aXAoKSA/PyAnJztcbiAgICAgICAgaWYgKCF0b29sdGlwVGV4dC5sZW5ndGggfHwgdGhpcy5vdmVybGF5UmVmICE9PSBudWxsKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHRoaXMuY2hlY2tUcnVuY2F0ZWRUZXh0KCkgJiYgIXRoaXMuY29udGVudElzVHJ1bmNhdGVkKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMuYnVpbGRQb3NpdGlvblN0cmF0ZWd5KCk7XG4gICAgICAgIGNvbnN0IHNjcm9sbFN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpO1xuXG4gICAgICAgIHRoaXMub3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoeyBwb3NpdGlvblN0cmF0ZWd5LCBzY3JvbGxTdHJhdGVneSB9KTtcblxuICAgICAgICBjb25zdCBwb3J0YWwgPSBuZXcgQ29tcG9uZW50UG9ydGFsKFRvb2x0aXBDb21wb25lbnQpO1xuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMub3ZlcmxheVJlZi5hdHRhY2gocG9ydGFsKTtcblxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5zZXRJbnB1dCgndG9vbHRpcCcsIHRvb2x0aXBUZXh0KTtcbiAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuc2V0SW5wdXQoJ2VzY2FwZScsIHRoaXMuZXNjYXBlKCkpO1xuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5zZXRJbnB1dCgncG9zaXRpb24nLCB0aGlzLnRvb2x0aXBQb3NpdGlvbigpKTtcblxuICAgICAgICB0aGlzLnBvc2l0aW9uQ2hhbmdlU3Vic2NyaXB0aW9uID0gcG9zaXRpb25TdHJhdGVneS5wb3NpdGlvbkNoYW5nZXMuc3Vic2NyaWJlKChjaGFuZ2UpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1hcHBlZFBvc2l0aW9uID0gdGhpcy5tYXBDZGtQb3NpdGlvblRvVG9vbHRpcFBvc2l0aW9uKGNoYW5nZS5jb25uZWN0aW9uUGFpcik7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlZj8uc2V0SW5wdXQoJ3Bvc2l0aW9uJywgbWFwcGVkUG9zaXRpb24pO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZWxheSA9IHVzZVNob3dEZWxheSA/IHRoaXMuc2hvd0RlbGF5KCkgOiAwO1xuICAgICAgICB0aGlzLnNob3dUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWY/LnNldElucHV0KCd2aXNpYmxlJywgdGhpcy52aXNpYmxlKCkpO1xuICAgICAgICB9LCBkZWxheSk7XG5cbiAgICAgICAgaWYgKGF1dG9EZXN0cm95ICYmIHRoaXMuZGlzcGxheVRpbWUoKSkge1xuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICAgICAgfSwgdGhpcy5kaXNwbGF5VGltZSgpISk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGJ1aWxkUG9zaXRpb25TdHJhdGVneSgpOiBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3kge1xuICAgICAgICBjb25zdCBwcmVmZXJyZWQgPSB0aGlzLnRvb2x0aXBQb3NpdGlvbigpO1xuICAgICAgICBjb25zdCBhbGxQb3NpdGlvbnM6IFRvb2x0aXBQb3NpdGlvbnNbXSA9IFsndG9wJywgJ2JvdHRvbScsICdsZWZ0JywgJ3JpZ2h0J107XG4gICAgICAgIGNvbnN0IG9yZGVyZWRQb3NpdGlvbnMgPSBbcHJlZmVycmVkLCAuLi5hbGxQb3NpdGlvbnMuZmlsdGVyKChwKSA9PiBwICE9PSBwcmVmZXJyZWQpXTtcblxuICAgICAgICByZXR1cm4gdGhpcy5vdmVybGF5XG4gICAgICAgICAgICAucG9zaXRpb24oKVxuICAgICAgICAgICAgLmZsZXhpYmxlQ29ubmVjdGVkVG8odGhpcy5lbGVtZW50UmVmKVxuICAgICAgICAgICAgLndpdGhQb3NpdGlvbnMob3JkZXJlZFBvc2l0aW9ucy5tYXAoKHApID0+IHRoaXMuZ2V0Q29ubmVjdGVkUG9zaXRpb24ocCkpKVxuICAgICAgICAgICAgLndpdGhGbGV4aWJsZURpbWVuc2lvbnMoZmFsc2UpXG4gICAgICAgICAgICAud2l0aFB1c2goZmFsc2UpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29ubmVjdGVkUG9zaXRpb24ocG9zOiBUb29sdGlwUG9zaXRpb25zKTogQ29ubmVjdGVkUG9zaXRpb24ge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSAxMDtcbiAgICAgICAgY29uc3QgcG9zaXRpb25NYXA6IFJlY29yZDxUb29sdGlwUG9zaXRpb25zLCBDb25uZWN0ZWRQb3NpdGlvbj4gPSB7XG4gICAgICAgICAgICB0b3A6IHsgb3JpZ2luWDogJ2NlbnRlcicsIG9yaWdpblk6ICd0b3AnLCBvdmVybGF5WDogJ2NlbnRlcicsIG92ZXJsYXlZOiAnYm90dG9tJywgb2Zmc2V0WTogLW9mZnNldCB9LFxuICAgICAgICAgICAgYm90dG9tOiB7IG9yaWdpblg6ICdjZW50ZXInLCBvcmlnaW5ZOiAnYm90dG9tJywgb3ZlcmxheVg6ICdjZW50ZXInLCBvdmVybGF5WTogJ3RvcCcsIG9mZnNldFk6IG9mZnNldCB9LFxuICAgICAgICAgICAgbGVmdDogeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJywgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ2NlbnRlcicsIG9mZnNldFg6IC1vZmZzZXQgfSxcbiAgICAgICAgICAgIHJpZ2h0OiB7IG9yaWdpblg6ICdlbmQnLCBvcmlnaW5ZOiAnY2VudGVyJywgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnY2VudGVyJywgb2Zmc2V0WDogb2Zmc2V0IH0sXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBwb3NpdGlvbk1hcFtwb3NdO1xuICAgIH1cblxuICAgIHByaXZhdGUgbWFwQ2RrUG9zaXRpb25Ub1Rvb2x0aXBQb3NpdGlvbihwYWlyOiB7IG92ZXJsYXlYOiBzdHJpbmc7IG92ZXJsYXlZOiBzdHJpbmcgfSk6IFRvb2x0aXBQb3NpdGlvbnMge1xuICAgICAgICBpZiAocGFpci5vdmVybGF5WSA9PT0gJ2JvdHRvbScpIHJldHVybiAndG9wJztcbiAgICAgICAgaWYgKHBhaXIub3ZlcmxheVkgPT09ICd0b3AnKSByZXR1cm4gJ2JvdHRvbSc7XG4gICAgICAgIGlmIChwYWlyLm92ZXJsYXlYID09PSAnZW5kJykgcmV0dXJuICdsZWZ0JztcbiAgICAgICAgcmV0dXJuICdyaWdodCc7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuc2hvd1RpbWVvdXQpO1xuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMudG91Y2hUaW1lb3V0KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvbkNoYW5nZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvbkNoYW5nZVN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLm92ZXJsYXlSZWYpIHtcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVJlZi5kaXNwb3NlKCk7XG4gICAgICAgICAgICB0aGlzLm92ZXJsYXlSZWYgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWYgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXQgY29udGVudElzVHJ1bmNhdGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIHJldHVybiBlbGVtZW50LnNjcm9sbEhlaWdodCA+IGVsZW1lbnQuY2xpZW50SGVpZ2h0IHx8IGVsZW1lbnQuc2Nyb2xsV2lkdGggPiBlbGVtZW50LmNsaWVudFdpZHRoO1xuICAgIH1cbn1cblxuIl19