@pepperi-addons/ngx-composite-lib 0.4.2-beta.9 → 0.4.2-beta.90

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 (175) hide show
  1. package/color-settings/color-settings.component.d.ts +3 -2
  2. package/core/common/services/dimx.service.d.ts +4 -0
  3. package/esm2020/color-settings/color-settings.component.mjs +6 -3
  4. package/esm2020/core/common/directives/reset-configuration-field.directive.mjs +5 -4
  5. package/esm2020/core/common/services/dimx.service.mjs +1 -1
  6. package/esm2020/data-view-builder/menu-data-view/menu-data-view.component.mjs +2 -2
  7. package/esm2020/file-status-panel/file-status-panel.module.mjs +23 -3
  8. package/esm2020/flow-picker-button/flow-picker-button.component.mjs +94 -0
  9. package/esm2020/flow-picker-button/flow-picker-button.module.mjs +36 -0
  10. package/esm2020/flow-picker-button/flow-picker-button.service.mjs +21 -0
  11. package/esm2020/flow-picker-button/pepperi-addons-ngx-composite-lib-flow-picker-button.mjs +5 -0
  12. package/esm2020/flow-picker-button/public-api.mjs +6 -0
  13. package/esm2020/generic-list/generic-list.component.mjs +50 -7
  14. package/esm2020/generic-list/generic-list.service.mjs +6 -2
  15. package/esm2020/group-buttons-settings/group-buttons-settings.component.mjs +17 -4
  16. package/esm2020/group-buttons-settings/group-buttons-settings.model.mjs +1 -1
  17. package/esm2020/group-buttons-settings/public-api.mjs +2 -2
  18. package/esm2020/icon-picker/icon-picker.component.mjs +79 -0
  19. package/esm2020/icon-picker/icon-picker.module.mjs +44 -0
  20. package/esm2020/icon-picker/icon-picker.service.mjs +17 -0
  21. package/esm2020/icon-picker/pepperi-addons-ngx-composite-lib-icon-picker.mjs +5 -0
  22. package/esm2020/icon-picker/public-api.mjs +6 -0
  23. package/esm2020/layout-builder/hide-in/hide-in.component.mjs +54 -0
  24. package/esm2020/layout-builder/hide-in/hide-in.module.mjs +81 -0
  25. package/esm2020/layout-builder/layout/layout.component.mjs +204 -0
  26. package/esm2020/layout-builder/layout/layout.module.mjs +54 -0
  27. package/esm2020/layout-builder/layout-builder-editor/layout-builder-editor.component.mjs +25 -0
  28. package/esm2020/layout-builder/layout-builder-editor/layout-builder-editor.module.mjs +45 -0
  29. package/esm2020/layout-builder/layout-builder-internal.service.mjs +628 -0
  30. package/esm2020/layout-builder/layout-builder.component.mjs +201 -0
  31. package/esm2020/layout-builder/layout-builder.model.mjs +2 -0
  32. package/esm2020/layout-builder/layout-builder.module.mjs +143 -0
  33. package/esm2020/layout-builder/layout-builder.service.mjs +36 -0
  34. package/esm2020/layout-builder/main-editor/main-editor.component.mjs +130 -0
  35. package/esm2020/layout-builder/main-editor/main-editor.module.mjs +99 -0
  36. package/esm2020/layout-builder/pepperi-addons-ngx-composite-lib-layout-builder.mjs +5 -0
  37. package/esm2020/layout-builder/public-api.mjs +12 -0
  38. package/esm2020/layout-builder/section/section.component.mjs +349 -0
  39. package/esm2020/layout-builder/section/section.module.mjs +44 -0
  40. package/esm2020/layout-builder/section-block/section-block.component.mjs +113 -0
  41. package/esm2020/layout-builder/section-block/section-block.module.mjs +34 -0
  42. package/esm2020/layout-builder/section-editor/section-editor.component.mjs +192 -0
  43. package/esm2020/layout-builder/section-editor/section-editor.module.mjs +44 -0
  44. package/esm2020/manage-parameters/manage-parameter/manage-parameter.component.mjs +82 -0
  45. package/esm2020/manage-parameters/manage-parameters.component.mjs +153 -0
  46. package/esm2020/manage-parameters/manage-parameters.model.mjs +24 -0
  47. package/esm2020/manage-parameters/manage-parameters.module.mjs +45 -0
  48. package/esm2020/manage-parameters/manage-parameters.service.mjs +142 -0
  49. package/esm2020/manage-parameters/pepperi-addons-ngx-composite-lib-manage-parameters.mjs +5 -0
  50. package/esm2020/manage-parameters/public-api.mjs +8 -0
  51. package/esm2020/rich-text/pepperi-addons-ngx-composite-lib-rich-text.mjs +5 -0
  52. package/esm2020/rich-text/public-api.mjs +6 -0
  53. package/esm2020/rich-text/rich-text.component.mjs +154 -0
  54. package/esm2020/rich-text/rich-text.module.mjs +52 -0
  55. package/esm2020/rich-text/rich-text.service.mjs +21 -0
  56. package/esm2020/shadow-settings/shadow-settings.component.mjs +7 -4
  57. package/esm2020/show-if-badge/pepperi-addons-ngx-composite-lib-show-if-badge.mjs +5 -0
  58. package/esm2020/show-if-badge/public-api.mjs +6 -0
  59. package/esm2020/show-if-badge/show-if-badge.component.mjs +44 -0
  60. package/esm2020/show-if-badge/show-if-badge.module.mjs +50 -0
  61. package/fesm2015/pepperi-addons-ngx-composite-lib-color-settings.mjs +5 -2
  62. package/fesm2015/pepperi-addons-ngx-composite-lib-color-settings.mjs.map +1 -1
  63. package/fesm2015/pepperi-addons-ngx-composite-lib-data-view-builder.mjs +2 -2
  64. package/fesm2015/pepperi-addons-ngx-composite-lib-file-status-panel.mjs +22 -3
  65. package/fesm2015/pepperi-addons-ngx-composite-lib-file-status-panel.mjs.map +1 -1
  66. package/fesm2015/pepperi-addons-ngx-composite-lib-flow-picker-button.mjs +161 -0
  67. package/fesm2015/pepperi-addons-ngx-composite-lib-flow-picker-button.mjs.map +1 -0
  68. package/fesm2015/pepperi-addons-ngx-composite-lib-generic-list.mjs +55 -7
  69. package/fesm2015/pepperi-addons-ngx-composite-lib-generic-list.mjs.map +1 -1
  70. package/fesm2015/pepperi-addons-ngx-composite-lib-group-buttons-settings.mjs +17 -4
  71. package/fesm2015/pepperi-addons-ngx-composite-lib-group-buttons-settings.mjs.map +1 -1
  72. package/fesm2015/pepperi-addons-ngx-composite-lib-icon-picker.mjs +146 -0
  73. package/fesm2015/pepperi-addons-ngx-composite-lib-icon-picker.mjs.map +1 -0
  74. package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder.mjs +2343 -0
  75. package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder.mjs.map +1 -0
  76. package/fesm2015/pepperi-addons-ngx-composite-lib-manage-parameters.mjs +441 -0
  77. package/fesm2015/pepperi-addons-ngx-composite-lib-manage-parameters.mjs.map +1 -0
  78. package/fesm2015/pepperi-addons-ngx-composite-lib-rich-text.mjs +234 -0
  79. package/fesm2015/pepperi-addons-ngx-composite-lib-rich-text.mjs.map +1 -0
  80. package/fesm2015/pepperi-addons-ngx-composite-lib-shadow-settings.mjs +6 -3
  81. package/fesm2015/pepperi-addons-ngx-composite-lib-shadow-settings.mjs.map +1 -1
  82. package/fesm2015/pepperi-addons-ngx-composite-lib-show-if-badge.mjs +100 -0
  83. package/fesm2015/pepperi-addons-ngx-composite-lib-show-if-badge.mjs.map +1 -0
  84. package/fesm2015/pepperi-addons-ngx-composite-lib.mjs +4 -3
  85. package/fesm2015/pepperi-addons-ngx-composite-lib.mjs.map +1 -1
  86. package/fesm2020/pepperi-addons-ngx-composite-lib-color-settings.mjs +5 -2
  87. package/fesm2020/pepperi-addons-ngx-composite-lib-color-settings.mjs.map +1 -1
  88. package/fesm2020/pepperi-addons-ngx-composite-lib-data-view-builder.mjs +2 -2
  89. package/fesm2020/pepperi-addons-ngx-composite-lib-file-status-panel.mjs +22 -3
  90. package/fesm2020/pepperi-addons-ngx-composite-lib-file-status-panel.mjs.map +1 -1
  91. package/fesm2020/pepperi-addons-ngx-composite-lib-flow-picker-button.mjs +155 -0
  92. package/fesm2020/pepperi-addons-ngx-composite-lib-flow-picker-button.mjs.map +1 -0
  93. package/fesm2020/pepperi-addons-ngx-composite-lib-generic-list.mjs +54 -7
  94. package/fesm2020/pepperi-addons-ngx-composite-lib-generic-list.mjs.map +1 -1
  95. package/fesm2020/pepperi-addons-ngx-composite-lib-group-buttons-settings.mjs +17 -4
  96. package/fesm2020/pepperi-addons-ngx-composite-lib-group-buttons-settings.mjs.map +1 -1
  97. package/fesm2020/pepperi-addons-ngx-composite-lib-icon-picker.mjs +145 -0
  98. package/fesm2020/pepperi-addons-ngx-composite-lib-icon-picker.mjs.map +1 -0
  99. package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder.mjs +2320 -0
  100. package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder.mjs.map +1 -0
  101. package/fesm2020/pepperi-addons-ngx-composite-lib-manage-parameters.mjs +438 -0
  102. package/fesm2020/pepperi-addons-ngx-composite-lib-manage-parameters.mjs.map +1 -0
  103. package/fesm2020/pepperi-addons-ngx-composite-lib-rich-text.mjs +230 -0
  104. package/fesm2020/pepperi-addons-ngx-composite-lib-rich-text.mjs.map +1 -0
  105. package/fesm2020/pepperi-addons-ngx-composite-lib-shadow-settings.mjs +6 -3
  106. package/fesm2020/pepperi-addons-ngx-composite-lib-shadow-settings.mjs.map +1 -1
  107. package/fesm2020/pepperi-addons-ngx-composite-lib-show-if-badge.mjs +100 -0
  108. package/fesm2020/pepperi-addons-ngx-composite-lib-show-if-badge.mjs.map +1 -0
  109. package/fesm2020/pepperi-addons-ngx-composite-lib.mjs +4 -3
  110. package/fesm2020/pepperi-addons-ngx-composite-lib.mjs.map +1 -1
  111. package/flow-picker-button/flow-picker-button.component.d.ts +27 -0
  112. package/flow-picker-button/flow-picker-button.module.d.ts +11 -0
  113. package/flow-picker-button/flow-picker-button.service.d.ts +9 -0
  114. package/flow-picker-button/index.d.ts +5 -0
  115. package/flow-picker-button/public-api.d.ts +2 -0
  116. package/generic-list/generic-list.component.d.ts +13 -4
  117. package/generic-list/generic-list.service.d.ts +2 -1
  118. package/group-buttons-settings/group-buttons-settings.component.d.ts +5 -2
  119. package/group-buttons-settings/group-buttons-settings.model.d.ts +1 -1
  120. package/icon-picker/icon-picker.component.d.ts +24 -0
  121. package/icon-picker/icon-picker.module.d.ts +13 -0
  122. package/icon-picker/icon-picker.service.d.ts +8 -0
  123. package/icon-picker/index.d.ts +5 -0
  124. package/icon-picker/public-api.d.ts +2 -0
  125. package/layout-builder/hide-in/hide-in.component.d.ts +25 -0
  126. package/layout-builder/hide-in/hide-in.component.theme.scss +9 -0
  127. package/layout-builder/hide-in/hide-in.module.d.ts +20 -0
  128. package/layout-builder/index.d.ts +5 -0
  129. package/layout-builder/layout/layout.component.d.ts +49 -0
  130. package/layout-builder/layout/layout.module.d.ts +16 -0
  131. package/layout-builder/layout-builder-editor/layout-builder-editor.component.d.ts +12 -0
  132. package/layout-builder/layout-builder-editor/layout-builder-editor.module.d.ts +14 -0
  133. package/layout-builder/layout-builder-internal.service.d.ts +120 -0
  134. package/layout-builder/layout-builder.component.d.ts +51 -0
  135. package/layout-builder/layout-builder.component.theme.scss +57 -0
  136. package/layout-builder/layout-builder.model.d.ts +43 -0
  137. package/layout-builder/layout-builder.module.d.ts +32 -0
  138. package/layout-builder/layout-builder.service.d.ts +15 -0
  139. package/layout-builder/main-editor/main-editor.component.d.ts +46 -0
  140. package/layout-builder/main-editor/main-editor.module.d.ts +27 -0
  141. package/layout-builder/public-api.d.ts +8 -0
  142. package/layout-builder/section/section.component.d.ts +76 -0
  143. package/layout-builder/section/section.component.theme.scss +115 -0
  144. package/layout-builder/section/section.module.d.ts +14 -0
  145. package/layout-builder/section-block/section-block.component.d.ts +38 -0
  146. package/layout-builder/section-block/section-block.component.theme.scss +13 -0
  147. package/layout-builder/section-block/section-block.module.d.ts +11 -0
  148. package/layout-builder/section-editor/section-editor.component.d.ts +53 -0
  149. package/layout-builder/section-editor/section-editor.module.d.ts +14 -0
  150. package/manage-parameters/index.d.ts +5 -0
  151. package/manage-parameters/manage-parameter/manage-parameter.component.d.ts +28 -0
  152. package/manage-parameters/manage-parameters.component.d.ts +33 -0
  153. package/manage-parameters/manage-parameters.model.d.ts +21 -0
  154. package/manage-parameters/manage-parameters.module.d.ts +14 -0
  155. package/manage-parameters/manage-parameters.service.d.ts +16 -0
  156. package/manage-parameters/public-api.d.ts +3 -0
  157. package/package.json +49 -1
  158. package/rich-text/index.d.ts +5 -0
  159. package/rich-text/public-api.d.ts +2 -0
  160. package/rich-text/rich-text.component.d.ts +43 -0
  161. package/rich-text/rich-text.module.d.ts +16 -0
  162. package/rich-text/rich-text.service.d.ts +9 -0
  163. package/shadow-settings/shadow-settings.component.d.ts +2 -1
  164. package/show-if-badge/index.d.ts +5 -0
  165. package/show-if-badge/public-api.d.ts +2 -0
  166. package/show-if-badge/show-if-badge.component.d.ts +20 -0
  167. package/show-if-badge/show-if-badge.module.d.ts +16 -0
  168. package/src/assets/i18n/en.ngx-composite-lib.json +80 -4
  169. package/pepperi-addons-ngx-composite-lib-0.4.2-beta.8.tgz +0 -0
  170. package/src/assets/images/brand-leaf-full@1x.png +0 -0
  171. package/src/assets/images/brand-leaf-full@2x.png +0 -0
  172. package/src/assets/images/brand-leaf-round.png +0 -0
  173. package/src/assets/images/brand-leaf-round@2x.png +0 -0
  174. package/src/assets/images/brand-leaf-skiny@1x.png +0 -0
  175. package/src/assets/images/brand-leaf-skiny@2x.png +0 -0
