@rocketshow/designer 1.40.0 → 1.44.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 (191) hide show
  1. package/fesm2022/rocketshow-designer.mjs +1389 -1148
  2. package/fesm2022/rocketshow-designer.mjs.map +1 -1
  3. package/index.d.ts +1676 -5
  4. package/package.json +2 -4
  5. package/rocketshow-designer-1.44.0.tgz +0 -0
  6. package/esm2022/lib/array-sort-pipe.mjs +0 -30
  7. package/esm2022/lib/designer.component.mjs +0 -672
  8. package/esm2022/lib/designer.module.mjs +0 -186
  9. package/esm2022/lib/designer.service.mjs +0 -14
  10. package/esm2022/lib/dropzone/dropzone.component.mjs +0 -93
  11. package/esm2022/lib/effect/effect-curve/effect-curve.component.mjs +0 -577
  12. package/esm2022/lib/effect/effect-pan-tilt/effect-pan-tilt.component.mjs +0 -36
  13. package/esm2022/lib/effect/effect.component.mjs +0 -174
  14. package/esm2022/lib/error-dialog/error-dialog.component.mjs +0 -75
  15. package/esm2022/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.mjs +0 -370
  16. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.mjs +0 -147
  17. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.mjs +0 -213
  18. package/esm2022/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.mjs +0 -78
  19. package/esm2022/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.mjs +0 -119
  20. package/esm2022/lib/fixture/fixture-capability/fixture-capability.component.mjs +0 -191
  21. package/esm2022/lib/fixture/fixture-channel/fixture-channel.component.mjs +0 -162
  22. package/esm2022/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.mjs +0 -365
  23. package/esm2022/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.mjs +0 -151
  24. package/esm2022/lib/fixture/fixture-settings/fixture-settings.component.mjs +0 -46
  25. package/esm2022/lib/fixture/fixture.component.mjs +0 -148
  26. package/esm2022/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.mjs +0 -145
  27. package/esm2022/lib/fixture-pool/fixture-pool.component.mjs +0 -641
  28. package/esm2022/lib/intro/intro.component.mjs +0 -95
  29. package/esm2022/lib/master-dimmer/master-dimmer.component.mjs +0 -66
  30. package/esm2022/lib/models/cached-fixture-capability.mjs +0 -9
  31. package/esm2022/lib/models/cached-fixture-channel.mjs +0 -7
  32. package/esm2022/lib/models/cached-fixture.mjs +0 -6
  33. package/esm2022/lib/models/color.mjs +0 -8
  34. package/esm2022/lib/models/composition.mjs +0 -46
  35. package/esm2022/lib/models/effect-curve-profile-channel.mjs +0 -15
  36. package/esm2022/lib/models/effect-curve.mjs +0 -69
  37. package/esm2022/lib/models/effect-pan-tilt.mjs +0 -19
  38. package/esm2022/lib/models/effect.mjs +0 -12
  39. package/esm2022/lib/models/fixture-capability-value.mjs +0 -15
  40. package/esm2022/lib/models/fixture-capability.mjs +0 -127
  41. package/esm2022/lib/models/fixture-channel-value.mjs +0 -11
  42. package/esm2022/lib/models/fixture-channel.mjs +0 -24
  43. package/esm2022/lib/models/fixture-matrix-pixel-group-constraints.mjs +0 -27
  44. package/esm2022/lib/models/fixture-matrix-pixel-group.mjs +0 -12
  45. package/esm2022/lib/models/fixture-matrix.mjs +0 -25
  46. package/esm2022/lib/models/fixture-mode-channel.mjs +0 -26
  47. package/esm2022/lib/models/fixture-mode.mjs +0 -17
  48. package/esm2022/lib/models/fixture-physical.mjs +0 -14
  49. package/esm2022/lib/models/fixture-profile.mjs +0 -85
  50. package/esm2022/lib/models/fixture-wheel-slot.mjs +0 -26
  51. package/esm2022/lib/models/fixture-wheel.mjs +0 -15
  52. package/esm2022/lib/models/fixture.mjs +0 -40
  53. package/esm2022/lib/models/preset-fixture.mjs +0 -10
  54. package/esm2022/lib/models/preset-region-scene.mjs +0 -8
  55. package/esm2022/lib/models/preset.mjs +0 -65
  56. package/esm2022/lib/models/project.mjs +0 -78
  57. package/esm2022/lib/models/scene-playback-region.mjs +0 -11
  58. package/esm2022/lib/models/scene.mjs +0 -27
  59. package/esm2022/lib/preset/preset-settings/preset-settings.component.mjs +0 -194
  60. package/esm2022/lib/preset/preset.component.mjs +0 -131
  61. package/esm2022/lib/preview/models/color-changer-3d.mjs +0 -52
  62. package/esm2022/lib/preview/models/fixture-3d.mjs +0 -260
  63. package/esm2022/lib/preview/models/moving-head-3d.mjs +0 -115
  64. package/esm2022/lib/preview/preview.component.mjs +0 -216
  65. package/esm2022/lib/project/project-browser/project-browser.component.mjs +0 -143
  66. package/esm2022/lib/project/project-import/project-import.component.mjs +0 -107
  67. package/esm2022/lib/project/project-save/project-save.component.mjs +0 -178
  68. package/esm2022/lib/project/project-share/project-share.component.mjs +0 -71
  69. package/esm2022/lib/scene/scene-settings/scene-settings.component.mjs +0 -146
  70. package/esm2022/lib/scene/scene.component.mjs +0 -110
  71. package/esm2022/lib/services/animation.service.mjs +0 -16
  72. package/esm2022/lib/services/config.service.mjs +0 -28
  73. package/esm2022/lib/services/effect.service.mjs +0 -14
  74. package/esm2022/lib/services/error-dialog.service.mjs +0 -39
  75. package/esm2022/lib/services/fixture-pool.service.mjs +0 -30
  76. package/esm2022/lib/services/fixture.service.mjs +0 -699
  77. package/esm2022/lib/services/hotkey-target-exclude.service.mjs +0 -24
  78. package/esm2022/lib/services/intro.service.mjs +0 -140
  79. package/esm2022/lib/services/preset.service.mjs +0 -450
  80. package/esm2022/lib/services/preview-mesh.service.mjs +0 -57
  81. package/esm2022/lib/services/preview.service.mjs +0 -481
  82. package/esm2022/lib/services/project-load.service.mjs +0 -206
  83. package/esm2022/lib/services/project.service.mjs +0 -93
  84. package/esm2022/lib/services/scene.service.mjs +0 -164
  85. package/esm2022/lib/services/timeline.service.mjs +0 -726
  86. package/esm2022/lib/services/user-ensure-login.service.mjs +0 -38
  87. package/esm2022/lib/services/user.service.mjs +0 -89
  88. package/esm2022/lib/services/uuid.service.mjs +0 -23
  89. package/esm2022/lib/services/warning-dialog.service.mjs +0 -38
  90. package/esm2022/lib/timeline/composition-settings/composition-settings.component.mjs +0 -304
  91. package/esm2022/lib/timeline/timeline-grid/timeline-grid.component.mjs +0 -216
  92. package/esm2022/lib/timeline/timeline.component.mjs +0 -418
  93. package/esm2022/lib/user/user-login/user-login.component.mjs +0 -144
  94. package/esm2022/lib/user/user-register/user-register.component.mjs +0 -220
  95. package/esm2022/lib/wait-dialog/wait-dialog.component.mjs +0 -26
  96. package/esm2022/lib/warning-dialog/warning-dialog.component.mjs +0 -68
  97. package/esm2022/public_api.mjs +0 -7
  98. package/esm2022/rocketshow-designer.mjs +0 -5
  99. package/lib/array-sort-pipe.d.ts +0 -7
  100. package/lib/designer.component.d.ts +0 -73
  101. package/lib/designer.module.d.ts +0 -57
  102. package/lib/designer.service.d.ts +0 -6
  103. package/lib/dropzone/dropzone.component.d.ts +0 -24
  104. package/lib/effect/effect-curve/effect-curve.component.d.ts +0 -59
  105. package/lib/effect/effect-pan-tilt/effect-pan-tilt.component.d.ts +0 -15
  106. package/lib/effect/effect.component.d.ts +0 -22
  107. package/lib/error-dialog/error-dialog.component.d.ts +0 -17
  108. package/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.d.ts +0 -41
  109. package/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.d.ts +0 -26
  110. package/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.d.ts +0 -34
  111. package/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.d.ts +0 -15
  112. package/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.d.ts +0 -18
  113. package/lib/fixture/fixture-capability/fixture-capability.component.d.ts +0 -31
  114. package/lib/fixture/fixture-channel/fixture-channel.component.d.ts +0 -25
  115. package/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.d.ts +0 -32
  116. package/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.d.ts +0 -14
  117. package/lib/fixture/fixture-settings/fixture-settings.component.d.ts +0 -14
  118. package/lib/fixture/fixture.component.d.ts +0 -25
  119. package/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.d.ts +0 -28
  120. package/lib/fixture-pool/fixture-pool.component.d.ts +0 -62
  121. package/lib/intro/intro.component.d.ts +0 -11
  122. package/lib/master-dimmer/master-dimmer.component.d.ts +0 -15
  123. package/lib/models/cached-fixture-capability.d.ts +0 -11
  124. package/lib/models/cached-fixture-channel.d.ts +0 -11
  125. package/lib/models/cached-fixture.d.ts +0 -11
  126. package/lib/models/color.d.ts +0 -6
  127. package/lib/models/composition.d.ts +0 -19
  128. package/lib/models/effect-curve-profile-channel.d.ts +0 -5
  129. package/lib/models/effect-curve.d.ts +0 -15
  130. package/lib/models/effect-pan-tilt.d.ts +0 -6
  131. package/lib/models/effect.d.ts +0 -6
  132. package/lib/models/fixture-capability-value.d.ts +0 -10
  133. package/lib/models/fixture-capability.d.ts +0 -117
  134. package/lib/models/fixture-channel-value.d.ts +0 -6
  135. package/lib/models/fixture-channel.d.ts +0 -9
  136. package/lib/models/fixture-matrix-pixel-group-constraints.d.ts +0 -8
  137. package/lib/models/fixture-matrix-pixel-group.d.ts +0 -6
  138. package/lib/models/fixture-matrix.d.ts +0 -6
  139. package/lib/models/fixture-mode-channel.d.ts +0 -8
  140. package/lib/models/fixture-mode.d.ts +0 -8
  141. package/lib/models/fixture-physical.d.ts +0 -4
  142. package/lib/models/fixture-profile.d.ts +0 -39
  143. package/lib/models/fixture-wheel-slot.d.ts +0 -17
  144. package/lib/models/fixture-wheel.d.ts +0 -5
  145. package/lib/models/fixture.d.ts +0 -23
  146. package/lib/models/preset-fixture.d.ts +0 -5
  147. package/lib/models/preset-region-scene.d.ts +0 -9
  148. package/lib/models/preset.d.ts +0 -20
  149. package/lib/models/project.d.ts +0 -31
  150. package/lib/models/scene-playback-region.d.ts +0 -6
  151. package/lib/models/scene.d.ts +0 -11
  152. package/lib/preset/preset-settings/preset-settings.component.d.ts +0 -22
  153. package/lib/preset/preset.component.d.ts +0 -25
  154. package/lib/preview/models/color-changer-3d.d.ts +0 -16
  155. package/lib/preview/models/fixture-3d.d.ts +0 -38
  156. package/lib/preview/models/moving-head-3d.d.ts +0 -23
  157. package/lib/preview/preview.component.d.ts +0 -38
  158. package/lib/project/project-browser/project-browser.component.d.ts +0 -27
  159. package/lib/project/project-import/project-import.component.d.ts +0 -23
  160. package/lib/project/project-save/project-save.component.d.ts +0 -28
  161. package/lib/project/project-share/project-share.component.d.ts +0 -16
  162. package/lib/scene/scene-settings/scene-settings.component.d.ts +0 -20
  163. package/lib/scene/scene.component.d.ts +0 -22
  164. package/lib/services/animation.service.d.ts +0 -7
  165. package/lib/services/config.service.d.ts +0 -20
  166. package/lib/services/effect.service.d.ts +0 -8
  167. package/lib/services/error-dialog.service.d.ts +0 -12
  168. package/lib/services/fixture-pool.service.d.ts +0 -10
  169. package/lib/services/fixture.service.d.ts +0 -70
  170. package/lib/services/hotkey-target-exclude.service.d.ts +0 -7
  171. package/lib/services/intro.service.d.ts +0 -21
  172. package/lib/services/preset.service.d.ts +0 -64
  173. package/lib/services/preview-mesh.service.d.ts +0 -14
  174. package/lib/services/preview.service.d.ts +0 -42
  175. package/lib/services/project-load.service.d.ts +0 -36
  176. package/lib/services/project.service.d.ts +0 -26
  177. package/lib/services/scene.service.d.ts +0 -30
  178. package/lib/services/timeline.service.d.ts +0 -70
  179. package/lib/services/user-ensure-login.service.d.ts +0 -14
  180. package/lib/services/user.service.d.ts +0 -22
  181. package/lib/services/uuid.service.d.ts +0 -7
  182. package/lib/services/warning-dialog.service.d.ts +0 -12
  183. package/lib/timeline/composition-settings/composition-settings.component.d.ts +0 -48
  184. package/lib/timeline/timeline-grid/timeline-grid.component.d.ts +0 -22
  185. package/lib/timeline/timeline.component.d.ts +0 -50
  186. package/lib/user/user-login/user-login.component.d.ts +0 -21
  187. package/lib/user/user-register/user-register.component.d.ts +0 -26
  188. package/lib/wait-dialog/wait-dialog.component.d.ts +0 -8
  189. package/lib/warning-dialog/warning-dialog.component.d.ts +0 -16
  190. package/public_api.d.ts +0 -3
  191. package/rocketshow-designer-1.40.0.tgz +0 -0
@@ -1,726 +0,0 @@
1
- import { HttpClient } from '@angular/common/http';
2
- import { Injectable } from '@angular/core';
3
- import { Subject, timer } from 'rxjs';
4
- import { map } from 'rxjs/operators';
5
- import WaveSurfer from 'wavesurfer.js';
6
- import CursorPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.cursor.min.js';
7
- import RegionsPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.regions.min.js';
8
- import TimeLinePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.timeline.min.js';
9
- import { guess } from 'web-audio-beat-detector';
10
- import { PresetRegionScene } from '../models/preset-region-scene';
11
- import { ScenePlaybackRegion } from '../models/scene-playback-region';
12
- import { ConfigService } from './config.service';
13
- import { PresetService } from './preset.service';
14
- import { ProjectService } from './project.service';
15
- import { SceneService } from './scene.service';
16
- import * as i0 from "@angular/core";
17
- import * as i1 from "./scene.service";
18
- import * as i2 from "./preset.service";
19
- import * as i3 from "./project.service";
20
- import * as i4 from "@angular/common/http";
21
- import * as i5 from "./config.service";
22
- export class TimelineService {
23
- constructor(sceneService, presetService, projectService, http, configService) {
24
- this.sceneService = sceneService;
25
- this.presetService = presetService;
26
- this.projectService = projectService;
27
- this.http = http;
28
- this.configService = configService;
29
- this.playState = 'paused';
30
- this.zoom = 0;
31
- this.timelineClicking = false;
32
- this.intensity = 0.2;
33
- this.intensitySelectedScene = 0.4;
34
- this.intensityHighlighted = 0.8;
35
- this.waveSurferReady = new Subject();
36
- this.detectChanges = new Subject();
37
- // can we add new compositions based on an external pool and
38
- // should new compositions not available in this pool be added there?
39
- this.externalCompositionsAvailable = false;
40
- this.loadingAudioFile = false;
41
- this.presetService.previewSelectionChanged.subscribe(() => {
42
- this.selectedPlaybackRegion = undefined;
43
- this.updateRegionSelection();
44
- });
45
- this.sceneService.sceneDeleted.subscribe(() => {
46
- this.redrawAllRegions();
47
- });
48
- this.sceneService.sceneSelected.subscribe(() => {
49
- this.redrawAllRegions();
50
- });
51
- }
52
- redrawAllRegions() {
53
- // remove all regions from wavesurver
54
- if (this.waveSurfer) {
55
- for (const key of Object.keys(this.waveSurfer.regions.list)) {
56
- const region = this.waveSurfer.regions.list[key];
57
- region.remove();
58
- }
59
- }
60
- // draw all regions
61
- this.drawAllRegions();
62
- }
63
- pad(num, size) {
64
- if (!num) {
65
- num = 0;
66
- }
67
- let padded = num.toString();
68
- while (padded.length < size) {
69
- padded = '0' + padded;
70
- }
71
- return padded;
72
- }
73
- msToTime(millis, includeMillis = true) {
74
- const ms = Math.round(millis % 1000);
75
- const seconds = Math.floor(((millis % 360000) % 60000) / 1000);
76
- const minutes = Math.floor((millis % 3600000) / 60000);
77
- if (includeMillis) {
78
- return this.pad(minutes, 2) + ':' + this.pad(seconds, 2) + '.' + this.pad(ms, 3);
79
- }
80
- else {
81
- return this.pad(minutes, 2) + ':' + this.pad(seconds, 2);
82
- }
83
- }
84
- updateCurrentTime() {
85
- if (!this.waveSurfer) {
86
- return;
87
- }
88
- // display the current time
89
- this.currentTime = this.msToTime(this.waveSurfer.getCurrentTime() * 1000);
90
- if (!this.waveSurfer.timeline.drawer) {
91
- return;
92
- }
93
- // draw the current cursor on the timeline
94
- // TODO redrawing the timeline each update is way to expensive.
95
- // maybe as a better solution use an element, like the cursor inside Wavesurfer to
96
- // display the progress?
97
- let x = 0;
98
- const duration = this.waveSurfer.backend.getDuration();
99
- const width = this.waveSurfer.params.fillParent && !this.waveSurfer.params.scrollParent
100
- ? this.waveSurfer.timeline.drawer.getWidth()
101
- : this.waveSurfer.timeline.drawer.wrapper.scrollWidth * this.waveSurfer.params.pixelRatio;
102
- x = (width / duration) * this.waveSurfer.getCurrentTime() - 2;
103
- // update the timeline canvas
104
- this.waveSurfer.timeline.render();
105
- // draw the cursor on the timeline
106
- this.waveSurfer.timeline.canvases.forEach((canvas, i) => {
107
- const leftOffset = i * this.waveSurfer.timeline.maxCanvasWidth;
108
- const ctx = canvas.getContext('2d');
109
- ctx.fillStyle = '#fd7e14';
110
- ctx.beginPath();
111
- ctx.moveTo(x - 12 - leftOffset, 20);
112
- ctx.lineTo(x + 12 - leftOffset, 20);
113
- ctx.lineTo(x - leftOffset, 45);
114
- ctx.fill();
115
- });
116
- }
117
- startTimeUpdater() {
118
- this.stopTimeUpdater();
119
- const timeUpdater = timer(0, 40);
120
- this.timeUpdateSubscription = timeUpdater.subscribe(() => {
121
- this.updateCurrentTime();
122
- });
123
- }
124
- stopTimeUpdater() {
125
- if (this.timeUpdateSubscription) {
126
- this.timeUpdateSubscription.unsubscribe();
127
- }
128
- }
129
- formatTimeCallback(seconds, pxPerSec) {
130
- if (this.selectedComposition.gridType === 'musical') {
131
- return Math.round(seconds / this.selectedComposition.timeSignatureUpper / (60 / this.selectedComposition.beatsPerMinute));
132
- }
133
- else {
134
- // calculate minutes and seconds from seconds count
135
- const minutes = parseInt((seconds / 60), 10);
136
- seconds = parseInt((seconds % 60), 10);
137
- // fill up seconds with zeroes
138
- const secondsStr = seconds < 10 ? '0' + seconds : seconds;
139
- return `${minutes}:${secondsStr}`;
140
- }
141
- }
142
- timeInterval(pxPerSec) {
143
- if (this.selectedComposition.gridType === 'musical') {
144
- const interval = 60 / this.selectedComposition.beatsPerMinute / this.selectedComposition.gridResolution;
145
- if (pxPerSec < 40) {
146
- return interval * 4;
147
- }
148
- else if (pxPerSec < 80) {
149
- return interval * 2;
150
- }
151
- return interval;
152
- }
153
- else {
154
- if (pxPerSec >= 25) {
155
- return 1;
156
- }
157
- else if (pxPerSec * 5 >= 25) {
158
- return 5;
159
- }
160
- else if (pxPerSec * 15 >= 25) {
161
- return 15;
162
- }
163
- return Math.ceil(0.5 / pxPerSec) * 60;
164
- }
165
- }
166
- primaryLabelInterval(pxPerSec) {
167
- if (this.selectedComposition.gridType === 'musical') {
168
- const interval = this.selectedComposition.timeSignatureUpper * this.selectedComposition.gridResolution;
169
- return interval;
170
- }
171
- else {
172
- if (pxPerSec >= 25) {
173
- return 10;
174
- }
175
- else if (pxPerSec * 5 >= 25) {
176
- return 6;
177
- }
178
- else if (pxPerSec * 15 >= 25) {
179
- return 4;
180
- }
181
- return 4;
182
- }
183
- }
184
- secondaryLabelInterval(pxPerSec) {
185
- if (this.selectedComposition.gridType === 'musical') {
186
- return 0;
187
- }
188
- else {
189
- if (pxPerSec >= 25) {
190
- return 5;
191
- }
192
- else if (pxPerSec * 5 >= 25) {
193
- return 2;
194
- }
195
- else if (pxPerSec * 15 >= 25) {
196
- return 2;
197
- }
198
- return 2;
199
- }
200
- }
201
- seeekWithTimeline(e) {
202
- // taken from wavesurfer -> drawer -> handleEvent
203
- const clientX = e.targetTouches ? e.targetTouches[0].clientX : e.clientX;
204
- const bbox = this.waveSurfer.timeline.wrapper.getBoundingClientRect();
205
- const nominalWidth = this.waveSurfer.timeline.drawer.width;
206
- const parentWidth = this.waveSurfer.timeline.drawer.getWidth();
207
- let progress;
208
- if (!this.waveSurfer.timeline.drawer.params.fillParent && nominalWidth < parentWidth) {
209
- progress =
210
- (this.waveSurfer.timeline.drawer.params.rtl ? bbox.right - clientX : clientX - bbox.left) *
211
- (this.waveSurfer.timeline.drawer.params.pixelRatio / nominalWidth) || 0;
212
- if (progress > 1) {
213
- progress = 1;
214
- }
215
- }
216
- else {
217
- progress =
218
- ((this.waveSurfer.timeline.drawer.params.rtl ? bbox.right - clientX : clientX - bbox.left) +
219
- this.waveSurfer.timeline.wrapper.scrollLeft) /
220
- this.waveSurfer.timeline.wrapper.scrollWidth || 0;
221
- }
222
- progress = Math.max(progress, 0);
223
- setTimeout(() => {
224
- this.waveSurfer.seekTo(progress);
225
- this.detectChanges.next();
226
- this.presetService.previewLive(this.selectedComposition.name, Math.round(this.waveSurfer.getCurrentTime() * 1000));
227
- }, 0);
228
- }
229
- applyZoom(zoom) {
230
- if (zoom < 0 || zoom > 200) {
231
- return;
232
- }
233
- this.zoom = zoom;
234
- if (this.waveSurfer) {
235
- setTimeout(() => {
236
- this.waveSurfer.zoom(this.zoom);
237
- this.updateCurrentTime();
238
- }, 0);
239
- }
240
- }
241
- isWaveSurferReady() {
242
- if (!this.waveSurfer) {
243
- return false;
244
- }
245
- if (!this.waveSurfer.isReady) {
246
- return false;
247
- }
248
- return true;
249
- }
250
- addRegion(waveSurferRegion) {
251
- if (!this.isWaveSurferReady()) {
252
- return;
253
- }
254
- if (!this.sceneService.selectedScenes || this.sceneService.selectedScenes.length !== 1) {
255
- return;
256
- }
257
- if (!this.selectedComposition) {
258
- return;
259
- }
260
- const scenePlaybackRegion = new ScenePlaybackRegion();
261
- scenePlaybackRegion.sceneUuid = this.sceneService.selectedScenes[0].uuid;
262
- if (waveSurferRegion) {
263
- scenePlaybackRegion.startMillis = waveSurferRegion.start * 1000;
264
- scenePlaybackRegion.endMillis = waveSurferRegion.end * 1000;
265
- }
266
- else {
267
- scenePlaybackRegion.startMillis = (this.waveSurfer.getDuration() * 1000) / 3;
268
- scenePlaybackRegion.endMillis = ((this.waveSurfer.getDuration() * 1000) / 3) * 2;
269
- }
270
- this.selectedComposition.scenePlaybackRegions.push(scenePlaybackRegion);
271
- this.selectedPlaybackRegion = scenePlaybackRegion;
272
- if (waveSurferRegion) {
273
- waveSurferRegion.color =
274
- 'rgba(' +
275
- this.hexToRgb(this.sceneService.selectedScenes[0].color).r +
276
- ', ' +
277
- this.hexToRgb(this.sceneService.selectedScenes[0].color).g +
278
- ', ' +
279
- this.hexToRgb(this.sceneService.selectedScenes[0].color).b +
280
- ', ' +
281
- this.intensityHighlighted +
282
- ')';
283
- waveSurferRegion.attributes.selectable = true;
284
- this.connectRegion(waveSurferRegion, this.sceneService.selectedScenes[0], scenePlaybackRegion);
285
- this.updateRegionSelection();
286
- }
287
- else {
288
- this.drawRegion(scenePlaybackRegion, this.sceneService.selectedScenes[0]);
289
- }
290
- this.presetService.previewLive();
291
- }
292
- getSnapToGridInterval() {
293
- if (this.selectedComposition.snapToGrid) {
294
- return 60 / this.selectedComposition.beatsPerMinute / this.selectedComposition.gridResolution;
295
- }
296
- return undefined;
297
- }
298
- getSnapToGridOffset() {
299
- return this.selectedComposition.gridOffsetMillis / 1000;
300
- }
301
- deleteSelectedComposition() {
302
- this.projectService.project.compositions.splice(this.selectedCompositionIndex, 1);
303
- this.selectedComposition = undefined;
304
- this.selectedCompositionIndex = undefined;
305
- this.destroyWaveSurfer();
306
- if (this.projectService.project.compositions.length > 0) {
307
- this.selectCompositionIndex(0);
308
- }
309
- }
310
- destroyWaveSurfer() {
311
- this.duration = undefined;
312
- this.loadingAudioFile = false;
313
- if (this.waveSurfer) {
314
- this.waveSurfer.destroy();
315
- this.waveSurfer = undefined;
316
- }
317
- }
318
- createWaveSurfer() {
319
- this.destroyWaveSurfer();
320
- if (!this.selectedComposition.audioFileName) {
321
- return;
322
- }
323
- this.loadingAudioFile = true;
324
- setTimeout(() => {
325
- this.waveSurfer = WaveSurfer.create({
326
- container: '#waveform',
327
- waveColor: 'white',
328
- progressColor: 'white',
329
- // barWidth: 2,
330
- height: 1,
331
- interact: false,
332
- // Use for timelines without sound. Wave will be displayed
333
- // wrong, but should work for a dummy audio without any waves.
334
- // duration: 400,
335
- plugins: [
336
- CursorPlugin.create({
337
- // showTime: true,
338
- opacity: 1,
339
- color: '#fd7e14',
340
- hideOnBlur: false /* don't show/hide the cursor on the wave (only on the timeline) */,
341
- }),
342
- RegionsPlugin.create({
343
- dragSelection: {
344
- slop: 5,
345
- },
346
- color: '#fff',
347
- snapToGridInterval: this.getSnapToGridInterval(),
348
- snapToGridOffset: this.getSnapToGridOffset(),
349
- }),
350
- TimeLinePlugin.create({
351
- container: '#waveform-timeline',
352
- primaryFontColor: '#fff',
353
- secondaryFontColor: '#fff',
354
- offset: this.getSnapToGridOffset(),
355
- formatTimeCallback: this.formatTimeCallback.bind(this),
356
- timeInterval: this.timeInterval.bind(this),
357
- primaryLabelInterval: this.primaryLabelInterval.bind(this),
358
- secondaryLabelInterval: this.secondaryLabelInterval.bind(this),
359
- }),
360
- ],
361
- });
362
- let audioFileName;
363
- if (this.configService.enableMediaLibrary) {
364
- // the file name is also used for the real file name
365
- audioFileName = 'file/get?name=' + this.selectedComposition.audioFileName + '&type=AUDIO';
366
- }
367
- else {
368
- // the composition uuid and extension is used as the file name
369
- audioFileName =
370
- 'composition-files/?file=' +
371
- this.selectedComposition.uuid +
372
- '.' +
373
- this.selectedComposition.audioFileName.substr(this.selectedComposition.audioFileName.lastIndexOf('.') + 1);
374
- }
375
- this.waveSurfer.load(this.configService.restUrl + audioFileName);
376
- this.waveSurfer.on('ready', () => {
377
- setTimeout(() => {
378
- // try guessing the bpm and offset from the file, if necessary
379
- if (this.selectedComposition.tempoGuessed) {
380
- // we already guessed the BPM of this file --> don't do it again
381
- this.loadingAudioFile = false;
382
- }
383
- else {
384
- // we have not yet guessed the BPM --> do it now
385
- this.selectedComposition.tempoGuessed = true;
386
- guess(this.waveSurfer.backend.buffer)
387
- .then(({ bpm, offset }) => {
388
- // the bpm and offset could be guessed
389
- this.selectedComposition.beatsPerMinute = bpm;
390
- this.selectedComposition.gridOffsetMillis = offset * 1000;
391
- this.loadingAudioFile = false;
392
- })
393
- .catch((err) => {
394
- // something went wrong
395
- console.error('Could not detect the BPM from the audio file', err);
396
- this.loadingAudioFile = false;
397
- });
398
- }
399
- this.duration = this.msToTime(this.waveSurfer.getDuration() * 1000);
400
- this.drawAllRegions();
401
- // scroll wavesurfer in sync with the timeline
402
- this.waveSurfer.timeline.wrapper.addEventListener('scroll', () => {
403
- this.waveSurfer.drawer.wrapper.scrollLeft = this.waveSurfer.timeline.wrapper.scrollLeft;
404
- // Set the scroll position of the timeline to the same position as the wavesurfer,
405
- // because the timeline is larger than wavesurfer and might get out of sync.
406
- // This way, if wavesurfer cannot scroll any further, we reset the position
407
- // of the timeline as well.
408
- this.waveSurfer.timeline.wrapper.scrollLeft = this.waveSurfer.drawer.wrapper.scrollLeft;
409
- });
410
- // display the cursor also on the timeline
411
- this.waveSurfer.timeline.wrapper.addEventListener('mouseenter', () => {
412
- this.waveSurfer.cursor.showCursor();
413
- });
414
- this.waveSurfer.timeline.wrapper.addEventListener('mouseleave', () => {
415
- this.waveSurfer.cursor.hideCursor();
416
- });
417
- this.waveSurfer.timeline.wrapper.addEventListener('mousemove', (e) => {
418
- const bbox = this.waveSurfer.container.getBoundingClientRect();
419
- const x = e.clientX - bbox.left;
420
- this.waveSurfer.cursor.updateCursorPosition(x, 0);
421
- });
422
- // hide the cursor on the wave initially. in combination with the param hideOnBlur = false,
423
- // it will never be displayed on the wave now. we handle it on the timeline only.
424
- this.waveSurfer.cursor.hideCursor();
425
- // seek on timeline-click
426
- this.waveSurfer.timeline.wrapper.addEventListener('mousedown', (e) => {
427
- this.timelineClicking = true;
428
- this.seeekWithTimeline(e);
429
- });
430
- this.waveSurfer.timeline.wrapper.addEventListener('mousemove', (e) => {
431
- if (this.timelineClicking) {
432
- this.seeekWithTimeline(e);
433
- }
434
- });
435
- this.waveSurfer.timeline.wrapper.addEventListener('mouseup', (e) => {
436
- this.timelineClicking = false;
437
- });
438
- this.updateCurrentTime();
439
- this.detectChanges.next();
440
- this.waveSurferReady.next();
441
- }, 0);
442
- });
443
- this.waveSurfer.on('error', (error) => {
444
- // could not load the composition --> delete it
445
- // (this may occur, when the composition has been deleted but the project is not saved afterwards)
446
- this.deleteSelectedComposition();
447
- });
448
- this.waveSurfer.on('seek', () => {
449
- this.updateCurrentTime();
450
- });
451
- this.waveSurfer.on('play', () => {
452
- this.startTimeUpdater();
453
- });
454
- this.waveSurfer.on('pause', () => {
455
- this.stopTimeUpdater();
456
- });
457
- this.waveSurfer.on('region-created', (region) => {
458
- // region created by selection or programmatically
459
- if (this.sceneService.selectedScenes && this.sceneService.selectedScenes.length === 1) {
460
- if (!region.data.handled) {
461
- this.addRegion(region);
462
- }
463
- }
464
- else {
465
- if (!region.data.handled) {
466
- region.remove();
467
- }
468
- }
469
- });
470
- this.waveSurfer.on('region-updated', (region) => {
471
- this.detectChanges.next();
472
- this.presetService.previewLive();
473
- });
474
- }, 0);
475
- }
476
- hexToRgb(hex) {
477
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
478
- return result
479
- ? {
480
- r: parseInt(result[1], 16),
481
- g: parseInt(result[2], 16),
482
- b: parseInt(result[3], 16),
483
- }
484
- : null;
485
- }
486
- updateRegionSelection() {
487
- if (!this.waveSurfer) {
488
- return;
489
- }
490
- for (const key of Object.keys(this.waveSurfer.regions.list)) {
491
- const region = this.waveSurfer.regions.list[key];
492
- // if no scene is set, the region is not valid (e.g. has been created, while
493
- // no scene has been selected and remove did not work properly)
494
- if (region.scene) {
495
- let intensity = this.intensity;
496
- region.drag = false;
497
- region.resize = false;
498
- region.attributes.selectable = false;
499
- if (this.sceneService.sceneIsSelected(region.scene)) {
500
- intensity = this.intensitySelectedScene;
501
- region.drag = true;
502
- region.resize = true;
503
- region.attributes.selectable = true;
504
- }
505
- region.attributes.selected = false;
506
- if (this.selectedPlaybackRegion && this.selectedPlaybackRegion === region.scenePlaybackRegion) {
507
- intensity = this.intensityHighlighted;
508
- region.attributes.selected = true;
509
- }
510
- region.color =
511
- 'rgba(' +
512
- this.hexToRgb(region.scene.color).r +
513
- ', ' +
514
- this.hexToRgb(region.scene.color).g +
515
- ', ' +
516
- this.hexToRgb(region.scene.color).b +
517
- ', ' +
518
- intensity +
519
- ')';
520
- region.updateRender();
521
- }
522
- }
523
- }
524
- updateSelectedRegion() {
525
- if (!this.waveSurfer) {
526
- return;
527
- }
528
- if (!this.selectedPlaybackRegion) {
529
- return;
530
- }
531
- for (const key of Object.keys(this.waveSurfer.regions.list)) {
532
- const region = this.waveSurfer.regions.list[key];
533
- if (this.selectedPlaybackRegion === region.scenePlaybackRegion) {
534
- region.start = this.selectedPlaybackRegion.startMillis / 1000;
535
- region.end = this.selectedPlaybackRegion.endMillis / 1000;
536
- region.updateRender();
537
- break;
538
- }
539
- }
540
- }
541
- setSelectedRegion(scenePlaybackRegion) {
542
- if (this.selectedPlaybackRegion && this.selectedPlaybackRegion === scenePlaybackRegion) {
543
- // No update required
544
- return;
545
- }
546
- if (scenePlaybackRegion) {
547
- this.selectedPlaybackRegion = scenePlaybackRegion;
548
- }
549
- this.updateRegionSelection();
550
- }
551
- getRegionSnapToGridValue(value) {
552
- // the regions should snap to a grid
553
- const offset = this.getSnapToGridOffset() || 0;
554
- const interval = this.getSnapToGridInterval() || 0;
555
- return Math.round((value - offset) / interval) * interval + offset;
556
- }
557
- connectRegion(waveSurferRegion, scene, scenePlaybackRegion, preset) {
558
- waveSurferRegion.scenePlaybackRegion = scenePlaybackRegion;
559
- waveSurferRegion.scene = scene;
560
- waveSurferRegion.preset = preset;
561
- waveSurferRegion.on('click', (event) => {
562
- if (this.sceneService.sceneIsSelected(scene)) {
563
- this.setSelectedRegion(scenePlaybackRegion);
564
- }
565
- });
566
- waveSurferRegion.on('update', () => {
567
- this.setSelectedRegion(scenePlaybackRegion);
568
- if (this.selectedComposition.snapToGrid) {
569
- // update the regions boundaries. they may not snap to grid, if it has been
570
- // disabled during creation of the region but activated afterwards.
571
- waveSurferRegion.start = this.getRegionSnapToGridValue(waveSurferRegion.start);
572
- waveSurferRegion.end = this.getRegionSnapToGridValue(waveSurferRegion.end);
573
- }
574
- scenePlaybackRegion.startMillis = waveSurferRegion.start * 1000;
575
- scenePlaybackRegion.endMillis = waveSurferRegion.end * 1000;
576
- });
577
- }
578
- drawRegion(scenePlaybackRegion, scene) {
579
- // draw the regions of the currently selected scene
580
- if (!this.isWaveSurferReady()) {
581
- return;
582
- }
583
- // add the playback region
584
- const waveSurferRegion = this.waveSurfer.addRegion({
585
- start: scenePlaybackRegion.startMillis / 1000,
586
- end: scenePlaybackRegion.endMillis / 1000,
587
- color: '#fff',
588
- data: { handled: true },
589
- });
590
- this.connectRegion(waveSurferRegion, scene, scenePlaybackRegion);
591
- // TODO show the all presets
592
- // for (let presetUuid of scene.presetUuids) {
593
- // const preset = this.presetService.getPresetByUuid(presetUuid);
594
- // let waveSurferRegion = this.timelineService.waveSurfer.addRegion({
595
- // start: (scenePlaybackRegion.startMillis + (preset.startMillis ? preset.startMillis : 0)) / 1000,
596
- // end: (scenePlaybackRegion.startMillis
597
- // + (preset.endMillis ? preset.endMillis : scenePlaybackRegion.endMillis - scenePlaybackRegion.startMillis)) / 1000,
598
- // color: '#fff',
599
- // data: { handled: true },
600
- // // TODO
601
- // attributes: {
602
- // preset: true,
603
- // name: 'Preset 1'
604
- // }
605
- // });
606
- // this.connectRegion(waveSurferRegion, scene, scenePlaybackRegion, preset);
607
- // }
608
- this.updateRegionSelection();
609
- }
610
- removeRegion() {
611
- if (!this.selectedPlaybackRegion) {
612
- return;
613
- }
614
- if (this.sceneService.selectedScenes.length !== 1) {
615
- return;
616
- }
617
- for (let i = 0; i < this.selectedComposition.scenePlaybackRegions.length; i++) {
618
- if (this.selectedComposition.scenePlaybackRegions[i] === this.selectedPlaybackRegion) {
619
- // remove the region from wavesurfer
620
- for (const key of Object.keys(this.waveSurfer.regions.list)) {
621
- const region = this.waveSurfer.regions.list[key];
622
- if (region.scenePlaybackRegion === this.selectedPlaybackRegion) {
623
- region.remove();
624
- }
625
- }
626
- this.selectedPlaybackRegion = undefined;
627
- this.selectedComposition.scenePlaybackRegions.splice(i, 1);
628
- return;
629
- }
630
- }
631
- this.presetService.previewLive();
632
- }
633
- getPresetsInTime(timeMillis) {
634
- // Return all presets which should be active during the specified time
635
- const activePresets = [];
636
- for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
637
- const scene = this.projectService.project.scenes[sceneIndex];
638
- for (const region of this.selectedComposition.scenePlaybackRegions) {
639
- if (region.sceneUuid === scene.uuid) {
640
- for (let presetIndex = this.projectService.project.presets.length - 1; presetIndex >= 0; presetIndex--) {
641
- for (const presetUuid of scene.presetUuids) {
642
- if (presetUuid === this.projectService.project.presets[presetIndex].uuid) {
643
- const preset = this.presetService.getPresetByUuid(presetUuid);
644
- if (preset) {
645
- let presetStartMillis = preset.startMillis === undefined ? region.startMillis : region.startMillis + preset.startMillis;
646
- let presetEndMillis = preset.endMillis === undefined ? region.endMillis : region.startMillis + preset.endMillis;
647
- // extend the running time, if fading is done outside the boundaries
648
- presetStartMillis -= preset.fadeInPre ? preset.fadeInMillis : 0;
649
- presetEndMillis += preset.fadeOutPost ? preset.fadeOutMillis : 0;
650
- if (presetStartMillis <= timeMillis && presetEndMillis >= timeMillis) {
651
- activePresets.push(new PresetRegionScene(preset, region, scene));
652
- }
653
- }
654
- }
655
- }
656
- }
657
- }
658
- }
659
- }
660
- return activePresets;
661
- }
662
- drawAllRegions() {
663
- if (!this.selectedComposition) {
664
- return;
665
- }
666
- // draw the regions in the same order as their corresponding scenes, but draw
667
- // the selected ones last, to make sure they're always clickable.
668
- for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
669
- const scene = this.projectService.project.scenes[sceneIndex];
670
- if (!this.sceneService.sceneIsSelected(scene)) {
671
- for (const scenePlaybackRegion of this.selectedComposition.scenePlaybackRegions) {
672
- if (scenePlaybackRegion.sceneUuid === scene.uuid) {
673
- this.drawRegion(scenePlaybackRegion, scene);
674
- }
675
- }
676
- }
677
- }
678
- // draw all selected scenes afterwards
679
- for (let sceneIndex = this.projectService.project.scenes.length - 1; sceneIndex >= 0; sceneIndex--) {
680
- const scene = this.projectService.project.scenes[sceneIndex];
681
- if (this.sceneService.sceneIsSelected(scene)) {
682
- for (const scenePlaybackRegion of this.selectedComposition.scenePlaybackRegions) {
683
- if (scenePlaybackRegion.sceneUuid === scene.uuid) {
684
- this.drawRegion(scenePlaybackRegion, scene);
685
- }
686
- }
687
- }
688
- }
689
- }
690
- updateGrid() {
691
- if (this.waveSurferReady) {
692
- this.waveSurfer.timeline.params.offset = this.getSnapToGridOffset();
693
- this.waveSurfer.regions.params.snapToGridInterval = this.getSnapToGridInterval();
694
- this.waveSurfer.regions.params.snapToGridOffset = this.getSnapToGridOffset();
695
- }
696
- this.updateCurrentTime();
697
- }
698
- getExternalCompositionNames() {
699
- // get available compositions from an external pool (e.g. Rocket Show)
700
- return this.http.get('composition/list').pipe(map((response) => {
701
- const compositionNames = [];
702
- for (const responseComposition of response) {
703
- compositionNames.push(responseComposition.name);
704
- }
705
- return compositionNames;
706
- }));
707
- }
708
- selectCompositionIndex(index) {
709
- this.selectedComposition = this.projectService.project.compositions[index];
710
- this.selectedCompositionIndex = index;
711
- this.projectService.project.selectedCompositionUuid = this.selectedComposition.uuid;
712
- this.createWaveSurfer();
713
- // required to trigger timeline.component.resize()
714
- this.waveSurferReady.next();
715
- this.applyZoom(0);
716
- }
717
- static { this.ɵfac = function TimelineService_Factory(t) { return new (t || TimelineService)(i0.ɵɵinject(i1.SceneService), i0.ɵɵinject(i2.PresetService), i0.ɵɵinject(i3.ProjectService), i0.ɵɵinject(i4.HttpClient), i0.ɵɵinject(i5.ConfigService)); }; }
718
- static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TimelineService, factory: TimelineService.ɵfac, providedIn: 'root' }); }
719
- }
720
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TimelineService, [{
721
- type: Injectable,
722
- args: [{
723
- providedIn: 'root',
724
- }]
725
- }], () => [{ type: i1.SceneService }, { type: i2.PresetService }, { type: i3.ProjectService }, { type: i4.HttpClient }, { type: i5.ConfigService }], null); })();
726
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbmVyL3NyYy9saWIvc2VydmljZXMvdGltZWxpbmUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsT0FBTyxFQUFnQixLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sVUFBVSxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLFlBQVksTUFBTSxvREFBb0QsQ0FBQztBQUM5RSxPQUFPLGFBQWEsTUFBTSxxREFBcUQsQ0FBQztBQUNoRixPQUFPLGNBQWMsTUFBTSxzREFBc0QsQ0FBQztBQUNsRixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHaEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7O0FBSy9DLE1BQU0sT0FBTyxlQUFlO0lBMEIxQixZQUNVLFlBQTBCLEVBQzFCLGFBQTRCLEVBQzVCLGNBQThCLEVBQzlCLElBQWdCLEVBQ2hCLGFBQTRCO1FBSjVCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FB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QyxLQUFLLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsS0FBSyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7UUFDcEYsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixDQUFDO2dGQXh6QlUsZUFBZTt1RUFBZixlQUFlLFdBQWYsZUFBZSxtQkFGZCxNQUFNOztpRkFFUCxlQUFlO2NBSDNCLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgV2F2ZVN1cmZlciBmcm9tICd3YXZlc3VyZmVyLmpzJztcbmltcG9ydCBDdXJzb3JQbHVnaW4gZnJvbSAnd2F2ZXN1cmZlci5qcy9kaXN0L3BsdWdpbi93YXZlc3VyZmVyLmN1cnNvci5taW4uanMnO1xuaW1wb3J0IFJlZ2lvbnNQbHVnaW4gZnJvbSAnd2F2ZXN1cmZlci5qcy9kaXN0L3BsdWdpbi93YXZlc3VyZmVyLnJlZ2lvbnMubWluLmpzJztcbmltcG9ydCBUaW1lTGluZVBsdWdpbiBmcm9tICd3YXZlc3VyZmVyLmpzL2Rpc3QvcGx1Z2luL3dhdmVzdXJmZXIudGltZWxpbmUubWluLmpzJztcbmltcG9ydCB7IGd1ZXNzIH0gZnJvbSAnd2ViLWF1ZGlvLWJlYXQtZGV0ZWN0b3InO1xuaW1wb3J0IHsgQ29tcG9zaXRpb24gfSBmcm9tICcuLi9tb2RlbHMvY29tcG9zaXRpb24nO1xuaW1wb3J0IHsgUHJlc2V0IH0gZnJvbSAnLi4vbW9kZWxzL3ByZXNldCc7XG5pbXBvcnQgeyBQcmVzZXRSZWdpb25TY2VuZSB9IGZyb20gJy4uL21vZGVscy9wcmVzZXQtcmVnaW9uLXNjZW5lJztcbmltcG9ydCB7IFNjZW5lIH0gZnJvbSAnLi4vbW9kZWxzL3NjZW5lJztcbmltcG9ydCB7IFNjZW5lUGxheWJhY2tSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvc2NlbmUtcGxheWJhY2stcmVnaW9uJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL2NvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7IFByZXNldFNlcnZpY2UgfSBmcm9tICcuL3ByZXNldC5zZXJ2aWNlJztcbmltcG9ydCB7IFByb2plY3RTZXJ2aWNlIH0gZnJvbSAnLi9wcm9qZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgU2NlbmVTZXJ2aWNlIH0gZnJvbSAnLi9zY2VuZS5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFRpbWVsaW5lU2VydmljZSB7XG4gIHB1YmxpYyB3YXZlU3VyZmVyOiBXYXZlU3VyZmVyO1xuICBwdWJsaWMgcGxheVN0YXRlID0gJ3BhdXNlZCc7XG5cbiAgcHVibGljIHpvb20gPSAwO1xuICBwcml2YXRlIHRpbWVVcGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHVibGljIGN1cnJlbnRUaW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZWxpbmVDbGlja2luZyA9IGZhbHNlO1xuICBwdWJsaWMgc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbjogU2NlbmVQbGF5YmFja1JlZ2lvbjtcbiAgcHJpdmF0ZSBpbnRlbnNpdHkgPSAwLjI7XG4gIHByaXZhdGUgaW50ZW5zaXR5U2VsZWN0ZWRTY2VuZSA9IDAuNDtcbiAgcHJpdmF0ZSBpbnRlbnNpdHlIaWdobGlnaHRlZCA9IDAuODtcbiAgcHVibGljIGR1cmF0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyB3YXZlU3VyZmVyUmVhZHk6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuICBwdWJsaWMgZGV0ZWN0Q2hhbmdlczogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgLy8gdGhlIGN1cnJlbnQgY29tcG9zaXRpb25cbiAgcHVibGljIHNlbGVjdGVkQ29tcG9zaXRpb246IENvbXBvc2l0aW9uO1xuICBwdWJsaWMgc2VsZWN0ZWRDb21wb3NpdGlvbkluZGV4OiBudW1iZXI7XG5cbiAgLy8gY2FuIHdlIGFkZCBuZXcgY29tcG9zaXRpb25zIGJhc2VkIG9uIGFuIGV4dGVybmFsIHBvb2wgYW5kXG4gIC8vIHNob3VsZCBuZXcgY29tcG9zaXRpb25zIG5vdCBhdmFpbGFibGUgaW4gdGhpcyBwb29sIGJlIGFkZGVkIHRoZXJlP1xuICBwdWJsaWMgZXh0ZXJuYWxDb21wb3NpdGlvbnNBdmFpbGFibGUgPSBmYWxzZTtcblxuICBwdWJsaWMgbG9hZGluZ0F1ZGlvRmlsZSA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2NlbmVTZXJ2aWNlOiBTY2VuZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwcmVzZXRTZXJ2aWNlOiBQcmVzZXRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcHJvamVjdFNlcnZpY2U6IFByb2plY3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICBwcml2YXRlIGNvbmZpZ1NlcnZpY2U6IENvbmZpZ1NlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdTZWxlY3Rpb25DaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnVwZGF0ZVJlZ2lvblNlbGVjdGlvbigpO1xuICAgIH0pO1xuICAgIHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lRGVsZXRlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWRyYXdBbGxSZWdpb25zKCk7XG4gICAgfSk7XG4gICAgdGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVTZWxlY3RlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWRyYXdBbGxSZWdpb25zKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlZHJhd0FsbFJlZ2lvbnMoKSB7XG4gICAgLy8gcmVtb3ZlIGFsbCByZWdpb25zIGZyb20gd2F2ZXN1cnZlclxuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lvbjogYW55ID0gdGhpcy53YXZlU3VyZmVyLnJlZ2lvbnMubGlzdFtrZXldO1xuICAgICAgICByZWdpb24ucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZHJhdyBhbGwgcmVnaW9uc1xuICAgIHRoaXMuZHJhd0FsbFJlZ2lvbnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFkKG51bTogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmICghbnVtKSB7XG4gICAgICBudW0gPSAwO1xuICAgIH1cblxuICAgIGxldCBwYWRkZWQ6IHN0cmluZyA9IG51bS50b1N0cmluZygpO1xuICAgIHdoaWxlIChwYWRkZWQubGVuZ3RoIDwgc2l6ZSkge1xuICAgICAgcGFkZGVkID0gJzAnICsgcGFkZGVkO1xuICAgIH1cblxuICAgIHJldHVybiBwYWRkZWQ7XG4gIH1cblxuICBwcml2YXRlIG1zVG9UaW1lKG1pbGxpczogbnVtYmVyLCBpbmNsdWRlTWlsbGlzOiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgbXM6IG51bWJlciA9IE1hdGgucm91bmQobWlsbGlzICUgMTAwMCk7XG4gICAgY29uc3Qgc2Vjb25kczogbnVtYmVyID0gTWF0aC5mbG9vcigoKG1pbGxpcyAlIDM2MDAwMCkgJSA2MDAwMCkgLyAxMDAwKTtcbiAgICBjb25zdCBtaW51dGVzOiBudW1iZXIgPSBNYXRoLmZsb29yKChtaWxsaXMgJSAzNjAwMDAwKSAvIDYwMDAwKTtcblxuICAgIGlmIChpbmNsdWRlTWlsbGlzKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYWQobWludXRlcywgMikgKyAnOicgKyB0aGlzLnBhZChzZWNvbmRzLCAyKSArICcuJyArIHRoaXMucGFkKG1zLCAzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucGFkKG1pbnV0ZXMsIDIpICsgJzonICsgdGhpcy5wYWQoc2Vjb25kcywgMik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50VGltZSgpIHtcbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRpc3BsYXkgdGhlIGN1cnJlbnQgdGltZVxuICAgIHRoaXMuY3VycmVudFRpbWUgPSB0aGlzLm1zVG9UaW1lKHRoaXMud2F2ZVN1cmZlci5nZXRDdXJyZW50VGltZSgpICogMTAwMCk7XG5cbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkcmF3IHRoZSBjdXJyZW50IGN1cnNvciBvbiB0aGUgdGltZWxpbmVcbiAgICAvLyBUT0RPIHJlZHJhd2luZyB0aGUgdGltZWxpbmUgZWFjaCB1cGRhdGUgaXMgd2F5IHRvIGV4cGVuc2l2ZS5cbiAgICAvLyBtYXliZSBhcyBhIGJldHRlciBzb2x1dGlvbiB1c2UgYW4gZWxlbWVudCwgbGlrZSB0aGUgY3Vyc29yIGluc2lkZSBXYXZlc3VyZmVyIHRvXG4gICAgLy8gZGlzcGxheSB0aGUgcHJvZ3Jlc3M/XG4gICAgbGV0IHggPSAwO1xuICAgIGNvbnN0IGR1cmF0aW9uOiBudW1iZXIgPSB0aGlzLndhdmVTdXJmZXIuYmFja2VuZC5nZXREdXJhdGlvbigpO1xuICAgIGNvbnN0IHdpZHRoOiBudW1iZXIgPVxuICAgICAgdGhpcy53YXZlU3VyZmVyLnBhcmFtcy5maWxsUGFyZW50ICYmICF0aGlzLndhdmVTdXJmZXIucGFyYW1zLnNjcm9sbFBhcmVudFxuICAgICAgICA/IHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIuZ2V0V2lkdGgoKVxuICAgICAgICA6IHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIud3JhcHBlci5zY3JvbGxXaWR0aCAqIHRoaXMud2F2ZVN1cmZlci5wYXJhbXMucGl4ZWxSYXRpbztcblxuICAgIHggPSAod2lkdGggLyBkdXJhdGlvbikgKiB0aGlzLndhdmVTdXJmZXIuZ2V0Q3VycmVudFRpbWUoKSAtIDI7XG5cbiAgICAvLyB1cGRhdGUgdGhlIHRpbWVsaW5lIGNhbnZhc1xuICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5yZW5kZXIoKTtcblxuICAgIC8vIGRyYXcgdGhlIGN1cnNvciBvbiB0aGUgdGltZWxpbmVcbiAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuY2FudmFzZXMuZm9yRWFjaCgoY2FudmFzLCBpKSA9PiB7XG4gICAgICBjb25zdCBsZWZ0T2Zmc2V0ID0gaSAqIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5tYXhDYW52YXNXaWR0aDtcblxuICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICAgIGN0eC5maWxsU3R5bGUgPSAnI2ZkN2UxNCc7XG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHgubW92ZVRvKHggLSAxMiAtIGxlZnRPZmZzZXQsIDIwKTtcbiAgICAgIGN0eC5saW5lVG8oeCArIDEyIC0gbGVmdE9mZnNldCwgMjApO1xuICAgICAgY3R4LmxpbmVUbyh4IC0gbGVmdE9mZnNldCwgNDUpO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUaW1lVXBkYXRlcigpIHtcbiAgICB0aGlzLnN0b3BUaW1lVXBkYXRlcigpO1xuXG4gICAgY29uc3QgdGltZVVwZGF0ZXIgPSB0aW1lcigwLCA0MCk7XG4gICAgdGhpcy50aW1lVXBkYXRlU3Vic2NyaXB0aW9uID0gdGltZVVwZGF0ZXIuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudFRpbWUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFRpbWVVcGRhdGVyKCkge1xuICAgIGlmICh0aGlzLnRpbWVVcGRhdGVTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudGltZVVwZGF0ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdFRpbWVDYWxsYmFjayhzZWNvbmRzOiBudW1iZXIsIHB4UGVyU2VjOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRUeXBlID09PSAnbXVzaWNhbCcpIHtcbiAgICAgIHJldHVybiBNYXRoLnJvdW5kKHNlY29uZHMgLyB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24udGltZVNpZ25hdHVyZVVwcGVyIC8gKDYwIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmJlYXRzUGVyTWludXRlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNhbGN1bGF0ZSBtaW51dGVzIGFuZCBzZWNvbmRzIGZyb20gc2Vjb25kcyBjb3VudFxuICAgICAgY29uc3QgbWludXRlcyA9IHBhcnNlSW50KChzZWNvbmRzIC8gNjApIGFzIGFueSwgMTApO1xuICAgICAgc2Vjb25kcyA9IHBhcnNlSW50KChzZWNvbmRzICUgNjApIGFzIGFueSwgMTApO1xuXG4gICAgICAvLyBmaWxsIHVwIHNlY29uZHMgd2l0aCB6ZXJvZXNcbiAgICAgIGNvbnN0IHNlY29uZHNTdHIgPSBzZWNvbmRzIDwgMTAgPyAnMCcgKyBzZWNvbmRzIDogc2Vjb25kcztcbiAgICAgIHJldHVybiBgJHttaW51dGVzfToke3NlY29uZHNTdHJ9YDtcbiAgICB9XG4gIH1cblxuICB0aW1lSW50ZXJ2YWwocHhQZXJTZWM6IG51bWJlcikge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZFR5cGUgPT09ICdtdXNpY2FsJykge1xuICAgICAgY29uc3QgaW50ZXJ2YWwgPSA2MCAvIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5iZWF0c1Blck1pbnV0ZSAvIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5ncmlkUmVzb2x1dGlvbjtcblxuICAgICAgaWYgKHB4UGVyU2VjIDwgNDApIHtcbiAgICAgICAgcmV0dXJuIGludGVydmFsICogNDtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgPCA4MCkge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWwgKiAyO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaW50ZXJ2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChweFBlclNlYyA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiA1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA1O1xuICAgICAgfSBlbHNlIGlmIChweFBlclNlYyAqIDE1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiAxNTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE1hdGguY2VpbCgwLjUgLyBweFBlclNlYykgKiA2MDtcbiAgICB9XG4gIH1cblxuICBwcmltYXJ5TGFiZWxJbnRlcnZhbChweFBlclNlYzogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5ncmlkVHlwZSA9PT0gJ211c2ljYWwnKSB7XG4gICAgICBjb25zdCBpbnRlcnZhbCA9IHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi50aW1lU2lnbmF0dXJlVXBwZXIgKiB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZFJlc29sdXRpb247XG5cbiAgICAgIHJldHVybiBpbnRlcnZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHB4UGVyU2VjID49IDI1KSB7XG4gICAgICAgIHJldHVybiAxMDtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiA1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA2O1xuICAgICAgfSBlbHNlIGlmIChweFBlclNlYyAqIDE1ID49IDI1KSB7XG4gICAgICAgIHJldHVybiA0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gNDtcbiAgICB9XG4gIH1cblxuICBzZWNvbmRhcnlMYWJlbEludGVydmFsKHB4UGVyU2VjOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRUeXBlID09PSAnbXVzaWNhbCcpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocHhQZXJTZWMgPj0gMjUpIHtcbiAgICAgICAgcmV0dXJuIDU7XG4gICAgICB9IGVsc2UgaWYgKHB4UGVyU2VjICogNSA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMjtcbiAgICAgIH0gZWxzZSBpZiAocHhQZXJTZWMgKiAxNSA+PSAyNSkge1xuICAgICAgICByZXR1cm4gMjtcbiAgICAgIH1cbiAgICAgIHJldHVybiAyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2VlZWtXaXRoVGltZWxpbmUoZTogYW55KSB7XG4gICAgLy8gdGFrZW4gZnJvbSB3YXZlc3VyZmVyIC0+IGRyYXdlciAtPiBoYW5kbGVFdmVudFxuICAgIGNvbnN0IGNsaWVudFggPSBlLnRhcmdldFRvdWNoZXMgPyBlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WCA6IGUuY2xpZW50WDtcbiAgICBjb25zdCBiYm94ID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBub21pbmFsV2lkdGggPSB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuZHJhd2VyLndpZHRoO1xuICAgIGNvbnN0IHBhcmVudFdpZHRoID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLmRyYXdlci5nZXRXaWR0aCgpO1xuXG4gICAgbGV0IHByb2dyZXNzOiBudW1iZXI7XG5cbiAgICBpZiAoIXRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLmZpbGxQYXJlbnQgJiYgbm9taW5hbFdpZHRoIDwgcGFyZW50V2lkdGgpIHtcbiAgICAgIHByb2dyZXNzID1cbiAgICAgICAgKHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLnJ0bCA/IGJib3gucmlnaHQgLSBjbGllbnRYIDogY2xpZW50WCAtIGJib3gubGVmdCkgKlxuICAgICAgICAgICh0aGlzLndhdmVTdXJmZXIudGltZWxpbmUuZHJhd2VyLnBhcmFtcy5waXhlbFJhdGlvIC8gbm9taW5hbFdpZHRoKSB8fCAwO1xuXG4gICAgICBpZiAocHJvZ3Jlc3MgPiAxKSB7XG4gICAgICAgIHByb2dyZXNzID0gMTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcHJvZ3Jlc3MgPVxuICAgICAgICAoKHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS5kcmF3ZXIucGFyYW1zLnJ0bCA/IGJib3gucmlnaHQgLSBjbGllbnRYIDogY2xpZW50WCAtIGJib3gubGVmdCkgK1xuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLnNjcm9sbExlZnQpIC9cbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5zY3JvbGxXaWR0aCB8fCAwO1xuICAgIH1cblxuICAgIHByb2dyZXNzID0gTWF0aC5tYXgocHJvZ3Jlc3MsIDApO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhdmVTdXJmZXIuc2Vla1RvKHByb2dyZXNzKTtcbiAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcy5uZXh0KCk7XG4gICAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLm5hbWUsIE1hdGgucm91bmQodGhpcy53YXZlU3VyZmVyLmdldEN1cnJlbnRUaW1lKCkgKiAxMDAwKSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBhcHBseVpvb20oem9vbTogYW55KSB7XG4gICAgaWYgKHpvb20gPCAwIHx8IHpvb20gPiAyMDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnpvb20gPSB6b29tO1xuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLndhdmVTdXJmZXIuem9vbSh0aGlzLnpvb20pO1xuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzV2F2ZVN1cmZlclJlYWR5KCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy53YXZlU3VyZmVyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIuaXNSZWFkeSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYWRkUmVnaW9uKHdhdmVTdXJmZXJSZWdpb24/OiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuaXNXYXZlU3VyZmVyUmVhZHkoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXMgfHwgdGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBsYXliYWNrUmVnaW9uOiBTY2VuZVBsYXliYWNrUmVnaW9uID0gbmV3IFNjZW5lUGxheWJhY2tSZWdpb24oKTtcbiAgICBzY2VuZVBsYXliYWNrUmVnaW9uLnNjZW5lVXVpZCA9IHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLnV1aWQ7XG5cbiAgICBpZiAod2F2ZVN1cmZlclJlZ2lvbikge1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyA9IHdhdmVTdXJmZXJSZWdpb24uc3RhcnQgKiAxMDAwO1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgPSB3YXZlU3VyZmVyUmVnaW9uLmVuZCAqIDEwMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjZW5lUGxheWJhY2tSZWdpb24uc3RhcnRNaWxsaXMgPSAodGhpcy53YXZlU3VyZmVyLmdldER1cmF0aW9uKCkgKiAxMDAwKSAvIDM7XG4gICAgICBzY2VuZVBsYXliYWNrUmVnaW9uLmVuZE1pbGxpcyA9ICgodGhpcy53YXZlU3VyZmVyLmdldER1cmF0aW9uKCkgKiAxMDAwKSAvIDMpICogMjtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc2NlbmVQbGF5YmFja1JlZ2lvbnMucHVzaChzY2VuZVBsYXliYWNrUmVnaW9uKTtcblxuICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHNjZW5lUGxheWJhY2tSZWdpb247XG5cbiAgICBpZiAod2F2ZVN1cmZlclJlZ2lvbikge1xuICAgICAgd2F2ZVN1cmZlclJlZ2lvbi5jb2xvciA9XG4gICAgICAgICdyZ2JhKCcgK1xuICAgICAgICB0aGlzLmhleFRvUmdiKHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLmNvbG9yKS5yICtcbiAgICAgICAgJywgJyArXG4gICAgICAgIHRoaXMuaGV4VG9SZ2IodGhpcy5zY2VuZVNlcnZpY2Uuc2VsZWN0ZWRTY2VuZXNbMF0uY29sb3IpLmcgK1xuICAgICAgICAnLCAnICtcbiAgICAgICAgdGhpcy5oZXhUb1JnYih0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lc1swXS5jb2xvcikuYiArXG4gICAgICAgICcsICcgK1xuICAgICAgICB0aGlzLmludGVuc2l0eUhpZ2hsaWdodGVkICtcbiAgICAgICAgJyknO1xuICAgICAgd2F2ZVN1cmZlclJlZ2lvbi5hdHRyaWJ1dGVzLnNlbGVjdGFibGUgPSB0cnVlO1xuICAgICAgdGhpcy5jb25uZWN0UmVnaW9uKHdhdmVTdXJmZXJSZWdpb24sIHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzWzBdLCBzY2VuZVBsYXliYWNrUmVnaW9uKTtcbiAgICAgIHRoaXMudXBkYXRlUmVnaW9uU2VsZWN0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZHJhd1JlZ2lvbihzY2VuZVBsYXliYWNrUmVnaW9uLCB0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lc1swXSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldFNuYXBUb0dyaWRJbnRlcnZhbCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc25hcFRvR3JpZCkge1xuICAgICAgcmV0dXJuIDYwIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmJlYXRzUGVyTWludXRlIC8gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRSZXNvbHV0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldFNuYXBUb0dyaWRPZmZzZXQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmdyaWRPZmZzZXRNaWxsaXMgLyAxMDAwO1xuICB9XG5cbiAgZGVsZXRlU2VsZWN0ZWRDb21wb3NpdGlvbigpIHtcbiAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuY29tcG9zaXRpb25zLnNwbGljZSh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb25JbmRleCwgMSk7XG4gICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbkluZGV4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZGVzdHJveVdhdmVTdXJmZXIoKTtcbiAgICBpZiAodGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LmNvbXBvc2l0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNlbGVjdENvbXBvc2l0aW9uSW5kZXgoMCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdHJveVdhdmVTdXJmZXIoKSB7XG4gICAgdGhpcy5kdXJhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRpbmdBdWRpb0ZpbGUgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHRoaXMud2F2ZVN1cmZlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLndhdmVTdXJmZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlV2F2ZVN1cmZlcigpIHtcbiAgICB0aGlzLmRlc3Ryb3lXYXZlU3VyZmVyKCk7XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5hdWRpb0ZpbGVOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YXZlU3VyZmVyID0gV2F2ZVN1cmZlci5jcmVhdGUoe1xuICAgICAgICBjb250YWluZXI6ICcjd2F2ZWZvcm0nLFxuICAgICAgICB3YXZlQ29sb3I6ICd3aGl0ZScsXG4gICAgICAgIHByb2dyZXNzQ29sb3I6ICd3aGl0ZScsXG4gICAgICAgIC8vIGJhcldpZHRoOiAyLFxuICAgICAgICBoZWlnaHQ6IDEsXG4gICAgICAgIGludGVyYWN0OiBmYWxzZSxcbiAgICAgICAgLy8gVXNlIGZvciB0aW1lbGluZXMgd2l0aG91dCBzb3VuZC4gV2F2ZSB3aWxsIGJlIGRpc3BsYXllZFxuICAgICAgICAvLyB3cm9uZywgYnV0IHNob3VsZCB3b3JrIGZvciBhIGR1bW15IGF1ZGlvIHdpdGhvdXQgYW55IHdhdmVzLlxuICAgICAgICAvLyBkdXJhdGlvbjogNDAwLFxuICAgICAgICBwbHVnaW5zOiBbXG4gICAgICAgICAgQ3Vyc29yUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICAvLyBzaG93VGltZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBjb2xvcjogJyNmZDdlMTQnLFxuICAgICAgICAgICAgaGlkZU9uQmx1cjogZmFsc2UgLyogZG9uJ3Qgc2hvdy9oaWRlIHRoZSBjdXJzb3Igb24gdGhlIHdhdmUgKG9ubHkgb24gdGhlIHRpbWVsaW5lKSAqLyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBSZWdpb25zUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICBkcmFnU2VsZWN0aW9uOiB7XG4gICAgICAgICAgICAgIHNsb3A6IDUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgICAgICAgIHNuYXBUb0dyaWRJbnRlcnZhbDogdGhpcy5nZXRTbmFwVG9HcmlkSW50ZXJ2YWwoKSxcbiAgICAgICAgICAgIHNuYXBUb0dyaWRPZmZzZXQ6IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIFRpbWVMaW5lUGx1Z2luLmNyZWF0ZSh7XG4gICAgICAgICAgICBjb250YWluZXI6ICcjd2F2ZWZvcm0tdGltZWxpbmUnLFxuICAgICAgICAgICAgcHJpbWFyeUZvbnRDb2xvcjogJyNmZmYnLFxuICAgICAgICAgICAgc2Vjb25kYXJ5Rm9udENvbG9yOiAnI2ZmZicsXG4gICAgICAgICAgICBvZmZzZXQ6IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpLFxuICAgICAgICAgICAgZm9ybWF0VGltZUNhbGxiYWNrOiB0aGlzLmZvcm1hdFRpbWVDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgdGltZUludGVydmFsOiB0aGlzLnRpbWVJbnRlcnZhbC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgcHJpbWFyeUxhYmVsSW50ZXJ2YWw6IHRoaXMucHJpbWFyeUxhYmVsSW50ZXJ2YWwuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHNlY29uZGFyeUxhYmVsSW50ZXJ2YWw6IHRoaXMuc2Vjb25kYXJ5TGFiZWxJbnRlcnZhbC5iaW5kKHRoaXMpLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGxldCBhdWRpb0ZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZ1NlcnZpY2UuZW5hYmxlTWVkaWFMaWJyYXJ5KSB7XG4gICAgICAgIC8vIHRoZSBmaWxlIG5hbWUgaXMgYWxzbyB1c2VkIGZvciB0aGUgcmVhbCBmaWxlIG5hbWVcbiAgICAgICAgYXVkaW9GaWxlTmFtZSA9ICdmaWxlL2dldD9uYW1lPScgKyB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uYXVkaW9GaWxlTmFtZSArICcmdHlwZT1BVURJTyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0aGUgY29tcG9zaXRpb24gdXVpZCBhbmQgZXh0ZW5zaW9uIGlzIHVzZWQgYXMgdGhlIGZpbGUgbmFtZVxuICAgICAgICBhdWRpb0ZpbGVOYW1lID1cbiAgICAgICAgICAnY29tcG9zaXRpb24tZmlsZXMvP2ZpbGU9JyArXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnV1aWQgK1xuICAgICAgICAgICcuJyArXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLmF1ZGlvRmlsZU5hbWUuc3Vic3RyKHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5hdWRpb0ZpbGVOYW1lLmxhc3RJbmRleE9mKCcuJykgKyAxKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy53YXZlU3VyZmVyLmxvYWQodGhpcy5jb25maWdTZXJ2aWNlLnJlc3RVcmwgKyBhdWRpb0ZpbGVOYW1lKTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdyZWFkeScsICgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgLy8gdHJ5IGd1ZXNzaW5nIHRoZSBicG0gYW5kIG9mZnNldCBmcm9tIHRoZSBmaWxlLCBpZiBuZWNlc3NhcnlcbiAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnRlbXBvR3Vlc3NlZCkge1xuICAgICAgICAgICAgLy8gd2UgYWxyZWFkeSBndWVzc2VkIHRoZSBCUE0gb2YgdGhpcyBmaWxlIC0tPiBkb24ndCBkbyBpdCBhZ2FpblxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgbm90IHlldCBndWVzc2VkIHRoZSBCUE0gLS0+IGRvIGl0IG5vd1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnRlbXBvR3Vlc3NlZCA9IHRydWU7XG4gICAgICAgICAgICBndWVzcyh0aGlzLndhdmVTdXJmZXIuYmFja2VuZC5idWZmZXIpXG4gICAgICAgICAgICAgIC50aGVuKCh7IGJwbSwgb2Zmc2V0IH0pID0+IHtcbiAgICAgICAgICAgICAgICAvLyB0aGUgYnBtIGFuZCBvZmZzZXQgY291bGQgYmUgZ3Vlc3NlZFxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5iZWF0c1Blck1pbnV0ZSA9IGJwbTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uZ3JpZE9mZnNldE1pbGxpcyA9IG9mZnNldCAqIDEwMDA7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdDb3VsZCBub3QgZGV0ZWN0IHRoZSBCUE0gZnJvbSB0aGUgYXVkaW8gZmlsZScsIGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nQXVkaW9GaWxlID0gZmFsc2U7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuZHVyYXRpb24gPSB0aGlzLm1zVG9UaW1lKHRoaXMud2F2ZVN1cmZlci5nZXREdXJhdGlvbigpICogMTAwMCk7XG4gICAgICAgICAgdGhpcy5kcmF3QWxsUmVnaW9ucygpO1xuXG4gICAgICAgICAgLy8gc2Nyb2xsIHdhdmVzdXJmZXIgaW4gc3luYyB3aXRoIHRoZSB0aW1lbGluZVxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci5kcmF3ZXIud3JhcHBlci5zY3JvbGxMZWZ0ID0gdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuc2Nyb2xsTGVmdDtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lIHRvIHRoZSBzYW1lIHBvc2l0aW9uIGFzIHRoZSB3YXZlc3VyZmVyLFxuICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGUgdGltZWxpbmUgaXMgbGFyZ2VyIHRoYW4gd2F2ZXN1cmZlciBhbmQgbWlnaHQgZ2V0IG91dCBvZiBzeW5jLlxuICAgICAgICAgICAgLy8gVGhpcyB3YXksIGlmIHdhdmVzdXJmZXIgY2Fubm90IHNjcm9sbCBhbnkgZnVydGhlciwgd2UgcmVzZXQgdGhlIHBvc2l0aW9uXG4gICAgICAgICAgICAvLyBvZiB0aGUgdGltZWxpbmUgYXMgd2VsbC5cbiAgICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLnNjcm9sbExlZnQgPSB0aGlzLndhdmVTdXJmZXIuZHJhd2VyLndyYXBwZXIuc2Nyb2xsTGVmdDtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIGRpc3BsYXkgdGhlIGN1cnNvciBhbHNvIG9uIHRoZSB0aW1lbGluZVxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLndhdmVTdXJmZXIuY3Vyc29yLnNob3dDdXJzb3IoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53YXZlU3VyZmVyLmN1cnNvci5oaWRlQ3Vyc29yKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLndyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGU6IGFueSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYmJveCA9IHRoaXMud2F2ZVN1cmZlci5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBjb25zdCB4ID0gZS5jbGllbnRYIC0gYmJveC5sZWZ0O1xuICAgICAgICAgICAgdGhpcy53YXZlU3VyZmVyLmN1cnNvci51cGRhdGVDdXJzb3JQb3NpdGlvbih4LCAwKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIGhpZGUgdGhlIGN1cnNvciBvbiB0aGUgd2F2ZSBpbml0aWFsbHkuIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIHBhcmFtIGhpZGVPbkJsdXIgPSBmYWxzZSxcbiAgICAgICAgICAvLyBpdCB3aWxsIG5ldmVyIGJlIGRpc3BsYXllZCBvbiB0aGUgd2F2ZSBub3cuIHdlIGhhbmRsZSBpdCBvbiB0aGUgdGltZWxpbmUgb25seS5cbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIuY3Vyc29yLmhpZGVDdXJzb3IoKTtcblxuICAgICAgICAgIC8vIHNlZWsgb24gdGltZWxpbmUtY2xpY2tcbiAgICAgICAgICB0aGlzLndhdmVTdXJmZXIudGltZWxpbmUud3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCAoZTogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRpbWVsaW5lQ2xpY2tpbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zZWVla1dpdGhUaW1lbGluZShlKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIChlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRpbWVsaW5lQ2xpY2tpbmcpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZWVla1dpdGhUaW1lbGluZShlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMud2F2ZVN1cmZlci50aW1lbGluZS53cmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoZTogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRpbWVsaW5lQ2xpY2tpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMudXBkYXRlQ3VycmVudFRpbWUoKTtcblxuICAgICAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlcy5uZXh0KCk7XG4gICAgICAgICAgdGhpcy53YXZlU3VyZmVyUmVhZHkubmV4dCgpO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLndhdmVTdXJmZXIub24oJ2Vycm9yJywgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgLy8gY291bGQgbm90IGxvYWQgdGhlIGNvbXBvc2l0aW9uIC0tPiBkZWxldGUgaXRcbiAgICAgICAgLy8gKHRoaXMgbWF5IG9jY3VyLCB3aGVuIHRoZSBjb21wb3NpdGlvbiBoYXMgYmVlbiBkZWxldGVkIGJ1dCB0aGUgcHJvamVjdCBpcyBub3Qgc2F2ZWQgYWZ0ZXJ3YXJkcylcbiAgICAgICAgdGhpcy5kZWxldGVTZWxlY3RlZENvbXBvc2l0aW9uKCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdzZWVrJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLm9uKCdwbGF5JywgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0YXJ0VGltZVVwZGF0ZXIoKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLndhdmVTdXJmZXIub24oJ3BhdXNlJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3BUaW1lVXBkYXRlcigpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMud2F2ZVN1cmZlci5vbigncmVnaW9uLWNyZWF0ZWQnLCAocmVnaW9uKSA9PiB7XG4gICAgICAgIC8vIHJlZ2lvbiBjcmVhdGVkIGJ5IHNlbGVjdGlvbiBvciBwcm9ncmFtbWF0aWNhbGx5XG4gICAgICAgIGlmICh0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lcyAmJiB0aGlzLnNjZW5lU2VydmljZS5zZWxlY3RlZFNjZW5lcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBpZiAoIXJlZ2lvbi5kYXRhLmhhbmRsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUmVnaW9uKHJlZ2lvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghcmVnaW9uLmRhdGEuaGFuZGxlZCkge1xuICAgICAgICAgICAgcmVnaW9uLnJlbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMud2F2ZVN1cmZlci5vbigncmVnaW9uLXVwZGF0ZWQnLCAocmVnaW9uOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5kZXRlY3RDaGFuZ2VzLm5leHQoKTtcbiAgICAgICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gICAgICB9KTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHByaXZhdGUgaGV4VG9SZ2IoaGV4OiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcbiAgICByZXR1cm4gcmVzdWx0XG4gICAgICA/IHtcbiAgICAgICAgICByOiBwYXJzZUludChyZXN1bHRbMV0sIDE2KSxcbiAgICAgICAgICBnOiBwYXJzZUludChyZXN1bHRbMl0sIDE2KSxcbiAgICAgICAgICBiOiBwYXJzZUludChyZXN1bHRbM10sIDE2KSxcbiAgICAgICAgfVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZWdpb25TZWxlY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0KSkge1xuICAgICAgY29uc3QgcmVnaW9uOiBhbnkgPSB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0W2tleV07XG5cbiAgICAgIC8vIGlmIG5vIHNjZW5lIGlzIHNldCwgdGhlIHJlZ2lvbiBpcyBub3QgdmFsaWQgKGUuZy4gaGFzIGJlZW4gY3JlYXRlZCwgd2hpbGVcbiAgICAgIC8vIG5vIHNjZW5lIGhhcyBiZWVuIHNlbGVjdGVkIGFuZCByZW1vdmUgZGlkIG5vdCB3b3JrIHByb3Blcmx5KVxuICAgICAgaWYgKHJlZ2lvbi5zY2VuZSkge1xuICAgICAgICBsZXQgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHk7XG5cbiAgICAgICAgcmVnaW9uLmRyYWcgPSBmYWxzZTtcbiAgICAgICAgcmVnaW9uLnJlc2l6ZSA9IGZhbHNlO1xuICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RhYmxlID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lSXNTZWxlY3RlZChyZWdpb24uc2NlbmUpKSB7XG4gICAgICAgICAgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHlTZWxlY3RlZFNjZW5lO1xuICAgICAgICAgIHJlZ2lvbi5kcmFnID0gdHJ1ZTtcbiAgICAgICAgICByZWdpb24ucmVzaXplID0gdHJ1ZTtcbiAgICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RhYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZ2lvbi5hdHRyaWJ1dGVzLnNlbGVjdGVkID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiAmJiB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24gPT09IHJlZ2lvbi5zY2VuZVBsYXliYWNrUmVnaW9uKSB7XG4gICAgICAgICAgaW50ZW5zaXR5ID0gdGhpcy5pbnRlbnNpdHlIaWdobGlnaHRlZDtcbiAgICAgICAgICByZWdpb24uYXR0cmlidXRlcy5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZWdpb24uY29sb3IgPVxuICAgICAgICAgICdyZ2JhKCcgK1xuICAgICAgICAgIHRoaXMuaGV4VG9SZ2IocmVnaW9uLnNjZW5lLmNvbG9yKS5yICtcbiAgICAgICAgICAnLCAnICtcbiAgICAgICAgICB0aGlzLmhleFRvUmdiKHJlZ2lvbi5zY2VuZS5jb2xvcikuZyArXG4gICAgICAgICAgJywgJyArXG4gICAgICAgICAgdGhpcy5oZXhUb1JnYihyZWdpb24uc2NlbmUuY29sb3IpLmIgK1xuICAgICAgICAgICcsICcgK1xuICAgICAgICAgIGludGVuc2l0eSArXG4gICAgICAgICAgJyknO1xuICAgICAgICByZWdpb24udXBkYXRlUmVuZGVyKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlU2VsZWN0ZWRSZWdpb24oKSB7XG4gICAgaWYgKCF0aGlzLndhdmVTdXJmZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICBjb25zdCByZWdpb246IGFueSA9IHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3Rba2V5XTtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9PT0gcmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICAgICAgcmVnaW9uLnN0YXJ0ID0gdGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzIC8gMTAwMDtcbiAgICAgICAgcmVnaW9uLmVuZCA9IHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgLyAxMDAwO1xuICAgICAgICByZWdpb24udXBkYXRlUmVuZGVyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U2VsZWN0ZWRSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbj86IFNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uICYmIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9PT0gc2NlbmVQbGF5YmFja1JlZ2lvbikge1xuICAgICAgLy8gTm8gdXBkYXRlIHJlcXVpcmVkXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHNjZW5lUGxheWJhY2tSZWdpb24pIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHNjZW5lUGxheWJhY2tSZWdpb247XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVSZWdpb25TZWxlY3Rpb24oKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UmVnaW9uU25hcFRvR3JpZFZhbHVlKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIC8vIHRoZSByZWdpb25zIHNob3VsZCBzbmFwIHRvIGEgZ3JpZFxuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpIHx8IDA7XG4gICAgY29uc3QgaW50ZXJ2YWwgPSB0aGlzLmdldFNuYXBUb0dyaWRJbnRlcnZhbCgpIHx8IDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoKHZhbHVlIC0gb2Zmc2V0KSAvIGludGVydmFsKSAqIGludGVydmFsICsgb2Zmc2V0O1xuICB9XG5cbiAgcHJpdmF0ZSBjb25uZWN0UmVnaW9uKHdhdmVTdXJmZXJSZWdpb246IGFueSwgc2NlbmU6IFNjZW5lLCBzY2VuZVBsYXliYWNrUmVnaW9uOiBTY2VuZVBsYXliYWNrUmVnaW9uLCBwcmVzZXQ/OiBQcmVzZXQpIHtcbiAgICB3YXZlU3VyZmVyUmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24gPSBzY2VuZVBsYXliYWNrUmVnaW9uO1xuICAgIHdhdmVTdXJmZXJSZWdpb24uc2NlbmUgPSBzY2VuZTtcbiAgICB3YXZlU3VyZmVyUmVnaW9uLnByZXNldCA9IHByZXNldDtcblxuICAgIHdhdmVTdXJmZXJSZWdpb24ub24oJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVJc1NlbGVjdGVkKHNjZW5lKSkge1xuICAgICAgICB0aGlzLnNldFNlbGVjdGVkUmVnaW9uKHNjZW5lUGxheWJhY2tSZWdpb24pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgd2F2ZVN1cmZlclJlZ2lvbi5vbigndXBkYXRlJywgKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTZWxlY3RlZFJlZ2lvbihzY2VuZVBsYXliYWNrUmVnaW9uKTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc25hcFRvR3JpZCkge1xuICAgICAgICAvLyB1cGRhdGUgdGhlIHJlZ2lvbnMgYm91bmRhcmllcy4gdGhleSBtYXkgbm90IHNuYXAgdG8gZ3JpZCwgaWYgaXQgaGFzIGJlZW5cbiAgICAgICAgLy8gZGlzYWJsZWQgZHVyaW5nIGNyZWF0aW9uIG9mIHRoZSByZWdpb24gYnV0IGFjdGl2YXRlZCBhZnRlcndhcmRzLlxuICAgICAgICB3YXZlU3VyZmVyUmVnaW9uLnN0YXJ0ID0gdGhpcy5nZXRSZWdpb25TbmFwVG9HcmlkVmFsdWUod2F2ZVN1cmZlclJlZ2lvbi5zdGFydCk7XG4gICAgICAgIHdhdmVTdXJmZXJSZWdpb24uZW5kID0gdGhpcy5nZXRSZWdpb25TbmFwVG9HcmlkVmFsdWUod2F2ZVN1cmZlclJlZ2lvbi5lbmQpO1xuICAgICAgfVxuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyA9IHdhdmVTdXJmZXJSZWdpb24uc3RhcnQgKiAxMDAwO1xuICAgICAgc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgPSB3YXZlU3VyZmVyUmVnaW9uLmVuZCAqIDEwMDA7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRyYXdSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbjogU2NlbmVQbGF5YmFja1JlZ2lvbiwgc2NlbmU6IFNjZW5lKSB7XG4gICAgLy8gZHJhdyB0aGUgcmVnaW9ucyBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHNjZW5lXG4gICAgaWYgKCF0aGlzLmlzV2F2ZVN1cmZlclJlYWR5KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhZGQgdGhlIHBsYXliYWNrIHJlZ2lvblxuICAgIGNvbnN0IHdhdmVTdXJmZXJSZWdpb24gPSB0aGlzLndhdmVTdXJmZXIuYWRkUmVnaW9uKHtcbiAgICAgIHN0YXJ0OiBzY2VuZVBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzIC8gMTAwMCxcbiAgICAgIGVuZDogc2NlbmVQbGF5YmFja1JlZ2lvbi5lbmRNaWxsaXMgLyAxMDAwLFxuICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgIGRhdGE6IHsgaGFuZGxlZDogdHJ1ZSB9LFxuICAgIH0pO1xuICAgIHRoaXMuY29ubmVjdFJlZ2lvbih3YXZlU3VyZmVyUmVnaW9uLCBzY2VuZSwgc2NlbmVQbGF5YmFja1JlZ2lvbik7XG5cbiAgICAvLyBUT0RPIHNob3cgdGhlIGFsbCBwcmVzZXRzXG4gICAgLy8gZm9yIChsZXQgcHJlc2V0VXVpZCBvZiBzY2VuZS5wcmVzZXRVdWlkcykge1xuICAgIC8vICAgY29uc3QgcHJlc2V0ID0gdGhpcy5wcmVzZXRTZXJ2aWNlLmdldFByZXNldEJ5VXVpZChwcmVzZXRVdWlkKTtcblxuICAgIC8vICAgbGV0IHdhdmVTdXJmZXJSZWdpb24gPSB0aGlzLnRpbWVsaW5lU2VydmljZS53YXZlU3VyZmVyLmFkZFJlZ2lvbih7XG4gICAgLy8gICAgIHN0YXJ0OiAoc2NlbmVQbGF5YmFja1JlZ2lvbi5zdGFydE1pbGxpcyArIChwcmVzZXQuc3RhcnRNaWxsaXMgPyBwcmVzZXQuc3RhcnRNaWxsaXMgOiAwKSkgLyAxMDAwLFxuICAgIC8vICAgICBlbmQ6IChzY2VuZVBsYXliYWNrUmVnaW9uLnN0YXJ0TWlsbGlzXG4gICAgLy8gICAgICAgKyAocHJlc2V0LmVuZE1pbGxpcyA/IHByZXNldC5lbmRNaWxsaXMgOiBzY2VuZVBsYXliYWNrUmVnaW9uLmVuZE1pbGxpcyAtIHNjZW5lUGxheWJhY2tSZWdpb24uc3RhcnRNaWxsaXMpKSAvIDEwMDAsXG4gICAgLy8gICAgIGNvbG9yOiAnI2ZmZicsXG4gICAgLy8gICAgIGRhdGE6IHsgaGFuZGxlZDogdHJ1ZSB9LFxuICAgIC8vICAgICAvLyBUT0RPXG4gICAgLy8gICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAvLyAgICAgICBwcmVzZXQ6IHRydWUsXG4gICAgLy8gICAgICAgbmFtZTogJ1ByZXNldCAxJ1xuICAgIC8vICAgICB9XG4gICAgLy8gICB9KTtcbiAgICAvLyAgIHRoaXMuY29ubmVjdFJlZ2lvbih3YXZlU3VyZmVyUmVnaW9uLCBzY2VuZSwgc2NlbmVQbGF5YmFja1JlZ2lvbiwgcHJlc2V0KTtcbiAgICAvLyB9XG5cbiAgICB0aGlzLnVwZGF0ZVJlZ2lvblNlbGVjdGlvbigpO1xuICB9XG5cbiAgcmVtb3ZlUmVnaW9uKCkge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZFBsYXliYWNrUmVnaW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNlbGVjdGVkU2NlbmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zW2ldID09PSB0aGlzLnNlbGVjdGVkUGxheWJhY2tSZWdpb24pIHtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSByZWdpb24gZnJvbSB3YXZlc3VyZmVyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMud2F2ZVN1cmZlci5yZWdpb25zLmxpc3QpKSB7XG4gICAgICAgICAgY29uc3QgcmVnaW9uOiBhbnkgPSB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5saXN0W2tleV07XG5cbiAgICAgICAgICBpZiAocmVnaW9uLnNjZW5lUGxheWJhY2tSZWdpb24gPT09IHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbikge1xuICAgICAgICAgICAgcmVnaW9uLnJlbW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRQbGF5YmFja1JlZ2lvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zLnNwbGljZShpLCAxKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gIH1cblxuICBnZXRQcmVzZXRzSW5UaW1lKHRpbWVNaWxsaXM6IG51bWJlcik6IFByZXNldFJlZ2lvblNjZW5lW10ge1xuICAgIC8vIFJldHVybiBhbGwgcHJlc2V0cyB3aGljaCBzaG91bGQgYmUgYWN0aXZlIGR1cmluZyB0aGUgc3BlY2lmaWVkIHRpbWVcbiAgICBjb25zdCBhY3RpdmVQcmVzZXRzOiBQcmVzZXRSZWdpb25TY2VuZVtdID0gW107XG5cbiAgICBmb3IgKGxldCBzY2VuZUluZGV4ID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lcy5sZW5ndGggLSAxOyBzY2VuZUluZGV4ID49IDA7IHNjZW5lSW5kZXgtLSkge1xuICAgICAgY29uc3Qgc2NlbmUgPSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3Quc2NlbmVzW3NjZW5lSW5kZXhdO1xuXG4gICAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24uc2NlbmVQbGF5YmFja1JlZ2lvbnMpIHtcbiAgICAgICAgaWYgKHJlZ2lvbi5zY2VuZVV1aWQgPT09IHNjZW5lLnV1aWQpIHtcbiAgICAgICAgICBmb3IgKGxldCBwcmVzZXRJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5wcmVzZXRzLmxlbmd0aCAtIDE7IHByZXNldEluZGV4ID49IDA7IHByZXNldEluZGV4LS0pIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJlc2V0VXVpZCBvZiBzY2VuZS5wcmVzZXRVdWlkcykge1xuICAgICAgICAgICAgICBpZiAocHJlc2V0VXVpZCA9PT0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnByZXNldHNbcHJlc2V0SW5kZXhdLnV1aWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmVzZXQgPSB0aGlzLnByZXNldFNlcnZpY2UuZ2V0UHJlc2V0QnlVdWlkKHByZXNldFV1aWQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHByZXNldCkge1xuICAgICAgICAgICAgICAgICAgbGV0IHByZXNldFN0YXJ0TWlsbGlzID0gcHJlc2V0LnN0YXJ0TWlsbGlzID09PSB1bmRlZmluZWQgPyByZWdpb24uc3RhcnRNaWxsaXMgOiByZWdpb24uc3RhcnRNaWxsaXMgKyBwcmVzZXQuc3RhcnRNaWxsaXM7XG4gICAgICAgICAgICAgICAgICBsZXQgcHJlc2V0RW5kTWlsbGlzID0gcHJlc2V0LmVuZE1pbGxpcyA9PT0gdW5kZWZpbmVkID8gcmVnaW9uLmVuZE1pbGxpcyA6IHJlZ2lvbi5zdGFydE1pbGxpcyArIHByZXNldC5lbmRNaWxsaXM7XG5cbiAgICAgICAgICAgICAgICAgIC8vIGV4dGVuZCB0aGUgcnVubmluZyB0aW1lLCBpZiBmYWRpbmcgaXMgZG9uZSBvdXRzaWRlIHRoZSBib3VuZGFyaWVzXG4gICAgICAgICAgICAgICAgICBwcmVzZXRTdGFydE1pbGxpcyAtPSBwcmVzZXQuZmFkZUluUHJlID8gcHJlc2V0LmZhZGVJbk1pbGxpcyA6IDA7XG4gICAgICAgICAgICAgICAgICBwcmVzZXRFbmRNaWxsaXMgKz0gcHJlc2V0LmZhZGVPdXRQb3N0ID8gcHJlc2V0LmZhZGVPdXRNaWxsaXMgOiAwO1xuXG4gICAgICAgICAgICAgICAgICBpZiAocHJlc2V0U3RhcnRNaWxsaXMgPD0gdGltZU1pbGxpcyAmJiBwcmVzZXRFbmRNaWxsaXMgPj0gdGltZU1pbGxpcykge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmVQcmVzZXRzLnB1c2gobmV3IFByZXNldFJlZ2lvblNjZW5lKHByZXNldCwgcmVnaW9uLCBzY2VuZSkpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhY3RpdmVQcmVzZXRzO1xuICB9XG5cbiAgZHJhd0FsbFJlZ2lvbnMoKSB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkcmF3IHRoZSByZWdpb25zIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZWlyIGNvcnJlc3BvbmRpbmcgc2NlbmVzLCBidXQgZHJhd1xuICAgIC8vIHRoZSBzZWxlY3RlZCBvbmVzIGxhc3QsIHRvIG1ha2Ugc3VyZSB0aGV5J3JlIGFsd2F5cyBjbGlja2FibGUuXG4gICAgZm9yIChsZXQgc2NlbmVJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zY2VuZXMubGVuZ3RoIC0gMTsgc2NlbmVJbmRleCA+PSAwOyBzY2VuZUluZGV4LS0pIHtcbiAgICAgIGNvbnN0IHNjZW5lID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lc1tzY2VuZUluZGV4XTtcbiAgICAgIGlmICghdGhpcy5zY2VuZVNlcnZpY2Uuc2NlbmVJc1NlbGVjdGVkKHNjZW5lKSkge1xuICAgICAgICBmb3IgKGNvbnN0IHNjZW5lUGxheWJhY2tSZWdpb24gb2YgdGhpcy5zZWxlY3RlZENvbXBvc2l0aW9uLnNjZW5lUGxheWJhY2tSZWdpb25zKSB7XG4gICAgICAgICAgaWYgKHNjZW5lUGxheWJhY2tSZWdpb24uc2NlbmVVdWlkID09PSBzY2VuZS51dWlkKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdSZWdpb24oc2NlbmVQbGF5YmFja1JlZ2lvbiwgc2NlbmUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRyYXcgYWxsIHNlbGVjdGVkIHNjZW5lcyBhZnRlcndhcmRzXG4gICAgZm9yIChsZXQgc2NlbmVJbmRleCA9IHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zY2VuZXMubGVuZ3RoIC0gMTsgc2NlbmVJbmRleCA+PSAwOyBzY2VuZUluZGV4LS0pIHtcbiAgICAgIGNvbnN0IHNjZW5lID0gdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LnNjZW5lc1tzY2VuZUluZGV4XTtcblxuICAgICAgaWYgKHRoaXMuc2NlbmVTZXJ2aWNlLnNjZW5lSXNTZWxlY3RlZChzY2VuZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBzY2VuZVBsYXliYWNrUmVnaW9uIG9mIHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi5zY2VuZVBsYXliYWNrUmVnaW9ucykge1xuICAgICAgICAgIGlmIChzY2VuZVBsYXliYWNrUmVnaW9uLnNjZW5lVXVpZCA9PT0gc2NlbmUudXVpZCkge1xuICAgICAgICAgICAgdGhpcy5kcmF3UmVnaW9uKHNjZW5lUGxheWJhY2tSZWdpb24sIHNjZW5lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB1cGRhdGVHcmlkKCkge1xuICAgIGlmICh0aGlzLndhdmVTdXJmZXJSZWFkeSkge1xuICAgICAgdGhpcy53YXZlU3VyZmVyLnRpbWVsaW5lLnBhcmFtcy5vZmZzZXQgPSB0aGlzLmdldFNuYXBUb0dyaWRPZmZzZXQoKTtcblxuICAgICAgdGhpcy53YXZlU3VyZmVyLnJlZ2lvbnMucGFyYW1zLnNuYXBUb0dyaWRJbnRlcnZhbCA9IHRoaXMuZ2V0U25hcFRvR3JpZEludGVydmFsKCk7XG4gICAgICB0aGlzLndhdmVTdXJmZXIucmVnaW9ucy5wYXJhbXMuc25hcFRvR3JpZE9mZnNldCA9IHRoaXMuZ2V0U25hcFRvR3JpZE9mZnNldCgpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUN1cnJlbnRUaW1lKCk7XG4gIH1cblxuICBnZXRFeHRlcm5hbENvbXBvc2l0aW9uTmFtZXMoKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgIC8vIGdldCBhdmFpbGFibGUgY29tcG9zaXRpb25zIGZyb20gYW4gZXh0ZXJuYWwgcG9vbCAoZS5nLiBSb2NrZXQgU2hvdylcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCgnY29tcG9zaXRpb24vbGlzdCcpLnBpcGUoXG4gICAgICBtYXAoKHJlc3BvbnNlOiBvYmplY3RbXSkgPT4ge1xuICAgICAgICBjb25zdCBjb21wb3NpdGlvbk5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2VDb21wb3NpdGlvbiBvZiByZXNwb25zZSkge1xuICAgICAgICAgIGNvbXBvc2l0aW9uTmFtZXMucHVzaCgocmVzcG9uc2VDb21wb3NpdGlvbiBhcyBhbnkpLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBvc2l0aW9uTmFtZXM7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBzZWxlY3RDb21wb3NpdGlvbkluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb24gPSB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuY29tcG9zaXRpb25zW2luZGV4XTtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9zaXRpb25JbmRleCA9IGluZGV4O1xuICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5zZWxlY3RlZENvbXBvc2l0aW9uVXVpZCA9IHRoaXMuc2VsZWN0ZWRDb21wb3NpdGlvbi51dWlkO1xuICAgIHRoaXMuY3JlYXRlV2F2ZVN1cmZlcigpO1xuXG4gICAgLy8gcmVxdWlyZWQgdG8gdHJpZ2dlciB0aW1lbGluZS5jb21wb25lbnQucmVzaXplKClcbiAgICB0aGlzLndhdmVTdXJmZXJSZWFkeS5uZXh0KCk7XG5cbiAgICB0aGlzLmFwcGx5Wm9vbSgwKTtcbiAgfVxufVxuIl19