@firestitch/list 12.7.2 → 12.8.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 (147) hide show
  1. package/app/classes/actions-controller.d.ts +20 -20
  2. package/app/classes/columns-controller.d.ts +71 -71
  3. package/app/classes/data-controller.d.ts +90 -90
  4. package/app/classes/external-params-controller.d.ts +31 -31
  5. package/app/classes/index.d.ts +2 -2
  6. package/app/classes/list-controller.d.ts +174 -174
  7. package/app/classes/pagination-controller.d.ts +189 -189
  8. package/app/classes/persistance-controller.d.ts +10 -10
  9. package/app/classes/reorder-controller.d.ts +62 -62
  10. package/app/classes/selection-controller.d.ts +141 -141
  11. package/app/classes/sorting-controller.d.ts +64 -64
  12. package/app/components/body/body.component.d.ts +32 -32
  13. package/app/components/body/row/actions/actions.component.d.ts +34 -35
  14. package/app/components/body/row/cell/cell.component.d.ts +23 -23
  15. package/app/components/body/row/inline-action/inline-action.component.d.ts +16 -16
  16. package/app/components/body/row/menu-action/menu-action.component.d.ts +14 -12
  17. package/app/components/body/row/row.component.d.ts +72 -72
  18. package/app/components/customize-cols/customize-cols.component.d.ts +17 -17
  19. package/app/components/footer/footer-row/footer-cell/footer-cell.component.d.ts +7 -7
  20. package/app/components/footer/footer-row/footer-row.component.d.ts +11 -11
  21. package/app/components/footer/footer.component.d.ts +11 -11
  22. package/app/components/head/head-cell/head-cell.component.d.ts +14 -14
  23. package/app/components/head/head.component.d.ts +43 -43
  24. package/app/components/list/list.component.d.ts +116 -116
  25. package/app/components/loader/loader.component.d.ts +14 -14
  26. package/app/components/manage-saved-filters/manage-saved-filters.component.d.ts +13 -13
  27. package/app/components/pagination/pagination.component.d.ts +14 -14
  28. package/app/components/saved-filters/saved-filters.component.d.ts +15 -15
  29. package/app/components/status/status.component.d.ts +21 -21
  30. package/app/directives/cell/cell.directive.d.ts +8 -8
  31. package/app/directives/column/column.directive.d.ts +33 -33
  32. package/app/directives/content/content.directive.d.ts +5 -5
  33. package/app/directives/content-init/content-init.directive.d.ts +9 -9
  34. package/app/directives/draggable-list/draggable-list.directive.d.ts +80 -80
  35. package/app/directives/draggable-row/draggable-row.directive.d.ts +21 -21
  36. package/app/directives/empty-state/empty-state.directive.d.ts +5 -5
  37. package/app/directives/footer/footer.directive.d.ts +8 -8
  38. package/app/directives/group-expand-trigger/group-expand-trigger.directive.d.ts +10 -10
  39. package/app/directives/group-footer/group-footer.directive.d.ts +6 -6
  40. package/app/directives/group-header/group-header.directive.d.ts +6 -6
  41. package/app/directives/header/header.directive.d.ts +8 -8
  42. package/app/enums/button-type.enum.d.ts +7 -7
  43. package/app/enums/page-change-type.enum.d.ts +4 -4
  44. package/app/enums/pagination-strategy.enum.d.ts +5 -5
  45. package/app/enums/row-type.enum.d.ts +6 -6
  46. package/app/enums/state.enum.d.ts +9 -9
  47. package/app/fs-list.module.d.ts +57 -56
  48. package/app/fs-list.providers.d.ts +3 -3
  49. package/app/interfaces/cellconfig.interface.d.ts +5 -5
  50. package/app/interfaces/column-config.interface.d.ts +2 -2
  51. package/app/interfaces/draggable-list.interface.d.ts +7 -7
  52. package/app/interfaces/external-params.interface.d.ts +13 -13
  53. package/app/interfaces/index.d.ts +3 -3
  54. package/app/interfaces/listconfig.interface.d.ts +250 -250
  55. package/app/interfaces/pagination.interface.d.ts +13 -13
  56. package/app/models/column-async-attribute.d.ts +5 -5
  57. package/app/models/column-attributes.d.ts +39 -39
  58. package/app/models/column.model.d.ts +59 -59
  59. package/app/models/row/base-row.d.ts +13 -13
  60. package/app/models/row/child-row.d.ts +12 -12
  61. package/app/models/row/group-footer-row.d.ts +10 -10
  62. package/app/models/row/group-row.d.ts +16 -16
  63. package/app/models/row/simple-row.d.ts +5 -5
  64. package/app/models/row-action.model.d.ts +29 -31
  65. package/app/models/row.d.ts +30 -30
  66. package/app/models/styleConfig.model.d.ts +31 -31
  67. package/app/pipes/action-label.d.ts +8 -0
  68. package/app/pipes/index.d.ts +1 -0
  69. package/app/services/group-expand-notifier.service.d.ts +11 -11
  70. package/bundles/firestitch-list.umd.js +6553 -6555
  71. package/bundles/firestitch-list.umd.js.map +1 -1
  72. package/esm2015/app/classes/actions-controller.js +55 -55
  73. package/esm2015/app/classes/columns-controller.js +205 -205
  74. package/esm2015/app/classes/data-controller.js +331 -331
  75. package/esm2015/app/classes/external-params-controller.js +153 -153
  76. package/esm2015/app/classes/index.js +3 -3
  77. package/esm2015/app/classes/list-controller.js +714 -714
  78. package/esm2015/app/classes/pagination-controller.js +460 -460
  79. package/esm2015/app/classes/persistance-controller.js +19 -19
  80. package/esm2015/app/classes/reorder-controller.js +177 -177
  81. package/esm2015/app/classes/selection-controller.js +445 -445
  82. package/esm2015/app/classes/sorting-controller.js +180 -180
  83. package/esm2015/app/components/body/body.component.js +75 -75
  84. package/esm2015/app/components/body/row/actions/actions.component.js +96 -100
  85. package/esm2015/app/components/body/row/cell/cell.component.js +104 -104
  86. package/esm2015/app/components/body/row/inline-action/inline-action.component.js +39 -39
  87. package/esm2015/app/components/body/row/menu-action/menu-action.component.js +36 -32
  88. package/esm2015/app/components/body/row/row.component.js +253 -253
  89. package/esm2015/app/components/customize-cols/customize-cols.component.js +72 -72
  90. package/esm2015/app/components/footer/footer-row/footer-cell/footer-cell.component.js +20 -20
  91. package/esm2015/app/components/footer/footer-row/footer-row.component.js +26 -26
  92. package/esm2015/app/components/footer/footer.component.js +26 -26
  93. package/esm2015/app/components/head/head-cell/head-cell.component.js +33 -33
  94. package/esm2015/app/components/head/head.component.js +90 -90
  95. package/esm2015/app/components/list/list.component.js +375 -375
  96. package/esm2015/app/components/loader/loader.component.js +47 -47
  97. package/esm2015/app/components/manage-saved-filters/manage-saved-filters.component.js +78 -78
  98. package/esm2015/app/components/pagination/pagination.component.js +44 -44
  99. package/esm2015/app/components/saved-filters/saved-filters.component.js +33 -33
  100. package/esm2015/app/components/status/status.component.js +74 -74
  101. package/esm2015/app/directives/cell/cell.directive.js +18 -18
  102. package/esm2015/app/directives/column/column.directive.js +111 -111
  103. package/esm2015/app/directives/content/content.directive.js +12 -12
  104. package/esm2015/app/directives/content-init/content-init.directive.js +21 -21
  105. package/esm2015/app/directives/draggable-list/draggable-list.directive.js +256 -256
  106. package/esm2015/app/directives/draggable-row/draggable-row.directive.js +73 -73
  107. package/esm2015/app/directives/empty-state/empty-state.directive.js +13 -13
  108. package/esm2015/app/directives/footer/footer.directive.js +18 -18
  109. package/esm2015/app/directives/group-expand-trigger/group-expand-trigger.directive.js +26 -26
  110. package/esm2015/app/directives/group-footer/group-footer.directive.js +13 -13
  111. package/esm2015/app/directives/group-header/group-header.directive.js +13 -13
  112. package/esm2015/app/directives/header/header.directive.js +18 -18
  113. package/esm2015/app/enums/button-type.enum.js +9 -9
  114. package/esm2015/app/enums/page-change-type.enum.js +6 -6
  115. package/esm2015/app/enums/pagination-strategy.enum.js +7 -7
  116. package/esm2015/app/enums/row-type.enum.js +7 -7
  117. package/esm2015/app/enums/state.enum.js +11 -11
  118. package/esm2015/app/fs-list.module.js +232 -228
  119. package/esm2015/app/fs-list.providers.js +4 -4
  120. package/esm2015/app/interfaces/cellconfig.interface.js +2 -2
  121. package/esm2015/app/interfaces/column-config.interface.js +1 -1
  122. package/esm2015/app/interfaces/draggable-list.interface.js +2 -2
  123. package/esm2015/app/interfaces/external-params.interface.js +2 -2
  124. package/esm2015/app/interfaces/index.js +4 -4
  125. package/esm2015/app/interfaces/listconfig.interface.js +1 -1
  126. package/esm2015/app/interfaces/pagination.interface.js +2 -2
  127. package/esm2015/app/models/column-async-attribute.js +13 -13
  128. package/esm2015/app/models/column-attributes.js +130 -130
  129. package/esm2015/app/models/column.model.js +166 -166
  130. package/esm2015/app/models/row/base-row.js +23 -23
  131. package/esm2015/app/models/row/child-row.js +28 -28
  132. package/esm2015/app/models/row/group-footer-row.js +20 -20
  133. package/esm2015/app/models/row/group-row.js +44 -44
  134. package/esm2015/app/models/row/simple-row.js +10 -10
  135. package/esm2015/app/models/row-action.model.js +95 -114
  136. package/esm2015/app/models/row.js +80 -80
  137. package/esm2015/app/models/styleConfig.model.js +75 -75
  138. package/esm2015/app/pipes/action-label.js +17 -0
  139. package/esm2015/app/pipes/index.js +2 -0
  140. package/esm2015/app/services/group-expand-notifier.service.js +26 -26
  141. package/esm2015/firestitch-list.js +4 -4
  142. package/esm2015/public_api.js +44 -44
  143. package/fesm2015/firestitch-list.js +5394 -5398
  144. package/fesm2015/firestitch-list.js.map +1 -1
  145. package/firestitch-list.d.ts +5 -5
  146. package/package.json +1 -1
  147. package/public_api.d.ts +38 -38