@@ -0,0 +1,628 @@
1
+ import { Injectable } from "@angular/core";
2
+ import { coerceNumberProperty } from "@angular/cdk/coercion";
3
+ import { moveItemInArray } from "@angular/cdk/drag-drop";
4
+ import { PepGuid, PepScreenSizeType } from "@pepperi-addons/ngx-lib";
5
+ import { BehaviorSubject } from 'rxjs';
6
+ import { distinctUntilChanged, filter } from 'rxjs/operators';
7
+ import { PepDialogData } from "@pepperi-addons/ngx-lib/dialog";
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@ngx-translate/core";
10
+ import * as i2 from "@pepperi-addons/ngx-lib/dialog";
11
+ import * as i3 from "@pepperi-addons/ngx-lib";
12
+ export class LayoutBuilderInternalService {
13
+ constructor(translate, dialogService, layoutService) {
14
+ this.translate = translate;
15
+ this.dialogService = dialogService;
16
+ this.layoutService = layoutService;
17
+ this._defaultSectionTitle = '';
18
+ // This configuration is for blocks behavior.
19
+ this._blocksLimitNumber = 0;
20
+ this._navigateToEditorAfterBlockAdded = false;
21
+ this._getBlockTitle = (blockKey) => { return blockKey; };
22
+ this._editorsBreadCrumb = Array();
23
+ this._editMode = false;
24
+ this._editableState = false;
25
+ // This subject is for the screen size change events.
26
+ this._screenSizeSubject = new BehaviorSubject(undefined);
27
+ // This subject is for demostrate the container size (Usage only in edit mode).
28
+ this._screenWidthSubject = new BehaviorSubject('100%');
29
+ // This subject is for load the current editor (Usage only in edit mode).
30
+ this._editorSubject = new BehaviorSubject(null);
31
+ // This is the sections columns drop list subject.
32
+ this._sectionsColumnsDropListSubject = new BehaviorSubject([]);
33
+ // This is the sections subject (a pare from the layout view object)
34
+ this._sectionsViewSubject = new BehaviorSubject([]);
35
+ // This subject is for layout view change.
36
+ this._layoutViewSubject = new BehaviorSubject(null);
37
+ // This subject is for edit mode when block is dragging now or not.
38
+ this._draggingBlockKey = new BehaviorSubject('');
39
+ // This subject is for edit mode when section is dragging now or not.
40
+ this._draggingSectionKey = new BehaviorSubject('');
41
+ // This subject is for lock or unlock the screen (Usage only in edit mode).
42
+ this._lockScreenSubject = new BehaviorSubject(false);
43
+ // This is for control the preview mode (for load the blocks with the CPI events)
44
+ this._previewModeSubject = new BehaviorSubject(false);
45
+ // This is for editor mode for block added.
46
+ this._blockAddedEventSubject = new BehaviorSubject(null);
47
+ // This is for editor mode for blocks removed.
48
+ this._blocksRemovedEventSubject = new BehaviorSubject([]);
49
+ // This subject is for skeleton.
50
+ this._showSkeletonSubject = new BehaviorSubject(true);
51
+ //
52
+ this.translate.get('LAYOUT_BUILDER.SECTION').subscribe((res) => {
53
+ // Set the default section name.
54
+ this._defaultSectionTitle = res;
55
+ });
56
+ this.layoutService.onResize$.subscribe((size) => {
57
+ this.notifyScreenSizeChange(size);
58
+ });
59
+ }
60
+ setBlocksConfig(value) {
61
+ this._blocksLimitNumber = value.blocksLimitNumber || 0;
62
+ this._navigateToEditorAfterBlockAdded = value.navigateToEditorAfterBlockAdded ?? false;
63
+ this._getBlockTitle = value.getBlockTitle ? value.getBlockTitle : (blockKey) => { return blockKey; };
64
+ }
65
+ get editMode() {
66
+ return this._editMode;
67
+ }
68
+ setEditMode(value) {
69
+ this._editMode = value;
70
+ this.setEditableState();
71
+ }
72
+ get editableState() {
73
+ return this._editableState;
74
+ }
75
+ get screenSizeChange$() {
76
+ return this._screenSizeSubject.asObservable().pipe(distinctUntilChanged());
77
+ }
78
+ get screenWidthChange$() {
79
+ return this._screenWidthSubject.asObservable().pipe(distinctUntilChanged());
80
+ }
81
+ get editorChange$() {
82
+ return this._editorSubject.asObservable().pipe(distinctUntilChanged());
83
+ }
84
+ get sectionsColumnsDropListChange$() {
85
+ return this._sectionsColumnsDropListSubject.asObservable();
86
+ }
87
+ get sectionsChange$() {
88
+ return this._sectionsViewSubject.asObservable();
89
+ // (prevSections, nextSections) => JSON.stringify(prevSections) === JSON.stringify(nextSections)));
90
+ }
91
+ get layoutViewChange$() {
92
+ return this._layoutViewSubject.asObservable().pipe(filter(layout => !!layout));
93
+ }
94
+ get draggingBlockKey() {
95
+ return this._draggingBlockKey.asObservable().pipe(distinctUntilChanged());
96
+ }
97
+ get draggingSectionKey() {
98
+ return this._draggingSectionKey.asObservable().pipe(distinctUntilChanged());
99
+ }
100
+ get lockScreenChange$() {
101
+ return this._lockScreenSubject.asObservable().pipe(distinctUntilChanged());
102
+ }
103
+ get previewModeChange$() {
104
+ return this._previewModeSubject.asObservable().pipe(distinctUntilChanged());
105
+ }
106
+ get blockAddedEventSubject$() {
107
+ return this._blockAddedEventSubject.asObservable();
108
+ }
109
+ get blocksRemovedEventSubject$() {
110
+ return this._blocksRemovedEventSubject.asObservable();
111
+ }
112
+ get showSkeletonChange$() {
113
+ return this._showSkeletonSubject.asObservable().pipe(distinctUntilChanged());
114
+ }
115
+ setEditableState() {
116
+ this._editableState = this.editMode && !this._previewModeSubject.getValue();
117
+ }
118
+ notifyLayoutViewChange(layoutViewToUpdate) {
119
+ if (layoutViewToUpdate) {
120
+ if (this.editMode) {
121
+ this.updateLayoutEditorProperties(layoutViewToUpdate);
122
+ }
123
+ // Update the layout for the view.
124
+ this._layoutViewSubject.next(layoutViewToUpdate);
125
+ // Update the sections for the view.
126
+ this._sectionsViewSubject.next(layoutViewToUpdate?.Layout.Sections || []);
127
+ }
128
+ }
129
+ notifyBlockAdded(blockAddedEventData) {
130
+ // Notify that the block is added (to raise the event for the client).
131
+ this._blockAddedEventSubject.next(blockAddedEventData);
132
+ }
133
+ notifyBlocksRemoved(keys) {
134
+ if (keys) {
135
+ // Notify that the blocks are removed (to raise the event for the client).
136
+ this._blocksRemovedEventSubject.next(keys);
137
+ }
138
+ }
139
+ notifyEditorChange(editor) {
140
+ this._editorSubject.next(editor);
141
+ }
142
+ notifyPreviewModeChange(value) {
143
+ this._previewModeSubject.next(value);
144
+ this.setEditableState();
145
+ }
146
+ notifyLockScreen(value) {
147
+ this._lockScreenSubject.next(value);
148
+ }
149
+ notifySectionsColumnsDropListChange(sectionsColumnsDropList) {
150
+ this._sectionsColumnsDropListSubject.next(sectionsColumnsDropList);
151
+ }
152
+ notifyScreenSizeChange(size) {
153
+ this._screenSizeSubject.next(size);
154
+ }
155
+ updateLayoutEditorProperties(layoutView) {
156
+ if (this._editorsBreadCrumb[0]) {
157
+ const layoutEditor = {
158
+ maxWidth: layoutView?.Layout.MaxWidth || 0,
159
+ verticalSpacing: layoutView?.Layout.VerticalSpacing,
160
+ horizontalSpacing: layoutView?.Layout.HorizontalSpacing,
161
+ sectionsGap: layoutView?.Layout.SectionsGap,
162
+ columnsGap: layoutView?.Layout.ColumnsGap,
163
+ // roundedCorners: layoutView?.Layout.RoundedCorners
164
+ };
165
+ this._editorsBreadCrumb[0].hostObject = layoutEditor;
166
+ }
167
+ }
168
+ loadDefaultEditor(layoutView) {
169
+ this._editorsBreadCrumb = new Array();
170
+ if (layoutView) {
171
+ this.translate.get('LAYOUT_BUILDER.DEFAULT_TITLE').subscribe((title) => {
172
+ this._editorsBreadCrumb.push({
173
+ id: LayoutBuilderInternalService.MAIN_EDITOR_ID,
174
+ type: 'layout-builder',
175
+ title: title,
176
+ // hostObject: {} // Updates in updateLayoutEditorProperties function above.
177
+ });
178
+ this.updateLayoutEditorProperties(layoutView);
179
+ this.notifyEditorChange(this._editorsBreadCrumb[0]);
180
+ });
181
+ }
182
+ else {
183
+ this.notifyEditorChange(null);
184
+ }
185
+ }
186
+ changeCurrentEditor() {
187
+ if (this._editorsBreadCrumb.length > 0) {
188
+ this.notifyEditorChange(this._editorsBreadCrumb[this._editorsBreadCrumb.length - 1]);
189
+ }
190
+ }
191
+ getEditorByType(editorType, id, title = '') {
192
+ // Build editor object.
193
+ let editor = null;
194
+ if (editorType === 'section') {
195
+ editor = this.getSectionEditor(id, title);
196
+ }
197
+ else if (editorType === 'block') {
198
+ editor = this.getBlockEditor(id, title);
199
+ }
200
+ return editor;
201
+ }
202
+ getBlockEditor(blockKey, title) {
203
+ // Get block editor title.
204
+ const blockTitle = title || this.getBlockTitle(blockKey);
205
+ return {
206
+ id: blockKey,
207
+ type: 'block',
208
+ title: blockTitle
209
+ };
210
+ }
211
+ getSectionEditorTitle(section, sectionIndex) {
212
+ return section.Name || `${this._defaultSectionTitle} ${sectionIndex + 1}`;
213
+ }
214
+ getSectionEditor(sectionId, title) {
215
+ const layoutView = this._layoutViewSubject.getValue();
216
+ const sections = layoutView?.Layout.Sections || [];
217
+ const sectionIndex = sections.findIndex(section => section.Key === sectionId);
218
+ if (sectionIndex >= 0) {
219
+ const section = sections[sectionIndex];
220
+ const sectionEditor = {
221
+ id: section.Key,
222
+ sectionName: section.Name || '',
223
+ split: section.Split || undefined,
224
+ height: section.Height || 0,
225
+ collapseOnTablet: section.CollapseOnTablet ?? false,
226
+ fillHeight: section.FillHeight ?? false
227
+ };
228
+ return {
229
+ id: sectionId,
230
+ type: 'section',
231
+ title: title || this.getSectionEditorTitle(section, sectionIndex),
232
+ hostObject: sectionEditor
233
+ };
234
+ }
235
+ else {
236
+ return null;
237
+ }
238
+ }
239
+ getSectionColumnByIdForEditor(sectionColumnId) {
240
+ let currentColumn = null;
241
+ // Get the section and column array by the pattern of the section column key.
242
+ const sectionColumnPatternSeparator = this.getSectionColumnKey();
243
+ const sectionColumnArr = sectionColumnId.split(sectionColumnPatternSeparator);
244
+ if (sectionColumnArr.length === 2) {
245
+ const layoutView = this._layoutViewSubject.getValue();
246
+ const sections = layoutView?.Layout.Sections || [];
247
+ // Get the section id to get the section index.
248
+ const sectionId = sectionColumnArr[0];
249
+ const sectionIndex = sections.findIndex(section => section.Key === sectionId);
250
+ // Get the column index.
251
+ const columnIndex = coerceNumberProperty(sectionColumnArr[1], -1);
252
+ if (sectionIndex >= 0 && columnIndex >= 0) {
253
+ currentColumn = sections[sectionIndex].Columns[columnIndex];
254
+ }
255
+ }
256
+ return currentColumn;
257
+ }
258
+ getCssScreenWidh(screenType) {
259
+ let widthToSet = '100%';
260
+ if (screenType === 'Tablet') {
261
+ widthToSet = '720';
262
+ }
263
+ else if (screenType === 'Phablet') {
264
+ widthToSet = '360';
265
+ }
266
+ return widthToSet;
267
+ }
268
+ getBlocksNumber() {
269
+ let blocksNumber = 0;
270
+ const sections = this._layoutViewSubject.getValue()?.Layout.Sections || [];
271
+ for (let index = 0; index < sections.length; index++) {
272
+ const section = sections[index];
273
+ for (let columnIndex = 0; columnIndex < section.Columns.length; columnIndex++) {
274
+ const column = section.Columns[columnIndex];
275
+ if (column.BlockContainer && column.BlockContainer.BlockKey?.length > 0) {
276
+ blocksNumber++;
277
+ }
278
+ }
279
+ }
280
+ return blocksNumber;
281
+ }
282
+ changeCursorOnDragStart() {
283
+ document.body.classList.add('inheritCursors');
284
+ document.body.style.cursor = 'grabbing';
285
+ }
286
+ changeCursorOnDragEnd() {
287
+ document.body.classList.remove('inheritCursors');
288
+ document.body.style.cursor = 'unset';
289
+ }
290
+ /***********************************************************************************************/
291
+ /* Public functions
292
+ /***********************************************************************************************/
293
+ getBlockTitle(blockKey) {
294
+ return this._getBlockTitle(blockKey) || blockKey;
295
+ }
296
+ setSectionsColumnsDropListChange(sectionsColumnsDropList) {
297
+ this.notifySectionsColumnsDropListChange(sectionsColumnsDropList);
298
+ }
299
+ changePreviewMode(value) {
300
+ this.notifyPreviewModeChange(value);
301
+ }
302
+ getCurrentScreenType() {
303
+ return this.getScreenType(this._screenSizeSubject?.getValue() || PepScreenSizeType.LG);
304
+ }
305
+ getScreenType(size) {
306
+ const screenType = size < PepScreenSizeType.MD ? 'Landscape' :
307
+ (size === PepScreenSizeType.MD || size === PepScreenSizeType.SM ? 'Tablet' : 'Phablet');
308
+ return screenType;
309
+ }
310
+ getSectionColumnKey(sectionKey = '', index = '') {
311
+ return `${sectionKey}_column_${index}`;
312
+ }
313
+ getIsHidden(hideIn, currentScreenType) {
314
+ return (hideIn && hideIn?.length > 0) ? hideIn.some(hi => hi === currentScreenType) : false;
315
+ }
316
+ navigateToEditor(editorType, id, title = '') {
317
+ let success = false;
318
+ // Cannot navigate into 'layout-builder' because this is first and const in the editorsBreadCrumbs.
319
+ if (editorType !== 'layout-builder' && id?.length > 0) {
320
+ // Check which editor we have now
321
+ const currentEditor = this._editorsBreadCrumb[this._editorsBreadCrumb.length - 1];
322
+ // Only if it's another editor.
323
+ if (currentEditor.id !== id) {
324
+ if (currentEditor.type !== 'layout-builder') {
325
+ // Always pop the last and insert the current.
326
+ this._editorsBreadCrumb.pop();
327
+ }
328
+ const editor = this.getEditorByType(editorType, id, title);
329
+ if (editor) {
330
+ this._editorsBreadCrumb.push(editor);
331
+ this.changeCurrentEditor();
332
+ success = true;
333
+ }
334
+ else {
335
+ success = false;
336
+ }
337
+ }
338
+ }
339
+ return success;
340
+ }
341
+ navigateBackFromEditor() {
342
+ // Keep the layout builder editor.
343
+ if (this._editorsBreadCrumb.length > 1) {
344
+ // Maybe we want to compare the last editor for validation ?
345
+ const lastEditor = this._editorsBreadCrumb.pop();
346
+ this.changeCurrentEditor();
347
+ }
348
+ }
349
+ updateLayoutFromEditor(editorData) {
350
+ const layoutView = this._layoutViewSubject.getValue();
351
+ if (layoutView) {
352
+ layoutView.Layout.MaxWidth = editorData.maxWidth;
353
+ layoutView.Layout.HorizontalSpacing = editorData.horizontalSpacing;
354
+ layoutView.Layout.VerticalSpacing = editorData.verticalSpacing;
355
+ layoutView.Layout.SectionsGap = editorData.sectionsGap;
356
+ layoutView.Layout.ColumnsGap = editorData.columnsGap;
357
+ // layoutView.Layout.RoundedCorners = editorData.roundedCorners;
358
+ this.notifyLayoutViewChange(layoutView);
359
+ }
360
+ }
361
+ updateSectionFromEditor(sectionData) {
362
+ const layoutView = this._layoutViewSubject.getValue();
363
+ const sections = layoutView?.Layout.Sections || [];
364
+ const sectionIndex = sections.findIndex(section => section.Key === sectionData.id);
365
+ // Update section details.
366
+ if (sectionIndex >= 0) {
367
+ const blocksIdsToRemove = [];
368
+ const currentSection = sections[sectionIndex];
369
+ currentSection.Name = sectionData.sectionName;
370
+ currentSection.Split = sectionData.split;
371
+ currentSection.Height = sectionData.height;
372
+ currentSection.CollapseOnTablet = sectionData.collapseOnTablet;
373
+ currentSection.FillHeight = sectionData.fillHeight;
374
+ // Get the new columns number from currentSection.Split, if its undefined put a default 1.
375
+ const newColumnsLength = currentSection.Split?.split(' ').length || 1;
376
+ if (newColumnsLength > currentSection.Columns.length) {
377
+ while (newColumnsLength > currentSection.Columns.length) {
378
+ currentSection.Columns.push({});
379
+ }
380
+ }
381
+ else if (newColumnsLength < currentSection.Columns.length) {
382
+ while (newColumnsLength < currentSection.Columns.length) {
383
+ const colunm = currentSection.Columns.pop();
384
+ // If there is block in this column delete it.
385
+ if (colunm && colunm.BlockContainer) {
386
+ blocksIdsToRemove.push(colunm.BlockContainer.BlockKey);
387
+ }
388
+ }
389
+ }
390
+ // Update editor title
391
+ const currentEditor = this._editorSubject.getValue();
392
+ if (currentEditor && currentEditor.type === 'section' && currentEditor.id === currentSection.Key) {
393
+ const title = this.getSectionEditorTitle(currentSection, sectionIndex);
394
+ currentEditor.title = title;
395
+ this.notifyEditorChange(currentEditor);
396
+ }
397
+ // Update sections change.
398
+ this.notifyLayoutViewChange(layoutView);
399
+ // If there are blocks to remove, notify the blocks removed.
400
+ if (blocksIdsToRemove.length > 0) {
401
+ this.notifyBlocksRemoved(blocksIdsToRemove);
402
+ }
403
+ }
404
+ }
405
+ addSection(section = null) {
406
+ // Create new section
407
+ if (!section) {
408
+ section = {
409
+ Key: PepGuid.newGuid(),
410
+ Columns: [{}],
411
+ Hide: []
412
+ };
413
+ }
414
+ // Add the new section to layout view.
415
+ const layoutView = this._layoutViewSubject.getValue();
416
+ const sections = layoutView?.Layout.Sections || [];
417
+ sections.push(section);
418
+ this.notifyLayoutViewChange(layoutView);
419
+ }
420
+ removeSection(sectionId) {
421
+ const layoutView = this._layoutViewSubject.getValue();
422
+ const sections = layoutView?.Layout.Sections || [];
423
+ const index = sections.findIndex(section => section.Key === sectionId);
424
+ if (index > -1) {
425
+ // Get the blocks id's to remove.
426
+ const blocksIdsToRemove = sections[index].Columns.map(column => column?.BlockContainer?.BlockKey);
427
+ // Remove section.
428
+ sections.splice(index, 1);
429
+ this.notifyLayoutViewChange(layoutView);
430
+ // If there are blocks to remove, notify the blocks removed.
431
+ if (blocksIdsToRemove.length > 0) {
432
+ this.notifyBlocksRemoved(blocksIdsToRemove);
433
+ }
434
+ }
435
+ }
436
+ hideSection(sectionId, hideIn) {
437
+ const layoutView = this._layoutViewSubject.getValue();
438
+ const sections = layoutView?.Layout.Sections || [];
439
+ const index = sections.findIndex(section => section.Key === sectionId);
440
+ if (index > -1) {
441
+ sections[index].Hide = hideIn;
442
+ this.notifyLayoutViewChange(layoutView);
443
+ }
444
+ }
445
+ onSectionDropped(event) {
446
+ const layoutView = this._layoutViewSubject.getValue();
447
+ const sections = layoutView?.Layout.Sections || [];
448
+ moveItemInArray(sections, event.previousIndex, event.currentIndex);
449
+ this.notifyLayoutViewChange(layoutView);
450
+ }
451
+ onSectionDragStart(event) {
452
+ this.changeCursorOnDragStart();
453
+ this._draggingSectionKey.next(event.source.data);
454
+ }
455
+ onSectionDragEnd(event) {
456
+ this.changeCursorOnDragEnd();
457
+ this._draggingSectionKey.next('');
458
+ }
459
+ removeBlockFromSection(blockId) {
460
+ let blockRemoved = false;
461
+ // Remove the block from section column.
462
+ const layoutView = this._layoutViewSubject.getValue();
463
+ const sections = layoutView?.Layout.Sections || [];
464
+ for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
465
+ const section = sections[sectionIndex];
466
+ // Remove the block container.
467
+ const columnIndex = section.Columns.findIndex(column => column.BlockContainer?.BlockKey === blockId);
468
+ if (columnIndex > -1) {
469
+ delete section.Columns[columnIndex].BlockContainer;
470
+ this.notifyLayoutViewChange(layoutView);
471
+ blockRemoved = true;
472
+ break;
473
+ }
474
+ }
475
+ // If the block was removed, notify the block removed.
476
+ if (blockRemoved) {
477
+ this.notifyBlocksRemoved([blockId]);
478
+ }
479
+ }
480
+ hideBlock(sectionId, blockId, hideIn) {
481
+ const layoutView = this._layoutViewSubject.getValue();
482
+ const sections = layoutView?.Layout.Sections || [];
483
+ const index = sections.findIndex(section => section.Key === sectionId);
484
+ if (index > -1) {
485
+ const columnIndex = sections[index].Columns.findIndex(column => column.BlockContainer?.BlockKey === blockId);
486
+ if (columnIndex > -1) {
487
+ const blockContainer = sections[index].Columns[columnIndex].BlockContainer;
488
+ if (blockContainer) {
489
+ blockContainer.Hide = hideIn;
490
+ this.notifyLayoutViewChange(layoutView);
491
+ }
492
+ }
493
+ }
494
+ }
495
+ onBlockDropped(event, sectionId) {
496
+ const layoutView = this._layoutViewSubject.getValue();
497
+ if (event.previousContainer.id === LayoutBuilderInternalService.AVAILABLE_BLOCKS_CONTAINER_ID) {
498
+ // Validate if blocks number allow.
499
+ if (this._blocksLimitNumber > 0 && this.getBlocksNumber() >= this._blocksLimitNumber) {
500
+ const data = new PepDialogData({
501
+ title: this.translate.instant('MESSAGES.DIALOG_NOTICE_TITLE'),
502
+ content: this.translate.instant('LAYOUT_BUILDER.BLOCKS_COUNT_LIMIT_MESSAGE'),
503
+ });
504
+ this.dialogService.openDefaultDialog(data);
505
+ }
506
+ else {
507
+ // Get the block relation (previousContainer.data is IPepDraggableItem and inside we have AvailableBlock object).
508
+ const draggableItem = event.previousContainer.data[event.previousIndex];
509
+ if (draggableItem) {
510
+ // lock the screen untill the editor will be loaded.
511
+ // this._lockScreenSubject.next(true);
512
+ // Get the column.
513
+ const currentColumn = this.getSectionColumnByIdForEditor(event.container.id);
514
+ // Set the block key in the section block only if there is a blank column.
515
+ if (currentColumn && !currentColumn.BlockContainer) {
516
+ // Generate the block uuid.
517
+ const blockKey = PepGuid.newGuid();
518
+ currentColumn.BlockContainer = {
519
+ BlockKey: blockKey,
520
+ };
521
+ // Here we update the layout view cause the layout is updated.
522
+ this.notifyLayoutViewChange(layoutView);
523
+ // Raise block added event.
524
+ const blockAddedEventData = {
525
+ BlockKey: blockKey,
526
+ DraggableItem: draggableItem,
527
+ };
528
+ this.notifyBlockAdded(blockAddedEventData);
529
+ if (this._navigateToEditorAfterBlockAdded) {
530
+ // Navigate to the block editor.
531
+ this.navigateToEditor('block', blockKey);
532
+ }
533
+ }
534
+ }
535
+ else {
536
+ console.log("draggableItem is not a IPepDraggableItem type");
537
+ }
538
+ }
539
+ }
540
+ else {
541
+ // If the block moved between columns in the same section or between different sections but not in the same column.
542
+ if (event.container.id !== event.previousContainer.id) {
543
+ // Get the column.
544
+ const currentColumn = this.getSectionColumnByIdForEditor(event.container.id);
545
+ // Get the previous column.
546
+ const previuosColumn = this.getSectionColumnByIdForEditor(event.previousContainer.id);
547
+ if (currentColumn && previuosColumn) {
548
+ currentColumn.BlockContainer = previuosColumn.BlockContainer;
549
+ delete previuosColumn.BlockContainer;
550
+ this.notifyLayoutViewChange(layoutView);
551
+ }
552
+ }
553
+ }
554
+ }
555
+ onBlockDragStart(event) {
556
+ this.changeCursorOnDragStart();
557
+ // Take the block key if exist, else take the available block key (relation key).
558
+ const blockKey = event.source.data?.BlockKey || event.source.data?.Key;
559
+ this._draggingBlockKey.next(blockKey);
560
+ }
561
+ onBlockDragEnd(event) {
562
+ this.changeCursorOnDragEnd();
563
+ this._draggingBlockKey.next('');
564
+ }
565
+ doesColumnContainBlock(sectionId, columnIndex) {
566
+ let res = false;
567
+ const layoutView = this._layoutViewSubject.getValue();
568
+ const section = layoutView?.Layout.Sections.find(section => section.Key === sectionId);
569
+ if (section && columnIndex >= 0 && section.Columns.length > columnIndex) {
570
+ res = !!section.Columns[columnIndex].BlockContainer;
571
+ }
572
+ return res;
573
+ }
574
+ setScreenWidth(screenType) {
575
+ const value = this.getCssScreenWidh(screenType);
576
+ const width = coerceNumberProperty(value, 0);
577
+ if (width === 0) {
578
+ this._screenWidthSubject.next('100%');
579
+ this.notifyScreenSizeChange(PepScreenSizeType.XL);
580
+ }
581
+ else {
582
+ this._screenWidthSubject.next(`${width}px`);
583
+ // Change the size according the width.
584
+ if (width >= 1920) {
585
+ this.notifyScreenSizeChange(PepScreenSizeType.XL);
586
+ }
587
+ else if (width >= 1280 && width < 1920) {
588
+ this.notifyScreenSizeChange(PepScreenSizeType.LG);
589
+ }
590
+ else if (width >= 960 && width < 1280) {
591
+ this.notifyScreenSizeChange(PepScreenSizeType.MD);
592
+ }
593
+ else if (width >= 600 && width < 960) {
594
+ this.notifyScreenSizeChange(PepScreenSizeType.SM);
595
+ }
596
+ else if (width < 600) {
597
+ this.notifyScreenSizeChange(PepScreenSizeType.XS);
598
+ }
599
+ }
600
+ }
601
+ showSkeleton(show) {
602
+ this._showSkeletonSubject.next(show);
603
+ }
604
+ lockScreen(value) {
605
+ this.notifyLockScreen(value);
606
+ }
607
+ loadLayoutBuilder(layoutView) {
608
+ if (this.editMode) {
609
+ if (this._editorsBreadCrumb.length === 0) {
610
+ // Load the layout editor.
611
+ this.loadDefaultEditor(layoutView);
612
+ }
613
+ }
614
+ // Load only the layout view.
615
+ this.notifyLayoutViewChange(layoutView);
616
+ }
617
+ }
618
+ LayoutBuilderInternalService.AVAILABLE_BLOCKS_CONTAINER_ID = 'availableBlocks';
619
+ LayoutBuilderInternalService.MAIN_EDITOR_ID = 'main';
620
+ LayoutBuilderInternalService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService, deps: [{ token: i1.TranslateService }, { token: i2.PepDialogService }, { token: i3.PepLayoutService }], target: i0.ɵɵFactoryTarget.Injectable });
621
+ LayoutBuilderInternalService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService, providedIn: 'root' });
622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService, decorators: [{
623
+ type: Injectable,
624
+ args: [{
625
+ providedIn: 'root',
626
+ }]
627
+ }], ctorParameters: function () { return [{ type: i1.TranslateService }, { type: i2.PepDialogService }, { type: i3.PepLayoutService }]; } });
628
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LWJ1aWxkZXItaW50ZXJuYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jb21wb3NpdGUtbGliL2xheW91dC1idWlsZGVyL2xheW91dC1idWlsZGVyLWludGVybmFsLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBQXdELGVBQWUsRUFBcUIsTUFBTSx3QkFBd0IsQ0FBQztBQUVsSSxPQUFPLEVBQW1CLE9BQU8sRUFBb0MsaUJBQWlCLEVBQTBDLE1BQU0seUJBQXlCLENBQUM7QUFHaEssT0FBTyxFQUFjLGVBQWUsRUFBVyxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQWdCLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxhQUFhLEVBQW9CLE1BQU0sZ0NBQWdDLENBQUM7Ozs7O0FBd0JqRixNQUFNLE9BQU8sNEJBQTRCO0lBOEdyQyxZQUNjLFNBQTJCLEVBQzNCLGFBQStCLEVBQ2pDLGFBQStCO1FBRjdCLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQzNCLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtRQUNqQyxrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUE3R25DLHlCQUFvQixHQUFHLEVBQUUsQ0FBQztRQUVsQyw2Q0FBNkM7UUFDckMsdUJBQWtCLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLHFDQUFnQyxHQUFHLEtBQUssQ0FBQztRQUN6QyxtQkFBYyxHQUFpQyxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsT0FBTyxRQUFRLENBQUEsQ0FBQyxDQUFDLENBQUM7UUFPakYsdUJBQWtCLEdBQUcsS0FBSyxFQUFXLENBQUM7UUFFdEMsY0FBUyxHQUFH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QkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IGNvZXJjZU51bWJlclByb3BlcnR5IH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9jb2VyY2lvblwiO1xuaW1wb3J0IHsgQ2RrRHJhZ0Ryb3AsIENka0RyYWdFbmQsIENka0RyYWdTdGFydCwgY29weUFycmF5SXRlbSwgbW92ZUl0ZW1JbkFycmF5LCB0cmFuc2ZlckFycmF5SXRlbSB9IGZyb20gXCJAYW5ndWxhci9jZGsvZHJhZy1kcm9wXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSBcIkBuZ3gtdHJhbnNsYXRlL2NvcmVcIjtcbmltcG9ydCB7IFBlcEFkZG9uU2VydmljZSwgUGVwR3VpZCwgUGVwSHR0cFNlcnZpY2UsIFBlcExheW91dFNlcnZpY2UsIFBlcFNjcmVlblNpemVUeXBlLCBQZXBTZXNzaW9uU2VydmljZSwgUGVwVXRpbGl0aWVzU2VydmljZSB9IGZyb20gXCJAcGVwcGVyaS1hZGRvbnMvbmd4LWxpYlwiO1xuaW1wb3J0IHsgSVBlcERyYWdnYWJsZUl0ZW0gfSBmcm9tIFwiQHBlcHBlcmktYWRkb25zL25neC1saWIvZHJhZ2dhYmxlLWl0ZW1zXCI7XG5pbXBvcnQgeyBEYXRhVmlld1NjcmVlblNpemUsIFNwbGl0VHlwZSB9IGZyb20gXCJAcGVwcGVyaS1hZGRvbnMvcGFwaS1zZGtcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgUGVwTGF5b3V0RWRpdG9yVHlwZSwgSVBlcExheW91dEJsb2NrQWRkZWRFdmVudCwgSVBlcExheW91dFNlY3Rpb24sIElQZXBMYXlvdXRTZWN0aW9uQ29sdW1uLCBJUGVwTGF5b3V0VmlldywgSVBlcExheW91dEJsb2NrQ29uZmlnLCBQZXBMYXlvdXRTaXplVHlwZSwgSUVkaXRvciB9IGZyb20gXCIuL2xheW91dC1idWlsZGVyLm1vZGVsXCI7XG5pbXBvcnQgeyBQZXBEaWFsb2dEYXRhLCBQZXBEaWFsb2dTZXJ2aWNlIH0gZnJvbSBcIkBwZXBwZXJpLWFkZG9ucy9uZ3gtbGliL2RpYWxvZ1wiO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgSUxheW91dEVkaXRvciB7XG4gICAgbWF4V2lkdGg6IG51bWJlcixcbiAgICBob3Jpem9udGFsU3BhY2luZz86IFBlcExheW91dFNpemVUeXBlLFxuICAgIHZlcnRpY2FsU3BhY2luZz86IFBlcExheW91dFNpemVUeXBlLFxuICAgIHNlY3Rpb25zR2FwPzogUGVwTGF5b3V0U2l6ZVR5cGUsXG4gICAgY29sdW1uc0dhcD86IFBlcExheW91dFNpemVUeXBlLFxuICAgIHJvdW5kZWRDb3JuZXJzPzogUGVwTGF5b3V0U2l6ZVR5cGUsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUxheW91dFNlY3Rpb25FZGl0b3Ige1xuICAgIGlkOiBzdHJpbmcsXG4gICAgc2VjdGlvbk5hbWU6IHN0cmluZyxcbiAgICBzcGxpdDogU3BsaXRUeXBlIHwgdW5kZWZpbmVkLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGNvbGxhcHNlT25UYWJsZXQ6IGJvb2xlYW4sXG4gICAgZmlsbEhlaWdodDogYm9vbGVhblxufVxuXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBMYXlvdXRCdWlsZGVySW50ZXJuYWxTZXJ2aWNlIHtcbiAgICBzdGF0aWMgcmVhZG9ubHkgQVZBSUxBQkxFX0JMT0NLU19DT05UQUlORVJfSUQgPSAnYXZhaWxhYmxlQmxvY2tzJztcbiAgICBzdGF0aWMgcmVhZG9ubHkgTUFJTl9FRElUT1JfSUQgPSAnbWFpbic7XG5cbiAgICBwcml2YXRlIF9kZWZhdWx0U2VjdGlvblRpdGxlID0gJyc7XG4gICAgXG4gICAgLy8gVGhpcyBjb25maWd1cmF0aW9uIGlzIGZvciBibG9ja3MgYmVoYXZpb3IuXG4gICAgcHJpdmF0ZSBfYmxvY2tzTGltaXROdW1iZXIgPSAwO1xuICAgIHByaXZhdGUgX25hdmlnYXRlVG9FZGl0b3JBZnRlckJsb2NrQWRkZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF9nZXRCbG9ja1RpdGxlOiAoYmxvY2tLZXk6IHN0cmluZykgPT4gc3RyaW5nID0gKGJsb2NrS2V5KSA9PiB7IHJldHVybiBibG9ja0tleSB9O1xuICAgIHNldEJsb2Nrc0NvbmZpZyh2YWx1ZTogSVBlcExheW91dEJsb2NrQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuX2Jsb2Nrc0xpbWl0TnVtYmVyID0gdmFsdWUuYmxvY2tzTGltaXROdW1iZXIgfHwgMDtcbiAgICAgICAgdGhpcy5fbmF2aWdhdGVUb0VkaXRvckFmdGVyQmxvY2tBZGRlZCA9IHZhbHVlLm5hdmlnYXRlVG9FZGl0b3JBZnRlckJsb2NrQWRkZWQgPz8gZmFsc2U7XG4gICAgICAgIHRoaXMuX2dldEJsb2NrVGl0bGUgPSB2YWx1ZS5nZXRCbG9ja1RpdGxlID8gdmFsdWUuZ2V0QmxvY2tUaXRsZSA6IChibG9ja0tleSkgPT4geyByZXR1cm4gYmxvY2tLZXkgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9lZGl0b3JzQnJlYWRDcnVtYiA9IEFycmF5PElFZGl0b3I+KCk7XG5cbiAgICBwcml2YXRlIF9lZGl0TW9kZSA9IGZhbHNlO1xuICAgIGdldCBlZGl0TW9kZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VkaXRNb2RlO1xuICAgIH1cbiAgICBzZXRFZGl0TW9kZSh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9lZGl0TW9kZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnNldEVkaXRhYmxlU3RhdGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9lZGl0YWJsZVN0YXRlID0gZmFsc2U7XG4gICAgZ2V0IGVkaXRhYmxlU3RhdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lZGl0YWJsZVN0YXRlO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgdGhlIHNjcmVlbiBzaXplIGNoYW5nZSBldmVudHMuXG4gICAgcHJpdmF0ZSBfc2NyZWVuU2l6ZVN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxQZXBTY3JlZW5TaXplVHlwZSB8IHVuZGVmaW5lZD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFBlcFNjcmVlblNpemVUeXBlIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICAgIGdldCBzY3JlZW5TaXplQ2hhbmdlJCgpOiBPYnNlcnZhYmxlPFBlcFNjcmVlblNpemVUeXBlIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY3JlZW5TaXplU3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cbiAgICBcbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIGRlbW9zdHJhdGUgdGhlIGNvbnRhaW5lciBzaXplIChVc2FnZSBvbmx5IGluIGVkaXQgbW9kZSkuXG4gICAgcHJpdmF0ZSBfc2NyZWVuV2lkdGhTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignMTAwJScpO1xuICAgIGdldCBzY3JlZW5XaWR0aENoYW5nZSQoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NjcmVlbldpZHRoU3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgbG9hZCB0aGUgY3VycmVudCBlZGl0b3IgKFVzYWdlIG9ubHkgaW4gZWRpdCBtb2RlKS5cbiAgICBwcml2YXRlIF9lZGl0b3JTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8SUVkaXRvciB8IG51bGw+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJRWRpdG9yIHwgbnVsbD4obnVsbCk7XG4gICAgZ2V0IGVkaXRvckNoYW5nZSQoKTogT2JzZXJ2YWJsZTxJRWRpdG9yIHwgbnVsbD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZWRpdG9yU3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgaXMgdGhlIHNlY3Rpb25zIGNvbHVtbnMgZHJvcCBsaXN0IHN1YmplY3QuXG4gICAgcHJpdmF0ZSBfc2VjdGlvbnNDb2x1bW5zRHJvcExpc3RTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8YW55W10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnlbXT4oW10pO1xuICAgIGdldCBzZWN0aW9uc0NvbHVtbnNEcm9wTGlzdENoYW5nZSQoKTogT2JzZXJ2YWJsZTxhbnlbXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VjdGlvbnNDb2x1bW5zRHJvcExpc3RTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgaXMgdGhlIHNlY3Rpb25zIHN1YmplY3QgKGEgcGFyZSBmcm9tIHRoZSBsYXlvdXQgdmlldyBvYmplY3QpXG4gICAgcHJpdmF0ZSBfc2VjdGlvbnNWaWV3U3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PElQZXBMYXlvdXRTZWN0aW9uW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJUGVwTGF5b3V0U2VjdGlvbltdPihbXSk7XG4gICAgZ2V0IHNlY3Rpb25zQ2hhbmdlJCgpOiBPYnNlcnZhYmxlPElQZXBMYXlvdXRTZWN0aW9uW10+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlY3Rpb25zVmlld1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgICAgIC8vIChwcmV2U2VjdGlvbnMsIG5leHRTZWN0aW9ucykgPT4gSlNPTi5zdHJpbmdpZnkocHJldlNlY3Rpb25zKSA9PT0gSlNPTi5zdHJpbmdpZnkobmV4dFNlY3Rpb25zKSkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgbGF5b3V0IHZpZXcgY2hhbmdlLlxuICAgIHByaXZhdGUgX2xheW91dFZpZXdTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8SVBlcExheW91dFZpZXcgfCBudWxsPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVBlcExheW91dFZpZXcgfCBudWxsPihudWxsKTtcbiAgICBnZXQgbGF5b3V0Vmlld0NoYW5nZSQoKTogT2JzZXJ2YWJsZTxJUGVwTGF5b3V0VmlldyB8IG51bGw+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpLnBpcGUoZmlsdGVyKGxheW91dCA9PiAhIWxheW91dCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgZWRpdCBtb2RlIHdoZW4gYmxvY2sgaXMgZHJhZ2dpbmcgbm93IG9yIG5vdC5cbiAgICBwcml2YXRlIF9kcmFnZ2luZ0Jsb2NrS2V5OiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPiA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpO1xuICAgIGdldCBkcmFnZ2luZ0Jsb2NrS2V5KCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmFnZ2luZ0Jsb2NrS2V5LmFzT2JzZXJ2YWJsZSgpLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBzdWJqZWN0IGlzIGZvciBlZGl0IG1vZGUgd2hlbiBzZWN0aW9uIGlzIGRyYWdnaW5nIG5vdyBvciBub3QuXG4gICAgcHJpdmF0ZSBfZHJhZ2dpbmdTZWN0aW9uS2V5OiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPiA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpO1xuICAgIGdldCBkcmFnZ2luZ1NlY3Rpb25LZXkoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyYWdnaW5nU2VjdGlvbktleS5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgbG9jayBvciB1bmxvY2sgdGhlIHNjcmVlbiAoVXNhZ2Ugb25seSBpbiBlZGl0IG1vZGUpLlxuICAgIHByaXZhdGUgX2xvY2tTY3JlZW5TdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgICBnZXQgbG9ja1NjcmVlbkNoYW5nZSQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2NrU2NyZWVuU3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgaXMgZm9yIGNvbnRyb2wgdGhlIHByZXZpZXcgbW9kZSAoZm9yIGxvYWQgdGhlIGJsb2NrcyB3aXRoIHRoZSBDUEkgZXZlbnRzKSBcbiAgICBwcml2YXRlIF9wcmV2aWV3TW9kZVN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICAgIGdldCBwcmV2aWV3TW9kZUNoYW5nZSQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmV2aWV3TW9kZVN1YmplY3QuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGZvciBlZGl0b3IgbW9kZSBmb3IgYmxvY2sgYWRkZWQuXG4gICAgcHJpdmF0ZSBfYmxvY2tBZGRlZEV2ZW50U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVBlcExheW91dEJsb2NrQWRkZWRFdmVudCB8IG51bGw+KG51bGwpO1xuICAgIGdldCBibG9ja0FkZGVkRXZlbnRTdWJqZWN0JCgpOiBPYnNlcnZhYmxlPElQZXBMYXlvdXRCbG9ja0FkZGVkRXZlbnQgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ibG9ja0FkZGVkRXZlbnRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cbiAgICAvLyBUaGlzIGlzIGZvciBlZGl0b3IgbW9kZSBmb3IgYmxvY2tzIHJlbW92ZWQuXG4gICAgcHJpdmF0ZSBfYmxvY2tzUmVtb3ZlZEV2ZW50U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nW10+KFtdKTtcbiAgICBnZXQgYmxvY2tzUmVtb3ZlZEV2ZW50U3ViamVjdCQoKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmxvY2tzUmVtb3ZlZEV2ZW50U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIHNrZWxldG9uLlxuICAgIHByaXZhdGUgX3Nob3dTa2VsZXRvblN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4odHJ1ZSk7XG4gICAgZ2V0IHNob3dTa2VsZXRvbkNoYW5nZSQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaG93U2tlbGV0b25TdWJqZWN0LmFzT2JzZXJ2YWJsZSgpLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgZGlhbG9nU2VydmljZTogUGVwRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBsYXlvdXRTZXJ2aWNlOiBQZXBMYXlvdXRTZXJ2aWNlLFxuICAgICkge1xuICAgICAgICAvL1xuICAgICAgICB0aGlzLnRyYW5zbGF0ZS5nZXQoJ0xBWU9VVF9CVUlMREVSLlNFQ1RJT04nKS5zdWJzY3JpYmUoKHJlczogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAvLyBTZXQgdGhlIGRlZmF1bHQgc2VjdGlvbiBuYW1lLlxuICAgICAgICAgICAgdGhpcy5fZGVmYXVsdFNlY3Rpb25UaXRsZSA9IHJlcztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5sYXlvdXRTZXJ2aWNlLm9uUmVzaXplJC5zdWJzY3JpYmUoKHNpemU6IFBlcFNjcmVlblNpemVUeXBlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeVNjcmVlblNpemVDaGFuZ2Uoc2l6ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICBwcml2YXRlIHNldEVkaXRhYmxlU3RhdGUoKSB7XG4gICAgICAgIHRoaXMuX2VkaXRhYmxlU3RhdGUgPSB0aGlzLmVkaXRNb2RlICYmICF0aGlzLl9wcmV2aWV3TW9kZVN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlld1RvVXBkYXRlOiBJUGVwTGF5b3V0VmlldyB8IG51bGwpIHtcbiAgICAgICAgaWYgKGxheW91dFZpZXdUb1VwZGF0ZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZWRpdE1vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxheW91dEVkaXRvclByb3BlcnRpZXMobGF5b3V0Vmlld1RvVXBkYXRlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBsYXlvdXQgZm9yIHRoZSB2aWV3LlxuICAgICAgICAgICAgdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QubmV4dChsYXlvdXRWaWV3VG9VcGRhdGUpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNlY3Rpb25zIGZvciB0aGUgdmlldy5cbiAgICAgICAgICAgIHRoaXMuX3NlY3Rpb25zVmlld1N1YmplY3QubmV4dChsYXlvdXRWaWV3VG9VcGRhdGU/LkxheW91dC5TZWN0aW9ucyB8fCBbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUJsb2NrQWRkZWQoYmxvY2tBZGRlZEV2ZW50RGF0YTogSVBlcExheW91dEJsb2NrQWRkZWRFdmVudCkge1xuICAgICAgICAvLyBOb3RpZnkgdGhhdCB0aGUgYmxvY2sgaXMgYWRkZWQgKHRvIHJhaXNlIHRoZSBldmVudCBmb3IgdGhlIGNsaWVudCkuXG4gICAgICAgIHRoaXMuX2Jsb2NrQWRkZWRFdmVudFN1YmplY3QubmV4dChibG9ja0FkZGVkRXZlbnREYXRhKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUJsb2Nrc1JlbW92ZWQoa2V5czogc3RyaW5nW10gfCB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGtleXMpIHtcbiAgICAgICAgICAgIC8vIE5vdGlmeSB0aGF0IHRoZSBibG9ja3MgYXJlIHJlbW92ZWQgKHRvIHJhaXNlIHRoZSBldmVudCBmb3IgdGhlIGNsaWVudCkuXG4gICAgICAgICAgICB0aGlzLl9ibG9ja3NSZW1vdmVkRXZlbnRTdWJqZWN0Lm5leHQoa2V5cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUVkaXRvckNoYW5nZShlZGl0b3I6IElFZGl0b3IgfCBudWxsKSB7XG4gICAgICAgIHRoaXMuX2VkaXRvclN1YmplY3QubmV4dChlZGl0b3IpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5UHJldmlld01vZGVDaGFuZ2UodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fcHJldmlld01vZGVTdWJqZWN0Lm5leHQodmFsdWUpO1xuICAgICAgICB0aGlzLnNldEVkaXRhYmxlU3RhdGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUxvY2tTY3JlZW4odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fbG9ja1NjcmVlblN1YmplY3QubmV4dCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBub3RpZnlTZWN0aW9uc0NvbHVtbnNEcm9wTGlzdENoYW5nZShzZWN0aW9uc0NvbHVtbnNEcm9wTGlzdDogYW55W10pIHtcbiAgICAgICAgdGhpcy5fc2VjdGlvbnNDb2x1bW5zRHJvcExpc3RTdWJqZWN0Lm5leHQoc2VjdGlvbnNDb2x1bW5zRHJvcExpc3QpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5U2NyZWVuU2l6ZUNoYW5nZShzaXplOiBQZXBTY3JlZW5TaXplVHlwZSkge1xuICAgICAgICB0aGlzLl9zY3JlZW5TaXplU3ViamVjdC5uZXh0KHNpemUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlTGF5b3V0RWRpdG9yUHJvcGVydGllcyhsYXlvdXRWaWV3OiBJUGVwTGF5b3V0Vmlldykge1xuICAgICAgICBpZiAodGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWJbMF0pIHtcbiAgICAgICAgICAgIGNvbnN0IGxheW91dEVkaXRvcjogSUxheW91dEVkaXRvciA9IHtcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogbGF5b3V0Vmlldz8uTGF5b3V0Lk1heFdpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgdmVydGljYWxTcGFjaW5nOiBsYXlvdXRWaWV3Py5MYXlvdXQuVmVydGljYWxTcGFjaW5nLFxuICAgICAgICAgICAgICAgIGhvcml6b250YWxTcGFjaW5nOiBsYXlvdXRWaWV3Py5MYXlvdXQuSG9yaXpvbnRhbFNwYWNpbmcsXG4gICAgICAgICAgICAgICAgc2VjdGlvbnNHYXA6IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9uc0dhcCxcbiAgICAgICAgICAgICAgICBjb2x1bW5zR2FwOiBsYXlvdXRWaWV3Py5MYXlvdXQuQ29sdW1uc0dhcCxcbiAgICAgICAgICAgICAgICAvLyByb3VuZGVkQ29ybmVyczogbGF5b3V0Vmlldz8uTGF5b3V0LlJvdW5kZWRDb3JuZXJzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYlswXS5ob3N0T2JqZWN0ID0gbGF5b3V0RWRpdG9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkRGVmYXVsdEVkaXRvcihsYXlvdXRWaWV3OiBJUGVwTGF5b3V0Vmlldykge1xuICAgICAgICB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYiA9IG5ldyBBcnJheTxJRWRpdG9yPigpO1xuXG4gICAgICAgIGlmIChsYXlvdXRWaWV3KSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZS5nZXQoJ0xBWU9VVF9CVUlMREVSLkRFRkFVTFRfVElUTEUnKS5zdWJzY3JpYmUoKHRpdGxlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IExheW91dEJ1aWxkZXJJbnRlcm5hbFNlcnZpY2UuTUFJTl9FRElUT1JfSUQsXG4gICAgICAgICAgICAgICAgICAgIHR5cGUgOiAnbGF5b3V0LWJ1aWxkZXInLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICAgICAgICAgIC8vIGhvc3RPYmplY3Q6IHt9IC8vIFVwZGF0ZXMgaW4gdXBkYXRlTGF5b3V0RWRpdG9yUHJvcGVydGllcyBmdW5jdGlvbiBhYm92ZS5cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTGF5b3V0RWRpdG9yUHJvcGVydGllcyhsYXlvdXRWaWV3KTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUVkaXRvckNoYW5nZSh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYlswXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5RWRpdG9yQ2hhbmdlKG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGFuZ2VDdXJyZW50RWRpdG9yKCkge1xuICAgICAgICBpZiAodGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlFZGl0b3JDaGFuZ2UodGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWJbdGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIubGVuZ3RoIC0gMV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFZGl0b3JCeVR5cGUoZWRpdG9yVHlwZTogUGVwTGF5b3V0RWRpdG9yVHlwZSwgaWQ6IHN0cmluZywgdGl0bGUgPSAnJyk6IElFZGl0b3IgfCBudWxsIHtcbiAgICAgICAgLy8gQnVpbGQgZWRpdG9yIG9iamVjdC5cbiAgICAgICAgbGV0IGVkaXRvcjogSUVkaXRvciB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgIGlmIChlZGl0b3JUeXBlID09PSAnc2VjdGlvbicpIHtcbiAgICAgICAgICAgIGVkaXRvciA9IHRoaXMuZ2V0U2VjdGlvbkVkaXRvcihpZCwgdGl0bGUpO1xuICAgICAgICB9IGVsc2UgaWYgKGVkaXRvclR5cGUgPT09ICdibG9jaycpIHtcbiAgICAgICAgICAgIGVkaXRvciA9IHRoaXMuZ2V0QmxvY2tFZGl0b3IoaWQsIHRpdGxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlZGl0b3I7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRCbG9ja0VkaXRvcihibG9ja0tleTogc3RyaW5nLCB0aXRsZTogc3RyaW5nKTogSUVkaXRvciB7XG4gICAgICAgIC8vIEdldCBibG9jayBlZGl0b3IgdGl0bGUuXG4gICAgICAgIGNvbnN0IGJsb2NrVGl0bGUgPSB0aXRsZSB8fCB0aGlzLmdldEJsb2NrVGl0bGUoYmxvY2tLZXkpOyBcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6IGJsb2NrS2V5LFxuICAgICAgICAgICAgdHlwZTogJ2Jsb2NrJyxcbiAgICAgICAgICAgIHRpdGxlOiBibG9ja1RpdGxlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNlY3Rpb25FZGl0b3JUaXRsZShzZWN0aW9uOiBJUGVwTGF5b3V0U2VjdGlvbiwgc2VjdGlvbkluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gc2VjdGlvbi5OYW1lIHx8IGAke3RoaXMuX2RlZmF1bHRTZWN0aW9uVGl0bGV9ICR7c2VjdGlvbkluZGV4ICsgMX1gO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U2VjdGlvbkVkaXRvcihzZWN0aW9uSWQ6IHN0cmluZywgdGl0bGU6IHN0cmluZyk6IElFZGl0b3IgfCBudWxsIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBjb25zdCBzZWN0aW9uSW5kZXggPSBzZWN0aW9ucy5maW5kSW5kZXgoc2VjdGlvbiA9PiBzZWN0aW9uLktleSA9PT0gc2VjdGlvbklkKTtcblxuICAgICAgICBpZiAoc2VjdGlvbkluZGV4ID49IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHNlY3Rpb24gPSBzZWN0aW9uc1tzZWN0aW9uSW5kZXhdO1xuICAgICAgICAgICAgY29uc3Qgc2VjdGlvbkVkaXRvcjogSUxheW91dFNlY3Rpb25FZGl0b3IgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IHNlY3Rpb24uS2V5LFxuICAgICAgICAgICAgICAgIHNlY3Rpb25OYW1lOiBzZWN0aW9uLk5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgc3BsaXQ6IHNlY3Rpb24uU3BsaXQgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGhlaWdodDogc2VjdGlvbi5IZWlnaHQgfHwgMCxcbiAgICAgICAgICAgICAgICBjb2xsYXBzZU9uVGFibGV0OiBzZWN0aW9uLkNvbGxhcHNlT25UYWJsZXQgPz8gZmFsc2UsXG4gICAgICAgICAgICAgICAgZmlsbEhlaWdodDogc2VjdGlvbi5GaWxsSGVpZ2h0ID8/IGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaWQ6IHNlY3Rpb25JZCxcbiAgICAgICAgICAgICAgICB0eXBlOiAnc2VjdGlvbicsXG4gICAgICAgICAgICAgICAgdGl0bGU6IHRpdGxlIHx8IHRoaXMuZ2V0U2VjdGlvbkVkaXRvclRpdGxlKHNlY3Rpb24sIHNlY3Rpb25JbmRleCksXG4gICAgICAgICAgICAgICAgaG9zdE9iamVjdDogc2VjdGlvbkVkaXRvclxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNlY3Rpb25Db2x1bW5CeUlkRm9yRWRpdG9yKHNlY3Rpb25Db2x1bW5JZDogc3RyaW5nKTogSVBlcExheW91dFNlY3Rpb25Db2x1bW4gfCBudWxsIHtcbiAgICAgICAgbGV0IGN1cnJlbnRDb2x1bW4gPSBudWxsO1xuXG4gICAgICAgIC8vIEdldCB0aGUgc2VjdGlvbiBhbmQgY29sdW1uIGFycmF5IGJ5IHRoZSBwYXR0ZXJuIG9mIHRoZSBzZWN0aW9uIGNvbHVtbiBrZXkuXG4gICAgICAgIGNvbnN0IHNlY3Rpb25Db2x1bW5QYXR0ZXJuU2VwYXJhdG9yID0gdGhpcy5nZXRTZWN0aW9uQ29sdW1uS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25Db2x1bW5BcnIgPSBzZWN0aW9uQ29sdW1uSWQuc3BsaXQoc2VjdGlvbkNvbHVtblBhdHRlcm5TZXBhcmF0b3IpO1xuXG4gICAgICAgIGlmIChzZWN0aW9uQ29sdW1uQXJyLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gR2V0IHRoZSBzZWN0aW9uIGlkIHRvIGdldCB0aGUgc2VjdGlvbiBpbmRleC5cbiAgICAgICAgICAgIGNvbnN0IHNlY3Rpb25JZCA9IHNlY3Rpb25Db2x1bW5BcnJbMF07XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uSW5kZXggPSBzZWN0aW9ucy5maW5kSW5kZXgoc2VjdGlvbiA9PiBzZWN0aW9uLktleSA9PT0gc2VjdGlvbklkKTtcbiAgICAgICAgICAgIC8vIEdldCB0aGUgY29sdW1uIGluZGV4LlxuICAgICAgICAgICAgY29uc3QgY29sdW1uSW5kZXggPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eShzZWN0aW9uQ29sdW1uQXJyWzFdLCAtMSk7XG4gICAgICAgICAgICBpZiAoc2VjdGlvbkluZGV4ID49IDAgJiYgY29sdW1uSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRDb2x1bW4gPSBzZWN0aW9uc1tzZWN0aW9uSW5kZXhdLkNvbHVtbnNbY29sdW1uSW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGN1cnJlbnRDb2x1bW47XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDc3NTY3JlZW5XaWRoKHNjcmVlblR5cGU6IERhdGFWaWV3U2NyZWVuU2l6ZSk6IHN0cmluZyB7XG4gICAgICAgIGxldCB3aWR0aFRvU2V0ID0gJzEwMCUnO1xuXG4gICAgICAgIGlmIChzY3JlZW5UeXBlID09PSAnVGFibGV0Jykge1xuICAgICAgICAgICAgd2lkdGhUb1NldCA9ICc3MjAnO1xuICAgICAgICB9IGVsc2UgaWYgKHNjcmVlblR5cGUgPT09ICdQaGFibGV0Jykge1xuICAgICAgICAgICAgd2lkdGhUb1NldCA9ICczNjAnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHdpZHRoVG9TZXQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRCbG9ja3NOdW1iZXIoKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGJsb2Nrc051bWJlciA9IDA7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKT8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzZWN0aW9ucy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlY3Rpb24gPSBzZWN0aW9uc1tpbmRleF07XG4gICAgICAgIFxuICAgICAgICAgICAgZm9yIChsZXQgY29sdW1uSW5kZXggPSAwOyBjb2x1bW5JbmRleCA8IHNlY3Rpb24uQ29sdW1ucy5sZW5ndGg7IGNvbHVtbkluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW4gPSBzZWN0aW9uLkNvbHVtbnNbY29sdW1uSW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmIChjb2x1bW4uQmxvY2tDb250YWluZXIgJiYgY29sdW1uLkJsb2NrQ29udGFpbmVyLkJsb2NrS2V5Py5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGJsb2Nrc051bWJlcisrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBibG9ja3NOdW1iZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGFuZ2VDdXJzb3JPbkRyYWdTdGFydCgpIHtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdpbmhlcml0Q3Vyc29ycycpO1xuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGFuZ2VDdXJzb3JPbkRyYWdFbmQoKSB7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnaW5oZXJpdEN1cnNvcnMnKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAndW5zZXQnO1xuICAgIH1cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbiAgICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQdWJsaWMgZnVuY3Rpb25zXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZ2V0QmxvY2tUaXRsZShibG9ja0tleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEJsb2NrVGl0bGUoYmxvY2tLZXkpIHx8IGJsb2NrS2V5O1xuICAgIH1cblxuICAgIHNldFNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0Q2hhbmdlKHNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0OiBhbnlbXSkge1xuICAgICAgICB0aGlzLm5vdGlmeVNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0Q2hhbmdlKHNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0KTtcbiAgICB9XG5cbiAgICBjaGFuZ2VQcmV2aWV3TW9kZSh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLm5vdGlmeVByZXZpZXdNb2RlQ2hhbmdlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBnZXRDdXJyZW50U2NyZWVuVHlwZSgpOiBEYXRhVmlld1NjcmVlblNpemUge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTY3JlZW5UeXBlKHRoaXMuX3NjcmVlblNpemVTdWJqZWN0Py5nZXRWYWx1ZSgpIHx8IFBlcFNjcmVlblNpemVUeXBlLkxHKTtcbiAgICB9XG5cbiAgICBnZXRTY3JlZW5UeXBlKHNpemU6IFBlcFNjcmVlblNpemVUeXBlKTogRGF0YVZpZXdTY3JlZW5TaXplIHtcbiAgICAgICAgY29uc3Qgc2NyZWVuVHlwZTogRGF0YVZpZXdTY3JlZW5TaXplID1cbiAgICAgICAgICAgIHNpemUgPCBQZXBTY3JlZW5TaXplVHlwZS5NRCA/ICdMYW5kc2NhcGUnIDpcbiAgICAgICAgICAgIChzaXplID09PSBQZXBTY3JlZW5TaXplVHlwZS5NRCB8fCBzaXplID09PSBQZXBTY3JlZW5TaXplVHlwZS5TTSA/ICdUYWJsZXQnIDogJ1BoYWJsZXQnKTtcblxuICAgICAgICByZXR1cm4gc2NyZWVuVHlwZTtcbiAgICB9XG5cbiAgICBnZXRTZWN0aW9uQ29sdW1uS2V5KHNlY3Rpb25LZXkgPSAnJywgaW5kZXggPSAnJykge1xuICAgICAgICByZXR1cm4gYCR7c2VjdGlvbktleX1fY29sdW1uXyR7aW5kZXh9YDtcbiAgICB9XG5cbiAgICBnZXRJc0hpZGRlbihoaWRlSW46IERhdGFWaWV3U2NyZWVuU2l6ZVtdIHwgdW5kZWZpbmVkLCBjdXJyZW50U2NyZWVuVHlwZTogRGF0YVZpZXdTY3JlZW5TaXplKSB7XG4gICAgICAgIHJldHVybiAoaGlkZUluICYmIGhpZGVJbj8ubGVuZ3RoID4gMCkgPyBoaWRlSW4uc29tZShoaSA9PiBoaSA9PT0gY3VycmVudFNjcmVlblR5cGUpIDogZmFsc2U7XG4gICAgfVxuXG4gICAgbmF2aWdhdGVUb0VkaXRvcihlZGl0b3JUeXBlOiBQZXBMYXlvdXRFZGl0b3JUeXBlLCBpZDogc3RyaW5nLCB0aXRsZSA9ICcnKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzdWNjZXNzID0gZmFsc2U7XG5cbiAgICAgICAgLy8gQ2Fubm90IG5hdmlnYXRlIGludG8gJ2xheW91dC1idWlsZGVyJyBiZWNhdXNlIHRoaXMgaXMgZmlyc3QgYW5kIGNvbnN0IGluIHRoZSBlZGl0b3JzQnJlYWRDcnVtYnMuXG4gICAgICAgIGlmIChlZGl0b3JUeXBlICE9PSAnbGF5b3V0LWJ1aWxkZXInICYmIGlkPy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBDaGVjayB3aGljaCBlZGl0b3Igd2UgaGF2ZSBub3dcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRFZGl0b3IgPSB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYlt0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5sZW5ndGggLSAxXTtcblxuICAgICAgICAgICAgLy8gT25seSBpZiBpdCdzIGFub3RoZXIgZWRpdG9yLlxuICAgICAgICAgICAgaWYoY3VycmVudEVkaXRvci5pZCAhPT0gaWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEVkaXRvci50eXBlICE9PSAnbGF5b3V0LWJ1aWxkZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEFsd2F5cyBwb3AgdGhlIGxhc3QgYW5kIGluc2VydCB0aGUgY3VycmVudC5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIucG9wKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZWRpdG9yID0gdGhpcy5nZXRFZGl0b3JCeVR5cGUoZWRpdG9yVHlwZSwgaWQsIHRpdGxlKTtcblxuICAgICAgICAgICAgICAgIGlmIChlZGl0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIucHVzaChlZGl0b3IpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZUN1cnJlbnRFZGl0b3IoKTtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzdWNjZXNzO1xuICAgIH1cblxuICAgIG5hdmlnYXRlQmFja0Zyb21FZGl0b3IoKSB7XG4gICAgICAgIC8vIEtlZXAgdGhlIGxheW91dCBidWlsZGVyIGVkaXRvci5cbiAgICAgICAgaWYgKHRoaXMuX2VkaXRvcnNCcmVhZENydW1iLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIC8vIE1heWJlIHdlIHdhbnQgdG8gY29tcGFyZSB0aGUgbGFzdCBlZGl0b3IgZm9yIHZhbGlkYXRpb24gP1xuICAgICAgICAgICAgY29uc3QgbGFzdEVkaXRvciA9IHRoaXMuX2VkaXRvcnNCcmVhZENydW1iLnBvcCgpO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VDdXJyZW50RWRpdG9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVMYXlvdXRGcm9tRWRpdG9yKGVkaXRvckRhdGE6IElMYXlvdXRFZGl0b3IpIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG5cbiAgICAgICAgaWYgKGxheW91dFZpZXcpIHtcbiAgICAgICAgICAgIGxheW91dFZpZXcuTGF5b3V0Lk1heFdpZHRoID0gZWRpdG9yRGF0YS5tYXhXaWR0aDtcbiAgICAgICAgICAgIGxheW91dFZpZXcuTGF5b3V0Lkhvcml6b250YWxTcGFjaW5nID0gZWRpdG9yRGF0YS5ob3Jpem9udGFsU3BhY2luZztcbiAgICAgICAgICAgIGxheW91dFZpZXcuTGF5b3V0LlZlcnRpY2FsU3BhY2luZyA9IGVkaXRvckRhdGEudmVydGljYWxTcGFjaW5nO1xuICAgICAgICAgICAgbGF5b3V0Vmlldy5MYXlvdXQuU2VjdGlvbnNHYXAgPSBlZGl0b3JEYXRhLnNlY3Rpb25zR2FwO1xuICAgICAgICAgICAgbGF5b3V0Vmlldy5MYXlvdXQuQ29sdW1uc0dhcCA9IGVkaXRvckRhdGEuY29sdW1uc0dhcDtcbiAgICAgICAgICAgIC8vIGxheW91dFZpZXcuTGF5b3V0LlJvdW5kZWRDb3JuZXJzID0gZWRpdG9yRGF0YS5yb3VuZGVkQ29ybmVycztcblxuICAgICAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuICAgICAgICB9XG4gICAgfVxuICAgIFxuICAgIHVwZGF0ZVNlY3Rpb25Gcm9tRWRpdG9yKHNlY3Rpb25EYXRhOiBJTGF5b3V0U2VjdGlvbkVkaXRvcikge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIGNvbnN0IHNlY3Rpb25JbmRleCA9IHNlY3Rpb25zLmZpbmRJbmRleChzZWN0aW9uID0+IHNlY3Rpb24uS2V5ID09PSBzZWN0aW9uRGF0YS5pZCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIHNlY3Rpb24gZGV0YWlscy5cbiAgICAgICAgaWYgKHNlY3Rpb25JbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBibG9ja3NJZHNUb1JlbW92ZSA9IFtdO1xuXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50U2VjdGlvbiA9IHNlY3Rpb25zW3NlY3Rpb25JbmRleF07XG4gICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5OYW1lID0gc2VjdGlvbkRhdGEuc2VjdGlvbk5hbWU7XG4gICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5TcGxpdCA9IHNlY3Rpb25EYXRhLnNwbGl0O1xuICAgICAgICAgICAgY3VycmVudFNlY3Rpb24uSGVpZ2h0ID0gc2VjdGlvbkRhdGEuaGVpZ2h0O1xuICAgICAgICAgICAgY3VycmVudFNlY3Rpb24uQ29sbGFwc2VPblRhYmxldCA9IHNlY3Rpb25EYXRhLmNvbGxhcHNlT25UYWJsZXQ7XG4gICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5GaWxsSGVpZ2h0ID0gc2VjdGlvbkRhdGEuZmlsbEhlaWdodDtcblxuICAgICAgICAgICAgLy8gR2V0IHRoZSBuZXcgY29sdW1ucyBudW1iZXIgZnJvbSBjdXJyZW50U2VjdGlvbi5TcGxpdCwgaWYgaXRzIHVuZGVmaW5lZCBwdXQgYSBkZWZhdWx0IDEuXG4gICAgICAgICAgICBjb25zdCBuZXdDb2x1bW5zTGVuZ3RoID0gY3VycmVudFNlY3Rpb24uU3BsaXQ/LnNwbGl0KCcgJykubGVuZ3RoIHx8IDE7XG4gICAgICAgICAgICBpZiAobmV3Q29sdW1uc0xlbmd0aCA+IGN1cnJlbnRTZWN0aW9uLkNvbHVtbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKG5ld0NvbHVtbnNMZW5ndGggPiBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLnB1c2goe30pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3Q29sdW1uc0xlbmd0aCA8IGN1cnJlbnRTZWN0aW9uLkNvbHVtbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKG5ld0NvbHVtbnNMZW5ndGggPCBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2x1bm0gPSBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBibG9jayBpbiB0aGlzIGNvbHVtbiBkZWxldGUgaXQuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bm0gJiYgY29sdW5tLkJsb2NrQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBibG9ja3NJZHNUb1JlbW92ZS5wdXNoKGNvbHVubS5CbG9ja0NvbnRhaW5lci5CbG9ja0tleSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFVwZGF0ZSBlZGl0b3IgdGl0bGVcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRFZGl0b3IgPSB0aGlzLl9lZGl0b3JTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudEVkaXRvciAmJiBjdXJyZW50RWRpdG9yLnR5cGUgPT09ICdzZWN0aW9uJyAmJiBjdXJyZW50RWRpdG9yLmlkID09PSBjdXJyZW50U2VjdGlvbi5LZXkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRoaXMuZ2V0U2VjdGlvbkVkaXRvclRpdGxlKGN1cnJlbnRTZWN0aW9uLCBzZWN0aW9uSW5kZXgpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnRFZGl0b3IudGl0bGUgPSB0aXRsZTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUVkaXRvckNoYW5nZShjdXJyZW50RWRpdG9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXBkYXRlIHNlY3Rpb25zIGNoYW5nZS5cbiAgICAgICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGJsb2NrcyB0byByZW1vdmUsIG5vdGlmeSB0aGUgYmxvY2tzIHJlbW92ZWQuXG4gICAgICAgICAgICBpZiAoYmxvY2tzSWRzVG9SZW1vdmUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5QmxvY2tzUmVtb3ZlZChibG9ja3NJZHNUb1JlbW92ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGRTZWN0aW9uKHNlY3Rpb246IElQZXBMYXlvdXRTZWN0aW9uIHwgbnVsbCA9IG51bGwpIHtcbiAgICAgICAgLy8gQ3JlYXRlIG5ldyBzZWN0aW9uXG4gICAgICAgIGlmICghc2VjdGlvbikge1xuICAgICAgICAgICAgc2VjdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBLZXk6IFBlcEd1aWQubmV3R3VpZCgpLFxuICAgICAgICAgICAgICAgIENvbHVtbnM6IFt7fV0sIC8vIEFkZCBlbXB0eSBzZWN0aW9uIGNvbHVtblxuICAgICAgICAgICAgICAgIEhpZGU6IFtdXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgdGhlIG5ldyBzZWN0aW9uIHRvIGxheW91dCB2aWV3LlxuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIHNlY3Rpb25zLnB1c2goc2VjdGlvbik7XG4gICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICB9XG5cbiAgICByZW1vdmVTZWN0aW9uKHNlY3Rpb25JZDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGxheW91dFZpZXcgPSB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgY29uc3QgaW5kZXggPSBzZWN0aW9ucy5maW5kSW5kZXgoc2VjdGlvbiA9PiBzZWN0aW9uLktleSA9PT0gc2VjdGlvbklkKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIC8vIEdldCB0aGUgYmxvY2tzIGlkJ3MgdG8gcmVtb3ZlLlxuICAgICAgICAgICAgY29uc3QgYmxvY2tzSWRzVG9SZW1vdmU6IGFueSA9IHNlY3Rpb25zW2luZGV4XS5Db2x1bW5zLm1hcChjb2x1bW4gPT4gY29sdW1uPy5CbG9ja0NvbnRhaW5lcj8uQmxvY2tLZXkpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgc2VjdGlvbi5cbiAgICAgICAgICAgIHNlY3Rpb25zLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBibG9ja3MgdG8gcmVtb3ZlLCBub3RpZnkgdGhlIGJsb2NrcyByZW1vdmVkLlxuICAgICAgICAgICAgaWYgKGJsb2Nrc0lkc1RvUmVtb3ZlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUJsb2Nrc1JlbW92ZWQoYmxvY2tzSWRzVG9SZW1vdmUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoaWRlU2VjdGlvbihzZWN0aW9uSWQ6IHN0cmluZywgaGlkZUluOiBEYXRhVmlld1NjcmVlblNpemVbXSkge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIGNvbnN0IGluZGV4ID0gc2VjdGlvbnMuZmluZEluZGV4KHNlY3Rpb24gPT4gc2VjdGlvbi5LZXkgPT09IHNlY3Rpb25JZCk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICBzZWN0aW9uc1tpbmRleF0uSGlkZSA9IGhpZGVJbjtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uU2VjdGlvbkRyb3BwZWQoZXZlbnQ6IENka0RyYWdEcm9wPGFueVtdPikge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIG1vdmVJdGVtSW5BcnJheShzZWN0aW9ucywgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcbiAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuICAgIH1cblxuICAgIG9uU2VjdGlvbkRyYWdTdGFydChldmVudDogQ2RrRHJhZ1N0YXJ0KSB7XG4gICAgICAgIHRoaXMuY2hhbmdlQ3Vyc29yT25EcmFnU3RhcnQoKTtcbiAgICAgICAgdGhpcy5fZHJhZ2dpbmdTZWN0aW9uS2V5Lm5leHQoZXZlbnQuc291cmNlLmRhdGEpO1xuICAgIH1cblxuICAgIG9uU2VjdGlvbkRyYWdFbmQoZXZlbnQ6IENka0RyYWdFbmQpIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VDdXJzb3JPbkRyYWdFbmQoKTtcbiAgICAgICAgdGhpcy5fZHJhZ2dpbmdTZWN0aW9uS2V5Lm5leHQoJycpO1xuICAgIH1cblxuICAgIHJlbW92ZUJsb2NrRnJvbVNlY3Rpb24oYmxvY2tJZDogc3RyaW5nKSB7XG4gICAgICAgIGxldCBibG9ja1JlbW92ZWQgPSBmYWxzZTtcblxuICAgICAgICAvLyBSZW1vdmUgdGhlIGJsb2NrIGZyb20gc2VjdGlvbiBjb2x1bW4uXG4gICAgICAgIGNvbnN0IGxheW91dFZpZXcgPSB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgXG4gICAgICAgIGZvciAobGV0IHNlY3Rpb25JbmRleCA9IDA7IHNlY3Rpb25JbmRleCA8IHNlY3Rpb25zLmxlbmd0aDsgc2VjdGlvbkluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlY3Rpb24gPSBzZWN0aW9uc1tzZWN0aW9uSW5kZXhdO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGJsb2NrIGNvbnRhaW5lci5cbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbkluZGV4ID0gc2VjdGlvbi5Db2x1bW5zLmZpbmRJbmRleChjb2x1bW4gPT4gY29sdW1uLkJsb2NrQ29udGFpbmVyPy5CbG9ja0tleSA9PT0gYmxvY2tJZCk7XG4gICAgICAgICAgICBpZiAoY29sdW1uSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBzZWN0aW9uLkNvbHVtbnNbY29sdW1uSW5kZXhdLkJsb2NrQ29udGFpbmVyO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICAgICAgICAgICAgICBibG9ja1JlbW92ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgYmxvY2sgd2FzIHJlbW92ZWQsIG5vdGlmeSB0aGUgYmxvY2sgcmVtb3ZlZC5cbiAgICAgICAgaWYgKGJsb2NrUmVtb3ZlZCkge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlCbG9ja3NSZW1vdmVkKFtibG9ja0lkXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoaWRlQmxvY2soc2VjdGlvbklkOiBzdHJpbmcsIGJsb2NrSWQ6IHN0cmluZywgaGlkZUluOiBEYXRhVmlld1NjcmVlblNpemVbXSkge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIFxuICAgICAgICBjb25zdCBpbmRleCA9IHNlY3Rpb25zLmZpbmRJbmRleChzZWN0aW9uID0+IHNlY3Rpb24uS2V5ID09PSBzZWN0aW9uSWQpO1xuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgY29uc3QgY29sdW1uSW5kZXggPSBzZWN0aW9uc1tpbmRleF0uQ29sdW1ucy5maW5kSW5kZXgoY29sdW1uID0+IGNvbHVtbi5CbG9ja0NvbnRhaW5lcj8uQmxvY2tLZXkgPT09IGJsb2NrSWQpO1xuICAgICAgICAgICAgaWYgKGNvbHVtbkluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBibG9ja0NvbnRhaW5lciA9IHNlY3Rpb25zW2luZGV4XS5Db2x1bW5zW2NvbHVtbkluZGV4XS5CbG9ja0NvbnRhaW5lcjtcbiAgICAgICAgICAgICAgICBpZiAoYmxvY2tDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgYmxvY2tDb250YWluZXIuSGlkZSA9IGhpZGVJbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uQmxvY2tEcm9wcGVkKGV2ZW50OiBDZGtEcmFnRHJvcDxJUGVwTGF5b3V0U2VjdGlvbkNvbHVtbiwgYW55LCBhbnk+LCBzZWN0aW9uSWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcblxuICAgICAgICBpZiAoZXZlbnQucHJldmlvdXNDb250YWluZXIuaWQgPT09IExheW91dEJ1aWxkZXJJbnRlcm5hbFNlcnZpY2UuQVZBSUxBQkxFX0JMT0NLU19DT05UQUlORVJfSUQpIHtcbiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGlmIGJsb2NrcyBudW1iZXIgYWxsb3cuXG4gICAgICAgICAgICBpZiAodGhpcy5fYmxvY2tzTGltaXROdW1iZXIgPiAwICYmIHRoaXMuZ2V0QmxvY2tzTnVtYmVyKCkgPj0gdGhpcy5fYmxvY2tzTGltaXROdW1iZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gbmV3IFBlcERpYWxvZ0RhdGEoe1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnTUVTU0FHRVMuRElBTE9HX05PVElDRV9USVRMRScpLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdMQVlPVVRfQlVJTERFUi5CTE9DS1NfQ09VTlRfTElNSVRfTUVTU0FHRScpLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kaWFsb2dTZXJ2aWNlLm9wZW5EZWZhdWx0RGlhbG9nKGRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGJsb2NrIHJlbGF0aW9uIChwcmV2aW91c0NvbnRhaW5lci5kYXRhIGlzIElQZXBEcmFnZ2FibGVJdGVtIGFuZCBpbnNpZGUgd2UgaGF2ZSBBdmFpbGFibGVCbG9jayBvYmplY3QpLlxuICAgICAgICAgICAgICAgIGNvbnN0IGRyYWdnYWJsZUl0ZW06IElQZXBEcmFnZ2FibGVJdGVtID0gZXZlbnQucHJldmlvdXNDb250YWluZXIuZGF0YVtldmVudC5wcmV2aW91c0luZGV4XSBhcyBJUGVwRHJhZ2dhYmxlSXRlbTtcblxuICAgICAgICAgICAgICAgIGlmIChkcmFnZ2FibGVJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvY2sgdGhlIHNjcmVlbiB1bnRpbGwgdGhlIGVkaXRvciB3aWxsIGJlIGxvYWRlZC5cbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5fbG9ja1NjcmVlblN1YmplY3QubmV4dCh0cnVlKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGNvbHVtbi5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbHVtbiA9IHRoaXMuZ2V0U2VjdGlvbkNvbHVtbkJ5SWRGb3JFZGl0b3IoZXZlbnQuY29udGFpbmVyLmlkKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIGJsb2NrIGtleSBpbiB0aGUgc2VjdGlvbiBibG9jayBvbmx5IGlmIHRoZXJlIGlzIGEgYmxhbmsgY29sdW1uLlxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudENvbHVtbiAmJiAhY3VycmVudENvbHVtbi5CbG9ja0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGhlIGJsb2NrIHV1aWQuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBibG9ja0tleSA9IFBlcEd1aWQubmV3R3VpZCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q29sdW1uLkJsb2NrQ29udGFpbmVyID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJsb2NrS2V5OiBibG9ja0tleSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlcmUgd2UgdXBkYXRlIHRoZSBsYXlvdXQgdmlldyBjYXVzZSB0aGUgbGF5b3V0IGlzIHVwZGF0ZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhaXNlIGJsb2NrIGFkZGVkIGV2ZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmxvY2tBZGRlZEV2ZW50RGF0YTogSVBlcExheW91dEJsb2NrQWRkZWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja0tleTogYmxvY2tLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRHJhZ2dhYmxlSXRlbTogZHJhZ2dhYmxlSXRlbSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlCbG9ja0FkZGVkKGJsb2NrQWRkZWRFdmVudERhdGEpOyAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXZpZ2F0ZVRvRWRpdG9yQWZ0ZXJCbG9ja0FkZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmF2aWdhdGUgdG8gdGhlIGJsb2NrIGVkaXRvci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRlVG9FZGl0b3IoJ2Jsb2NrJywgYmxvY2tLZXkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJkcmFnZ2FibGVJdGVtIGlzIG5vdCBhIElQZXBEcmFnZ2FibGVJdGVtIHR5cGVcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGJsb2NrIG1vdmVkIGJldHdlZW4gY29sdW1ucyBpbiB0aGUgc2FtZSBzZWN0aW9uIG9yIGJldHdlZW4gZGlmZmVyZW50IHNlY3Rpb25zIGJ1dCBub3QgaW4gdGhlIHNhbWUgY29sdW1uLlxuICAgICAgICAgICAgaWYgKGV2ZW50LmNvbnRhaW5lci5pZCAhPT0gZXZlbnQucHJldmlvdXNDb250YWluZXIuaWQpIHtcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGNvbHVtbi5cbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29sdW1uID0gdGhpcy5nZXRTZWN0aW9uQ29sdW1uQnlJZEZvckVkaXRvcihldmVudC5jb250YWluZXIuaWQpO1xuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgcHJldmlvdXMgY29sdW1uLlxuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpdW9zQ29sdW1uID0gdGhpcy5nZXRTZWN0aW9uQ29sdW1uQnlJZEZvckVkaXRvcihldmVudC5wcmV2aW91c0NvbnRhaW5lci5pZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudENvbHVtbiAmJiBwcmV2aXVvc0NvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q29sdW1uLkJsb2NrQ29udGFpbmVyID0gcHJldml1b3NDb2x1bW4uQmxvY2tDb250YWluZXI7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwcmV2aXVvc0NvbHVtbi5CbG9ja0NvbnRhaW5lcjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uQmxvY2tEcmFnU3RhcnQoZXZlbnQ6IENka0RyYWdTdGFydCkge1xuICAgICAgICB0aGlzLmNoYW5nZUN1cnNvck9uRHJhZ1N0YXJ0KCk7XG4gICAgICAgIC8vIFRha2UgdGhlIGJsb2NrIGtleSBpZiBleGlzdCwgZWxzZSB0YWtlIHRoZSBhdmFpbGFibGUgYmxvY2sga2V5IChyZWxhdGlvbiBrZXkpLlxuICAgICAgICBjb25zdCBibG9ja0tleSA9IGV2ZW50LnNvdXJjZS5kYXRhPy5CbG9ja0tleSB8fCBldmVudC5zb3VyY2UuZGF0YT8uS2V5O1xuICAgICAgICB0aGlzLl9kcmFnZ2luZ0Jsb2NrS2V5Lm5leHQoYmxvY2tLZXkpO1xuICAgIH1cblxuICAgIG9uQmxvY2tEcmFnRW5kKGV2ZW50OiBDZGtEcmFnRW5kKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlQ3Vyc29yT25EcmFnRW5kKCk7XG4gICAgICAgIHRoaXMuX2RyYWdnaW5nQmxvY2tLZXkubmV4dCgnJyk7XG4gICAgfVxuICAgIFxuICAgIGRvZXNDb2x1bW5Db250YWluQmxvY2soc2VjdGlvbklkOiBzdHJpbmcsIGNvbHVtbkluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IHJlcyA9IGZhbHNlO1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbiA9IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9ucy5maW5kKHNlY3Rpb24gPT4gc2VjdGlvbi5LZXkgPT09IHNlY3Rpb25JZCk7XG5cbiAgICAgICAgaWYgKHNlY3Rpb24gJiYgY29sdW1uSW5kZXggPj0gMCAmJiBzZWN0aW9uLkNvbHVtbnMubGVuZ3RoID4gY29sdW1uSW5kZXgpIHtcbiAgICAgICAgICAgIHJlcyA9ICEhc2VjdGlvbi5Db2x1bW5zW2NvbHVtbkluZGV4XS5CbG9ja0NvbnRhaW5lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgc2V0U2NyZWVuV2lkdGgoc2NyZWVuVHlwZTogRGF0YVZpZXdTY3JlZW5TaXplKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRDc3NTY3JlZW5XaWRoKHNjcmVlblR5cGUpXG5cbiAgICAgICAgY29uc3Qgd2lkdGggPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWx1ZSwgMCk7XG4gICAgICAgIGlmICh3aWR0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fc2NyZWVuV2lkdGhTdWJqZWN0Lm5leHQoJzEwMCUnKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5U2NyZWVuU2l6ZUNoYW5nZShQZXBTY3JlZW5TaXplVHlwZS5YTCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zY3JlZW5XaWR0aFN1YmplY3QubmV4dChgJHt3aWR0aH1weGApO1xuXG4gICAgICAgICAgICAvLyBDaGFuZ2UgdGhlIHNpemUgYWNjb3JkaW5nIHRoZSB3aWR0aC5cbiAgICAgICAgICAgIGlmICh3aWR0aCA+PSAxOTIwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKFBlcFNjcmVlblNpemVUeXBlLlhMKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod2lkdGggPj0gMTI4MCAmJiB3aWR0aCA8IDE5MjApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeVNjcmVlblNpemVDaGFuZ2UoUGVwU2NyZWVuU2l6ZVR5cGUuTEcpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh3aWR0aCA+PSA5NjAgJiYgd2lkdGggPCAxMjgwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKFBlcFNjcmVlblNpemVUeXBlLk1EKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod2lkdGggPj0gNjAwICYmIHdpZHRoIDwgOTYwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKFBlcFNjcmVlblNpemVUeXBlLlNNKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod2lkdGggPCA2MDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeVNjcmVlblNpemVDaGFuZ2UoUGVwU2NyZWVuU2l6ZVR5cGUuWFMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2hvd1NrZWxldG9uKHNob3c6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fc2hvd1NrZWxldG9uU3ViamVjdC5uZXh0KHNob3cpO1xuICAgIH1cbiAgICBcbiAgICBsb2NrU2NyZWVuKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMubm90aWZ5TG9ja1NjcmVlbih2YWx1ZSk7XG4gICAgfVxuXG4gICAgbG9hZExheW91dEJ1aWxkZXIobGF5b3V0VmlldzogSVBlcExheW91dFZpZXcpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZWRpdE1vZGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAvLyBMb2FkIHRoZSBsYXlvdXQgZWRpdG9yLlxuICAgICAgICAgICAgICAgIHRoaXMubG9hZERlZmF1bHRFZGl0b3IobGF5b3V0Vmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb2FkIG9ubHkgdGhlIGxheW91dCB2aWV3LlxuICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgfVxufVxuIl19