@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,699 +0,0 @@
1
- import { HttpClient } from '@angular/common/http';
2
- import { Injectable } from '@angular/core';
3
- import { TranslateService } from '@ngx-translate/core';
4
- import { ToastrService } from 'ngx-toastr';
5
- import { forkJoin, of } from 'rxjs';
6
- import { map } from 'rxjs/operators';
7
- import { CachedFixture } from '../models/cached-fixture';
8
- import { CachedFixtureCapability } from '../models/cached-fixture-capability';
9
- import { CachedFixtureChannel } from '../models/cached-fixture-channel';
10
- import { Color } from '../models/color';
11
- import { Fixture } from '../models/fixture';
12
- import { FixtureProfile } from '../models/fixture-profile';
13
- import { FixtureWheelSlotType } from '../models/fixture-wheel-slot';
14
- import { ProjectService } from './project.service';
15
- import { UuidService } from './uuid.service';
16
- import * as i0 from "@angular/core";
17
- import * as i1 from "@angular/common/http";
18
- import * as i2 from "./project.service";
19
- import * as i3 from "@ngx-translate/core";
20
- import * as i4 from "ngx-toastr";
21
- import * as i5 from "./uuid.service";
22
- export class FixtureService {
23
- constructor(http, projectService, translateService, toastrService, uuidService) {
24
- this.http = http;
25
- this.projectService = projectService;
26
- this.translateService = translateService;
27
- this.toastrService = toastrService;
28
- this.uuidService = uuidService;
29
- this.cachedFixtures = [];
30
- // is the side-tab settings currently selected?
31
- this.settingsSelection = false;
32
- this.selectedSettingsFixtures = [];
33
- }
34
- getFixtureByUuid(uuid) {
35
- for (const fixture of this.projectService.project.fixtures) {
36
- if (fixture.uuid === uuid) {
37
- return fixture;
38
- }
39
- }
40
- }
41
- fixtureUuidAndPixelKeyEquals(fixtureUuid1, fixtureUuid2, pixelKey1, pixelKey2) {
42
- return fixtureUuid1 === fixtureUuid2 && ((pixelKey1 == null && pixelKey2 == null) || pixelKey1 === pixelKey2);
43
- }
44
- getCachedFixtureByUuid(uuid, pixelKey) {
45
- for (const fixture of this.cachedFixtures) {
46
- if (this.fixtureUuidAndPixelKeyEquals(fixture.fixture.uuid, uuid, fixture.pixelKey, pixelKey)) {
47
- return fixture;
48
- }
49
- }
50
- // not yet found -> try searching the fixture without pixelKey for the general channels
51
- if (pixelKey) {
52
- return undefined;
53
- }
54
- for (const fixture of this.cachedFixtures) {
55
- if (!fixture.pixelKey && fixture.fixture.uuid === uuid) {
56
- return fixture;
57
- }
58
- }
59
- }
60
- // Get all profiles to search for (only metadata)
61
- getSearchProfiles() {
62
- return this.http.get('fixtures').pipe(map((response) => {
63
- const searchProfiles = [];
64
- for (const profile of response) {
65
- searchProfiles.push(new FixtureProfile(profile));
66
- }
67
- return searchProfiles;
68
- }));
69
- }
70
- getProfileByUuid(uuid) {
71
- for (const fixtureProfile of this.projectService.project.fixtureProfiles) {
72
- if (fixtureProfile.uuid === uuid) {
73
- return fixtureProfile;
74
- }
75
- }
76
- }
77
- loadProfileByUuid(uuid) {
78
- const loadedProfile = this.getProfileByUuid(uuid);
79
- if (loadedProfile) {
80
- // This profile is already loaded
81
- return of(undefined);
82
- }
83
- // Load the metadata and the profile
84
- return forkJoin([this.http.get('fixtures?uuid=' + encodeURI(uuid)), this.http.get('fixture?uuid=' + encodeURI(uuid))]).pipe(map((result) => {
85
- const mergedData = { ...result[0][0], ...result[1] };
86
- const fixtureProfile = new FixtureProfile(mergedData);
87
- this.projectService.project.fixtureProfiles.push(fixtureProfile);
88
- }));
89
- }
90
- getRotationAngleDeg(value) {
91
- // convert a rotation angle value into degrees
92
- if (value.endsWith('deg')) {
93
- return Number.parseInt(value.replace('deg', ''), 10);
94
- }
95
- else if (value.endsWith('%')) {
96
- const perc = Number.parseInt(value.replace('%', ''), 10);
97
- return (perc / 100) * 360;
98
- }
99
- return undefined;
100
- }
101
- getWheelSlotColors(wheel, slotNumber) {
102
- let colors = [];
103
- const wheelSlots = this.getWheelSlots(wheel, slotNumber);
104
- for (const slot of wheelSlots) {
105
- if (slot.colors && slot.colors.length > 0) {
106
- colors = colors.concat(slot.colors);
107
- }
108
- }
109
- return colors;
110
- }
111
- getMixedWheelSlotColor(wheel, slotNumber) {
112
- const colors = this.getWheelSlotColors(wheel, slotNumber);
113
- const colorsRgb = [];
114
- if (colors.length === 0) {
115
- return undefined;
116
- }
117
- for (const color of colors) {
118
- colorsRgb.push(this.hexToRgb(color));
119
- }
120
- return this.mixColors(colorsRgb);
121
- }
122
- componentToHex(c) {
123
- const hex = c.toString(16);
124
- return hex.length === 1 ? '0' + hex : hex;
125
- }
126
- rgbToHex(r, g, b) {
127
- return '#' + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
128
- }
129
- hexToRgb(hex) {
130
- // expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
131
- const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
132
- hex = hex.replace(shorthandRegex, (m, r, g, b) => {
133
- return r + r + g + g + b + b;
134
- });
135
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
136
- return result ? new Color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)) : null;
137
- }
138
- mixColors(colors) {
139
- // mix an array of rgb-colors containing r, g, b values to a new color
140
- let r = 0;
141
- let g = 0;
142
- let b = 0;
143
- for (const color of colors) {
144
- r += color.red;
145
- g += color.green;
146
- b += color.blue;
147
- }
148
- r /= colors.length;
149
- g /= colors.length;
150
- b /= colors.length;
151
- return new Color(r, g, b);
152
- }
153
- wheelHasSlotType(wheel, slotType) {
154
- for (const slot of wheel.slots) {
155
- if (slot.type === slotType) {
156
- return true;
157
- }
158
- }
159
- return false;
160
- }
161
- getWheelByName(profile, wheelName) {
162
- for (const property in profile.wheels) {
163
- if (property === wheelName) {
164
- return profile.wheels[property];
165
- }
166
- }
167
- // wheel not found
168
- return undefined;
169
- }
170
- getWheelSlots(wheel, slotNumber) {
171
- // return one slot or two slots, if they are mixed (e.g. slor number 2.5 returns the slots 2 and 3)
172
- const slots = [];
173
- if (!wheel) {
174
- return slots;
175
- }
176
- if (slotNumber - Math.floor(slotNumber) > 0) {
177
- // two slots are set
178
- const number = Math.floor(slotNumber);
179
- slots.push(wheel.slots[number - 1]);
180
- if (number >= 0 && number < wheel.slots.length) {
181
- slots.push(wheel.slots[number]);
182
- }
183
- }
184
- else {
185
- // only one slot is set
186
- slots.push(wheel.slots[slotNumber - 1]);
187
- }
188
- return slots;
189
- }
190
- getModeByFixture(profile, fixture) {
191
- for (const mode of profile.modes) {
192
- if (mode.shortName) {
193
- if (mode.shortName === fixture.modeShortName) {
194
- return mode;
195
- }
196
- }
197
- else {
198
- if (mode.name === fixture.modeShortName) {
199
- return mode;
200
- }
201
- }
202
- }
203
- }
204
- getFixtureCapability(capability, channelName, profile) {
205
- const cachedFixtureCapability = new CachedFixtureCapability();
206
- cachedFixtureCapability.capability = capability;
207
- if (capability.slotNumber) {
208
- // there is a wheel connected to this capability
209
- if (typeof capability.wheel === 'string') {
210
- cachedFixtureCapability.wheelName = capability.wheel;
211
- }
212
- else if (Array.isArray(capability.wheel)) {
213
- cachedFixtureCapability.wheelName = capability.wheel[0];
214
- }
215
- else {
216
- cachedFixtureCapability.wheelName = channelName;
217
- }
218
- cachedFixtureCapability.wheel = this.getWheelByName(profile, cachedFixtureCapability.wheelName);
219
- cachedFixtureCapability.wheelSlots = this.getWheelSlots(cachedFixtureCapability.wheel, capability.slotNumber);
220
- cachedFixtureCapability.wheelIsColor = this.wheelHasSlotType(cachedFixtureCapability.wheel, FixtureWheelSlotType.Color);
221
- }
222
- if (cachedFixtureCapability.capability.dmxRange && cachedFixtureCapability.capability.dmxRange.length === 2) {
223
- cachedFixtureCapability.centerValue = Math.floor((cachedFixtureCapability.capability.dmxRange[0] + cachedFixtureCapability.capability.dmxRange[1]) / 2);
224
- }
225
- return cachedFixtureCapability;
226
- }
227
- getCapabilitiesByChannel(fixtureChannel, channelName, profile) {
228
- const capabilites = [];
229
- if (fixtureChannel.capability) {
230
- capabilites.push(this.getFixtureCapability(fixtureChannel.capability, channelName, profile));
231
- }
232
- else if (fixtureChannel.capabilities) {
233
- for (const capability of fixtureChannel.capabilities) {
234
- capabilites.push(this.getFixtureCapability(capability, channelName, profile));
235
- }
236
- }
237
- return capabilites;
238
- }
239
- getMaxValueByChannel(fixtureChannel) {
240
- return Math.pow(256, 1 + fixtureChannel.fineChannelAliases.length) - 1;
241
- }
242
- getDefaultValueByChannel(fixtureChannel) {
243
- if (!fixtureChannel.defaultValue) {
244
- return undefined;
245
- }
246
- if (isNaN(fixtureChannel.defaultValue) && fixtureChannel.defaultValue.endsWith('%')) {
247
- // percentage value
248
- const percentage = Number.parseInt(fixtureChannel.defaultValue.replace('%', ''), 10);
249
- const maxValue = this.getMaxValueByChannel(fixtureChannel);
250
- return (maxValue / 100) * percentage;
251
- }
252
- else {
253
- // DMX value
254
- return Number.parseInt(fixtureChannel.defaultValue, 10);
255
- }
256
- }
257
- getColorWheelByChannel(channel, profile) {
258
- for (const channelCapability of channel.capabilities) {
259
- if (channelCapability.wheelIsColor) {
260
- return channelCapability.wheel;
261
- }
262
- }
263
- return undefined;
264
- }
265
- getChannelByName(fixture, channelName) {
266
- for (const channel of fixture.channels) {
267
- if ((channel.name && channel.name === channelName) ||
268
- (channel.channel && channel.channel.fineChannelAliases.indexOf(channelName) > -1)) {
269
- return channel;
270
- }
271
- }
272
- return undefined;
273
- }
274
- getChannelNameWithPixelKey(templateChannelName, pixelKey) {
275
- return templateChannelName.replace('$pixelKey', pixelKey);
276
- }
277
- addCachedChannel(channels, channel, templateChannelName, pixelKey, profile) {
278
- const cachedFixtureChannel = new CachedFixtureChannel();
279
- const channelName = this.getChannelNameWithPixelKey(templateChannelName, pixelKey);
280
- cachedFixtureChannel.channel = channel;
281
- cachedFixtureChannel.name = channelName;
282
- cachedFixtureChannel.capabilities = this.getCapabilitiesByChannel(cachedFixtureChannel.channel, channelName, profile);
283
- const defaultValue = this.getDefaultValueByChannel(cachedFixtureChannel.channel);
284
- if (defaultValue) {
285
- cachedFixtureChannel.defaultValue = defaultValue;
286
- }
287
- cachedFixtureChannel.maxValue = this.getMaxValueByChannel(cachedFixtureChannel.channel);
288
- cachedFixtureChannel.colorWheel = this.getColorWheelByChannel(cachedFixtureChannel, profile);
289
- channels.push(cachedFixtureChannel);
290
- }
291
- alphanumericSort(a, b) {
292
- return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });
293
- }
294
- getAllPixelKeys(profile) {
295
- let result = [];
296
- if (!profile.matrix.pixelKeys) {
297
- return result;
298
- }
299
- for (let pixelKeyX of profile.matrix.pixelKeys) {
300
- for (let pixelKeyY of pixelKeyX) {
301
- for (let pixelKeyZ of pixelKeyY) {
302
- if (pixelKeyZ) {
303
- result.push(pixelKeyZ);
304
- }
305
- }
306
- }
307
- }
308
- return result;
309
- }
310
- getAllPixelGroups(profile) {
311
- let result = [];
312
- if (!profile.matrix.pixelGroups) {
313
- return result;
314
- }
315
- for (const property of Object.keys(profile.matrix.pixelGroups)) {
316
- result.push(property);
317
- }
318
- return result;
319
- }
320
- getPixelKeysInOrder(profile, repeatFor) {
321
- let result = [];
322
- // could contain just a single string (e.g. 'eachPixelABC') or
323
- if (repeatFor.length > 1) {
324
- // an array of pixel (groups)
325
- result = repeatFor;
326
- }
327
- else if (repeatFor.length === 0) {
328
- return result;
329
- }
330
- else if (repeatFor[0] === 'eachPixelABC') {
331
- // Gets computed into an alphanumerically sorted list of all pixelKeys
332
- if (profile.matrix.pixelCount.length === 3) {
333
- for (let x = 0; x < profile.matrix.pixelCount[0]; x++) {
334
- for (let y = 0; y < profile.matrix.pixelCount[1]; y++) {
335
- for (let z = 0; z < profile.matrix.pixelCount[2]; z++) {
336
- result.push('Pixel ' + (x + 1) + '-' + (y + 1) + '-' + (z + 1));
337
- }
338
- }
339
- }
340
- }
341
- else {
342
- result = result.concat(this.getAllPixelKeys(profile));
343
- }
344
- result.sort(this.alphanumericSort);
345
- }
346
- else if (repeatFor[0] === 'eachPixelGroup') {
347
- // Gets computed into an array of all pixel group keys, ordered by appearance in the JSON file
348
- result = result.concat(this.getAllPixelGroups(profile));
349
- }
350
- else if (repeatFor[0] === 'eachPixelXYZ') {
351
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
352
- for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
353
- for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
354
- const pixel = profile.matrix.pixelKeys[x][y][z];
355
- if (pixel) {
356
- result.push(pixel);
357
- }
358
- }
359
- }
360
- }
361
- }
362
- else if (repeatFor[0] === 'eachPixelXZY') {
363
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
364
- for (let z = 0; z < profile.matrix.pixelKeys[x][0].length; z++) {
365
- for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
366
- const pixel = profile.matrix.pixelKeys[x][y][z];
367
- if (pixel) {
368
- result.push(pixel);
369
- }
370
- }
371
- }
372
- }
373
- }
374
- else if (repeatFor[0] === 'eachPixelYXZ') {
375
- for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
376
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
377
- for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
378
- const pixel = profile.matrix.pixelKeys[x][y][z];
379
- if (pixel) {
380
- result.push(pixel);
381
- }
382
- }
383
- }
384
- }
385
- }
386
- else if (repeatFor[0] === 'eachPixelYZX') {
387
- for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
388
- for (let z = 0; z < profile.matrix.pixelKeys[0][y].length; z++) {
389
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
390
- const pixel = profile.matrix.pixelKeys[x][y][z];
391
- if (pixel) {
392
- result.push(pixel);
393
- }
394
- }
395
- }
396
- }
397
- }
398
- else if (repeatFor[0] === 'eachPixelZXY') {
399
- for (let z = 0; z < profile.matrix.pixelKeys[0][0].length; z++) {
400
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
401
- for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
402
- const pixel = profile.matrix.pixelKeys[x][y][z];
403
- if (pixel) {
404
- result.push(pixel);
405
- }
406
- }
407
- }
408
- }
409
- }
410
- else if (repeatFor[0] === 'eachPixelZYX') {
411
- for (let z = 0; z < profile.matrix.pixelKeys[0][0].length; z++) {
412
- for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
413
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
414
- const pixel = profile.matrix.pixelKeys[x][y][z];
415
- if (pixel) {
416
- result.push(pixel);
417
- }
418
- }
419
- }
420
- }
421
- }
422
- return result;
423
- }
424
- getModeChannelCount(profile, mode) {
425
- let count = 0;
426
- // already calculated?
427
- if (mode.channelCount) {
428
- return mode.channelCount;
429
- }
430
- for (let channel of mode.channels) {
431
- if (channel.insert === 'matrixChannels') {
432
- if (channel.repeatFor.length > 1) {
433
- count += channel.repeatFor.length * channel.templateChannels.length;
434
- }
435
- else if (channel.repeatFor[0] === 'eachPixelGroup') {
436
- count += profile.matrix.pixelGroups.length * channel.templateChannels.length;
437
- }
438
- else if (channel.repeatFor[0].startsWith('eachPixel')) {
439
- if (profile.matrix.pixelCount.length === 3) {
440
- count +=
441
- profile.matrix.pixelCount[0] * profile.matrix.pixelCount[1] * profile.matrix.pixelCount[2] * channel.templateChannels.length;
442
- }
443
- else {
444
- for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
445
- for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
446
- for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
447
- const pixel = profile.matrix.pixelKeys[x][y][z];
448
- if (pixel) {
449
- count += channel.templateChannels.length;
450
- }
451
- }
452
- }
453
- }
454
- }
455
- }
456
- }
457
- else {
458
- count++;
459
- }
460
- }
461
- mode.channelCount = count;
462
- return mode.channelCount;
463
- }
464
- getCachedChannels(profile, mode, pixelKey) {
465
- const channels = [];
466
- if (!mode) {
467
- return channels;
468
- }
469
- for (const channel of mode.channels) {
470
- if (channel.name && !pixelKey) {
471
- // direct reference to a channel
472
- // don't check the fine channels. only add the coarse channel.
473
- let channelFound = false;
474
- for (const availableChannelName of Object.keys(profile.availableChannels)) {
475
- if (channel.name === availableChannelName) {
476
- const availableChannel = profile.availableChannels[availableChannelName];
477
- this.addCachedChannel(channels, availableChannel, availableChannelName, null, profile);
478
- }
479
- }
480
- // check the template channels, if not found in the available channels
481
- if (!channelFound) {
482
- for (const templateChannelName of Object.keys(profile.templateChannels)) {
483
- let existingPixelKeys = this.getAllPixelKeys(profile).concat(this.getAllPixelGroups(profile));
484
- for (const existingPixelKey of existingPixelKeys) {
485
- const channelName = this.getChannelNameWithPixelKey(templateChannelName, existingPixelKey);
486
- if (channel.name === channelName) {
487
- const templateChannel = profile.templateChannels[templateChannelName];
488
- this.addCachedChannel(channels, templateChannel, channelName, existingPixelKey, profile);
489
- }
490
- }
491
- }
492
- }
493
- }
494
- else {
495
- // reference a channel through a pixel matrix
496
- const availablePixelKeys = this.getPixelKeysInOrder(profile, channel.repeatFor);
497
- if (channel.channelOrder === 'perPixel') {
498
- // each channel for each pixel
499
- for (const availablePixelKey of availablePixelKeys) {
500
- if (availablePixelKey === pixelKey) {
501
- for (const modeTemplateChannelName of channel.templateChannels) {
502
- for (const templateChannelName of Object.keys(profile.templateChannels)) {
503
- // don't check the fine channels. only add the coarse channel.
504
- if (modeTemplateChannelName === templateChannelName) {
505
- const templateChannel = profile.templateChannels[templateChannelName];
506
- this.addCachedChannel(channels, templateChannel, templateChannelName, availablePixelKey, profile);
507
- }
508
- }
509
- }
510
- }
511
- }
512
- }
513
- else if (channel.channelOrder === 'perChannel') {
514
- // each pixel for each channel
515
- for (const modeTemplateChannelName of channel.templateChannels) {
516
- for (const availablePixelKey of availablePixelKeys) {
517
- if (availablePixelKey === pixelKey) {
518
- for (const templateChannelName of Object.keys(profile.templateChannels)) {
519
- // don't check the fine channels. only add the coarse channel.
520
- if (modeTemplateChannelName === templateChannelName) {
521
- const templateChannel = profile.templateChannels[templateChannelName];
522
- this.addCachedChannel(channels, templateChannel, templateChannelName, availablePixelKey, profile);
523
- }
524
- }
525
- }
526
- }
527
- }
528
- }
529
- }
530
- }
531
- return channels;
532
- }
533
- fixtureGetUniquePixelKeys(fixture) {
534
- let pixelKeys = new Set();
535
- let profile = this.getProfileByUuid(fixture.profileUuid);
536
- let mode = this.getModeByFixture(profile, fixture);
537
- // add the unique pixel keys
538
- for (let channel of mode.channels) {
539
- this.getPixelKeysInOrder(profile, channel.repeatFor).forEach((str) => {
540
- pixelKeys.add(str);
541
- });
542
- }
543
- return Array.from(pixelKeys);
544
- }
545
- // does the fixture have a general channel without reference to specific pixel keys in the current mode?
546
- fixtureHasGeneralChannel(fixture) {
547
- let profile = this.getProfileByUuid(fixture.profileUuid);
548
- let mode = this.getModeByFixture(profile, fixture);
549
- // add the unique pixel keys
550
- for (let channel of mode.channels) {
551
- if (this.getPixelKeysInOrder(profile, channel.repeatFor).length === 0) {
552
- return true;
553
- }
554
- }
555
- return false;
556
- }
557
- updateCachedFixtures() {
558
- // calculate some frequently used values as a cache to save cpu time
559
- // afterwards
560
- this.cachedFixtures = [];
561
- for (const fixture of this.projectService.project.fixtures) {
562
- if (this.fixtureHasGeneralChannel(fixture)) {
563
- const cachedFixture = new CachedFixture();
564
- cachedFixture.fixture = fixture;
565
- cachedFixture.profile = this.getProfileByUuid(fixture.profileUuid);
566
- cachedFixture.mode = this.getModeByFixture(cachedFixture.profile, fixture);
567
- cachedFixture.channels = this.getCachedChannels(cachedFixture.profile, cachedFixture.mode, null);
568
- this.cachedFixtures.push(cachedFixture);
569
- }
570
- const pixelKeys = this.fixtureGetUniquePixelKeys(fixture);
571
- for (let pixelKey of pixelKeys) {
572
- const cachedFixture = new CachedFixture();
573
- cachedFixture.fixture = fixture;
574
- cachedFixture.pixelKey = pixelKey;
575
- cachedFixture.profile = this.getProfileByUuid(fixture.profileUuid);
576
- cachedFixture.mode = this.getModeByFixture(cachedFixture.profile, fixture);
577
- cachedFixture.channels = this.getCachedChannels(cachedFixture.profile, cachedFixture.mode, pixelKey);
578
- this.cachedFixtures.push(cachedFixture);
579
- }
580
- }
581
- }
582
- capabilitiesMatch(type1, type2, color1, color2, wheel1, wheel2, profileUuid1, profileUuid2) {
583
- // checks, whether two provided capapabilities match
584
- return (type1 === type2 &&
585
- (!color1 || color1 === color2) &&
586
- (!wheel1 || wheel1 === wheel2) &&
587
- (!profileUuid1 || profileUuid1 === profileUuid2));
588
- }
589
- settingsFixtureIsSelected(fixture) {
590
- for (const selectedFixture of this.selectedSettingsFixtures) {
591
- if (selectedFixture === fixture) {
592
- return true;
593
- }
594
- }
595
- return false;
596
- }
597
- switchSettingsFixtureSelection(fixture) {
598
- if (this.settingsFixtureIsSelected(fixture)) {
599
- this.selectedSettingsFixtures.splice(this.selectedSettingsFixtures.indexOf(fixture), 1);
600
- }
601
- else {
602
- this.selectedSettingsFixtures.push(fixture);
603
- }
604
- }
605
- getFixtureIconClass(profile) {
606
- if (!profile) {
607
- return '';
608
- }
609
- if (profile.categories.length === 0) {
610
- return '';
611
- }
612
- if (!profile.categories[0]) {
613
- return '';
614
- }
615
- return profile.categories[0].replace(' ', '-').toLocaleLowerCase();
616
- }
617
- updateProfiles() {
618
- return this.http.post('update-profiles', null);
619
- }
620
- getNextFreeDmxChannel(fixturePool, neededChannels) {
621
- // get the next free space for this fixture
622
- let freeChannels = 0;
623
- for (let i = 0; i < 512; i++) {
624
- let occupiedChannels = 0;
625
- for (const fixture of fixturePool) {
626
- const profile = this.getProfileByUuid(fixture.profileUuid);
627
- const mode = this.getModeByFixture(this.getProfileByUuid(fixture.profileUuid), fixture);
628
- const channelCount = this.getModeChannelCount(profile, mode);
629
- if (i >= fixture.dmxFirstChannel && i < fixture.dmxFirstChannel + channelCount) {
630
- // this channel is already occupied by a fixture -> move forward to the end of the fixture
631
- if (channelCount > occupiedChannels) {
632
- occupiedChannels = channelCount - (i - fixture.dmxFirstChannel);
633
- }
634
- }
635
- }
636
- if (occupiedChannels > 0) {
637
- i += occupiedChannels - 1;
638
- freeChannels = 0;
639
- }
640
- else {
641
- freeChannels++;
642
- }
643
- if (freeChannels === neededChannels) {
644
- return i - freeChannels + 1;
645
- }
646
- }
647
- // no free space left for the needed channels
648
- return -1;
649
- }
650
- addFixture(profile, fixturePool) {
651
- const fixture = new Fixture();
652
- fixture.uuid = this.uuidService.getUuid();
653
- fixture.profileUuid = profile.uuid;
654
- fixture.name = profile.name;
655
- if (profile.modes && profile.modes.length > 0) {
656
- fixture.modeShortName = profile.modes[0].shortName;
657
- }
658
- // add the same mode as an existing fixture, if available
659
- let existingModeShortName;
660
- for (const existingFixture of fixturePool) {
661
- const existingProfile = this.getProfileByUuid(existingFixture.profileUuid);
662
- if (existingProfile === profile) {
663
- existingModeShortName = existingFixture.modeShortName;
664
- break;
665
- }
666
- }
667
- if (existingModeShortName) {
668
- fixture.modeShortName = existingModeShortName;
669
- }
670
- else {
671
- fixture.modeShortName = profile.modes[0].shortName || profile.modes[0].name;
672
- }
673
- const mode = this.getModeByFixture(profile, fixture);
674
- const channelCount = this.getModeChannelCount(profile, mode);
675
- const firstChannel = this.getNextFreeDmxChannel(fixturePool, channelCount);
676
- if (firstChannel >= 0) {
677
- fixture.dmxFirstChannel = firstChannel;
678
- fixturePool.push(fixture);
679
- return fixture;
680
- }
681
- else {
682
- // no free space anymore
683
- const msg = 'designer.fixture-pool.no-free-space';
684
- const title = 'designer.fixture-pool.no-free-space-title';
685
- this.translateService.get([msg, title]).subscribe((result) => {
686
- this.toastrService.error(result[msg], result[title]);
687
- });
688
- }
689
- }
690
- static { this.ɵfac = function FixtureService_Factory(t) { return new (t || FixtureService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.ProjectService), i0.ɵɵinject(i3.TranslateService), i0.ɵɵinject(i4.ToastrService), i0.ɵɵinject(i5.UuidService)); }; }
691
- static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FixtureService, factory: FixtureService.ɵfac, providedIn: 'root' }); }
692
- }
693
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FixtureService, [{
694
- type: Injectable,
695
- args: [{
696
- providedIn: 'root',
697
- }]
698
- }], () => [{ type: i1.HttpClient }, { type: i2.ProjectService }, { type: i3.TranslateService }, { type: i4.ToastrService }, { type: i5.UuidService }], null); })();
699
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduZXIvc3JjL2xpYi9zZXJ2aWNlcy9maXh0dXJlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFJNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBb0Isb0JBQW9CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7O0FBSzdDLE1BQU0sT0FBTyxjQUFjO0lBUXpCLFlBQ1UsSUFBZ0IsRUFDaEIsY0FBOEIsRUFDOUIsZ0JBQWtDLEVBQ2xDLGFBQTRC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WSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFM0UsSUFBSSxZQUFZLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLGVBQWUsR0FBRyxZQUFZLENBQUM7WUFDdkMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMxQixPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDO2FBQU0sQ0FBQztZQUNOLHdCQUF3QjtZQUN4QixNQUFNLEdBQUcsR0FBRyxxQ0FBcUMsQ0FBQztZQUNsRCxNQUFNLEtBQUssR0FBRywyQ0FBMkMsQ0FBQztZQUUxRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQzNELElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN2RCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDOytFQS93QlUsY0FBYzt1RUFBZCxjQUFjLFdBQWQsY0FBYyxtQkFGYixNQUFNOztpRkFFUCxjQUFjO2NBSDFCLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBUb2FzdHJTZXJ2aWNlIH0gZnJvbSAnbmd4LXRvYXN0cic7XG5pbXBvcnQgeyBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENhY2hlZEZpeHR1cmUgfSBmcm9tICcuLi9tb2RlbHMvY2FjaGVkLWZpeHR1cmUnO1xuaW1wb3J0IHsgQ2FjaGVkRml4dHVyZUNhcGFiaWxpdHkgfSBmcm9tICcuLi9tb2RlbHMvY2FjaGVkLWZpeHR1cmUtY2FwYWJpbGl0eSc7XG5pbXBvcnQgeyBDYWNoZWRGaXh0dXJlQ2hhbm5lbCB9IGZyb20gJy4uL21vZGVscy9jYWNoZWQtZml4dHVyZS1jaGFubmVsJztcbmltcG9ydCB7IENvbG9yIH0gZnJvbSAnLi4vbW9kZWxzL2NvbG9yJztcbmltcG9ydCB7IEZpeHR1cmUgfSBmcm9tICcuLi9tb2RlbHMvZml4dHVyZSc7XG5pbXBvcnQgeyBGaXh0dXJlQ2FwYWJpbGl0eSwgRml4dHVyZUNhcGFiaWxpdHlDb2xvciwgRml4dHVyZUNhcGFiaWxpdHlUeXBlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtY2FwYWJpbGl0eSc7XG5pbXBvcnQgeyBGaXh0dXJlQ2hhbm5lbCB9IGZyb20gJy4uL21vZGVscy9maXh0dXJlLWNoYW5uZWwnO1xuaW1wb3J0IHsgRml4dHVyZU1vZGUgfSBmcm9tICcuLi9tb2RlbHMvZml4dHVyZS1tb2RlJztcbmltcG9ydCB7IEZpeHR1cmVQcm9maWxlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtcHJvZmlsZSc7XG5pbXBvcnQgeyBGaXh0dXJlV2hlZWwgfSBmcm9tICcuLi9tb2RlbHMvZml4dHVyZS13aGVlbCc7XG5pbXBvcnQgeyBGaXh0dXJlV2hlZWxTbG90LCBGaXh0dXJlV2hlZWxTbG90VHlwZSB9IGZyb20gJy4uL21vZGVscy9maXh0dXJlLXdoZWVsLXNsb3QnO1xuaW1wb3J0IHsgUHJvamVjdFNlcnZpY2UgfSBmcm9tICcuL3Byb2plY3Quc2VydmljZSc7XG5pbXBvcnQgeyBVdWlkU2VydmljZSB9IGZyb20gJy4vdXVpZC5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIEZpeHR1cmVTZXJ2aWNlIHtcbiAgY2FjaGVkRml4dHVyZXM6IENhY2hlZEZpeHR1cmVbXSA9IFtdO1xuXG4gIC8vIGlzIHRoZSBzaWRlLXRhYiBzZXR0aW5ncyBjdXJyZW50bHkgc2VsZWN0ZWQ/XG4gIHNldHRpbmdzU2VsZWN0aW9uID0gZmFsc2U7XG5cbiAgc2VsZWN0ZWRTZXR0aW5nc0ZpeHR1cmVzOiBGaXh0dXJlW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBwcm9qZWN0U2VydmljZTogUHJvamVjdFNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RyU2VydmljZTogVG9hc3RyU2VydmljZSxcbiAgICBwcml2YXRlIHV1aWRTZXJ2aWNlOiBVdWlkU2VydmljZVxuICApIHt9XG5cbiAgZ2V0Rml4dHVyZUJ5VXVpZCh1dWlkOiBzdHJpbmcpOiBGaXh0dXJlIHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgdGhpcy5wcm9qZWN0U2VydmljZS5wcm9qZWN0LmZpeHR1cmVzKSB7XG4gICAgICBpZiAoZml4dHVyZS51dWlkID09PSB1dWlkKSB7XG4gICAgICAgIHJldHVybiBmaXh0dXJlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZml4dHVyZVV1aWRBbmRQaXhlbEtleUVxdWFscyhmaXh0dXJlVXVpZDE6IHN0cmluZywgZml4dHVyZVV1aWQyOiBzdHJpbmcsIHBpeGVsS2V5MTogc3RyaW5nLCBwaXhlbEtleTI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmaXh0dXJlVXVpZDEgPT09IGZpeHR1cmVVdWlkMiAmJiAoKHBpeGVsS2V5MSA9PSBudWxsICYmIHBpeGVsS2V5MiA9PSBudWxsKSB8fCBwaXhlbEtleTEgPT09IHBpeGVsS2V5Mik7XG4gIH1cblxuICBnZXRDYWNoZWRGaXh0dXJlQnlVdWlkKHV1aWQ6IHN0cmluZywgcGl4ZWxLZXk6IHN0cmluZyk6IENhY2hlZEZpeHR1cmUge1xuICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiB0aGlzLmNhY2hlZEZpeHR1cmVzKSB7XG4gICAgICBpZiAodGhpcy5maXh0dXJlVXVpZEFuZFBpeGVsS2V5RXF1YWxzKGZpeHR1cmUuZml4dHVyZS51dWlkLCB1dWlkLCBmaXh0dXJlLnBpeGVsS2V5LCBwaXhlbEtleSkpIHtcbiAgICAgICAgcmV0dXJuIGZpeHR1cmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gbm90IHlldCBmb3VuZCAtPiB0cnkgc2VhcmNoaW5nIHRoZSBmaXh0dXJlIHdpdGhvdXQgcGl4ZWxLZXkgZm9yIHRoZSBnZW5lcmFsIGNoYW5uZWxzXG4gICAgaWYgKHBpeGVsS2V5KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiB0aGlzLmNhY2hlZEZpeHR1cmVzKSB7XG4gICAgICBpZiAoIWZpeHR1cmUucGl4ZWxLZXkgJiYgZml4dHVyZS5maXh0dXJlLnV1aWQgPT09IHV1aWQpIHtcbiAgICAgICAgcmV0dXJuIGZpeHR1cmU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0IGFsbCBwcm9maWxlcyB0byBzZWFyY2ggZm9yIChvbmx5IG1ldGFkYXRhKVxuICBnZXRTZWFyY2hQcm9maWxlcygpOiBPYnNlcnZhYmxlPEZpeHR1cmVQcm9maWxlW10+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCgnZml4dHVyZXMnKS5waXBlKFxuICAgICAgbWFwKChyZXNwb25zZTogb2JqZWN0W10pID0+IHtcbiAgICAgICAgY29uc3Qgc2VhcmNoUHJvZmlsZXM6IEZpeHR1cmVQcm9maWxlW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHByb2ZpbGUgb2YgcmVzcG9uc2UpIHtcbiAgICAgICAgICBzZWFyY2hQcm9maWxlcy5wdXNoKG5ldyBGaXh0dXJlUHJvZmlsZShwcm9maWxlKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2VhcmNoUHJvZmlsZXM7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBnZXRQcm9maWxlQnlVdWlkKHV1aWQ6IHN0cmluZyk6IEZpeHR1cmVQcm9maWxlIHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmVQcm9maWxlIG9mIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5maXh0dXJlUHJvZmlsZXMpIHtcbiAgICAgIGlmIChmaXh0dXJlUHJvZmlsZS51dWlkID09PSB1dWlkKSB7XG4gICAgICAgIHJldHVybiBmaXh0dXJlUHJvZmlsZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsb2FkUHJvZmlsZUJ5VXVpZCh1dWlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2FkZWRQcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKHV1aWQpO1xuXG4gICAgaWYgKGxvYWRlZFByb2ZpbGUpIHtcbiAgICAgIC8vIFRoaXMgcHJvZmlsZSBpcyBhbHJlYWR5IGxvYWRlZFxuICAgICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCB0aGUgbWV0YWRhdGEgYW5kIHRoZSBwcm9maWxlXG4gICAgcmV0dXJuIGZvcmtKb2luKFt0aGlzLmh0dHAuZ2V0KCdmaXh0dXJlcz91dWlkPScgKyBlbmNvZGVVUkkodXVpZCkpLCB0aGlzLmh0dHAuZ2V0KCdmaXh0dXJlP3V1aWQ9JyArIGVuY29kZVVSSSh1dWlkKSldKS5waXBlKFxuICAgICAgbWFwKChyZXN1bHQpID0+IHtcbiAgICAgICAgY29uc3QgbWVyZ2VkRGF0YSA9IHsgLi4ucmVzdWx0WzBdWzBdLCAuLi5yZXN1bHRbMV0gfTtcbiAgICAgICAgY29uc3QgZml4dHVyZVByb2ZpbGUgPSBuZXcgRml4dHVyZVByb2ZpbGUobWVyZ2VkRGF0YSk7XG4gICAgICAgIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5maXh0dXJlUHJvZmlsZXMucHVzaChmaXh0dXJlUHJvZmlsZSk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBnZXRSb3RhdGlvbkFuZ2xlRGVnKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIC8vIGNvbnZlcnQgYSByb3RhdGlvbiBhbmdsZSB2YWx1ZSBpbnRvIGRlZ3JlZXNcbiAgICBpZiAodmFsdWUuZW5kc1dpdGgoJ2RlZycpKSB7XG4gICAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHZhbHVlLnJlcGxhY2UoJ2RlZycsICcnKSwgMTApO1xuICAgIH0gZWxzZSBpZiAodmFsdWUuZW5kc1dpdGgoJyUnKSkge1xuICAgICAgY29uc3QgcGVyYyA9IE51bWJlci5wYXJzZUludCh2YWx1ZS5yZXBsYWNlKCclJywgJycpLCAxMCk7XG4gICAgICByZXR1cm4gKHBlcmMgLyAxMDApICogMzYwO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBnZXRXaGVlbFNsb3RDb2xvcnMod2hlZWw6IEZpeHR1cmVXaGVlbCwgc2xvdE51bWJlcjogbnVtYmVyKTogc3RyaW5nW10ge1xuICAgIGxldCBjb2xvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgd2hlZWxTbG90cyA9IHRoaXMuZ2V0V2hlZWxTbG90cyh3aGVlbCwgc2xvdE51bWJlcik7XG5cbiAgICBmb3IgKGNvbnN0IHNsb3Qgb2Ygd2hlZWxTbG90cykge1xuICAgICAgaWYgKHNsb3QuY29sb3JzICYmIHNsb3QuY29sb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29sb3JzID0gY29sb3JzLmNvbmNhdChzbG90LmNvbG9ycyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbG9ycztcbiAgfVxuXG4gIGdldE1peGVkV2hlZWxTbG90Q29sb3Iod2hlZWw6IEZpeHR1cmVXaGVlbCwgc2xvdE51bWJlcjogbnVtYmVyKTogQ29sb3Ige1xuICAgIGNvbnN0IGNvbG9ycyA9IHRoaXMuZ2V0V2hlZWxTbG90Q29sb3JzKHdoZWVsLCBzbG90TnVtYmVyKTtcbiAgICBjb25zdCBjb2xvcnNSZ2I6IENvbG9yW10gPSBbXTtcblxuICAgIGlmIChjb2xvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY29sb3Igb2YgY29sb3JzKSB7XG4gICAgICBjb2xvcnNSZ2IucHVzaCh0aGlzLmhleFRvUmdiKGNvbG9yKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubWl4Q29sb3JzKGNvbG9yc1JnYik7XG4gIH1cblxuICBwcml2YXRlIGNvbXBvbmVudFRvSGV4KGM6IG51bWJlcik6IGFueSB7XG4gICAgY29uc3QgaGV4ID0gYy50b1N0cmluZygxNik7XG4gICAgcmV0dXJuIGhleC5sZW5ndGggPT09IDEgPyAnMCcgKyBoZXggOiBoZXg7XG4gIH1cblxuICByZ2JUb0hleChyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJyMnICsgdGhpcy5jb21wb25lbnRUb0hleChyKSArIHRoaXMuY29tcG9uZW50VG9IZXgoZykgKyB0aGlzLmNvbXBvbmVudFRvSGV4KGIpO1xuICB9XG5cbiAgaGV4VG9SZ2IoaGV4OiBzdHJpbmcpOiBDb2xvciB7XG4gICAgLy8gZXhwYW5kIHNob3J0aGFuZCBmb3JtIChlLmcuIFwiMDNGXCIpIHRvIGZ1bGwgZm9ybSAoZS5nLiBcIjAwMzNGRlwiKVxuICAgIGNvbnN0IHNob3J0aGFuZFJlZ2V4ID0gL14jPyhbYS1mXFxkXSkoW2EtZlxcZF0pKFthLWZcXGRdKSQvaTtcbiAgICBoZXggPSBoZXgucmVwbGFjZShzaG9ydGhhbmRSZWdleCwgKG0sIHIsIGcsIGIpID0+IHtcbiAgICAgIHJldHVybiByICsgciArIGcgKyBnICsgYiArIGI7XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcbiAgICByZXR1cm4gcmVzdWx0ID8gbmV3IENvbG9yKHBhcnNlSW50KHJlc3VsdFsxXSwgMTYpLCBwYXJzZUludChyZXN1bHRbMl0sIDE2KSwgcGFyc2VJbnQocmVzdWx0WzNdLCAxNikpIDogbnVsbDtcbiAgfVxuXG4gIG1peENvbG9ycyhjb2xvcnM6IENvbG9yW10pOiBDb2xvciB7XG4gICAgLy8gbWl4IGFuIGFycmF5IG9mIHJnYi1jb2xvcnMgY29udGFpbmluZyByLCBnLCBiIHZhbHVlcyB0byBhIG5ldyBjb2xvclxuICAgIGxldCByID0gMDtcbiAgICBsZXQgZyA9IDA7XG4gICAgbGV0IGIgPSAwO1xuXG4gICAgZm9yIChjb25zdCBjb2xvciBvZiBjb2xvcnMpIHtcbiAgICAgIHIgKz0gY29sb3IucmVkO1xuICAgICAgZyArPSBjb2xvci5ncmVlbjtcbiAgICAgIGIgKz0gY29sb3IuYmx1ZTtcbiAgICB9XG5cbiAgICByIC89IGNvbG9ycy5sZW5ndGg7XG4gICAgZyAvPSBjb2xvcnMubGVuZ3RoO1xuICAgIGIgLz0gY29sb3JzLmxlbmd0aDtcblxuICAgIHJldHVybiBuZXcgQ29sb3IociwgZywgYik7XG4gIH1cblxuICB3aGVlbEhhc1Nsb3RUeXBlKHdoZWVsOiBGaXh0dXJlV2hlZWwsIHNsb3RUeXBlOiBGaXh0dXJlV2hlZWxTbG90VHlwZSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3Qgc2xvdCBvZiB3aGVlbC5zbG90cykge1xuICAgICAgaWYgKHNsb3QudHlwZSA9PT0gc2xvdFR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0V2hlZWxCeU5hbWUocHJvZmlsZTogRml4dHVyZVByb2ZpbGUsIHdoZWVsTmFtZTogc3RyaW5nKTogRml4dHVyZVdoZWVsIHtcbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHByb2ZpbGUud2hlZWxzKSB7XG4gICAgICBpZiAocHJvcGVydHkgPT09IHdoZWVsTmFtZSkge1xuICAgICAgICByZXR1cm4gcHJvZmlsZS53aGVlbHNbcHJvcGVydHldO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHdoZWVsIG5vdCBmb3VuZFxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldFdoZWVsU2xvdHMod2hlZWw6IEZpeHR1cmVXaGVlbCwgc2xvdE51bWJlcjogbnVtYmVyKTogRml4dHVyZVdoZWVsU2xvdFtdIHtcbiAgICAvLyByZXR1cm4gb25lIHNsb3Qgb3IgdHdvIHNsb3RzLCBpZiB0aGV5IGFyZSBtaXhlZCAoZS5nLiBzbG9yIG51bWJlciAyLjUgcmV0dXJucyB0aGUgc2xvdHMgMiBhbmQgMylcbiAgICBjb25zdCBzbG90czogRml4dHVyZVdoZWVsU2xvdFtdID0gW107XG5cbiAgICBpZiAoIXdoZWVsKSB7XG4gICAgICByZXR1cm4gc2xvdHM7XG4gICAgfVxuXG4gICAgaWYgKHNsb3ROdW1iZXIgLSBNYXRoLmZsb29yKHNsb3ROdW1iZXIpID4gMCkge1xuICAgICAgLy8gdHdvIHNsb3RzIGFyZSBzZXRcbiAgICAgIGNvbnN0IG51bWJlciA9IE1hdGguZmxvb3Ioc2xvdE51bWJlcik7XG4gICAgICBzbG90cy5wdXNoKHdoZWVsLnNsb3RzW251bWJlciAtIDFdKTtcbiAgICAgIGlmIChudW1iZXIgPj0gMCAmJiBudW1iZXIgPCB3aGVlbC5zbG90cy5sZW5ndGgpIHtcbiAgICAgICAgc2xvdHMucHVzaCh3aGVlbC5zbG90c1tudW1iZXJdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb25seSBvbmUgc2xvdCBpcyBzZXRcbiAgICAgIHNsb3RzLnB1c2god2hlZWwuc2xvdHNbc2xvdE51bWJlciAtIDFdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2xvdHM7XG4gIH1cblxuICBnZXRNb2RlQnlGaXh0dXJlKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCBmaXh0dXJlOiBGaXh0dXJlKTogRml4dHVyZU1vZGUge1xuICAgIGZvciAoY29uc3QgbW9kZSBvZiBwcm9maWxlLm1vZGVzKSB7XG4gICAgICBpZiAobW9kZS5zaG9ydE5hbWUpIHtcbiAgICAgICAgaWYgKG1vZGUuc2hvcnROYW1lID09PSBmaXh0dXJlLm1vZGVTaG9ydE5hbWUpIHtcbiAgICAgICAgICByZXR1cm4gbW9kZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKG1vZGUubmFtZSA9PT0gZml4dHVyZS5tb2RlU2hvcnROYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIG1vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEZpeHR1cmVDYXBhYmlsaXR5KGNhcGFiaWxpdHk6IEZpeHR1cmVDYXBhYmlsaXR5LCBjaGFubmVsTmFtZTogc3RyaW5nLCBwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSk6IENhY2hlZEZpeHR1cmVDYXBhYmlsaXR5IHtcbiAgICBjb25zdCBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eSA9IG5ldyBDYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eSgpO1xuICAgIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LmNhcGFiaWxpdHkgPSBjYXBhYmlsaXR5O1xuICAgIGlmIChjYXBhYmlsaXR5LnNsb3ROdW1iZXIpIHtcbiAgICAgIC8vIHRoZXJlIGlzIGEgd2hlZWwgY29ubmVjdGVkIHRvIHRoaXMgY2FwYWJpbGl0eVxuICAgICAgaWYgKHR5cGVvZiBjYXBhYmlsaXR5LndoZWVsID09PSAnc3RyaW5nJykge1xuICAgICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS53aGVlbE5hbWUgPSBjYXBhYmlsaXR5LndoZWVsIGFzIHN0cmluZztcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjYXBhYmlsaXR5LndoZWVsKSkge1xuICAgICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS53aGVlbE5hbWUgPSBjYXBhYmlsaXR5LndoZWVsWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWxOYW1lID0gY2hhbm5lbE5hbWU7XG4gICAgICB9XG4gICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS53aGVlbCA9IHRoaXMuZ2V0V2hlZWxCeU5hbWUocHJvZmlsZSwgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWxOYW1lKTtcbiAgICAgIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LndoZWVsU2xvdHMgPSB0aGlzLmdldFdoZWVsU2xvdHMoY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWwsIGNhcGFiaWxpdHkuc2xvdE51bWJlcik7XG4gICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS53aGVlbElzQ29sb3IgPSB0aGlzLndoZWVsSGFzU2xvdFR5cGUoY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWwsIEZpeHR1cmVXaGVlbFNsb3RUeXBlLkNvbG9yKTtcbiAgICB9XG4gICAgaWYgKGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LmNhcGFiaWxpdHkuZG14UmFuZ2UgJiYgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkuY2FwYWJpbGl0eS5kbXhSYW5nZS5sZW5ndGggPT09IDIpIHtcbiAgICAgIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LmNlbnRlclZhbHVlID0gTWF0aC5mbG9vcihcbiAgICAgICAgKGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LmNhcGFiaWxpdHkuZG14UmFuZ2VbMF0gKyBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LmRteFJhbmdlWzFdKSAvIDJcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2FwYWJpbGl0aWVzQnlDaGFubmVsKFxuICAgIGZpeHR1cmVDaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCxcbiAgICBjaGFubmVsTmFtZTogc3RyaW5nLFxuICAgIHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlXG4gICk6IENhY2hlZEZpeHR1cmVDYXBhYmlsaXR5W10ge1xuICAgIGNvbnN0IGNhcGFiaWxpdGVzOiBDYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eVtdID0gW107XG5cbiAgICBpZiAoZml4dHVyZUNoYW5uZWwuY2FwYWJpbGl0eSkge1xuICAgICAgY2FwYWJpbGl0ZXMucHVzaCh0aGlzLmdldEZpeHR1cmVDYXBhYmlsaXR5KGZpeHR1cmVDaGFubmVsLmNhcGFiaWxpdHksIGNoYW5uZWxOYW1lLCBwcm9maWxlKSk7XG4gICAgfSBlbHNlIGlmIChmaXh0dXJlQ2hhbm5lbC5jYXBhYmlsaXRpZXMpIHtcbiAgICAgIGZvciAoY29uc3QgY2FwYWJpbGl0eSBvZiBmaXh0dXJlQ2hhbm5lbC5jYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgY2FwYWJpbGl0ZXMucHVzaCh0aGlzLmdldEZpeHR1cmVDYXBhYmlsaXR5KGNhcGFiaWxpdHksIGNoYW5uZWxOYW1lLCBwcm9maWxlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhcGFiaWxpdGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRNYXhWYWx1ZUJ5Q2hhbm5lbChmaXh0dXJlQ2hhbm5lbDogRml4dHVyZUNoYW5uZWwpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLnBvdygyNTYsIDEgKyBmaXh0dXJlQ2hhbm5lbC5maW5lQ2hhbm5lbEFsaWFzZXMubGVuZ3RoKSAtIDE7XG4gIH1cblxuICBwcml2YXRlIGdldERlZmF1bHRWYWx1ZUJ5Q2hhbm5lbChmaXh0dXJlQ2hhbm5lbDogRml4dHVyZUNoYW5uZWwpOiBudW1iZXIge1xuICAgIGlmICghZml4dHVyZUNoYW5uZWwuZGVmYXVsdFZhbHVlKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChpc05hTihmaXh0dXJlQ2hhbm5lbC5kZWZhdWx0VmFsdWUgYXMgYW55KSAmJiAoZml4dHVyZUNoYW5uZWwuZGVmYXVsdFZhbHVlIGFzIHN0cmluZykuZW5kc1dpdGgoJyUnKSkge1xuICAgICAgLy8gcGVyY2VudGFnZSB2YWx1ZVxuICAgICAgY29uc3QgcGVyY2VudGFnZSA9IE51bWJlci5wYXJzZUludCgoZml4dHVyZUNoYW5uZWwuZGVmYXVsdFZhbHVlIGFzIHN0cmluZykucmVwbGFjZSgnJScsICcnKSwgMTApO1xuICAgICAgY29uc3QgbWF4VmFsdWUgPSB0aGlzLmdldE1heFZhbHVlQnlDaGFubmVsKGZpeHR1cmVDaGFubmVsKTtcbiAgICAgIHJldHVybiAobWF4VmFsdWUgLyAxMDApICogcGVyY2VudGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRE1YIHZhbHVlXG4gICAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KGZpeHR1cmVDaGFubmVsLmRlZmF1bHRWYWx1ZSBhcyBhbnksIDEwKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldENvbG9yV2hlZWxCeUNoYW5uZWwoY2hhbm5lbDogQ2FjaGVkRml4dHVyZUNoYW5uZWwsIHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlKTogRml4dHVyZVdoZWVsIHtcbiAgICBmb3IgKGNvbnN0IGNoYW5uZWxDYXBhYmlsaXR5IG9mIGNoYW5uZWwuY2FwYWJpbGl0aWVzKSB7XG4gICAgICBpZiAoY2hhbm5lbENhcGFiaWxpdHkud2hlZWxJc0NvbG9yKSB7XG4gICAgICAgIHJldHVybiBjaGFubmVsQ2FwYWJpbGl0eS53aGVlbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0Q2hhbm5lbEJ5TmFtZShmaXh0dXJlOiBDYWNoZWRGaXh0dXJlLCBjaGFubmVsTmFtZTogc3RyaW5nKTogQ2FjaGVkRml4dHVyZUNoYW5uZWwge1xuICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBmaXh0dXJlLmNoYW5uZWxzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChjaGFubmVsLm5hbWUgJiYgY2hhbm5lbC5uYW1lID09PSBjaGFubmVsTmFtZSkgfHxcbiAgICAgICAgKGNoYW5uZWwuY2hhbm5lbCAmJiBjaGFubmVsLmNoYW5uZWwuZmluZUNoYW5uZWxBbGlhc2VzLmluZGV4T2YoY2hhbm5lbE5hbWUpID4gLTEpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGNoYW5uZWw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2hhbm5lbE5hbWVXaXRoUGl4ZWxLZXkodGVtcGxhdGVDaGFubmVsTmFtZTogc3RyaW5nLCBwaXhlbEtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlQ2hhbm5lbE5hbWUucmVwbGFjZSgnJHBpeGVsS2V5JywgcGl4ZWxLZXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRDYWNoZWRDaGFubmVsKFxuICAgIGNoYW5uZWxzOiBDYWNoZWRGaXh0dXJlQ2hhbm5lbFtdLFxuICAgIGNoYW5uZWw6IEZpeHR1cmVDaGFubmVsLFxuICAgIHRlbXBsYXRlQ2hhbm5lbE5hbWU6IHN0cmluZyxcbiAgICBwaXhlbEtleTogc3RyaW5nLFxuICAgIHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlXG4gICkge1xuICAgIGNvbnN0IGNhY2hlZEZpeHR1cmVDaGFubmVsID0gbmV3IENhY2hlZEZpeHR1cmVDaGFubmVsKCk7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSB0aGlzLmdldENoYW5uZWxOYW1lV2l0aFBpeGVsS2V5KHRlbXBsYXRlQ2hhbm5lbE5hbWUsIHBpeGVsS2V5KTtcblxuICAgIGNhY2hlZEZpeHR1cmVDaGFubmVsLmNoYW5uZWwgPSBjaGFubmVsO1xuICAgIGNhY2hlZEZpeHR1cmVDaGFubmVsLm5hbWUgPSBjaGFubmVsTmFtZTtcbiAgICBjYWNoZWRGaXh0dXJlQ2hhbm5lbC5jYXBhYmlsaXRpZXMgPSB0aGlzLmdldENhcGFiaWxpdGllc0J5Q2hhbm5lbChjYWNoZWRGaXh0dXJlQ2hhbm5lbC5jaGFubmVsLCBjaGFubmVsTmFtZSwgcHJvZmlsZSk7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5nZXREZWZhdWx0VmFsdWVCeUNoYW5uZWwoY2FjaGVkRml4dHVyZUNoYW5uZWwuY2hhbm5lbCk7XG4gICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgY2FjaGVkRml4dHVyZUNoYW5uZWwuZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgIH1cbiAgICBjYWNoZWRGaXh0dXJlQ2hhbm5lbC5tYXhWYWx1ZSA9IHRoaXMuZ2V0TWF4VmFsdWVCeUNoYW5uZWwoY2FjaGVkRml4dHVyZUNoYW5uZWwuY2hhbm5lbCk7XG4gICAgY2FjaGVkRml4dHVyZUNoYW5uZWwuY29sb3JXaGVlbCA9IHRoaXMuZ2V0Q29sb3JXaGVlbEJ5Q2hhbm5lbChjYWNoZWRGaXh0dXJlQ2hhbm5lbCwgcHJvZmlsZSk7XG4gICAgY2hhbm5lbHMucHVzaChjYWNoZWRGaXh0dXJlQ2hhbm5lbCk7XG4gIH1cblxuICBwcml2YXRlIGFscGhhbnVtZXJpY1NvcnQoYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiBhLmxvY2FsZUNvbXBhcmUoYiwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUsIHNlbnNpdGl2aXR5OiAnYmFzZScgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEFsbFBpeGVsS2V5cyhwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSkge1xuICAgIGxldCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gICAgaWYoIXByb2ZpbGUubWF0cml4LnBpeGVsS2V5cykge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgZm9yIChsZXQgcGl4ZWxLZXlYIG9mIHByb2ZpbGUubWF0cml4LnBpeGVsS2V5cykge1xuICAgICAgZm9yIChsZXQgcGl4ZWxLZXlZIG9mIHBpeGVsS2V5WCkge1xuICAgICAgICBmb3IgKGxldCBwaXhlbEtleVogb2YgcGl4ZWxLZXlZKSB7XG4gICAgICAgICAgaWYgKHBpeGVsS2V5Wikge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWxLZXlaKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWxsUGl4ZWxHcm91cHMocHJvZmlsZTogRml4dHVyZVByb2ZpbGUpIHtcbiAgICBsZXQgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmKCFwcm9maWxlLm1hdHJpeC5waXhlbEdyb3Vwcykge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBPYmplY3Qua2V5cyhwcm9maWxlLm1hdHJpeC5waXhlbEdyb3VwcykpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHByb3BlcnR5KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGl4ZWxLZXlzSW5PcmRlcihwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgcmVwZWF0Rm9yOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgICBsZXQgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gY291bGQgY29udGFpbiBqdXN0IGEgc2luZ2xlIHN0cmluZyAoZS5nLiAnZWFjaFBpeGVsQUJDJykgb3JcbiAgICBpZiAocmVwZWF0Rm9yLmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIGFuIGFycmF5IG9mIHBpeGVsIChncm91cHMpXG4gICAgICByZXN1bHQgPSByZXBlYXRGb3I7XG4gICAgfSBlbHNlIGlmIChyZXBlYXRGb3IubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsQUJDJykge1xuICAgICAgLy8gR2V0cyBjb21wdXRlZCBpbnRvIGFuIGFscGhhbnVtZXJpY2FsbHkgc29ydGVkIGxpc3Qgb2YgYWxsIHBpeGVsS2V5c1xuICAgICAgaWYgKHByb2ZpbGUubWF0cml4LnBpeGVsQ291bnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudFswXTsgeCsrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbENvdW50WzFdOyB5KyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudFsyXTsgeisrKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKCdQaXhlbCAnICsgKHggKyAxKSArICctJyArICh5ICsgMSkgKyAnLScgKyAoeiArIDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQodGhpcy5nZXRBbGxQaXhlbEtleXMocHJvZmlsZSkpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnNvcnQodGhpcy5hbHBoYW51bWVyaWNTb3J0KTtcbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbEdyb3VwJykge1xuICAgICAgLy8gR2V0cyBjb21wdXRlZCBpbnRvIGFuIGFycmF5IG9mIGFsbCBwaXhlbCBncm91cCBrZXlzLCBvcmRlcmVkIGJ5IGFwcGVhcmFuY2UgaW4gdGhlIEpTT04gZmlsZVxuICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmdldEFsbFBpeGVsR3JvdXBzKHByb2ZpbGUpKTtcbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFhZWicpIHtcbiAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzLmxlbmd0aDsgeCsrKSB7XG4gICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFhaWScpIHtcbiAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzLmxlbmd0aDsgeCsrKSB7XG4gICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdWzBdLmxlbmd0aDsgeisrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFlYWicpIHtcbiAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzLmxlbmd0aDsgeCsrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFlaWCcpIHtcbiAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdW3ldLmxlbmd0aDsgeisrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFpYWScpIHtcbiAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdWzBdLmxlbmd0aDsgeisrKSB7XG4gICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzLmxlbmd0aDsgeCsrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbFpZWCcpIHtcbiAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdWzBdLmxlbmd0aDsgeisrKSB7XG4gICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzWzBdLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZ2V0TW9kZUNoYW5uZWxDb3VudChwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgbW9kZTogRml4dHVyZU1vZGUpOiBudW1iZXIge1xuICAgIGxldCBjb3VudDogbnVtYmVyID0gMDtcblxuICAgIC8vIGFscmVhZHkgY2FsY3VsYXRlZD9cbiAgICBpZiAobW9kZS5jaGFubmVsQ291bnQpIHtcbiAgICAgIHJldHVybiBtb2RlLmNoYW5uZWxDb3VudDtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBjaGFubmVsIG9mIG1vZGUuY2hhbm5lbHMpIHtcbiAgICAgIGlmIChjaGFubmVsLmluc2VydCA9PT0gJ21hdHJpeENoYW5uZWxzJykge1xuICAgICAgICBpZiAoY2hhbm5lbC5yZXBlYXRGb3IubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGNvdW50ICs9IGNoYW5uZWwucmVwZWF0Rm9yLmxlbmd0aCAqIGNoYW5uZWwudGVtcGxhdGVDaGFubmVscy5sZW5ndGg7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbC5yZXBlYXRGb3JbMF0gPT09ICdlYWNoUGl4ZWxHcm91cCcpIHtcbiAgICAgICAgICBjb3VudCArPSBwcm9maWxlLm1hdHJpeC5waXhlbEdyb3Vwcy5sZW5ndGggKiBjaGFubmVsLnRlbXBsYXRlQ2hhbm5lbHMubGVuZ3RoO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYW5uZWwucmVwZWF0Rm9yWzBdLnN0YXJ0c1dpdGgoJ2VhY2hQaXhlbCcpKSB7XG4gICAgICAgICAgaWYgKHByb2ZpbGUubWF0cml4LnBpeGVsQ291bnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICBjb3VudCArPVxuICAgICAgICAgICAgICBwcm9maWxlLm1hdHJpeC5waXhlbENvdW50WzBdICogcHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudFsxXSAqIHByb2ZpbGUubWF0cml4LnBpeGVsQ291bnRbMl0gKiBjaGFubmVsLnRlbXBsYXRlQ2hhbm5lbHMubGVuZ3RoO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5cy5sZW5ndGg7IHgrKykge1xuICAgICAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XS5sZW5ndGg7IHkrKykge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldLmxlbmd0aDsgeisrKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBwaXhlbCA9IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XVt5XVt6XTtcbiAgICAgICAgICAgICAgICAgIGlmIChwaXhlbCkge1xuICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGFubmVsLnRlbXBsYXRlQ2hhbm5lbHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY291bnQrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtb2RlLmNoYW5uZWxDb3VudCA9IGNvdW50O1xuXG4gICAgcmV0dXJuIG1vZGUuY2hhbm5lbENvdW50O1xuICB9XG5cbiAgZ2V0Q2FjaGVkQ2hhbm5lbHMocHJvZmlsZTogRml4dHVyZVByb2ZpbGUsIG1vZGU6IEZpeHR1cmVNb2RlLCBwaXhlbEtleTogc3RyaW5nKTogQ2FjaGVkRml4dHVyZUNoYW5uZWxbXSB7XG4gICAgY29uc3QgY2hhbm5lbHM6IENhY2hlZEZpeHR1cmVDaGFubmVsW10gPSBbXTtcblxuICAgIGlmICghbW9kZSkge1xuICAgICAgcmV0dXJuIGNoYW5uZWxzO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBtb2RlLmNoYW5uZWxzKSB7XG4gICAgICBpZiAoY2hhbm5lbC5uYW1lICYmICFwaXhlbEtleSkge1xuICAgICAgICAvLyBkaXJlY3QgcmVmZXJlbmNlIHRvIGEgY2hhbm5lbFxuICAgICAgICAvLyBkb24ndCBjaGVjayB0aGUgZmluZSBjaGFubmVscy4gb25seSBhZGQgdGhlIGNvYXJzZSBjaGFubmVsLlxuICAgICAgICBsZXQgY2hhbm5lbEZvdW5kID0gZmFsc2U7XG5cbiAgICAgICAgZm9yIChjb25zdCBhdmFpbGFibGVDaGFubmVsTmFtZSBvZiBPYmplY3Qua2V5cyhwcm9maWxlLmF2YWlsYWJsZUNoYW5uZWxzKSkge1xuICAgICAgICAgIGlmIChjaGFubmVsLm5hbWUgPT09IGF2YWlsYWJsZUNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBhdmFpbGFibGVDaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCA9IHByb2ZpbGUuYXZhaWxhYmxlQ2hhbm5lbHNbYXZhaWxhYmxlQ2hhbm5lbE5hbWVdO1xuXG4gICAgICAgICAgICB0aGlzLmFkZENhY2hlZENoYW5uZWwoY2hhbm5lbHMsIGF2YWlsYWJsZUNoYW5uZWwsIGF2YWlsYWJsZUNoYW5uZWxOYW1lLCBudWxsLCBwcm9maWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGVjayB0aGUgdGVtcGxhdGUgY2hhbm5lbHMsIGlmIG5vdCBmb3VuZCBpbiB0aGUgYXZhaWxhYmxlIGNoYW5uZWxzXG4gICAgICAgIGlmICghY2hhbm5lbEZvdW5kKSB7XG4gICAgICAgICAgZm9yIChjb25zdCB0ZW1wbGF0ZUNoYW5uZWxOYW1lIG9mIE9iamVjdC5rZXlzKHByb2ZpbGUudGVtcGxhdGVDaGFubmVscykpIHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZ1BpeGVsS2V5cyA9IHRoaXMuZ2V0QWxsUGl4ZWxLZXlzKHByb2ZpbGUpLmNvbmNhdCh0aGlzLmdldEFsbFBpeGVsR3JvdXBzKHByb2ZpbGUpKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBleGlzdGluZ1BpeGVsS2V5IG9mIGV4aXN0aW5nUGl4ZWxLZXlzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gdGhpcy5nZXRDaGFubmVsTmFtZVdpdGhQaXhlbEtleSh0ZW1wbGF0ZUNoYW5uZWxOYW1lLCBleGlzdGluZ1BpeGVsS2V5KTtcblxuICAgICAgICAgICAgICBpZiAoY2hhbm5lbC5uYW1lID09PSBjaGFubmVsTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlQ2hhbm5lbDogRml4dHVyZUNoYW5uZWwgPSBwcm9maWxlLnRlbXBsYXRlQ2hhbm5lbHNbdGVtcGxhdGVDaGFubmVsTmFtZV07XG5cbiAgICAgICAgICAgICAgICB0aGlzLmFkZENhY2hlZENoYW5uZWwoY2hhbm5lbHMsIHRlbXBsYXRlQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGV4aXN0aW5nUGl4ZWxLZXksIHByb2ZpbGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyByZWZlcmVuY2UgYSBjaGFubmVsIHRocm91Z2ggYSBwaXhlbCBtYXRyaXhcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlUGl4ZWxLZXlzID0gdGhpcy5nZXRQaXhlbEtleXNJbk9yZGVyKHByb2ZpbGUsIGNoYW5uZWwucmVwZWF0Rm9yKTtcblxuICAgICAgICBpZiAoY2hhbm5lbC5jaGFubmVsT3JkZXIgPT09ICdwZXJQaXhlbCcpIHtcbiAgICAgICAgICAvLyBlYWNoIGNoYW5uZWwgZm9yIGVhY2ggcGl4ZWxcblxuICAgICAgICAgIGZvciAoY29uc3QgYXZhaWxhYmxlUGl4ZWxLZXkgb2YgYXZhaWxhYmxlUGl4ZWxLZXlzKSB7XG4gICAgICAgICAgICBpZiAoYXZhaWxhYmxlUGl4ZWxLZXkgPT09IHBpeGVsS2V5KSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgbW9kZVRlbXBsYXRlQ2hhbm5lbE5hbWUgb2YgY2hhbm5lbC50ZW1wbGF0ZUNoYW5uZWxzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0ZW1wbGF0ZUNoYW5uZWxOYW1lIG9mIE9iamVjdC5rZXlzKHByb2ZpbGUudGVtcGxhdGVDaGFubmVscykpIHtcbiAgICAgICAgICAgICAgICAgIC8vIGRvbid0IGNoZWNrIHRoZSBmaW5lIGNoYW5uZWxzLiBvbmx5IGFkZCB0aGUgY29hcnNlIGNoYW5uZWwuXG4gICAgICAgICAgICAgICAgICBpZiAobW9kZVRlbXBsYXRlQ2hhbm5lbE5hbWUgPT09IHRlbXBsYXRlQ2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVDaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCA9IHByb2ZpbGUudGVtcGxhdGVDaGFubmVsc1t0ZW1wbGF0ZUNoYW5uZWxOYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZENhY2hlZENoYW5uZWwoY2hhbm5lbHMsIHRlbXBsYXRlQ2hhbm5lbCwgdGVtcGxhdGVDaGFubmVsTmFtZSwgYXZhaWxhYmxlUGl4ZWxLZXksIHByb2ZpbGUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChjaGFubmVsLmNoYW5uZWxPcmRlciA9PT0gJ3BlckNoYW5uZWwnKSB7XG4gICAgICAgICAgLy8gZWFjaCBwaXhlbCBmb3IgZWFjaCBjaGFubmVsXG5cbiAgICAgICAgICBmb3IgKGNvbnN0IG1vZGVUZW1wbGF0ZUNoYW5uZWxOYW1lIG9mIGNoYW5uZWwudGVtcGxhdGVDaGFubmVscykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhdmFpbGFibGVQaXhlbEtleSBvZiBhdmFpbGFibGVQaXhlbEtleXMpIHtcbiAgICAgICAgICAgICAgaWYgKGF2YWlsYWJsZVBpeGVsS2V5ID09PSBwaXhlbEtleSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdGVtcGxhdGVDaGFubmVsTmFtZSBvZiBPYmplY3Qua2V5cyhwcm9maWxlLnRlbXBsYXRlQ2hhbm5lbHMpKSB7XG4gICAgICAgICAgICAgICAgICAvLyBkb24ndCBjaGVjayB0aGUgZmluZSBjaGFubmVscy4gb25seSBhZGQgdGhlIGNvYXJzZSBjaGFubmVsLlxuICAgICAgICAgICAgICAgICAgaWYgKG1vZGVUZW1wbGF0ZUNoYW5uZWxOYW1lID09PSB0ZW1wbGF0ZUNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlQ2hhbm5lbDogRml4dHVyZUNoYW5uZWwgPSBwcm9maWxlLnRlbXBsYXRlQ2hhbm5lbHNbdGVtcGxhdGVDaGFubmVsTmFtZV07XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRDYWNoZWRDaGFubmVsKGNoYW5uZWxzLCB0ZW1wbGF0ZUNoYW5uZWwsIHRlbXBsYXRlQ2hhbm5lbE5hbWUsIGF2YWlsYWJsZVBpeGVsS2V5LCBwcm9maWxlKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2hhbm5lbHM7XG4gIH1cblxuICBmaXh0dXJlR2V0VW5pcXVlUGl4ZWxLZXlzKGZpeHR1cmU6IEZpeHR1cmUpOiBzdHJpbmdbXSB7XG4gICAgbGV0IHBpeGVsS2V5czogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgICBsZXQgcHJvZmlsZSA9IHRoaXMuZ2V0UHJvZmlsZUJ5VXVpZChmaXh0dXJlLnByb2ZpbGVVdWlkKTtcbiAgICBsZXQgbW9kZSA9IHRoaXMuZ2V0TW9kZUJ5Rml4dHVyZShwcm9maWxlLCBmaXh0dXJlKTtcblxuICAgIC8vIGFkZCB0aGUgdW5pcXVlIHBpeGVsIGtleXNcbiAgICBmb3IgKGxldCBjaGFubmVsIG9mIG1vZGUuY2hhbm5lbHMpIHtcbiAgICAgIHRoaXMuZ2V0UGl4ZWxLZXlzSW5PcmRlcihwcm9maWxlLCBjaGFubmVsLnJlcGVhdEZvcikuZm9yRWFjaCgoc3RyKSA9PiB7XG4gICAgICAgIHBpeGVsS2V5cy5hZGQoc3RyKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBBcnJheS5mcm9tKHBpeGVsS2V5cyk7XG4gIH1cblxuICAvLyBkb2VzIHRoZSBmaXh0dXJlIGhhdmUgYSBnZW5lcmFsIGNoYW5uZWwgd2l0aG91dCByZWZlcmVuY2UgdG8gc3BlY2lmaWMgcGl4ZWwga2V5cyBpbiB0aGUgY3VycmVudCBtb2RlP1xuICBmaXh0dXJlSGFzR2VuZXJhbENoYW5uZWwoZml4dHVyZTogRml4dHVyZSk6IGJvb2xlYW4ge1xuICAgIGxldCBwcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpO1xuICAgIGxldCBtb2RlID0gdGhpcy5nZXRNb2RlQnlGaXh0dXJlKHByb2ZpbGUsIGZpeHR1cmUpO1xuXG4gICAgLy8gYWRkIHRoZSB1bmlxdWUgcGl4ZWwga2V5c1xuICAgIGZvciAobGV0IGNoYW5uZWwgb2YgbW9kZS5jaGFubmVscykge1xuICAgICAgaWYgKHRoaXMuZ2V0UGl4ZWxLZXlzSW5PcmRlcihwcm9maWxlLCBjaGFubmVsLnJlcGVhdEZvcikubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHVwZGF0ZUNhY2hlZEZpeHR1cmVzKCkge1xuICAgIC8vIGNhbGN1bGF0ZSBzb21lIGZyZXF1ZW50bHkgdXNlZCB2YWx1ZXMgYXMgYSBjYWNoZSB0byBzYXZlIGNwdSB0aW1lXG4gICAgLy8gYWZ0ZXJ3YXJkc1xuICAgIHRoaXMuY2FjaGVkRml4dHVyZXMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuZml4dHVyZXMpIHtcbiAgICAgIGlmICh0aGlzLmZpeHR1cmVIYXNHZW5lcmFsQ2hhbm5lbChmaXh0dXJlKSkge1xuICAgICAgICBjb25zdCBjYWNoZWRGaXh0dXJlID0gbmV3IENhY2hlZEZpeHR1cmUoKTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5maXh0dXJlID0gZml4dHVyZTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5wcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLm1vZGUgPSB0aGlzLmdldE1vZGVCeUZpeHR1cmUoY2FjaGVkRml4dHVyZS5wcm9maWxlLCBmaXh0dXJlKTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5jaGFubmVscyA9IHRoaXMuZ2V0Q2FjaGVkQ2hhbm5lbHMoY2FjaGVkRml4dHVyZS5wcm9maWxlLCBjYWNoZWRGaXh0dXJlLm1vZGUsIG51bGwpO1xuICAgICAgICB0aGlzLmNhY2hlZEZpeHR1cmVzLnB1c2goY2FjaGVkRml4dHVyZSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBpeGVsS2V5cyA9IHRoaXMuZml4dHVyZUdldFVuaXF1ZVBpeGVsS2V5cyhmaXh0dXJlKTtcblxuICAgICAgZm9yIChsZXQgcGl4ZWxLZXkgb2YgcGl4ZWxLZXlzKSB7XG4gICAgICAgIGNvbnN0IGNhY2hlZEZpeHR1cmUgPSBuZXcgQ2FjaGVkRml4dHVyZSgpO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLmZpeHR1cmUgPSBmaXh0dXJlO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLnBpeGVsS2V5ID0gcGl4ZWxLZXk7XG4gICAgICAgIGNhY2hlZEZpeHR1cmUucHJvZmlsZSA9IHRoaXMuZ2V0UHJvZmlsZUJ5VXVpZChmaXh0dXJlLnByb2ZpbGVVdWlkKTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5tb2RlID0gdGhpcy5nZXRNb2RlQnlGaXh0dXJlKGNhY2hlZEZpeHR1cmUucHJvZmlsZSwgZml4dHVyZSk7XG4gICAgICAgIGNhY2hlZEZpeHR1cmUuY2hhbm5lbHMgPSB0aGlzLmdldENhY2hlZENoYW5uZWxzKGNhY2hlZEZpeHR1cmUucHJvZmlsZSwgY2FjaGVkRml4dHVyZS5tb2RlLCBwaXhlbEtleSk7XG4gICAgICAgIHRoaXMuY2FjaGVkRml4dHVyZXMucHVzaChjYWNoZWRGaXh0dXJlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjYXBhYmlsaXRpZXNNYXRjaChcbiAgICB0eXBlMTogRml4dHVyZUNhcGFiaWxpdHlUeXBlLFxuICAgIHR5cGUyOiBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUsXG4gICAgY29sb3IxOiBGaXh0dXJlQ2FwYWJpbGl0eUNvbG9yLFxuICAgIGNvbG9yMjogRml4dHVyZUNhcGFiaWxpdHlDb2xvcixcbiAgICB3aGVlbDE6IHN0cmluZyxcbiAgICB3aGVlbDI6IHN0cmluZyxcbiAgICBwcm9maWxlVXVpZDE6IHN0cmluZyxcbiAgICBwcm9maWxlVXVpZDI6IHN0cmluZ1xuICApOiBib29sZWFuIHtcbiAgICAvLyBjaGVja3MsIHdoZXRoZXIgdHdvIHByb3ZpZGVkIGNhcGFwYWJpbGl0aWVzIG1hdGNoXG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGUxID09PSB0eXBlMiAmJlxuICAgICAgKCFjb2xvcjEgfHwgY29sb3IxID09PSBjb2xvcjIpICYmXG4gICAgICAoIXdoZWVsMSB8fCB3aGVlbDEgPT09IHdoZWVsMikgJiZcbiAgICAgICghcHJvZmlsZVV1aWQxIHx8IHByb2ZpbGVVdWlkMSA9PT0gcHJvZmlsZVV1aWQyKVxuICAgICk7XG4gIH1cblxuICBzZXR0aW5nc0ZpeHR1cmVJc1NlbGVjdGVkKGZpeHR1cmU6IEZpeHR1cmUpOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdGVkRml4dHVyZSBvZiB0aGlzLnNlbGVjdGVkU2V0dGluZ3NGaXh0dXJlcykge1xuICAgICAgaWYgKHNlbGVjdGVkRml4dHVyZSA9PT0gZml4dHVyZSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzd2l0Y2hTZXR0aW5nc0ZpeHR1cmVTZWxlY3Rpb24oZml4dHVyZTogRml4dHVyZSkge1xuICAgIGlmICh0aGlzLnNldHRpbmdzRml4dHVyZUlzU2VsZWN0ZWQoZml4dHVyZSkpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRTZXR0aW5nc0ZpeHR1cmVzLnNwbGljZSh0aGlzLnNlbGVjdGVkU2V0dGluZ3NGaXh0dXJlcy5pbmRleE9mKGZpeHR1cmUpLCAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFNldHRpbmdzRml4dHVyZXMucHVzaChmaXh0dXJlKTtcbiAgICB9XG4gIH1cblxuICBnZXRGaXh0dXJlSWNvbkNsYXNzKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlKTogc3RyaW5nIHtcbiAgICBpZiAoIXByb2ZpbGUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKHByb2ZpbGUuY2F0ZWdvcmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKCFwcm9maWxlLmNhdGVnb3JpZXNbMF0pIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHByb2ZpbGUuY2F0ZWdvcmllc1swXS5yZXBsYWNlKCcgJywgJy0nKS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICB9XG5cbiAgdXBkYXRlUHJvZmlsZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KCd1cGRhdGUtcHJvZmlsZXMnLCBudWxsKTtcbiAgfVxuXG4gIGdldE5leHRGcmVlRG14Q2hhbm5lbChmaXh0dXJlUG9vbDogRml4dHVyZVtdLCBuZWVkZWRDaGFubmVsczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAvLyBnZXQgdGhlIG5leHQgZnJlZSBzcGFjZSBmb3IgdGhpcyBmaXh0dXJlXG4gICAgbGV0IGZyZWVDaGFubmVscyA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDUxMjsgaSsrKSB7XG4gICAgICBsZXQgb2NjdXBpZWRDaGFubmVscyA9IDA7XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlUG9vbCkge1xuICAgICAgICBjb25zdCBwcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpO1xuICAgICAgICBjb25zdCBtb2RlID0gdGhpcy5nZXRNb2RlQnlGaXh0dXJlKHRoaXMuZ2V0UHJvZmlsZUJ5VXVpZChmaXh0dXJlLnByb2ZpbGVVdWlkKSwgZml4dHVyZSk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxDb3VudCA9IHRoaXMuZ2V0TW9kZUNoYW5uZWxDb3VudChwcm9maWxlLCBtb2RlKTtcblxuICAgICAgICBpZiAoaSA+PSBmaXh0dXJlLmRteEZpcnN0Q2hhbm5lbCAmJiBpIDwgZml4dHVyZS5kbXhGaXJzdENoYW5uZWwgKyBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAvLyB0aGlzIGNoYW5uZWwgaXMgYWxyZWFkeSBvY2N1cGllZCBieSBhIGZpeHR1cmUgLT4gbW92ZSBmb3J3YXJkIHRvIHRoZSBlbmQgb2YgdGhlIGZpeHR1cmVcbiAgICAgICAgICBpZiAoY2hhbm5lbENvdW50ID4gb2NjdXBpZWRDaGFubmVscykge1xuICAgICAgICAgICAgb2NjdXBpZWRDaGFubmVscyA9IGNoYW5uZWxDb3VudCAtIChpIC0gZml4dHVyZS5kbXhGaXJzdENoYW5uZWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob2NjdXBpZWRDaGFubmVscyA+IDApIHtcbiAgICAgICAgaSArPSBvY2N1cGllZENoYW5uZWxzIC0gMTtcbiAgICAgICAgZnJlZUNoYW5uZWxzID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyZWVDaGFubmVscysrO1xuICAgICAgfVxuXG4gICAgICBpZiAoZnJlZUNoYW5uZWxzID09PSBuZWVkZWRDaGFubmVscykge1xuICAgICAgICByZXR1cm4gaSAtIGZyZWVDaGFubmVscyArIDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gbm8gZnJlZSBzcGFjZSBsZWZ0IGZvciB0aGUgbmVlZGVkIGNoYW5uZWxzXG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgYWRkRml4dHVyZShwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgZml4dHVyZVBvb2w6IEZpeHR1cmVbXSk6IEZpeHR1cmUge1xuICAgIGNvbnN0IGZpeHR1cmUgPSBuZXcgRml4dHVyZSgpO1xuXG4gICAgZml4dHVyZS51dWlkID0gdGhpcy51dWlkU2VydmljZS5nZXRVdWlkKCk7XG4gICAgZml4dHVyZS5wcm9maWxlVXVpZCA9IHByb2ZpbGUudXVpZDtcbiAgICBmaXh0dXJlLm5hbWUgPSBwcm9maWxlLm5hbWU7XG5cbiAgICBpZiAocHJvZmlsZS5tb2RlcyAmJiBwcm9maWxlLm1vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZpeHR1cmUubW9kZVNob3J0TmFtZSA9IHByb2ZpbGUubW9kZXNbMF0uc2hvcnROYW1lO1xuICAgIH1cblxuICAgIC8vIGFkZCB0aGUgc2FtZSBtb2RlIGFzIGFuIGV4aXN0aW5nIGZpeHR1cmUsIGlmIGF2YWlsYWJsZVxuICAgIGxldCBleGlzdGluZ01vZGVTaG9ydE5hbWU6IHN0cmluZztcbiAgICBmb3IgKGNvbnN0IGV4aXN0aW5nRml4dHVyZSBvZiBmaXh0dXJlUG9vbCkge1xuICAgICAgY29uc3QgZXhpc3RpbmdQcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGV4aXN0aW5nRml4dHVyZS5wcm9maWxlVXVpZCk7XG5cbiAgICAgIGlmIChleGlzdGluZ1Byb2ZpbGUgPT09IHByb2ZpbGUpIHtcbiAgICAgICAgZXhpc3RpbmdNb2RlU2hvcnROYW1lID0gZXhpc3RpbmdGaXh0dXJlLm1vZGVTaG9ydE5hbWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleGlzdGluZ01vZGVTaG9ydE5hbWUpIHtcbiAgICAgIGZpeHR1cmUubW9kZVNob3J0TmFtZSA9IGV4aXN0aW5nTW9kZVNob3J0TmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZml4dHVyZS5tb2RlU2hvcnROYW1lID0gcHJvZmlsZS5tb2Rlc1swXS5zaG9ydE5hbWUgfHwgcHJvZmlsZS5tb2Rlc1swXS5uYW1lO1xuICAgIH1cblxuICAgIGNvbnN0IG1vZGUgPSB0aGlzLmdldE1vZGVCeUZpeHR1cmUocHJvZmlsZSwgZml4dHVyZSk7XG4gICAgY29uc3QgY2hhbm5lbENvdW50ID0gdGhpcy5nZXRNb2RlQ2hhbm5lbENvdW50KHByb2ZpbGUsIG1vZGUpO1xuICAgIGNvbnN0IGZpcnN0Q2hhbm5lbCA9IHRoaXMuZ2V0TmV4dEZyZWVEbXhDaGFubmVsKGZpeHR1cmVQb29sLCBjaGFubmVsQ291bnQpO1xuXG4gICAgaWYgKGZpcnN0Q2hhbm5lbCA+PSAwKSB7XG4gICAgICBmaXh0dXJlLmRteEZpcnN0Q2hhbm5lbCA9IGZpcnN0Q2hhbm5lbDtcbiAgICAgIGZpeHR1cmVQb29sLnB1c2goZml4dHVyZSk7XG4gICAgICByZXR1cm4gZml4dHVyZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbm8gZnJlZSBzcGFjZSBhbnltb3JlXG4gICAgICBjb25zdCBtc2cgPSAnZGVzaWduZXIuZml4dHVyZS1wb29sLm5vLWZyZWUtc3BhY2UnO1xuICAgICAgY29uc3QgdGl0bGUgPSAnZGVzaWduZXIuZml4dHVyZS1wb29sLm5vLWZyZWUtc3BhY2UtdGl0bGUnO1xuXG4gICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KFttc2csIHRpdGxlXSkuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgdGhpcy50b2FzdHJTZXJ2aWNlLmVycm9yKHJlc3VsdFttc2ddLCByZXN1bHRbdGl0bGVdKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19