@@ -1,256 +1,256 @@
1
- import { ChangeDetectorRef, Directive, ElementRef, Input, NgZone } from '@angular/core';
2
- import { Observable, Subject } from 'rxjs';
3
- import { takeUntil } from 'rxjs/operators';
4
- import { ReorderController, ReorderStrategy } from '../../classes/reorder-controller';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "../../classes/reorder-controller";
7
- export class FsListDraggableListDirective {
8
- constructor(_cdRef, _zone, _containerElement, _reorderController) {
9
- this._cdRef = _cdRef;
10
- this._zone = _zone;
11
- this._containerElement = _containerElement;
12
- this._reorderController = _reorderController;
13
- // Handlers
14
- this._dragToHandler = this.dragTo.bind(this);
15
- this._dragEndHandler = this.dragEnd.bind(this);
16
- this._windowTouchMoveHandler = () => { };
17
- this._dragInProgress = false;
18
- this._dragStart$ = new Subject();
19
- this._dragEnd$ = new Subject();
20
- this._destroy$ = new Subject();
21
- }
22
- get dragStart$() {
23
- return this._dragStart$.pipe(takeUntil(this._destroy$));
24
- }
25
- get dragEnd$() {
26
- return this._dragEnd$.pipe(takeUntil(this._destroy$));
27
- }
28
- get draggableItem() {
29
- return this._rows[this._draggableElementIndex];
30
- }
31
- /**
32
- * Prepare draggable elements and add events
33
- * @param draggableElement
34
- */
35
- dragStart(draggableElement) {
36
- if (this._dragInProgress) {
37
- return;
38
- }
39
- if (this._reorderController.startCallback
40
- && this._reorderController.strategy === ReorderStrategy.Always) {
41
- this._reorderController.startCallback();
42
- }
43
- this._dragInProgress = true;
44
- window.document.body.classList.add('reorder-in-progress');
45
- this._draggableElement = draggableElement;
46
- this.prepareElements();
47
- this.initDraggableElement();
48
- this._draggableElement.classList.add('draggable-elem');
49
- this._zone.runOutsideAngular(() => {
50
- window.addEventListener('touchmove', this._windowTouchMoveHandler, { passive: true });
51
- window.document.addEventListener('mousemove', this._dragToHandler, { passive: true });
52
- window.document.addEventListener('touchmove', this._dragToHandler, { passive: false });
53
- window.document.addEventListener('mouseup', this._dragEndHandler);
54
- window.document.addEventListener('touchend', this._dragEndHandler);
55
- window.document.addEventListener('touchcancel', this._dragEndHandler);
56
- });
57
- this._dragStart$.next();
58
- }
59
- /**
60
- * Move draggable elements and swap items
61
- * @param event
62
- */
63
- dragTo(event) {
64
- this.touchFix(event);
65
- const elemIndex = this.lookupElementUnder(event);
66
- const targetRow = this._rows[elemIndex];
67
- // Can not drag before first group and after last group
68
- const swapWithBoundaryGroupElement = (elemIndex === 0 || elemIndex === this._rows.length - 1)
69
- && targetRow.isGroup
70
- && this.draggableItem.isChild;
71
- if (!swapWithBoundaryGroupElement) {
72
- if (elemIndex !== null) {
73
- if (targetRow.readyToSwap) {
74
- this.swapWithIndex(elemIndex);
75
- this._draggableElementPreview.classList.remove('fs-list-no-drop');
76
- }
77
- else {
78
- this._draggableElementPreview.classList.add('fs-list-no-drop');
79
- }
80
- }
81
- }
82
- const topOffset = (event.y || event.clientY) - (this._draggableElementHeight / 2);
83
- this._draggableElementPreview.style.top = topOffset + 'px';
84
- }
85
- /**
86
- * Remove events and classes after drag finish
87
- */
88
- dragEnd() {
89
- this._dragInProgress = false;
90
- ///
91
- if (this._reorderController.movedCallback) {
92
- this._reorderController.movedCallback(this._reorderController.dataController.reorderData);
93
- }
94
- if (this._reorderController.strategy === ReorderStrategy.Always) {
95
- this._zone.run(() => {
96
- if (this._reorderController.doneCallback) {
97
- const result = this._reorderController.doneCallback(this._reorderController.dataController.reorderData);
98
- this._waitUntilIsNotDone(result);
99
- }
100
- });
101
- }
102
- // this._reorderController.dataController.updateOrderByRows(this._rows);
103
- ///
104
- this._draggableElement.classList.remove('draggable-elem');
105
- window.document.body.classList.remove('reorder-in-progress');
106
- this._draggableElementPreview.remove();
107
- this._draggableElement = null;
108
- this._draggableElementPreview = null;
109
- this._draggableElementHeight = null;
110
- this._draggableElementIndex = null;
111
- window.removeEventListener('touchmove', this._windowTouchMoveHandler);
112
- window.document.removeEventListener('mousemove', this._dragToHandler);
113
- window.document.removeEventListener('touchmove', this._dragToHandler);
114
- window.document.removeEventListener('mouseup', this._dragEndHandler);
115
- window.document.removeEventListener('touchend', this._dragEndHandler);
116
- window.document.removeEventListener('touchcancel', this._dragEndHandler);
117
- this._dragEnd$.next();
118
- }
119
- /**
120
- * looking row elements and save their dims
121
- */
122
- prepareElements() {
123
- this.lookupChildElements();
124
- this.calcElementsDimensions();
125
- }
126
- /**
127
- * Store child rows
128
- */
129
- lookupChildElements() {
130
- this._childRowElements = Array.from(this._containerElement.nativeElement.querySelectorAll('tr'))
131
- .reduce((acc, rowElement, index) => {
132
- const element = { target: rowElement };
133
- if (rowElement === this._draggableElement) {
134
- this._draggableElementIndex = index;
135
- element.active = true;
136
- }
137
- acc.push(element);
138
- return acc;
139
- }, []);
140
- }
141
- /**
142
- * Calc child rows sizes/offsets
143
- */
144
- calcElementsDimensions() {
145
- this._childRowElements.forEach((el, index) => {
146
- const dims = el.target.getBoundingClientRect();
147
- el.top = dims.top;
148
- el.height = dims.height;
149
- el.center = dims.top + (dims.height / 2);
150
- el.index = index;
151
- });
152
- }
153
- /**
154
- * Init draggable element
155
- */
156
- initDraggableElement() {
157
- const el = this._draggableElement.cloneNode(true);
158
- const data = this._draggableElement.getBoundingClientRect();
159
- el.style.width = data.width + 'px';
160
- el.style.left = data.left + 'px';
161
- el.style.top = data.top + 'px';
162
- el.classList.add('draggable');
163
- this._containerElement.nativeElement.insertAdjacentElement('afterbegin', el);
164
- this._draggableElementPreview = el;
165
- this._draggableElementHeight = data.height;
166
- this.updateDraggableDims();
167
- }
168
- /**
169
- * Looking by stored row elemens for overlapped row
170
- * @param event
171
- */
172
- lookupElementUnder(event) {
173
- const top = event.y || event.clientY;
174
- const bottom = event.y || event.clientY;
175
- let elemIndex = null;
176
- for (let i = 0; i < this._childRowElements.length; i++) {
177
- const el = this._childRowElements[i];
178
- if (!el.active) {
179
- if (top < el.center + (el.height / 2) && el.index < this._draggableElementIndex
180
- || bottom > el.center - (el.height / 2) && el.index > this._draggableElementIndex) {
181
- elemIndex = i;
182
- }
183
- }
184
- }
185
- return elemIndex;
186
- }
187
- /**
188
- * Swap rows
189
- * @param index
190
- */
191
- swapWithIndex(index) {
192
- const activeIndex = this._draggableElementIndex;
193
- // Swap rows in global rows stack
194
- this._reorderController
195
- .dataController
196
- .swapRows(this._rows[activeIndex], this._rows[index]);
197
- // Swap visible rows
198
- const activeRow = this._rows[activeIndex];
199
- this._rows[activeIndex] = this._rows[index];
200
- this._rows[index] = activeRow;
201
- const activeElement = this._childRowElements[activeIndex].target;
202
- this._childRowElements[activeIndex].active = false;
203
- this._childRowElements[activeIndex].target = this._childRowElements[index].target;
204
- this._childRowElements[index].target = activeElement;
205
- this._childRowElements[index].active = true;
206
- this._draggableElementIndex = index;
207
- this._cdRef.detectChanges();
208
- }
209
- /**
210
- * Update cell width for draggable elem
211
- */
212
- updateDraggableDims() {
213
- const draggableCells = Array.from(this._draggableElementPreview.querySelectorAll('td'));
214
- Array.from(this._draggableElementPreview.querySelectorAll('td')).forEach((elem, index) => {
215
- const dims = elem.getBoundingClientRect();
216
- draggableCells[index].style.width = dims.width + 'px';
217
- });
218
- }
219
- _waitUntilIsNotDone(doneResult) {
220
- if (doneResult instanceof Observable) {
221
- this._reorderController.disableReorderAction();
222
- doneResult
223
- .pipe(takeUntil(this._destroy$))
224
- .subscribe(() => {
225
- console.log('enable');
226
- this._reorderController.enableReorderAction();
227
- });
228
- }
229
- }
230
- /**
231
- * Fix background when mobile
232
- * @param e
233
- */
234
- touchFix(e) {
235
- if (!('clientX' in e) && !('clientY' in e)) {
236
- const touches = e.touches || e.originalEvent.touches;
237
- if (touches && touches.length) {
238
- e.clientX = touches[0].clientX;
239
- e.clientY = touches[0].clientY;
240
- }
241
- e.preventDefault();
242
- }
243
- }
244
- }
245
- FsListDraggableListDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsListDraggableListDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i1.ReorderController }], target: i0.ɵɵFactoryTarget.Directive });
246
- FsListDraggableListDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.16", type: FsListDraggableListDirective, selector: "[fsListDraggableList]", inputs: { _rows: ["rows", "_rows"] }, ngImport: i0 });
247
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsListDraggableListDirective, decorators: [{
248
- type: Directive,
249
- args: [{
250
- selector: '[fsListDraggableList]',
251
- }]
252
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i1.ReorderController }]; }, propDecorators: { _rows: [{
253
- type: Input,
254
- args: ['rows']
255
- }] } });
256
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLWxpc3QuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9kaXJlY3RpdmVzL2RyYWdnYWJsZS1saXN0L2RyYWdnYWJsZS1saXN0LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXhGLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7OztBQVF0RixNQUFNLE9BQU8sNEJBQTRCO0lBd0J2QyxZQUNVLE1BQXlCLEVBQ3pCLEtBQWEsRUFDYixpQkFBNkIsRUFDN0Isa0JBQXFDO1FBSHJDLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQ3pCLFVBQUssR0FBTCxLQUFLLENBQVE7UUFDYixzQkFBaUIsR0FBakIsaUJBQWlCLENBQVk7UUFDN0IsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFtQjtRQXBCL0MsV0FBVztRQUNILG1CQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsb0JBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyw0QkFBdUIsR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFFbkMsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFHeEIsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2xDLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBS2hDLGNBQVMsR0FBRyxJ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QW1CO1FBQzdDLElBQUksVUFBVSxZQUFZLFVBQVUsRUFBRTtZQUNwQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUUvQyxVQUFVO2lCQUNQLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUMvQixTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ2hELENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssUUFBUSxDQUFDLENBQUM7UUFDaEIsSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLEVBQUU7WUFDMUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQztZQUNyRCxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO2dCQUM3QixDQUFDLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQy9CLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQzthQUNoQztZQUVELENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUNwQjtJQUNILENBQUM7OzBIQTNUVSw0QkFBNEI7OEdBQTVCLDRCQUE0Qjs0RkFBNUIsNEJBQTRCO2tCQUh4QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSx1QkFBdUI7aUJBQ2xDO3NMQXFCUyxLQUFLO3NCQURaLEtBQUs7dUJBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZW9yZGVyQ29udHJvbGxlciwgUmVvcmRlclN0cmF0ZWd5IH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy9yZW9yZGVyLWNvbnRyb2xsZXInO1xuaW1wb3J0IHsgUm93IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Jvdyc7XG5pbXBvcnQgeyBGc0xpc3REcmFnQ2hpbGRSb3dFbGVtZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9kcmFnZ2FibGUtbGlzdC5pbnRlcmZhY2UnO1xuXG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tmc0xpc3REcmFnZ2FibGVMaXN0XScsXG59KVxuZXhwb3J0IGNsYXNzIEZzTGlzdERyYWdnYWJsZUxpc3REaXJlY3RpdmUge1xuXG4gIC8vIERyYWdnYWJsZSBFbGVtZW50XG4gIHByaXZhdGUgX2RyYWdnYWJsZUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIF9kcmFnZ2FibGVFbGVtZW50UHJldmlldzogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgX2RyYWdnYWJsZUVsZW1lbnRIZWlnaHQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBfZHJhZ2dhYmxlRWxlbWVudEluZGV4OiBudW1iZXI7XG5cbiAgLy8gSGFuZGxlcnNcbiAgcHJpdmF0ZSBfZHJhZ1RvSGFuZGxlciA9IHRoaXMuZHJhZ1RvLmJpbmQodGhpcyk7XG4gIHByaXZhdGUgX2RyYWdFbmRIYW5kbGVyID0gdGhpcy5kcmFnRW5kLmJpbmQodGhpcyk7XG4gIHByaXZhdGUgX3dpbmRvd1RvdWNoTW92ZUhhbmRsZXIgPSAoKSA9PiB7fTtcblxuICBwcml2YXRlIF9kcmFnSW5Qcm9ncmVzcyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgX2NoaWxkUm93RWxlbWVudHM6IEZzTGlzdERyYWdDaGlsZFJvd0VsZW1lbnRbXTtcbiAgcHJpdmF0ZSBfZHJhZ1N0YXJ0JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX2RyYWdFbmQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBASW5wdXQoJ3Jvd3MnKVxuICBwcml2YXRlIF9yb3dzOiBSb3dbXTtcblxuICBwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfY2RSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgX3pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIF9jb250YWluZXJFbGVtZW50OiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgX3Jlb3JkZXJDb250cm9sbGVyOiBSZW9yZGVyQ29udHJvbGxlcixcbiAgKSB7fVxuXG4gIHB1YmxpYyBnZXQgZHJhZ1N0YXJ0JCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fZHJhZ1N0YXJ0JC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpO1xuICB9XG5cbiAgcHVibGljIGdldCBkcmFnRW5kJCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fZHJhZ0VuZCQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZHJhZ2dhYmxlSXRlbSgpOiBSb3cge1xuICAgIHJldHVybiB0aGlzLl9yb3dzW3RoaXMuX2RyYWdnYWJsZUVsZW1lbnRJbmRleF07XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyZSBkcmFnZ2FibGUgZWxlbWVudHMgYW5kIGFkZCBldmVudHNcbiAgICogQHBhcmFtIGRyYWdnYWJsZUVsZW1lbnRcbiAgICovXG4gIHB1YmxpYyBkcmFnU3RhcnQoZHJhZ2dhYmxlRWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAodGhpcy5fZHJhZ0luUHJvZ3Jlc3MpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5zdGFydENhbGxiYWNrXG4gICAgICAmJiB0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5zdHJhdGVneSA9PT0gUmVvcmRlclN0cmF0ZWd5LkFsd2F5c1xuICAgICkge1xuICAgICAgdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuc3RhcnRDYWxsYmFjaygpO1xuICAgIH1cblxuICAgIHRoaXMuX2RyYWdJblByb2dyZXNzID0gdHJ1ZTtcblxuICAgIHdpbmRvdy5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ3Jlb3JkZXItaW4tcHJvZ3Jlc3MnKTtcblxuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnQgPSBkcmFnZ2FibGVFbGVtZW50O1xuXG4gICAgdGhpcy5wcmVwYXJlRWxlbWVudHMoKTtcblxuICAgIHRoaXMuaW5pdERyYWdnYWJsZUVsZW1lbnQoKTtcblxuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZ2dhYmxlLWVsZW0nKTtcblxuICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoICd0b3VjaG1vdmUnLCB0aGlzLl93aW5kb3dUb3VjaE1vdmVIYW5kbGVyLCB7IHBhc3NpdmU6IHRydWUgfSk7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5fZHJhZ1RvSGFuZGxlciwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuX2RyYWdUb0hhbmRsZXIsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuX2RyYWdFbmRIYW5kbGVyKTtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMuX2RyYWdFbmRIYW5kbGVyKTtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuX2RyYWdFbmRIYW5kbGVyKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2RyYWdTdGFydCQubmV4dCgpO1xuXG4gIH1cblxuXG4gIC8qKlxuICAgKiBNb3ZlIGRyYWdnYWJsZSBlbGVtZW50cyBhbmQgc3dhcCBpdGVtc1xuICAgKiBAcGFyYW0gZXZlbnRcbiAgICovXG4gIHB1YmxpYyBkcmFnVG8oZXZlbnQpIHtcbiAgICB0aGlzLnRvdWNoRml4KGV2ZW50KTtcbiAgICBjb25zdCBlbGVtSW5kZXggPSB0aGlzLmxvb2t1cEVsZW1lbnRVbmRlcihldmVudCk7XG4gICAgY29uc3QgdGFyZ2V0Um93ID0gdGhpcy5fcm93c1tlbGVtSW5kZXhdO1xuXG4gICAgLy8gQ2FuIG5vdCBkcmFnIGJlZm9yZSBmaXJzdCBncm91cCBhbmQgYWZ0ZXIgbGFzdCBncm91cFxuICAgIGNvbnN0IHN3YXBXaXRoQm91bmRhcnlHcm91cEVsZW1lbnQgPVxuICAgICAgKGVsZW1JbmRleCA9PT0gMCB8fCBlbGVtSW5kZXggPT09IHRoaXMuX3Jvd3MubGVuZ3RoIC0gMSlcbiAgICAgICYmIHRhcmdldFJvdy5pc0dyb3VwXG4gICAgICAmJiB0aGlzLmRyYWdnYWJsZUl0ZW0uaXNDaGlsZDtcblxuICAgIGlmICghc3dhcFdpdGhCb3VuZGFyeUdyb3VwRWxlbWVudCkge1xuICAgICAgaWYgKGVsZW1JbmRleCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAodGFyZ2V0Um93LnJlYWR5VG9Td2FwKSB7XG4gICAgICAgICAgdGhpcy5zd2FwV2l0aEluZGV4KGVsZW1JbmRleClcbiAgICAgICAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5jbGFzc0xpc3QucmVtb3ZlKCdmcy1saXN0LW5vLWRyb3AnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5jbGFzc0xpc3QuYWRkKCdmcy1saXN0LW5vLWRyb3AnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRvcE9mZnNldCA9IChldmVudC55IHx8IGV2ZW50LmNsaWVudFkpIC0gKHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRIZWlnaHQgLyAyKTtcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5zdHlsZS50b3AgPSAgdG9wT2Zmc2V0ICsgJ3B4JztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgZXZlbnRzIGFuZCBjbGFzc2VzIGFmdGVyIGRyYWcgZmluaXNoXG4gICAqL1xuICBwdWJsaWMgZHJhZ0VuZCgpIHtcbiAgICB0aGlzLl9kcmFnSW5Qcm9ncmVzcyA9IGZhbHNlO1xuXG4gICAgLy8vXG4gICAgaWYgKHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLm1vdmVkQ2FsbGJhY2spIHtcbiAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLm1vdmVkQ2FsbGJhY2soXG4gICAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRhdGFDb250cm9sbGVyLnJlb3JkZXJEYXRhXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5zdHJhdGVneSA9PT0gUmVvcmRlclN0cmF0ZWd5LkFsd2F5cykge1xuICAgICAgdGhpcy5fem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuZG9uZUNhbGxiYWNrKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuZG9uZUNhbGxiYWNrKFxuICAgICAgICAgICAgdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuZGF0YUNvbnRyb2xsZXIucmVvcmRlckRhdGFcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5fd2FpdFVudGlsSXNOb3REb25lKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRhdGFDb250cm9sbGVyLnVwZGF0ZU9yZGVyQnlSb3dzKHRoaXMuX3Jvd3MpO1xuICAgIC8vL1xuXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2FibGUtZWxlbScpO1xuICAgIHdpbmRvdy5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ3Jlb3JkZXItaW4tcHJvZ3Jlc3MnKTtcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5yZW1vdmUoKTtcblxuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRQcmV2aWV3ID0gbnVsbDtcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SGVpZ2h0ID0gbnVsbDtcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXggPSBudWxsO1xuXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoICd0b3VjaG1vdmUnLCB0aGlzLl93aW5kb3dUb3VjaE1vdmVIYW5kbGVyKTtcbiAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5fZHJhZ1RvSGFuZGxlcik7XG4gICAgd2luZG93LmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuX2RyYWdUb0hhbmRsZXIpO1xuICAgIHdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fZHJhZ0VuZEhhbmRsZXIpO1xuICAgIHdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMuX2RyYWdFbmRIYW5kbGVyKTtcbiAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCB0aGlzLl9kcmFnRW5kSGFuZGxlcik7XG5cbiAgICB0aGlzLl9kcmFnRW5kJC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogbG9va2luZyByb3cgZWxlbWVudHMgYW5kIHNhdmUgdGhlaXIgZGltc1xuICAgKi9cbiAgcHJpdmF0ZSBwcmVwYXJlRWxlbWVudHMoKSB7XG4gICAgdGhpcy5sb29rdXBDaGlsZEVsZW1lbnRzKCk7XG4gICAgdGhpcy5jYWxjRWxlbWVudHNEaW1lbnNpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgY2hpbGQgcm93c1xuICAgKi9cbiAgcHJpdmF0ZSBsb29rdXBDaGlsZEVsZW1lbnRzKCkge1xuICAgIHRoaXMuX2NoaWxkUm93RWxlbWVudHMgPSBBcnJheS5mcm9tKHRoaXMuX2NvbnRhaW5lckVsZW1lbnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0cicpKVxuICAgICAgLnJlZHVjZSgoYWNjOiBhbnlbXSwgcm93RWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudDogYW55ID0geyB0YXJnZXQ6IHJvd0VsZW1lbnQgfTtcblxuICAgICAgICBpZiAocm93RWxlbWVudCA9PT0gdGhpcy5fZHJhZ2dhYmxlRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRJbmRleCA9IGluZGV4O1xuICAgICAgICAgIGVsZW1lbnQuYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFjYy5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCBbXSkgYXMgRnNMaXN0RHJhZ0NoaWxkUm93RWxlbWVudFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGMgY2hpbGQgcm93cyBzaXplcy9vZmZzZXRzXG4gICAqL1xuICBwcml2YXRlIGNhbGNFbGVtZW50c0RpbWVuc2lvbnMoKSB7XG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50cy5mb3JFYWNoKChlbDogYW55LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgZGltcyA9IGVsLnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGVsLnRvcCA9IGRpbXMudG9wO1xuICAgICAgZWwuaGVpZ2h0ID0gZGltcy5oZWlnaHQ7XG4gICAgICBlbC5jZW50ZXIgPSBkaW1zLnRvcCArIChkaW1zLmhlaWdodCAvIDIpO1xuICAgICAgZWwuaW5kZXggPSBpbmRleDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0IGRyYWdnYWJsZSBlbGVtZW50XG4gICAqL1xuICBwcml2YXRlIGluaXREcmFnZ2FibGVFbGVtZW50KCkge1xuICAgIGNvbnN0IGVsID0gdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuX2RyYWdnYWJsZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBlbC5zdHlsZS53aWR0aCA9IGRhdGEud2lkdGggKyAncHgnO1xuICAgIGVsLnN0eWxlLmxlZnQgPSBkYXRhLmxlZnQgKyAncHgnO1xuICAgIGVsLnN0eWxlLnRvcCA9IGRhdGEudG9wICsgJ3B4JztcblxuICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2RyYWdnYWJsZScpO1xuXG4gICAgdGhpcy5fY29udGFpbmVyRWxlbWVudC5uYXRpdmVFbGVtZW50Lmluc2VydEFkamFjZW50RWxlbWVudCgnYWZ0ZXJiZWdpbicsIGVsKTtcblxuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRQcmV2aWV3ID0gZWw7XG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudEhlaWdodCA9IGRhdGEuaGVpZ2h0O1xuXG4gICAgdGhpcy51cGRhdGVEcmFnZ2FibGVEaW1zKCk7XG4gIH1cblxuICAvKipcbiAgICogTG9va2luZyBieSBzdG9yZWQgcm93IGVsZW1lbnMgZm9yIG92ZXJsYXBwZWQgcm93XG4gICAqIEBwYXJhbSBldmVudFxuICAgKi9cbiAgcHJpdmF0ZSBsb29rdXBFbGVtZW50VW5kZXIoZXZlbnQpIHtcbiAgICBjb25zdCB0b3AgPSBldmVudC55IHx8IGV2ZW50LmNsaWVudFk7XG4gICAgY29uc3QgYm90dG9tID0gZXZlbnQueSB8fCBldmVudC5jbGllbnRZO1xuICAgIGxldCBlbGVtSW5kZXggPSBudWxsO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9jaGlsZFJvd0VsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbCA9IHRoaXMuX2NoaWxkUm93RWxlbWVudHNbaV07XG5cbiAgICAgIGlmICghZWwuYWN0aXZlKSB7XG4gICAgICAgIGlmICh0b3AgPCBlbC5jZW50ZXIgKyAoZWwuaGVpZ2h0IC8gMikgJiYgZWwuaW5kZXggPCB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXhcbiAgICAgICAgICB8fCBib3R0b20gPiBlbC5jZW50ZXIgLSAoZWwuaGVpZ2h0IC8gMikgICYmIGVsLmluZGV4ID4gdGhpcy5fZHJhZ2dhYmxlRWxlbWVudEluZGV4KSB7XG4gICAgICAgICAgZWxlbUluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlbGVtSW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogU3dhcCByb3dzXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgcHJpdmF0ZSBzd2FwV2l0aEluZGV4KGluZGV4KSB7XG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXg7XG5cbiAgICAvLyBTd2FwIHJvd3MgaW4gZ2xvYmFsIHJvd3Mgc3RhY2tcbiAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlclxuICAgICAgLmRhdGFDb250cm9sbGVyXG4gICAgICAuc3dhcFJvd3ModGhpcy5fcm93c1thY3RpdmVJbmRleF0gLCB0aGlzLl9yb3dzW2luZGV4XSk7XG5cbiAgICAvLyBTd2FwIHZpc2libGUgcm93c1xuICAgIGNvbnN0IGFjdGl2ZVJvdyA9IHRoaXMuX3Jvd3NbYWN0aXZlSW5kZXhdO1xuICAgIHRoaXMuX3Jvd3NbYWN0aXZlSW5kZXhdID0gdGhpcy5fcm93c1tpbmRleF07XG4gICAgdGhpcy5fcm93c1tpbmRleF0gPSBhY3RpdmVSb3c7XG5cbiAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gdGhpcy5fY2hpbGRSb3dFbGVtZW50c1thY3RpdmVJbmRleF0udGFyZ2V0O1xuICAgIHRoaXMuX2NoaWxkUm93RWxlbWVudHNbYWN0aXZlSW5kZXhdLmFjdGl2ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50c1thY3RpdmVJbmRleF0udGFyZ2V0ID0gdGhpcy5fY2hpbGRSb3dFbGVtZW50c1tpbmRleF0udGFyZ2V0O1xuICAgIHRoaXMuX2NoaWxkUm93RWxlbWVudHNbaW5kZXhdLnRhcmdldCA9IGFjdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50c1tpbmRleF0uYWN0aXZlID0gdHJ1ZTtcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXggPSBpbmRleDtcblxuICAgIHRoaXMuX2NkUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgY2VsbCB3aWR0aCBmb3IgZHJhZ2dhYmxlIGVsZW1cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlRHJhZ2dhYmxlRGltcygpIHtcbiAgICBjb25zdCBkcmFnZ2FibGVDZWxsczogYW55ID0gQXJyYXkuZnJvbSh0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5xdWVyeVNlbGVjdG9yQWxsKCd0ZCcpKTtcblxuICAgIEFycmF5LmZyb20oXG4gICAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5xdWVyeVNlbGVjdG9yQWxsKCd0ZCcpXG4gICAgKS5mb3JFYWNoKChlbGVtOiBhbnksIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBkaW1zID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGRyYWdnYWJsZUNlbGxzW2luZGV4XS5zdHlsZS53aWR0aCA9IGRpbXMud2lkdGggKyAncHgnO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfd2FpdFVudGlsSXNOb3REb25lKGRvbmVSZXN1bHQ6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoZG9uZVJlc3VsdCBpbnN0YW5jZW9mIE9ic2VydmFibGUpIHtcbiAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRpc2FibGVSZW9yZGVyQWN0aW9uKCk7XG5cbiAgICAgIGRvbmVSZXN1bHRcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ2VuYWJsZScpO1xuICAgICAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmVuYWJsZVJlb3JkZXJBY3Rpb24oKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpeCBiYWNrZ3JvdW5kIHdoZW4gbW9iaWxlXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBwcml2YXRlIHRvdWNoRml4KGUpIHtcbiAgICBpZiAoISgnY2xpZW50WCcgaW4gZSkgJiYgISgnY2xpZW50WScgaW4gZSkpIHtcbiAgICAgIGNvbnN0IHRvdWNoZXMgPSBlLnRvdWNoZXMgfHwgZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXM7XG4gICAgICBpZiAodG91Y2hlcyAmJiB0b3VjaGVzLmxlbmd0aCkge1xuICAgICAgICBlLmNsaWVudFggPSB0b3VjaGVzWzBdLmNsaWVudFg7XG4gICAgICAgIGUuY2xpZW50WSA9IHRvdWNoZXNbMF0uY2xpZW50WTtcbiAgICAgIH1cblxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxufVxuIl19
1
+ import { ChangeDetectorRef, Directive, ElementRef, Input, NgZone } from '@angular/core';
2
+ import { Observable, Subject } from 'rxjs';
3
+ import { takeUntil } from 'rxjs/operators';
4
+ import { ReorderController, ReorderStrategy } from '../../classes/reorder-controller';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../../classes/reorder-controller";
7
+ export class FsListDraggableListDirective {
8
+ constructor(_cdRef, _zone, _containerElement, _reorderController) {
9
+ this._cdRef = _cdRef;
10
+ this._zone = _zone;
11
+ this._containerElement = _containerElement;
12
+ this._reorderController = _reorderController;
13
+ // Handlers
14
+ this._dragToHandler = this.dragTo.bind(this);
15
+ this._dragEndHandler = this.dragEnd.bind(this);
16
+ this._windowTouchMoveHandler = () => { };
17
+ this._dragInProgress = false;
18
+ this._dragStart$ = new Subject();
19
+ this._dragEnd$ = new Subject();
20
+ this._destroy$ = new Subject();
21
+ }
22
+ get dragStart$() {
23
+ return this._dragStart$.pipe(takeUntil(this._destroy$));
24
+ }
25
+ get dragEnd$() {
26
+ return this._dragEnd$.pipe(takeUntil(this._destroy$));
27
+ }
28
+ get draggableItem() {
29
+ return this._rows[this._draggableElementIndex];
30
+ }
31
+ /**
32
+ * Prepare draggable elements and add events
33
+ * @param draggableElement
34
+ */
35
+ dragStart(draggableElement) {
36
+ if (this._dragInProgress) {
37
+ return;
38
+ }
39
+ if (this._reorderController.startCallback
40
+ && this._reorderController.strategy === ReorderStrategy.Always) {
41
+ this._reorderController.startCallback();
42
+ }
43
+ this._dragInProgress = true;
44
+ window.document.body.classList.add('reorder-in-progress');
45
+ this._draggableElement = draggableElement;
46
+ this.prepareElements();
47
+ this.initDraggableElement();
48
+ this._draggableElement.classList.add('draggable-elem');
49
+ this._zone.runOutsideAngular(() => {
50
+ window.addEventListener('touchmove', this._windowTouchMoveHandler, { passive: true });
51
+ window.document.addEventListener('mousemove', this._dragToHandler, { passive: true });
52
+ window.document.addEventListener('touchmove', this._dragToHandler, { passive: false });
53
+ window.document.addEventListener('mouseup', this._dragEndHandler);
54
+ window.document.addEventListener('touchend', this._dragEndHandler);
55
+ window.document.addEventListener('touchcancel', this._dragEndHandler);
56
+ });
57
+ this._dragStart$.next();
58
+ }
59
+ /**
60
+ * Move draggable elements and swap items
61
+ * @param event
62
+ */
63
+ dragTo(event) {
64
+ this.touchFix(event);
65
+ const elemIndex = this.lookupElementUnder(event);
66
+ const targetRow = this._rows[elemIndex];
67
+ // Can not drag before first group and after last group
68
+ const swapWithBoundaryGroupElement = (elemIndex === 0 || elemIndex === this._rows.length - 1)
69
+ && targetRow.isGroup
70
+ && this.draggableItem.isChild;
71
+ if (!swapWithBoundaryGroupElement) {
72
+ if (elemIndex !== null) {
73
+ if (targetRow.readyToSwap) {
74
+ this.swapWithIndex(elemIndex);
75
+ this._draggableElementPreview.classList.remove('fs-list-no-drop');
76
+ }
77
+ else {
78
+ this._draggableElementPreview.classList.add('fs-list-no-drop');
79
+ }
80
+ }
81
+ }
82
+ const topOffset = (event.y || event.clientY) - (this._draggableElementHeight / 2);
83
+ this._draggableElementPreview.style.top = topOffset + 'px';
84
+ }
85
+ /**
86
+ * Remove events and classes after drag finish
87
+ */
88
+ dragEnd() {
89
+ this._dragInProgress = false;
90
+ ///
91
+ if (this._reorderController.movedCallback) {
92
+ this._reorderController.movedCallback(this._reorderController.dataController.reorderData);
93
+ }
94
+ if (this._reorderController.strategy === ReorderStrategy.Always) {
95
+ this._zone.run(() => {
96
+ if (this._reorderController.doneCallback) {
97
+ const result = this._reorderController.doneCallback(this._reorderController.dataController.reorderData);
98
+ this._waitUntilIsNotDone(result);
99
+ }
100
+ });
101
+ }
102
+ // this._reorderController.dataController.updateOrderByRows(this._rows);
103
+ ///
104
+ this._draggableElement.classList.remove('draggable-elem');
105
+ window.document.body.classList.remove('reorder-in-progress');
106
+ this._draggableElementPreview.remove();
107
+ this._draggableElement = null;
108
+ this._draggableElementPreview = null;
109
+ this._draggableElementHeight = null;
110
+ this._draggableElementIndex = null;
111
+ window.removeEventListener('touchmove', this._windowTouchMoveHandler);
112
+ window.document.removeEventListener('mousemove', this._dragToHandler);
113
+ window.document.removeEventListener('touchmove', this._dragToHandler);
114
+ window.document.removeEventListener('mouseup', this._dragEndHandler);
115
+ window.document.removeEventListener('touchend', this._dragEndHandler);
116
+ window.document.removeEventListener('touchcancel', this._dragEndHandler);
117
+ this._dragEnd$.next();
118
+ }
119
+ /**
120
+ * looking row elements and save their dims
121
+ */
122
+ prepareElements() {
123
+ this.lookupChildElements();
124
+ this.calcElementsDimensions();
125
+ }
126
+ /**
127
+ * Store child rows
128
+ */
129
+ lookupChildElements() {
130
+ this._childRowElements = Array.from(this._containerElement.nativeElement.querySelectorAll('tr'))
131
+ .reduce((acc, rowElement, index) => {
132
+ const element = { target: rowElement };
133
+ if (rowElement === this._draggableElement) {
134
+ this._draggableElementIndex = index;
135
+ element.active = true;
136
+ }
137
+ acc.push(element);
138
+ return acc;
139
+ }, []);
140
+ }
141
+ /**
142
+ * Calc child rows sizes/offsets
143
+ */
144
+ calcElementsDimensions() {
145
+ this._childRowElements.forEach((el, index) => {
146
+ const dims = el.target.getBoundingClientRect();
147
+ el.top = dims.top;
148
+ el.height = dims.height;
149
+ el.center = dims.top + (dims.height / 2);
150
+ el.index = index;
151
+ });
152
+ }
153
+ /**
154
+ * Init draggable element
155
+ */
156
+ initDraggableElement() {
157
+ const el = this._draggableElement.cloneNode(true);
158
+ const data = this._draggableElement.getBoundingClientRect();
159
+ el.style.width = data.width + 'px';
160
+ el.style.left = data.left + 'px';
161
+ el.style.top = data.top + 'px';
162
+ el.classList.add('draggable');
163
+ this._containerElement.nativeElement.insertAdjacentElement('afterbegin', el);
164
+ this._draggableElementPreview = el;
165
+ this._draggableElementHeight = data.height;
166
+ this.updateDraggableDims();
167
+ }
168
+ /**
169
+ * Looking by stored row elemens for overlapped row
170
+ * @param event
171
+ */
172
+ lookupElementUnder(event) {
173
+ const top = event.y || event.clientY;
174
+ const bottom = event.y || event.clientY;
175
+ let elemIndex = null;
176
+ for (let i = 0; i < this._childRowElements.length; i++) {
177
+ const el = this._childRowElements[i];
178
+ if (!el.active) {
179
+ if (top < el.center + (el.height / 2) && el.index < this._draggableElementIndex
180
+ || bottom > el.center - (el.height / 2) && el.index > this._draggableElementIndex) {
181
+ elemIndex = i;
182
+ }
183
+ }
184
+ }
185
+ return elemIndex;
186
+ }
187
+ /**
188
+ * Swap rows
189
+ * @param index
190
+ */
191
+ swapWithIndex(index) {
192
+ const activeIndex = this._draggableElementIndex;
193
+ // Swap rows in global rows stack
194
+ this._reorderController
195
+ .dataController
196
+ .swapRows(this._rows[activeIndex], this._rows[index]);
197
+ // Swap visible rows
198
+ const activeRow = this._rows[activeIndex];
199
+ this._rows[activeIndex] = this._rows[index];
200
+ this._rows[index] = activeRow;
201
+ const activeElement = this._childRowElements[activeIndex].target;
202
+ this._childRowElements[activeIndex].active = false;
203
+ this._childRowElements[activeIndex].target = this._childRowElements[index].target;
204
+ this._childRowElements[index].target = activeElement;
205
+ this._childRowElements[index].active = true;
206
+ this._draggableElementIndex = index;
207
+ this._cdRef.detectChanges();
208
+ }
209
+ /**
210
+ * Update cell width for draggable elem
211
+ */
212
+ updateDraggableDims() {
213
+ const draggableCells = Array.from(this._draggableElementPreview.querySelectorAll('td'));
214
+ Array.from(this._draggableElementPreview.querySelectorAll('td')).forEach((elem, index) => {
215
+ const dims = elem.getBoundingClientRect();
216
+ draggableCells[index].style.width = dims.width + 'px';
217
+ });
218
+ }
219
+ _waitUntilIsNotDone(doneResult) {
220
+ if (doneResult instanceof Observable) {
221
+ this._reorderController.disableReorderAction();
222
+ doneResult
223
+ .pipe(takeUntil(this._destroy$))
224
+ .subscribe(() => {
225
+ console.log('enable');
226
+ this._reorderController.enableReorderAction();
227
+ });
228
+ }
229
+ }
230
+ /**
231
+ * Fix background when mobile
232
+ * @param e
233
+ */
234
+ touchFix(e) {
235
+ if (!('clientX' in e) && !('clientY' in e)) {
236
+ const touches = e.touches || e.originalEvent.touches;
237
+ if (touches && touches.length) {
238
+ e.clientX = touches[0].clientX;
239
+ e.clientY = touches[0].clientY;
240
+ }
241
+ e.preventDefault();
242
+ }
243
+ }
244
+ }
245
+ FsListDraggableListDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsListDraggableListDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i1.ReorderController }], target: i0.ɵɵFactoryTarget.Directive });
246
+ FsListDraggableListDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.16", type: FsListDraggableListDirective, selector: "[fsListDraggableList]", inputs: { _rows: ["rows", "_rows"] }, ngImport: i0 });
247
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsListDraggableListDirective, decorators: [{
248
+ type: Directive,
249
+ args: [{
250
+ selector: '[fsListDraggableList]',
251
+ }]
252
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i1.ReorderController }]; }, propDecorators: { _rows: [{
253
+ type: Input,
254
+ args: ['rows']
255
+ }] } });
256
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLWxpc3QuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9kaXJlY3RpdmVzL2RyYWdnYWJsZS1saXN0L2RyYWdnYWJsZS1saXN0LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXhGLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7OztBQVF0RixNQUFNLE9BQU8sNEJBQTRCO0lBd0J2QyxZQUNVLE1BQXlCLEVBQ3pCLEtBQWEsRUFDYixpQkFBNkIsRUFDN0Isa0JBQXFDO1FBSHJDLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQ3pCLFVBQUssR0FBTCxLQUFLLENBQVE7UUFDYixzQkFBaUIsR0FBakIsaUJBQWlCLENBQVk7UUFDN0IsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFtQjtRQXBCL0MsV0FBVztRQUNILG1CQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsb0JBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyw0QkFBdUIsR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFFbkMsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFHeEIsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2xDLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBS2hDLGNBQVMsR0FBRyxJ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QW1CO1FBQzdDLElBQUksVUFBVSxZQUFZLFVBQVUsRUFBRTtZQUNwQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUUvQyxVQUFVO2lCQUNQLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUMvQixTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ2hELENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssUUFBUSxDQUFDLENBQUM7UUFDaEIsSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLEVBQUU7WUFDMUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQztZQUNyRCxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO2dCQUM3QixDQUFDLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQy9CLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQzthQUNoQztZQUVELENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUNwQjtJQUNILENBQUM7OzBIQTNUVSw0QkFBNEI7OEdBQTVCLDRCQUE0Qjs0RkFBNUIsNEJBQTRCO2tCQUh4QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSx1QkFBdUI7aUJBQ2xDO3NMQXFCUyxLQUFLO3NCQURaLEtBQUs7dUJBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgUmVvcmRlckNvbnRyb2xsZXIsIFJlb3JkZXJTdHJhdGVneSB9IGZyb20gJy4uLy4uL2NsYXNzZXMvcmVvcmRlci1jb250cm9sbGVyJztcclxuaW1wb3J0IHsgUm93IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Jvdyc7XHJcbmltcG9ydCB7IEZzTGlzdERyYWdDaGlsZFJvd0VsZW1lbnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2RyYWdnYWJsZS1saXN0LmludGVyZmFjZSc7XHJcblxyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbZnNMaXN0RHJhZ2dhYmxlTGlzdF0nLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRnNMaXN0RHJhZ2dhYmxlTGlzdERpcmVjdGl2ZSB7XHJcblxyXG4gIC8vIERyYWdnYWJsZSBFbGVtZW50XHJcbiAgcHJpdmF0ZSBfZHJhZ2dhYmxlRWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgcHJpdmF0ZSBfZHJhZ2dhYmxlRWxlbWVudFByZXZpZXc6IEhUTUxFbGVtZW50O1xyXG4gIHByaXZhdGUgX2RyYWdnYWJsZUVsZW1lbnRIZWlnaHQ6IG51bWJlcjtcclxuICBwcml2YXRlIF9kcmFnZ2FibGVFbGVtZW50SW5kZXg6IG51bWJlcjtcclxuXHJcbiAgLy8gSGFuZGxlcnNcclxuICBwcml2YXRlIF9kcmFnVG9IYW5kbGVyID0gdGhpcy5kcmFnVG8uYmluZCh0aGlzKTtcclxuICBwcml2YXRlIF9kcmFnRW5kSGFuZGxlciA9IHRoaXMuZHJhZ0VuZC5iaW5kKHRoaXMpO1xyXG4gIHByaXZhdGUgX3dpbmRvd1RvdWNoTW92ZUhhbmRsZXIgPSAoKSA9PiB7fTtcclxuXHJcbiAgcHJpdmF0ZSBfZHJhZ0luUHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBfY2hpbGRSb3dFbGVtZW50czogRnNMaXN0RHJhZ0NoaWxkUm93RWxlbWVudFtdO1xyXG4gIHByaXZhdGUgX2RyYWdTdGFydCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gIHByaXZhdGUgX2RyYWdFbmQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgQElucHV0KCdyb3dzJylcclxuICBwcml2YXRlIF9yb3dzOiBSb3dbXTtcclxuXHJcbiAgcHJpdmF0ZSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX2NkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIHByaXZhdGUgX3pvbmU6IE5nWm9uZSxcclxuICAgIHByaXZhdGUgX2NvbnRhaW5lckVsZW1lbnQ6IEVsZW1lbnRSZWYsXHJcbiAgICBwcml2YXRlIF9yZW9yZGVyQ29udHJvbGxlcjogUmVvcmRlckNvbnRyb2xsZXIsXHJcbiAgKSB7fVxyXG5cclxuICBwdWJsaWMgZ2V0IGRyYWdTdGFydCQoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJhZ1N0YXJ0JC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBkcmFnRW5kJCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcclxuICAgIHJldHVybiB0aGlzLl9kcmFnRW5kJC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBkcmFnZ2FibGVJdGVtKCk6IFJvdyB7XHJcbiAgICByZXR1cm4gdGhpcy5fcm93c1t0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXhdO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUHJlcGFyZSBkcmFnZ2FibGUgZWxlbWVudHMgYW5kIGFkZCBldmVudHNcclxuICAgKiBAcGFyYW0gZHJhZ2dhYmxlRWxlbWVudFxyXG4gICAqL1xyXG4gIHB1YmxpYyBkcmFnU3RhcnQoZHJhZ2dhYmxlRWxlbWVudDogSFRNTEVsZW1lbnQpIHtcclxuICAgIGlmICh0aGlzLl9kcmFnSW5Qcm9ncmVzcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5zdGFydENhbGxiYWNrXHJcbiAgICAgICYmIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLnN0cmF0ZWd5ID09PSBSZW9yZGVyU3RyYXRlZ3kuQWx3YXlzXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuc3RhcnRDYWxsYmFjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2RyYWdJblByb2dyZXNzID0gdHJ1ZTtcclxuXHJcbiAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdyZW9yZGVyLWluLXByb2dyZXNzJyk7XHJcblxyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudCA9IGRyYWdnYWJsZUVsZW1lbnQ7XHJcblxyXG4gICAgdGhpcy5wcmVwYXJlRWxlbWVudHMoKTtcclxuXHJcbiAgICB0aGlzLmluaXREcmFnZ2FibGVFbGVtZW50KCk7XHJcblxyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2FibGUtZWxlbScpO1xyXG5cclxuICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggJ3RvdWNobW92ZScsIHRoaXMuX3dpbmRvd1RvdWNoTW92ZUhhbmRsZXIsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcclxuICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuX2RyYWdUb0hhbmRsZXIsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcclxuICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuX2RyYWdUb0hhbmRsZXIsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XHJcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fZHJhZ0VuZEhhbmRsZXIpO1xyXG4gICAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLl9kcmFnRW5kSGFuZGxlcik7XHJcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuX2RyYWdFbmRIYW5kbGVyKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX2RyYWdTdGFydCQubmV4dCgpO1xyXG5cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBNb3ZlIGRyYWdnYWJsZSBlbGVtZW50cyBhbmQgc3dhcCBpdGVtc1xyXG4gICAqIEBwYXJhbSBldmVudFxyXG4gICAqL1xyXG4gIHB1YmxpYyBkcmFnVG8oZXZlbnQpIHtcclxuICAgIHRoaXMudG91Y2hGaXgoZXZlbnQpO1xyXG4gICAgY29uc3QgZWxlbUluZGV4ID0gdGhpcy5sb29rdXBFbGVtZW50VW5kZXIoZXZlbnQpO1xyXG4gICAgY29uc3QgdGFyZ2V0Um93ID0gdGhpcy5fcm93c1tlbGVtSW5kZXhdO1xyXG5cclxuICAgIC8vIENhbiBub3QgZHJhZyBiZWZvcmUgZmlyc3QgZ3JvdXAgYW5kIGFmdGVyIGxhc3QgZ3JvdXBcclxuICAgIGNvbnN0IHN3YXBXaXRoQm91bmRhcnlHcm91cEVsZW1lbnQgPVxyXG4gICAgICAoZWxlbUluZGV4ID09PSAwIHx8IGVsZW1JbmRleCA9PT0gdGhpcy5fcm93cy5sZW5ndGggLSAxKVxyXG4gICAgICAmJiB0YXJnZXRSb3cuaXNHcm91cFxyXG4gICAgICAmJiB0aGlzLmRyYWdnYWJsZUl0ZW0uaXNDaGlsZDtcclxuXHJcbiAgICBpZiAoIXN3YXBXaXRoQm91bmRhcnlHcm91cEVsZW1lbnQpIHtcclxuICAgICAgaWYgKGVsZW1JbmRleCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGlmICh0YXJnZXRSb3cucmVhZHlUb1N3YXApIHtcclxuICAgICAgICAgIHRoaXMuc3dhcFdpdGhJbmRleChlbGVtSW5kZXgpXHJcbiAgICAgICAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5jbGFzc0xpc3QucmVtb3ZlKCdmcy1saXN0LW5vLWRyb3AnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudFByZXZpZXcuY2xhc3NMaXN0LmFkZCgnZnMtbGlzdC1uby1kcm9wJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdG9wT2Zmc2V0ID0gKGV2ZW50LnkgfHwgZXZlbnQuY2xpZW50WSkgLSAodGhpcy5fZHJhZ2dhYmxlRWxlbWVudEhlaWdodCAvIDIpO1xyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudFByZXZpZXcuc3R5bGUudG9wID0gIHRvcE9mZnNldCArICdweCc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmUgZXZlbnRzIGFuZCBjbGFzc2VzIGFmdGVyIGRyYWcgZmluaXNoXHJcbiAgICovXHJcbiAgcHVibGljIGRyYWdFbmQoKSB7XHJcbiAgICB0aGlzLl9kcmFnSW5Qcm9ncmVzcyA9IGZhbHNlO1xyXG5cclxuICAgIC8vL1xyXG4gICAgaWYgKHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLm1vdmVkQ2FsbGJhY2spIHtcclxuICAgICAgdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIubW92ZWRDYWxsYmFjayhcclxuICAgICAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5kYXRhQ29udHJvbGxlci5yZW9yZGVyRGF0YVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5zdHJhdGVneSA9PT0gUmVvcmRlclN0cmF0ZWd5LkFsd2F5cykge1xyXG4gICAgICB0aGlzLl96b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRvbmVDYWxsYmFjaykge1xyXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcmVvcmRlckNvbnRyb2xsZXIuZG9uZUNhbGxiYWNrKFxyXG4gICAgICAgICAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlci5kYXRhQ29udHJvbGxlci5yZW9yZGVyRGF0YVxyXG4gICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICB0aGlzLl93YWl0VW50aWxJc05vdERvbmUocmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRhdGFDb250cm9sbGVyLnVwZGF0ZU9yZGVyQnlSb3dzKHRoaXMuX3Jvd3MpO1xyXG4gICAgLy8vXHJcblxyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2FibGUtZWxlbScpO1xyXG4gICAgd2luZG93LmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgncmVvcmRlci1pbi1wcm9ncmVzcycpO1xyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudFByZXZpZXcucmVtb3ZlKCk7XHJcblxyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudCA9IG51bGw7XHJcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldyA9IG51bGw7XHJcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SGVpZ2h0ID0gbnVsbDtcclxuICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRJbmRleCA9IG51bGw7XHJcblxyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoICd0b3VjaG1vdmUnLCB0aGlzLl93aW5kb3dUb3VjaE1vdmVIYW5kbGVyKTtcclxuICAgIHdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLl9kcmFnVG9IYW5kbGVyKTtcclxuICAgIHdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLl9kcmFnVG9IYW5kbGVyKTtcclxuICAgIHdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fZHJhZ0VuZEhhbmRsZXIpO1xyXG4gICAgd2luZG93LmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5fZHJhZ0VuZEhhbmRsZXIpO1xyXG4gICAgd2luZG93LmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5fZHJhZ0VuZEhhbmRsZXIpO1xyXG5cclxuICAgIHRoaXMuX2RyYWdFbmQkLm5leHQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGxvb2tpbmcgcm93IGVsZW1lbnRzIGFuZCBzYXZlIHRoZWlyIGRpbXNcclxuICAgKi9cclxuICBwcml2YXRlIHByZXBhcmVFbGVtZW50cygpIHtcclxuICAgIHRoaXMubG9va3VwQ2hpbGRFbGVtZW50cygpO1xyXG4gICAgdGhpcy5jYWxjRWxlbWVudHNEaW1lbnNpb25zKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTdG9yZSBjaGlsZCByb3dzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBsb29rdXBDaGlsZEVsZW1lbnRzKCkge1xyXG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50cyA9IEFycmF5LmZyb20odGhpcy5fY29udGFpbmVyRWxlbWVudC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RyJykpXHJcbiAgICAgIC5yZWR1Y2UoKGFjYzogYW55W10sIHJvd0VsZW1lbnQsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudDogYW55ID0geyB0YXJnZXQ6IHJvd0VsZW1lbnQgfTtcclxuXHJcbiAgICAgICAgaWYgKHJvd0VsZW1lbnQgPT09IHRoaXMuX2RyYWdnYWJsZUVsZW1lbnQpIHtcclxuICAgICAgICAgIHRoaXMuX2RyYWdnYWJsZUVsZW1lbnRJbmRleCA9IGluZGV4O1xyXG4gICAgICAgICAgZWxlbWVudC5hY3RpdmUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYWNjLnB1c2goZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgIH0sIFtdKSBhcyBGc0xpc3REcmFnQ2hpbGRSb3dFbGVtZW50W107XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYWxjIGNoaWxkIHJvd3Mgc2l6ZXMvb2Zmc2V0c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgY2FsY0VsZW1lbnRzRGltZW5zaW9ucygpIHtcclxuICAgIHRoaXMuX2NoaWxkUm93RWxlbWVudHMuZm9yRWFjaCgoZWw6IGFueSwgaW5kZXgpID0+IHtcclxuICAgICAgY29uc3QgZGltcyA9IGVsLnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgZWwudG9wID0gZGltcy50b3A7XHJcbiAgICAgIGVsLmhlaWdodCA9IGRpbXMuaGVpZ2h0O1xyXG4gICAgICBlbC5jZW50ZXIgPSBkaW1zLnRvcCArIChkaW1zLmhlaWdodCAvIDIpO1xyXG4gICAgICBlbC5pbmRleCA9IGluZGV4O1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0IGRyYWdnYWJsZSBlbGVtZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpbml0RHJhZ2dhYmxlRWxlbWVudCgpIHtcclxuICAgIGNvbnN0IGVsID0gdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBkYXRhID0gdGhpcy5fZHJhZ2dhYmxlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBlbC5zdHlsZS53aWR0aCA9IGRhdGEud2lkdGggKyAncHgnO1xyXG4gICAgZWwuc3R5bGUubGVmdCA9IGRhdGEubGVmdCArICdweCc7XHJcbiAgICBlbC5zdHlsZS50b3AgPSBkYXRhLnRvcCArICdweCc7XHJcblxyXG4gICAgZWwuY2xhc3NMaXN0LmFkZCgnZHJhZ2dhYmxlJyk7XHJcblxyXG4gICAgdGhpcy5fY29udGFpbmVyRWxlbWVudC5uYXRpdmVFbGVtZW50Lmluc2VydEFkamFjZW50RWxlbWVudCgnYWZ0ZXJiZWdpbicsIGVsKTtcclxuXHJcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldyA9IGVsO1xyXG4gICAgdGhpcy5fZHJhZ2dhYmxlRWxlbWVudEhlaWdodCA9IGRhdGEuaGVpZ2h0O1xyXG5cclxuICAgIHRoaXMudXBkYXRlRHJhZ2dhYmxlRGltcygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9va2luZyBieSBzdG9yZWQgcm93IGVsZW1lbnMgZm9yIG92ZXJsYXBwZWQgcm93XHJcbiAgICogQHBhcmFtIGV2ZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBsb29rdXBFbGVtZW50VW5kZXIoZXZlbnQpIHtcclxuICAgIGNvbnN0IHRvcCA9IGV2ZW50LnkgfHwgZXZlbnQuY2xpZW50WTtcclxuICAgIGNvbnN0IGJvdHRvbSA9IGV2ZW50LnkgfHwgZXZlbnQuY2xpZW50WTtcclxuICAgIGxldCBlbGVtSW5kZXggPSBudWxsO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fY2hpbGRSb3dFbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBlbCA9IHRoaXMuX2NoaWxkUm93RWxlbWVudHNbaV07XHJcblxyXG4gICAgICBpZiAoIWVsLmFjdGl2ZSkge1xyXG4gICAgICAgIGlmICh0b3AgPCBlbC5jZW50ZXIgKyAoZWwuaGVpZ2h0IC8gMikgJiYgZWwuaW5kZXggPCB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXhcclxuICAgICAgICAgIHx8IGJvdHRvbSA+IGVsLmNlbnRlciAtIChlbC5oZWlnaHQgLyAyKSAgJiYgZWwuaW5kZXggPiB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXgpIHtcclxuICAgICAgICAgIGVsZW1JbmRleCA9IGk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsZW1JbmRleDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN3YXAgcm93c1xyXG4gICAqIEBwYXJhbSBpbmRleFxyXG4gICAqL1xyXG4gIHByaXZhdGUgc3dhcFdpdGhJbmRleChpbmRleCkge1xyXG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXg7XHJcblxyXG4gICAgLy8gU3dhcCByb3dzIGluIGdsb2JhbCByb3dzIHN0YWNrXHJcbiAgICB0aGlzLl9yZW9yZGVyQ29udHJvbGxlclxyXG4gICAgICAuZGF0YUNvbnRyb2xsZXJcclxuICAgICAgLnN3YXBSb3dzKHRoaXMuX3Jvd3NbYWN0aXZlSW5kZXhdICwgdGhpcy5fcm93c1tpbmRleF0pO1xyXG5cclxuICAgIC8vIFN3YXAgdmlzaWJsZSByb3dzXHJcbiAgICBjb25zdCBhY3RpdmVSb3cgPSB0aGlzLl9yb3dzW2FjdGl2ZUluZGV4XTtcclxuICAgIHRoaXMuX3Jvd3NbYWN0aXZlSW5kZXhdID0gdGhpcy5fcm93c1tpbmRleF07XHJcbiAgICB0aGlzLl9yb3dzW2luZGV4XSA9IGFjdGl2ZVJvdztcclxuXHJcbiAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gdGhpcy5fY2hpbGRSb3dFbGVtZW50c1thY3RpdmVJbmRleF0udGFyZ2V0O1xyXG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50c1thY3RpdmVJbmRleF0uYWN0aXZlID0gZmFsc2U7XHJcblxyXG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50c1thY3RpdmVJbmRleF0udGFyZ2V0ID0gdGhpcy5fY2hpbGRSb3dFbGVtZW50c1tpbmRleF0udGFyZ2V0O1xyXG4gICAgdGhpcy5fY2hpbGRSb3dFbGVtZW50c1tpbmRleF0udGFyZ2V0ID0gYWN0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuX2NoaWxkUm93RWxlbWVudHNbaW5kZXhdLmFjdGl2ZSA9IHRydWU7XHJcbiAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50SW5kZXggPSBpbmRleDtcclxuXHJcbiAgICB0aGlzLl9jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgY2VsbCB3aWR0aCBmb3IgZHJhZ2dhYmxlIGVsZW1cclxuICAgKi9cclxuICBwcml2YXRlIHVwZGF0ZURyYWdnYWJsZURpbXMoKSB7XHJcbiAgICBjb25zdCBkcmFnZ2FibGVDZWxsczogYW55ID0gQXJyYXkuZnJvbSh0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5xdWVyeVNlbGVjdG9yQWxsKCd0ZCcpKTtcclxuXHJcbiAgICBBcnJheS5mcm9tKFxyXG4gICAgICB0aGlzLl9kcmFnZ2FibGVFbGVtZW50UHJldmlldy5xdWVyeVNlbGVjdG9yQWxsKCd0ZCcpXHJcbiAgICApLmZvckVhY2goKGVsZW06IGFueSwgaW5kZXgpID0+IHtcclxuICAgICAgY29uc3QgZGltcyA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgIGRyYWdnYWJsZUNlbGxzW2luZGV4XS5zdHlsZS53aWR0aCA9IGRpbXMud2lkdGggKyAncHgnO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF93YWl0VW50aWxJc05vdERvbmUoZG9uZVJlc3VsdDogdW5rbm93bik6IHZvaWQge1xyXG4gICAgaWYgKGRvbmVSZXN1bHQgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XHJcbiAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmRpc2FibGVSZW9yZGVyQWN0aW9uKCk7XHJcblxyXG4gICAgICBkb25lUmVzdWx0XHJcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSlcclxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdlbmFibGUnKTtcclxuICAgICAgICAgIHRoaXMuX3Jlb3JkZXJDb250cm9sbGVyLmVuYWJsZVJlb3JkZXJBY3Rpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpeCBiYWNrZ3JvdW5kIHdoZW4gbW9iaWxlXHJcbiAgICogQHBhcmFtIGVcclxuICAgKi9cclxuICBwcml2YXRlIHRvdWNoRml4KGUpIHtcclxuICAgIGlmICghKCdjbGllbnRYJyBpbiBlKSAmJiAhKCdjbGllbnRZJyBpbiBlKSkge1xyXG4gICAgICBjb25zdCB0b3VjaGVzID0gZS50b3VjaGVzIHx8IGUub3JpZ2luYWxFdmVudC50b3VjaGVzO1xyXG4gICAgICBpZiAodG91Y2hlcyAmJiB0b3VjaGVzLmxlbmd0aCkge1xyXG4gICAgICAgIGUuY2xpZW50WCA9IHRvdWNoZXNbMF0uY2xpZW50WDtcclxuICAgICAgICBlLmNsaWVudFkgPSB0b3VjaGVzWzBdLmNsaWVudFk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19