@esotericsoftware/spine-core 4.2.116 → 4.3.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 (129) hide show
  1. package/dist/Animation.d.ts +426 -274
  2. package/dist/Animation.js +1174 -1210
  3. package/dist/AnimationState.d.ts +246 -201
  4. package/dist/AnimationState.js +508 -471
  5. package/dist/AnimationStateData.d.ts +12 -10
  6. package/dist/AnimationStateData.js +19 -20
  7. package/dist/AssetManagerBase.d.ts +27 -21
  8. package/dist/AssetManagerBase.js +67 -43
  9. package/dist/AtlasAttachmentLoader.d.ts +18 -12
  10. package/dist/AtlasAttachmentLoader.js +28 -39
  11. package/dist/Bone.d.ts +15 -109
  12. package/dist/Bone.js +22 -362
  13. package/dist/BoneData.d.ts +13 -28
  14. package/dist/BoneData.js +20 -29
  15. package/dist/BonePose.d.ts +130 -0
  16. package/dist/BonePose.js +426 -0
  17. package/dist/Constraint.d.ts +41 -0
  18. package/dist/Constraint.js +38 -0
  19. package/dist/ConstraintData.d.ts +7 -5
  20. package/dist/ConstraintData.js +5 -9
  21. package/dist/DrawOrder.d.ts +48 -0
  22. package/dist/DrawOrder.js +64 -0
  23. package/dist/Event.d.ts +11 -6
  24. package/dist/Event.js +10 -5
  25. package/dist/EventData.d.ts +10 -6
  26. package/dist/EventData.js +18 -7
  27. package/dist/IkConstraint.d.ts +22 -28
  28. package/dist/IkConstraint.js +115 -117
  29. package/dist/IkConstraintData.d.ts +23 -18
  30. package/dist/IkConstraintData.js +32 -22
  31. package/dist/IkConstraintPose.d.ts +49 -0
  32. package/dist/IkConstraintPose.js +55 -0
  33. package/dist/PathConstraint.d.ts +18 -22
  34. package/dist/PathConstraint.js +160 -136
  35. package/dist/PathConstraintData.d.ts +11 -14
  36. package/dist/PathConstraintData.js +14 -16
  37. package/dist/PathConstraintPose.d.ts +43 -0
  38. package/dist/PathConstraintPose.js +49 -0
  39. package/dist/Physics.d.ts +39 -0
  40. package/dist/Physics.js +41 -0
  41. package/dist/PhysicsConstraint.d.ts +26 -30
  42. package/dist/PhysicsConstraint.js +102 -94
  43. package/dist/PhysicsConstraintData.d.ts +22 -12
  44. package/dist/PhysicsConstraintData.js +23 -12
  45. package/dist/PhysicsConstraintPose.d.ts +47 -0
  46. package/dist/PhysicsConstraintPose.js +55 -0
  47. package/dist/Pose.d.ts +33 -0
  48. package/dist/Pose.js +30 -0
  49. package/dist/Posed.d.ts +58 -0
  50. package/dist/Posed.js +78 -0
  51. package/dist/PosedActive.d.ts +41 -0
  52. package/dist/{attachments/HasTextureRegion.js → PosedActive.js} +17 -2
  53. package/dist/PosedData.d.ts +40 -0
  54. package/dist/PosedData.js +45 -0
  55. package/dist/Skeleton.d.ts +110 -99
  56. package/dist/Skeleton.js +271 -449
  57. package/dist/SkeletonBinary.d.ts +1 -1
  58. package/dist/SkeletonBinary.js +644 -466
  59. package/dist/SkeletonBounds.d.ts +4 -4
  60. package/dist/SkeletonBounds.js +45 -46
  61. package/dist/SkeletonClipping.d.ts +26 -22
  62. package/dist/SkeletonClipping.js +654 -340
  63. package/dist/SkeletonData.d.ts +18 -35
  64. package/dist/SkeletonData.js +57 -97
  65. package/dist/SkeletonJson.d.ts +8 -6
  66. package/dist/SkeletonJson.js +892 -641
  67. package/dist/SkeletonRendererCore.d.ts +58 -0
  68. package/dist/SkeletonRendererCore.js +310 -0
  69. package/dist/Skin.d.ts +20 -16
  70. package/dist/Skin.js +58 -53
  71. package/dist/Slider.d.ts +46 -0
  72. package/dist/Slider.js +115 -0
  73. package/dist/SliderData.d.ts +58 -0
  74. package/dist/SliderData.js +59 -0
  75. package/dist/SliderPose.d.ts +37 -0
  76. package/dist/SliderPose.js +40 -0
  77. package/dist/Slot.d.ts +16 -38
  78. package/dist/Slot.js +37 -60
  79. package/dist/SlotData.d.ts +5 -12
  80. package/dist/SlotData.js +7 -15
  81. package/dist/SlotPose.d.ts +59 -0
  82. package/dist/SlotPose.js +81 -0
  83. package/dist/Texture.d.ts +1 -0
  84. package/dist/Texture.js +2 -1
  85. package/dist/TextureAtlas.d.ts +3 -3
  86. package/dist/TextureAtlas.js +49 -49
  87. package/dist/TransformConstraint.d.ts +16 -28
  88. package/dist/TransformConstraint.js +72 -209
  89. package/dist/TransformConstraintData.d.ts +108 -20
  90. package/dist/TransformConstraintData.js +274 -24
  91. package/dist/TransformConstraintPose.d.ts +45 -0
  92. package/dist/TransformConstraintPose.js +52 -0
  93. package/dist/Triangulator.d.ts +1 -1
  94. package/dist/Triangulator.js +91 -107
  95. package/dist/{Updatable.d.ts → Update.d.ts} +5 -12
  96. package/dist/Update.js +30 -0
  97. package/dist/Utils.d.ts +12 -3
  98. package/dist/Utils.js +78 -37
  99. package/dist/attachments/Attachment.d.ts +27 -19
  100. package/dist/attachments/Attachment.js +59 -35
  101. package/dist/attachments/AttachmentLoader.d.ts +14 -14
  102. package/dist/attachments/AttachmentLoader.js +1 -1
  103. package/dist/attachments/BoundingBoxAttachment.d.ts +1 -1
  104. package/dist/attachments/BoundingBoxAttachment.js +2 -2
  105. package/dist/attachments/ClippingAttachment.d.ts +10 -3
  106. package/dist/attachments/ClippingAttachment.js +12 -3
  107. package/dist/attachments/{HasTextureRegion.d.ts → HasSequence.d.ts} +11 -14
  108. package/dist/attachments/HasSequence.js +30 -0
  109. package/dist/attachments/MeshAttachment.d.ts +28 -35
  110. package/dist/attachments/MeshAttachment.js +85 -97
  111. package/dist/attachments/PathAttachment.d.ts +3 -3
  112. package/dist/attachments/PathAttachment.js +6 -6
  113. package/dist/attachments/PointAttachment.d.ts +11 -6
  114. package/dist/attachments/PointAttachment.js +8 -3
  115. package/dist/attachments/RegionAttachment.d.ts +25 -27
  116. package/dist/attachments/RegionAttachment.js +101 -113
  117. package/dist/attachments/Sequence.d.ts +31 -6
  118. package/dist/attachments/Sequence.js +79 -13
  119. package/dist/esm/spine-core.min.mjs +2 -2
  120. package/dist/esm/spine-core.mjs +7651 -6090
  121. package/dist/esm/spine-core.mjs.map +4 -4
  122. package/dist/iife/spine-core.js +7651 -6090
  123. package/dist/iife/spine-core.js.map +4 -4
  124. package/dist/iife/spine-core.min.js +2 -2
  125. package/dist/index.d.ts +32 -11
  126. package/dist/index.js +33 -12
  127. package/dist/polyfills.js +4 -5
  128. package/package.json +1 -1
  129. package/dist/Updatable.js +0 -30
@@ -26,42 +26,40 @@
26
26
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
27
  * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
  *****************************************************************************/
29
- import { Animation, MixBlend, AttachmentTimeline, MixDirection, RotateTimeline, DrawOrderTimeline, Timeline, EventTimeline } from "./Animation.js";
30
- import { StringSet, Pool, Utils, MathUtils } from "./Utils.js";
29
+ /** biome-ignore-all lint/style/noNonNullAssertion: reference runtime expects some nullable to not be null */
30
+ import { Animation, AttachmentTimeline, DrawOrderFolderTimeline, DrawOrderTimeline, EventTimeline, RotateTimeline, Timeline } from "./Animation.js";
31
+ import { Interpolation, MathUtils, Pool, StringSet, Utils } from "./Utils.js";
31
32
  /** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies
32
33
  * multiple animations on top of each other (layering).
33
34
  *
34
- * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */
35
+ * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations#AnimationState-API) in the Spine Runtimes Guide. */
35
36
  export class AnimationState {
36
- static _emptyAnimation = new Animation("<empty>", [], 0);
37
- static emptyAnimation() {
38
- return AnimationState._emptyAnimation;
39
- }
37
+ static emptyAnimation = new Animation("<empty>", [], 0);
40
38
  /** The AnimationStateData to look up mix durations. */
41
39
  data;
42
- /** The list of tracks that currently have animations, which may contain null entries. */
43
- tracks = new Array();
40
+ /** The list of tracks that have had animations. May contain null entries for tracks that currently have no animation. */
41
+ tracks = [];
44
42
  /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
45
43
  * or faster. Defaults to 1.
46
44
  *
47
- * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */
45
+ * See {@link TrackEntry.timeScale} to affect a single animation. */
48
46
  timeScale = 1;
49
47
  unkeyedState = 0;
50
- events = new Array();
51
- listeners = new Array();
48
+ events = [];
49
+ listeners = [];
52
50
  queue = new EventQueue(this);
53
- propertyIDs = new StringSet();
51
+ propertyIds = new StringSet();
54
52
  animationsChanged = false;
55
53
  trackEntryPool = new Pool(() => new TrackEntry());
56
54
  constructor(data) {
57
55
  this.data = data;
58
56
  }
59
- /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */
57
+ /** Increments each track entry {@link TrackEntry.trackTime}, setting queued animations as current if needed. */
60
58
  update(delta) {
61
59
  delta *= this.timeScale;
62
- let tracks = this.tracks;
60
+ const tracks = this.tracks;
63
61
  for (let i = 0, n = tracks.length; i < n; i++) {
64
- let current = tracks[i];
62
+ const current = tracks[i];
65
63
  if (!current)
66
64
  continue;
67
65
  current.animationLast = current.nextAnimationLast;
@@ -77,12 +75,12 @@ export class AnimationState {
77
75
  let next = current.next;
78
76
  if (next) {
79
77
  // When the next entry's delay is passed, change to the next entry, preserving leftover time.
80
- let nextTime = current.trackLast - next.delay;
78
+ const nextTime = current.trackLast - next.delay;
81
79
  if (nextTime >= 0) {
82
80
  next.delay = 0;
83
- next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale;
81
+ next.trackTime += current.timeScale === 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale;
84
82
  current.trackTime += currentDelta;
85
- this.setCurrent(i, next, true);
83
+ this.setTrack(i, next, true);
86
84
  while (next.mixingFrom) {
87
85
  next.mixTime += delta;
88
86
  next = next.mixingFrom;
@@ -113,20 +111,23 @@ export class AnimationState {
113
111
  }
114
112
  /** Returns true when all mixing from entries are complete. */
115
113
  updateMixingFrom(to, delta) {
116
- let from = to.mixingFrom;
114
+ const from = to.mixingFrom;
117
115
  if (!from)
118
116
  return true;
119
- let finished = this.updateMixingFrom(from, delta);
117
+ const finished = this.updateMixingFrom(from, delta);
120
118
  from.animationLast = from.nextAnimationLast;
121
119
  from.trackLast = from.nextTrackLast;
122
120
  // The from entry was applied at least once and the mix is complete.
123
- if (to.nextTrackLast != -1 && to.mixTime >= to.mixDuration) {
121
+ if (to.nextTrackLast !== -1 && to.mixTime >= to.mixDuration) {
124
122
  // Mixing is complete for all entries before the from entry or the mix is instantaneous.
125
- if (from.totalAlpha == 0 || to.mixDuration == 0) {
123
+ if (from.totalAlpha === 0 || to.mixDuration === 0) {
126
124
  to.mixingFrom = from.mixingFrom;
127
125
  if (from.mixingFrom != null)
128
126
  from.mixingFrom.mixingTo = to;
129
- to.interruptAlpha = from.interruptAlpha;
127
+ if (from.totalAlpha === 0) {
128
+ for (let next = to; next.mixingTo != null; next = next.mixingTo)
129
+ next.keepHold = true;
130
+ }
130
131
  this.queue.end(from);
131
132
  }
132
133
  return finished;
@@ -135,30 +136,28 @@ export class AnimationState {
135
136
  to.mixTime += delta;
136
137
  return false;
137
138
  }
138
- /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
139
- * animation state can be applied to multiple skeletons to pose them identically.
139
+ /** Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple
140
+ * skeletons to pose them identically.
140
141
  * @returns True if any animations were applied. */
141
142
  apply(skeleton) {
142
143
  if (!skeleton)
143
144
  throw new Error("skeleton cannot be null.");
144
145
  if (this.animationsChanged)
145
146
  this._animationsChanged();
146
- let events = this.events;
147
- let tracks = this.tracks;
147
+ const events = this.events;
148
+ const tracks = this.tracks;
148
149
  let applied = false;
149
150
  for (let i = 0, n = tracks.length; i < n; i++) {
150
- let current = tracks[i];
151
+ const current = tracks[i];
151
152
  if (!current || current.delay > 0)
152
153
  continue;
153
154
  applied = true;
154
- let blend = i == 0 ? MixBlend.first : current.mixBlend;
155
155
  // Apply mixing from entries first.
156
156
  let alpha = current.alpha;
157
157
  if (current.mixingFrom)
158
- alpha *= this.applyMixingFrom(current, skeleton, blend);
158
+ alpha *= this.applyMixingFrom(current, skeleton);
159
159
  else if (current.trackTime >= current.trackEnd && !current.next)
160
160
  alpha = 0;
161
- let attachments = alpha >= current.alphaAttachmentThreshold;
162
161
  // Apply current entry.
163
162
  let animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime;
164
163
  let applyEvents = events;
@@ -166,149 +165,115 @@ export class AnimationState {
166
165
  applyTime = current.animation.duration - applyTime;
167
166
  applyEvents = null;
168
167
  }
169
- let timelines = current.animation.timelines;
170
- let timelineCount = timelines.length;
171
- if ((i == 0 && alpha == 1) || blend == MixBlend.add) {
172
- if (i == 0)
173
- attachments = true;
168
+ const timelines = current.animation.timelines;
169
+ const timelineCount = timelines.length;
170
+ if ((i === 0 && alpha === 1)) {
174
171
  for (let ii = 0; ii < timelineCount; ii++) {
175
172
  // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets
176
173
  // to sometimes stop rendering when using color correction, as their RGBA values become NaN.
177
174
  // (https://github.com/pixijs/pixi-spine/issues/302)
178
- Utils.webkit602BugfixHelper(alpha, blend);
179
- var timeline = timelines[ii];
175
+ Utils.webkit602BugfixHelper(alpha);
176
+ const timeline = timelines[ii];
180
177
  if (timeline instanceof AttachmentTimeline)
181
- this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments);
178
+ this.applyAttachmentTimeline(timeline, skeleton, applyTime, true, true);
182
179
  else
183
- timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, blend, MixDirection.mixIn);
180
+ timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, true, false, false, false);
184
181
  }
185
182
  }
186
183
  else {
187
- let timelineMode = current.timelineMode;
188
- let shortestRotation = current.shortestRotation;
189
- let firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1;
184
+ const timelineMode = current.timelineMode;
185
+ const retainAttachments = alpha >= current.alphaAttachmentThreshold;
186
+ const add = current.additive, shortestRotation = add || current.shortestRotation;
187
+ const firstFrame = !shortestRotation && current.timelinesRotation.length !== timelineCount << 1;
190
188
  if (firstFrame)
191
189
  current.timelinesRotation.length = timelineCount << 1;
192
190
  for (let ii = 0; ii < timelineCount; ii++) {
193
- let timeline = timelines[ii];
194
- let timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : MixBlend.setup;
191
+ const timeline = timelines[ii];
192
+ const fromSetup = (timelineMode[ii] & FIRST) !== 0;
195
193
  if (!shortestRotation && timeline instanceof RotateTimeline) {
196
- this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, current.timelinesRotation, ii << 1, firstFrame);
194
+ this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, fromSetup, current.timelinesRotation, ii << 1, firstFrame);
197
195
  }
198
196
  else if (timeline instanceof AttachmentTimeline) {
199
- this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments);
197
+ this.applyAttachmentTimeline(timeline, skeleton, applyTime, fromSetup, retainAttachments);
200
198
  }
201
199
  else {
202
- // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
203
- Utils.webkit602BugfixHelper(alpha, blend);
204
- timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, timelineBlend, MixDirection.mixIn);
200
+ // This fixes the WebKit 602 specific issue described at https://esotericsoftware.com/forum/d/10109-ios-10-disappearing-graphics
201
+ Utils.webkit602BugfixHelper(alpha);
202
+ timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, fromSetup, add, false, false);
205
203
  }
206
204
  }
207
205
  }
206
+ if (current.reverse)
207
+ this.eventsReverse(current, animationLast, animationTime);
208
208
  this.queueEvents(current, animationTime);
209
209
  events.length = 0;
210
210
  current.nextAnimationLast = animationTime;
211
211
  current.nextTrackLast = current.trackTime;
212
212
  }
213
- // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so
214
- // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or
215
- // the time is before the first key).
216
- var setupState = this.unkeyedState + SETUP;
217
- var slots = skeleton.slots;
218
- for (var i = 0, n = skeleton.slots.length; i < n; i++) {
219
- var slot = slots[i];
220
- if (slot.attachmentState == setupState) {
221
- var attachmentName = slot.data.attachmentName;
222
- slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
213
+ // Set slot attachments to the setup pose if they were set temporarily to apply deform timelines.
214
+ const setupState = this.unkeyedState + SETUP;
215
+ const slots = skeleton.slots;
216
+ for (let i = 0, n = skeleton.slots.length; i < n; i++) {
217
+ const slot = slots[i];
218
+ if (slot.attachmentState === setupState) {
219
+ const attachmentName = slot.data.attachmentName;
220
+ slot.pose.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
223
221
  }
224
222
  }
225
- this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot.
223
+ this.unkeyedState += 2; // Reset.
226
224
  this.queue.drain();
227
225
  return applied;
228
226
  }
229
- applyMixingFrom(to, skeleton, blend) {
230
- let from = to.mixingFrom;
231
- if (from.mixingFrom)
232
- this.applyMixingFrom(from, skeleton, blend);
233
- let mix = 0;
234
- if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes.
235
- mix = 1;
236
- if (blend == MixBlend.first)
237
- blend = MixBlend.setup;
238
- }
239
- else {
240
- mix = to.mixTime / to.mixDuration;
241
- if (mix > 1)
242
- mix = 1;
243
- if (blend != MixBlend.first)
244
- blend = from.mixBlend;
245
- }
246
- let attachments = mix < from.mixAttachmentThreshold, drawOrder = mix < from.mixDrawOrderThreshold;
247
- let timelines = from.animation.timelines;
248
- let timelineCount = timelines.length;
249
- let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
227
+ applyMixingFrom(to, skeleton) {
228
+ const from = to.mixingFrom;
229
+ const fromMix = from.mixingFrom !== null ? this.applyMixingFrom(from, skeleton) : 1;
230
+ const mix = to.mix();
231
+ const a = from.alpha * fromMix, keep = 1 - mix * to.alpha;
232
+ const alphaMix = a * (1 - mix), alphaHold = keep > 0 ? alphaMix / keep : a;
233
+ const timelines = from.animation.timelines;
234
+ const timelineCount = timelines.length;
235
+ const timelineMode = from.timelineMode;
236
+ const timelineHoldMix = from.timelineHoldMix;
237
+ const retainAttachments = mix < from.mixAttachmentThreshold, drawOrder = mix < from.mixDrawOrderThreshold;
238
+ const add = from.additive, shortestRotation = add || from.shortestRotation;
239
+ const firstFrame = !shortestRotation && from.timelinesRotation.length !== timelineCount << 1;
240
+ if (firstFrame)
241
+ from.timelinesRotation.length = timelineCount << 1;
242
+ const timelinesRotation = from.timelinesRotation;
250
243
  let animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime;
251
244
  let events = null;
252
245
  if (from.reverse)
253
246
  applyTime = from.animation.duration - applyTime;
254
- else if (mix < from.eventThreshold)
247
+ else if (mix < from.eventThreshold) //
255
248
  events = this.events;
256
- if (blend == MixBlend.add) {
257
- for (let i = 0; i < timelineCount; i++)
258
- timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection.mixOut);
259
- }
260
- else {
261
- let timelineMode = from.timelineMode;
262
- let timelineHoldMix = from.timelineHoldMix;
263
- let shortestRotation = from.shortestRotation;
264
- let firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1;
265
- if (firstFrame)
266
- from.timelinesRotation.length = timelineCount << 1;
267
- from.totalAlpha = 0;
268
- for (let i = 0; i < timelineCount; i++) {
269
- let timeline = timelines[i];
270
- let direction = MixDirection.mixOut;
271
- let timelineBlend;
272
- let alpha = 0;
273
- switch (timelineMode[i]) {
274
- case SUBSEQUENT:
275
- if (!drawOrder && timeline instanceof DrawOrderTimeline)
276
- continue;
277
- timelineBlend = blend;
278
- alpha = alphaMix;
279
- break;
280
- case FIRST:
281
- timelineBlend = MixBlend.setup;
282
- alpha = alphaMix;
283
- break;
284
- case HOLD_SUBSEQUENT:
285
- timelineBlend = blend;
286
- alpha = alphaHold;
287
- break;
288
- case HOLD_FIRST:
289
- timelineBlend = MixBlend.setup;
290
- alpha = alphaHold;
291
- break;
292
- default:
293
- timelineBlend = MixBlend.setup;
294
- let holdMix = timelineHoldMix[i];
295
- alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
296
- break;
297
- }
298
- from.totalAlpha += alpha;
299
- if (!shortestRotation && timeline instanceof RotateTimeline)
300
- this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame);
301
- else if (timeline instanceof AttachmentTimeline)
302
- this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments && alpha >= from.alphaAttachmentThreshold);
303
- else {
304
- // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
305
- Utils.webkit602BugfixHelper(alpha, blend);
306
- if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == MixBlend.setup)
307
- direction = MixDirection.mixIn;
308
- timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction);
309
- }
249
+ from.totalAlpha = 0;
250
+ for (let i = 0; i < timelineCount; i++) {
251
+ const timeline = timelines[i];
252
+ const mode = timelineMode[i];
253
+ let alpha = 0;
254
+ if ((mode & HOLD) !== 0) {
255
+ const holdMix = timelineHoldMix[i];
256
+ alpha = holdMix == null ? alphaHold : alphaHold * (1 - holdMix.mix());
257
+ }
258
+ else {
259
+ if (!drawOrder && timeline instanceof DrawOrderTimeline)
260
+ continue;
261
+ alpha = alphaMix;
262
+ }
263
+ from.totalAlpha += alpha;
264
+ const fromSetup = (mode & FIRST) !== 0;
265
+ if (!shortestRotation && timeline instanceof RotateTimeline) {
266
+ this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, fromSetup, timelinesRotation, i << 1, firstFrame);
267
+ }
268
+ else if (timeline instanceof AttachmentTimeline)
269
+ this.applyAttachmentTimeline(timeline, skeleton, applyTime, fromSetup, retainAttachments && alpha >= from.alphaAttachmentThreshold);
270
+ else {
271
+ const out = !drawOrder || !(timeline instanceof DrawOrderTimeline) || !fromSetup;
272
+ timeline.apply(skeleton, animationLast, applyTime, events, alpha, fromSetup, add, out, false);
310
273
  }
311
274
  }
275
+ if (from.reverse && mix < from.eventThreshold)
276
+ this.eventsReverse(from, animationLast, animationTime);
312
277
  if (to.mixDuration > 0)
313
278
  this.queueEvents(from, animationTime);
314
279
  this.events.length = 0;
@@ -316,56 +281,56 @@ export class AnimationState {
316
281
  from.nextTrackLast = from.trackTime;
317
282
  return mix;
318
283
  }
319
- applyAttachmentTimeline(timeline, skeleton, time, blend, attachments) {
320
- var slot = skeleton.slots[timeline.slotIndex];
284
+ /** Applies the attachment timeline and sets {@link Slot.attachmentState}.
285
+ * @param retain True if the attachment remains after apply, false if temporary for deform timelines. */
286
+ applyAttachmentTimeline(timeline, skeleton, time, fromSetup, retain) {
287
+ const slot = skeleton.slots[timeline.slotIndex];
321
288
  if (!slot.bone.active)
322
289
  return;
323
- if (time < timeline.frames[0]) { // Time is before first frame.
324
- if (blend == MixBlend.setup || blend == MixBlend.first)
325
- this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments);
290
+ if (!retain && slot.attachmentState === this.unkeyedState + RETAIN)
291
+ return;
292
+ let setup = time < timeline.frames[0];
293
+ let name = null;
294
+ if (!setup) {
295
+ name = timeline.attachmentNames[Timeline.search(timeline.frames, time)];
296
+ setup = !retain && name == null;
326
297
  }
327
- else
328
- this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments);
329
- // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.
330
- if (slot.attachmentState <= this.unkeyedState)
298
+ if (setup) {
299
+ if (!fromSetup)
300
+ return;
301
+ name = slot.data.attachmentName;
302
+ }
303
+ slot.pose.setAttachment(name == null ? null : skeleton.getAttachment(slot.data.index, name));
304
+ if (retain)
305
+ slot.attachmentState = this.unkeyedState + RETAIN;
306
+ else if (!setup) //
331
307
  slot.attachmentState = this.unkeyedState + SETUP;
332
308
  }
333
- setAttachment(skeleton, slot, attachmentName, attachments) {
334
- slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
335
- if (attachments)
336
- slot.attachmentState = this.unkeyedState + CURRENT;
337
- }
338
- applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) {
309
+ /** Applies the rotate timeline, mixing with the current pose while keeping the same rotation direction chosen as the shortest
310
+ * the first time the mixing was applied. */
311
+ applyRotateTimeline(timeline, skeleton, time, alpha, fromSetup, timelinesRotation, i, firstFrame) {
339
312
  if (firstFrame)
340
313
  timelinesRotation[i] = 0;
341
- if (alpha == 1) {
342
- timeline.apply(skeleton, 0, time, null, 1, blend, MixDirection.mixIn);
314
+ if (alpha === 1) {
315
+ timeline.apply(skeleton, 0, time, null, 1, fromSetup, false, false, false);
343
316
  return;
344
317
  }
345
- let bone = skeleton.bones[timeline.boneIndex];
318
+ const bone = skeleton.bones[timeline.boneIndex];
346
319
  if (!bone.active)
347
320
  return;
348
- let frames = timeline.frames;
349
- let r1 = 0, r2 = 0;
350
- if (time < frames[0]) {
351
- switch (blend) {
352
- case MixBlend.setup:
353
- bone.rotation = bone.data.rotation;
354
- default:
355
- return;
356
- case MixBlend.first:
357
- r1 = bone.rotation;
358
- r2 = bone.data.rotation;
359
- }
360
- }
361
- else {
362
- r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
363
- r2 = bone.data.rotation + timeline.getCurveValue(time);
321
+ const pose = bone.pose, setup = bone.data.setupPose;
322
+ const frames = timeline.frames;
323
+ if (time < frames[0]) { // Time is before first frame.
324
+ if (fromSetup)
325
+ pose.rotation = setup.rotation;
326
+ return;
364
327
  }
328
+ const r1 = fromSetup ? setup.rotation : pose.rotation;
329
+ const r2 = setup.rotation + timeline.getCurveValue(time);
365
330
  // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
366
331
  let total = 0, diff = r2 - r1;
367
332
  diff -= Math.ceil(diff / 360 - 0.5) * 360;
368
- if (diff == 0) {
333
+ if (diff === 0) {
369
334
  total = timelinesRotation[i];
370
335
  }
371
336
  else {
@@ -378,45 +343,46 @@ export class AnimationState {
378
343
  lastTotal = timelinesRotation[i];
379
344
  lastDiff = timelinesRotation[i + 1];
380
345
  }
381
- let loops = lastTotal - lastTotal % 360;
346
+ const loops = lastTotal - lastTotal % 360;
382
347
  total = diff + loops;
383
348
  let current = diff >= 0, dir = lastTotal >= 0;
384
- if (Math.abs(lastDiff) <= 90 && MathUtils.signum(lastDiff) != MathUtils.signum(diff)) {
349
+ if (Math.abs(lastDiff) <= 90 && MathUtils.signum(lastDiff) !== MathUtils.signum(diff)) {
385
350
  if (Math.abs(lastTotal - loops) > 180) {
386
351
  total += 360 * MathUtils.signum(lastTotal);
387
352
  dir = current;
388
353
  }
389
- else if (loops != 0)
354
+ else if (loops !== 0)
390
355
  total -= 360 * MathUtils.signum(lastTotal);
391
356
  else
392
357
  dir = current;
393
358
  }
394
- if (dir != current)
359
+ if (dir !== current)
395
360
  total += 360 * MathUtils.signum(lastTotal);
396
361
  timelinesRotation[i] = total;
397
362
  }
398
363
  timelinesRotation[i + 1] = diff;
399
- bone.rotation = r1 + total * alpha;
364
+ pose.rotation = r1 + total * alpha;
400
365
  }
401
366
  queueEvents(entry, animationTime) {
402
- let animationStart = entry.animationStart, animationEnd = entry.animationEnd;
403
- let duration = animationEnd - animationStart;
404
- let trackLastWrapped = entry.trackLast % duration;
367
+ const animationStart = entry.animationStart, animationEnd = entry.animationEnd, duration = animationEnd - animationStart;
368
+ const reverse = entry.reverse;
369
+ let split = entry.trackLast % duration;
370
+ if (reverse)
371
+ split = duration - split;
405
372
  // Queue events before complete.
406
- let events = this.events;
373
+ const events = this.events;
407
374
  let i = 0, n = events.length;
408
375
  for (; i < n; i++) {
409
- let event = events[i];
410
- if (event.time < trackLastWrapped)
411
- break;
412
- if (event.time > animationEnd)
413
- continue; // Discard events outside animation start/end.
414
- this.queue.event(entry, event);
376
+ const event = events[i];
377
+ if ((event.time < split) !== reverse)
378
+ break; // java: if (event.time < split ^ reverse) break;
379
+ if (event.time >= animationStart && event.time <= animationEnd)
380
+ this.queue.event(entry, event);
415
381
  }
416
382
  // Queue complete if completed a loop iteration or the animation.
417
383
  let complete = false;
418
384
  if (entry.loop) {
419
- if (duration == 0)
385
+ if (duration === 0)
420
386
  complete = true;
421
387
  else {
422
388
  const cycles = Math.floor(entry.trackTime / duration);
@@ -429,18 +395,51 @@ export class AnimationState {
429
395
  this.queue.complete(entry);
430
396
  // Queue events after complete.
431
397
  for (; i < n; i++) {
432
- let event = events[i];
433
- if (event.time < animationStart)
434
- continue; // Discard events outside animation start/end.
435
- this.queue.event(entry, event);
398
+ const event = events[i];
399
+ if (event.time >= animationStart && event.time <= animationEnd)
400
+ this.queue.event(entry, event);
401
+ }
402
+ }
403
+ eventsReverse(entry, animationLast, animationTime) {
404
+ const duration = entry.animation.duration, from = duration - animationLast, to = duration - animationTime;
405
+ const timelines = entry.animation.timelines;
406
+ for (let i = 0, n = entry.animation.timelines.length; i < n; i++) {
407
+ const eventTimeline = timelines[i];
408
+ if (!(eventTimeline instanceof EventTimeline))
409
+ continue;
410
+ const timelineEvents = eventTimeline.events;
411
+ const frames = eventTimeline.frames;
412
+ const frameCount = frames.length;
413
+ if (from >= to) { // from -> to
414
+ for (let ii = 0; ii < frameCount; ii++) {
415
+ if (frames[ii] < to)
416
+ continue;
417
+ if (frames[ii] >= from)
418
+ break;
419
+ this.events.push(timelineEvents[ii]);
420
+ }
421
+ }
422
+ else {
423
+ for (let ii = 0; ii < frameCount; ii++) { // from -> 0
424
+ if (frames[ii] >= from)
425
+ break;
426
+ this.events.push(timelineEvents[ii]);
427
+ }
428
+ let ii = 0; // end -> to
429
+ for (; ii < frameCount; ii++)
430
+ if (frames[ii] >= to)
431
+ break;
432
+ for (; ii < frameCount; ii++)
433
+ this.events.push(timelineEvents[ii]);
434
+ }
436
435
  }
437
436
  }
438
437
  /** Removes all animations from all tracks, leaving skeletons in their current pose.
439
438
  *
440
- * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,
441
- * rather than leaving them in their current pose. */
439
+ * Usually you want to use {@link setEmptyAnimations} to mix the skeletons back to the setup pose, rather than leaving
440
+ * them in their current pose. */
442
441
  clearTracks() {
443
- let oldDrainDisabled = this.queue.drainDisabled;
442
+ const oldDrainDisabled = this.queue.drainDisabled;
444
443
  this.queue.drainDisabled = true;
445
444
  for (let i = 0, n = this.tracks.length; i < n; i++)
446
445
  this.clearTrack(i);
@@ -450,19 +449,21 @@ export class AnimationState {
450
449
  }
451
450
  /** Removes all animations from the track, leaving skeletons in their current pose.
452
451
  *
453
- * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,
454
- * rather than leaving them in their current pose. */
452
+ * Usually you want to use {@link setEmptyAnimation} to mix the skeletons back to the setup pose, rather than
453
+ * leaving them in their current pose. */
455
454
  clearTrack(trackIndex) {
455
+ if (trackIndex < 0)
456
+ throw new Error("trackIndex must be >= 0.");
456
457
  if (trackIndex >= this.tracks.length)
457
458
  return;
458
- let current = this.tracks[trackIndex];
459
+ const current = this.tracks[trackIndex];
459
460
  if (!current)
460
461
  return;
461
462
  this.queue.end(current);
462
463
  this.clearNext(current);
463
464
  let entry = current;
464
465
  while (true) {
465
- let from = entry.mixingFrom;
466
+ const from = entry.mixingFrom;
466
467
  if (!from)
467
468
  break;
468
469
  this.queue.end(from);
@@ -473,45 +474,49 @@ export class AnimationState {
473
474
  this.tracks[current.trackIndex] = null;
474
475
  this.queue.drain();
475
476
  }
476
- setCurrent(index, current, interrupt) {
477
- let from = this.expandToIndex(index);
477
+ setTrack(index, current, interrupt) {
478
+ const from = this.expandToIndex(index);
478
479
  this.tracks[index] = current;
479
480
  current.previous = null;
480
481
  if (from) {
482
+ from.next = null;
481
483
  if (interrupt)
482
484
  this.queue.interrupt(from);
483
485
  current.mixingFrom = from;
484
486
  from.mixingTo = current;
485
487
  current.mixTime = 0;
486
- // Store the interrupted mix percentage.
487
- if (from.mixingFrom && from.mixDuration > 0)
488
- current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
489
488
  from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in.
490
489
  }
491
490
  this.queue.start(current);
492
491
  }
493
- /** Sets an animation by name.
494
- *
495
- * See {@link #setAnimationWith()}. */
496
- setAnimation(trackIndex, animationName, loop = false) {
497
- let animation = this.data.skeletonData.findAnimation(animationName);
492
+ setAnimation(trackIndex, animationNameOrAnimation, loop = false) {
493
+ if (typeof animationNameOrAnimation === "string")
494
+ return this.setAnimation1(trackIndex, animationNameOrAnimation, loop);
495
+ return this.setAnimation2(trackIndex, animationNameOrAnimation, loop);
496
+ }
497
+ setAnimation1(trackIndex, animationName, loop = false) {
498
+ const animation = this.data.skeletonData.findAnimation(animationName);
498
499
  if (!animation)
499
- throw new Error("Animation not found: " + animationName);
500
- return this.setAnimationWith(trackIndex, animation, loop);
500
+ throw new Error(`Animation not found: ${animationName}`);
501
+ return this.setAnimation2(trackIndex, animation, loop);
501
502
  }
502
- /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never
503
- * applied to a skeleton, it is replaced (not mixed from).
503
+ /** Sets the current animation for a track, discarding any queued animations.
504
+ *
505
+ * If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
506
+ * from).
504
507
  * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
505
- * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared.
506
- * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
507
- * after the {@link AnimationStateListener#dispose()} event occurs. */
508
- setAnimationWith(trackIndex, animation, loop = false) {
508
+ * duration. In either case {@link TrackEntry.getTrackEnd} determines when the track is cleared.
509
+ * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
510
+ * after the {@link AnimationStateListener.dispose} event occurs. */
511
+ setAnimation2(trackIndex, animation, loop = false) {
512
+ if (trackIndex < 0)
513
+ throw new Error("trackIndex must be >= 0.");
509
514
  if (!animation)
510
515
  throw new Error("animation cannot be null.");
511
516
  let interrupt = true;
512
517
  let current = this.expandToIndex(trackIndex);
513
518
  if (current) {
514
- if (current.nextTrackLast == -1) {
519
+ if (current.nextTrackLast === -1 && current.animation === animation) {
515
520
  // Don't mix from an entry that was never applied.
516
521
  this.tracks[trackIndex] = current.mixingFrom;
517
522
  this.queue.interrupt(current);
@@ -523,29 +528,25 @@ export class AnimationState {
523
528
  else
524
529
  this.clearNext(current);
525
530
  }
526
- let entry = this.trackEntry(trackIndex, animation, loop, current);
527
- this.setCurrent(trackIndex, entry, interrupt);
531
+ const entry = this.trackEntry(trackIndex, animation, loop, current);
532
+ this.setTrack(trackIndex, entry, interrupt);
528
533
  this.queue.drain();
529
534
  return entry;
530
535
  }
531
- /** Queues an animation by name.
532
- *
533
- * See {@link #addAnimationWith()}. */
534
- addAnimation(trackIndex, animationName, loop = false, delay = 0) {
535
- let animation = this.data.skeletonData.findAnimation(animationName);
536
+ addAnimation(trackIndex, animationNameOrAnimation, loop = false, delay = 0) {
537
+ if (typeof animationNameOrAnimation === "string")
538
+ return this.addAnimation1(trackIndex, animationNameOrAnimation, loop, delay);
539
+ return this.addAnimation2(trackIndex, animationNameOrAnimation, loop, delay);
540
+ }
541
+ addAnimation1(trackIndex, animationName, loop = false, delay = 0) {
542
+ const animation = this.data.skeletonData.findAnimation(animationName);
536
543
  if (!animation)
537
- throw new Error("Animation not found: " + animationName);
538
- return this.addAnimationWith(trackIndex, animation, loop, delay);
544
+ throw new Error(`Animation not found: ${animationName}`);
545
+ return this.addAnimation2(trackIndex, animation, loop, delay);
539
546
  }
540
- /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is
541
- * equivalent to calling {@link #setAnimationWith()}.
542
- * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry
543
- * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix
544
- * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the
545
- * previous entry is looping, its next loop completion is used instead of its duration.
546
- * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
547
- * after the {@link AnimationStateListener#dispose()} event occurs. */
548
- addAnimationWith(trackIndex, animation, loop = false, delay = 0) {
547
+ addAnimation2(trackIndex, animation, loop = false, delay = 0) {
548
+ if (trackIndex < 0)
549
+ throw new Error("trackIndex must be >= 0.");
549
550
  if (!animation)
550
551
  throw new Error("animation cannot be null.");
551
552
  let last = this.expandToIndex(trackIndex);
@@ -553,9 +554,9 @@ export class AnimationState {
553
554
  while (last.next)
554
555
  last = last.next;
555
556
  }
556
- let entry = this.trackEntry(trackIndex, animation, loop, last);
557
+ const entry = this.trackEntry(trackIndex, animation, loop, last);
557
558
  if (!last) {
558
- this.setCurrent(trackIndex, entry, true);
559
+ this.setTrack(trackIndex, entry, true);
559
560
  this.queue.drain();
560
561
  if (delay < 0)
561
562
  delay = 0;
@@ -570,51 +571,58 @@ export class AnimationState {
570
571
  return entry;
571
572
  }
572
573
  /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's
573
- * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out.
574
+ * {@link TrackEntry.mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out.
574
575
  *
575
- * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()},
576
- * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes
576
+ * Mixing out is done by setting an empty animation with a mix duration using either {@link setEmptyAnimation},
577
+ * {@link setEmptyAnimations}, or {@link addEmptyAnimation}. Mixing to an empty animation causes
577
578
  * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
578
579
  * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
579
- * 0 still mixes out over one frame.
580
+ * 0 still needs to be applied one more time to mix out, so the properties it was animating are reverted.
580
581
  *
581
582
  * Mixing in is done by first setting an empty animation, then adding an animation using
582
- * {@link #addAnimation()} and on the returned track entry, set the
583
- * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and
584
- * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the
585
- * setup pose value if no lower tracks key the property to the value keyed in the new animation. */
583
+ * {@link addAnimation} with the desired delay (an empty animation has a duration of 0) and on
584
+ * the returned track entry, set the {@link TrackEntry.setMixDuration}. Mixing from an empty animation causes the new
585
+ * animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value
586
+ * from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new animation.
587
+ *
588
+ * See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
589
+ * Runtimes Guide. */
586
590
  setEmptyAnimation(trackIndex, mixDuration = 0) {
587
- let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false);
591
+ const entry = this.setAnimation(trackIndex, AnimationState.emptyAnimation, false);
588
592
  entry.mixDuration = mixDuration;
589
593
  entry.trackEnd = mixDuration;
590
594
  return entry;
591
595
  }
592
596
  /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
593
- * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling
594
- * {@link #setEmptyAnimation()}.
597
+ * {@link TrackEntry.mixDuration}. If the track has no entries, it is equivalent to calling
598
+ * {@link setEmptyAnimation}.
595
599
  *
596
- * See {@link #setEmptyAnimation()}.
597
- * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry
598
- * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or
599
- * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next
600
- * loop completion is used instead of its duration.
600
+ * See {@link setEmptyAnimation} and
601
+ * <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine Runtimes
602
+ * Guide.
603
+ * @param delay If > 0, sets {@link TrackEntry.delay}. If <= 0, the delay set is the duration of the previous track entry minus
604
+ * any mix duration plus the specified `delay` (ie the mix ends at (when `delay` = 0) or before
605
+ * (when `delay` < 0) the previous track entry duration). If the previous entry is looping, its next loop
606
+ * completion is used instead of its duration.
601
607
  * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
602
- * after the {@link AnimationStateListener#dispose()} event occurs. */
608
+ * after the {@link AnimationStateListener.dispose} event occurs. */
603
609
  addEmptyAnimation(trackIndex, mixDuration = 0, delay = 0) {
604
- let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay);
610
+ const entry = this.addAnimation(trackIndex, AnimationState.emptyAnimation, false, delay);
605
611
  if (delay <= 0)
606
612
  entry.delay = Math.max(entry.delay + entry.mixDuration - mixDuration, 0);
607
613
  entry.mixDuration = mixDuration;
608
614
  entry.trackEnd = mixDuration;
609
615
  return entry;
610
616
  }
611
- /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix
612
- * duration. */
617
+ /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
618
+ *
619
+ * See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
620
+ * Runtimes Guide. */
613
621
  setEmptyAnimations(mixDuration = 0) {
614
- let oldDrainDisabled = this.queue.drainDisabled;
622
+ const oldDrainDisabled = this.queue.drainDisabled;
615
623
  this.queue.drainDisabled = true;
616
624
  for (let i = 0, n = this.tracks.length; i < n; i++) {
617
- let current = this.tracks[i];
625
+ const current = this.tracks[i];
618
626
  if (current)
619
627
  this.setEmptyAnimation(current.trackIndex, mixDuration);
620
628
  }
@@ -630,12 +638,12 @@ export class AnimationState {
630
638
  }
631
639
  /** @param last May be null. */
632
640
  trackEntry(trackIndex, animation, loop, last) {
633
- let entry = this.trackEntryPool.obtain();
641
+ const entry = this.trackEntryPool.obtain();
634
642
  entry.reset();
635
643
  entry.trackIndex = trackIndex;
636
644
  entry.animation = animation;
637
645
  entry.loop = loop;
638
- entry.holdPrevious = false;
646
+ entry.additive = false;
639
647
  entry.reverse = false;
640
648
  entry.shortestRotation = false;
641
649
  entry.eventThreshold = 0;
@@ -655,12 +663,11 @@ export class AnimationState {
655
663
  entry.alpha = 1;
656
664
  entry.mixTime = 0;
657
665
  entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation);
658
- entry.interruptAlpha = 1;
659
666
  entry.totalAlpha = 0;
660
- entry.mixBlend = MixBlend.replace;
667
+ entry.keepHold = false;
661
668
  return entry;
662
669
  }
663
- /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */
670
+ /** Removes {@link TrackEntry.next} and all entries after it for the specified entry. */
664
671
  clearNext(entry) {
665
672
  let next = entry.next;
666
673
  while (next) {
@@ -671,8 +678,7 @@ export class AnimationState {
671
678
  }
672
679
  _animationsChanged() {
673
680
  this.animationsChanged = false;
674
- this.propertyIDs.clear();
675
- let tracks = this.tracks;
681
+ const tracks = this.tracks;
676
682
  for (let i = 0, n = tracks.length; i < n; i++) {
677
683
  let entry = tracks[i];
678
684
  if (!entry)
@@ -680,52 +686,62 @@ export class AnimationState {
680
686
  while (entry.mixingFrom)
681
687
  entry = entry.mixingFrom;
682
688
  do {
683
- if (!entry.mixingTo || entry.mixBlend != MixBlend.add)
684
- this.computeHold(entry);
689
+ this.computeHold(entry);
685
690
  entry = entry.mixingTo;
686
691
  } while (entry);
687
692
  }
693
+ this.propertyIds.clear();
688
694
  }
689
695
  computeHold(entry) {
690
- let to = entry.mixingTo;
691
- let timelines = entry.animation.timelines;
692
- let timelinesCount = entry.animation.timelines.length;
693
- let timelineMode = entry.timelineMode;
696
+ const timelines = entry.animation.timelines;
697
+ const timelinesCount = entry.animation.timelines.length;
698
+ const timelineMode = entry.timelineMode;
694
699
  timelineMode.length = timelinesCount;
695
- let timelineHoldMix = entry.timelineHoldMix;
700
+ const timelineHoldMix = entry.timelineHoldMix;
696
701
  timelineHoldMix.length = 0;
697
- let propertyIDs = this.propertyIDs;
698
- if (to && to.holdPrevious) {
699
- for (let i = 0; i < timelinesCount; i++)
700
- timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT;
701
- return;
702
- }
702
+ const propertyIds = this.propertyIds;
703
+ const add = entry.additive, keepHold = entry.keepHold;
704
+ const to = entry.mixingTo;
703
705
  outer: for (let i = 0; i < timelinesCount; i++) {
704
- let timeline = timelines[i];
705
- let ids = timeline.getPropertyIds();
706
- if (!propertyIDs.addAll(ids))
707
- timelineMode[i] = SUBSEQUENT;
708
- else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
709
- || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) {
710
- timelineMode[i] = FIRST;
706
+ const timeline = timelines[i];
707
+ const ids = timeline.propertyIds;
708
+ const first = propertyIds.addAll(ids)
709
+ && !(timeline instanceof DrawOrderFolderTimeline && propertyIds.contains(DrawOrderTimeline.propertyID));
710
+ if (add && timeline.additive) {
711
+ timelineMode[i] = first ? FIRST : SUBSEQUENT;
712
+ continue;
711
713
  }
714
+ for (let from = entry.mixingFrom; from != null; from = from.mixingFrom) {
715
+ if (from.animation.hasTimeline(ids)) {
716
+ // An earlier entry on this track keys this property, isolating it from lower tracks.
717
+ timelineMode[i] = SUBSEQUENT;
718
+ continue outer;
719
+ }
720
+ }
721
+ // Hold if the next entry will overwrite this property.
722
+ let mode;
723
+ if (to === null || timeline.instant || (to.additive && timeline.additive) || !to.animation?.hasTimeline(ids))
724
+ mode = first ? FIRST : SUBSEQUENT;
712
725
  else {
713
- for (let next = to.mixingTo; next; next = next.mixingTo) {
714
- if (next.animation.hasTimeline(ids))
715
- continue;
716
- if (entry.mixDuration > 0) {
717
- timelineMode[i] = HOLD_MIX;
718
- timelineHoldMix[i] = next;
719
- continue outer;
726
+ mode = first ? HOLD_FIRST : HOLD;
727
+ // Find next entry that doesn't overwrite this property. Its mix fades out the hold, instead of it ending abruptly.
728
+ for (let next = to.mixingTo; next != null; next = next.mixingTo) {
729
+ if ((next.additive && timeline.additive) || !next.animation?.hasTimeline(ids)) {
730
+ if (next.mixDuration > 0)
731
+ timelineHoldMix[i] = next;
732
+ break;
720
733
  }
721
- break;
722
734
  }
723
- timelineMode[i] = HOLD_FIRST;
724
735
  }
736
+ if (keepHold)
737
+ mode = (mode & ~HOLD) | (timelineMode[i] & HOLD);
738
+ timelineMode[i] = mode;
725
739
  }
726
740
  }
727
741
  /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
728
- getCurrent(trackIndex) {
742
+ getTrack(trackIndex) {
743
+ if (trackIndex < 0)
744
+ throw new Error("trackIndex must be >= 0.");
729
745
  if (trackIndex >= this.tracks.length)
730
746
  return null;
731
747
  return this.tracks[trackIndex];
@@ -736,13 +752,13 @@ export class AnimationState {
736
752
  throw new Error("listener cannot be null.");
737
753
  this.listeners.push(listener);
738
754
  }
739
- /** Removes the listener added with {@link #addListener()}. */
755
+ /** Removes the listener added with {@link addListener}. */
740
756
  removeListener(listener) {
741
- let index = this.listeners.indexOf(listener);
757
+ const index = this.listeners.indexOf(listener);
742
758
  if (index >= 0)
743
759
  this.listeners.splice(index, 1);
744
760
  }
745
- /** Removes all listeners added with {@link #addListener()}. */
761
+ /** Removes all listeners added with {@link addListener}. */
746
762
  clearListeners() {
747
763
  this.listeners.length = 0;
748
764
  }
@@ -755,84 +771,94 @@ export class AnimationState {
755
771
  }
756
772
  /** Stores settings and other state for the playback of an animation on an {@link AnimationState} track.
757
773
  *
758
- * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. */
774
+ * References to a track entry must not be kept after the {@link AnimationStateListener.dispose} event occurs. */
759
775
  export class TrackEntry {
760
776
  /** The animation to apply for this track entry. */
761
777
  animation = null;
762
778
  previous = null;
763
779
  /** The animation queued to start after this animation, or null. `next` makes up a linked list. */
764
780
  next = null;
765
- /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
766
- * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */
781
+ /** The track entry for the previous animation when mixing to this animation, or null if no mixing is currently occurring.
782
+ * When mixing from multiple animations, `mixingFrom` makes up a doubly linked list. */
767
783
  mixingFrom = null;
768
- /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is
769
- * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */
784
+ /** The track entry for the next animation when mixing from this animation, or null if no mixing is currently occurring.
785
+ * When mixing to multiple animations, `mixingTo` makes up a doubly linked list. */
770
786
  mixingTo = null;
771
787
  /** The listener for events generated by this track entry, or null.
772
788
  *
773
- * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation
774
- * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */
789
+ * A track entry returned from {@link AnimationState.setAnimation} is already the current animation
790
+ * for the track, so the callback for listener {@link AnimationStateListener.start} will not be called. */
775
791
  listener = null;
776
792
  /** The index of the track where this track entry is either current or queued.
777
793
  *
778
- * See {@link AnimationState#getCurrent()}. */
794
+ * See {@link AnimationState.getTrack}. */
779
795
  trackIndex = 0;
780
796
  /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
781
797
  * duration. */
782
798
  loop = false;
783
- /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead
784
- * of being mixed out.
799
+ /** When true, timelines in this animation that support additive have their values added to the setup or current pose values
800
+ * instead of replacing them. Additive can be set for a new track entry only before {@link AnimationState.apply}
801
+ * is next called. */
802
+ additive = false;
803
+ /** If true, the animation will be applied in reverse. */
804
+ reverse = false;
805
+ /** If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
806
+ * shortest rotation direction may change during the mix.
785
807
  *
786
- * When mixing between animations that key the same property, if a lower track also keys that property then the value will
787
- * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%
788
- * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation
789
- * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which
790
- * keys the property, only when a higher track also keys the property.
808
+ * If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
809
+ * of the mix. Defaults to false.
791
810
  *
792
- * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the
793
- * previous animation. */
794
- holdPrevious = false;
795
- reverse = false;
811
+ * See {@link resetRotationDirections}. */
796
812
  shortestRotation = false;
797
- /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the
798
- * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event
799
- * timelines are not applied while this animation is being mixed out. */
813
+ keepHold = false;
814
+ /** When the interpolated mix percentage is less than the `eventThreshold` , event timelines are applied while
815
+ * this animation is being mixed out. Defaults to 0, so event timelines are not applied while this animation is being mixed
816
+ * out. */
800
817
  eventThreshold = 0;
801
- /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the
802
- * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to
803
- * 0, so attachment timelines are not applied while this animation is being mixed out. */
818
+ /** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
819
+ * applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
820
+ * animation is being mixed out. */
804
821
  mixAttachmentThreshold = 0;
805
- /** When {@link #getAlpha()} is greater than <code>alphaAttachmentThreshold</code>, attachment timelines are applied.
806
- * Defaults to 0, so attachment timelines are always applied. */
822
+ /** When the computed alpha is greater than `alphaAttachmentThreshold`, attachment timelines are applied. The
823
+ * computed alpha includes {@link alpha} and the interpolated mix percentage. Defaults to 0, so attachment timelines are
824
+ * always applied. */
807
825
  alphaAttachmentThreshold = 0;
808
- /** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
809
- * <code>mixDrawOrderThreshold</code>, draw order timelines are applied while this animation is being mixed out. Defaults to
810
- * 0, so draw order timelines are not applied while this animation is being mixed out. */
826
+ /** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
827
+ * applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
828
+ * animation is being mixed out. */
811
829
  mixDrawOrderThreshold = 0;
812
- /** Seconds when this animation starts, both initially and after looping. Defaults to 0.
830
+ /** The time in seconds for the first frame of this animation, both initially and after looping. Defaults to 0.
813
831
  *
814
- * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same
815
- * value to prevent timeline keys before the start time from triggering. */
832
+ * When setting `animationStart` time, {@link animationLast} can be set to the same value to avoid firing events
833
+ * from the start of the animation. */
816
834
  animationStart = 0;
817
- /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will
818
- * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */
835
+ /** The time in seconds for the last frame of this animation. Past this time, non-looping animations hold the pose at this
836
+ * time while looping animations will loop back to {@link animationStart}. Defaults to the {@link Animation.duration}. */
819
837
  animationEnd = 0;
820
- /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
821
- * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and
822
- * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation
823
- * is applied. */
838
+ /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. For example, when
839
+ * this animation is applied, event timelines will fire all events between the `animationLast` time (exclusive)
840
+ * and `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this
841
+ * animation is applied. */
824
842
  animationLast = 0;
825
843
  nextAnimationLast = 0;
826
- /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay`
827
- * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from
828
- * the start of the previous animation to when this track entry will become the current track entry (ie when the previous
829
- * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`).
844
+ /** Seconds to postpone playing the animation. Must be >= 0. When this track entry is the current track entry,
845
+ * `delay` postpones incrementing the {@link trackTime}. When this track entry is queued, `delay` is
846
+ * the time from the start of the previous animation to when this track entry will become the current track entry (ie when
847
+ * the previous track entry {@link trackTime} >= this track entry's `delay`).
848
+ *
849
+ * {@link timeScale} affects the delay.
830
850
  *
831
- * {@link #timeScale} affects the delay. */
851
+ * When passing `delay` <= 0 to {@link AnimationState.addAnimation} this
852
+ * `delay` is set using a mix duration from {@link AnimationStateData}. To change the {@link mixDuration}
853
+ * afterward, use {@link setMixDuration} so this `delay` is adjusted. */
832
854
  delay = 0;
833
- /** Current time in seconds this track entry has been the current track entry. The track time determines
834
- * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting
835
- * looping. */
855
+ /** The time in seconds this track entry has been the current track entry, starting at 0 and increasing forever. Compare to
856
+ * {@link getAnimationTime}, which is always between {@link animationStart} and {@link animationEnd}.
857
+ *
858
+ * The track time can be set to start the animation at a time other than 0, without affecting looping. When doing so,
859
+ * {@link animationLast} can be set to the same value to avoid firing events from the start of the animation.
860
+ *
861
+ * To set the time an animation starts and loops, use {@link animationStart} and {@link animationEnd}. */
836
862
  trackTime = 0;
837
863
  trackLast = 0;
838
864
  nextTrackLast = 0;
@@ -841,94 +867,127 @@ export class TrackEntry {
841
867
  * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
842
868
  * properties keyed by the animation are set to the setup pose and the track is cleared.
843
869
  *
844
- * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation
870
+ * Usually you want to use {@link AnimationState.addEmptyAnimation} rather than have the animation
845
871
  * abruptly cease being applied. */
846
872
  trackEnd = 0;
847
873
  /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or
848
874
  * faster. Defaults to 1.
849
875
  *
850
- * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to
851
- * match the animation speed.
876
+ * Values < 0 are not supported. To play an animation in reverse, use {@link reverse}.
877
+ *
878
+ * {@link mixTime} is not affected by track entry time scale, so {@link mixDuration} may need to be adjusted to match the
879
+ * animation speed.
852
880
  *
853
- * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the
854
- * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If
855
- * the time scale is not 1, the delay may need to be adjusted.
881
+ * When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
882
+ * {@link delay} is set using the mix duration from {@link AnimationState.data}, assuming time scale to be 1. If the time
883
+ * scale is not 1, the delay may need to be adjusted.
856
884
  *
857
- * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */
885
+ * See {@link AnimationState.timeScale} to affect all animations. */
858
886
  timeScale = 0;
859
- /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults
860
- * to 1, which overwrites the skeleton's current pose with this animation.
887
+ /** Values < 1 mix this animation with the skeleton's current pose (either the setup pose or the pose from lower tracks).
888
+ * Defaults to 1, which overwrites the skeleton's current pose with this animation.
861
889
  *
862
- * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to
863
- * use alpha on track 0 if the skeleton pose is from the last frame render. */
890
+ * Alpha should be 1 on track 0.
891
+ *
892
+ * See {@link getAlphaAttachmentThreshold}. */
864
893
  alpha = 0;
865
- /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be
866
- * slightly more than `mixDuration` when the mix is complete. */
894
+ /** Seconds elapsed from 0 to the {@link mixDuration} when mixing from the previous animation to this animation. May
895
+ * be slightly more than `mixDuration` when the mix is complete. */
867
896
  mixTime = 0;
868
- /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData
869
- * {@link AnimationStateData#getMix()} based on the animation before this animation (if any).
897
+ /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
898
+ * {@link AnimationStateData.getMix} based on the animation before this animation (if any).
870
899
  *
871
- * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the
872
- * properties it was animating.
900
+ * A mix duration of 0 still needs to be applied one more time to mix out, so the the properties it was animating are
901
+ * reverted. A mix duration of 0 can be set at any time to end the mix on the next
902
+ * {@link AnimationState.update | update}.
873
903
  *
874
904
  * The `mixDuration` can be set manually rather than use the value from
875
- * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new
876
- * track entry only before {@link AnimationState#update(float)} is first called.
905
+ * {@link AnimationStateData.getMix}. In that case, the `mixDuration` can be set for a new
906
+ * track entry only before {@link AnimationState.update} is next called.
907
+ *
908
+ * When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
909
+ * {@link getDelay} is set using the mix duration from {@link AnimationState.data}. If `mixDuration` is set
910
+ * afterward, the delay needs to be adjusted:
911
+ *
912
+ * <pre>
913
+ * entry.mixDuration = 0.25;<br>
914
+ * entry.delay = entry.previous.getTrackComplete() - entry.mixDuration + 0;
915
+ * </pre>
877
916
  *
878
- * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the
879
- * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set
880
- * afterward. */
881
- _mixDuration = 0;
882
- interruptAlpha = 0;
917
+ * Alternatively, use {@link setMixDuration} to set both the mix duration and recompute the delay:<br>
918
+ *
919
+ * <pre>
920
+ entry.setMixDuration(0.25f, 0); // mixDuration, delay
921
+ * </pre>
922
+ */
923
+ mixDuration = 0;
883
924
  totalAlpha = 0;
884
- get mixDuration() {
885
- return this._mixDuration;
925
+ mixInterpolation = Interpolation.linear;
926
+ /** Sets both {@link getMixDuration} and {@link getDelay}.
927
+ * @param delay If > 0, sets {@link getDelay}. If <= 0, the delay set is the duration of the previous track entry minus
928
+ * the specified mix duration plus the specified `delay` (ie the mix ends at (when `delay` =
929
+ * 0) or before (when `delay` < 0) the previous track entry duration). If the previous entry is
930
+ * looping, its next loop completion is used instead of its duration. */
931
+ setMixDuration(mixDuration, delay) {
932
+ this.mixDuration = mixDuration;
933
+ if (delay !== undefined) {
934
+ if (delay <= 0)
935
+ delay = this.previous == null ? 0 : Math.max(delay + this.previous.getTrackComplete() - mixDuration, 0);
936
+ this.delay = delay;
937
+ }
886
938
  }
887
- set mixDuration(mixDuration) {
888
- this._mixDuration = mixDuration;
939
+ /** The interpolation to apply to the mix percentage ({@link mixTime} / {@link mixDuration}) when mixing from the previous
940
+ * animation to this animation. Defaults to linear. */
941
+ setMixInterpolation(mixInterpolation) {
942
+ if (!mixInterpolation)
943
+ throw new Error("mixInterpolation cannot be null.");
944
+ this.mixInterpolation = mixInterpolation;
889
945
  }
890
- setMixDurationWithDelay(mixDuration, delay) {
891
- this._mixDuration = mixDuration;
892
- if (delay <= 0) {
893
- if (this.previous != null)
894
- delay = Math.max(delay + this.previous.getTrackComplete() - mixDuration, 0);
895
- else
896
- delay = 0;
897
- }
898
- this.delay = delay;
946
+ mix() {
947
+ if (this.mixDuration === 0)
948
+ return 1;
949
+ let mix = this.mixTime / this.mixDuration;
950
+ if (mix >= 1)
951
+ return 1;
952
+ if (this.mixInterpolation === Interpolation.linear)
953
+ return mix;
954
+ mix = this.mixInterpolation.apply(mix);
955
+ if (mix < 0)
956
+ return 0;
957
+ if (mix > 1)
958
+ return 1;
959
+ return mix;
899
960
  }
900
- /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which
901
- * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to
902
- * the values from the lower tracks.
903
- *
904
- * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first
905
- * called. */
906
- mixBlend = MixBlend.replace;
907
- timelineMode = new Array();
908
- timelineHoldMix = new Array();
909
- timelinesRotation = new Array();
961
+ /** For each timeline:
962
+ * - Bit 0, FIRST: 0 = mix from current pose, 1 = mix from setup pose. Timeline is first to set the property.
963
+ * - Bit 1, HOLD: 0 = mix out using alphaMix, 1 = apply full alpha to prevent dipping. Timeline is first on its track to
964
+ * set the property and the next entry (mixingTo) also sets it. When held, timelineHoldMix's mix controls how the hold fades
965
+ * out (for 3+ entry chains where the chain eventually stops setting the property). */
966
+ timelineMode = [];
967
+ timelineHoldMix = [];
968
+ timelinesRotation = [];
910
969
  reset() {
911
970
  this.next = null;
912
971
  this.previous = null;
913
972
  this.mixingFrom = null;
914
973
  this.mixingTo = null;
974
+ this.mixInterpolation = Interpolation.linear;
915
975
  this.animation = null;
916
976
  this.listener = null;
917
977
  this.timelineMode.length = 0;
918
978
  this.timelineHoldMix.length = 0;
919
979
  this.timelinesRotation.length = 0;
920
980
  }
921
- /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart}
922
- * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the
981
+ /** Uses {@link trackTime} to compute the `animationTime`, which is always between {@link animationStart} and
982
+ * {@link animationEnd}. When `trackTime` is 0, `animationTime` is equal to the
923
983
  * `animationStart` time. */
924
984
  getAnimationTime() {
925
- if (this.loop) {
926
- let duration = this.animationEnd - this.animationStart;
927
- if (duration == 0)
928
- return this.animationStart;
929
- return (this.trackTime % duration) + this.animationStart;
930
- }
931
- return Math.min(this.trackTime + this.animationStart, this.animationEnd);
985
+ if (!this.loop)
986
+ return Math.min(this.trackTime + this.animationStart, this.animationEnd);
987
+ const duration = this.animationEnd - this.animationStart;
988
+ if (duration === 0)
989
+ return this.animationStart;
990
+ return (this.trackTime % duration) + this.animationStart;
932
991
  }
933
992
  setAnimationLast(animationLast) {
934
993
  this.animationLast = animationLast;
@@ -936,23 +995,29 @@ export class TrackEntry {
936
995
  }
937
996
  /** Returns true if at least one loop has been completed.
938
997
  *
939
- * See {@link AnimationStateListener#complete()}. */
998
+ * See {@link AnimationStateListener.complete}. */
940
999
  isComplete() {
941
1000
  return this.trackTime >= this.animationEnd - this.animationStart;
942
1001
  }
943
- /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
944
- * long way around when using {@link #alpha} and starting animations on other tracks.
1002
+ /** When {@link shortestRotation} is false, this clears the directions for mixing this entry's rotation. This can be useful
1003
+ * to avoid bones rotating the long way around when using {@link getAlpha} and starting animations on other tracks.
945
1004
  *
946
- * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions:
947
- * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long
948
- * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the
949
- * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */
1005
+ * Mixing involves finding a rotation between two others. There are two possible solutions: the short or the long way
1006
+ * around. When the two rotations change over time, which direction is the short or long way can also change. If the short
1007
+ * way was always chosen, bones flip to the other side when that direction became the long way. TrackEntry chooses the short
1008
+ * way the first time it is applied and remembers that direction. Resetting that direction makes it choose a new short way
1009
+ * on the next apply. */
950
1010
  resetRotationDirections() {
951
1011
  this.timelinesRotation.length = 0;
952
1012
  }
1013
+ /** If this track entry is non-looping, this is the track time in seconds when {@link animationEnd} is reached, or the
1014
+ * current {@link trackTime} if it has already been reached.
1015
+ *
1016
+ * If this track entry is looping, this is the track time when this animation will reach its next {@link animationEnd} (the
1017
+ * next loop completion). */
953
1018
  getTrackComplete() {
954
- let duration = this.animationEnd - this.animationStart;
955
- if (duration != 0) {
1019
+ const duration = this.animationEnd - this.animationStart;
1020
+ if (duration !== 0) {
956
1021
  if (this.loop)
957
1022
  return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop.
958
1023
  if (this.trackTime < duration)
@@ -961,13 +1026,13 @@ export class TrackEntry {
961
1026
  return this.trackTime; // Next update.
962
1027
  }
963
1028
  /** Returns true if this track entry has been applied at least once.
964
- * <p>
965
- * See {@link AnimationState#apply(Skeleton)}. */
1029
+ *
1030
+ * See {@link AnimationState.apply}. */
966
1031
  wasApplied() {
967
- return this.nextTrackLast != -1;
1032
+ return this.nextTrackLast !== -1;
968
1033
  }
969
- /** Returns true if there is a {@link #getNext()} track entry and it will become the current track entry during the next
970
- * {@link AnimationState#update(float)}. */
1034
+ /** Returns true if there is a {@link next} track entry and it will become the current track entry during the next
1035
+ * {@link AnimationState.update}. */
971
1036
  isNextReady() {
972
1037
  return this.next != null && this.nextTrackLast - this.next.delay >= 0;
973
1038
  }
@@ -1008,70 +1073,72 @@ export class EventQueue {
1008
1073
  }
1009
1074
  drain() {
1010
1075
  if (this.drainDisabled)
1011
- return;
1076
+ return; // Not reentrant.
1012
1077
  this.drainDisabled = true;
1013
- let objects = this.objects;
1014
- for (let i = 0; i < objects.length; i += 2) {
1015
- let type = objects[i];
1016
- let entry = objects[i + 1];
1017
- let listeners = this.animState.listeners.slice();
1078
+ for (let i = 0; i < this.objects.length; i += 2) {
1079
+ const objects = this.objects;
1080
+ const type = objects[i];
1081
+ const entry = objects[i + 1];
1082
+ const listeners = this.animState.listeners.slice();
1018
1083
  switch (type) {
1019
1084
  case EventType.start:
1020
- if (entry.listener && entry.listener.start)
1085
+ if (entry.listener?.start)
1021
1086
  entry.listener.start(entry);
1022
1087
  for (let ii = 0; ii < listeners.length; ii++) {
1023
- let listener = listeners[ii];
1088
+ const listener = listeners[ii];
1024
1089
  if (listener.start)
1025
1090
  listener.start(entry);
1026
1091
  }
1027
1092
  break;
1028
1093
  case EventType.interrupt:
1029
- if (entry.listener && entry.listener.interrupt)
1094
+ if (entry.listener?.interrupt)
1030
1095
  entry.listener.interrupt(entry);
1031
1096
  for (let ii = 0; ii < listeners.length; ii++) {
1032
- let listener = listeners[ii];
1097
+ const listener = listeners[ii];
1033
1098
  if (listener.interrupt)
1034
1099
  listener.interrupt(entry);
1035
1100
  }
1036
1101
  break;
1102
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: reference runtime does fall through
1037
1103
  case EventType.end:
1038
- if (entry.listener && entry.listener.end)
1104
+ if (entry.listener?.end)
1039
1105
  entry.listener.end(entry);
1040
1106
  for (let ii = 0; ii < listeners.length; ii++) {
1041
- let listener = listeners[ii];
1107
+ const listener = listeners[ii];
1042
1108
  if (listener.end)
1043
1109
  listener.end(entry);
1044
1110
  }
1045
1111
  // Fall through.
1046
1112
  case EventType.dispose:
1047
- if (entry.listener && entry.listener.dispose)
1113
+ if (entry.listener?.dispose)
1048
1114
  entry.listener.dispose(entry);
1049
1115
  for (let ii = 0; ii < listeners.length; ii++) {
1050
- let listener = listeners[ii];
1116
+ const listener = listeners[ii];
1051
1117
  if (listener.dispose)
1052
1118
  listener.dispose(entry);
1053
1119
  }
1054
1120
  this.animState.trackEntryPool.free(entry);
1055
1121
  break;
1056
1122
  case EventType.complete:
1057
- if (entry.listener && entry.listener.complete)
1123
+ if (entry.listener?.complete)
1058
1124
  entry.listener.complete(entry);
1059
1125
  for (let ii = 0; ii < listeners.length; ii++) {
1060
- let listener = listeners[ii];
1126
+ const listener = listeners[ii];
1061
1127
  if (listener.complete)
1062
1128
  listener.complete(entry);
1063
1129
  }
1064
1130
  break;
1065
- case EventType.event:
1066
- let event = objects[i++ + 2];
1067
- if (entry.listener && entry.listener.event)
1131
+ case EventType.event: {
1132
+ const event = objects[i++ + 2];
1133
+ if (entry.listener?.event)
1068
1134
  entry.listener.event(entry, event);
1069
1135
  for (let ii = 0; ii < listeners.length; ii++) {
1070
- let listener = listeners[ii];
1136
+ const listener = listeners[ii];
1071
1137
  if (listener.event)
1072
1138
  listener.event(entry, event);
1073
1139
  }
1074
1140
  break;
1141
+ }
1075
1142
  }
1076
1143
  }
1077
1144
  this.clear();
@@ -1104,40 +1171,10 @@ export class AnimationStateAdapter {
1104
1171
  event(entry, event) {
1105
1172
  }
1106
1173
  }
1107
- /** 1. A previously applied timeline has set this property.
1108
- *
1109
- * Result: Mix from the current pose to the timeline pose. */
1110
1174
  export const SUBSEQUENT = 0;
1111
- /** 1. This is the first timeline to set this property.
1112
- * 2. The next track entry applied after this one does not have a timeline to set this property.
1113
- *
1114
- * Result: Mix from the setup pose to the timeline pose. */
1115
1175
  export const FIRST = 1;
1116
- /** 1) A previously applied timeline has set this property.<br>
1117
- * 2) The next track entry to be applied does have a timeline to set this property.<br>
1118
- * 3) The next track entry after that one does not have a timeline to set this property.<br>
1119
- * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading
1120
- * animations that key the same property. A subsequent timeline will set this property using a mix. */
1121
- export const HOLD_SUBSEQUENT = 2;
1122
- /** 1) This is the first timeline to set this property.<br>
1123
- * 2) The next track entry to be applied does have a timeline to set this property.<br>
1124
- * 3) The next track entry after that one does not have a timeline to set this property.<br>
1125
- * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations
1126
- * that key the same property. A subsequent timeline will set this property using a mix. */
1176
+ export const HOLD = 2;
1127
1177
  export const HOLD_FIRST = 3;
1128
- /** 1. This is the first timeline to set this property.
1129
- * 2. The next track entry to be applied does have a timeline to set this property.
1130
- * 3. The next track entry after that one does have a timeline to set this property.
1131
- * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property.
1132
- *
1133
- * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than
1134
- * 2 track entries in a row have a timeline that sets the same property.
1135
- *
1136
- * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid
1137
- * "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A
1138
- * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into
1139
- * place. */
1140
- export const HOLD_MIX = 4;
1141
1178
  export const SETUP = 1;
1142
- export const CURRENT = 2;
1143
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQW5pbWF0aW9uU3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSW5KLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJL0Q7OztvSEFHb0g7QUFDcEgsTUFBTSxPQUFPLGNBQWM7SUFDMUIsTUFBTSxDQUFDLGVBQWUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sQ0FBQyxjQUFjO1FBQzVCLE9BQU8sY0FBYyxDQUFDLGVBQWUsQ0FBQztJQUN2QyxDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELElBQUksQ0FBcUI7SUFFekIseUZBQXlGO0lBQ3pGLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBcUIsQ0FBQztJQUV4Qzs7O3VGQUdtRjtJQUNuRixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUVqQixNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVMsQ0FBQztJQUM1QixTQUFTLEdBQUcsSUFBSSxLQUFLLEVBQTBCLENBQUM7SUFDaEQsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLFdBQVcsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQzlCLGlCQUFpQixHQUFHLEtBQUssQ0FBQztJQUUxQixjQUFjLEdBQUcsSUFBSSxJQUFJLENBQWEsR0FBRyxFQUFFLENBQUMsSUFBSSxV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SUFBRSxtREFBUyxDQUFBO0lBQUUsdUNBQUcsQ0FBQTtJQUFFLCtDQUFPLENBQUE7SUFBRSxpREFBUSxDQUFBO0lBQUUsMkNBQUssQ0FBQTtBQUNoRCxDQUFDLEVBRlcsU0FBUyxLQUFULFNBQVMsUUFFcEI7QUE2QkQsTUFBTSxPQUFnQixxQkFBcUI7SUFDMUMsS0FBSyxDQUFFLEtBQWlCO0lBQ3hCLENBQUM7SUFFRCxTQUFTLENBQUUsS0FBaUI7SUFDNUIsQ0FBQztJQUVELEdBQUcsQ0FBRSxLQUFpQjtJQUN0QixDQUFDO0lBRUQsT0FBTyxDQUFFLEtBQWlCO0lBQzFCLENBQUM7SUFFRCxRQUFRLENBQUUsS0FBaUI7SUFDM0IsQ0FBQztJQUVELEtBQUssQ0FBRSxLQUFpQixFQUFFLEtBQVk7SUFDdEMsQ0FBQztDQUNEO0FBRUQ7OzZEQUU2RDtBQUM3RCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0FBQzVCOzs7MkRBRzJEO0FBQzNELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDdkI7Ozs7c0dBSXNHO0FBQ3RHLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLENBQUM7QUFDakM7Ozs7MkZBSTJGO0FBQzNGLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDNUI7Ozs7Ozs7Ozs7O1lBV1k7QUFDWixNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRTFCLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDdkIsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgQW5pbWF0aW9uLCBNaXhCbGVuZCwgQXR0YWNobWVudFRpbWVsaW5lLCBNaXhEaXJlY3Rpb24sIFJvdGF0ZVRpbWVsaW5lLCBEcmF3T3JkZXJUaW1lbGluZSwgVGltZWxpbmUsIEV2ZW50VGltZWxpbmUgfSBmcm9tIFwiLi9BbmltYXRpb24uanNcIjtcbmltcG9ydCB7IEFuaW1hdGlvblN0YXRlRGF0YSB9IGZyb20gXCIuL0FuaW1hdGlvblN0YXRlRGF0YS5qc1wiO1xuaW1wb3J0IHsgU2tlbGV0b24gfSBmcm9tIFwiLi9Ta2VsZXRvbi5qc1wiO1xuaW1wb3J0IHsgU2xvdCB9IGZyb20gXCIuL1Nsb3QuanNcIjtcbmltcG9ydCB7IFN0cmluZ1NldCwgUG9vbCwgVXRpbHMsIE1hdGhVdGlscyB9IGZyb20gXCIuL1V0aWxzLmpzXCI7XG5pbXBvcnQgeyBFdmVudCB9IGZyb20gXCIuL0V2ZW50LmpzXCI7XG5cblxuLyoqIEFwcGxpZXMgYW5pbWF0aW9ucyBvdmVyIHRpbWUsIHF1ZXVlcyBhbmltYXRpb25zIGZvciBsYXRlciBwbGF5YmFjaywgbWl4ZXMgKGNyb3NzZmFkaW5nKSBiZXR3ZWVuIGFuaW1hdGlvbnMsIGFuZCBhcHBsaWVzXG4gKiBtdWx0aXBsZSBhbmltYXRpb25zIG9uIHRvcCBvZiBlYWNoIG90aGVyIChsYXllcmluZykuXG4gKlxuICogU2VlIFtBcHBseWluZyBBbmltYXRpb25zXShodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtYXBwbHlpbmctYW5pbWF0aW9ucy8pIGluIHRoZSBTcGluZSBSdW50aW1lcyBHdWlkZS4gKi9cbmV4cG9ydCBjbGFzcyBBbmltYXRpb25TdGF0ZSB7XG5cdHN0YXRpYyBfZW1wdHlBbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKFwiPGVtcHR5PlwiLCBbXSwgMCk7XG5cdHByaXZhdGUgc3RhdGljIGVtcHR5QW5pbWF0aW9uICgpOiBBbmltYXRpb24ge1xuXHRcdHJldHVybiBBbmltYXRpb25TdGF0ZS5fZW1wdHlBbmltYXRpb247XG5cdH1cblxuXHQvKiogVGhlIEFuaW1hdGlvblN0YXRlRGF0YSB0byBsb29rIHVwIG1peCBkdXJhdGlvbnMuICovXG5cdGRhdGE6IEFuaW1hdGlvblN0YXRlRGF0YTtcblxuXHQvKiogVGhlIGxpc3Qgb2YgdHJhY2tzIHRoYXQgY3VycmVudGx5IGhhdmUgYW5pbWF0aW9ucywgd2hpY2ggbWF5IGNvbnRhaW4gbnVsbCBlbnRyaWVzLiAqL1xuXHR0cmFja3MgPSBuZXcgQXJyYXk8VHJhY2tFbnRyeSB8IG51bGw+KCk7XG5cblx0LyoqIE11bHRpcGxpZXIgZm9yIHRoZSBkZWx0YSB0aW1lIHdoZW4gdGhlIGFuaW1hdGlvbiBzdGF0ZSBpcyB1cGRhdGVkLCBjYXVzaW5nIHRpbWUgZm9yIGFsbCBhbmltYXRpb25zIGFuZCBtaXhlcyB0byBwbGF5IHNsb3dlclxuXHQgKiBvciBmYXN0ZXIuIERlZmF1bHRzIHRvIDEuXG5cdCAqXG5cdCAqIFNlZSBUcmFja0VudHJ5IHtAbGluayBUcmFja0VudHJ5I3RpbWVTY2FsZX0gZm9yIGFmZmVjdGluZyBhIHNpbmdsZSBhbmltYXRpb24uICovXG5cdHRpbWVTY2FsZSA9IDE7XG5cdHVua2V5ZWRTdGF0ZSA9IDA7XG5cblx0ZXZlbnRzID0gbmV3IEFycmF5PEV2ZW50PigpO1xuXHRsaXN0ZW5lcnMgPSBuZXcgQXJyYXk8QW5pbWF0aW9uU3RhdGVMaXN0ZW5lcj4oKTtcblx0cXVldWUgPSBuZXcgRXZlbnRRdWV1ZSh0aGlzKTtcblx0cHJvcGVydHlJRHMgPSBuZXcgU3RyaW5nU2V0KCk7XG5cdGFuaW1hdGlvbnNDaGFuZ2VkID0gZmFsc2U7XG5cblx0dHJhY2tFbnRyeVBvb2wgPSBuZXcgUG9vbDxUcmFja0VudHJ5PigoKSA9PiBuZXcgVHJhY2tFbnRyeSgpKTtcblxuXHRjb25zdHJ1Y3RvciAoZGF0YTogQW5pbWF0aW9uU3RhdGVEYXRhKSB7XG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0fVxuXG5cdC8qKiBJbmNyZW1lbnRzIGVhY2ggdHJhY2sgZW50cnkge0BsaW5rIFRyYWNrRW50cnkjdHJhY2tUaW1lKCl9LCBzZXR0aW5nIHF1ZXVlZCBhbmltYXRpb25zIGFzIGN1cnJlbnQgaWYgbmVlZGVkLiAqL1xuXHR1cGRhdGUgKGRlbHRhOiBudW1iZXIpIHtcblx0XHRkZWx0YSAqPSB0aGlzLnRpbWVTY2FsZTtcblx0XHRsZXQgdHJhY2tzID0gdGhpcy50cmFja3M7XG5cdFx0Zm9yIChsZXQgaSA9IDAsIG4gPSB0cmFja3MubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG5cdFx0XHRsZXQgY3VycmVudCA9IHRyYWNrc1tpXTtcblx0XHRcdGlmICghY3VycmVudCkgY29udGludWU7XG5cblx0XHRcdGN1cnJlbnQuYW5pbWF0aW9uTGFzdCA9IGN1cnJlbnQubmV4dEFuaW1hdGlvbkxhc3Q7XG5cdFx0XHRjdXJyZW50LnRyYWNrTGFzdCA9IGN1cnJlbnQubmV4dFRyYWNrTGFzdDtcblxuXHRcdFx0bGV0IGN1cnJlbnREZWx0YSA9IGRlbHRhICogY3VycmVudC50aW1lU2NhbGU7XG5cblx0XHRcdGlmIChjdXJyZW50LmRlbGF5ID4gMCkge1xuXHRcdFx0XHRjdXJyZW50LmRlbGF5IC09IGN1cnJlbnREZWx0YTtcblx0XHRcdFx0aWYgKGN1cnJlbnQuZGVsYXkgPiAwKSBjb250aW51ZTtcblx0XHRcdFx0Y3VycmVudERlbHRhID0gLWN1cnJlbnQuZGVsYXk7XG5cdFx0XHRcdGN1cnJlbnQuZGVsYXkgPSAwO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgbmV4dCA9IGN1cnJlbnQubmV4dDtcblx0XHRcdGlmIChuZXh0KSB7XG5cdFx0XHRcdC8vIFdoZW4gdGhlIG5leHQgZW50cnkncyBkZWxheSBpcyBwYXNzZWQsIGNoYW5nZSB0byB0aGUgbmV4dCBlbnRyeSwgcHJlc2VydmluZyBsZWZ0b3ZlciB0aW1lLlxuXHRcdFx0XHRsZXQgbmV4dFRpbWUgPSBjdXJyZW50LnRyYWNrTGFzdCAtIG5leHQuZGVsYXk7XG5cdFx0XHRcdGlmIChuZXh0VGltZSA+PSAwKSB7XG5cdFx0XHRcdFx0bmV4dC5kZWxheSA9IDA7XG5cdFx0XHRcdFx0bmV4dC50cmFja1RpbWUgKz0gY3VycmVudC50aW1lU2NhbGUgPT0gMCA/IDAgOiAobmV4dFRpbWUgLyBjdXJyZW50LnRpbWVTY2FsZSArIGRlbHRhKSAqIG5leHQudGltZVNjYWxlO1xuXHRcdFx0XHRcdGN1cnJlbnQudHJhY2tUaW1lICs9IGN1cnJlbnREZWx0YTtcblx0XHRcdFx0XHR0aGlzLnNldEN1cnJlbnQoaSwgbmV4dCwgdHJ1ZSk7XG5cdFx0XHRcdFx0d2hpbGUgKG5leHQubWl4aW5nRnJvbSkge1xuXHRcdFx0XHRcdFx0bmV4dC5taXhUaW1lICs9IGRlbHRhO1xuXHRcdFx0XHRcdFx0bmV4dCA9IG5leHQubWl4aW5nRnJvbTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoY3VycmVudC50cmFja0xhc3QgPj0gY3VycmVudC50cmFja0VuZCAmJiAhY3VycmVudC5taXhpbmdGcm9tKSB7XG5cdFx0XHRcdHRyYWNrc1tpXSA9IG51bGw7XG5cdFx0XHRcdHRoaXMucXVldWUuZW5kKGN1cnJlbnQpO1xuXHRcdFx0XHR0aGlzLmNsZWFyTmV4dChjdXJyZW50KTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRpZiAoY3VycmVudC5taXhpbmdGcm9tICYmIHRoaXMudXBkYXRlTWl4aW5nRnJvbShjdXJyZW50LCBkZWx0YSkpIHtcblx0XHRcdFx0Ly8gRW5kIG1peGluZyBmcm9tIGVudHJpZXMgb25jZSBhbGwgaGF2ZSBjb21wbGV0ZWQuXG5cdFx0XHRcdGxldCBmcm9tOiBUcmFja0VudHJ5IHwgbnVsbCA9IGN1cnJlbnQubWl4aW5nRnJvbTtcblx0XHRcdFx0Y3VycmVudC5taXhpbmdGcm9tID0gbnVsbDtcblx0XHRcdFx0aWYgKGZyb20pIGZyb20ubWl4aW5nVG8gPSBudWxsO1xuXHRcdFx0XHR3aGlsZSAoZnJvbSkge1xuXHRcdFx0XHRcdHRoaXMucXVldWUuZW5kKGZyb20pO1xuXHRcdFx0XHRcdGZyb20gPSBmcm9tLm1peGluZ0Zyb207XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Y3VycmVudC50cmFja1RpbWUgKz0gY3VycmVudERlbHRhO1xuXHRcdH1cblxuXHRcdHRoaXMucXVldWUuZHJhaW4oKTtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRydWUgd2hlbiBhbGwgbWl4aW5nIGZyb20gZW50cmllcyBhcmUgY29tcGxldGUuICovXG5cdHVwZGF0ZU1peGluZ0Zyb20gKHRvOiBUcmFja0VudHJ5LCBkZWx0YTogbnVtYmVyKTogYm9vbGVhbiB7XG5cdFx0bGV0IGZyb20gPSB0by5taXhpbmdGcm9tO1xuXHRcdGlmICghZnJvbSkgcmV0dXJuIHRydWU7XG5cblx0XHRsZXQgZmluaXNoZWQgPSB0aGlzLnVwZGF0ZU1peGluZ0Zyb20oZnJvbSwgZGVsdGEpO1xuXG5cdFx0ZnJvbS5hbmltYXRpb25MYXN0ID0gZnJvbS5uZXh0QW5pbWF0aW9uTGFzdDtcblx0XHRmcm9tLnRyYWNrTGFzdCA9IGZyb20ubmV4dFRyYWNrTGFzdDtcblxuXHRcdC8vIFRoZSBmcm9tIGVudHJ5IHdhcyBhcHBsaWVkIGF0IGxlYXN0IG9uY2UgYW5kIHRoZSBtaXggaXMgY29tcGxldGUuXG5cdFx0aWYgKHRvLm5leHRUcmFja0xhc3QgIT0gLTEgJiYgdG8ubWl4VGltZSA+PSB0by5taXhEdXJhdGlvbikge1xuXHRcdFx0Ly8gTWl4aW5nIGlzIGNvbXBsZXRlIGZvciBhbGwgZW50cmllcyBiZWZvcmUgdGhlIGZyb20gZW50cnkgb3IgdGhlIG1peCBpcyBpbnN0YW50YW5lb3VzLlxuXHRcdFx0aWYgKGZyb20udG90YWxBbHBoYSA9PSAwIHx8IHRvLm1peER1cmF0aW9uID09IDApIHtcblx0XHRcdFx0dG8ubWl4aW5nRnJvbSA9IGZyb20ubWl4aW5nRnJvbTtcblx0XHRcdFx0aWYgKGZyb20ubWl4aW5nRnJvbSAhPSBudWxsKSBmcm9tLm1peGluZ0Zyb20ubWl4aW5nVG8gPSB0bztcblx0XHRcdFx0dG8uaW50ZXJydXB0QWxwaGEgPSBmcm9tLmludGVycnVwdEFscGhhO1xuXHRcdFx0XHR0aGlzLnF1ZXVlLmVuZChmcm9tKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmaW5pc2hlZDtcblx0XHR9XG5cblx0XHRmcm9tLnRyYWNrVGltZSArPSBkZWx0YSAqIGZyb20udGltZVNjYWxlO1xuXHRcdHRvLm1peFRpbWUgKz0gZGVsdGE7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0LyoqIFBvc2VzIHRoZSBza2VsZXRvbiB1c2luZyB0aGUgdHJhY2sgZW50cnkgYW5pbWF0aW9ucy4gVGhlcmUgYXJlIG5vIHNpZGUgZWZmZWN0cyBvdGhlciB0aGFuIGludm9raW5nIGxpc3RlbmVycywgc28gdGhlXG5cdCAqIGFuaW1hdGlvbiBzdGF0ZSBjYW4gYmUgYXBwbGllZCB0byBtdWx0aXBsZSBza2VsZXRvbnMgdG8gcG9zZSB0aGVtIGlkZW50aWNhbGx5LlxuXHQgKiBAcmV0dXJucyBUcnVlIGlmIGFueSBhbmltYXRpb25zIHdlcmUgYXBwbGllZC4gKi9cblx0YXBwbHkgKHNrZWxldG9uOiBTa2VsZXRvbik6IGJvb2xlYW4ge1xuXHRcdGlmICghc2tlbGV0b24pIHRocm93IG5ldyBFcnJvcihcInNrZWxldG9uIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHRpZiAodGhpcy5hbmltYXRpb25zQ2hhbmdlZCkgdGhpcy5fYW5pbWF0aW9uc0NoYW5nZWQoKTtcblxuXHRcdGxldCBldmVudHMgPSB0aGlzLmV2ZW50cztcblx0XHRsZXQgdHJhY2tzID0gdGhpcy50cmFja3M7XG5cdFx0bGV0IGFwcGxpZWQgPSBmYWxzZTtcblxuXHRcdGZvciAobGV0IGkgPSAwLCBuID0gdHJhY2tzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuXHRcdFx0bGV0IGN1cnJlbnQgPSB0cmFja3NbaV07XG5cdFx0XHRpZiAoIWN1cnJlbnQgfHwgY3VycmVudC5kZWxheSA+IDApIGNvbnRpbnVlO1xuXHRcdFx0YXBwbGllZCA9IHRydWU7XG5cdFx0XHRsZXQgYmxlbmQ6IE1peEJsZW5kID0gaSA9PSAwID8gTWl4QmxlbmQuZmlyc3QgOiBjdXJyZW50Lm1peEJsZW5kO1xuXG5cdFx0XHQvLyBBcHBseSBtaXhpbmcgZnJvbSBlbnRyaWVzIGZpcnN0LlxuXHRcdFx0bGV0IGFscGhhID0gY3VycmVudC5hbHBoYTtcblx0XHRcdGlmIChjdXJyZW50Lm1peGluZ0Zyb20pXG5cdFx0XHRcdGFscGhhICo9IHRoaXMuYXBwbHlNaXhpbmdGcm9tKGN1cnJlbnQsIHNrZWxldG9uLCBibGVuZCk7XG5cdFx0XHRlbHNlIGlmIChjdXJyZW50LnRyYWNrVGltZSA+PSBjdXJyZW50LnRyYWNrRW5kICYmICFjdXJyZW50Lm5leHQpXG5cdFx0XHRcdGFscGhhID0gMDtcblx0XHRcdGxldCBhdHRhY2htZW50cyA9IGFscGhhID49IGN1cnJlbnQuYWxwaGFBdHRhY2htZW50VGhyZXNob2xkO1xuXG5cblx0XHRcdC8vIEFwcGx5IGN1cnJlbnQgZW50cnkuXG5cdFx0XHRsZXQgYW5pbWF0aW9uTGFzdCA9IGN1cnJlbnQuYW5pbWF0aW9uTGFzdCwgYW5pbWF0aW9uVGltZSA9IGN1cnJlbnQuZ2V0QW5pbWF0aW9uVGltZSgpLCBhcHBseVRpbWUgPSBhbmltYXRpb25UaW1lO1xuXHRcdFx0bGV0IGFwcGx5RXZlbnRzOiBFdmVudFtdIHwgbnVsbCA9IGV2ZW50cztcblx0XHRcdGlmIChjdXJyZW50LnJldmVyc2UpIHtcblx0XHRcdFx0YXBwbHlUaW1lID0gY3VycmVudC5hbmltYXRpb24hLmR1cmF0aW9uIC0gYXBwbHlUaW1lO1xuXHRcdFx0XHRhcHBseUV2ZW50cyA9IG51bGw7XG5cdFx0XHR9XG5cdFx0XHRsZXQgdGltZWxpbmVzID0gY3VycmVudC5hbmltYXRpb24hLnRpbWVsaW5lcztcblx0XHRcdGxldCB0aW1lbGluZUNvdW50ID0gdGltZWxpbmVzLmxlbmd0aDtcblx0XHRcdGlmICgoaSA9PSAwICYmIGFscGhhID09IDEpIHx8IGJsZW5kID09IE1peEJsZW5kLmFkZCkge1xuXHRcdFx0XHRpZiAoaSA9PSAwKSBhdHRhY2htZW50cyA9IHRydWU7XG5cdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCB0aW1lbGluZUNvdW50OyBpaSsrKSB7XG5cdFx0XHRcdFx0Ly8gRml4ZXMgaXNzdWUgIzMwMiBvbiBJT1M5IHdoZXJlIG1peCwgYmxlbmQgc29tZXRpbWVzIGJlY2FtZSB1bmRlZmluZWQgYW5kIGNhdXNlZCBhc3NldHNcblx0XHRcdFx0XHQvLyB0byBzb21ldGltZXMgc3RvcCByZW5kZXJpbmcgd2hlbiB1c2luZyBjb2xvciBjb3JyZWN0aW9uLCBhcyB0aGVpciBSR0JBIHZhbHVlcyBiZWNvbWUgTmFOLlxuXHRcdFx0XHRcdC8vIChodHRwczovL2dpdGh1Yi5jb20vcGl4aWpzL3BpeGktc3BpbmUvaXNzdWVzLzMwMilcblx0XHRcdFx0XHRVdGlscy53ZWJraXQ2MDJCdWdmaXhIZWxwZXIoYWxwaGEsIGJsZW5kKTtcblx0XHRcdFx0XHR2YXIgdGltZWxpbmUgPSB0aW1lbGluZXNbaWldO1xuXHRcdFx0XHRcdGlmICh0aW1lbGluZSBpbnN0YW5jZW9mIEF0dGFjaG1lbnRUaW1lbGluZSlcblx0XHRcdFx0XHRcdHRoaXMuYXBwbHlBdHRhY2htZW50VGltZWxpbmUodGltZWxpbmUsIHNrZWxldG9uLCBhcHBseVRpbWUsIGJsZW5kLCBhdHRhY2htZW50cyk7XG5cdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdFx0dGltZWxpbmUuYXBwbHkoc2tlbGV0b24sIGFuaW1hdGlvbkxhc3QsIGFwcGx5VGltZSwgYXBwbHlFdmVudHMsIGFscGhhLCBibGVuZCwgTWl4RGlyZWN0aW9uLm1peEluKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGV0IHRpbWVsaW5lTW9kZSA9IGN1cnJlbnQudGltZWxpbmVNb2RlO1xuXG5cdFx0XHRcdGxldCBzaG9ydGVzdFJvdGF0aW9uID0gY3VycmVudC5zaG9ydGVzdFJvdGF0aW9uO1xuXHRcdFx0XHRsZXQgZmlyc3RGcmFtZSA9ICFzaG9ydGVzdFJvdGF0aW9uICYmIGN1cnJlbnQudGltZWxpbmVzUm90YXRpb24ubGVuZ3RoICE9IHRpbWVsaW5lQ291bnQgPDwgMTtcblx0XHRcdFx0aWYgKGZpcnN0RnJhbWUpIGN1cnJlbnQudGltZWxpbmVzUm90YXRpb24ubGVuZ3RoID0gdGltZWxpbmVDb3VudCA8PCAxO1xuXG5cdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCB0aW1lbGluZUNvdW50OyBpaSsrKSB7XG5cdFx0XHRcdFx0bGV0IHRpbWVsaW5lID0gdGltZWxpbmVzW2lpXTtcblx0XHRcdFx0XHRsZXQgdGltZWxpbmVCbGVuZCA9IHRpbWVsaW5lTW9kZVtpaV0gPT0gU1VCU0VRVUVOVCA/IGJsZW5kIDogTWl4QmxlbmQuc2V0dXA7XG5cdFx0XHRcdFx0aWYgKCFzaG9ydGVzdFJvdGF0aW9uICYmIHRpbWVsaW5lIGluc3RhbmNlb2YgUm90YXRlVGltZWxpbmUpIHtcblx0XHRcdFx0XHRcdHRoaXMuYXBwbHlSb3RhdGVUaW1lbGluZSh0aW1lbGluZSwgc2tlbGV0b24sIGFwcGx5VGltZSwgYWxwaGEsIHRpbWVsaW5lQmxlbmQsIGN1cnJlbnQudGltZWxpbmVzUm90YXRpb24sIGlpIDw8IDEsIGZpcnN0RnJhbWUpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAodGltZWxpbmUgaW5zdGFuY2VvZiBBdHRhY2htZW50VGltZWxpbmUpIHtcblx0XHRcdFx0XHRcdHRoaXMuYXBwbHlBdHRhY2htZW50VGltZWxpbmUodGltZWxpbmUsIHNrZWxldG9uLCBhcHBseVRpbWUsIGJsZW5kLCBhdHRhY2htZW50cyk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIFRoaXMgZml4ZXMgdGhlIFdlYktpdCA2MDIgc3BlY2lmaWMgaXNzdWUgZGVzY3JpYmVkIGF0IGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9mb3J1bS9pT1MtMTAtZGlzYXBwZWFyaW5nLWdyYXBoaWNzLTEwMTA5XG5cdFx0XHRcdFx0XHRVdGlscy53ZWJraXQ2MDJCdWdmaXhIZWxwZXIoYWxwaGEsIGJsZW5kKTtcblx0XHRcdFx0XHRcdHRpbWVsaW5lLmFwcGx5KHNrZWxldG9uLCBhbmltYXRpb25MYXN0LCBhcHBseVRpbWUsIGFwcGx5RXZlbnRzLCBhbHBoYSwgdGltZWxpbmVCbGVuZCwgTWl4RGlyZWN0aW9uLm1peEluKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMucXVldWVFdmVudHMoY3VycmVudCwgYW5pbWF0aW9uVGltZSk7XG5cdFx0XHRldmVudHMubGVuZ3RoID0gMDtcblx0XHRcdGN1cnJlbnQubmV4dEFuaW1hdGlvbkxhc3QgPSBhbmltYXRpb25UaW1lO1xuXHRcdFx0Y3VycmVudC5uZXh0VHJhY2tMYXN0ID0gY3VycmVudC50cmFja1RpbWU7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHNsb3RzIGF0dGFjaG1lbnRzIHRvIHRoZSBzZXR1cCBwb3NlLCBpZiBuZWVkZWQuIFRoaXMgb2NjdXJzIGlmIGFuIGFuaW1hdGlvbiB0aGF0IGlzIG1peGluZyBvdXQgc2V0cyBhdHRhY2htZW50cyBzb1xuXHRcdC8vIHN1YnNlcXVlbnQgdGltZWxpbmVzIHNlZSBhbnkgZGVmb3JtLCBidXQgdGhlIHN1YnNlcXVlbnQgdGltZWxpbmVzIGRvbid0IHNldCBhbiBhdHRhY2htZW50IChlZyB0aGV5IGFyZSBhbHNvIG1peGluZyBvdXQgb3Jcblx0XHQvLyB0aGUgdGltZSBpcyBiZWZvcmUgdGhlIGZpcnN0IGtleSkuXG5cdFx0dmFyIHNldHVwU3RhdGUgPSB0aGlzLnVua2V5ZWRTdGF0ZSArIFNFVFVQO1xuXHRcdHZhciBzbG90cyA9IHNrZWxldG9uLnNsb3RzO1xuXHRcdGZvciAodmFyIGkgPSAwLCBuID0gc2tlbGV0b24uc2xvdHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG5cdFx0XHR2YXIgc2xvdCA9IHNsb3RzW2ldO1xuXHRcdFx0aWYgKHNsb3QuYXR0YWNobWVudFN0YXRlID09IHNldHVwU3RhdGUpIHtcblx0XHRcdFx0dmFyIGF0dGFjaG1lbnROYW1lID0gc2xvdC5kYXRhLmF0dGFjaG1lbnROYW1lO1xuXHRcdFx0XHRzbG90LnNldEF0dGFjaG1lbnQoIWF0dGFjaG1lbnROYW1lID8gbnVsbCA6IHNrZWxldG9uLmdldEF0dGFjaG1lbnQoc2xvdC5kYXRhLmluZGV4LCBhdHRhY2htZW50TmFtZSkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnVua2V5ZWRTdGF0ZSArPSAyOyAvLyBJbmNyZWFzaW5nIGFmdGVyIGVhY2ggdXNlIGF2b2lkcyB0aGUgbmVlZCB0byByZXNldCBhdHRhY2htZW50U3RhdGUgZm9yIGV2ZXJ5IHNsb3QuXG5cblx0XHR0aGlzLnF1ZXVlLmRyYWluKCk7XG5cdFx0cmV0dXJuIGFwcGxpZWQ7XG5cdH1cblxuXHRhcHBseU1peGluZ0Zyb20gKHRvOiBUcmFja0VudHJ5LCBza2VsZXRvbjogU2tlbGV0b24sIGJsZW5kOiBNaXhCbGVuZCkge1xuXHRcdGxldCBmcm9tID0gdG8ubWl4aW5nRnJvbSE7XG5cdFx0aWYgKGZyb20ubWl4aW5nRnJvbSkgdGhpcy5hcHBseU1peGluZ0Zyb20oZnJvbSwgc2tlbGV0b24sIGJsZW5kKTtcblxuXHRcdGxldCBtaXggPSAwO1xuXHRcdGlmICh0by5taXhEdXJhdGlvbiA9PSAwKSB7IC8vIFNpbmdsZSBmcmFtZSBtaXggdG8gdW5kbyBtaXhpbmdGcm9tIGNoYW5nZXMuXG5cdFx0XHRtaXggPSAxO1xuXHRcdFx0aWYgKGJsZW5kID09IE1peEJsZW5kLmZpcnN0KSBibGVuZCA9IE1peEJsZW5kLnNldHVwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtaXggPSB0by5taXhUaW1lIC8gdG8ubWl4RHVyYXRpb247XG5cdFx0XHRpZiAobWl4ID4gMSkgbWl4ID0gMTtcblx0XHRcdGlmIChibGVuZCAhPSBNaXhCbGVuZC5maXJzdCkgYmxlbmQgPSBmcm9tLm1peEJsZW5kO1xuXHRcdH1cblxuXHRcdGxldCBhdHRhY2htZW50cyA9IG1peCA8IGZyb20ubWl4QXR0YWNobWVudFRocmVzaG9sZCwgZHJhd09yZGVyID0gbWl4IDwgZnJvbS5taXhEcmF3T3JkZXJUaHJlc2hvbGQ7XG5cdFx0bGV0IHRpbWVsaW5lcyA9IGZyb20uYW5pbWF0aW9uIS50aW1lbGluZXM7XG5cdFx0bGV0IHRpbWVsaW5lQ291bnQgPSB0aW1lbGluZXMubGVuZ3RoO1xuXHRcdGxldCBhbHBoYUhvbGQgPSBmcm9tLmFscGhhICogdG8uaW50ZXJydXB0QWxwaGEsIGFscGhhTWl4ID0gYWxwaGFIb2xkICogKDEgLSBtaXgpO1xuXHRcdGxldCBhbmltYXRpb25MYXN0ID0gZnJvbS5hbmltYXRpb25MYXN0LCBhbmltYXRpb25UaW1lID0gZnJvbS5nZXRBbmltYXRpb25UaW1lKCksIGFwcGx5VGltZSA9IGFuaW1hdGlvblRpbWU7XG5cdFx0bGV0IGV2ZW50cyA9IG51bGw7XG5cdFx0aWYgKGZyb20ucmV2ZXJzZSlcblx0XHRcdGFwcGx5VGltZSA9IGZyb20uYW5pbWF0aW9uIS5kdXJhdGlvbiAtIGFwcGx5VGltZTtcblx0XHRlbHNlIGlmIChtaXggPCBmcm9tLmV2ZW50VGhyZXNob2xkKVxuXHRcdFx0ZXZlbnRzID0gdGhpcy5ldmVudHM7XG5cblx0XHRpZiAoYmxlbmQgPT0gTWl4QmxlbmQuYWRkKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRpbWVsaW5lQ291bnQ7IGkrKylcblx0XHRcdFx0dGltZWxpbmVzW2ldLmFwcGx5KHNrZWxldG9uLCBhbmltYXRpb25MYXN0LCBhcHBseVRpbWUsIGV2ZW50cywgYWxwaGFNaXgsIGJsZW5kLCBNaXhEaXJlY3Rpb24ubWl4T3V0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGV0IHRpbWVsaW5lTW9kZSA9IGZyb20udGltZWxpbmVNb2RlO1xuXHRcdFx0bGV0IHRpbWVsaW5lSG9sZE1peCA9IGZyb20udGltZWxpbmVIb2xkTWl4O1xuXG5cdFx0XHRsZXQgc2hvcnRlc3RSb3RhdGlvbiA9IGZyb20uc2hvcnRlc3RSb3RhdGlvbjtcblx0XHRcdGxldCBmaXJzdEZyYW1lID0gIXNob3J0ZXN0Um90YXRpb24gJiYgZnJvbS50aW1lbGluZXNSb3RhdGlvbi5sZW5ndGggIT0gdGltZWxpbmVDb3VudCA8PCAxO1xuXHRcdFx0aWYgKGZpcnN0RnJhbWUpIGZyb20udGltZWxpbmVzUm90YXRpb24ubGVuZ3RoID0gdGltZWxpbmVDb3VudCA8PCAxO1xuXG5cdFx0XHRmcm9tLnRvdGFsQWxwaGEgPSAwO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aW1lbGluZUNvdW50OyBpKyspIHtcblx0XHRcdFx0bGV0IHRpbWVsaW5lID0gdGltZWxpbmVzW2ldO1xuXHRcdFx0XHRsZXQgZGlyZWN0aW9uID0gTWl4RGlyZWN0aW9uLm1peE91dDtcblx0XHRcdFx0bGV0IHRpbWVsaW5lQmxlbmQ6IE1peEJsZW5kO1xuXHRcdFx0XHRsZXQgYWxwaGEgPSAwO1xuXHRcdFx0XHRzd2l0Y2ggKHRpbWVsaW5lTW9kZVtpXSkge1xuXHRcdFx0XHRcdGNhc2UgU1VCU0VRVUVOVDpcblx0XHRcdFx0XHRcdGlmICghZHJhd09yZGVyICYmIHRpbWVsaW5lIGluc3RhbmNlb2YgRHJhd09yZGVyVGltZWxpbmUpIGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0dGltZWxpbmVCbGVuZCA9IGJsZW5kO1xuXHRcdFx0XHRcdFx0YWxwaGEgPSBhbHBoYU1peDtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgRklSU1Q6XG5cdFx0XHRcdFx0XHR0aW1lbGluZUJsZW5kID0gTWl4QmxlbmQuc2V0dXA7XG5cdFx0XHRcdFx0XHRhbHBoYSA9IGFscGhhTWl4O1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBIT0xEX1NVQlNFUVVFTlQ6XG5cdFx0XHRcdFx0XHR0aW1lbGluZUJsZW5kID0gYmxlbmQ7XG5cdFx0XHRcdFx0XHRhbHBoYSA9IGFscGhhSG9sZDtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgSE9MRF9GSVJTVDpcblx0XHRcdFx0XHRcdHRpbWVsaW5lQmxlbmQgPSBNaXhCbGVuZC5zZXR1cDtcblx0XHRcdFx0XHRcdGFscGhhID0gYWxwaGFIb2xkO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdHRpbWVsaW5lQmxlbmQgPSBNaXhCbGVuZC5zZXR1cDtcblx0XHRcdFx0XHRcdGxldCBob2xkTWl4ID0gdGltZWxpbmVIb2xkTWl4W2ldO1xuXHRcdFx0XHRcdFx0YWxwaGEgPSBhbHBoYUhvbGQgKiBNYXRoLm1heCgwLCAxIC0gaG9sZE1peC5taXhUaW1lIC8gaG9sZE1peC5taXhEdXJhdGlvbik7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHRmcm9tLnRvdGFsQWxwaGEgKz0gYWxwaGE7XG5cblx0XHRcdFx0aWYgKCFzaG9ydGVzdFJvdGF0aW9uICYmIHRpbWVsaW5lIGluc3RhbmNlb2YgUm90YXRlVGltZWxpbmUpXG5cdFx0XHRcdFx0dGhpcy5hcHBseVJvdGF0ZVRpbWVsaW5lKHRpbWVsaW5lLCBza2VsZXRvbiwgYXBwbHlUaW1lLCBhbHBoYSwgdGltZWxpbmVCbGVuZCwgZnJvbS50aW1lbGluZXNSb3RhdGlvbiwgaSA8PCAxLCBmaXJzdEZyYW1lKTtcblx0XHRcdFx0ZWxzZSBpZiAodGltZWxpbmUgaW5zdGFuY2VvZiBBdHRhY2htZW50VGltZWxpbmUpXG5cdFx0XHRcdFx0dGhpcy5hcHBseUF0dGFjaG1lbnRUaW1lbGluZSh0aW1lbGluZSwgc2tlbGV0b24sIGFwcGx5VGltZSwgdGltZWxpbmVCbGVuZCwgYXR0YWNobWVudHMgJiYgYWxwaGEgPj0gZnJvbS5hbHBoYUF0dGFjaG1lbnRUaHJlc2hvbGQpO1xuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHQvLyBUaGlzIGZpeGVzIHRoZSBXZWJLaXQgNjAyIHNwZWNpZmljIGlzc3VlIGRlc2NyaWJlZCBhdCBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vZm9ydW0vaU9TLTEwLWRpc2FwcGVhcmluZy1ncmFwaGljcy0xMDEwOVxuXHRcdFx0XHRcdFV0aWxzLndlYmtpdDYwMkJ1Z2ZpeEhlbHBlcihhbHBoYSwgYmxlbmQpO1xuXHRcdFx0XHRcdGlmIChkcmF3T3JkZXIgJiYgdGltZWxpbmUgaW5zdGFuY2VvZiBEcmF3T3JkZXJUaW1lbGluZSAmJiB0aW1lbGluZUJsZW5kID09IE1peEJsZW5kLnNldHVwKVxuXHRcdFx0XHRcdFx0ZGlyZWN0aW9uID0gTWl4RGlyZWN0aW9uLm1peEluO1xuXHRcdFx0XHRcdHRpbWVsaW5lLmFwcGx5KHNrZWxldG9uLCBhbmltYXRpb25MYXN0LCBhcHBseVRpbWUsIGV2ZW50cywgYWxwaGEsIHRpbWVsaW5lQmxlbmQsIGRpcmVjdGlvbik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodG8ubWl4RHVyYXRpb24gPiAwKSB0aGlzLnF1ZXVlRXZlbnRzKGZyb20sIGFuaW1hdGlvblRpbWUpO1xuXHRcdHRoaXMuZXZlbnRzLmxlbmd0aCA9IDA7XG5cdFx0ZnJvbS5uZXh0QW5pbWF0aW9uTGFzdCA9IGFuaW1hdGlvblRpbWU7XG5cdFx0ZnJvbS5uZXh0VHJhY2tMYXN0ID0gZnJvbS50cmFja1RpbWU7XG5cblx0XHRyZXR1cm4gbWl4O1xuXHR9XG5cblx0YXBwbHlBdHRhY2htZW50VGltZWxpbmUgKHRpbWVsaW5lOiBBdHRhY2htZW50VGltZWxpbmUsIHNrZWxldG9uOiBTa2VsZXRvbiwgdGltZTogbnVtYmVyLCBibGVuZDogTWl4QmxlbmQsIGF0dGFjaG1lbnRzOiBib29sZWFuKSB7XG5cdFx0dmFyIHNsb3QgPSBza2VsZXRvbi5zbG90c1t0aW1lbGluZS5zbG90SW5kZXhdO1xuXHRcdGlmICghc2xvdC5ib25lLmFjdGl2ZSkgcmV0dXJuO1xuXG5cdFx0aWYgKHRpbWUgPCB0aW1lbGluZS5mcmFtZXNbMF0pIHsgLy8gVGltZSBpcyBiZWZvcmUgZmlyc3QgZnJhbWUuXG5cdFx0XHRpZiAoYmxlbmQgPT0gTWl4QmxlbmQuc2V0dXAgfHwgYmxlbmQgPT0gTWl4QmxlbmQuZmlyc3QpXG5cdFx0XHRcdHRoaXMuc2V0QXR0YWNobWVudChza2VsZXRvbiwgc2xvdCwgc2xvdC5kYXRhLmF0dGFjaG1lbnROYW1lLCBhdHRhY2htZW50cyk7XG5cdFx0fSBlbHNlXG5cdFx0XHR0aGlzLnNldEF0dGFjaG1lbnQoc2tlbGV0b24sIHNsb3QsIHRpbWVsaW5lLmF0dGFjaG1lbnROYW1lc1tUaW1lbGluZS5zZWFyY2gxKHRpbWVsaW5lLmZyYW1lcywgdGltZSldLCBhdHRhY2htZW50cyk7XG5cblx0XHQvLyBJZiBhbiBhdHRhY2htZW50IHdhc24ndCBzZXQgKGllIGJlZm9yZSB0aGUgZmlyc3QgZnJhbWUgb3IgYXR0YWNobWVudHMgaXMgZmFsc2UpLCBzZXQgdGhlIHNldHVwIGF0dGFjaG1lbnQgbGF0ZXIuXG5cdFx0aWYgKHNsb3QuYXR0YWNobWVudFN0YXRlIDw9IHRoaXMudW5rZXllZFN0YXRlKSBzbG90LmF0dGFjaG1lbnRTdGF0ZSA9IHRoaXMudW5rZXllZFN0YXRlICsgU0VUVVA7XG5cdH1cblxuXHRzZXRBdHRhY2htZW50IChza2VsZXRvbjogU2tlbGV0b24sIHNsb3Q6IFNsb3QsIGF0dGFjaG1lbnROYW1lOiBzdHJpbmcgfCBudWxsLCBhdHRhY2htZW50czogYm9vbGVhbikge1xuXHRcdHNsb3Quc2V0QXR0YWNobWVudCghYXR0YWNobWVudE5hbWUgPyBudWxsIDogc2tlbGV0b24uZ2V0QXR0YWNobWVudChzbG90LmRhdGEuaW5kZXgsIGF0dGFjaG1lbnROYW1lKSk7XG5cdFx0aWYgKGF0dGFjaG1lbnRzKSBzbG90LmF0dGFjaG1lbnRTdGF0ZSA9IHRoaXMudW5rZXllZFN0YXRlICsgQ1VSUkVOVDtcblx0fVxuXG5cdGFwcGx5Um90YXRlVGltZWxpbmUgKHRpbWVsaW5lOiBSb3RhdGVUaW1lbGluZSwgc2tlbGV0b246IFNrZWxldG9uLCB0aW1lOiBudW1iZXIsIGFscGhhOiBudW1iZXIsIGJsZW5kOiBNaXhCbGVuZCxcblx0XHR0aW1lbGluZXNSb3RhdGlvbjogQXJyYXk8bnVtYmVyPiwgaTogbnVtYmVyLCBmaXJzdEZyYW1lOiBib29sZWFuKSB7XG5cblx0XHRpZiAoZmlyc3RGcmFtZSkgdGltZWxpbmVzUm90YXRpb25baV0gPSAwO1xuXG5cdFx0aWYgKGFscGhhID09IDEpIHtcblx0XHRcdHRpbWVsaW5lLmFwcGx5KHNrZWxldG9uLCAwLCB0aW1lLCBudWxsLCAxLCBibGVuZCwgTWl4RGlyZWN0aW9uLm1peEluKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRsZXQgYm9uZSA9IHNrZWxldG9uLmJvbmVzW3RpbWVsaW5lLmJvbmVJbmRleF07XG5cdFx0aWYgKCFib25lLmFjdGl2ZSkgcmV0dXJuO1xuXHRcdGxldCBmcmFtZXMgPSB0aW1lbGluZS5mcmFtZXM7XG5cdFx0bGV0IHIxID0gMCwgcjIgPSAwO1xuXHRcdGlmICh0aW1lIDwgZnJhbWVzWzBdKSB7XG5cdFx0XHRzd2l0Y2ggKGJsZW5kKSB7XG5cdFx0XHRcdGNhc2UgTWl4QmxlbmQuc2V0dXA6XG5cdFx0XHRcdFx0Ym9uZS5yb3RhdGlvbiA9IGJvbmUuZGF0YS5yb3RhdGlvbjtcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdGNhc2UgTWl4QmxlbmQuZmlyc3Q6XG5cdFx0XHRcdFx0cjEgPSBib25lLnJvdGF0aW9uO1xuXHRcdFx0XHRcdHIyID0gYm9uZS5kYXRhLnJvdGF0aW9uO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyMSA9IGJsZW5kID09IE1peEJsZW5kLnNldHVwID8gYm9uZS5kYXRhLnJvdGF0aW9uIDogYm9uZS5yb3RhdGlvbjtcblx0XHRcdHIyID0gYm9uZS5kYXRhLnJvdGF0aW9uICsgdGltZWxpbmUuZ2V0Q3VydmVWYWx1ZSh0aW1lKTtcblx0XHR9XG5cblx0XHQvLyBNaXggYmV0d2VlbiByb3RhdGlvbnMgdXNpbmcgdGhlIGRpcmVjdGlvbiBvZiB0aGUgc2hvcnRlc3Qgcm91dGUgb24gdGhlIGZpcnN0IGZyYW1lIHdoaWxlIGRldGVjdGluZyBjcm9zc2VzLlxuXHRcdGxldCB0b3RhbCA9IDAsIGRpZmYgPSByMiAtIHIxO1xuXHRcdGRpZmYgLT0gTWF0aC5jZWlsKGRpZmYgLyAzNjAgLSAwLjUpICogMzYwO1xuXHRcdGlmIChkaWZmID09IDApIHtcblx0XHRcdHRvdGFsID0gdGltZWxpbmVzUm90YXRpb25baV07XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBsYXN0VG90YWwgPSAwLCBsYXN0RGlmZiA9IDA7XG5cdFx0XHRpZiAoZmlyc3RGcmFtZSkge1xuXHRcdFx0XHRsYXN0VG90YWwgPSAwO1xuXHRcdFx0XHRsYXN0RGlmZiA9IGRpZmY7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsYXN0VG90YWwgPSB0aW1lbGluZXNSb3RhdGlvbltpXTtcblx0XHRcdFx0bGFzdERpZmYgPSB0aW1lbGluZXNSb3RhdGlvbltpICsgMV07XG5cdFx0XHR9XG5cdFx0XHRsZXQgbG9vcHMgPSBsYXN0VG90YWwgLSBsYXN0VG90YWwgJSAzNjA7XG5cdFx0XHR0b3RhbCA9IGRpZmYgKyBsb29wcztcblx0XHRcdGxldCBjdXJyZW50ID0gZGlmZiA+PSAwLCBkaXIgPSBsYXN0VG90YWwgPj0gMDtcblx0XHRcdGlmIChNYXRoLmFicyhsYXN0RGlmZikgPD0gOTAgJiYgTWF0aFV0aWxzLnNpZ251bShsYXN0RGlmZikgIT0gTWF0aFV0aWxzLnNpZ251bShkaWZmKSkge1xuXHRcdFx0XHRpZiAoTWF0aC5hYnMobGFzdFRvdGFsIC0gbG9vcHMpID4gMTgwKSB7XG5cdFx0XHRcdFx0dG90YWwgKz0gMzYwICogTWF0aFV0aWxzLnNpZ251bShsYXN0VG90YWwpO1xuXHRcdFx0XHRcdGRpciA9IGN1cnJlbnQ7XG5cdFx0XHRcdH0gZWxzZSBpZiAobG9vcHMgIT0gMClcblx0XHRcdFx0XHR0b3RhbCAtPSAzNjAgKiBNYXRoVXRpbHMuc2lnbnVtKGxhc3RUb3RhbCk7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRkaXIgPSBjdXJyZW50O1xuXHRcdFx0fVxuXHRcdFx0aWYgKGRpciAhPSBjdXJyZW50KSB0b3RhbCArPSAzNjAgKiBNYXRoVXRpbHMuc2lnbnVtKGxhc3RUb3RhbCk7XG5cdFx0XHR0aW1lbGluZXNSb3RhdGlvbltpXSA9IHRvdGFsO1xuXHRcdH1cblx0XHR0aW1lbGluZXNSb3RhdGlvbltpICsgMV0gPSBkaWZmO1xuXHRcdGJvbmUucm90YXRpb24gPSByMSArIHRvdGFsICogYWxwaGE7XG5cdH1cblxuXHRxdWV1ZUV2ZW50cyAoZW50cnk6IFRyYWNrRW50cnksIGFuaW1hdGlvblRpbWU6IG51bWJlcikge1xuXHRcdGxldCBhbmltYXRpb25TdGFydCA9IGVudHJ5LmFuaW1hdGlvblN0YXJ0LCBhbmltYXRpb25FbmQgPSBlbnRyeS5hbmltYXRpb25FbmQ7XG5cdFx0bGV0IGR1cmF0aW9uID0gYW5pbWF0aW9uRW5kIC0gYW5pbWF0aW9uU3RhcnQ7XG5cdFx0bGV0IHRyYWNrTGFzdFdyYXBwZWQgPSBlbnRyeS50cmFja0xhc3QgJSBkdXJhdGlvbjtcblxuXHRcdC8vIFF1ZXVlIGV2ZW50cyBiZWZvcmUgY29tcGxldGUuXG5cdFx0bGV0IGV2ZW50cyA9IHRoaXMuZXZlbnRzO1xuXHRcdGxldCBpID0gMCwgbiA9IGV2ZW50cy5sZW5ndGg7XG5cdFx0Zm9yICg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGxldCBldmVudCA9IGV2ZW50c1tpXTtcblx0XHRcdGlmIChldmVudC50aW1lIDwgdHJhY2tMYXN0V3JhcHBlZCkgYnJlYWs7XG5cdFx0XHRpZiAoZXZlbnQudGltZSA+IGFuaW1hdGlvbkVuZCkgY29udGludWU7IC8vIERpc2NhcmQgZXZlbnRzIG91dHNpZGUgYW5pbWF0aW9uIHN0YXJ0L2VuZC5cblx0XHRcdHRoaXMucXVldWUuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHR9XG5cblx0XHQvLyBRdWV1ZSBjb21wbGV0ZSBpZiBjb21wbGV0ZWQgYSBsb29wIGl0ZXJhdGlvbiBvciB0aGUgYW5pbWF0aW9uLlxuXHRcdGxldCBjb21wbGV0ZSA9IGZhbHNlO1xuXHRcdGlmIChlbnRyeS5sb29wKSB7XG5cdFx0XHRpZiAoZHVyYXRpb24gPT0gMClcblx0XHRcdFx0Y29tcGxldGUgPSB0cnVlO1xuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdGNvbnN0IGN5Y2xlcyA9IE1hdGguZmxvb3IoZW50cnkudHJhY2tUaW1lIC8gZHVyYXRpb24pO1xuXHRcdFx0XHRjb21wbGV0ZSA9IGN5Y2xlcyA+IDAgJiYgY3ljbGVzID4gTWF0aC5mbG9vcihlbnRyeS50cmFja0xhc3QgLyBkdXJhdGlvbik7XG5cdFx0XHR9XG5cdFx0fSBlbHNlXG5cdFx0XHRjb21wbGV0ZSA9IGFuaW1hdGlvblRpbWUgPj0gYW5pbWF0aW9uRW5kICYmIGVudHJ5LmFuaW1hdGlvbkxhc3QgPCBhbmltYXRpb25FbmQ7XG5cdFx0aWYgKGNvbXBsZXRlKSB0aGlzLnF1ZXVlLmNvbXBsZXRlKGVudHJ5KTtcblxuXHRcdC8vIFF1ZXVlIGV2ZW50cyBhZnRlciBjb21wbGV0ZS5cblx0XHRmb3IgKDsgaSA8IG47IGkrKykge1xuXHRcdFx0bGV0IGV2ZW50ID0gZXZlbnRzW2ldO1xuXHRcdFx0aWYgKGV2ZW50LnRpbWUgPCBhbmltYXRpb25TdGFydCkgY29udGludWU7IC8vIERpc2NhcmQgZXZlbnRzIG91dHNpZGUgYW5pbWF0aW9uIHN0YXJ0L2VuZC5cblx0XHRcdHRoaXMucXVldWUuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHQvKiogUmVtb3ZlcyBhbGwgYW5pbWF0aW9ucyBmcm9tIGFsbCB0cmFja3MsIGxlYXZpbmcgc2tlbGV0b25zIGluIHRoZWlyIGN1cnJlbnQgcG9zZS5cblx0ICpcblx0ICogSXQgbWF5IGJlIGRlc2lyZWQgdG8gdXNlIHtAbGluayBBbmltYXRpb25TdGF0ZSNzZXRFbXB0eUFuaW1hdGlvbigpfSB0byBtaXggdGhlIHNrZWxldG9ucyBiYWNrIHRvIHRoZSBzZXR1cCBwb3NlLFxuXHQgKiByYXRoZXIgdGhhbiBsZWF2aW5nIHRoZW0gaW4gdGhlaXIgY3VycmVudCBwb3NlLiAqL1xuXHRjbGVhclRyYWNrcyAoKSB7XG5cdFx0bGV0IG9sZERyYWluRGlzYWJsZWQgPSB0aGlzLnF1ZXVlLmRyYWluRGlzYWJsZWQ7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbkRpc2FibGVkID0gdHJ1ZTtcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRoaXMudHJhY2tzLmxlbmd0aDsgaSA8IG47IGkrKylcblx0XHRcdHRoaXMuY2xlYXJUcmFjayhpKTtcblx0XHR0aGlzLnRyYWNrcy5sZW5ndGggPSAwO1xuXHRcdHRoaXMucXVldWUuZHJhaW5EaXNhYmxlZCA9IG9sZERyYWluRGlzYWJsZWQ7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbigpO1xuXHR9XG5cblx0LyoqIFJlbW92ZXMgYWxsIGFuaW1hdGlvbnMgZnJvbSB0aGUgdHJhY2ssIGxlYXZpbmcgc2tlbGV0b25zIGluIHRoZWlyIGN1cnJlbnQgcG9zZS5cblx0ICpcblx0ICogSXQgbWF5IGJlIGRlc2lyZWQgdG8gdXNlIHtAbGluayBBbmltYXRpb25TdGF0ZSNzZXRFbXB0eUFuaW1hdGlvbigpfSB0byBtaXggdGhlIHNrZWxldG9ucyBiYWNrIHRvIHRoZSBzZXR1cCBwb3NlLFxuXHQgKiByYXRoZXIgdGhhbiBsZWF2aW5nIHRoZW0gaW4gdGhlaXIgY3VycmVudCBwb3NlLiAqL1xuXHRjbGVhclRyYWNrICh0cmFja0luZGV4OiBudW1iZXIpIHtcblx0XHRpZiAodHJhY2tJbmRleCA+PSB0aGlzLnRyYWNrcy5sZW5ndGgpIHJldHVybjtcblx0XHRsZXQgY3VycmVudCA9IHRoaXMudHJhY2tzW3RyYWNrSW5kZXhdO1xuXHRcdGlmICghY3VycmVudCkgcmV0dXJuO1xuXG5cdFx0dGhpcy5xdWV1ZS5lbmQoY3VycmVudCk7XG5cblx0XHR0aGlzLmNsZWFyTmV4dChjdXJyZW50KTtcblxuXHRcdGxldCBlbnRyeSA9IGN1cnJlbnQ7XG5cdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdGxldCBmcm9tID0gZW50cnkubWl4aW5nRnJvbTtcblx0XHRcdGlmICghZnJvbSkgYnJlYWs7XG5cdFx0XHR0aGlzLnF1ZXVlLmVuZChmcm9tKTtcblx0XHRcdGVudHJ5Lm1peGluZ0Zyb20gPSBudWxsO1xuXHRcdFx0ZW50cnkubWl4aW5nVG8gPSBudWxsO1xuXHRcdFx0ZW50cnkgPSBmcm9tO1xuXHRcdH1cblxuXHRcdHRoaXMudHJhY2tzW2N1cnJlbnQudHJhY2tJbmRleF0gPSBudWxsO1xuXG5cdFx0dGhpcy5xdWV1ZS5kcmFpbigpO1xuXHR9XG5cblx0c2V0Q3VycmVudCAoaW5kZXg6IG51bWJlciwgY3VycmVudDogVHJhY2tFbnRyeSwgaW50ZXJydXB0OiBib29sZWFuKSB7XG5cdFx0bGV0IGZyb20gPSB0aGlzLmV4cGFuZFRvSW5kZXgoaW5kZXgpO1xuXHRcdHRoaXMudHJhY2tzW2luZGV4XSA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudC5wcmV2aW91cyA9IG51bGw7XG5cblx0XHRpZiAoZnJvbSkge1xuXHRcdFx0aWYgKGludGVycnVwdCkgdGhpcy5xdWV1ZS5pbnRlcnJ1cHQoZnJvbSk7XG5cdFx0XHRjdXJyZW50Lm1peGluZ0Zyb20gPSBmcm9tO1xuXHRcdFx0ZnJvbS5taXhpbmdUbyA9IGN1cnJlbnQ7XG5cdFx0XHRjdXJyZW50Lm1peFRpbWUgPSAwO1xuXG5cdFx0XHQvLyBTdG9yZSB0aGUgaW50ZXJydXB0ZWQgbWl4IHBlcmNlbnRhZ2UuXG5cdFx0XHRpZiAoZnJvbS5taXhpbmdGcm9tICYmIGZyb20ubWl4RHVyYXRpb24gPiAwKVxuXHRcdFx0XHRjdXJyZW50LmludGVycnVwdEFscGhhICo9IE1hdGgubWluKDEsIGZyb20ubWl4VGltZSAvIGZyb20ubWl4RHVyYXRpb24pO1xuXG5cdFx0XHRmcm9tLnRpbWVsaW5lc1JvdGF0aW9uLmxlbmd0aCA9IDA7IC8vIFJlc2V0IHJvdGF0aW9uIGZvciBtaXhpbmcgb3V0LCBpbiBjYXNlIGVudHJ5IHdhcyBtaXhlZCBpbi5cblx0XHR9XG5cblx0XHR0aGlzLnF1ZXVlLnN0YXJ0KGN1cnJlbnQpO1xuXHR9XG5cblx0LyoqIFNldHMgYW4gYW5pbWF0aW9uIGJ5IG5hbWUuXG5cdCAgKlxuXHQgICogU2VlIHtAbGluayAjc2V0QW5pbWF0aW9uV2l0aCgpfS4gKi9cblx0c2V0QW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbk5hbWU6IHN0cmluZywgbG9vcDogYm9vbGVhbiA9IGZhbHNlKSB7XG5cdFx0bGV0IGFuaW1hdGlvbiA9IHRoaXMuZGF0YS5za2VsZXRvbkRhdGEuZmluZEFuaW1hdGlvbihhbmltYXRpb25OYW1lKTtcblx0XHRpZiAoIWFuaW1hdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiQW5pbWF0aW9uIG5vdCBmb3VuZDogXCIgKyBhbmltYXRpb25OYW1lKTtcblx0XHRyZXR1cm4gdGhpcy5zZXRBbmltYXRpb25XaXRoKHRyYWNrSW5kZXgsIGFuaW1hdGlvbiwgbG9vcCk7XG5cdH1cblxuXHQvKiogU2V0cyB0aGUgY3VycmVudCBhbmltYXRpb24gZm9yIGEgdHJhY2ssIGRpc2NhcmRpbmcgYW55IHF1ZXVlZCBhbmltYXRpb25zLiBJZiB0aGUgZm9ybWVybHkgY3VycmVudCB0cmFjayBlbnRyeSB3YXMgbmV2ZXJcblx0ICogYXBwbGllZCB0byBhIHNrZWxldG9uLCBpdCBpcyByZXBsYWNlZCAobm90IG1peGVkIGZyb20pLlxuXHQgKiBAcGFyYW0gbG9vcCBJZiB0cnVlLCB0aGUgYW5pbWF0aW9uIHdpbGwgcmVwZWF0LiBJZiBmYWxzZSBpdCB3aWxsIG5vdCwgaW5zdGVhZCBpdHMgbGFzdCBmcmFtZSBpcyBhcHBsaWVkIGlmIHBsYXllZCBiZXlvbmQgaXRzXG5cdCAqICAgICAgICAgICBkdXJhdGlvbi4gSW4gZWl0aGVyIGNhc2Uge0BsaW5rIFRyYWNrRW50cnkjdHJhY2tFbmR9IGRldGVybWluZXMgd2hlbiB0aGUgdHJhY2sgaXMgY2xlYXJlZC5cblx0ICogQHJldHVybnMgQSB0cmFjayBlbnRyeSB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb24gb2YgYW5pbWF0aW9uIHBsYXliYWNrLiBSZWZlcmVuY2VzIHRvIHRoZSB0cmFjayBlbnRyeSBtdXN0IG5vdCBiZSBrZXB0XG5cdCAqICAgICAgICAgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyI2Rpc3Bvc2UoKX0gZXZlbnQgb2NjdXJzLiAqL1xuXHRzZXRBbmltYXRpb25XaXRoICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbjogQW5pbWF0aW9uLCBsb29wOiBib29sZWFuID0gZmFsc2UpIHtcblx0XHRpZiAoIWFuaW1hdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiYW5pbWF0aW9uIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHRsZXQgaW50ZXJydXB0ID0gdHJ1ZTtcblx0XHRsZXQgY3VycmVudCA9IHRoaXMuZXhwYW5kVG9JbmRleCh0cmFja0luZGV4KTtcblx0XHRpZiAoY3VycmVudCkge1xuXHRcdFx0aWYgKGN1cnJlbnQubmV4dFRyYWNrTGFzdCA9PSAtMSkge1xuXHRcdFx0XHQvLyBEb24ndCBtaXggZnJvbSBhbiBlbnRyeSB0aGF0IHdhcyBuZXZlciBhcHBsaWVkLlxuXHRcdFx0XHR0aGlzLnRyYWNrc1t0cmFja0luZGV4XSA9IGN1cnJlbnQubWl4aW5nRnJvbTtcblx0XHRcdFx0dGhpcy5xdWV1ZS5pbnRlcnJ1cHQoY3VycmVudCk7XG5cdFx0XHRcdHRoaXMucXVldWUuZW5kKGN1cnJlbnQpO1xuXHRcdFx0XHR0aGlzLmNsZWFyTmV4dChjdXJyZW50KTtcblx0XHRcdFx0Y3VycmVudCA9IGN1cnJlbnQubWl4aW5nRnJvbTtcblx0XHRcdFx0aW50ZXJydXB0ID0gZmFsc2U7XG5cdFx0XHR9IGVsc2Vcblx0XHRcdFx0dGhpcy5jbGVhck5leHQoY3VycmVudCk7XG5cdFx0fVxuXHRcdGxldCBlbnRyeSA9IHRoaXMudHJhY2tFbnRyeSh0cmFja0luZGV4LCBhbmltYXRpb24sIGxvb3AsIGN1cnJlbnQpO1xuXHRcdHRoaXMuc2V0Q3VycmVudCh0cmFja0luZGV4LCBlbnRyeSwgaW50ZXJydXB0KTtcblx0XHR0aGlzLnF1ZXVlLmRyYWluKCk7XG5cdFx0cmV0dXJuIGVudHJ5O1xuXHR9XG5cblx0LyoqIFF1ZXVlcyBhbiBhbmltYXRpb24gYnkgbmFtZS5cblx0ICpcblx0ICogU2VlIHtAbGluayAjYWRkQW5pbWF0aW9uV2l0aCgpfS4gKi9cblx0YWRkQW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbk5hbWU6IHN0cmluZywgbG9vcDogYm9vbGVhbiA9IGZhbHNlLCBkZWxheTogbnVtYmVyID0gMCkge1xuXHRcdGxldCBhbmltYXRpb24gPSB0aGlzLmRhdGEuc2tlbGV0b25EYXRhLmZpbmRBbmltYXRpb24oYW5pbWF0aW9uTmFtZSk7XG5cdFx0aWYgKCFhbmltYXRpb24pIHRocm93IG5ldyBFcnJvcihcIkFuaW1hdGlvbiBub3QgZm91bmQ6IFwiICsgYW5pbWF0aW9uTmFtZSk7XG5cdFx0cmV0dXJuIHRoaXMuYWRkQW5pbWF0aW9uV2l0aCh0cmFja0luZGV4LCBhbmltYXRpb24sIGxvb3AsIGRlbGF5KTtcblx0fVxuXG5cdC8qKiBBZGRzIGFuIGFuaW1hdGlvbiB0byBiZSBwbGF5ZWQgYWZ0ZXIgdGhlIGN1cnJlbnQgb3IgbGFzdCBxdWV1ZWQgYW5pbWF0aW9uIGZvciBhIHRyYWNrLiBJZiB0aGUgdHJhY2sgaXMgZW1wdHksIGl0IGlzXG5cdCAqIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB7QGxpbmsgI3NldEFuaW1hdGlvbldpdGgoKX0uXG5cdCAqIEBwYXJhbSBkZWxheSBJZiA+IDAsIHNldHMge0BsaW5rIFRyYWNrRW50cnkjZGVsYXl9LiBJZiA8PSAwLCB0aGUgZGVsYXkgc2V0IGlzIHRoZSBkdXJhdGlvbiBvZiB0aGUgcHJldmlvdXMgdHJhY2sgZW50cnlcblx0ICogICAgICAgICAgIG1pbnVzIGFueSBtaXggZHVyYXRpb24gKGZyb20gdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZURhdGF9KSBwbHVzIHRoZSBzcGVjaWZpZWQgYGRlbGF5YCAoaWUgdGhlIG1peFxuXHQgKiAgICAgICAgICAgZW5kcyBhdCAoYGRlbGF5YCA9IDApIG9yIGJlZm9yZSAoYGRlbGF5YCA8IDApIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeSBkdXJhdGlvbikuIElmIHRoZVxuXHQgKiAgICAgICAgICAgcHJldmlvdXMgZW50cnkgaXMgbG9vcGluZywgaXRzIG5leHQgbG9vcCBjb21wbGV0aW9uIGlzIHVzZWQgaW5zdGVhZCBvZiBpdHMgZHVyYXRpb24uXG5cdCAqIEByZXR1cm5zIEEgdHJhY2sgZW50cnkgdG8gYWxsb3cgZnVydGhlciBjdXN0b21pemF0aW9uIG9mIGFuaW1hdGlvbiBwbGF5YmFjay4gUmVmZXJlbmNlcyB0byB0aGUgdHJhY2sgZW50cnkgbXVzdCBub3QgYmUga2VwdFxuXHQgKiAgICAgICAgIGFmdGVyIHRoZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lciNkaXNwb3NlKCl9IGV2ZW50IG9jY3Vycy4gKi9cblx0YWRkQW5pbWF0aW9uV2l0aCAodHJhY2tJbmRleDogbnVtYmVyLCBhbmltYXRpb246IEFuaW1hdGlvbiwgbG9vcDogYm9vbGVhbiA9IGZhbHNlLCBkZWxheTogbnVtYmVyID0gMCkge1xuXHRcdGlmICghYW5pbWF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJhbmltYXRpb24gY2Fubm90IGJlIG51bGwuXCIpO1xuXG5cdFx0bGV0IGxhc3QgPSB0aGlzLmV4cGFuZFRvSW5kZXgodHJhY2tJbmRleCk7XG5cdFx0aWYgKGxhc3QpIHtcblx0XHRcdHdoaWxlIChsYXN0Lm5leHQpXG5cdFx0XHRcdGxhc3QgPSBsYXN0Lm5leHQ7XG5cdFx0fVxuXG5cdFx0bGV0IGVudHJ5ID0gdGhpcy50cmFja0VudHJ5KHRyYWNrSW5kZXgsIGFuaW1hdGlvbiwgbG9vcCwgbGFzdCk7XG5cblx0XHRpZiAoIWxhc3QpIHtcblx0XHRcdHRoaXMuc2V0Q3VycmVudCh0cmFja0luZGV4LCBlbnRyeSwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnF1ZXVlLmRyYWluKCk7XG5cdFx0XHRpZiAoZGVsYXkgPCAwKSBkZWxheSA9IDA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxhc3QubmV4dCA9IGVudHJ5O1xuXHRcdFx0ZW50cnkucHJldmlvdXMgPSBsYXN0O1xuXHRcdFx0aWYgKGRlbGF5IDw9IDApIGRlbGF5ID0gTWF0aC5tYXgoZGVsYXkgKyBsYXN0LmdldFRyYWNrQ29tcGxldGUoKSAtIGVudHJ5Lm1peER1cmF0aW9uLCAwKTtcblx0XHR9XG5cblx0XHRlbnRyeS5kZWxheSA9IGRlbGF5O1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxuXG5cdC8qKiBTZXRzIGFuIGVtcHR5IGFuaW1hdGlvbiBmb3IgYSB0cmFjaywgZGlzY2FyZGluZyBhbnkgcXVldWVkIGFuaW1hdGlvbnMsIGFuZCBzZXRzIHRoZSB0cmFjayBlbnRyeSdzXG5cdCAqIHtAbGluayBUcmFja0VudHJ5I21peGR1cmF0aW9ufS4gQW4gZW1wdHkgYW5pbWF0aW9uIGhhcyBubyB0aW1lbGluZXMgYW5kIHNlcnZlcyBhcyBhIHBsYWNlaG9sZGVyIGZvciBtaXhpbmcgaW4gb3Igb3V0LlxuXHQgKlxuXHQgKiBNaXhpbmcgb3V0IGlzIGRvbmUgYnkgc2V0dGluZyBhbiBlbXB0eSBhbmltYXRpb24gd2l0aCBhIG1peCBkdXJhdGlvbiB1c2luZyBlaXRoZXIge0BsaW5rICNzZXRFbXB0eUFuaW1hdGlvbigpfSxcblx0ICoge0BsaW5rICNzZXRFbXB0eUFuaW1hdGlvbnMoKX0sIG9yIHtAbGluayAjYWRkRW1wdHlBbmltYXRpb24oKX0uIE1peGluZyB0byBhbiBlbXB0eSBhbmltYXRpb24gY2F1c2VzXG5cdCAqIHRoZSBwcmV2aW91cyBhbmltYXRpb24gdG8gYmUgYXBwbGllZCBsZXNzIGFuZCBsZXNzIG92ZXIgdGhlIG1peCBkdXJhdGlvbi4gUHJvcGVydGllcyBrZXllZCBpbiB0aGUgcHJldmlvdXMgYW5pbWF0aW9uXG5cdCAqIHRyYW5zaXRpb24gdG8gdGhlIHZhbHVlIGZyb20gbG93ZXIgdHJhY2tzIG9yIHRvIHRoZSBzZXR1cCBwb3NlIHZhbHVlIGlmIG5vIGxvd2VyIHRyYWNrcyBrZXkgdGhlIHByb3BlcnR5LiBBIG1peCBkdXJhdGlvbiBvZlxuXHQgKiAwIHN0aWxsIG1peGVzIG91dCBvdmVyIG9uZSBmcmFtZS5cblx0ICpcblx0ICogTWl4aW5nIGluIGlzIGRvbmUgYnkgZmlyc3Qgc2V0dGluZyBhbiBlbXB0eSBhbmltYXRpb24sIHRoZW4gYWRkaW5nIGFuIGFuaW1hdGlvbiB1c2luZ1xuXHQgKiB7QGxpbmsgI2FkZEFuaW1hdGlvbigpfSBhbmQgb24gdGhlIHJldHVybmVkIHRyYWNrIGVudHJ5LCBzZXQgdGhlXG5cdCAqIHtAbGluayBUcmFja0VudHJ5I3NldE1peER1cmF0aW9uKCl9LiBNaXhpbmcgZnJvbSBhbiBlbXB0eSBhbmltYXRpb24gY2F1c2VzIHRoZSBuZXcgYW5pbWF0aW9uIHRvIGJlIGFwcGxpZWQgbW9yZSBhbmRcblx0ICogbW9yZSBvdmVyIHRoZSBtaXggZHVyYXRpb24uIFByb3BlcnRpZXMga2V5ZWQgaW4gdGhlIG5ldyBhbmltYXRpb24gdHJhbnNpdGlvbiBmcm9tIHRoZSB2YWx1ZSBmcm9tIGxvd2VyIHRyYWNrcyBvciBmcm9tIHRoZVxuXHQgKiBzZXR1cCBwb3NlIHZhbHVlIGlmIG5vIGxvd2VyIHRyYWNrcyBrZXkgdGhlIHByb3BlcnR5IHRvIHRoZSB2YWx1ZSBrZXllZCBpbiB0aGUgbmV3IGFuaW1hdGlvbi4gKi9cblx0c2V0RW1wdHlBbmltYXRpb24gKHRyYWNrSW5kZXg6IG51bWJlciwgbWl4RHVyYXRpb246IG51bWJlciA9IDApIHtcblx0XHRsZXQgZW50cnkgPSB0aGlzLnNldEFuaW1hdGlvbldpdGgodHJhY2tJbmRleCwgQW5pbWF0aW9uU3RhdGUuZW1wdHlBbmltYXRpb24oKSwgZmFsc2UpO1xuXHRcdGVudHJ5Lm1peER1cmF0aW9uID0gbWl4RHVyYXRpb247XG5cdFx0ZW50cnkudHJhY2tFbmQgPSBtaXhEdXJhdGlvbjtcblx0XHRyZXR1cm4gZW50cnk7XG5cdH1cblxuXHQvKiogQWRkcyBhbiBlbXB0eSBhbmltYXRpb24gdG8gYmUgcGxheWVkIGFmdGVyIHRoZSBjdXJyZW50IG9yIGxhc3QgcXVldWVkIGFuaW1hdGlvbiBmb3IgYSB0cmFjaywgYW5kIHNldHMgdGhlIHRyYWNrIGVudHJ5J3Ncblx0ICoge0BsaW5rIFRyYWNrRW50cnkjbWl4RHVyYXRpb259LiBJZiB0aGUgdHJhY2sgaXMgZW1wdHksIGl0IGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZ1xuXHQgKiB7QGxpbmsgI3NldEVtcHR5QW5pbWF0aW9uKCl9LlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rICNzZXRFbXB0eUFuaW1hdGlvbigpfS5cblx0ICogQHBhcmFtIGRlbGF5IElmID4gMCwgc2V0cyB7QGxpbmsgVHJhY2tFbnRyeSNkZWxheX0uIElmIDw9IDAsIHRoZSBkZWxheSBzZXQgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeVxuXHQgKiAgICAgICAgICAgbWludXMgYW55IG1peCBkdXJhdGlvbiBwbHVzIHRoZSBzcGVjaWZpZWQgYGRlbGF5YCAoaWUgdGhlIG1peCBlbmRzIGF0IChgZGVsYXlgID0gMCkgb3Jcblx0ICogICAgICAgICAgIGJlZm9yZSAoYGRlbGF5YCA8IDApIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeSBkdXJhdGlvbikuIElmIHRoZSBwcmV2aW91cyBlbnRyeSBpcyBsb29waW5nLCBpdHMgbmV4dFxuXHQgKiAgICAgICAgICAgbG9vcCBjb21wbGV0aW9uIGlzIHVzZWQgaW5zdGVhZCBvZiBpdHMgZHVyYXRpb24uXG5cdCAqIEByZXR1cm4gQSB0cmFjayBlbnRyeSB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb24gb2YgYW5pbWF0aW9uIHBsYXliYWNrLiBSZWZlcmVuY2VzIHRvIHRoZSB0cmFjayBlbnRyeSBtdXN0IG5vdCBiZSBrZXB0XG5cdCAqICAgICAgICAgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyI2Rpc3Bvc2UoKX0gZXZlbnQgb2NjdXJzLiAqL1xuXHRhZGRFbXB0eUFuaW1hdGlvbiAodHJhY2tJbmRleDogbnVtYmVyLCBtaXhEdXJhdGlvbjogbnVtYmVyID0gMCwgZGVsYXk6IG51bWJlciA9IDApIHtcblx0XHRsZXQgZW50cnkgPSB0aGlzLmFkZEFuaW1hdGlvbldpdGgodHJhY2tJbmRleCwgQW5pbWF0aW9uU3RhdGUuZW1wdHlBbmltYXRpb24oKSwgZmFsc2UsIGRlbGF5KTtcblx0XHRpZiAoZGVsYXkgPD0gMCkgZW50cnkuZGVsYXkgPSBNYXRoLm1heChlbnRyeS5kZWxheSArIGVudHJ5Lm1peER1cmF0aW9uIC0gbWl4RHVyYXRpb24sIDApO1xuXHRcdGVudHJ5Lm1peER1cmF0aW9uID0gbWl4RHVyYXRpb247XG5cdFx0ZW50cnkudHJhY2tFbmQgPSBtaXhEdXJhdGlvbjtcblx0XHRyZXR1cm4gZW50cnk7XG5cdH1cblxuXHQvKiogU2V0cyBhbiBlbXB0eSBhbmltYXRpb24gZm9yIGV2ZXJ5IHRyYWNrLCBkaXNjYXJkaW5nIGFueSBxdWV1ZWQgYW5pbWF0aW9ucywgYW5kIG1peGVzIHRvIGl0IG92ZXIgdGhlIHNwZWNpZmllZCBtaXhcblx0ICAqIGR1cmF0aW9uLiAqL1xuXHRzZXRFbXB0eUFuaW1hdGlvbnMgKG1peER1cmF0aW9uOiBudW1iZXIgPSAwKSB7XG5cdFx0bGV0IG9sZERyYWluRGlzYWJsZWQgPSB0aGlzLnF1ZXVlLmRyYWluRGlzYWJsZWQ7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbkRpc2FibGVkID0gdHJ1ZTtcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRoaXMudHJhY2tzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuXHRcdFx0bGV0IGN1cnJlbnQgPSB0aGlzLnRyYWNrc1tpXTtcblx0XHRcdGlmIChjdXJyZW50KSB0aGlzLnNldEVtcHR5QW5pbWF0aW9uKGN1cnJlbnQudHJhY2tJbmRleCwgbWl4RHVyYXRpb24pO1xuXHRcdH1cblx0XHR0aGlzLnF1ZXVlLmRyYWluRGlzYWJsZWQgPSBvbGREcmFpbkRpc2FibGVkO1xuXHRcdHRoaXMucXVldWUuZHJhaW4oKTtcblx0fVxuXG5cdGV4cGFuZFRvSW5kZXggKGluZGV4OiBudW1iZXIpIHtcblx0XHRpZiAoaW5kZXggPCB0aGlzLnRyYWNrcy5sZW5ndGgpIHJldHVybiB0aGlzLnRyYWNrc1tpbmRleF07XG5cdFx0VXRpbHMuZW5zdXJlQXJyYXlDYXBhY2l0eSh0aGlzLnRyYWNrcywgaW5kZXggKyAxLCBudWxsKTtcblx0XHR0aGlzLnRyYWNrcy5sZW5ndGggPSBpbmRleCArIDE7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKiogQHBhcmFtIGxhc3QgTWF5IGJlIG51bGwuICovXG5cdHRyYWNrRW50cnkgKHRyYWNrSW5kZXg6IG51bWJlciwgYW5pbWF0aW9uOiBBbmltYXRpb24sIGxvb3A6IGJvb2xlYW4sIGxhc3Q6IFRyYWNrRW50cnkgfCBudWxsKSB7XG5cdFx0bGV0IGVudHJ5ID0gdGhpcy50cmFja0VudHJ5UG9vbC5vYnRhaW4oKTtcblx0XHRlbnRyeS5yZXNldCgpO1xuXHRcdGVudHJ5LnRyYWNrSW5kZXggPSB0cmFja0luZGV4O1xuXHRcdGVudHJ5LmFuaW1hdGlvbiA9IGFuaW1hdGlvbjtcblx0XHRlbnRyeS5sb29wID0gbG9vcDtcblx0XHRlbnRyeS5ob2xkUHJldmlvdXMgPSBmYWxzZTtcblxuXHRcdGVudHJ5LnJldmVyc2UgPSBmYWxzZTtcblx0XHRlbnRyeS5zaG9ydGVzdFJvdGF0aW9uID0gZmFsc2U7XG5cblx0XHRlbnRyeS5ldmVudFRocmVzaG9sZCA9IDA7XG5cdFx0ZW50cnkuYWxwaGFBdHRhY2htZW50VGhyZXNob2xkID0gMDtcblx0XHRlbnRyeS5taXhBdHRhY2htZW50VGhyZXNob2xkID0gMDtcblx0XHRlbnRyeS5taXhEcmF3T3JkZXJUaHJlc2hvbGQgPSAwO1xuXG5cdFx0ZW50cnkuYW5pbWF0aW9uU3RhcnQgPSAwO1xuXHRcdGVudHJ5LmFuaW1hdGlvbkVuZCA9IGFuaW1hdGlvbi5kdXJhdGlvbjtcblx0XHRlbnRyeS5hbmltYXRpb25MYXN0ID0gLTE7XG5cdFx0ZW50cnkubmV4dEFuaW1hdGlvbkxhc3QgPSAtMTtcblxuXHRcdGVudHJ5LmRlbGF5ID0gMDtcblx0XHRlbnRyeS50cmFja1RpbWUgPSAwO1xuXHRcdGVudHJ5LnRyYWNrTGFzdCA9IC0xO1xuXHRcdGVudHJ5Lm5leHRUcmFja0xhc3QgPSAtMTtcblx0XHRlbnRyeS50cmFja0VuZCA9IE51bWJlci5NQVhfVkFMVUU7XG5cdFx0ZW50cnkudGltZVNjYWxlID0gMTtcblxuXHRcdGVudHJ5LmFscGhhID0gMTtcblx0XHRlbnRyeS5taXhUaW1lID0gMDtcblx0XHRlbnRyeS5taXhEdXJhdGlvbiA9ICFsYXN0ID8gMCA6IHRoaXMuZGF0YS5nZXRNaXgobGFzdC5hbmltYXRpb24hLCBhbmltYXRpb24pO1xuXHRcdGVudHJ5LmludGVycnVwdEFscGhhID0gMTtcblx0XHRlbnRyeS50b3RhbEFscGhhID0gMDtcblx0XHRlbnRyeS5taXhCbGVuZCA9IE1peEJsZW5kLnJlcGxhY2U7XG5cdFx0cmV0dXJuIGVudHJ5O1xuXHR9XG5cblx0LyoqIFJlbW92ZXMgdGhlIHtAbGluayBUcmFja0VudHJ5I2dldE5leHQoKSBuZXh0IGVudHJ5fSBhbmQgYWxsIGVudHJpZXMgYWZ0ZXIgaXQgZm9yIHRoZSBzcGVjaWZpZWQgZW50cnkuICovXG5cdGNsZWFyTmV4dCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHRsZXQgbmV4dCA9IGVudHJ5Lm5leHQ7XG5cdFx0d2hpbGUgKG5leHQpIHtcblx0XHRcdHRoaXMucXVldWUuZGlzcG9zZShuZXh0KTtcblx0XHRcdG5leHQgPSBuZXh0Lm5leHQ7XG5cdFx0fVxuXHRcdGVudHJ5Lm5leHQgPSBudWxsO1xuXHR9XG5cblx0X2FuaW1hdGlvbnNDaGFuZ2VkICgpIHtcblx0XHR0aGlzLmFuaW1hdGlvbnNDaGFuZ2VkID0gZmFsc2U7XG5cblx0XHR0aGlzLnByb3BlcnR5SURzLmNsZWFyKCk7XG5cdFx0bGV0IHRyYWNrcyA9IHRoaXMudHJhY2tzO1xuXHRcdGZvciAobGV0IGkgPSAwLCBuID0gdHJhY2tzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuXHRcdFx0bGV0IGVudHJ5ID0gdHJhY2tzW2ldO1xuXHRcdFx0aWYgKCFlbnRyeSkgY29udGludWU7XG5cdFx0XHR3aGlsZSAoZW50cnkubWl4aW5nRnJvbSlcblx0XHRcdFx0ZW50cnkgPSBlbnRyeS5taXhpbmdGcm9tO1xuXHRcdFx0ZG8ge1xuXHRcdFx0XHRpZiAoIWVudHJ5Lm1peGluZ1RvIHx8IGVudHJ5Lm1peEJsZW5kICE9IE1peEJsZW5kLmFkZCkgdGhpcy5jb21wdXRlSG9sZChlbnRyeSk7XG5cdFx0XHRcdGVudHJ5ID0gZW50cnkubWl4aW5nVG87XG5cdFx0XHR9IHdoaWxlIChlbnRyeSk7XG5cdFx0fVxuXHR9XG5cblx0Y29tcHV0ZUhvbGQgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdFx0bGV0IHRvID0gZW50cnkubWl4aW5nVG87XG5cdFx0bGV0IHRpbWVsaW5lcyA9IGVudHJ5LmFuaW1hdGlvbiEudGltZWxpbmVzO1xuXHRcdGxldCB0aW1lbGluZXNDb3VudCA9IGVudHJ5LmFuaW1hdGlvbiEudGltZWxpbmVzLmxlbmd0aDtcblx0XHRsZXQgdGltZWxpbmVNb2RlID0gZW50cnkudGltZWxpbmVNb2RlO1xuXHRcdHRpbWVsaW5lTW9kZS5sZW5ndGggPSB0aW1lbGluZXNDb3VudDtcblx0XHRsZXQgdGltZWxpbmVIb2xkTWl4ID0gZW50cnkudGltZWxpbmVIb2xkTWl4O1xuXHRcdHRpbWVsaW5lSG9sZE1peC5sZW5ndGggPSAwO1xuXHRcdGxldCBwcm9wZXJ0eUlEcyA9IHRoaXMucHJvcGVydHlJRHM7XG5cblx0XHRpZiAodG8gJiYgdG8uaG9sZFByZXZpb3VzKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRpbWVsaW5lc0NvdW50OyBpKyspXG5cdFx0XHRcdHRpbWVsaW5lTW9kZVtpXSA9IHByb3BlcnR5SURzLmFkZEFsbCh0aW1lbGluZXNbaV0uZ2V0UHJvcGVydHlJZHMoKSkgPyBIT0xEX0ZJUlNUIDogSE9MRF9TVUJTRVFVRU5UO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG91dGVyOlxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGltZWxpbmVzQ291bnQ7IGkrKykge1xuXHRcdFx0bGV0IHRpbWVsaW5lID0gdGltZWxpbmVzW2ldO1xuXHRcdFx0bGV0IGlkcyA9IHRpbWVsaW5lLmdldFByb3BlcnR5SWRzKCk7XG5cdFx0XHRpZiAoIXByb3BlcnR5SURzLmFkZEFsbChpZHMpKVxuXHRcdFx0XHR0aW1lbGluZU1vZGVbaV0gPSBTVUJTRVFVRU5UO1xuXHRcdFx0ZWxzZSBpZiAoIXRvIHx8IHRpbWVsaW5lIGluc3RhbmNlb2YgQXR0YWNobWVudFRpbWVsaW5lIHx8IHRpbWVsaW5lIGluc3RhbmNlb2YgRHJhd09yZGVyVGltZWxpbmVcblx0XHRcdFx0fHwgdGltZWxpbmUgaW5zdGFuY2VvZiBFdmVudFRpbWVsaW5lIHx8ICF0by5hbmltYXRpb24hLmhhc1RpbWVsaW5lKGlkcykpIHtcblx0XHRcdFx0dGltZWxpbmVNb2RlW2ldID0gRklSU1Q7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKGxldCBuZXh0ID0gdG8ubWl4aW5nVG87IG5leHQ7IG5leHQgPSBuZXh0IS5taXhpbmdUbykge1xuXHRcdFx0XHRcdGlmIChuZXh0LmFuaW1hdGlvbiEuaGFzVGltZWxpbmUoaWRzKSkgY29udGludWU7XG5cdFx0XHRcdFx0aWYgKGVudHJ5Lm1peER1cmF0aW9uID4gMCkge1xuXHRcdFx0XHRcdFx0dGltZWxpbmVNb2RlW2ldID0gSE9MRF9NSVg7XG5cdFx0XHRcdFx0XHR0aW1lbGluZUhvbGRNaXhbaV0gPSBuZXh0O1xuXHRcdFx0XHRcdFx0Y29udGludWUgb3V0ZXI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRpbWVsaW5lTW9kZVtpXSA9IEhPTERfRklSU1Q7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIFJldHVybnMgdGhlIHRyYWNrIGVudHJ5IGZvciB0aGUgYW5pbWF0aW9uIGN1cnJlbnRseSBwbGF5aW5nIG9uIHRoZSB0cmFjaywgb3IgbnVsbCBpZiBubyBhbmltYXRpb24gaXMgY3VycmVudGx5IHBsYXlpbmcuICovXG5cdGdldEN1cnJlbnQgKHRyYWNrSW5kZXg6IG51bWJlcikge1xuXHRcdGlmICh0cmFja0luZGV4ID49IHRoaXMudHJhY2tzLmxlbmd0aCkgcmV0dXJuIG51bGw7XG5cdFx0cmV0dXJuIHRoaXMudHJhY2tzW3RyYWNrSW5kZXhdO1xuXHR9XG5cblx0LyoqIEFkZHMgYSBsaXN0ZW5lciB0byByZWNlaXZlIGV2ZW50cyBmb3IgYWxsIHRyYWNrIGVudHJpZXMuICovXG5cdGFkZExpc3RlbmVyIChsaXN0ZW5lcjogQW5pbWF0aW9uU3RhdGVMaXN0ZW5lcikge1xuXHRcdGlmICghbGlzdGVuZXIpIHRocm93IG5ldyBFcnJvcihcImxpc3RlbmVyIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHR0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBhZGRlZCB3aXRoIHtAbGluayAjYWRkTGlzdGVuZXIoKX0uICovXG5cdHJlbW92ZUxpc3RlbmVyIChsaXN0ZW5lcjogQW5pbWF0aW9uU3RhdGVMaXN0ZW5lcikge1xuXHRcdGxldCBpbmRleCA9IHRoaXMubGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuXHRcdGlmIChpbmRleCA+PSAwKSB0aGlzLmxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXHR9XG5cblx0LyoqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBhZGRlZCB3aXRoIHtAbGluayAjYWRkTGlzdGVuZXIoKX0uICovXG5cdGNsZWFyTGlzdGVuZXJzICgpIHtcblx0XHR0aGlzLmxpc3RlbmVycy5sZW5ndGggPSAwO1xuXHR9XG5cblx0LyoqIERpc2NhcmRzIGFsbCBsaXN0ZW5lciBub3RpZmljYXRpb25zIHRoYXQgaGF2ZSBub3QgeWV0IGJlZW4gZGVsaXZlcmVkLiBUaGlzIGNhbiBiZSB1c2VmdWwgdG8gY2FsbCBmcm9tIGFuXG5cdCAqIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyfSB3aGVuIGl0IGlzIGtub3duIHRoYXQgZnVydGhlciBub3RpZmljYXRpb25zIHRoYXQgbWF5IGhhdmUgYmVlbiBhbHJlYWR5IHF1ZXVlZCBmb3IgZGVsaXZlcnlcblx0ICogYXJlIG5vdCB3YW50ZWQgYmVjYXVzZSBuZXcgYW5pbWF0aW9ucyBhcmUgYmVpbmcgc2V0LiAqL1xuXHRjbGVhckxpc3RlbmVyTm90aWZpY2F0aW9ucyAoKSB7XG5cdFx0dGhpcy5xdWV1ZS5jbGVhcigpO1xuXHR9XG59XG5cbi8qKiBTdG9yZXMgc2V0dGluZ3MgYW5kIG90aGVyIHN0YXRlIGZvciB0aGUgcGxheWJhY2sgb2YgYW4gYW5pbWF0aW9uIG9uIGFuIHtAbGluayBBbmltYXRpb25TdGF0ZX0gdHJhY2suXG4gKlxuICogUmVmZXJlbmNlcyB0byBhIHRyYWNrIGVudHJ5IG11c3Qgbm90IGJlIGtlcHQgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyI2Rpc3Bvc2UoKX0gZXZlbnQgb2NjdXJzLiAqL1xuZXhwb3J0IGNsYXNzIFRyYWNrRW50cnkge1xuXHQvKiogVGhlIGFuaW1hdGlvbiB0byBhcHBseSBmb3IgdGhpcyB0cmFjayBlbnRyeS4gKi9cblx0YW5pbWF0aW9uOiBBbmltYXRpb24gfCBudWxsID0gbnVsbDtcblxuXHRwcmV2aW91czogVHJhY2tFbnRyeSB8IG51bGwgPSBudWxsO1xuXG5cdC8qKiBUaGUgYW5pbWF0aW9uIHF1ZXVlZCB0byBzdGFydCBhZnRlciB0aGlzIGFuaW1hdGlvbiwgb3IgbnVsbC4gYG5leHRgIG1ha2VzIHVwIGEgbGlua2VkIGxpc3QuICovXG5cdG5leHQ6IFRyYWNrRW50cnkgfCBudWxsID0gbnVsbDtcblxuXHQvKiogVGhlIHRyYWNrIGVudHJ5IGZvciB0aGUgcHJldmlvdXMgYW5pbWF0aW9uIHdoZW4gbWl4aW5nIGZyb20gdGhlIHByZXZpb3VzIGFuaW1hdGlvbiB0byB0aGlzIGFuaW1hdGlvbiwgb3IgbnVsbCBpZiBub1xuXHQgKiBtaXhpbmcgaXMgY3VycmVudGx5IG9jY3VyaW5nLiBXaGVuIG1peGluZyBmcm9tIG11bHRpcGxlIGFuaW1hdGlvbnMsIGBtaXhpbmdGcm9tYCBtYWtlcyB1cCBhIGxpbmtlZCBsaXN0LiAqL1xuXHRtaXhpbmdGcm9tOiBUcmFja0VudHJ5IHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFRoZSB0cmFjayBlbnRyeSBmb3IgdGhlIG5leHQgYW5pbWF0aW9uIHdoZW4gbWl4aW5nIGZyb20gdGhpcyBhbmltYXRpb24gdG8gdGhlIG5leHQgYW5pbWF0aW9uLCBvciBudWxsIGlmIG5vIG1peGluZyBpc1xuXHQgKiBjdXJyZW50bHkgb2NjdXJpbmcuIFdoZW4gbWl4aW5nIHRvIG11bHRpcGxlIGFuaW1hdGlvbnMsIGBtaXhpbmdUb2AgbWFrZXMgdXAgYSBsaW5rZWQgbGlzdC4gKi9cblx0bWl4aW5nVG86IFRyYWNrRW50cnkgfCBudWxsID0gbnVsbDtcblxuXHQvKiogVGhlIGxpc3RlbmVyIGZvciBldmVudHMgZ2VuZXJhdGVkIGJ5IHRoaXMgdHJhY2sgZW50cnksIG9yIG51bGwuXG5cdCAqXG5cdCAqIEEgdHJhY2sgZW50cnkgcmV0dXJuZWQgZnJvbSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjc2V0QW5pbWF0aW9uKCl9IGlzIGFscmVhZHkgdGhlIGN1cnJlbnQgYW5pbWF0aW9uXG5cdCAqIGZvciB0aGUgdHJhY2ssIHNvIHRoZSB0cmFjayBlbnRyeSBsaXN0ZW5lciB7QGxpbmsgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lciNzdGFydCgpfSB3aWxsIG5vdCBiZSBjYWxsZWQuICovXG5cdGxpc3RlbmVyOiBBbmltYXRpb25TdGF0ZUxpc3RlbmVyIHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFRoZSBpbmRleCBvZiB0aGUgdHJhY2sgd2hlcmUgdGhpcyB0cmFjayBlbnRyeSBpcyBlaXRoZXIgY3VycmVudCBvciBxdWV1ZWQuXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjZ2V0Q3VycmVudCgpfS4gKi9cblx0dHJhY2tJbmRleDogbnVtYmVyID0gMDtcblxuXHQvKiogSWYgdHJ1ZSwgdGhlIGFuaW1hdGlvbiB3aWxsIHJlcGVhdC4gSWYgZmFsc2UgaXQgd2lsbCBub3QsIGluc3RlYWQgaXRzIGxhc3QgZnJhbWUgaXMgYXBwbGllZCBpZiBwbGF5ZWQgYmV5b25kIGl0c1xuXHQgKiBkdXJhdGlvbi4gKi9cblx0bG9vcDogYm9vbGVhbiA9IGZhbHNlO1xuXG5cdC8qKiBJZiB0cnVlLCB3aGVuIG1peGluZyBmcm9tIHRoZSBwcmV2aW91cyBhbmltYXRpb24gdG8gdGhpcyBhbmltYXRpb24sIHRoZSBwcmV2aW91cyBhbmltYXRpb24gaXMgYXBwbGllZCBhcyBub3JtYWwgaW5zdGVhZFxuXHQgKiBvZiBiZWluZyBtaXhlZCBvdXQuXG5cdCAqXG5cdCAqIFdoZW4gbWl4aW5nIGJldHdlZW4gYW5pbWF0aW9ucyB0aGF0IGtleSB0aGUgc2FtZSBwcm9wZXJ0eSwgaWYgYSBsb3dlciB0cmFjayBhbHNvIGtleXMgdGhhdCBwcm9wZXJ0eSB0aGVuIHRoZSB2YWx1ZSB3aWxsXG5cdCAqIGJyaWVmbHkgZGlwIHRvd2FyZCB0aGUgbG93ZXIgdHJhY2sgdmFsdWUgZHVyaW5nIHRoZSBtaXguIFRoaXMgaGFwcGVucyBiZWNhdXNlIHRoZSBmaXJzdCBhbmltYXRpb24gbWl4ZXMgZnJvbSAxMDAlIHRvIDAlXG5cdCAqIHdoaWxlIHRoZSBzZWNvbmQgYW5pbWF0aW9uIG1peGVzIGZyb20gMCUgdG8gMTAwJS4gU2V0dGluZyBgaG9sZFByZXZpb3VzYCB0byB0cnVlIGFwcGxpZXMgdGhlIGZpcnN0IGFuaW1hdGlvblxuXHQgKiBhdCAxMDAlIGR1cmluZyB0aGUgbWl4IHNvIHRoZSBsb3dlciB0cmFjayB2YWx1ZSBpcyBvdmVyd3JpdHRlbi4gU3VjaCBkaXBwaW5nIGRvZXMgbm90IG9jY3VyIG9uIHRoZSBsb3dlc3QgdHJhY2sgd2hpY2hcblx0ICoga2V5cyB0aGUgcHJvcGVydHksIG9ubHkgd2hlbiBhIGhpZ2hlciB0cmFjayBhbHNvIGtleXMgdGhlIHByb3BlcnR5LlxuXHQgKlxuXHQgKiBTbmFwcGluZyB3aWxsIG9jY3VyIGlmIGBob2xkUHJldmlvdXNgIGlzIHRydWUgYW5kIHRoaXMgYW5pbWF0aW9uIGRvZXMgbm90IGtleSBhbGwgdGhlIHNhbWUgcHJvcGVydGllcyBhcyB0aGVcblx0ICogcHJldmlvdXMgYW5pbWF0aW9uLiAqL1xuXHRob2xkUHJldmlvdXM6IGJvb2xlYW4gPSBmYWxzZTtcblxuXHRyZXZlcnNlOiBib29sZWFuID0gZmFsc2U7XG5cblx0c2hvcnRlc3RSb3RhdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xuXG5cdC8qKiBXaGVuIHRoZSBtaXggcGVyY2VudGFnZSAoe0BsaW5rICNtaXhUaW1lfSAvIHtAbGluayAjbWl4RHVyYXRpb259KSBpcyBsZXNzIHRoYW4gdGhlXG5cdCAqIGBldmVudFRocmVzaG9sZGAsIGV2ZW50IHRpbWVsaW5lcyBhcmUgYXBwbGllZCB3aGlsZSB0aGlzIGFuaW1hdGlvbiBpcyBiZWluZyBtaXhlZCBvdXQuIERlZmF1bHRzIHRvIDAsIHNvIGV2ZW50XG5cdCAqIHRpbWVsaW5lcyBhcmUgbm90IGFwcGxpZWQgd2hpbGUgdGhpcyBhbmltYXRpb24gaXMgYmVpbmcgbWl4ZWQgb3V0LiAqL1xuXHRldmVudFRocmVzaG9sZDogbnVtYmVyID0gMDtcblxuXHQvKiogV2hlbiB0aGUgbWl4IHBlcmNlbnRhZ2UgKHtAbGluayAjbWl4dGltZX0gLyB7QGxpbmsgI21peER1cmF0aW9ufSkgaXMgbGVzcyB0aGFuIHRoZVxuXHQgKiBgYXR0YWNobWVudFRocmVzaG9sZGAsIGF0dGFjaG1lbnQgdGltZWxpbmVzIGFyZSBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gRGVmYXVsdHMgdG9cblx0ICogMCwgc28gYXR0YWNobWVudCB0aW1lbGluZXMgYXJlIG5vdCBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gKi9cblx0bWl4QXR0YWNobWVudFRocmVzaG9sZDogbnVtYmVyID0gMDtcblxuXHQvKiogV2hlbiB7QGxpbmsgI2dldEFscGhhKCl9IGlzIGdyZWF0ZXIgdGhhbiA8Y29kZT5hbHBoYUF0dGFjaG1lbnRUaHJlc2hvbGQ8L2NvZGU+LCBhdHRhY2htZW50IHRpbWVsaW5lcyBhcmUgYXBwbGllZC5cblx0ICogRGVmYXVsdHMgdG8gMCwgc28gYXR0YWNobWVudCB0aW1lbGluZXMgYXJlIGFsd2F5cyBhcHBsaWVkLiAqL1xuXHRhbHBoYUF0dGFjaG1lbnRUaHJlc2hvbGQ6IG51bWJlciA9IDA7XG5cblx0LyoqIFdoZW4gdGhlIG1peCBwZXJjZW50YWdlICh7QGxpbmsgI2dldE1peFRpbWUoKX0gLyB7QGxpbmsgI2dldE1peER1cmF0aW9uKCl9KSBpcyBsZXNzIHRoYW4gdGhlXG5cdCAqIDxjb2RlPm1peERyYXdPcmRlclRocmVzaG9sZDwvY29kZT4sIGRyYXcgb3JkZXIgdGltZWxpbmVzIGFyZSBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gRGVmYXVsdHMgdG9cblx0ICogMCwgc28gZHJhdyBvcmRlciB0aW1lbGluZXMgYXJlIG5vdCBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gKi9cblx0bWl4RHJhd09yZGVyVGhyZXNob2xkOiBudW1iZXIgPSAwO1xuXG5cdC8qKiBTZWNvbmRzIHdoZW4gdGhpcyBhbmltYXRpb24gc3RhcnRzLCBib3RoIGluaXRpYWxseSBhbmQgYWZ0ZXIgbG9vcGluZy4gRGVmYXVsdHMgdG8gMC5cblx0ICpcblx0ICogV2hlbiBjaGFuZ2luZyB0aGUgYGFuaW1hdGlvblN0YXJ0YCB0aW1lLCBpdCBvZnRlbiBtYWtlcyBzZW5zZSB0byBzZXQge0BsaW5rICNhbmltYXRpb25MYXN0fSB0byB0aGUgc2FtZVxuXHQgKiB2YWx1ZSB0byBwcmV2ZW50IHRpbWVsaW5lIGtleXMgYmVmb3JlIHRoZSBzdGFydCB0aW1lIGZyb20gdHJpZ2dlcmluZy4gKi9cblx0YW5pbWF0aW9uU3RhcnQ6IG51bWJlciA9IDA7XG5cblx0LyoqIFNlY29uZHMgZm9yIHRoZSBsYXN0IGZyYW1lIG9mIHRoaXMgYW5pbWF0aW9uLiBOb24tbG9vcGluZyBhbmltYXRpb25zIHdvbid0IHBsYXkgcGFzdCB0aGlzIHRpbWUuIExvb3BpbmcgYW5pbWF0aW9ucyB3aWxsXG5cdCAqIGxvb3AgYmFjayB0byB7QGxpbmsgI2FuaW1hdGlvblN0YXJ0fSBhdCB0aGlzIHRpbWUuIERlZmF1bHRzIHRvIHRoZSBhbmltYXRpb24ge0BsaW5rIEFuaW1hdGlvbiNkdXJhdGlvbn0uICovXG5cdGFuaW1hdGlvbkVuZDogbnVtYmVyID0gMDtcblxuXG5cdC8qKiBUaGUgdGltZSBpbiBzZWNvbmRzIHRoaXMgYW5pbWF0aW9uIHdhcyBsYXN0IGFwcGxpZWQuIFNvbWUgdGltZWxpbmVzIHVzZSB0aGlzIGZvciBvbmUtdGltZSB0cmlnZ2Vycy4gRWcsIHdoZW4gdGhpc1xuXHQgKiBhbmltYXRpb24gaXMgYXBwbGllZCwgZXZlbnQgdGltZWxpbmVzIHdpbGwgZmlyZSBhbGwgZXZlbnRzIGJldHdlZW4gdGhlIGBhbmltYXRpb25MYXN0YCB0aW1lIChleGNsdXNpdmUpIGFuZFxuXHQgKiBgYW5pbWF0aW9uVGltZWAgKGluY2x1c2l2ZSkuIERlZmF1bHRzIHRvIC0xIHRvIGVuc3VyZSB0cmlnZ2VycyBvbiBmcmFtZSAwIGhhcHBlbiB0aGUgZmlyc3QgdGltZSB0aGlzIGFuaW1hdGlvblxuXHQgKiBpcyBhcHBsaWVkLiAqL1xuXHRhbmltYXRpb25MYXN0OiBudW1iZXIgPSAwO1xuXG5cdG5leHRBbmltYXRpb25MYXN0OiBudW1iZXIgPSAwO1xuXG5cdC8qKiBTZWNvbmRzIHRvIHBvc3Rwb25lIHBsYXlpbmcgdGhlIGFuaW1hdGlvbi4gV2hlbiB0aGlzIHRyYWNrIGVudHJ5IGlzIHRoZSBjdXJyZW50IHRyYWNrIGVudHJ5LCBgZGVsYXlgXG5cdCAqIHBvc3Rwb25lcyBpbmNyZW1lbnRpbmcgdGhlIHtAbGluayAjdHJhY2tUaW1lfS4gV2hlbiB0aGlzIHRyYWNrIGVudHJ5IGlzIHF1ZXVlZCwgYGRlbGF5YCBpcyB0aGUgdGltZSBmcm9tXG5cdCAqIHRoZSBzdGFydCBvZiB0aGUgcHJldmlvdXMgYW5pbWF0aW9uIHRvIHdoZW4gdGhpcyB0cmFjayBlbnRyeSB3aWxsIGJlY29tZSB0aGUgY3VycmVudCB0cmFjayBlbnRyeSAoaWUgd2hlbiB0aGUgcHJldmlvdXNcblx0ICogdHJhY2sgZW50cnkge0BsaW5rIFRyYWNrRW50cnkjdHJhY2tUaW1lfSA+PSB0aGlzIHRyYWNrIGVudHJ5J3MgYGRlbGF5YCkuXG5cdCAqXG5cdCAqIHtAbGluayAjdGltZVNjYWxlfSBhZmZlY3RzIHRoZSBkZWxheS4gKi9cblx0ZGVsYXk6IG51bWJlciA9IDA7XG5cblx0LyoqIEN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIHRoaXMgdHJhY2sgZW50cnkgaGFzIGJlZW4gdGhlIGN1cnJlbnQgdHJhY2sgZW50cnkuIFRoZSB0cmFjayB0aW1lIGRldGVybWluZXNcblx0ICoge0BsaW5rICNhbmltYXRpb25UaW1lfS4gVGhlIHRyYWNrIHRpbWUgY2FuIGJlIHNldCB0byBzdGFydCB0aGUgYW5pbWF0aW9uIGF0IGEgdGltZSBvdGhlciB0aGFuIDAsIHdpdGhvdXQgYWZmZWN0aW5nXG5cdCAqIGxvb3BpbmcuICovXG5cdHRyYWNrVGltZTogbnVtYmVyID0gMDtcblxuXHR0cmFja0xhc3Q6IG51bWJlciA9IDA7IG5leHRUcmFja0xhc3Q6IG51bWJlciA9IDA7XG5cblx0LyoqIFRoZSB0cmFjayB0aW1lIGluIHNlY29uZHMgd2hlbiB0aGlzIGFuaW1hdGlvbiB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgdHJhY2suIERlZmF1bHRzIHRvIHRoZSBoaWdoZXN0IHBvc3NpYmxlIGZsb2F0XG5cdCAqIHZhbHVlLCBtZWFuaW5nIHRoZSBhbmltYXRpb24gd2lsbCBiZSBhcHBsaWVkIHVudGlsIGEgbmV3IGFuaW1hdGlvbiBpcyBzZXQgb3IgdGhlIHRyYWNrIGlzIGNsZWFyZWQuIElmIHRoZSB0cmFjayBlbmQgdGltZVxuXHQgKiBpcyByZWFjaGVkLCBubyBvdGhlciBhbmltYXRpb25zIGFyZSBxdWV1ZWQgZm9yIHBsYXliYWNrLCBhbmQgbWl4aW5nIGZyb20gYW55IHByZXZpb3VzIGFuaW1hdGlvbnMgaXMgY29tcGxldGUsIHRoZW4gdGhlXG5cdCAqIHByb3BlcnRpZXMga2V5ZWQgYnkgdGhlIGFuaW1hdGlvbiBhcmUgc2V0IHRvIHRoZSBzZXR1cCBwb3NlIGFuZCB0aGUgdHJhY2sgaXMgY2xlYXJlZC5cblx0ICpcblx0ICogSXQgbWF5IGJlIGRlc2lyZWQgdG8gdXNlIHtAbGluayBBbmltYXRpb25TdGF0ZSNhZGRFbXB0eUFuaW1hdGlvbigpfSByYXRoZXIgdGhhbiBoYXZlIHRoZSBhbmltYXRpb25cblx0ICogYWJydXB0bHkgY2Vhc2UgYmVpbmcgYXBwbGllZC4gKi9cblx0dHJhY2tFbmQ6IG51bWJlciA9IDA7XG5cblx0LyoqIE11bHRpcGxpZXIgZm9yIHRoZSBkZWx0YSB0aW1lIHdoZW4gdGhpcyB0cmFjayBlbnRyeSBpcyB1cGRhdGVkLCBjYXVzaW5nIHRpbWUgZm9yIHRoaXMgYW5pbWF0aW9uIHRvIHBhc3Mgc2xvd2VyIG9yXG5cdCAqIGZhc3Rlci4gRGVmYXVsdHMgdG8gMS5cblx0ICpcblx0ICoge0BsaW5rICNtaXhUaW1lfSBpcyBub3QgYWZmZWN0ZWQgYnkgdHJhY2sgZW50cnkgdGltZSBzY2FsZSwgc28ge0BsaW5rICNtaXhEdXJhdGlvbn0gbWF5IG5lZWQgdG8gYmUgYWRqdXN0ZWQgdG9cblx0ICogbWF0Y2ggdGhlIGFuaW1hdGlvbiBzcGVlZC5cblx0ICpcblx0ICogV2hlbiB1c2luZyB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjYWRkQW5pbWF0aW9uKCl9IHdpdGggYSBgZGVsYXlgIDw9IDAsIG5vdGUgdGhlXG5cdCAqIHtAbGluayAjZGVsYXl9IGlzIHNldCB1c2luZyB0aGUgbWl4IGR1cmF0aW9uIGZyb20gdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZURhdGF9LCBhc3N1bWluZyB0aW1lIHNjYWxlIHRvIGJlIDEuIElmXG5cdCAqIHRoZSB0aW1lIHNjYWxlIGlzIG5vdCAxLCB0aGUgZGVsYXkgbWF5IG5lZWQgdG8gYmUgYWRqdXN0ZWQuXG5cdCAqXG5cdCAqIFNlZSBBbmltYXRpb25TdGF0ZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjdGltZVNjYWxlfSBmb3IgYWZmZWN0aW5nIGFsbCBhbmltYXRpb25zLiAqL1xuXHR0aW1lU2NhbGU6IG51bWJlciA9IDA7XG5cblx0LyoqIFZhbHVlcyA8IDEgbWl4IHRoaXMgYW5pbWF0aW9uIHdpdGggdGhlIHNrZWxldG9uJ3MgY3VycmVudCBwb3NlICh1c3VhbGx5IHRoZSBwb3NlIHJlc3VsdGluZyBmcm9tIGxvd2VyIHRyYWNrcykuIERlZmF1bHRzXG5cdCAqIHRvIDEsIHdoaWNoIG92ZXJ3cml0ZXMgdGhlIHNrZWxldG9uJ3MgY3VycmVudCBwb3NlIHdpdGggdGhpcyBhbmltYXRpb24uXG5cdCAqXG5cdCAqIFR5cGljYWxseSB0cmFjayAwIGlzIHVzZWQgdG8gY29tcGxldGVseSBwb3NlIHRoZSBza2VsZXRvbiwgdGhlbiBhbHBoYSBpcyB1c2VkIG9uIGhpZ2hlciB0cmFja3MuIEl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0b1xuXHQgKiB1c2UgYWxwaGEgb24gdHJhY2sgMCBpZiB0aGUgc2tlbGV0b24gcG9zZSBpcyBmcm9tIHRoZSBsYXN0IGZyYW1lIHJlbmRlci4gKi9cblx0YWxwaGE6IG51bWJlciA9IDA7XG5cblx0LyoqIFNlY29uZHMgZnJvbSAwIHRvIHRoZSB7QGxpbmsgI2dldE1peER1cmF0aW9uKCl9IHdoZW4gbWl4aW5nIGZyb20gdGhlIHByZXZpb3VzIGFuaW1hdGlvbiB0byB0aGlzIGFuaW1hdGlvbi4gTWF5IGJlXG5cdCAqIHNsaWdodGx5IG1vcmUgdGhhbiBgbWl4RHVyYXRpb25gIHdoZW4gdGhlIG1peCBpcyBjb21wbGV0ZS4gKi9cblx0bWl4VGltZTogbnVtYmVyID0gMDtcblxuXHQvKiogU2Vjb25kcyBmb3IgbWl4aW5nIGZyb20gdGhlIHByZXZpb3VzIGFuaW1hdGlvbiB0byB0aGlzIGFuaW1hdGlvbi4gRGVmYXVsdHMgdG8gdGhlIHZhbHVlIHByb3ZpZGVkIGJ5IEFuaW1hdGlvblN0YXRlRGF0YVxuXHQgKiB7QGxpbmsgQW5pbWF0aW9uU3RhdGVEYXRhI2dldE1peCgpfSBiYXNlZCBvbiB0aGUgYW5pbWF0aW9uIGJlZm9yZSB0aGlzIGFuaW1hdGlvbiAoaWYgYW55KS5cblx0ICpcblx0ICogQSBtaXggZHVyYXRpb24gb2YgMCBzdGlsbCBtaXhlcyBvdXQgb3ZlciBvbmUgZnJhbWUgdG8gcHJvdmlkZSB0aGUgdHJhY2sgZW50cnkgYmVpbmcgbWl4ZWQgb3V0IGEgY2hhbmNlIHRvIHJldmVydCB0aGVcblx0ICogcHJvcGVydGllcyBpdCB3YXMgYW5pbWF0aW5nLlxuXHQgKlxuXHQgKiBUaGUgYG1peER1cmF0aW9uYCBjYW4gYmUgc2V0IG1hbnVhbGx5IHJhdGhlciB0aGFuIHVzZSB0aGUgdmFsdWUgZnJvbVxuXHQgKiB7QGxpbmsgQW5pbWF0aW9uU3RhdGVEYXRhI2dldE1peCgpfS4gSW4gdGhhdCBjYXNlLCB0aGUgYG1peER1cmF0aW9uYCBjYW4gYmUgc2V0IGZvciBhIG5ld1xuXHQgKiB0cmFjayBlbnRyeSBvbmx5IGJlZm9yZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjdXBkYXRlKGZsb2F0KX0gaXMgZmlyc3QgY2FsbGVkLlxuXHQgKlxuXHQgKiBXaGVuIHVzaW5nIHtAbGluayBBbmltYXRpb25TdGF0ZSNhZGRBbmltYXRpb24oKX0gd2l0aCBhIGBkZWxheWAgPD0gMCwgbm90ZSB0aGVcblx0ICoge0BsaW5rICNkZWxheX0gaXMgc2V0IHVzaW5nIHRoZSBtaXggZHVyYXRpb24gZnJvbSB0aGUge0BsaW5rIEFuaW1hdGlvblN0YXRlRGF0YX0sIG5vdCBhIG1peCBkdXJhdGlvbiBzZXRcblx0ICogYWZ0ZXJ3YXJkLiAqL1xuXHRfbWl4RHVyYXRpb246IG51bWJlciA9IDA7IGludGVycnVwdEFscGhhOiBudW1iZXIgPSAwOyB0b3RhbEFscGhhOiBudW1iZXIgPSAwO1xuXG5cdGdldCBtaXhEdXJhdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX21peER1cmF0aW9uO1xuXHR9XG5cblx0c2V0IG1peER1cmF0aW9uIChtaXhEdXJhdGlvbjogbnVtYmVyKSB7XG5cdFx0dGhpcy5fbWl4RHVyYXRpb24gPSBtaXhEdXJhdGlvbjtcblx0fVxuXG5cdHNldE1peER1cmF0aW9uV2l0aERlbGF5IChtaXhEdXJhdGlvbjogbnVtYmVyLCBkZWxheTogbnVtYmVyKSB7XG5cdFx0dGhpcy5fbWl4RHVyYXRpb24gPSBtaXhEdXJhdGlvbjtcblx0XHRpZiAoZGVsYXkgPD0gMCkge1xuXHRcdFx0aWYgKHRoaXMucHJldmlvdXMgIT0gbnVsbClcblx0XHRcdFx0ZGVsYXkgPSBNYXRoLm1heChkZWxheSArIHRoaXMucHJldmlvdXMuZ2V0VHJhY2tDb21wbGV0ZSgpIC0gbWl4RHVyYXRpb24sIDApO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRkZWxheSA9IDA7XG5cdFx0fVxuXHRcdHRoaXMuZGVsYXkgPSBkZWxheTtcblx0fVxuXG5cdC8qKiBDb250cm9scyBob3cgcHJvcGVydGllcyBrZXllZCBpbiB0aGUgYW5pbWF0aW9uIGFyZSBtaXhlZCB3aXRoIGxvd2VyIHRyYWNrcy4gRGVmYXVsdHMgdG8ge0BsaW5rIE1peEJsZW5kI3JlcGxhY2V9LCB3aGljaFxuXHQgKiByZXBsYWNlcyB0aGUgdmFsdWVzIGZyb20gdGhlIGxvd2VyIHRyYWNrcyB3aXRoIHRoZSBhbmltYXRpb24gdmFsdWVzLiB7QGxpbmsgTWl4QmxlbmQjYWRkfSBhZGRzIHRoZSBhbmltYXRpb24gdmFsdWVzIHRvXG5cdCAqIHRoZSB2YWx1ZXMgZnJvbSB0aGUgbG93ZXIgdHJhY2tzLlxuXHQgKlxuXHQgKiBUaGUgYG1peEJsZW5kYCBjYW4gYmUgc2V0IGZvciBhIG5ldyB0cmFjayBlbnRyeSBvbmx5IGJlZm9yZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjYXBwbHkoKX0gaXMgZmlyc3Rcblx0ICogY2FsbGVkLiAqL1xuXHRtaXhCbGVuZCA9IE1peEJsZW5kLnJlcGxhY2U7XG5cdHRpbWVsaW5lTW9kZSA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cdHRpbWVsaW5lSG9sZE1peCA9IG5ldyBBcnJheTxUcmFja0VudHJ5PigpO1xuXHR0aW1lbGluZXNSb3RhdGlvbiA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cblx0cmVzZXQgKCkge1xuXHRcdHRoaXMubmV4dCA9IG51bGw7XG5cdFx0dGhpcy5wcmV2aW91cyA9IG51bGw7XG5cdFx0dGhpcy5taXhpbmdGcm9tID0gbnVsbDtcblx0XHR0aGlzLm1peGluZ1RvID0gbnVsbDtcblx0XHR0aGlzLmFuaW1hdGlvbiA9IG51bGw7XG5cdFx0dGhpcy5saXN0ZW5lciA9IG51bGw7XG5cdFx0dGhpcy50aW1lbGluZU1vZGUubGVuZ3RoID0gMDtcblx0XHR0aGlzLnRpbWVsaW5lSG9sZE1peC5sZW5ndGggPSAwO1xuXHRcdHRoaXMudGltZWxpbmVzUm90YXRpb24ubGVuZ3RoID0gMDtcblx0fVxuXG5cdC8qKiBVc2VzIHtAbGluayAjdHJhY2tUaW1lfSB0byBjb21wdXRlIHRoZSBgYW5pbWF0aW9uVGltZWAsIHdoaWNoIGlzIGJldHdlZW4ge0BsaW5rICNhbmltYXRpb25TdGFydH1cblx0ICogYW5kIHtAbGluayAjYW5pbWF0aW9uRW5kfS4gV2hlbiB0aGUgYHRyYWNrVGltZWAgaXMgMCwgdGhlIGBhbmltYXRpb25UaW1lYCBpcyBlcXVhbCB0byB0aGVcblx0ICogYGFuaW1hdGlvblN0YXJ0YCB0aW1lLiAqL1xuXHRnZXRBbmltYXRpb25UaW1lICgpIHtcblx0XHRpZiAodGhpcy5sb29wKSB7XG5cdFx0XHRsZXQgZHVyYXRpb24gPSB0aGlzLmFuaW1hdGlvbkVuZCAtIHRoaXMuYW5pbWF0aW9uU3RhcnQ7XG5cdFx0XHRpZiAoZHVyYXRpb24gPT0gMCkgcmV0dXJuIHRoaXMuYW5pbWF0aW9uU3RhcnQ7XG5cdFx0XHRyZXR1cm4gKHRoaXMudHJhY2tUaW1lICUgZHVyYXRpb24pICsgdGhpcy5hbmltYXRpb25TdGFydDtcblx0XHR9XG5cdFx0cmV0dXJuIE1hdGgubWluKHRoaXMudHJhY2tUaW1lICsgdGhpcy5hbmltYXRpb25TdGFydCwgdGhpcy5hbmltYXRpb25FbmQpO1xuXHR9XG5cblx0c2V0QW5pbWF0aW9uTGFzdCAoYW5pbWF0aW9uTGFzdDogbnVtYmVyKSB7XG5cdFx0dGhpcy5hbmltYXRpb25MYXN0ID0gYW5pbWF0aW9uTGFzdDtcblx0XHR0aGlzLm5leHRBbmltYXRpb25MYXN0ID0gYW5pbWF0aW9uTGFzdDtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRydWUgaWYgYXQgbGVhc3Qgb25lIGxvb3AgaGFzIGJlZW4gY29tcGxldGVkLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIjY29tcGxldGUoKX0uICovXG5cdGlzQ29tcGxldGUgKCkge1xuXHRcdHJldHVybiB0aGlzLnRyYWNrVGltZSA+PSB0aGlzLmFuaW1hdGlvbkVuZCAtIHRoaXMuYW5pbWF0aW9uU3RhcnQ7XG5cdH1cblxuXHQvKiogUmVzZXRzIHRoZSByb3RhdGlvbiBkaXJlY3Rpb25zIGZvciBtaXhpbmcgdGhpcyBlbnRyeSdzIHJvdGF0ZSB0aW1lbGluZXMuIFRoaXMgY2FuIGJlIHVzZWZ1bCB0byBhdm9pZCBib25lcyByb3RhdGluZyB0aGVcblx0ICogbG9uZyB3YXkgYXJvdW5kIHdoZW4gdXNpbmcge0BsaW5rICNhbHBoYX0gYW5kIHN0YXJ0aW5nIGFuaW1hdGlvbnMgb24gb3RoZXIgdHJhY2tzLlxuXHQgKlxuXHQgKiBNaXhpbmcgd2l0aCB7QGxpbmsgTWl4QmxlbmQjcmVwbGFjZX0gaW52b2x2ZXMgZmluZGluZyBhIHJvdGF0aW9uIGJldHdlZW4gdHdvIG90aGVycywgd2hpY2ggaGFzIHR3byBwb3NzaWJsZSBzb2x1dGlvbnM6XG5cdCAqIHRoZSBzaG9ydCB3YXkgb3IgdGhlIGxvbmcgd2F5IGFyb3VuZC4gVGhlIHR3byByb3RhdGlvbnMgbGlrZWx5IGNoYW5nZSBvdmVyIHRpbWUsIHNvIHdoaWNoIGRpcmVjdGlvbiBpcyB0aGUgc2hvcnQgb3IgbG9uZ1xuXHQgKiB3YXkgYWxzbyBjaGFuZ2VzLiBJZiB0aGUgc2hvcnQgd2F5IHdhcyBhbHdheXMgY2hvc2VuLCBib25lcyB3b3VsZCBmbGlwIHRvIHRoZSBvdGhlciBzaWRlIHdoZW4gdGhhdCBkaXJlY3Rpb24gYmVjYW1lIHRoZVxuXHQgKiBsb25nIHdheS4gVHJhY2tFbnRyeSBjaG9vc2VzIHRoZSBzaG9ydCB3YXkgdGhlIGZpcnN0IHRpbWUgaXQgaXMgYXBwbGllZCBhbmQgcmVtZW1iZXJzIHRoYXQgZGlyZWN0aW9uLiAqL1xuXHRyZXNldFJvdGF0aW9uRGlyZWN0aW9ucyAoKSB7XG5cdFx0dGhpcy50aW1lbGluZXNSb3RhdGlvbi5sZW5ndGggPSAwO1xuXHR9XG5cblx0Z2V0VHJhY2tDb21wbGV0ZSAoKSB7XG5cdFx0bGV0IGR1cmF0aW9uID0gdGhpcy5hbmltYXRpb25FbmQgLSB0aGlzLmFuaW1hdGlvblN0YXJ0O1xuXHRcdGlmIChkdXJhdGlvbiAhPSAwKSB7XG5cdFx0XHRpZiAodGhpcy5sb29wKSByZXR1cm4gZHVyYXRpb24gKiAoMSArICgodGhpcy50cmFja1RpbWUgLyBkdXJhdGlvbikgfCAwKSk7IC8vIENvbXBsZXRpb24gb2YgbmV4dCBsb29wLlxuXHRcdFx0aWYgKHRoaXMudHJhY2tUaW1lIDwgZHVyYXRpb24pIHJldHVybiBkdXJhdGlvbjsgLy8gQmVmb3JlIGR1cmF0aW9uLlxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy50cmFja1RpbWU7IC8vIE5leHQgdXBkYXRlLlxuXHR9XG5cblx0LyoqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHRyYWNrIGVudHJ5IGhhcyBiZWVuIGFwcGxpZWQgYXQgbGVhc3Qgb25jZS5cblx0ICogPHA+XG5cdCAqIFNlZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjYXBwbHkoU2tlbGV0b24pfS4gKi9cblx0d2FzQXBwbGllZCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMubmV4dFRyYWNrTGFzdCAhPSAtMTtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgYSB7QGxpbmsgI2dldE5leHQoKX0gdHJhY2sgZW50cnkgYW5kIGl0IHdpbGwgYmVjb21lIHRoZSBjdXJyZW50IHRyYWNrIGVudHJ5IGR1cmluZyB0aGUgbmV4dFxuXHQgKiB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjdXBkYXRlKGZsb2F0KX0uICovXG5cdGlzTmV4dFJlYWR5ICgpIHtcblx0XHRyZXR1cm4gdGhpcy5uZXh0ICE9IG51bGwgJiYgdGhpcy5uZXh0VHJhY2tMYXN0IC0gdGhpcy5uZXh0LmRlbGF5ID49IDA7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIEV2ZW50UXVldWUge1xuXHRvYmplY3RzOiBBcnJheTxhbnk+ID0gW107XG5cdGRyYWluRGlzYWJsZWQgPSBmYWxzZTtcblx0YW5pbVN0YXRlOiBBbmltYXRpb25TdGF0ZTtcblxuXHRjb25zdHJ1Y3RvciAoYW5pbVN0YXRlOiBBbmltYXRpb25TdGF0ZSkge1xuXHRcdHRoaXMuYW5pbVN0YXRlID0gYW5pbVN0YXRlO1xuXHR9XG5cblx0c3RhcnQgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goRXZlbnRUeXBlLnN0YXJ0KTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdFx0dGhpcy5hbmltU3RhdGUuYW5pbWF0aW9uc0NoYW5nZWQgPSB0cnVlO1xuXHR9XG5cblx0aW50ZXJydXB0IChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKEV2ZW50VHlwZS5pbnRlcnJ1cHQpO1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKGVudHJ5KTtcblx0fVxuXG5cdGVuZCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHR0aGlzLm9iamVjdHMucHVzaChFdmVudFR5cGUuZW5kKTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdFx0dGhpcy5hbmltU3RhdGUuYW5pbWF0aW9uc0NoYW5nZWQgPSB0cnVlO1xuXHR9XG5cblx0ZGlzcG9zZSAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHR0aGlzLm9iamVjdHMucHVzaChFdmVudFR5cGUuZGlzcG9zZSk7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goZW50cnkpO1xuXHR9XG5cblx0Y29tcGxldGUgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goRXZlbnRUeXBlLmNvbXBsZXRlKTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdH1cblxuXHRldmVudCAoZW50cnk6IFRyYWNrRW50cnksIGV2ZW50OiBFdmVudCkge1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKEV2ZW50VHlwZS5ldmVudCk7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goZW50cnkpO1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKGV2ZW50KTtcblx0fVxuXG5cdGRyYWluICgpIHtcblx0XHRpZiAodGhpcy5kcmFpbkRpc2FibGVkKSByZXR1cm47XG5cdFx0dGhpcy5kcmFpbkRpc2FibGVkID0gdHJ1ZTtcblxuXHRcdGxldCBvYmplY3RzID0gdGhpcy5vYmplY3RzO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSArPSAyKSB7XG5cdFx0XHRsZXQgdHlwZSA9IG9iamVjdHNbaV0gYXMgRXZlbnRUeXBlO1xuXHRcdFx0bGV0IGVudHJ5ID0gb2JqZWN0c1tpICsgMV0gYXMgVHJhY2tFbnRyeTtcblx0XHRcdGxldCBsaXN0ZW5lcnMgPSB0aGlzLmFuaW1TdGF0ZS5saXN0ZW5lcnMuc2xpY2UoKTtcblx0XHRcdHN3aXRjaCAodHlwZSkge1xuXHRcdFx0XHRjYXNlIEV2ZW50VHlwZS5zdGFydDpcblx0XHRcdFx0XHRpZiAoZW50cnkubGlzdGVuZXIgJiYgZW50cnkubGlzdGVuZXIuc3RhcnQpIGVudHJ5Lmxpc3RlbmVyLnN0YXJ0KGVudHJ5KTtcblx0XHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRcdFx0bGV0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2lpXTtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5zdGFydCkgbGlzdGVuZXIuc3RhcnQoZW50cnkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBFdmVudFR5cGUuaW50ZXJydXB0OlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lciAmJiBlbnRyeS5saXN0ZW5lci5pbnRlcnJ1cHQpIGVudHJ5Lmxpc3RlbmVyLmludGVycnVwdChlbnRyeSk7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IGxpc3RlbmVycy5sZW5ndGg7IGlpKyspIHtcblx0XHRcdFx0XHRcdGxldCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpaV07XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIuaW50ZXJydXB0KSBsaXN0ZW5lci5pbnRlcnJ1cHQoZW50cnkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBFdmVudFR5cGUuZW5kOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lciAmJiBlbnRyeS5saXN0ZW5lci5lbmQpIGVudHJ5Lmxpc3RlbmVyLmVuZChlbnRyeSk7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IGxpc3RlbmVycy5sZW5ndGg7IGlpKyspIHtcblx0XHRcdFx0XHRcdGxldCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpaV07XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIuZW5kKSBsaXN0ZW5lci5lbmQoZW50cnkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0Ly8gRmFsbCB0aHJvdWdoLlxuXHRcdFx0XHRjYXNlIEV2ZW50VHlwZS5kaXNwb3NlOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lciAmJiBlbnRyeS5saXN0ZW5lci5kaXNwb3NlKSBlbnRyeS5saXN0ZW5lci5kaXNwb3NlKGVudHJ5KTtcblx0XHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRcdFx0bGV0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2lpXTtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5kaXNwb3NlKSBsaXN0ZW5lci5kaXNwb3NlKGVudHJ5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5hbmltU3RhdGUudHJhY2tFbnRyeVBvb2wuZnJlZShlbnRyeSk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgRXZlbnRUeXBlLmNvbXBsZXRlOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lciAmJiBlbnRyeS5saXN0ZW5lci5jb21wbGV0ZSkgZW50cnkubGlzdGVuZXIuY29tcGxldGUoZW50cnkpO1xuXHRcdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdFx0XHRsZXQgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaWldO1xuXHRcdFx0XHRcdFx0aWYgKGxpc3RlbmVyLmNvbXBsZXRlKSBsaXN0ZW5lci5jb21wbGV0ZShlbnRyeSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIEV2ZW50VHlwZS5ldmVudDpcblx0XHRcdFx0XHRsZXQgZXZlbnQgPSBvYmplY3RzW2krKyArIDJdIGFzIEV2ZW50O1xuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lciAmJiBlbnRyeS5saXN0ZW5lci5ldmVudCkgZW50cnkubGlzdGVuZXIuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRcdFx0bGV0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2lpXTtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5ldmVudCkgbGlzdGVuZXIuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuY2xlYXIoKTtcblxuXHRcdHRoaXMuZHJhaW5EaXNhYmxlZCA9IGZhbHNlO1xuXHR9XG5cblx0Y2xlYXIgKCkge1xuXHRcdHRoaXMub2JqZWN0cy5sZW5ndGggPSAwO1xuXHR9XG59XG5cbmV4cG9ydCBlbnVtIEV2ZW50VHlwZSB7XG5cdHN0YXJ0LCBpbnRlcnJ1cHQsIGVuZCwgZGlzcG9zZSwgY29tcGxldGUsIGV2ZW50XG59XG5cbi8qKiBUaGUgaW50ZXJmYWNlIHRvIGltcGxlbWVudCBmb3IgcmVjZWl2aW5nIFRyYWNrRW50cnkgZXZlbnRzLiBJdCBpcyBhbHdheXMgc2FmZSB0byBjYWxsIEFuaW1hdGlvblN0YXRlIG1ldGhvZHMgd2hlbiByZWNlaXZpbmdcbiAqIGV2ZW50cy5cbiAqXG4gKiBTZWUgVHJhY2tFbnRyeSB7QGxpbmsgVHJhY2tFbnRyeSNsaXN0ZW5lcn0gYW5kIEFuaW1hdGlvblN0YXRlXG4gKiB7QGxpbmsgQW5pbWF0aW9uU3RhdGUjYWRkTGlzdGVuZXIoKX0uICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIge1xuXHQvKiogSW52b2tlZCB3aGVuIHRoaXMgZW50cnkgaGFzIGJlZW4gc2V0IGFzIHRoZSBjdXJyZW50IGVudHJ5LiAqL1xuXHRzdGFydD86IChlbnRyeTogVHJhY2tFbnRyeSkgPT4gdm9pZDtcblxuXHQvKiogSW52b2tlZCB3aGVuIGFub3RoZXIgZW50cnkgaGFzIHJlcGxhY2VkIHRoaXMgZW50cnkgYXMgdGhlIGN1cnJlbnQgZW50cnkuIFRoaXMgZW50cnkgbWF5IGNvbnRpbnVlIGJlaW5nIGFwcGxpZWQgZm9yXG5cdCAqIG1peGluZy4gKi9cblx0aW50ZXJydXB0PzogKGVudHJ5OiBUcmFja0VudHJ5KSA9PiB2b2lkO1xuXG5cdC8qKiBJbnZva2VkIHdoZW4gdGhpcyBlbnRyeSBpcyBubyBsb25nZXIgdGhlIGN1cnJlbnQgZW50cnkgYW5kIHdpbGwgbmV2ZXIgYmUgYXBwbGllZCBhZ2Fpbi4gKi9cblx0ZW5kPzogKGVudHJ5OiBUcmFja0VudHJ5KSA9PiB2b2lkO1xuXG5cdC8qKiBJbnZva2VkIHdoZW4gdGhpcyBlbnRyeSB3aWxsIGJlIGRpc3Bvc2VkLiBUaGlzIG1heSBvY2N1ciB3aXRob3V0IHRoZSBlbnRyeSBldmVyIGJlaW5nIHNldCBhcyB0aGUgY3VycmVudCBlbnRyeS5cblx0ICogUmVmZXJlbmNlcyB0byB0aGUgZW50cnkgc2hvdWxkIG5vdCBiZSBrZXB0IGFmdGVyIGRpc3Bvc2UgaXMgY2FsbGVkLCBhcyBpdCBtYXkgYmUgZGVzdHJveWVkIG9yIHJldXNlZC4gKi9cblx0ZGlzcG9zZT86IChlbnRyeTogVHJhY2tFbnRyeSkgPT4gdm9pZDtcblxuXHQvKiogSW52b2tlZCBldmVyeSB0aW1lIHRoaXMgZW50cnkncyBhbmltYXRpb24gY29tcGxldGVzIGEgbG9vcC4gKi9cblx0Y29tcGxldGU/OiAoZW50cnk6IFRyYWNrRW50cnkpID0+IHZvaWQ7XG5cblx0LyoqIEludm9rZWQgd2hlbiB0aGlzIGVudHJ5J3MgYW5pbWF0aW9uIHRyaWdnZXJzIGFuIGV2ZW50LiAqL1xuXHRldmVudD86IChlbnRyeTogVHJhY2tFbnRyeSwgZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQW5pbWF0aW9uU3RhdGVBZGFwdGVyIGltcGxlbWVudHMgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lciB7XG5cdHN0YXJ0IChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHR9XG5cblx0aW50ZXJydXB0IChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHR9XG5cblx0ZW5kIChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHR9XG5cblx0ZGlzcG9zZSAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0fVxuXG5cdGNvbXBsZXRlIChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHR9XG5cblx0ZXZlbnQgKGVudHJ5OiBUcmFja0VudHJ5LCBldmVudDogRXZlbnQpIHtcblx0fVxufVxuXG4vKiogMS4gQSBwcmV2aW91c2x5IGFwcGxpZWQgdGltZWxpbmUgaGFzIHNldCB0aGlzIHByb3BlcnR5LlxuICpcbiAqIFJlc3VsdDogTWl4IGZyb20gdGhlIGN1cnJlbnQgcG9zZSB0byB0aGUgdGltZWxpbmUgcG9zZS4gKi9cbmV4cG9ydCBjb25zdCBTVUJTRVFVRU5UID0gMDtcbi8qKiAxLiBUaGlzIGlzIHRoZSBmaXJzdCB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS5cbiAqIDIuIFRoZSBuZXh0IHRyYWNrIGVudHJ5IGFwcGxpZWQgYWZ0ZXIgdGhpcyBvbmUgZG9lcyBub3QgaGF2ZSBhIHRpbWVsaW5lIHRvIHNldCB0aGlzIHByb3BlcnR5LlxuICpcbiAqIFJlc3VsdDogTWl4IGZyb20gdGhlIHNldHVwIHBvc2UgdG8gdGhlIHRpbWVsaW5lIHBvc2UuICovXG5leHBvcnQgY29uc3QgRklSU1QgPSAxO1xuLyoqIDEpIEEgcHJldmlvdXNseSBhcHBsaWVkIHRpbWVsaW5lIGhhcyBzZXQgdGhpcyBwcm9wZXJ0eS48YnI+XG4gKiAyKSBUaGUgbmV4dCB0cmFjayBlbnRyeSB0byBiZSBhcHBsaWVkIGRvZXMgaGF2ZSBhIHRpbWVsaW5lIHRvIHNldCB0aGlzIHByb3BlcnR5Ljxicj5cbiAqIDMpIFRoZSBuZXh0IHRyYWNrIGVudHJ5IGFmdGVyIHRoYXQgb25lIGRvZXMgbm90IGhhdmUgYSB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS48YnI+XG4gKiBSZXN1bHQ6IE1peCBmcm9tIHRoZSBjdXJyZW50IHBvc2UgdG8gdGhlIHRpbWVsaW5lIHBvc2UsIGJ1dCBkbyBub3QgbWl4IG91dC4gVGhpcyBhdm9pZHMgXCJkaXBwaW5nXCIgd2hlbiBjcm9zc2ZhZGluZ1xuICogYW5pbWF0aW9ucyB0aGF0IGtleSB0aGUgc2FtZSBwcm9wZXJ0eS4gQSBzdWJzZXF1ZW50IHRpbWVsaW5lIHdpbGwgc2V0IHRoaXMgcHJvcGVydHkgdXNpbmcgYSBtaXguICovXG5leHBvcnQgY29uc3QgSE9MRF9TVUJTRVFVRU5UID0gMjtcbi8qKiAxKSBUaGlzIGlzIHRoZSBmaXJzdCB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS48YnI+XG4gKiAyKSBUaGUgbmV4dCB0cmFjayBlbnRyeSB0byBiZSBhcHBsaWVkIGRvZXMgaGF2ZSBhIHRpbWVsaW5lIHRvIHNldCB0aGlzIHByb3BlcnR5Ljxicj5cbiAqIDMpIFRoZSBuZXh0IHRyYWNrIGVudHJ5IGFmdGVyIHRoYXQgb25lIGRvZXMgbm90IGhhdmUgYSB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS48YnI+XG4gKiBSZXN1bHQ6IE1peCBmcm9tIHRoZSBzZXR1cCBwb3NlIHRvIHRoZSB0aW1lbGluZSBwb3NlLCBidXQgZG8gbm90IG1peCBvdXQuIFRoaXMgYXZvaWRzIFwiZGlwcGluZ1wiIHdoZW4gY3Jvc3NmYWRpbmcgYW5pbWF0aW9uc1xuICogdGhhdCBrZXkgdGhlIHNhbWUgcHJvcGVydHkuIEEgc3Vic2VxdWVudCB0aW1lbGluZSB3aWxsIHNldCB0aGlzIHByb3BlcnR5IHVzaW5nIGEgbWl4LiAqL1xuZXhwb3J0IGNvbnN0IEhPTERfRklSU1QgPSAzO1xuLyoqIDEuIFRoaXMgaXMgdGhlIGZpcnN0IHRpbWVsaW5lIHRvIHNldCB0aGlzIHByb3BlcnR5LlxuICogMi4gVGhlIG5leHQgdHJhY2sgZW50cnkgdG8gYmUgYXBwbGllZCBkb2VzIGhhdmUgYSB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS5cbiAqIDMuIFRoZSBuZXh0IHRyYWNrIGVudHJ5IGFmdGVyIHRoYXQgb25lIGRvZXMgaGF2ZSBhIHRpbWVsaW5lIHRvIHNldCB0aGlzIHByb3BlcnR5LlxuICogNC4gdGltZWxpbmVIb2xkTWl4IHN0b3JlcyB0aGUgZmlyc3Qgc3Vic2VxdWVudCB0cmFjayBlbnRyeSB0aGF0IGRvZXMgbm90IGhhdmUgYSB0aW1lbGluZSB0byBzZXQgdGhpcyBwcm9wZXJ0eS5cbiAqXG4gKiBSZXN1bHQ6IFRoZSBzYW1lIGFzIEhPTEQgZXhjZXB0IHRoZSBtaXggcGVyY2VudGFnZSBmcm9tIHRoZSB0aW1lbGluZUhvbGRNaXggdHJhY2sgZW50cnkgaXMgdXNlZC4gVGhpcyBoYW5kbGVzIHdoZW4gbW9yZSB0aGFuXG4gKiAyIHRyYWNrIGVudHJpZXMgaW4gYSByb3cgaGF2ZSBhIHRpbWVsaW5lIHRoYXQgc2V0cyB0aGUgc2FtZSBwcm9wZXJ0eS5cbiAqXG4gKiBFZywgQSAtPiBCIC0+IEMgLT4gRCB3aGVyZSBBLCBCLCBhbmQgQyBoYXZlIGEgdGltZWxpbmUgc2V0dGluZyBzYW1lIHByb3BlcnR5LCBidXQgRCBkb2VzIG5vdC4gV2hlbiBBIGlzIGFwcGxpZWQsIHRvIGF2b2lkXG4gKiBcImRpcHBpbmdcIiBBIGlzIG5vdCBtaXhlZCBvdXQsIGhvd2V2ZXIgRCAodGhlIGZpcnN0IGVudHJ5IHRoYXQgZG9lc24ndCBzZXQgdGhlIHByb3BlcnR5KSBtaXhpbmcgaW4gaXMgdXNlZCB0byBtaXggb3V0IEFcbiAqICh3aGljaCBhZmZlY3RzIEIgYW5kIEMpLiBXaXRob3V0IHVzaW5nIEQgdG8gbWl4IG91dCwgQSB3b3VsZCBiZSBhcHBsaWVkIGZ1bGx5IHVudGlsIG1peGluZyBjb21wbGV0ZXMsIHRoZW4gc25hcCBpbnRvXG4gKiBwbGFjZS4gKi9cbmV4cG9ydCBjb25zdCBIT0xEX01JWCA9IDQ7XG5cbmV4cG9ydCBjb25zdCBTRVRVUCA9IDE7XG5leHBvcnQgY29uc3QgQ1VSUkVOVCA9IDI7XG4iXX0=
1179
+ export const RETAIN = 2;
1180
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQW5pbWF0aW9uU3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLDZHQUE2RztBQUU3RyxPQUFPLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLcEosT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFHOUU7OztzSUFHc0k7QUFDdEksTUFBTSxPQUFPLGNBQWM7SUFDMUIsTUFBTSxDQUFVLGNBQWMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWpFLHVEQUF1RDtJQUN2RCxJQUFJLENBQXFCO0lBRXpCLHlIQUF5SDtJQUNoSCxNQUFNLEdBQUcsRUFBMkIsQ0FBQztJQUU5Qzs7O3dFQUdvRTtJQUNwRSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUVSLE1BQU0sR0FBRyxFQUFhLENBQUM7SUFDdkIsU0FBUyxHQUFHLEVBQThCLENBQUM7SUFDcEQsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLFdBQVcsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQzlCLGlCQUFpQixHQUFHLEtBQUssQ0FBQztJQUUxQixjQUFjLEdBQUcsSUFBSSxJQUFJLENBQWEsR0FBRyxFQUFFLENBQUMsSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBRTlELFlBQWEsSUFBd0I7UUFDcEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbEIs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QUFNLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFFNUIsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKiogYmlvbWUtaWdub3JlLWFsbCBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogcmVmZXJlbmNlIHJ1bnRpbWUgZXhwZWN0cyBzb21lIG51bGxhYmxlIHRvIG5vdCBiZSBudWxsICovXG5cbmltcG9ydCB7IEFuaW1hdGlvbiwgQXR0YWNobWVudFRpbWVsaW5lLCBEcmF3T3JkZXJGb2xkZXJUaW1lbGluZSwgRHJhd09yZGVyVGltZWxpbmUsIEV2ZW50VGltZWxpbmUsIFJvdGF0ZVRpbWVsaW5lLCBUaW1lbGluZSB9IGZyb20gXCIuL0FuaW1hdGlvbi5qc1wiO1xuaW1wb3J0IHR5cGUgeyBBbmltYXRpb25TdGF0ZURhdGEgfSBmcm9tIFwiLi9BbmltYXRpb25TdGF0ZURhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgRXZlbnQgfSBmcm9tIFwiLi9FdmVudC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNsb3QgfSBmcm9tIFwiLi9TbG90LmpzXCI7XG5pbXBvcnQgeyBJbnRlcnBvbGF0aW9uLCBNYXRoVXRpbHMsIFBvb2wsIFN0cmluZ1NldCwgVXRpbHMgfSBmcm9tIFwiLi9VdGlscy5qc1wiO1xuXG5cbi8qKiBBcHBsaWVzIGFuaW1hdGlvbnMgb3ZlciB0aW1lLCBxdWV1ZXMgYW5pbWF0aW9ucyBmb3IgbGF0ZXIgcGxheWJhY2ssIG1peGVzIChjcm9zc2ZhZGluZykgYmV0d2VlbiBhbmltYXRpb25zLCBhbmQgYXBwbGllc1xuICogbXVsdGlwbGUgYW5pbWF0aW9ucyBvbiB0b3Agb2YgZWFjaCBvdGhlciAobGF5ZXJpbmcpLlxuICpcbiAqIFNlZSBbQXBwbHlpbmcgQW5pbWF0aW9uc10oaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWFwcGx5aW5nLWFuaW1hdGlvbnMjQW5pbWF0aW9uU3RhdGUtQVBJKSBpbiB0aGUgU3BpbmUgUnVudGltZXMgR3VpZGUuICovXG5leHBvcnQgY2xhc3MgQW5pbWF0aW9uU3RhdGUge1xuXHRzdGF0aWMgcmVhZG9ubHkgZW1wdHlBbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKFwiPGVtcHR5PlwiLCBbXSwgMCk7XG5cblx0LyoqIFRoZSBBbmltYXRpb25TdGF0ZURhdGEgdG8gbG9vayB1cCBtaXggZHVyYXRpb25zLiAqL1xuXHRkYXRhOiBBbmltYXRpb25TdGF0ZURhdGE7XG5cblx0LyoqIFRoZSBsaXN0IG9mIHRyYWNrcyB0aGF0IGhhdmUgaGFkIGFuaW1hdGlvbnMuIE1heSBjb250YWluIG51bGwgZW50cmllcyBmb3IgdHJhY2tzIHRoYXQgY3VycmVudGx5IGhhdmUgbm8gYW5pbWF0aW9uLiAqL1xuXHRyZWFkb25seSB0cmFja3MgPSBbXSBhcyAoVHJhY2tFbnRyeSB8IG51bGwpW107XG5cblx0LyoqIE11bHRpcGxpZXIgZm9yIHRoZSBkZWx0YSB0aW1lIHdoZW4gdGhlIGFuaW1hdGlvbiBzdGF0ZSBpcyB1cGRhdGVkLCBjYXVzaW5nIHRpbWUgZm9yIGFsbCBhbmltYXRpb25zIGFuZCBtaXhlcyB0byBwbGF5IHNsb3dlclxuXHQgKiBvciBmYXN0ZXIuIERlZmF1bHRzIHRvIDEuXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgVHJhY2tFbnRyeS50aW1lU2NhbGV9IHRvIGFmZmVjdCBhIHNpbmdsZSBhbmltYXRpb24uICovXG5cdHRpbWVTY2FsZSA9IDE7XG5cdHVua2V5ZWRTdGF0ZSA9IDA7XG5cblx0cmVhZG9ubHkgZXZlbnRzID0gW10gYXMgRXZlbnRbXTtcblx0cmVhZG9ubHkgbGlzdGVuZXJzID0gW10gYXMgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lcltdO1xuXHRxdWV1ZSA9IG5ldyBFdmVudFF1ZXVlKHRoaXMpO1xuXHRwcm9wZXJ0eUlkcyA9IG5ldyBTdHJpbmdTZXQoKTtcblx0YW5pbWF0aW9uc0NoYW5nZWQgPSBmYWxzZTtcblxuXHR0cmFja0VudHJ5UG9vbCA9IG5ldyBQb29sPFRyYWNrRW50cnk+KCgpID0+IG5ldyBUcmFja0VudHJ5KCkpO1xuXG5cdGNvbnN0cnVjdG9yIChkYXRhOiBBbmltYXRpb25TdGF0ZURhdGEpIHtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHR9XG5cblx0LyoqIEluY3JlbWVudHMgZWFjaCB0cmFjayBlbnRyeSB7QGxpbmsgVHJhY2tFbnRyeS50cmFja1RpbWV9LCBzZXR0aW5nIHF1ZXVlZCBhbmltYXRpb25zIGFzIGN1cnJlbnQgaWYgbmVlZGVkLiAqL1xuXHR1cGRhdGUgKGRlbHRhOiBudW1iZXIpIHtcblx0XHRkZWx0YSAqPSB0aGlzLnRpbWVTY2FsZTtcblx0XHRjb25zdCB0cmFja3MgPSB0aGlzLnRyYWNrcztcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRyYWNrcy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IGN1cnJlbnQgPSB0cmFja3NbaV07XG5cdFx0XHRpZiAoIWN1cnJlbnQpIGNvbnRpbnVlO1xuXG5cdFx0XHRjdXJyZW50LmFuaW1hdGlvbkxhc3QgPSBjdXJyZW50Lm5leHRBbmltYXRpb25MYXN0O1xuXHRcdFx0Y3VycmVudC50cmFja0xhc3QgPSBjdXJyZW50Lm5leHRUcmFja0xhc3Q7XG5cblx0XHRcdGxldCBjdXJyZW50RGVsdGEgPSBkZWx0YSAqIGN1cnJlbnQudGltZVNjYWxlO1xuXG5cdFx0XHRpZiAoY3VycmVudC5kZWxheSA+IDApIHtcblx0XHRcdFx0Y3VycmVudC5kZWxheSAtPSBjdXJyZW50RGVsdGE7XG5cdFx0XHRcdGlmIChjdXJyZW50LmRlbGF5ID4gMCkgY29udGludWU7XG5cdFx0XHRcdGN1cnJlbnREZWx0YSA9IC1jdXJyZW50LmRlbGF5O1xuXHRcdFx0XHRjdXJyZW50LmRlbGF5ID0gMDtcblx0XHRcdH1cblxuXHRcdFx0bGV0IG5leHQgPSBjdXJyZW50Lm5leHQ7XG5cdFx0XHRpZiAobmV4dCkge1xuXHRcdFx0XHQvLyBXaGVuIHRoZSBuZXh0IGVudHJ5J3MgZGVsYXkgaXMgcGFzc2VkLCBjaGFuZ2UgdG8gdGhlIG5leHQgZW50cnksIHByZXNlcnZpbmcgbGVmdG92ZXIgdGltZS5cblx0XHRcdFx0Y29uc3QgbmV4dFRpbWUgPSBjdXJyZW50LnRyYWNrTGFzdCAtIG5leHQuZGVsYXk7XG5cdFx0XHRcdGlmIChuZXh0VGltZSA+PSAwKSB7XG5cdFx0XHRcdFx0bmV4dC5kZWxheSA9IDA7XG5cdFx0XHRcdFx0bmV4dC50cmFja1RpbWUgKz0gY3VycmVudC50aW1lU2NhbGUgPT09IDAgPyAwIDogKG5leHRUaW1lIC8gY3VycmVudC50aW1lU2NhbGUgKyBkZWx0YSkgKiBuZXh0LnRpbWVTY2FsZTtcblx0XHRcdFx0XHRjdXJyZW50LnRyYWNrVGltZSArPSBjdXJyZW50RGVsdGE7XG5cdFx0XHRcdFx0dGhpcy5zZXRUcmFjayhpLCBuZXh0LCB0cnVlKTtcblx0XHRcdFx0XHR3aGlsZSAobmV4dC5taXhpbmdGcm9tKSB7XG5cdFx0XHRcdFx0XHRuZXh0Lm1peFRpbWUgKz0gZGVsdGE7XG5cdFx0XHRcdFx0XHRuZXh0ID0gbmV4dC5taXhpbmdGcm9tO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmIChjdXJyZW50LnRyYWNrTGFzdCA+PSBjdXJyZW50LnRyYWNrRW5kICYmICFjdXJyZW50Lm1peGluZ0Zyb20pIHtcblx0XHRcdFx0dHJhY2tzW2ldID0gbnVsbDtcblx0XHRcdFx0dGhpcy5xdWV1ZS5lbmQoY3VycmVudCk7XG5cdFx0XHRcdHRoaXMuY2xlYXJOZXh0KGN1cnJlbnQpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGlmIChjdXJyZW50Lm1peGluZ0Zyb20gJiYgdGhpcy51cGRhdGVNaXhpbmdGcm9tKGN1cnJlbnQsIGRlbHRhKSkge1xuXHRcdFx0XHQvLyBFbmQgbWl4aW5nIGZyb20gZW50cmllcyBvbmNlIGFsbCBoYXZlIGNvbXBsZXRlZC5cblx0XHRcdFx0bGV0IGZyb206IFRyYWNrRW50cnkgfCBudWxsID0gY3VycmVudC5taXhpbmdGcm9tO1xuXHRcdFx0XHRjdXJyZW50Lm1peGluZ0Zyb20gPSBudWxsO1xuXHRcdFx0XHRpZiAoZnJvbSkgZnJvbS5taXhpbmdUbyA9IG51bGw7XG5cdFx0XHRcdHdoaWxlIChmcm9tKSB7XG5cdFx0XHRcdFx0dGhpcy5xdWV1ZS5lbmQoZnJvbSk7XG5cdFx0XHRcdFx0ZnJvbSA9IGZyb20ubWl4aW5nRnJvbTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRjdXJyZW50LnRyYWNrVGltZSArPSBjdXJyZW50RGVsdGE7XG5cdFx0fVxuXG5cdFx0dGhpcy5xdWV1ZS5kcmFpbigpO1xuXHR9XG5cblx0LyoqIFJldHVybnMgdHJ1ZSB3aGVuIGFsbCBtaXhpbmcgZnJvbSBlbnRyaWVzIGFyZSBjb21wbGV0ZS4gKi9cblx0dXBkYXRlTWl4aW5nRnJvbSAodG86IFRyYWNrRW50cnksIGRlbHRhOiBudW1iZXIpOiBib29sZWFuIHtcblx0XHRjb25zdCBmcm9tID0gdG8ubWl4aW5nRnJvbTtcblx0XHRpZiAoIWZyb20pIHJldHVybiB0cnVlO1xuXG5cdFx0Y29uc3QgZmluaXNoZWQgPSB0aGlzLnVwZGF0ZU1peGluZ0Zyb20oZnJvbSwgZGVsdGEpO1xuXG5cdFx0ZnJvbS5hbmltYXRpb25MYXN0ID0gZnJvbS5uZXh0QW5pbWF0aW9uTGFzdDtcblx0XHRmcm9tLnRyYWNrTGFzdCA9IGZyb20ubmV4dFRyYWNrTGFzdDtcblxuXHRcdC8vIFRoZSBmcm9tIGVudHJ5IHdhcyBhcHBsaWVkIGF0IGxlYXN0IG9uY2UgYW5kIHRoZSBtaXggaXMgY29tcGxldGUuXG5cdFx0aWYgKHRvLm5leHRUcmFja0xhc3QgIT09IC0xICYmIHRvLm1peFRpbWUgPj0gdG8ubWl4RHVyYXRpb24pIHtcblx0XHRcdC8vIE1peGluZyBpcyBjb21wbGV0ZSBmb3IgYWxsIGVudHJpZXMgYmVmb3JlIHRoZSBmcm9tIGVudHJ5IG9yIHRoZSBtaXggaXMgaW5zdGFudGFuZW91cy5cblx0XHRcdGlmIChmcm9tLnRvdGFsQWxwaGEgPT09IDAgfHwgdG8ubWl4RHVyYXRpb24gPT09IDApIHtcblx0XHRcdFx0dG8ubWl4aW5nRnJvbSA9IGZyb20ubWl4aW5nRnJvbTtcblx0XHRcdFx0aWYgKGZyb20ubWl4aW5nRnJvbSAhPSBudWxsKSBmcm9tLm1peGluZ0Zyb20ubWl4aW5nVG8gPSB0bztcblx0XHRcdFx0aWYgKGZyb20udG90YWxBbHBoYSA9PT0gMCkge1xuXHRcdFx0XHRcdGZvciAobGV0IG5leHQgPSB0bzsgbmV4dC5taXhpbmdUbyAhPSBudWxsOyBuZXh0ID0gbmV4dC5taXhpbmdUbylcblx0XHRcdFx0XHRcdG5leHQua2VlcEhvbGQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMucXVldWUuZW5kKGZyb20pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZpbmlzaGVkO1xuXHRcdH1cblxuXHRcdGZyb20udHJhY2tUaW1lICs9IGRlbHRhICogZnJvbS50aW1lU2NhbGU7XG5cdFx0dG8ubWl4VGltZSArPSBkZWx0YTtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKiogUG9zZXMgdGhlIHNrZWxldG9uIHVzaW5nIHRoZSB0cmFjayBlbnRyeSBhbmltYXRpb25zLiBUaGUgYW5pbWF0aW9uIHN0YXRlIGlzIG5vdCBjaGFuZ2VkLCBzbyBjYW4gYmUgYXBwbGllZCB0byBtdWx0aXBsZVxuXHQgKiBza2VsZXRvbnMgdG8gcG9zZSB0aGVtIGlkZW50aWNhbGx5LlxuXHQgKiBAcmV0dXJucyBUcnVlIGlmIGFueSBhbmltYXRpb25zIHdlcmUgYXBwbGllZC4gKi9cblx0YXBwbHkgKHNrZWxldG9uOiBTa2VsZXRvbik6IGJvb2xlYW4ge1xuXHRcdGlmICghc2tlbGV0b24pIHRocm93IG5ldyBFcnJvcihcInNrZWxldG9uIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHRpZiAodGhpcy5hbmltYXRpb25zQ2hhbmdlZCkgdGhpcy5fYW5pbWF0aW9uc0NoYW5nZWQoKTtcblxuXHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMuZXZlbnRzO1xuXHRcdGNvbnN0IHRyYWNrcyA9IHRoaXMudHJhY2tzO1xuXHRcdGxldCBhcHBsaWVkID0gZmFsc2U7XG5cblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRyYWNrcy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IGN1cnJlbnQgPSB0cmFja3NbaV07XG5cdFx0XHRpZiAoIWN1cnJlbnQgfHwgY3VycmVudC5kZWxheSA+IDApIGNvbnRpbnVlO1xuXHRcdFx0YXBwbGllZCA9IHRydWU7XG5cblx0XHRcdC8vIEFwcGx5IG1peGluZyBmcm9tIGVudHJpZXMgZmlyc3QuXG5cdFx0XHRsZXQgYWxwaGEgPSBjdXJyZW50LmFscGhhO1xuXHRcdFx0aWYgKGN1cnJlbnQubWl4aW5nRnJvbSlcblx0XHRcdFx0YWxwaGEgKj0gdGhpcy5hcHBseU1peGluZ0Zyb20oY3VycmVudCwgc2tlbGV0b24pO1xuXHRcdFx0ZWxzZSBpZiAoY3VycmVudC50cmFja1RpbWUgPj0gY3VycmVudC50cmFja0VuZCAmJiAhY3VycmVudC5uZXh0KVxuXHRcdFx0XHRhbHBoYSA9IDA7XG5cblx0XHRcdC8vIEFwcGx5IGN1cnJlbnQgZW50cnkuXG5cdFx0XHRsZXQgYW5pbWF0aW9uTGFzdCA9IGN1cnJlbnQuYW5pbWF0aW9uTGFzdCwgYW5pbWF0aW9uVGltZSA9IGN1cnJlbnQuZ2V0QW5pbWF0aW9uVGltZSgpLCBhcHBseVRpbWUgPSBhbmltYXRpb25UaW1lO1xuXHRcdFx0bGV0IGFwcGx5RXZlbnRzOiBFdmVudFtdIHwgbnVsbCA9IGV2ZW50cztcblx0XHRcdGlmIChjdXJyZW50LnJldmVyc2UpIHtcblx0XHRcdFx0YXBwbHlUaW1lID0gY3VycmVudC5hbmltYXRpb24hLmR1cmF0aW9uIC0gYXBwbHlUaW1lO1xuXHRcdFx0XHRhcHBseUV2ZW50cyA9IG51bGw7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCB0aW1lbGluZXMgPSBjdXJyZW50LmFuaW1hdGlvbiEudGltZWxpbmVzO1xuXHRcdFx0Y29uc3QgdGltZWxpbmVDb3VudCA9IHRpbWVsaW5lcy5sZW5ndGg7XG5cdFx0XHRpZiAoKGkgPT09IDAgJiYgYWxwaGEgPT09IDEpKSB7XG5cdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCB0aW1lbGluZUNvdW50OyBpaSsrKSB7XG5cdFx0XHRcdFx0Ly8gRml4ZXMgaXNzdWUgIzMwMiBvbiBJT1M5IHdoZXJlIG1peCwgYmxlbmQgc29tZXRpbWVzIGJlY2FtZSB1bmRlZmluZWQgYW5kIGNhdXNlZCBhc3NldHNcblx0XHRcdFx0XHQvLyB0byBzb21ldGltZXMgc3RvcCByZW5kZXJpbmcgd2hlbiB1c2luZyBjb2xvciBjb3JyZWN0aW9uLCBhcyB0aGVpciBSR0JBIHZhbHVlcyBiZWNvbWUgTmFOLlxuXHRcdFx0XHRcdC8vIChodHRwczovL2dpdGh1Yi5jb20vcGl4aWpzL3BpeGktc3BpbmUvaXNzdWVzLzMwMilcblx0XHRcdFx0XHRVdGlscy53ZWJraXQ2MDJCdWdmaXhIZWxwZXIoYWxwaGEpO1xuXHRcdFx0XHRcdGNvbnN0IHRpbWVsaW5lID0gdGltZWxpbmVzW2lpXTtcblx0XHRcdFx0XHRpZiAodGltZWxpbmUgaW5zdGFuY2VvZiBBdHRhY2htZW50VGltZWxpbmUpXG5cdFx0XHRcdFx0XHR0aGlzLmFwcGx5QXR0YWNobWVudFRpbWVsaW5lKHRpbWVsaW5lLCBza2VsZXRvbiwgYXBwbHlUaW1lLCB0cnVlLCB0cnVlKTtcblx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHR0aW1lbGluZS5hcHBseShza2VsZXRvbiwgYW5pbWF0aW9uTGFzdCwgYXBwbHlUaW1lLCBhcHBseUV2ZW50cywgYWxwaGEsIHRydWUsIGZhbHNlLCBmYWxzZSwgZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCB0aW1lbGluZU1vZGUgPSBjdXJyZW50LnRpbWVsaW5lTW9kZTtcblx0XHRcdFx0Y29uc3QgcmV0YWluQXR0YWNobWVudHMgPSBhbHBoYSA+PSBjdXJyZW50LmFscGhhQXR0YWNobWVudFRocmVzaG9sZDtcblx0XHRcdFx0Y29uc3QgYWRkID0gY3VycmVudC5hZGRpdGl2ZSwgc2hvcnRlc3RSb3RhdGlvbiA9IGFkZCB8fCBjdXJyZW50LnNob3J0ZXN0Um90YXRpb247XG5cdFx0XHRcdGNvbnN0IGZpcnN0RnJhbWUgPSAhc2hvcnRlc3RSb3RhdGlvbiAmJiBjdXJyZW50LnRpbWVsaW5lc1JvdGF0aW9uLmxlbmd0aCAhPT0gdGltZWxpbmVDb3VudCA8PCAxO1xuXHRcdFx0XHRpZiAoZmlyc3RGcmFtZSkgY3VycmVudC50aW1lbGluZXNSb3RhdGlvbi5sZW5ndGggPSB0aW1lbGluZUNvdW50IDw8IDE7XG5cblx0XHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IHRpbWVsaW5lQ291bnQ7IGlpKyspIHtcblx0XHRcdFx0XHRjb25zdCB0aW1lbGluZSA9IHRpbWVsaW5lc1tpaV07XG5cdFx0XHRcdFx0Y29uc3QgZnJvbVNldHVwID0gKHRpbWVsaW5lTW9kZVtpaV0gJiBGSVJTVCkgIT09IDA7XG5cdFx0XHRcdFx0aWYgKCFzaG9ydGVzdFJvdGF0aW9uICYmIHRpbWVsaW5lIGluc3RhbmNlb2YgUm90YXRlVGltZWxpbmUpIHtcblx0XHRcdFx0XHRcdHRoaXMuYXBwbHlSb3RhdGVUaW1lbGluZSh0aW1lbGluZSwgc2tlbGV0b24sIGFwcGx5VGltZSwgYWxwaGEsIGZyb21TZXR1cCwgY3VycmVudC50aW1lbGluZXNSb3RhdGlvbiwgaWkgPDwgMSwgZmlyc3RGcmFtZSk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aW1lbGluZSBpbnN0YW5jZW9mIEF0dGFjaG1lbnRUaW1lbGluZSkge1xuXHRcdFx0XHRcdFx0dGhpcy5hcHBseUF0dGFjaG1lbnRUaW1lbGluZSh0aW1lbGluZSwgc2tlbGV0b24sIGFwcGx5VGltZSwgZnJvbVNldHVwLCByZXRhaW5BdHRhY2htZW50cyk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIFRoaXMgZml4ZXMgdGhlIFdlYktpdCA2MDIgc3BlY2lmaWMgaXNzdWUgZGVzY3JpYmVkIGF0IGh0dHBzOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vZm9ydW0vZC8xMDEwOS1pb3MtMTAtZGlzYXBwZWFyaW5nLWdyYXBoaWNzXG5cdFx0XHRcdFx0XHRVdGlscy53ZWJraXQ2MDJCdWdmaXhIZWxwZXIoYWxwaGEpO1xuXHRcdFx0XHRcdFx0dGltZWxpbmUuYXBwbHkoc2tlbGV0b24sIGFuaW1hdGlvbkxhc3QsIGFwcGx5VGltZSwgYXBwbHlFdmVudHMsIGFscGhhLCBmcm9tU2V0dXAsIGFkZCwgZmFsc2UsIGZhbHNlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChjdXJyZW50LnJldmVyc2UpIHRoaXMuZXZlbnRzUmV2ZXJzZShjdXJyZW50LCBhbmltYXRpb25MYXN0LCBhbmltYXRpb25UaW1lKTtcblx0XHRcdHRoaXMucXVldWVFdmVudHMoY3VycmVudCwgYW5pbWF0aW9uVGltZSk7XG5cdFx0XHRldmVudHMubGVuZ3RoID0gMDtcblx0XHRcdGN1cnJlbnQubmV4dEFuaW1hdGlvbkxhc3QgPSBhbmltYXRpb25UaW1lO1xuXHRcdFx0Y3VycmVudC5uZXh0VHJhY2tMYXN0ID0gY3VycmVudC50cmFja1RpbWU7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHNsb3QgYXR0YWNobWVudHMgdG8gdGhlIHNldHVwIHBvc2UgaWYgdGhleSB3ZXJlIHNldCB0ZW1wb3JhcmlseSB0byBhcHBseSBkZWZvcm0gdGltZWxpbmVzLlxuXHRcdGNvbnN0IHNldHVwU3RhdGUgPSB0aGlzLnVua2V5ZWRTdGF0ZSArIFNFVFVQO1xuXHRcdGNvbnN0IHNsb3RzID0gc2tlbGV0b24uc2xvdHM7XG5cdFx0Zm9yIChsZXQgaSA9IDAsIG4gPSBza2VsZXRvbi5zbG90cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IHNsb3QgPSBzbG90c1tpXTtcblx0XHRcdGlmIChzbG90LmF0dGFjaG1lbnRTdGF0ZSA9PT0gc2V0dXBTdGF0ZSkge1xuXHRcdFx0XHRjb25zdCBhdHRhY2htZW50TmFtZSA9IHNsb3QuZGF0YS5hdHRhY2htZW50TmFtZTtcblx0XHRcdFx0c2xvdC5wb3NlLnNldEF0dGFjaG1lbnQoIWF0dGFjaG1lbnROYW1lID8gbnVsbCA6IHNrZWxldG9uLmdldEF0dGFjaG1lbnQoc2xvdC5kYXRhLmluZGV4LCBhdHRhY2htZW50TmFtZSkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnVua2V5ZWRTdGF0ZSArPSAyOyAvLyBSZXNldC5cblxuXHRcdHRoaXMucXVldWUuZHJhaW4oKTtcblx0XHRyZXR1cm4gYXBwbGllZDtcblx0fVxuXG5cdGFwcGx5TWl4aW5nRnJvbSAodG86IFRyYWNrRW50cnksIHNrZWxldG9uOiBTa2VsZXRvbikge1xuXHRcdGNvbnN0IGZyb20gPSB0by5taXhpbmdGcm9tITtcblx0XHRjb25zdCBmcm9tTWl4ID0gZnJvbS5taXhpbmdGcm9tICE9PSBudWxsID8gdGhpcy5hcHBseU1peGluZ0Zyb20oZnJvbSwgc2tlbGV0b24pIDogMTtcblx0XHRjb25zdCBtaXggPSB0by5taXgoKTtcblxuXHRcdGNvbnN0IGEgPSBmcm9tLmFscGhhICogZnJvbU1peCwga2VlcCA9IDEgLSBtaXggKiB0by5hbHBoYTtcblx0XHRjb25zdCBhbHBoYU1peCA9IGEgKiAoMSAtIG1peCksIGFscGhhSG9sZCA9IGtlZXAgPiAwID8gYWxwaGFNaXggLyBrZWVwIDogYTtcblxuXHRcdGNvbnN0IHRpbWVsaW5lcyA9IGZyb20uYW5pbWF0aW9uIS50aW1lbGluZXM7XG5cdFx0Y29uc3QgdGltZWxpbmVDb3VudCA9IHRpbWVsaW5lcy5sZW5ndGg7XG5cdFx0Y29uc3QgdGltZWxpbmVNb2RlID0gZnJvbS50aW1lbGluZU1vZGU7XG5cdFx0Y29uc3QgdGltZWxpbmVIb2xkTWl4ID0gZnJvbS50aW1lbGluZUhvbGRNaXg7XG5cblx0XHRjb25zdCByZXRhaW5BdHRhY2htZW50cyA9IG1peCA8IGZyb20ubWl4QXR0YWNobWVudFRocmVzaG9sZCwgZHJhd09yZGVyID0gbWl4IDwgZnJvbS5taXhEcmF3T3JkZXJUaHJlc2hvbGQ7XG5cdFx0Y29uc3QgYWRkID0gZnJvbS5hZGRpdGl2ZSwgc2hvcnRlc3RSb3RhdGlvbiA9IGFkZCB8fCBmcm9tLnNob3J0ZXN0Um90YXRpb247XG5cdFx0Y29uc3QgZmlyc3RGcmFtZSA9ICFzaG9ydGVzdFJvdGF0aW9uICYmIGZyb20udGltZWxpbmVzUm90YXRpb24ubGVuZ3RoICE9PSB0aW1lbGluZUNvdW50IDw8IDE7XG5cdFx0aWYgKGZpcnN0RnJhbWUpIGZyb20udGltZWxpbmVzUm90YXRpb24ubGVuZ3RoID0gdGltZWxpbmVDb3VudCA8PCAxO1xuXHRcdGNvbnN0IHRpbWVsaW5lc1JvdGF0aW9uID0gZnJvbS50aW1lbGluZXNSb3RhdGlvbjtcblxuXHRcdGxldCBhbmltYXRpb25MYXN0ID0gZnJvbS5hbmltYXRpb25MYXN0LCBhbmltYXRpb25UaW1lID0gZnJvbS5nZXRBbmltYXRpb25UaW1lKCksIGFwcGx5VGltZSA9IGFuaW1hdGlvblRpbWU7XG5cdFx0bGV0IGV2ZW50cyA9IG51bGw7XG5cdFx0aWYgKGZyb20ucmV2ZXJzZSlcblx0XHRcdGFwcGx5VGltZSA9IGZyb20uYW5pbWF0aW9uIS5kdXJhdGlvbiAtIGFwcGx5VGltZTtcblx0XHRlbHNlIGlmIChtaXggPCBmcm9tLmV2ZW50VGhyZXNob2xkKSAvL1xuXHRcdFx0ZXZlbnRzID0gdGhpcy5ldmVudHM7XG5cblx0XHRmcm9tLnRvdGFsQWxwaGEgPSAwO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aW1lbGluZUNvdW50OyBpKyspIHtcblx0XHRcdGNvbnN0IHRpbWVsaW5lID0gdGltZWxpbmVzW2ldO1xuXHRcdFx0Y29uc3QgbW9kZSA9IHRpbWVsaW5lTW9kZVtpXTtcblx0XHRcdGxldCBhbHBoYSA9IDA7XG5cdFx0XHRpZiAoKG1vZGUgJiBIT0xEKSAhPT0gMCkge1xuXHRcdFx0XHRjb25zdCBob2xkTWl4ID0gdGltZWxpbmVIb2xkTWl4W2ldO1xuXHRcdFx0XHRhbHBoYSA9IGhvbGRNaXggPT0gbnVsbCA/IGFscGhhSG9sZCA6IGFscGhhSG9sZCAqICgxIC0gaG9sZE1peC5taXgoKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIWRyYXdPcmRlciAmJiB0aW1lbGluZSBpbnN0YW5jZW9mIERyYXdPcmRlclRpbWVsaW5lKSBjb250aW51ZTtcblx0XHRcdFx0YWxwaGEgPSBhbHBoYU1peDtcblx0XHRcdH1cblx0XHRcdGZyb20udG90YWxBbHBoYSArPSBhbHBoYTtcblx0XHRcdGNvbnN0IGZyb21TZXR1cCA9IChtb2RlICYgRklSU1QpICE9PSAwO1xuXHRcdFx0aWYgKCFzaG9ydGVzdFJvdGF0aW9uICYmIHRpbWVsaW5lIGluc3RhbmNlb2YgUm90YXRlVGltZWxpbmUpIHtcblx0XHRcdFx0dGhpcy5hcHBseVJvdGF0ZVRpbWVsaW5lKHRpbWVsaW5lLCBza2VsZXRvbiwgYXBwbHlUaW1lLCBhbHBoYSwgZnJvbVNldHVwLCB0aW1lbGluZXNSb3RhdGlvbiwgaSA8PCAxLCBmaXJzdEZyYW1lKTtcblx0XHRcdH0gZWxzZSBpZiAodGltZWxpbmUgaW5zdGFuY2VvZiBBdHRhY2htZW50VGltZWxpbmUpXG5cdFx0XHRcdHRoaXMuYXBwbHlBdHRhY2htZW50VGltZWxpbmUodGltZWxpbmUsIHNrZWxldG9uLCBhcHBseVRpbWUsIGZyb21TZXR1cCxcblx0XHRcdFx0XHRyZXRhaW5BdHRhY2htZW50cyAmJiBhbHBoYSA+PSBmcm9tLmFscGhhQXR0YWNobWVudFRocmVzaG9sZCk7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0Y29uc3Qgb3V0ID0gIWRyYXdPcmRlciB8fCAhKHRpbWVsaW5lIGluc3RhbmNlb2YgRHJhd09yZGVyVGltZWxpbmUpIHx8ICFmcm9tU2V0dXA7XG5cdFx0XHRcdHRpbWVsaW5lLmFwcGx5KHNrZWxldG9uLCBhbmltYXRpb25MYXN0LCBhcHBseVRpbWUsIGV2ZW50cywgYWxwaGEsIGZyb21TZXR1cCwgYWRkLCBvdXQsIGZhbHNlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZnJvbS5yZXZlcnNlICYmIG1peCA8IGZyb20uZXZlbnRUaHJlc2hvbGQpIHRoaXMuZXZlbnRzUmV2ZXJzZShmcm9tLCBhbmltYXRpb25MYXN0LCBhbmltYXRpb25UaW1lKTtcblx0XHRpZiAodG8ubWl4RHVyYXRpb24gPiAwKSB0aGlzLnF1ZXVlRXZlbnRzKGZyb20sIGFuaW1hdGlvblRpbWUpO1xuXHRcdHRoaXMuZXZlbnRzLmxlbmd0aCA9IDA7XG5cblx0XHRmcm9tLm5leHRBbmltYXRpb25MYXN0ID0gYW5pbWF0aW9uVGltZTtcblx0XHRmcm9tLm5leHRUcmFja0xhc3QgPSBmcm9tLnRyYWNrVGltZTtcblx0XHRyZXR1cm4gbWl4O1xuXHR9XG5cblx0LyoqIEFwcGxpZXMgdGhlIGF0dGFjaG1lbnQgdGltZWxpbmUgYW5kIHNldHMge0BsaW5rIFNsb3QuYXR0YWNobWVudFN0YXRlfS5cblx0ICogQHBhcmFtIHJldGFpbiBUcnVlIGlmIHRoZSBhdHRhY2htZW50IHJlbWFpbnMgYWZ0ZXIgYXBwbHksIGZhbHNlIGlmIHRlbXBvcmFyeSBmb3IgZGVmb3JtIHRpbWVsaW5lcy4gKi9cblx0YXBwbHlBdHRhY2htZW50VGltZWxpbmUgKHRpbWVsaW5lOiBBdHRhY2htZW50VGltZWxpbmUsIHNrZWxldG9uOiBTa2VsZXRvbiwgdGltZTogbnVtYmVyLCBmcm9tU2V0dXA6IGJvb2xlYW4sIHJldGFpbjogYm9vbGVhbikge1xuXHRcdGNvbnN0IHNsb3QgPSBza2VsZXRvbi5zbG90c1t0aW1lbGluZS5zbG90SW5kZXhdO1xuXHRcdGlmICghc2xvdC5ib25lLmFjdGl2ZSkgcmV0dXJuO1xuXHRcdGlmICghcmV0YWluICYmIHNsb3QuYXR0YWNobWVudFN0YXRlID09PSB0aGlzLnVua2V5ZWRTdGF0ZSArIFJFVEFJTikgcmV0dXJuO1xuXG5cdFx0bGV0IHNldHVwID0gdGltZSA8IHRpbWVsaW5lLmZyYW1lc1swXTtcblx0XHRsZXQgbmFtZSA9IG51bGw7XG5cdFx0aWYgKCFzZXR1cCkge1xuXHRcdFx0bmFtZSA9IHRpbWVsaW5lLmF0dGFjaG1lbnROYW1lc1tUaW1lbGluZS5zZWFyY2godGltZWxpbmUuZnJhbWVzLCB0aW1lKV07XG5cdFx0XHRzZXR1cCA9ICFyZXRhaW4gJiYgbmFtZSA9PSBudWxsO1xuXHRcdH1cblx0XHRpZiAoc2V0dXApIHtcblx0XHRcdGlmICghZnJvbVNldHVwKSByZXR1cm47XG5cdFx0XHRuYW1lID0gc2xvdC5kYXRhLmF0dGFjaG1lbnROYW1lO1xuXHRcdH1cblx0XHRzbG90LnBvc2Uuc2V0QXR0YWNobWVudChuYW1lID09IG51bGwgPyBudWxsIDogc2tlbGV0b24uZ2V0QXR0YWNobWVudChzbG90LmRhdGEuaW5kZXgsIG5hbWUpKTtcblx0XHRpZiAocmV0YWluKVxuXHRcdFx0c2xvdC5hdHRhY2htZW50U3RhdGUgPSB0aGlzLnVua2V5ZWRTdGF0ZSArIFJFVEFJTjtcblx0XHRlbHNlIGlmICghc2V0dXApIC8vXG5cdFx0XHRzbG90LmF0dGFjaG1lbnRTdGF0ZSA9IHRoaXMudW5rZXllZFN0YXRlICsgU0VUVVA7XG5cdH1cblxuXHQvKiogQXBwbGllcyB0aGUgcm90YXRlIHRpbWVsaW5lLCBtaXhpbmcgd2l0aCB0aGUgY3VycmVudCBwb3NlIHdoaWxlIGtlZXBpbmcgdGhlIHNhbWUgcm90YXRpb24gZGlyZWN0aW9uIGNob3NlbiBhcyB0aGUgc2hvcnRlc3Rcblx0ICogdGhlIGZpcnN0IHRpbWUgdGhlIG1peGluZyB3YXMgYXBwbGllZC4gKi9cblx0YXBwbHlSb3RhdGVUaW1lbGluZSAodGltZWxpbmU6IFJvdGF0ZVRpbWVsaW5lLCBza2VsZXRvbjogU2tlbGV0b24sIHRpbWU6IG51bWJlciwgYWxwaGE6IG51bWJlciwgZnJvbVNldHVwOiBib29sZWFuLFxuXHRcdHRpbWVsaW5lc1JvdGF0aW9uOiBBcnJheTxudW1iZXI+LCBpOiBudW1iZXIsIGZpcnN0RnJhbWU6IGJvb2xlYW4pIHtcblxuXHRcdGlmIChmaXJzdEZyYW1lKSB0aW1lbGluZXNSb3RhdGlvbltpXSA9IDA7XG5cblx0XHRpZiAoYWxwaGEgPT09IDEpIHtcblx0XHRcdHRpbWVsaW5lLmFwcGx5KHNrZWxldG9uLCAwLCB0aW1lLCBudWxsLCAxLCBmcm9tU2V0dXAsIGZhbHNlLCBmYWxzZSwgZmFsc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGJvbmUgPSBza2VsZXRvbi5ib25lc1t0aW1lbGluZS5ib25lSW5kZXhdO1xuXHRcdGlmICghYm9uZS5hY3RpdmUpIHJldHVybjtcblx0XHRjb25zdCBwb3NlID0gYm9uZS5wb3NlLCBzZXR1cCA9IGJvbmUuZGF0YS5zZXR1cFBvc2U7XG5cdFx0Y29uc3QgZnJhbWVzID0gdGltZWxpbmUuZnJhbWVzO1xuXHRcdGlmICh0aW1lIDwgZnJhbWVzWzBdKSB7IC8vIFRpbWUgaXMgYmVmb3JlIGZpcnN0IGZyYW1lLlxuXHRcdFx0aWYgKGZyb21TZXR1cCkgcG9zZS5yb3RhdGlvbiA9IHNldHVwLnJvdGF0aW9uO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRjb25zdCByMSA9IGZyb21TZXR1cCA/IHNldHVwLnJvdGF0aW9uIDogcG9zZS5yb3RhdGlvbjtcblx0XHRjb25zdCByMiA9IHNldHVwLnJvdGF0aW9uICsgdGltZWxpbmUuZ2V0Q3VydmVWYWx1ZSh0aW1lKTtcblxuXHRcdC8vIE1peCBiZXR3ZWVuIHJvdGF0aW9ucyB1c2luZyB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzaG9ydGVzdCByb3V0ZSBvbiB0aGUgZmlyc3QgZnJhbWUgd2hpbGUgZGV0ZWN0aW5nIGNyb3NzZXMuXG5cdFx0bGV0IHRvdGFsID0gMCwgZGlmZiA9IHIyIC0gcjE7XG5cdFx0ZGlmZiAtPSBNYXRoLmNlaWwoZGlmZiAvIDM2MCAtIDAuNSkgKiAzNjA7XG5cdFx0aWYgKGRpZmYgPT09IDApIHtcblx0XHRcdHRvdGFsID0gdGltZWxpbmVzUm90YXRpb25baV07XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBsYXN0VG90YWwgPSAwLCBsYXN0RGlmZiA9IDA7XG5cdFx0XHRpZiAoZmlyc3RGcmFtZSkge1xuXHRcdFx0XHRsYXN0VG90YWwgPSAwO1xuXHRcdFx0XHRsYXN0RGlmZiA9IGRpZmY7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsYXN0VG90YWwgPSB0aW1lbGluZXNSb3RhdGlvbltpXTtcblx0XHRcdFx0bGFzdERpZmYgPSB0aW1lbGluZXNSb3RhdGlvbltpICsgMV07XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBsb29wcyA9IGxhc3RUb3RhbCAtIGxhc3RUb3RhbCAlIDM2MDtcblx0XHRcdHRvdGFsID0gZGlmZiArIGxvb3BzO1xuXHRcdFx0bGV0IGN1cnJlbnQgPSBkaWZmID49IDAsIGRpciA9IGxhc3RUb3RhbCA+PSAwO1xuXHRcdFx0aWYgKE1hdGguYWJzKGxhc3REaWZmKSA8PSA5MCAmJiBNYXRoVXRpbHMuc2lnbnVtKGxhc3REaWZmKSAhPT0gTWF0aFV0aWxzLnNpZ251bShkaWZmKSkge1xuXHRcdFx0XHRpZiAoTWF0aC5hYnMobGFzdFRvdGFsIC0gbG9vcHMpID4gMTgwKSB7XG5cdFx0XHRcdFx0dG90YWwgKz0gMzYwICogTWF0aFV0aWxzLnNpZ251bShsYXN0VG90YWwpO1xuXHRcdFx0XHRcdGRpciA9IGN1cnJlbnQ7XG5cdFx0XHRcdH0gZWxzZSBpZiAobG9vcHMgIT09IDApXG5cdFx0XHRcdFx0dG90YWwgLT0gMzYwICogTWF0aFV0aWxzLnNpZ251bShsYXN0VG90YWwpO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0ZGlyID0gY3VycmVudDtcblx0XHRcdH1cblx0XHRcdGlmIChkaXIgIT09IGN1cnJlbnQpIHRvdGFsICs9IDM2MCAqIE1hdGhVdGlscy5zaWdudW0obGFzdFRvdGFsKTtcblx0XHRcdHRpbWVsaW5lc1JvdGF0aW9uW2ldID0gdG90YWw7XG5cdFx0fVxuXHRcdHRpbWVsaW5lc1JvdGF0aW9uW2kgKyAxXSA9IGRpZmY7XG5cdFx0cG9zZS5yb3RhdGlvbiA9IHIxICsgdG90YWwgKiBhbHBoYTtcblx0fVxuXG5cdHF1ZXVlRXZlbnRzIChlbnRyeTogVHJhY2tFbnRyeSwgYW5pbWF0aW9uVGltZTogbnVtYmVyKSB7XG5cdFx0Y29uc3QgYW5pbWF0aW9uU3RhcnQgPSBlbnRyeS5hbmltYXRpb25TdGFydCwgYW5pbWF0aW9uRW5kID0gZW50cnkuYW5pbWF0aW9uRW5kLCBkdXJhdGlvbiA9IGFuaW1hdGlvbkVuZCAtIGFuaW1hdGlvblN0YXJ0O1xuXHRcdGNvbnN0IHJldmVyc2UgPSBlbnRyeS5yZXZlcnNlO1xuXHRcdGxldCBzcGxpdCA9IGVudHJ5LnRyYWNrTGFzdCAlIGR1cmF0aW9uO1xuXHRcdGlmIChyZXZlcnNlKSBzcGxpdCA9IGR1cmF0aW9uIC0gc3BsaXQ7XG5cblx0XHQvLyBRdWV1ZSBldmVudHMgYmVmb3JlIGNvbXBsZXRlLlxuXHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMuZXZlbnRzO1xuXHRcdGxldCBpID0gMCwgbiA9IGV2ZW50cy5sZW5ndGg7XG5cdFx0Zm9yICg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IGV2ZW50ID0gZXZlbnRzW2ldO1xuXHRcdFx0aWYgKChldmVudC50aW1lIDwgc3BsaXQpICE9PSByZXZlcnNlKSBicmVhazsgLy8gamF2YTogaWYgKGV2ZW50LnRpbWUgPCBzcGxpdCBeIHJldmVyc2UpIGJyZWFrO1xuXHRcdFx0aWYgKGV2ZW50LnRpbWUgPj0gYW5pbWF0aW9uU3RhcnQgJiYgZXZlbnQudGltZSA8PSBhbmltYXRpb25FbmQpIHRoaXMucXVldWUuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHR9XG5cblx0XHQvLyBRdWV1ZSBjb21wbGV0ZSBpZiBjb21wbGV0ZWQgYSBsb29wIGl0ZXJhdGlvbiBvciB0aGUgYW5pbWF0aW9uLlxuXHRcdGxldCBjb21wbGV0ZSA9IGZhbHNlO1xuXHRcdGlmIChlbnRyeS5sb29wKSB7XG5cdFx0XHRpZiAoZHVyYXRpb24gPT09IDApXG5cdFx0XHRcdGNvbXBsZXRlID0gdHJ1ZTtcblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRjb25zdCBjeWNsZXMgPSBNYXRoLmZsb29yKGVudHJ5LnRyYWNrVGltZSAvIGR1cmF0aW9uKTtcblx0XHRcdFx0Y29tcGxldGUgPSBjeWNsZXMgPiAwICYmIGN5Y2xlcyA+IE1hdGguZmxvb3IoZW50cnkudHJhY2tMYXN0IC8gZHVyYXRpb24pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZVxuXHRcdFx0Y29tcGxldGUgPSBhbmltYXRpb25UaW1lID49IGFuaW1hdGlvbkVuZCAmJiBlbnRyeS5hbmltYXRpb25MYXN0IDwgYW5pbWF0aW9uRW5kO1xuXHRcdGlmIChjb21wbGV0ZSkgdGhpcy5xdWV1ZS5jb21wbGV0ZShlbnRyeSk7XG5cblx0XHQvLyBRdWV1ZSBldmVudHMgYWZ0ZXIgY29tcGxldGUuXG5cdFx0Zm9yICg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IGV2ZW50ID0gZXZlbnRzW2ldO1xuXHRcdFx0aWYgKGV2ZW50LnRpbWUgPj0gYW5pbWF0aW9uU3RhcnQgJiYgZXZlbnQudGltZSA8PSBhbmltYXRpb25FbmQpIHRoaXMucXVldWUuZXZlbnQoZW50cnksIGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGV2ZW50c1JldmVyc2UgKGVudHJ5OiBUcmFja0VudHJ5LCBhbmltYXRpb25MYXN0OiBudW1iZXIsIGFuaW1hdGlvblRpbWU6IG51bWJlcikge1xuXHRcdGNvbnN0IGR1cmF0aW9uID0gZW50cnkuYW5pbWF0aW9uIS5kdXJhdGlvbiwgZnJvbSA9IGR1cmF0aW9uIC0gYW5pbWF0aW9uTGFzdCwgdG8gPSBkdXJhdGlvbiAtIGFuaW1hdGlvblRpbWU7XG5cdFx0Y29uc3QgdGltZWxpbmVzID0gZW50cnkuYW5pbWF0aW9uIS50aW1lbGluZXM7XG5cdFx0Zm9yIChsZXQgaSA9IDAsIG4gPSBlbnRyeS5hbmltYXRpb24hLnRpbWVsaW5lcy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGNvbnN0IGV2ZW50VGltZWxpbmUgPSB0aW1lbGluZXNbaV07XG5cdFx0XHRpZiAoIShldmVudFRpbWVsaW5lIGluc3RhbmNlb2YgRXZlbnRUaW1lbGluZSkpIGNvbnRpbnVlO1xuXHRcdFx0Y29uc3QgdGltZWxpbmVFdmVudHMgPSBldmVudFRpbWVsaW5lLmV2ZW50cztcblx0XHRcdGNvbnN0IGZyYW1lcyA9IGV2ZW50VGltZWxpbmUuZnJhbWVzO1xuXHRcdFx0Y29uc3QgZnJhbWVDb3VudCA9IGZyYW1lcy5sZW5ndGg7XG5cdFx0XHRpZiAoZnJvbSA+PSB0bykgeyAvLyBmcm9tIC0+IHRvXG5cdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCBmcmFtZUNvdW50OyBpaSsrKSB7XG5cdFx0XHRcdFx0aWYgKGZyYW1lc1tpaV0gPCB0bykgY29udGludWU7XG5cdFx0XHRcdFx0aWYgKGZyYW1lc1tpaV0gPj0gZnJvbSkgYnJlYWs7XG5cdFx0XHRcdFx0dGhpcy5ldmVudHMucHVzaCh0aW1lbGluZUV2ZW50c1tpaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgZnJhbWVDb3VudDsgaWkrKykgeyAvLyBmcm9tIC0+IDBcblx0XHRcdFx0XHRpZiAoZnJhbWVzW2lpXSA+PSBmcm9tKSBicmVhaztcblx0XHRcdFx0XHR0aGlzLmV2ZW50cy5wdXNoKHRpbWVsaW5lRXZlbnRzW2lpXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bGV0IGlpID0gMDsgLy8gZW5kIC0+IHRvXG5cdFx0XHRcdGZvciAoOyBpaSA8IGZyYW1lQ291bnQ7IGlpKyspXG5cdFx0XHRcdFx0aWYgKGZyYW1lc1tpaV0gPj0gdG8pIGJyZWFrO1xuXHRcdFx0XHRmb3IgKDsgaWkgPCBmcmFtZUNvdW50OyBpaSsrKVxuXHRcdFx0XHRcdHRoaXMuZXZlbnRzLnB1c2godGltZWxpbmVFdmVudHNbaWldKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKiogUmVtb3ZlcyBhbGwgYW5pbWF0aW9ucyBmcm9tIGFsbCB0cmFja3MsIGxlYXZpbmcgc2tlbGV0b25zIGluIHRoZWlyIGN1cnJlbnQgcG9zZS5cblx0ICpcblx0ICogVXN1YWxseSB5b3Ugd2FudCB0byB1c2Uge0BsaW5rIHNldEVtcHR5QW5pbWF0aW9uc30gdG8gbWl4IHRoZSBza2VsZXRvbnMgYmFjayB0byB0aGUgc2V0dXAgcG9zZSwgcmF0aGVyIHRoYW4gbGVhdmluZ1xuXHQgKiB0aGVtIGluIHRoZWlyIGN1cnJlbnQgcG9zZS4gKi9cblx0Y2xlYXJUcmFja3MgKCkge1xuXHRcdGNvbnN0IG9sZERyYWluRGlzYWJsZWQgPSB0aGlzLnF1ZXVlLmRyYWluRGlzYWJsZWQ7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbkRpc2FibGVkID0gdHJ1ZTtcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRoaXMudHJhY2tzLmxlbmd0aDsgaSA8IG47IGkrKylcblx0XHRcdHRoaXMuY2xlYXJUcmFjayhpKTtcblx0XHR0aGlzLnRyYWNrcy5sZW5ndGggPSAwO1xuXHRcdHRoaXMucXVldWUuZHJhaW5EaXNhYmxlZCA9IG9sZERyYWluRGlzYWJsZWQ7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbigpO1xuXHR9XG5cblx0LyoqIFJlbW92ZXMgYWxsIGFuaW1hdGlvbnMgZnJvbSB0aGUgdHJhY2ssIGxlYXZpbmcgc2tlbGV0b25zIGluIHRoZWlyIGN1cnJlbnQgcG9zZS5cblx0ICpcblx0ICogVXN1YWxseSB5b3Ugd2FudCB0byB1c2Uge0BsaW5rIHNldEVtcHR5QW5pbWF0aW9ufSB0byBtaXggdGhlIHNrZWxldG9ucyBiYWNrIHRvIHRoZSBzZXR1cCBwb3NlLCByYXRoZXIgdGhhblxuXHQgKiBsZWF2aW5nIHRoZW0gaW4gdGhlaXIgY3VycmVudCBwb3NlLiAqL1xuXHRjbGVhclRyYWNrICh0cmFja0luZGV4OiBudW1iZXIpIHtcblx0XHRpZiAodHJhY2tJbmRleCA8IDApIHRocm93IG5ldyBFcnJvcihcInRyYWNrSW5kZXggbXVzdCBiZSA+PSAwLlwiKTtcblx0XHRpZiAodHJhY2tJbmRleCA+PSB0aGlzLnRyYWNrcy5sZW5ndGgpIHJldHVybjtcblx0XHRjb25zdCBjdXJyZW50ID0gdGhpcy50cmFja3NbdHJhY2tJbmRleF07XG5cdFx0aWYgKCFjdXJyZW50KSByZXR1cm47XG5cblx0XHR0aGlzLnF1ZXVlLmVuZChjdXJyZW50KTtcblxuXHRcdHRoaXMuY2xlYXJOZXh0KGN1cnJlbnQpO1xuXG5cdFx0bGV0IGVudHJ5ID0gY3VycmVudDtcblx0XHR3aGlsZSAodHJ1ZSkge1xuXHRcdFx0Y29uc3QgZnJvbSA9IGVudHJ5Lm1peGluZ0Zyb207XG5cdFx0XHRpZiAoIWZyb20pIGJyZWFrO1xuXHRcdFx0dGhpcy5xdWV1ZS5lbmQoZnJvbSk7XG5cdFx0XHRlbnRyeS5taXhpbmdGcm9tID0gbnVsbDtcblx0XHRcdGVudHJ5Lm1peGluZ1RvID0gbnVsbDtcblx0XHRcdGVudHJ5ID0gZnJvbTtcblx0XHR9XG5cblx0XHR0aGlzLnRyYWNrc1tjdXJyZW50LnRyYWNrSW5kZXhdID0gbnVsbDtcblxuXHRcdHRoaXMucXVldWUuZHJhaW4oKTtcblx0fVxuXG5cdHNldFRyYWNrIChpbmRleDogbnVtYmVyLCBjdXJyZW50OiBUcmFja0VudHJ5LCBpbnRlcnJ1cHQ6IGJvb2xlYW4pIHtcblx0XHRjb25zdCBmcm9tID0gdGhpcy5leHBhbmRUb0luZGV4KGluZGV4KTtcblx0XHR0aGlzLnRyYWNrc1tpbmRleF0gPSBjdXJyZW50O1xuXHRcdGN1cnJlbnQucHJldmlvdXMgPSBudWxsO1xuXG5cdFx0aWYgKGZyb20pIHtcblx0XHRcdGZyb20ubmV4dCA9IG51bGw7XG5cdFx0XHRpZiAoaW50ZXJydXB0KSB0aGlzLnF1ZXVlLmludGVycnVwdChmcm9tKTtcblx0XHRcdGN1cnJlbnQubWl4aW5nRnJvbSA9IGZyb207XG5cdFx0XHRmcm9tLm1peGluZ1RvID0gY3VycmVudDtcblx0XHRcdGN1cnJlbnQubWl4VGltZSA9IDA7XG5cblx0XHRcdGZyb20udGltZWxpbmVzUm90YXRpb24ubGVuZ3RoID0gMDsgLy8gUmVzZXQgcm90YXRpb24gZm9yIG1peGluZyBvdXQsIGluIGNhc2UgZW50cnkgd2FzIG1peGVkIGluLlxuXHRcdH1cblxuXHRcdHRoaXMucXVldWUuc3RhcnQoY3VycmVudCk7XG5cdH1cblxuXHQvKiogU2V0cyBhbiBhbmltYXRpb24gYnkgbmFtZS5cblx0ICpcblx0ICogU2VlIHtAbGluayBzZXRBbmltYXRpb259LiAqL1xuXHRzZXRBbmltYXRpb24gKHRyYWNrSW5kZXg6IG51bWJlciwgYW5pbWF0aW9uTmFtZTogc3RyaW5nLCBsb29wPzogYm9vbGVhbik6IFRyYWNrRW50cnk7XG5cblx0LyoqIFNldHMgdGhlIGN1cnJlbnQgYW5pbWF0aW9uIGZvciBhIHRyYWNrLCBkaXNjYXJkaW5nIGFueSBxdWV1ZWQgYW5pbWF0aW9ucy5cblx0ICpcblx0ICogSWYgdGhlIGZvcm1lcmx5IGN1cnJlbnQgdHJhY2sgZW50cnkgaXMgZm9yIHRoZSBzYW1lIGFuaW1hdGlvbiBhbmQgd2FzIG5ldmVyIGFwcGxpZWQgdG8gYSBza2VsZXRvbiwgaXQgaXMgcmVwbGFjZWQgKG5vdCBtaXhlZFxuXHQgKiBmcm9tKS5cblx0ICogQHBhcmFtIGxvb3AgSWYgdHJ1ZSwgdGhlIGFuaW1hdGlvbiB3aWxsIHJlcGVhdC4gSWYgZmFsc2UgaXQgd2lsbCBub3QsIGluc3RlYWQgaXRzIGxhc3QgZnJhbWUgaXMgYXBwbGllZCBpZiBwbGF5ZWQgYmV5b25kIGl0c1xuXHQgKiAgICAgICAgICAgZHVyYXRpb24uIEluIGVpdGhlciBjYXNlIHtAbGluayBUcmFja0VudHJ5LnRyYWNrRW5kfSBkZXRlcm1pbmVzIHdoZW4gdGhlIHRyYWNrIGlzIGNsZWFyZWQuXG5cdCAqIEByZXR1cm4gQSB0cmFjayBlbnRyeSB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb24gb2YgYW5pbWF0aW9uIHBsYXliYWNrLiBSZWZlcmVuY2VzIHRvIHRoZSB0cmFjayBlbnRyeSBtdXN0IG5vdCBiZSBrZXB0XG5cdCAqICAgICAgICAgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyLmRpc3Bvc2V9IGV2ZW50IG9jY3Vycy4gKi9cblx0c2V0QW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbjogQW5pbWF0aW9uLCBsb29wPzogYm9vbGVhbik6IFRyYWNrRW50cnk7XG5cblx0c2V0QW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbk5hbWVPckFuaW1hdGlvbjogc3RyaW5nIHwgQW5pbWF0aW9uLCBsb29wID0gZmFsc2UpOiBUcmFja0VudHJ5IHtcblx0XHRpZiAodHlwZW9mIGFuaW1hdGlvbk5hbWVPckFuaW1hdGlvbiA9PT0gXCJzdHJpbmdcIilcblx0XHRcdHJldHVybiB0aGlzLnNldEFuaW1hdGlvbjEodHJhY2tJbmRleCwgYW5pbWF0aW9uTmFtZU9yQW5pbWF0aW9uLCBsb29wKTtcblx0XHRyZXR1cm4gdGhpcy5zZXRBbmltYXRpb24yKHRyYWNrSW5kZXgsIGFuaW1hdGlvbk5hbWVPckFuaW1hdGlvbiwgbG9vcCk7XG5cdH1cblxuXHRwcml2YXRlIHNldEFuaW1hdGlvbjEgKHRyYWNrSW5kZXg6IG51bWJlciwgYW5pbWF0aW9uTmFtZTogc3RyaW5nLCBsb29wOiBib29sZWFuID0gZmFsc2UpIHtcblx0XHRjb25zdCBhbmltYXRpb24gPSB0aGlzLmRhdGEuc2tlbGV0b25EYXRhLmZpbmRBbmltYXRpb24oYW5pbWF0aW9uTmFtZSk7XG5cdFx0aWYgKCFhbmltYXRpb24pIHRocm93IG5ldyBFcnJvcihgQW5pbWF0aW9uIG5vdCBmb3VuZDogJHthbmltYXRpb25OYW1lfWApO1xuXHRcdHJldHVybiB0aGlzLnNldEFuaW1hdGlvbjIodHJhY2tJbmRleCwgYW5pbWF0aW9uLCBsb29wKTtcblx0fVxuXG5cdC8qKiBTZXRzIHRoZSBjdXJyZW50IGFuaW1hdGlvbiBmb3IgYSB0cmFjaywgZGlzY2FyZGluZyBhbnkgcXVldWVkIGFuaW1hdGlvbnMuXG5cdCAqXG5cdCAqIElmIHRoZSBmb3JtZXJseSBjdXJyZW50IHRyYWNrIGVudHJ5IGlzIGZvciB0aGUgc2FtZSBhbmltYXRpb24gYW5kIHdhcyBuZXZlciBhcHBsaWVkIHRvIGEgc2tlbGV0b24sIGl0IGlzIHJlcGxhY2VkIChub3QgbWl4ZWRcblx0ICogZnJvbSkuXG5cdCAqIEBwYXJhbSBsb29wIElmIHRydWUsIHRoZSBhbmltYXRpb24gd2lsbCByZXBlYXQuIElmIGZhbHNlIGl0IHdpbGwgbm90LCBpbnN0ZWFkIGl0cyBsYXN0IGZyYW1lIGlzIGFwcGxpZWQgaWYgcGxheWVkIGJleW9uZCBpdHNcblx0ICogICAgICAgICAgIGR1cmF0aW9uLiBJbiBlaXRoZXIgY2FzZSB7QGxpbmsgVHJhY2tFbnRyeS5nZXRUcmFja0VuZH0gZGV0ZXJtaW5lcyB3aGVuIHRoZSB0cmFjayBpcyBjbGVhcmVkLlxuXHQgKiBAcmV0dXJuIEEgdHJhY2sgZW50cnkgdG8gYWxsb3cgZnVydGhlciBjdXN0b21pemF0aW9uIG9mIGFuaW1hdGlvbiBwbGF5YmFjay4gUmVmZXJlbmNlcyB0byB0aGUgdHJhY2sgZW50cnkgbXVzdCBub3QgYmUga2VwdFxuXHQgKiAgICAgICAgIGFmdGVyIHRoZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lci5kaXNwb3NlfSBldmVudCBvY2N1cnMuICovXG5cdHByaXZhdGUgc2V0QW5pbWF0aW9uMiAodHJhY2tJbmRleDogbnVtYmVyLCBhbmltYXRpb246IEFuaW1hdGlvbiwgbG9vcDogYm9vbGVhbiA9IGZhbHNlKSB7XG5cdFx0aWYgKHRyYWNrSW5kZXggPCAwKSB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFja0luZGV4IG11c3QgYmUgPj0gMC5cIik7XG5cdFx0aWYgKCFhbmltYXRpb24pIHRocm93IG5ldyBFcnJvcihcImFuaW1hdGlvbiBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0bGV0IGludGVycnVwdCA9IHRydWU7XG5cdFx0bGV0IGN1cnJlbnQgPSB0aGlzLmV4cGFuZFRvSW5kZXgodHJhY2tJbmRleCk7XG5cdFx0aWYgKGN1cnJlbnQpIHtcblx0XHRcdGlmIChjdXJyZW50Lm5leHRUcmFja0xhc3QgPT09IC0xICYmIGN1cnJlbnQuYW5pbWF0aW9uID09PSBhbmltYXRpb24pIHtcblx0XHRcdFx0Ly8gRG9uJ3QgbWl4IGZyb20gYW4gZW50cnkgdGhhdCB3YXMgbmV2ZXIgYXBwbGllZC5cblx0XHRcdFx0dGhpcy50cmFja3NbdHJhY2tJbmRleF0gPSBjdXJyZW50Lm1peGluZ0Zyb207XG5cdFx0XHRcdHRoaXMucXVldWUuaW50ZXJydXB0KGN1cnJlbnQpO1xuXHRcdFx0XHR0aGlzLnF1ZXVlLmVuZChjdXJyZW50KTtcblx0XHRcdFx0dGhpcy5jbGVhck5leHQoY3VycmVudCk7XG5cdFx0XHRcdGN1cnJlbnQgPSBjdXJyZW50Lm1peGluZ0Zyb207XG5cdFx0XHRcdGludGVycnVwdCA9IGZhbHNlO1xuXHRcdFx0fSBlbHNlXG5cdFx0XHRcdHRoaXMuY2xlYXJOZXh0KGN1cnJlbnQpO1xuXHRcdH1cblx0XHRjb25zdCBlbnRyeSA9IHRoaXMudHJhY2tFbnRyeSh0cmFja0luZGV4LCBhbmltYXRpb24sIGxvb3AsIGN1cnJlbnQpO1xuXHRcdHRoaXMuc2V0VHJhY2sodHJhY2tJbmRleCwgZW50cnksIGludGVycnVwdCk7XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbigpO1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxuXG5cdC8qKiBRdWV1ZXMgYW4gYW5pbWF0aW9uIGJ5IG5hbWUuXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgYWRkQW5pbWF0aW9ufS4gKi9cblx0YWRkQW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbk5hbWU6IHN0cmluZywgbG9vcD86IGJvb2xlYW4sIGRlbGF5PzogbnVtYmVyKTogVHJhY2tFbnRyeTtcblxuXHQvKiogQWRkcyBhbiBhbmltYXRpb24gdG8gYmUgcGxheWVkIGFmdGVyIHRoZSBjdXJyZW50IG9yIGxhc3QgcXVldWVkIGFuaW1hdGlvbiBmb3IgYSB0cmFjay4gSWYgdGhlIHRyYWNrIGhhcyBubyBlbnRyaWVzLCB0aGlzIGlzXG5cdCAqIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB7QGxpbmsgc2V0QW5pbWF0aW9ufS5cblx0ICogQHBhcmFtIGRlbGF5IElmID4gMCwgc2V0cyB7QGxpbmsgVHJhY2tFbnRyeS5kZWxheX0uIElmIDw9IDAsIHRoZSBkZWxheSBzZXQgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeVxuXHQgKiAgICAgICAgICAgbWludXMgYW55IG1peCBkdXJhdGlvbiAoZnJvbSB7QGxpbmsgZGF0YX0pIHBsdXMgdGhlIHNwZWNpZmllZCBgZGVsYXlgIChpZSB0aGUgbWl4IGVuZHMgYXQgKHdoZW5cblx0ICogICAgICAgICAgIGBkZWxheWAgPSAwKSBvciBiZWZvcmUgKHdoZW4gYGRlbGF5YCA8IDApIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeSBkdXJhdGlvbikuIElmIHRoZVxuXHQgKiAgICAgICAgICAgcHJldmlvdXMgZW50cnkgaXMgbG9vcGluZywgaXRzIG5leHQgbG9vcCBjb21wbGV0aW9uIGlzIHVzZWQgaW5zdGVhZCBvZiBpdHMgZHVyYXRpb24uXG5cdCAqIEByZXR1cm4gQSB0cmFjayBlbnRyeSB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb24gb2YgYW5pbWF0aW9uIHBsYXliYWNrLiBSZWZlcmVuY2VzIHRvIHRoZSB0cmFjayBlbnRyeSBtdXN0IG5vdCBiZSBrZXB0XG5cdCAqICAgICAgICAgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyLmRpc3Bvc2V9IGV2ZW50IG9jY3Vycy4gKi9cblx0YWRkQW5pbWF0aW9uICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbjogQW5pbWF0aW9uLCBsb29wPzogYm9vbGVhbiwgZGVsYXk/OiBudW1iZXIpOiBUcmFja0VudHJ5O1xuXG5cdGFkZEFuaW1hdGlvbiAodHJhY2tJbmRleDogbnVtYmVyLCBhbmltYXRpb25OYW1lT3JBbmltYXRpb246IHN0cmluZyB8IEFuaW1hdGlvbiwgbG9vcCA9IGZhbHNlLCBkZWxheTogbnVtYmVyID0gMCk6IFRyYWNrRW50cnkge1xuXHRcdGlmICh0eXBlb2YgYW5pbWF0aW9uTmFtZU9yQW5pbWF0aW9uID09PSBcInN0cmluZ1wiKVxuXHRcdFx0cmV0dXJuIHRoaXMuYWRkQW5pbWF0aW9uMSh0cmFja0luZGV4LCBhbmltYXRpb25OYW1lT3JBbmltYXRpb24sIGxvb3AsIGRlbGF5KTtcblx0XHRyZXR1cm4gdGhpcy5hZGRBbmltYXRpb24yKHRyYWNrSW5kZXgsIGFuaW1hdGlvbk5hbWVPckFuaW1hdGlvbiwgbG9vcCwgZGVsYXkpO1xuXHR9XG5cblx0cHJpdmF0ZSBhZGRBbmltYXRpb24xICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbk5hbWU6IHN0cmluZywgbG9vcDogYm9vbGVhbiA9IGZhbHNlLCBkZWxheTogbnVtYmVyID0gMCkge1xuXHRcdGNvbnN0IGFuaW1hdGlvbiA9IHRoaXMuZGF0YS5za2VsZXRvbkRhdGEuZmluZEFuaW1hdGlvbihhbmltYXRpb25OYW1lKTtcblx0XHRpZiAoIWFuaW1hdGlvbikgdGhyb3cgbmV3IEVycm9yKGBBbmltYXRpb24gbm90IGZvdW5kOiAke2FuaW1hdGlvbk5hbWV9YCk7XG5cdFx0cmV0dXJuIHRoaXMuYWRkQW5pbWF0aW9uMih0cmFja0luZGV4LCBhbmltYXRpb24sIGxvb3AsIGRlbGF5KTtcblx0fVxuXG5cdHByaXZhdGUgYWRkQW5pbWF0aW9uMiAodHJhY2tJbmRleDogbnVtYmVyLCBhbmltYXRpb246IEFuaW1hdGlvbiwgbG9vcDogYm9vbGVhbiA9IGZhbHNlLCBkZWxheTogbnVtYmVyID0gMCkge1xuXHRcdGlmICh0cmFja0luZGV4IDwgMCkgdGhyb3cgbmV3IEVycm9yKFwidHJhY2tJbmRleCBtdXN0IGJlID49IDAuXCIpO1xuXHRcdGlmICghYW5pbWF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJhbmltYXRpb24gY2Fubm90IGJlIG51bGwuXCIpO1xuXG5cdFx0bGV0IGxhc3QgPSB0aGlzLmV4cGFuZFRvSW5kZXgodHJhY2tJbmRleCk7XG5cdFx0aWYgKGxhc3QpIHtcblx0XHRcdHdoaWxlIChsYXN0Lm5leHQpXG5cdFx0XHRcdGxhc3QgPSBsYXN0Lm5leHQ7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZW50cnkgPSB0aGlzLnRyYWNrRW50cnkodHJhY2tJbmRleCwgYW5pbWF0aW9uLCBsb29wLCBsYXN0KTtcblxuXHRcdGlmICghbGFzdCkge1xuXHRcdFx0dGhpcy5zZXRUcmFjayh0cmFja0luZGV4LCBlbnRyeSwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnF1ZXVlLmRyYWluKCk7XG5cdFx0XHRpZiAoZGVsYXkgPCAwKSBkZWxheSA9IDA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxhc3QubmV4dCA9IGVudHJ5O1xuXHRcdFx0ZW50cnkucHJldmlvdXMgPSBsYXN0O1xuXHRcdFx0aWYgKGRlbGF5IDw9IDApIGRlbGF5ID0gTWF0aC5tYXgoZGVsYXkgKyBsYXN0LmdldFRyYWNrQ29tcGxldGUoKSAtIGVudHJ5Lm1peER1cmF0aW9uLCAwKTtcblx0XHR9XG5cblx0XHRlbnRyeS5kZWxheSA9IGRlbGF5O1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxuXG5cdC8qKiBTZXRzIGFuIGVtcHR5IGFuaW1hdGlvbiBmb3IgYSB0cmFjaywgZGlzY2FyZGluZyBhbnkgcXVldWVkIGFuaW1hdGlvbnMsIGFuZCBzZXRzIHRoZSB0cmFjayBlbnRyeSdzXG5cdCAqIHtAbGluayBUcmFja0VudHJ5Lm1peGR1cmF0aW9ufS4gQW4gZW1wdHkgYW5pbWF0aW9uIGhhcyBubyB0aW1lbGluZXMgYW5kIHNlcnZlcyBhcyBhIHBsYWNlaG9sZGVyIGZvciBtaXhpbmcgaW4gb3Igb3V0LlxuXHQgKlxuXHQgKiBNaXhpbmcgb3V0IGlzIGRvbmUgYnkgc2V0dGluZyBhbiBlbXB0eSBhbmltYXRpb24gd2l0aCBhIG1peCBkdXJhdGlvbiB1c2luZyBlaXRoZXIge0BsaW5rIHNldEVtcHR5QW5pbWF0aW9ufSxcblx0ICoge0BsaW5rIHNldEVtcHR5QW5pbWF0aW9uc30sIG9yIHtAbGluayBhZGRFbXB0eUFuaW1hdGlvbn0uIE1peGluZyB0byBhbiBlbXB0eSBhbmltYXRpb24gY2F1c2VzXG5cdCAqIHRoZSBwcmV2aW91cyBhbmltYXRpb24gdG8gYmUgYXBwbGllZCBsZXNzIGFuZCBsZXNzIG92ZXIgdGhlIG1peCBkdXJhdGlvbi4gUHJvcGVydGllcyBrZXllZCBpbiB0aGUgcHJldmlvdXMgYW5pbWF0aW9uXG5cdCAqIHRyYW5zaXRpb24gdG8gdGhlIHZhbHVlIGZyb20gbG93ZXIgdHJhY2tzIG9yIHRvIHRoZSBzZXR1cCBwb3NlIHZhbHVlIGlmIG5vIGxvd2VyIHRyYWNrcyBrZXkgdGhlIHByb3BlcnR5LiBBIG1peCBkdXJhdGlvbiBvZlxuXHQgKiAwIHN0aWxsIG5lZWRzIHRvIGJlIGFwcGxpZWQgb25lIG1vcmUgdGltZSB0byBtaXggb3V0LCBzbyB0aGUgcHJvcGVydGllcyBpdCB3YXMgYW5pbWF0aW5nIGFyZSByZXZlcnRlZC5cblx0ICpcblx0ICogTWl4aW5nIGluIGlzIGRvbmUgYnkgZmlyc3Qgc2V0dGluZyBhbiBlbXB0eSBhbmltYXRpb24sIHRoZW4gYWRkaW5nIGFuIGFuaW1hdGlvbiB1c2luZ1xuXHQgKiB7QGxpbmsgYWRkQW5pbWF0aW9ufSB3aXRoIHRoZSBkZXNpcmVkIGRlbGF5IChhbiBlbXB0eSBhbmltYXRpb24gaGFzIGEgZHVyYXRpb24gb2YgMCkgYW5kIG9uXG5cdCAqIHRoZSByZXR1cm5lZCB0cmFjayBlbnRyeSwgc2V0IHRoZSB7QGxpbmsgVHJhY2tFbnRyeS5zZXRNaXhEdXJhdGlvbn0uIE1peGluZyBmcm9tIGFuIGVtcHR5IGFuaW1hdGlvbiBjYXVzZXMgdGhlIG5ld1xuXHQgKiBhbmltYXRpb24gdG8gYmUgYXBwbGllZCBtb3JlIGFuZCBtb3JlIG92ZXIgdGhlIG1peCBkdXJhdGlvbi4gUHJvcGVydGllcyBrZXllZCBpbiB0aGUgbmV3IGFuaW1hdGlvbiB0cmFuc2l0aW9uIGZyb20gdGhlIHZhbHVlXG5cdCAqIGZyb20gbG93ZXIgdHJhY2tzIG9yIGZyb20gdGhlIHNldHVwIHBvc2UgdmFsdWUgaWYgbm8gbG93ZXIgdHJhY2tzIGtleSB0aGUgcHJvcGVydHkgdG8gdGhlIHZhbHVlIGtleWVkIGluIHRoZSBuZXcgYW5pbWF0aW9uLlxuXHQgKlxuXHQgKiBTZWUgPGEgaHJlZj0naHR0cHM6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1hcHBseWluZy1hbmltYXRpb25zI0VtcHR5LWFuaW1hdGlvbnMnPkVtcHR5IGFuaW1hdGlvbnM8L2E+IGluIHRoZSBTcGluZVxuXHQgKiBSdW50aW1lcyBHdWlkZS4gKi9cblx0c2V0RW1wdHlBbmltYXRpb24gKHRyYWNrSW5kZXg6IG51bWJlciwgbWl4RHVyYXRpb246IG51bWJlciA9IDApIHtcblx0XHRjb25zdCBlbnRyeSA9IHRoaXMuc2V0QW5pbWF0aW9uKHRyYWNrSW5kZXgsIEFuaW1hdGlvblN0YXRlLmVtcHR5QW5pbWF0aW9uLCBmYWxzZSk7XG5cdFx0ZW50cnkubWl4RHVyYXRpb24gPSBtaXhEdXJhdGlvbjtcblx0XHRlbnRyeS50cmFja0VuZCA9IG1peER1cmF0aW9uO1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxuXG5cdC8qKiBBZGRzIGFuIGVtcHR5IGFuaW1hdGlvbiB0byBiZSBwbGF5ZWQgYWZ0ZXIgdGhlIGN1cnJlbnQgb3IgbGFzdCBxdWV1ZWQgYW5pbWF0aW9uIGZvciBhIHRyYWNrLCBhbmQgc2V0cyB0aGUgdHJhY2sgZW50cnknc1xuXHQgKiB7QGxpbmsgVHJhY2tFbnRyeS5taXhEdXJhdGlvbn0uIElmIHRoZSB0cmFjayBoYXMgbm8gZW50cmllcywgaXQgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nXG5cdCAqIHtAbGluayBzZXRFbXB0eUFuaW1hdGlvbn0uXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgc2V0RW1wdHlBbmltYXRpb259IGFuZFxuXHQgKiA8YSBocmVmPSdodHRwczovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWFwcGx5aW5nLWFuaW1hdGlvbnMjRW1wdHktYW5pbWF0aW9ucyc+RW1wdHkgYW5pbWF0aW9uczwvYT4gaW4gdGhlIFNwaW5lIFJ1bnRpbWVzXG5cdCAqIEd1aWRlLlxuXHQgKiBAcGFyYW0gZGVsYXkgSWYgPiAwLCBzZXRzIHtAbGluayBUcmFja0VudHJ5LmRlbGF5fS4gSWYgPD0gMCwgdGhlIGRlbGF5IHNldCBpcyB0aGUgZHVyYXRpb24gb2YgdGhlIHByZXZpb3VzIHRyYWNrIGVudHJ5IG1pbnVzXG5cdCAqICAgICAgICAgICBhbnkgbWl4IGR1cmF0aW9uIHBsdXMgdGhlIHNwZWNpZmllZCBgZGVsYXlgIChpZSB0aGUgbWl4IGVuZHMgYXQgKHdoZW4gYGRlbGF5YCA9IDApIG9yIGJlZm9yZVxuXHQgKiAgICAgICAgICAgKHdoZW4gYGRlbGF5YCA8IDApIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeSBkdXJhdGlvbikuIElmIHRoZSBwcmV2aW91cyBlbnRyeSBpcyBsb29waW5nLCBpdHMgbmV4dCBsb29wXG5cdCAqICAgICAgICAgICBjb21wbGV0aW9uIGlzIHVzZWQgaW5zdGVhZCBvZiBpdHMgZHVyYXRpb24uXG5cdCAqIEByZXR1cm4gQSB0cmFjayBlbnRyeSB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb24gb2YgYW5pbWF0aW9uIHBsYXliYWNrLiBSZWZlcmVuY2VzIHRvIHRoZSB0cmFjayBlbnRyeSBtdXN0IG5vdCBiZSBrZXB0XG5cdCAqICAgICAgICAgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyLmRpc3Bvc2V9IGV2ZW50IG9jY3Vycy4gKi9cblx0YWRkRW1wdHlBbmltYXRpb24gKHRyYWNrSW5kZXg6IG51bWJlciwgbWl4RHVyYXRpb246IG51bWJlciA9IDAsIGRlbGF5OiBudW1iZXIgPSAwKSB7XG5cdFx0Y29uc3QgZW50cnkgPSB0aGlzLmFkZEFuaW1hdGlvbih0cmFja0luZGV4LCBBbmltYXRpb25TdGF0ZS5lbXB0eUFuaW1hdGlvbiwgZmFsc2UsIGRlbGF5KTtcblx0XHRpZiAoZGVsYXkgPD0gMCkgZW50cnkuZGVsYXkgPSBNYXRoLm1heChlbnRyeS5kZWxheSArIGVudHJ5Lm1peER1cmF0aW9uIC0gbWl4RHVyYXRpb24sIDApO1xuXHRcdGVudHJ5Lm1peER1cmF0aW9uID0gbWl4RHVyYXRpb247XG5cdFx0ZW50cnkudHJhY2tFbmQgPSBtaXhEdXJhdGlvbjtcblx0XHRyZXR1cm4gZW50cnk7XG5cdH1cblxuXHQvKiogU2V0cyBhbiBlbXB0eSBhbmltYXRpb24gZm9yIGV2ZXJ5IHRyYWNrLCBkaXNjYXJkaW5nIGFueSBxdWV1ZWQgYW5pbWF0aW9ucywgYW5kIG1peGVzIHRvIGl0IG92ZXIgdGhlIHNwZWNpZmllZCBtaXggZHVyYXRpb24uXG5cdCAqXG5cdCAqIFNlZSA8YSBocmVmPSdodHRwczovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWFwcGx5aW5nLWFuaW1hdGlvbnMjRW1wdHktYW5pbWF0aW9ucyc+RW1wdHkgYW5pbWF0aW9uczwvYT4gaW4gdGhlIFNwaW5lXG5cdCAqIFJ1bnRpbWVzIEd1aWRlLiAqL1xuXHRzZXRFbXB0eUFuaW1hdGlvbnMgKG1peER1cmF0aW9uOiBudW1iZXIgPSAwKSB7XG5cdFx0Y29uc3Qgb2xkRHJhaW5EaXNhYmxlZCA9IHRoaXMucXVldWUuZHJhaW5EaXNhYmxlZDtcblx0XHR0aGlzLnF1ZXVlLmRyYWluRGlzYWJsZWQgPSB0cnVlO1xuXHRcdGZvciAobGV0IGkgPSAwLCBuID0gdGhpcy50cmFja3MubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG5cdFx0XHRjb25zdCBjdXJyZW50ID0gdGhpcy50cmFja3NbaV07XG5cdFx0XHRpZiAoY3VycmVudCkgdGhpcy5zZXRFbXB0eUFuaW1hdGlvbihjdXJyZW50LnRyYWNrSW5kZXgsIG1peER1cmF0aW9uKTtcblx0XHR9XG5cdFx0dGhpcy5xdWV1ZS5kcmFpbkRpc2FibGVkID0gb2xkRHJhaW5EaXNhYmxlZDtcblx0XHR0aGlzLnF1ZXVlLmRyYWluKCk7XG5cdH1cblxuXHRleHBhbmRUb0luZGV4IChpbmRleDogbnVtYmVyKSB7XG5cdFx0aWYgKGluZGV4IDwgdGhpcy50cmFja3MubGVuZ3RoKSByZXR1cm4gdGhpcy50cmFja3NbaW5kZXhdO1xuXHRcdFV0aWxzLmVuc3VyZUFycmF5Q2FwYWNpdHkodGhpcy50cmFja3MsIGluZGV4ICsgMSwgbnVsbCk7XG5cdFx0dGhpcy50cmFja3MubGVuZ3RoID0gaW5kZXggKyAxO1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0LyoqIEBwYXJhbSBsYXN0IE1heSBiZSBudWxsLiAqL1xuXHR0cmFja0VudHJ5ICh0cmFja0luZGV4OiBudW1iZXIsIGFuaW1hdGlvbjogQW5pbWF0aW9uLCBsb29wOiBib29sZWFuLCBsYXN0OiBUcmFja0VudHJ5IHwgbnVsbCkge1xuXHRcdGNvbnN0IGVudHJ5ID0gdGhpcy50cmFja0VudHJ5UG9vbC5vYnRhaW4oKTtcblx0XHRlbnRyeS5yZXNldCgpO1xuXHRcdGVudHJ5LnRyYWNrSW5kZXggPSB0cmFja0luZGV4O1xuXHRcdGVudHJ5LmFuaW1hdGlvbiA9IGFuaW1hdGlvbjtcblx0XHRlbnRyeS5sb29wID0gbG9vcDtcblxuXHRcdGVudHJ5LmFkZGl0aXZlID0gZmFsc2U7XG5cdFx0ZW50cnkucmV2ZXJzZSA9IGZhbHNlO1xuXHRcdGVudHJ5LnNob3J0ZXN0Um90YXRpb24gPSBmYWxzZTtcblxuXHRcdGVudHJ5LmV2ZW50VGhyZXNob2xkID0gMDtcblx0XHRlbnRyeS5hbHBoYUF0dGFjaG1lbnRUaHJlc2hvbGQgPSAwO1xuXHRcdGVudHJ5Lm1peEF0dGFjaG1lbnRUaHJlc2hvbGQgPSAwO1xuXHRcdGVudHJ5Lm1peERyYXdPcmRlclRocmVzaG9sZCA9IDA7XG5cblx0XHRlbnRyeS5hbmltYXRpb25TdGFydCA9IDA7XG5cdFx0ZW50cnkuYW5pbWF0aW9uRW5kID0gYW5pbWF0aW9uLmR1cmF0aW9uO1xuXHRcdGVudHJ5LmFuaW1hdGlvbkxhc3QgPSAtMTtcblx0XHRlbnRyeS5uZXh0QW5pbWF0aW9uTGFzdCA9IC0xO1xuXG5cdFx0ZW50cnkuZGVsYXkgPSAwO1xuXHRcdGVudHJ5LnRyYWNrVGltZSA9IDA7XG5cdFx0ZW50cnkudHJhY2tMYXN0ID0gLTE7XG5cdFx0ZW50cnkubmV4dFRyYWNrTGFzdCA9IC0xO1xuXHRcdGVudHJ5LnRyYWNrRW5kID0gTnVtYmVyLk1BWF9WQUxVRTtcblx0XHRlbnRyeS50aW1lU2NhbGUgPSAxO1xuXG5cdFx0ZW50cnkuYWxwaGEgPSAxO1xuXHRcdGVudHJ5Lm1peFRpbWUgPSAwO1xuXHRcdGVudHJ5Lm1peER1cmF0aW9uID0gIWxhc3QgPyAwIDogdGhpcy5kYXRhLmdldE1peChsYXN0LmFuaW1hdGlvbiEsIGFuaW1hdGlvbik7XG5cdFx0ZW50cnkudG90YWxBbHBoYSA9IDA7XG5cdFx0ZW50cnkua2VlcEhvbGQgPSBmYWxzZTtcblx0XHRyZXR1cm4gZW50cnk7XG5cdH1cblxuXHQvKiogUmVtb3ZlcyB7QGxpbmsgVHJhY2tFbnRyeS5uZXh0fSBhbmQgYWxsIGVudHJpZXMgYWZ0ZXIgaXQgZm9yIHRoZSBzcGVjaWZpZWQgZW50cnkuICovXG5cdGNsZWFyTmV4dCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHRsZXQgbmV4dCA9IGVudHJ5Lm5leHQ7XG5cdFx0d2hpbGUgKG5leHQpIHtcblx0XHRcdHRoaXMucXVldWUuZGlzcG9zZShuZXh0KTtcblx0XHRcdG5leHQgPSBuZXh0Lm5leHQ7XG5cdFx0fVxuXHRcdGVudHJ5Lm5leHQgPSBudWxsO1xuXHR9XG5cblx0X2FuaW1hdGlvbnNDaGFuZ2VkICgpIHtcblx0XHR0aGlzLmFuaW1hdGlvbnNDaGFuZ2VkID0gZmFsc2U7XG5cblx0XHRjb25zdCB0cmFja3MgPSB0aGlzLnRyYWNrcztcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IHRyYWNrcy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGxldCBlbnRyeSA9IHRyYWNrc1tpXTtcblx0XHRcdGlmICghZW50cnkpIGNvbnRpbnVlO1xuXHRcdFx0d2hpbGUgKGVudHJ5Lm1peGluZ0Zyb20pXG5cdFx0XHRcdGVudHJ5ID0gZW50cnkubWl4aW5nRnJvbTtcblx0XHRcdGRvIHtcblx0XHRcdFx0dGhpcy5jb21wdXRlSG9sZChlbnRyeSk7XG5cdFx0XHRcdGVudHJ5ID0gZW50cnkubWl4aW5nVG87XG5cdFx0XHR9IHdoaWxlIChlbnRyeSk7XG5cdFx0fVxuXHRcdHRoaXMucHJvcGVydHlJZHMuY2xlYXIoKTtcblx0fVxuXG5cdGNvbXB1dGVIb2xkIChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHRcdGNvbnN0IHRpbWVsaW5lcyA9IGVudHJ5LmFuaW1hdGlvbiEudGltZWxpbmVzO1xuXHRcdGNvbnN0IHRpbWVsaW5lc0NvdW50ID0gZW50cnkuYW5pbWF0aW9uIS50aW1lbGluZXMubGVuZ3RoO1xuXHRcdGNvbnN0IHRpbWVsaW5lTW9kZSA9IGVudHJ5LnRpbWVsaW5lTW9kZTtcblx0XHR0aW1lbGluZU1vZGUubGVuZ3RoID0gdGltZWxpbmVzQ291bnQ7XG5cdFx0Y29uc3QgdGltZWxpbmVIb2xkTWl4ID0gZW50cnkudGltZWxpbmVIb2xkTWl4O1xuXHRcdHRpbWVsaW5lSG9sZE1peC5sZW5ndGggPSAwO1xuXHRcdGNvbnN0IHByb3BlcnR5SWRzID0gdGhpcy5wcm9wZXJ0eUlkcztcblx0XHRjb25zdCBhZGQgPSBlbnRyeS5hZGRpdGl2ZSwga2VlcEhvbGQgPSBlbnRyeS5rZWVwSG9sZDtcblx0XHRjb25zdCB0byA9IGVudHJ5Lm1peGluZ1RvO1xuXG5cdFx0b3V0ZXI6XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aW1lbGluZXNDb3VudDsgaSsrKSB7XG5cdFx0XHRjb25zdCB0aW1lbGluZSA9IHRpbWVsaW5lc1tpXTtcblx0XHRcdGNvbnN0IGlkcyA9IHRpbWVsaW5lLnByb3BlcnR5SWRzO1xuXHRcdFx0Y29uc3QgZmlyc3QgPSBwcm9wZXJ0eUlkcy5hZGRBbGwoaWRzKVxuXHRcdFx0XHQmJiAhKHRpbWVsaW5lIGluc3RhbmNlb2YgRHJhd09yZGVyRm9sZGVyVGltZWxpbmUgJiYgcHJvcGVydHlJZHMuY29udGFpbnMoRHJhd09yZGVyVGltZWxpbmUucHJvcGVydHlJRCkpO1xuXG5cdFx0XHRpZiAoYWRkICYmIHRpbWVsaW5lLmFkZGl0aXZlKSB7XG5cdFx0XHRcdHRpbWVsaW5lTW9kZVtpXSA9IGZpcnN0ID8gRklSU1QgOiBTVUJTRVFVRU5UO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Zm9yIChsZXQgZnJvbSA9IGVudHJ5Lm1peGluZ0Zyb207IGZyb20gIT0gbnVsbDsgZnJvbSA9IGZyb20ubWl4aW5nRnJvbSkge1xuXHRcdFx0XHRpZiAoZnJvbS5hbmltYXRpb24hLmhhc1RpbWVsaW5lKGlkcykpIHtcblx0XHRcdFx0XHQvLyBBbiBlYXJsaWVyIGVudHJ5IG9uIHRoaXMgdHJhY2sga2V5cyB0aGlzIHByb3BlcnR5LCBpc29sYXRpbmcgaXQgZnJvbSBsb3dlciB0cmFja3MuXG5cdFx0XHRcdFx0dGltZWxpbmVNb2RlW2ldID0gU1VCU0VRVUVOVDtcblx0XHRcdFx0XHRjb250aW51ZSBvdXRlcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBIb2xkIGlmIHRoZSBuZXh0IGVudHJ5IHdpbGwgb3ZlcndyaXRlIHRoaXMgcHJvcGVydHkuXG5cdFx0XHRsZXQgbW9kZTogbnVtYmVyO1xuXHRcdFx0aWYgKHRvID09PSBudWxsIHx8IHRpbWVsaW5lLmluc3RhbnQgfHwgKHRvLmFkZGl0aXZlICYmIHRpbWVsaW5lLmFkZGl0aXZlKSB8fCAhdG8uYW5pbWF0aW9uPy5oYXNUaW1lbGluZShpZHMpKVxuXHRcdFx0XHRtb2RlID0gZmlyc3QgPyBGSVJTVCA6IFNVQlNFUVVFTlQ7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0bW9kZSA9IGZpcnN0ID8gSE9MRF9GSVJTVCA6IEhPTEQ7XG5cdFx0XHRcdC8vIEZpbmQgbmV4dCBlbnRyeSB0aGF0IGRvZXNuJ3Qgb3ZlcndyaXRlIHRoaXMgcHJvcGVydHkuIEl0cyBtaXggZmFkZXMgb3V0IHRoZSBob2xkLCBpbnN0ZWFkIG9mIGl0IGVuZGluZyBhYnJ1cHRseS5cblx0XHRcdFx0Zm9yIChsZXQgbmV4dCA9IHRvLm1peGluZ1RvOyBuZXh0ICE9IG51bGw7IG5leHQgPSBuZXh0Lm1peGluZ1RvKSB7XG5cdFx0XHRcdFx0aWYgKChuZXh0LmFkZGl0aXZlICYmIHRpbWVsaW5lLmFkZGl0aXZlKSB8fCAhbmV4dC5hbmltYXRpb24/Lmhhc1RpbWVsaW5lKGlkcykpIHtcblx0XHRcdFx0XHRcdGlmIChuZXh0Lm1peER1cmF0aW9uID4gMCkgdGltZWxpbmVIb2xkTWl4W2ldID0gbmV4dDtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGtlZXBIb2xkKSBtb2RlID0gKG1vZGUgJiB+SE9MRCkgfCAodGltZWxpbmVNb2RlW2ldICYgSE9MRCk7XG5cdFx0XHR0aW1lbGluZU1vZGVbaV0gPSBtb2RlO1xuXHRcdH1cblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRoZSB0cmFjayBlbnRyeSBmb3IgdGhlIGFuaW1hdGlvbiBjdXJyZW50bHkgcGxheWluZyBvbiB0aGUgdHJhY2ssIG9yIG51bGwgaWYgbm8gYW5pbWF0aW9uIGlzIGN1cnJlbnRseSBwbGF5aW5nLiAqL1xuXHRnZXRUcmFjayAodHJhY2tJbmRleDogbnVtYmVyKSB7XG5cdFx0aWYgKHRyYWNrSW5kZXggPCAwKSB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFja0luZGV4IG11c3QgYmUgPj0gMC5cIik7XG5cdFx0aWYgKHRyYWNrSW5kZXggPj0gdGhpcy50cmFja3MubGVuZ3RoKSByZXR1cm4gbnVsbDtcblx0XHRyZXR1cm4gdGhpcy50cmFja3NbdHJhY2tJbmRleF07XG5cdH1cblxuXG5cdC8qKiBBZGRzIGEgbGlzdGVuZXIgdG8gcmVjZWl2ZSBldmVudHMgZm9yIGFsbCB0cmFjayBlbnRyaWVzLiAqL1xuXHRhZGRMaXN0ZW5lciAobGlzdGVuZXI6IEFuaW1hdGlvblN0YXRlTGlzdGVuZXIpIHtcblx0XHRpZiAoIWxpc3RlbmVyKSB0aHJvdyBuZXcgRXJyb3IoXCJsaXN0ZW5lciBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0dGhpcy5saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG5cdH1cblxuXHQvKiogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgYWRkZWQgd2l0aCB7QGxpbmsgYWRkTGlzdGVuZXJ9LiAqL1xuXHRyZW1vdmVMaXN0ZW5lciAobGlzdGVuZXI6IEFuaW1hdGlvblN0YXRlTGlzdGVuZXIpIHtcblx0XHRjb25zdCBpbmRleCA9IHRoaXMubGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuXHRcdGlmIChpbmRleCA+PSAwKSB0aGlzLmxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXHR9XG5cblx0LyoqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBhZGRlZCB3aXRoIHtAbGluayBhZGRMaXN0ZW5lcn0uICovXG5cdGNsZWFyTGlzdGVuZXJzICgpIHtcblx0XHR0aGlzLmxpc3RlbmVycy5sZW5ndGggPSAwO1xuXHR9XG5cblx0LyoqIERpc2NhcmRzIGFsbCBsaXN0ZW5lciBub3RpZmljYXRpb25zIHRoYXQgaGF2ZSBub3QgeWV0IGJlZW4gZGVsaXZlcmVkLiBUaGlzIGNhbiBiZSB1c2VmdWwgdG8gY2FsbCBmcm9tIGFuXG5cdCAqIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyfSB3aGVuIGl0IGlzIGtub3duIHRoYXQgZnVydGhlciBub3RpZmljYXRpb25zIHRoYXQgbWF5IGhhdmUgYmVlbiBhbHJlYWR5IHF1ZXVlZCBmb3IgZGVsaXZlcnlcblx0ICogYXJlIG5vdCB3YW50ZWQgYmVjYXVzZSBuZXcgYW5pbWF0aW9ucyBhcmUgYmVpbmcgc2V0LiAqL1xuXHRjbGVhckxpc3RlbmVyTm90aWZpY2F0aW9ucyAoKSB7XG5cdFx0dGhpcy5xdWV1ZS5jbGVhcigpO1xuXHR9XG59XG5cbi8qKiBTdG9yZXMgc2V0dGluZ3MgYW5kIG90aGVyIHN0YXRlIGZvciB0aGUgcGxheWJhY2sgb2YgYW4gYW5pbWF0aW9uIG9uIGFuIHtAbGluayBBbmltYXRpb25TdGF0ZX0gdHJhY2suXG4gKlxuICogUmVmZXJlbmNlcyB0byBhIHRyYWNrIGVudHJ5IG11c3Qgbm90IGJlIGtlcHQgYWZ0ZXIgdGhlIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyLmRpc3Bvc2V9IGV2ZW50IG9jY3Vycy4gKi9cbmV4cG9ydCBjbGFzcyBUcmFja0VudHJ5IHtcblx0LyoqIFRoZSBhbmltYXRpb24gdG8gYXBwbHkgZm9yIHRoaXMgdHJhY2sgZW50cnkuICovXG5cdGFuaW1hdGlvbjogQW5pbWF0aW9uIHwgbnVsbCA9IG51bGw7XG5cblx0cHJldmlvdXM6IFRyYWNrRW50cnkgfCBudWxsID0gbnVsbDtcblxuXHQvKiogVGhlIGFuaW1hdGlvbiBxdWV1ZWQgdG8gc3RhcnQgYWZ0ZXIgdGhpcyBhbmltYXRpb24sIG9yIG51bGwuIGBuZXh0YCBtYWtlcyB1cCBhIGxpbmtlZCBsaXN0LiAqL1xuXHRuZXh0OiBUcmFja0VudHJ5IHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFRoZSB0cmFjayBlbnRyeSBmb3IgdGhlIHByZXZpb3VzIGFuaW1hdGlvbiB3aGVuIG1peGluZyB0byB0aGlzIGFuaW1hdGlvbiwgb3IgbnVsbCBpZiBubyBtaXhpbmcgaXMgY3VycmVudGx5IG9jY3VycmluZy5cblx0ICogV2hlbiBtaXhpbmcgZnJvbSBtdWx0aXBsZSBhbmltYXRpb25zLCBgbWl4aW5nRnJvbWAgbWFrZXMgdXAgYSBkb3VibHkgbGlua2VkIGxpc3QuICovXG5cdG1peGluZ0Zyb206IFRyYWNrRW50cnkgfCBudWxsID0gbnVsbDtcblxuXHQvKiogVGhlIHRyYWNrIGVudHJ5IGZvciB0aGUgbmV4dCBhbmltYXRpb24gd2hlbiBtaXhpbmcgZnJvbSB0aGlzIGFuaW1hdGlvbiwgb3IgbnVsbCBpZiBubyBtaXhpbmcgaXMgY3VycmVudGx5IG9jY3VycmluZy5cblx0ICogV2hlbiBtaXhpbmcgdG8gbXVsdGlwbGUgYW5pbWF0aW9ucywgYG1peGluZ1RvYCBtYWtlcyB1cCBhIGRvdWJseSBsaW5rZWQgbGlzdC4gKi9cblx0bWl4aW5nVG86IFRyYWNrRW50cnkgfCBudWxsID0gbnVsbDtcblxuXHQvKiogVGhlIGxpc3RlbmVyIGZvciBldmVudHMgZ2VuZXJhdGVkIGJ5IHRoaXMgdHJhY2sgZW50cnksIG9yIG51bGwuXG5cdCAqXG5cdCAqIEEgdHJhY2sgZW50cnkgcmV0dXJuZWQgZnJvbSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUuc2V0QW5pbWF0aW9ufSBpcyBhbHJlYWR5IHRoZSBjdXJyZW50IGFuaW1hdGlvblxuXHQgKiBmb3IgdGhlIHRyYWNrLCBzbyB0aGUgY2FsbGJhY2sgZm9yIGxpc3RlbmVyIHtAbGluayBBbmltYXRpb25TdGF0ZUxpc3RlbmVyLnN0YXJ0fSB3aWxsIG5vdCBiZSBjYWxsZWQuICovXG5cdGxpc3RlbmVyOiBBbmltYXRpb25TdGF0ZUxpc3RlbmVyIHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFRoZSBpbmRleCBvZiB0aGUgdHJhY2sgd2hlcmUgdGhpcyB0cmFjayBlbnRyeSBpcyBlaXRoZXIgY3VycmVudCBvciBxdWV1ZWQuXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUuZ2V0VHJhY2t9LiAqL1xuXHR0cmFja0luZGV4ID0gMDtcblxuXHQvKiogSWYgdHJ1ZSwgdGhlIGFuaW1hdGlvbiB3aWxsIHJlcGVhdC4gSWYgZmFsc2UgaXQgd2lsbCBub3QsIGluc3RlYWQgaXRzIGxhc3QgZnJhbWUgaXMgYXBwbGllZCBpZiBwbGF5ZWQgYmV5b25kIGl0c1xuXHQgKiBkdXJhdGlvbi4gKi9cblx0bG9vcCA9IGZhbHNlO1xuXG5cdC8qKiBXaGVuIHRydWUsIHRpbWVsaW5lcyBpbiB0aGlzIGFuaW1hdGlvbiB0aGF0IHN1cHBvcnQgYWRkaXRpdmUgaGF2ZSB0aGVpciB2YWx1ZXMgYWRkZWQgdG8gdGhlIHNldHVwIG9yIGN1cnJlbnQgcG9zZSB2YWx1ZXNcblx0ICogaW5zdGVhZCBvZiByZXBsYWNpbmcgdGhlbS4gQWRkaXRpdmUgY2FuIGJlIHNldCBmb3IgYSBuZXcgdHJhY2sgZW50cnkgb25seSBiZWZvcmUge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFwcGx5fVxuXHQgKiBpcyBuZXh0IGNhbGxlZC4gKi9cblx0YWRkaXRpdmUgPSBmYWxzZTtcblxuXHQvKiogSWYgdHJ1ZSwgdGhlIGFuaW1hdGlvbiB3aWxsIGJlIGFwcGxpZWQgaW4gcmV2ZXJzZS4gKi9cblx0cmV2ZXJzZSA9IGZhbHNlO1xuXG5cdC8qKiBJZiB0cnVlLCBtaXhpbmcgcm90YXRpb24gYmV0d2VlbiB0cmFja3MgYWx3YXlzIHVzZXMgdGhlIHNob3J0ZXN0IHJvdGF0aW9uIGRpcmVjdGlvbi4gSWYgdGhlIHJvdGF0aW9uIGlzIGFuaW1hdGVkLCB0aGVcblx0ICogc2hvcnRlc3Qgcm90YXRpb24gZGlyZWN0aW9uIG1heSBjaGFuZ2UgZHVyaW5nIHRoZSBtaXguXG5cdCAqXG5cdCAqIElmIGZhbHNlLCB0aGUgc2hvcnRlc3Qgcm90YXRpb24gZGlyZWN0aW9uIGlzIHJlbWVtYmVyZWQgd2hlbiB0aGUgbWl4IHN0YXJ0cyBhbmQgdGhlIHNhbWUgZGlyZWN0aW9uIGlzIHVzZWQgZm9yIHRoZSByZXN0XG5cdCAqIG9mIHRoZSBtaXguIERlZmF1bHRzIHRvIGZhbHNlLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIHJlc2V0Um90YXRpb25EaXJlY3Rpb25zfS4gKi9cblx0c2hvcnRlc3RSb3RhdGlvbiA9IGZhbHNlO1xuXG5cdGtlZXBIb2xkID0gZmFsc2U7XG5cblx0LyoqIFdoZW4gdGhlIGludGVycG9sYXRlZCBtaXggcGVyY2VudGFnZSBpcyBsZXNzIHRoYW4gdGhlIGBldmVudFRocmVzaG9sZGAgLCBldmVudCB0aW1lbGluZXMgYXJlIGFwcGxpZWQgd2hpbGVcblx0ICogdGhpcyBhbmltYXRpb24gaXMgYmVpbmcgbWl4ZWQgb3V0LiBEZWZhdWx0cyB0byAwLCBzbyBldmVudCB0aW1lbGluZXMgYXJlIG5vdCBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkXG5cdCAqIG91dC4gKi9cblx0ZXZlbnRUaHJlc2hvbGQgPSAwO1xuXG5cdC8qKiBXaGVuIHRoZSBpbnRlcnBvbGF0ZWQgbWl4IHBlcmNlbnRhZ2UgaXMgbGVzcyB0aGFuIHRoZSBgbWl4QXR0YWNobWVudFRocmVzaG9sZGAsIGF0dGFjaG1lbnQgdGltZWxpbmVzIGFyZVxuXHQgKiBhcHBsaWVkIHdoaWxlIHRoaXMgYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gRGVmYXVsdHMgdG8gMCwgc28gYXR0YWNobWVudCB0aW1lbGluZXMgYXJlIG5vdCBhcHBsaWVkIHdoaWxlIHRoaXNcblx0ICogYW5pbWF0aW9uIGlzIGJlaW5nIG1peGVkIG91dC4gKi9cblx0bWl4QXR0YWNobWVudFRocmVzaG9sZCA9IDA7XG5cblx0LyoqIFdoZW4gdGhlIGNvbXB1dGVkIGFscGhhIGlzIGdyZWF0ZXIgdGhhbiBgYWxwaGFBdHRhY2htZW50VGhyZXNob2xkYCwgYXR0YWNobWVudCB0aW1lbGluZXMgYXJlIGFwcGxpZWQuIFRoZVxuXHQgKiBjb21wdXRlZCBhbHBoYSBpbmNsdWRlcyB7QGxpbmsgYWxwaGF9IGFuZCB0aGUgaW50ZXJwb2xhdGVkIG1peCBwZXJjZW50YWdlLiBEZWZhdWx0cyB0byAwLCBzbyBhdHRhY2htZW50IHRpbWVsaW5lcyBhcmVcblx0ICogYWx3YXlzIGFwcGxpZWQuICovXG5cdGFscGhhQXR0YWNobWVudFRocmVzaG9sZCA9IDA7XG5cblx0LyoqIFdoZW4gdGhlIGludGVycG9sYXRlZCBtaXggcGVyY2VudGFnZSBpcyBsZXNzIHRoYW4gdGhlIGBtaXhBdHRhY2htZW50VGhyZXNob2xkYCwgYXR0YWNobWVudCB0aW1lbGluZXMgYXJlXG5cdCAqIGFwcGxpZWQgd2hpbGUgdGhpcyBhbmltYXRpb24gaXMgYmVpbmcgbWl4ZWQgb3V0LiBEZWZhdWx0cyB0byAwLCBzbyBhdHRhY2htZW50IHRpbWVsaW5lcyBhcmUgbm90IGFwcGxpZWQgd2hpbGUgdGhpc1xuXHQgKiBhbmltYXRpb24gaXMgYmVpbmcgbWl4ZWQgb3V0LiAqL1xuXHRtaXhEcmF3T3JkZXJUaHJlc2hvbGQgPSAwO1xuXG5cdC8qKiBUaGUgdGltZSBpbiBzZWNvbmRzIGZvciB0aGUgZmlyc3QgZnJhbWUgb2YgdGhpcyBhbmltYXRpb24sIGJvdGggaW5pdGlhbGx5IGFuZCBhZnRlciBsb29waW5nLiBEZWZhdWx0cyB0byAwLlxuXHQgKlxuXHQgKiBXaGVuIHNldHRpbmcgYGFuaW1hdGlvblN0YXJ0YCB0aW1lLCB7QGxpbmsgYW5pbWF0aW9uTGFzdH0gY2FuIGJlIHNldCB0byB0aGUgc2FtZSB2YWx1ZSB0byBhdm9pZCBmaXJpbmcgZXZlbnRzXG5cdCAqIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBhbmltYXRpb24uICovXG5cdGFuaW1hdGlvblN0YXJ0ID0gMDtcblxuXHQvKiogVGhlIHRpbWUgaW4gc2Vjb25kcyBmb3IgdGhlIGxhc3QgZnJhbWUgb2YgdGhpcyBhbmltYXRpb24uIFBhc3QgdGhpcyB0aW1lLCBub24tbG9vcGluZyBhbmltYXRpb25zIGhvbGQgdGhlIHBvc2UgYXQgdGhpc1xuXHQgKiB0aW1lIHdoaWxlIGxvb3BpbmcgYW5pbWF0aW9ucyB3aWxsIGxvb3AgYmFjayB0byB7QGxpbmsgYW5pbWF0aW9uU3RhcnR9LiBEZWZhdWx0cyB0byB0aGUge0BsaW5rIEFuaW1hdGlvbi5kdXJhdGlvbn0uICovXG5cdGFuaW1hdGlvbkVuZCA9IDA7XG5cblxuXHQvKiogVGhlIHRpbWUgaW4gc2Vjb25kcyB0aGlzIGFuaW1hdGlvbiB3YXMgbGFzdCBhcHBsaWVkLiBTb21lIHRpbWVsaW5lcyB1c2UgdGhpcyBmb3Igb25lLXRpbWUgdHJpZ2dlcnMuIEZvciBleGFtcGxlLCB3aGVuXG5cdCAqIHRoaXMgYW5pbWF0aW9uIGlzIGFwcGxpZWQsIGV2ZW50IHRpbWVsaW5lcyB3aWxsIGZpcmUgYWxsIGV2ZW50cyBiZXR3ZWVuIHRoZSBgYW5pbWF0aW9uTGFzdGAgdGltZSAoZXhjbHVzaXZlKVxuXHQgKiBhbmQgYGFuaW1hdGlvblRpbWVgIChpbmNsdXNpdmUpLiBEZWZhdWx0cyB0byAtMSB0byBlbnN1cmUgdHJpZ2dlcnMgb24gZnJhbWUgMCBoYXBwZW4gdGhlIGZpcnN0IHRpbWUgdGhpc1xuXHQgKiBhbmltYXRpb24gaXMgYXBwbGllZC4gKi9cblx0YW5pbWF0aW9uTGFzdCA9IDA7XG5cblx0bmV4dEFuaW1hdGlvbkxhc3QgPSAwO1xuXG5cdC8qKiBTZWNvbmRzIHRvIHBvc3Rwb25lIHBsYXlpbmcgdGhlIGFuaW1hdGlvbi4gTXVzdCBiZSA+PSAwLiBXaGVuIHRoaXMgdHJhY2sgZW50cnkgaXMgdGhlIGN1cnJlbnQgdHJhY2sgZW50cnksXG5cdCAqIGBkZWxheWAgcG9zdHBvbmVzIGluY3JlbWVudGluZyB0aGUge0BsaW5rIHRyYWNrVGltZX0uIFdoZW4gdGhpcyB0cmFjayBlbnRyeSBpcyBxdWV1ZWQsIGBkZWxheWAgaXNcblx0ICogdGhlIHRpbWUgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHByZXZpb3VzIGFuaW1hdGlvbiB0byB3aGVuIHRoaXMgdHJhY2sgZW50cnkgd2lsbCBiZWNvbWUgdGhlIGN1cnJlbnQgdHJhY2sgZW50cnkgKGllIHdoZW5cblx0ICogdGhlIHByZXZpb3VzIHRyYWNrIGVudHJ5IHtAbGluayB0cmFja1RpbWV9ID49IHRoaXMgdHJhY2sgZW50cnkncyBgZGVsYXlgKS5cblx0ICpcblx0ICoge0BsaW5rIHRpbWVTY2FsZX0gYWZmZWN0cyB0aGUgZGVsYXkuXG5cdCAqXG5cdCAqIFdoZW4gcGFzc2luZyBgZGVsYXlgIDw9IDAgdG8ge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFkZEFuaW1hdGlvbn0gdGhpc1xuXHQgKiBgZGVsYXlgIGlzIHNldCB1c2luZyBhIG1peCBkdXJhdGlvbiBmcm9tIHtAbGluayBBbmltYXRpb25TdGF0ZURhdGF9LiBUbyBjaGFuZ2UgdGhlIHtAbGluayBtaXhEdXJhdGlvbn1cblx0ICogYWZ0ZXJ3YXJkLCB1c2Uge0BsaW5rIHNldE1peER1cmF0aW9ufSBzbyB0aGlzIGBkZWxheWAgaXMgYWRqdXN0ZWQuICovXG5cdGRlbGF5ID0gMDtcblxuXHQvKiogVGhlIHRpbWUgaW4gc2Vjb25kcyB0aGlzIHRyYWNrIGVudHJ5IGhhcyBiZWVuIHRoZSBjdXJyZW50IHRyYWNrIGVudHJ5LCBzdGFydGluZyBhdCAwIGFuZCBpbmNyZWFzaW5nIGZvcmV2ZXIuIENvbXBhcmUgdG9cblx0ICoge0BsaW5rIGdldEFuaW1hdGlvblRpbWV9LCB3aGljaCBpcyBhbHdheXMgYmV0d2VlbiB7QGxpbmsgYW5pbWF0aW9uU3RhcnR9IGFuZCB7QGxpbmsgYW5pbWF0aW9uRW5kfS5cblx0ICpcblx0ICogVGhlIHRyYWNrIHRpbWUgY2FuIGJlIHNldCB0byBzdGFydCB0aGUgYW5pbWF0aW9uIGF0IGEgdGltZSBvdGhlciB0aGFuIDAsIHdpdGhvdXQgYWZmZWN0aW5nIGxvb3BpbmcuIFdoZW4gZG9pbmcgc28sXG5cdCAqIHtAbGluayBhbmltYXRpb25MYXN0fSBjYW4gYmUgc2V0IHRvIHRoZSBzYW1lIHZhbHVlIHRvIGF2b2lkIGZpcmluZyBldmVudHMgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGFuaW1hdGlvbi5cblx0ICpcblx0ICogVG8gc2V0IHRoZSB0aW1lIGFuIGFuaW1hdGlvbiBzdGFydHMgYW5kIGxvb3BzLCB1c2Uge0BsaW5rIGFuaW1hdGlvblN0YXJ0fSBhbmQge0BsaW5rIGFuaW1hdGlvbkVuZH0uICovXG5cdHRyYWNrVGltZSA9IDA7XG5cblx0dHJhY2tMYXN0ID0gMDsgbmV4dFRyYWNrTGFzdCA9IDA7XG5cblx0LyoqIFRoZSB0cmFjayB0aW1lIGluIHNlY29uZHMgd2hlbiB0aGlzIGFuaW1hdGlvbiB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgdHJhY2suIERlZmF1bHRzIHRvIHRoZSBoaWdoZXN0IHBvc3NpYmxlIGZsb2F0XG5cdCAqIHZhbHVlLCBtZWFuaW5nIHRoZSBhbmltYXRpb24gd2lsbCBiZSBhcHBsaWVkIHVudGlsIGEgbmV3IGFuaW1hdGlvbiBpcyBzZXQgb3IgdGhlIHRyYWNrIGlzIGNsZWFyZWQuIElmIHRoZSB0cmFjayBlbmQgdGltZVxuXHQgKiBpcyByZWFjaGVkLCBubyBvdGhlciBhbmltYXRpb25zIGFyZSBxdWV1ZWQgZm9yIHBsYXliYWNrLCBhbmQgbWl4aW5nIGZyb20gYW55IHByZXZpb3VzIGFuaW1hdGlvbnMgaXMgY29tcGxldGUsIHRoZW4gdGhlXG5cdCAqIHByb3BlcnRpZXMga2V5ZWQgYnkgdGhlIGFuaW1hdGlvbiBhcmUgc2V0IHRvIHRoZSBzZXR1cCBwb3NlIGFuZCB0aGUgdHJhY2sgaXMgY2xlYXJlZC5cblx0ICpcblx0ICogVXN1YWxseSB5b3Ugd2FudCB0byB1c2Uge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFkZEVtcHR5QW5pbWF0aW9ufSByYXRoZXIgdGhhbiBoYXZlIHRoZSBhbmltYXRpb25cblx0ICogYWJydXB0bHkgY2Vhc2UgYmVpbmcgYXBwbGllZC4gKi9cblx0dHJhY2tFbmQgPSAwO1xuXG5cdC8qKiBNdWx0aXBsaWVyIGZvciB0aGUgZGVsdGEgdGltZSB3aGVuIHRoaXMgdHJhY2sgZW50cnkgaXMgdXBkYXRlZCwgY2F1c2luZyB0aW1lIGZvciB0aGlzIGFuaW1hdGlvbiB0byBwYXNzIHNsb3dlciBvclxuXHQgKiBmYXN0ZXIuIERlZmF1bHRzIHRvIDEuXG5cdCAqXG5cdCAqIFZhbHVlcyA8IDAgYXJlIG5vdCBzdXBwb3J0ZWQuIFRvIHBsYXkgYW4gYW5pbWF0aW9uIGluIHJldmVyc2UsIHVzZSB7QGxpbmsgcmV2ZXJzZX0uXG5cdCAqXG5cdCAqIHtAbGluayBtaXhUaW1lfSBpcyBub3QgYWZmZWN0ZWQgYnkgdHJhY2sgZW50cnkgdGltZSBzY2FsZSwgc28ge0BsaW5rIG1peER1cmF0aW9ufSBtYXkgbmVlZCB0byBiZSBhZGp1c3RlZCB0byBtYXRjaCB0aGVcblx0ICogYW5pbWF0aW9uIHNwZWVkLlxuXHQgKlxuXHQgKiBXaGVuIHVzaW5nIHtAbGluayBBbmltYXRpb25TdGF0ZS5hZGRBbmltYXRpb259IHdpdGggYSBgZGVsYXlgIDw9IDAsIHRoZVxuXHQgKiB7QGxpbmsgZGVsYXl9IGlzIHNldCB1c2luZyB0aGUgbWl4IGR1cmF0aW9uIGZyb20ge0BsaW5rIEFuaW1hdGlvblN0YXRlLmRhdGF9LCBhc3N1bWluZyB0aW1lIHNjYWxlIHRvIGJlIDEuIElmIHRoZSB0aW1lXG5cdCAqIHNjYWxlIGlzIG5vdCAxLCB0aGUgZGVsYXkgbWF5IG5lZWQgdG8gYmUgYWRqdXN0ZWQuXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgQW5pbWF0aW9uU3RhdGUudGltZVNjYWxlfSB0byBhZmZlY3QgYWxsIGFuaW1hdGlvbnMuICovXG5cdHRpbWVTY2FsZSA9IDA7XG5cblx0LyoqIFZhbHVlcyA8IDEgbWl4IHRoaXMgYW5pbWF0aW9uIHdpdGggdGhlIHNrZWxldG9uJ3MgY3VycmVudCBwb3NlIChlaXRoZXIgdGhlIHNldHVwIHBvc2Ugb3IgdGhlIHBvc2UgZnJvbSBsb3dlciB0cmFja3MpLlxuXHQgKiBEZWZhdWx0cyB0byAxLCB3aGljaCBvdmVyd3JpdGVzIHRoZSBza2VsZXRvbidzIGN1cnJlbnQgcG9zZSB3aXRoIHRoaXMgYW5pbWF0aW9uLlxuXHQgKlxuXHQgKiBBbHBoYSBzaG91bGQgYmUgMSBvbiB0cmFjayAwLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIGdldEFscGhhQXR0YWNobWVudFRocmVzaG9sZH0uICovXG5cdGFscGhhID0gMDtcblxuXHQvKiogU2Vjb25kcyBlbGFwc2VkIGZyb20gMCB0byB0aGUge0BsaW5rIG1peER1cmF0aW9ufSB3aGVuIG1peGluZyBmcm9tIHRoZSBwcmV2aW91cyBhbmltYXRpb24gdG8gdGhpcyBhbmltYXRpb24uIE1heVxuXHQgKiBiZSBzbGlnaHRseSBtb3JlIHRoYW4gYG1peER1cmF0aW9uYCB3aGVuIHRoZSBtaXggaXMgY29tcGxldGUuICovXG5cdG1peFRpbWUgPSAwO1xuXG5cdC8qKiBTZWNvbmRzIGZvciBtaXhpbmcgZnJvbSB0aGUgcHJldmlvdXMgYW5pbWF0aW9uIHRvIHRoaXMgYW5pbWF0aW9uLiBEZWZhdWx0cyB0byB0aGUgdmFsdWUgcHJvdmlkZWQgYnlcblx0ICoge0BsaW5rIEFuaW1hdGlvblN0YXRlRGF0YS5nZXRNaXh9IGJhc2VkIG9uIHRoZSBhbmltYXRpb24gYmVmb3JlIHRoaXMgYW5pbWF0aW9uIChpZiBhbnkpLlxuXHQgKlxuXHQgKiBBIG1peCBkdXJhdGlvbiBvZiAwIHN0aWxsIG5lZWRzIHRvIGJlIGFwcGxpZWQgb25lIG1vcmUgdGltZSB0byBtaXggb3V0LCBzbyB0aGUgdGhlIHByb3BlcnRpZXMgaXQgd2FzIGFuaW1hdGluZyBhcmVcblx0ICogcmV2ZXJ0ZWQuIEEgbWl4IGR1cmF0aW9uIG9mIDAgY2FuIGJlIHNldCBhdCBhbnkgdGltZSB0byBlbmQgdGhlIG1peCBvbiB0aGUgbmV4dFxuXHQgKiB7QGxpbmsgQW5pbWF0aW9uU3RhdGUudXBkYXRlIHwgdXBkYXRlfS5cblx0ICpcblx0ICogVGhlIGBtaXhEdXJhdGlvbmAgY2FuIGJlIHNldCBtYW51YWxseSByYXRoZXIgdGhhbiB1c2UgdGhlIHZhbHVlIGZyb21cblx0ICoge0BsaW5rIEFuaW1hdGlvblN0YXRlRGF0YS5nZXRNaXh9LiBJbiB0aGF0IGNhc2UsIHRoZSBgbWl4RHVyYXRpb25gIGNhbiBiZSBzZXQgZm9yIGEgbmV3XG5cdCAqIHRyYWNrIGVudHJ5IG9ubHkgYmVmb3JlIHtAbGluayBBbmltYXRpb25TdGF0ZS51cGRhdGV9IGlzIG5leHQgY2FsbGVkLlxuXHQgKlxuXHQgKiBXaGVuIHVzaW5nIHtAbGluayBBbmltYXRpb25TdGF0ZS5hZGRBbmltYXRpb259IHdpdGggYSBgZGVsYXlgIDw9IDAsIHRoZVxuXHQgKiB7QGxpbmsgZ2V0RGVsYXl9IGlzIHNldCB1c2luZyB0aGUgbWl4IGR1cmF0aW9uIGZyb20ge0BsaW5rIEFuaW1hdGlvblN0YXRlLmRhdGF9LiBJZiBgbWl4RHVyYXRpb25gIGlzIHNldFxuXHQgKiBhZnRlcndhcmQsIHRoZSBkZWxheSBuZWVkcyB0byBiZSBhZGp1c3RlZDpcblx0ICpcblx0ICogPHByZT5cblx0ICogZW50cnkubWl4RHVyYXRpb24gPSAwLjI1Ozxicj5cblx0ICogZW50cnkuZGVsYXkgPSBlbnRyeS5wcmV2aW91cy5nZXRUcmFja0NvbXBsZXRlKCkgLSBlbnRyeS5taXhEdXJhdGlvbiArIDA7XG5cdCAqIDwvcHJlPlxuXHQgKlxuXHQgKiBBbHRlcm5hdGl2ZWx5LCB1c2Uge0BsaW5rIHNldE1peER1cmF0aW9ufSB0byBzZXQgYm90aCB0aGUgbWl4IGR1cmF0aW9uIGFuZCByZWNvbXB1dGUgdGhlIGRlbGF5Ojxicj5cblx0ICpcblx0ICogPHByZT5cblx0ICBlbnRyeS5zZXRNaXhEdXJhdGlvbigwLjI1ZiwgMCk7IC8vIG1peER1cmF0aW9uLCBkZWxheVxuXHQgKiA8L3ByZT5cblx0ICovXG5cdG1peER1cmF0aW9uID0gMDtcblxuXHR0b3RhbEFscGhhID0gMDtcblxuXHRtaXhJbnRlcnBvbGF0aW9uOiBJbnRlcnBvbGF0aW9uID0gSW50ZXJwb2xhdGlvbi5saW5lYXI7XG5cblx0LyoqIFNldHMgYm90aCB7QGxpbmsgZ2V0TWl4RHVyYXRpb259IGFuZCB7QGxpbmsgZ2V0RGVsYXl9LlxuXHQgKiBAcGFyYW0gZGVsYXkgSWYgPiAwLCBzZXRzIHtAbGluayBnZXREZWxheX0uIElmIDw9IDAsIHRoZSBkZWxheSBzZXQgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBwcmV2aW91cyB0cmFjayBlbnRyeSBtaW51c1xuXHQgKiAgICAgICAgICAgdGhlIHNwZWNpZmllZCBtaXggZHVyYXRpb24gcGx1cyB0aGUgc3BlY2lmaWVkIGBkZWxheWAgKGllIHRoZSBtaXggZW5kcyBhdCAod2hlbiBgZGVsYXlgID1cblx0ICogICAgICAgICAgIDApIG9yIGJlZm9yZSAod2hlbiBgZGVsYXlgIDwgMCkgdGhlIHByZXZpb3VzIHRyYWNrIGVudHJ5IGR1cmF0aW9uKS4gSWYgdGhlIHByZXZpb3VzIGVudHJ5IGlzXG5cdCAqICAgICAgICAgICBsb29waW5nLCBpdHMgbmV4dCBsb29wIGNvbXBsZXRpb24gaXMgdXNlZCBpbnN0ZWFkIG9mIGl0cyBkdXJhdGlvbi4gKi9cblx0c2V0TWl4RHVyYXRpb24gKG1peER1cmF0aW9uOiBudW1iZXIsIGRlbGF5PzogbnVtYmVyKSB7XG5cdFx0dGhpcy5taXhEdXJhdGlvbiA9IG1peER1cmF0aW9uO1xuXHRcdGlmIChkZWxheSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRpZiAoZGVsYXkgPD0gMCkgZGVsYXkgPSB0aGlzLnByZXZpb3VzID09IG51bGwgPyAwIDogTWF0aC5tYXgoZGVsYXkgKyB0aGlzLnByZXZpb3VzLmdldFRyYWNrQ29tcGxldGUoKSAtIG1peER1cmF0aW9uLCAwKTtcblx0XHRcdHRoaXMuZGVsYXkgPSBkZWxheTtcblx0XHR9XG5cdH1cblxuXHQvKiogVGhlIGludGVycG9sYXRpb24gdG8gYXBwbHkgdG8gdGhlIG1peCBwZXJjZW50YWdlICh7QGxpbmsgbWl4VGltZX0gLyB7QGxpbmsgbWl4RHVyYXRpb259KSB3aGVuIG1peGluZyBmcm9tIHRoZSBwcmV2aW91c1xuXHQgKiBhbmltYXRpb24gdG8gdGhpcyBhbmltYXRpb24uIERlZmF1bHRzIHRvIGxpbmVhci4gKi9cblx0c2V0TWl4SW50ZXJwb2xhdGlvbiAobWl4SW50ZXJwb2xhdGlvbjogSW50ZXJwb2xhdGlvbikge1xuXHRcdGlmICghbWl4SW50ZXJwb2xhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwibWl4SW50ZXJwb2xhdGlvbiBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0dGhpcy5taXhJbnRlcnBvbGF0aW9uID0gbWl4SW50ZXJwb2xhdGlvbjtcblx0fVxuXG5cdG1peCAoKTogbnVtYmVyIHtcblx0XHRpZiAodGhpcy5taXhEdXJhdGlvbiA9PT0gMCkgcmV0dXJuIDE7XG5cdFx0bGV0IG1peCA9IHRoaXMubWl4VGltZSAvIHRoaXMubWl4RHVyYXRpb247XG5cdFx0aWYgKG1peCA+PSAxKSByZXR1cm4gMTtcblx0XHRpZiAodGhpcy5taXhJbnRlcnBvbGF0aW9uID09PSBJbnRlcnBvbGF0aW9uLmxpbmVhcikgcmV0dXJuIG1peDtcblx0XHRtaXggPSB0aGlzLm1peEludGVycG9sYXRpb24uYXBwbHkobWl4KTtcblx0XHRpZiAobWl4IDwgMCkgcmV0dXJuIDA7XG5cdFx0aWYgKG1peCA+IDEpIHJldHVybiAxO1xuXHRcdHJldHVybiBtaXg7XG5cdH1cblxuXHQvKiogRm9yIGVhY2ggdGltZWxpbmU6XG5cdCAqIC0gQml0IDAsIEZJUlNUOiAwID0gbWl4IGZyb20gY3VycmVudCBwb3NlLCAxID0gbWl4IGZyb20gc2V0dXAgcG9zZS4gVGltZWxpbmUgaXMgZmlyc3QgdG8gc2V0IHRoZSBwcm9wZXJ0eS5cblx0ICogLSBCaXQgMSwgSE9MRDogMCA9IG1peCBvdXQgdXNpbmcgYWxwaGFNaXgsIDEgPSBhcHBseSBmdWxsIGFscGhhIHRvIHByZXZlbnQgZGlwcGluZy4gVGltZWxpbmUgaXMgZmlyc3Qgb24gaXRzIHRyYWNrIHRvXG5cdCAqIHNldCB0aGUgcHJvcGVydHkgYW5kIHRoZSBuZXh0IGVudHJ5IChtaXhpbmdUbykgYWxzbyBzZXRzIGl0LiBXaGVuIGhlbGQsIHRpbWVsaW5lSG9sZE1peCdzIG1peCBjb250cm9scyBob3cgdGhlIGhvbGQgZmFkZXNcblx0ICogb3V0IChmb3IgMysgZW50cnkgY2hhaW5zIHdoZXJlIHRoZSBjaGFpbiBldmVudHVhbGx5IHN0b3BzIHNldHRpbmcgdGhlIHByb3BlcnR5KS4gKi9cblx0dGltZWxpbmVNb2RlID0gW10gYXMgbnVtYmVyW107XG5cdHRpbWVsaW5lSG9sZE1peCA9IFtdIGFzIFRyYWNrRW50cnlbXTtcblx0dGltZWxpbmVzUm90YXRpb24gPSBbXSBhcyBudW1iZXJbXTtcblxuXHRyZXNldCAoKSB7XG5cdFx0dGhpcy5uZXh0ID0gbnVsbDtcblx0XHR0aGlzLnByZXZpb3VzID0gbnVsbDtcblx0XHR0aGlzLm1peGluZ0Zyb20gPSBudWxsO1xuXHRcdHRoaXMubWl4aW5nVG8gPSBudWxsO1xuXHRcdHRoaXMubWl4SW50ZXJwb2xhdGlvbiA9IEludGVycG9sYXRpb24ubGluZWFyO1xuXHRcdHRoaXMuYW5pbWF0aW9uID0gbnVsbDtcblx0XHR0aGlzLmxpc3RlbmVyID0gbnVsbDtcblx0XHR0aGlzLnRpbWVsaW5lTW9kZS5sZW5ndGggPSAwO1xuXHRcdHRoaXMudGltZWxpbmVIb2xkTWl4Lmxlbmd0aCA9IDA7XG5cdFx0dGhpcy50aW1lbGluZXNSb3RhdGlvbi5sZW5ndGggPSAwO1xuXHR9XG5cblx0LyoqIFVzZXMge0BsaW5rIHRyYWNrVGltZX0gdG8gY29tcHV0ZSB0aGUgYGFuaW1hdGlvblRpbWVgLCB3aGljaCBpcyBhbHdheXMgYmV0d2VlbiB7QGxpbmsgYW5pbWF0aW9uU3RhcnR9IGFuZFxuXHQgKiB7QGxpbmsgYW5pbWF0aW9uRW5kfS4gV2hlbiBgdHJhY2tUaW1lYCBpcyAwLCBgYW5pbWF0aW9uVGltZWAgaXMgZXF1YWwgdG8gdGhlXG5cdCAqIGBhbmltYXRpb25TdGFydGAgdGltZS4gKi9cblx0Z2V0QW5pbWF0aW9uVGltZSAoKSB7XG5cdFx0aWYgKCF0aGlzLmxvb3ApIHJldHVybiBNYXRoLm1pbih0aGlzLnRyYWNrVGltZSArIHRoaXMuYW5pbWF0aW9uU3RhcnQsIHRoaXMuYW5pbWF0aW9uRW5kKTtcblx0XHRjb25zdCBkdXJhdGlvbiA9IHRoaXMuYW5pbWF0aW9uRW5kIC0gdGhpcy5hbmltYXRpb25TdGFydDtcblx0XHRpZiAoZHVyYXRpb24gPT09IDApIHJldHVybiB0aGlzLmFuaW1hdGlvblN0YXJ0O1xuXHRcdHJldHVybiAodGhpcy50cmFja1RpbWUgJSBkdXJhdGlvbikgKyB0aGlzLmFuaW1hdGlvblN0YXJ0O1xuXHR9XG5cblx0c2V0QW5pbWF0aW9uTGFzdCAoYW5pbWF0aW9uTGFzdDogbnVtYmVyKSB7XG5cdFx0dGhpcy5hbmltYXRpb25MYXN0ID0gYW5pbWF0aW9uTGFzdDtcblx0XHR0aGlzLm5leHRBbmltYXRpb25MYXN0ID0gYW5pbWF0aW9uTGFzdDtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIHRydWUgaWYgYXQgbGVhc3Qgb25lIGxvb3AgaGFzIGJlZW4gY29tcGxldGVkLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIuY29tcGxldGV9LiAqL1xuXHRpc0NvbXBsZXRlICgpIHtcblx0XHRyZXR1cm4gdGhpcy50cmFja1RpbWUgPj0gdGhpcy5hbmltYXRpb25FbmQgLSB0aGlzLmFuaW1hdGlvblN0YXJ0O1xuXHR9XG5cblx0LyoqIFdoZW4ge0BsaW5rIHNob3J0ZXN0Um90YXRpb259IGlzIGZhbHNlLCB0aGlzIGNsZWFycyB0aGUgZGlyZWN0aW9ucyBmb3IgbWl4aW5nIHRoaXMgZW50cnkncyByb3RhdGlvbi4gVGhpcyBjYW4gYmUgdXNlZnVsXG5cdCAqIHRvIGF2b2lkIGJvbmVzIHJvdGF0aW5nIHRoZSBsb25nIHdheSBhcm91bmQgd2hlbiB1c2luZyB7QGxpbmsgZ2V0QWxwaGF9IGFuZCBzdGFydGluZyBhbmltYXRpb25zIG9uIG90aGVyIHRyYWNrcy5cblx0ICpcblx0ICogTWl4aW5nIGludm9sdmVzIGZpbmRpbmcgYSByb3RhdGlvbiBiZXR3ZWVuIHR3byBvdGhlcnMuIFRoZXJlIGFyZSB0d28gcG9zc2libGUgc29sdXRpb25zOiB0aGUgc2hvcnQgb3IgdGhlIGxvbmcgd2F5XG5cdCAqIGFyb3VuZC4gV2hlbiB0aGUgdHdvIHJvdGF0aW9ucyBjaGFuZ2Ugb3ZlciB0aW1lLCB3aGljaCBkaXJlY3Rpb24gaXMgdGhlIHNob3J0IG9yIGxvbmcgd2F5IGNhbiBhbHNvIGNoYW5nZS4gSWYgdGhlIHNob3J0XG5cdCAqIHdheSB3YXMgYWx3YXlzIGNob3NlbiwgYm9uZXMgZmxpcCB0byB0aGUgb3RoZXIgc2lkZSB3aGVuIHRoYXQgZGlyZWN0aW9uIGJlY2FtZSB0aGUgbG9uZyB3YXkuIFRyYWNrRW50cnkgY2hvb3NlcyB0aGUgc2hvcnRcblx0ICogd2F5IHRoZSBmaXJzdCB0aW1lIGl0IGlzIGFwcGxpZWQgYW5kIHJlbWVtYmVycyB0aGF0IGRpcmVjdGlvbi4gUmVzZXR0aW5nIHRoYXQgZGlyZWN0aW9uIG1ha2VzIGl0IGNob29zZSBhIG5ldyBzaG9ydCB3YXlcblx0ICogb24gdGhlIG5leHQgYXBwbHkuICovXG5cdHJlc2V0Um90YXRpb25EaXJlY3Rpb25zICgpIHtcblx0XHR0aGlzLnRpbWVsaW5lc1JvdGF0aW9uLmxlbmd0aCA9IDA7XG5cdH1cblxuXHQvKiogSWYgdGhpcyB0cmFjayBlbnRyeSBpcyBub24tbG9vcGluZywgdGhpcyBpcyB0aGUgdHJhY2sgdGltZSBpbiBzZWNvbmRzIHdoZW4ge0BsaW5rIGFuaW1hdGlvbkVuZH0gaXMgcmVhY2hlZCwgb3IgdGhlXG5cdCAqIGN1cnJlbnQge0BsaW5rIHRyYWNrVGltZX0gaWYgaXQgaGFzIGFscmVhZHkgYmVlbiByZWFjaGVkLlxuXHQgKlxuXHQgKiBJZiB0aGlzIHRyYWNrIGVudHJ5IGlzIGxvb3BpbmcsIHRoaXMgaXMgdGhlIHRyYWNrIHRpbWUgd2hlbiB0aGlzIGFuaW1hdGlvbiB3aWxsIHJlYWNoIGl0cyBuZXh0IHtAbGluayBhbmltYXRpb25FbmR9ICh0aGVcblx0ICogbmV4dCBsb29wIGNvbXBsZXRpb24pLiAqL1xuXHRnZXRUcmFja0NvbXBsZXRlICgpIHtcblx0XHRjb25zdCBkdXJhdGlvbiA9IHRoaXMuYW5pbWF0aW9uRW5kIC0gdGhpcy5hbmltYXRpb25TdGFydDtcblx0XHRpZiAoZHVyYXRpb24gIT09IDApIHtcblx0XHRcdGlmICh0aGlzLmxvb3ApIHJldHVybiBkdXJhdGlvbiAqICgxICsgKCh0aGlzLnRyYWNrVGltZSAvIGR1cmF0aW9uKSB8IDApKTsgLy8gQ29tcGxldGlvbiBvZiBuZXh0IGxvb3AuXG5cdFx0XHRpZiAodGhpcy50cmFja1RpbWUgPCBkdXJhdGlvbikgcmV0dXJuIGR1cmF0aW9uOyAvLyBCZWZvcmUgZHVyYXRpb24uXG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLnRyYWNrVGltZTsgLy8gTmV4dCB1cGRhdGUuXG5cdH1cblxuXHQvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgdHJhY2sgZW50cnkgaGFzIGJlZW4gYXBwbGllZCBhdCBsZWFzdCBvbmNlLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFwcGx5fS4gKi9cblx0d2FzQXBwbGllZCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMubmV4dFRyYWNrTGFzdCAhPT0gLTE7XG5cdH1cblxuXHQvKiogUmV0dXJucyB0cnVlIGlmIHRoZXJlIGlzIGEge0BsaW5rIG5leHR9IHRyYWNrIGVudHJ5IGFuZCBpdCB3aWxsIGJlY29tZSB0aGUgY3VycmVudCB0cmFjayBlbnRyeSBkdXJpbmcgdGhlIG5leHRcblx0ICoge0BsaW5rIEFuaW1hdGlvblN0YXRlLnVwZGF0ZX0uICovXG5cdGlzTmV4dFJlYWR5ICgpIHtcblx0XHRyZXR1cm4gdGhpcy5uZXh0ICE9IG51bGwgJiYgdGhpcy5uZXh0VHJhY2tMYXN0IC0gdGhpcy5uZXh0LmRlbGF5ID49IDA7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIEV2ZW50UXVldWUge1xuXHRvYmplY3RzOiBBcnJheTxFdmVudFR5cGUgfCBUcmFja0VudHJ5IHwgRXZlbnQ+ID0gW107XG5cdGRyYWluRGlzYWJsZWQgPSBmYWxzZTtcblx0YW5pbVN0YXRlOiBBbmltYXRpb25TdGF0ZTtcblxuXHRjb25zdHJ1Y3RvciAoYW5pbVN0YXRlOiBBbmltYXRpb25TdGF0ZSkge1xuXHRcdHRoaXMuYW5pbVN0YXRlID0gYW5pbVN0YXRlO1xuXHR9XG5cblx0c3RhcnQgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goRXZlbnRUeXBlLnN0YXJ0KTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdFx0dGhpcy5hbmltU3RhdGUuYW5pbWF0aW9uc0NoYW5nZWQgPSB0cnVlO1xuXHR9XG5cblx0aW50ZXJydXB0IChlbnRyeTogVHJhY2tFbnRyeSkge1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKEV2ZW50VHlwZS5pbnRlcnJ1cHQpO1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKGVudHJ5KTtcblx0fVxuXG5cdGVuZCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHR0aGlzLm9iamVjdHMucHVzaChFdmVudFR5cGUuZW5kKTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdFx0dGhpcy5hbmltU3RhdGUuYW5pbWF0aW9uc0NoYW5nZWQgPSB0cnVlO1xuXHR9XG5cblx0ZGlzcG9zZSAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0XHR0aGlzLm9iamVjdHMucHVzaChFdmVudFR5cGUuZGlzcG9zZSk7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goZW50cnkpO1xuXHR9XG5cblx0Y29tcGxldGUgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goRXZlbnRUeXBlLmNvbXBsZXRlKTtcblx0XHR0aGlzLm9iamVjdHMucHVzaChlbnRyeSk7XG5cdH1cblxuXHRldmVudCAoZW50cnk6IFRyYWNrRW50cnksIGV2ZW50OiBFdmVudCkge1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKEV2ZW50VHlwZS5ldmVudCk7XG5cdFx0dGhpcy5vYmplY3RzLnB1c2goZW50cnkpO1xuXHRcdHRoaXMub2JqZWN0cy5wdXNoKGV2ZW50KTtcblx0fVxuXG5cdGRyYWluICgpIHtcblx0XHRpZiAodGhpcy5kcmFpbkRpc2FibGVkKSByZXR1cm47IC8vIE5vdCByZWVudHJhbnQuXG5cdFx0dGhpcy5kcmFpbkRpc2FibGVkID0gdHJ1ZTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5vYmplY3RzLmxlbmd0aDsgaSArPSAyKSB7XG5cdFx0XHRjb25zdCBvYmplY3RzID0gdGhpcy5vYmplY3RzO1xuXHRcdFx0Y29uc3QgdHlwZSA9IG9iamVjdHNbaV0gYXMgRXZlbnRUeXBlO1xuXHRcdFx0Y29uc3QgZW50cnkgPSBvYmplY3RzW2kgKyAxXSBhcyBUcmFja0VudHJ5O1xuXHRcdFx0Y29uc3QgbGlzdGVuZXJzID0gdGhpcy5hbmltU3RhdGUubGlzdGVuZXJzLnNsaWNlKCk7XG5cdFx0XHRzd2l0Y2ggKHR5cGUpIHtcblx0XHRcdFx0Y2FzZSBFdmVudFR5cGUuc3RhcnQ6XG5cdFx0XHRcdFx0aWYgKGVudHJ5Lmxpc3RlbmVyPy5zdGFydCkgZW50cnkubGlzdGVuZXIuc3RhcnQoZW50cnkpO1xuXHRcdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpaV07XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIuc3RhcnQpIGxpc3RlbmVyLnN0YXJ0KGVudHJ5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgRXZlbnRUeXBlLmludGVycnVwdDpcblx0XHRcdFx0XHRpZiAoZW50cnkubGlzdGVuZXI/LmludGVycnVwdCkgZW50cnkubGlzdGVuZXIuaW50ZXJydXB0KGVudHJ5KTtcblx0XHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRcdFx0Y29uc3QgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaWldO1xuXHRcdFx0XHRcdFx0aWYgKGxpc3RlbmVyLmludGVycnVwdCkgbGlzdGVuZXIuaW50ZXJydXB0KGVudHJ5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9GYWxsdGhyb3VnaFN3aXRjaENsYXVzZTogcmVmZXJlbmNlIHJ1bnRpbWUgZG9lcyBmYWxsIHRocm91Z2hcblx0XHRcdFx0Y2FzZSBFdmVudFR5cGUuZW5kOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lcj8uZW5kKSBlbnRyeS5saXN0ZW5lci5lbmQoZW50cnkpO1xuXHRcdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpaV07XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIuZW5kKSBsaXN0ZW5lci5lbmQoZW50cnkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0Ly8gRmFsbCB0aHJvdWdoLlxuXHRcdFx0XHRjYXNlIEV2ZW50VHlwZS5kaXNwb3NlOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lcj8uZGlzcG9zZSkgZW50cnkubGlzdGVuZXIuZGlzcG9zZShlbnRyeSk7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IGxpc3RlbmVycy5sZW5ndGg7IGlpKyspIHtcblx0XHRcdFx0XHRcdGNvbnN0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2lpXTtcblx0XHRcdFx0XHRcdGlmIChsaXN0ZW5lci5kaXNwb3NlKSBsaXN0ZW5lci5kaXNwb3NlKGVudHJ5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5hbmltU3RhdGUudHJhY2tFbnRyeVBvb2wuZnJlZShlbnRyeSk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgRXZlbnRUeXBlLmNvbXBsZXRlOlxuXHRcdFx0XHRcdGlmIChlbnRyeS5saXN0ZW5lcj8uY29tcGxldGUpIGVudHJ5Lmxpc3RlbmVyLmNvbXBsZXRlKGVudHJ5KTtcblx0XHRcdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRcdFx0Y29uc3QgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaWldO1xuXHRcdFx0XHRcdFx0aWYgKGxpc3RlbmVyLmNvbXBsZXRlKSBsaXN0ZW5lci5jb21wbGV0ZShlbnRyeSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIEV2ZW50VHlwZS5ldmVudDoge1xuXHRcdFx0XHRcdGNvbnN0IGV2ZW50ID0gb2JqZWN0c1tpKysgKyAyXSBhcyBFdmVudDtcblx0XHRcdFx0XHRpZiAoZW50cnkubGlzdGVuZXI/LmV2ZW50KSBlbnRyeS5saXN0ZW5lci5ldmVudChlbnRyeSwgZXZlbnQpO1xuXHRcdFx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpaV07XG5cdFx0XHRcdFx0XHRpZiAobGlzdGVuZXIuZXZlbnQpIGxpc3RlbmVyLmV2ZW50KGVudHJ5LCBldmVudCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuY2xlYXIoKTtcblxuXHRcdHRoaXMuZHJhaW5EaXNhYmxlZCA9IGZhbHNlO1xuXHR9XG5cblx0Y2xlYXIgKCkge1xuXHRcdHRoaXMub2JqZWN0cy5sZW5ndGggPSAwO1xuXHR9XG59XG5cbmV4cG9ydCBlbnVtIEV2ZW50VHlwZSB7XG5cdHN0YXJ0LCBpbnRlcnJ1cHQsIGVuZCwgZGlzcG9zZSwgY29tcGxldGUsIGV2ZW50XG59XG5cbi8qKiBUaGUgaW50ZXJmYWNlIHRvIGltcGxlbWVudCBmb3IgcmVjZWl2aW5nIFRyYWNrRW50cnkgZXZlbnRzLiBJdCBpcyBhbHdheXMgc2FmZSB0byBjYWxsIEFuaW1hdGlvblN0YXRlIG1ldGhvZHMgd2hlbiByZWNlaXZpbmdcbiAqIGV2ZW50cy5cbiAqXG4gKiBUcmFja0VudHJ5IGV2ZW50cyBhcmUgY29sbGVjdGVkIGR1cmluZyB7QGxpbmsgQW5pbWF0aW9uU3RhdGUudXBkYXRlfSBhbmQge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFwcGx5fSBhbmRcbiAqIGZpcmVkIG9ubHkgYWZ0ZXIgdGhvc2UgbWV0aG9kcyBhcmUgZmluaXNoZWQuXG4gKlxuICogU2VlIHtAbGluayBUcmFja0VudHJ5Lmxpc3RlbmVyfSBhbmRcbiAqIHtAbGluayBBbmltYXRpb25TdGF0ZS5hZGRMaXN0ZW5lcn0uICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIge1xuXHQvKiogSW52b2tlZCB3aGVuIHRoaXMgZW50cnkgaGFzIGJlZW4gc2V0IGFzIHRoZSBjdXJyZW50IGVudHJ5LiB7QGxpbmsgZW5kfSB3aWxsIG9jY3VyIHdoZW4gdGhpcyBlbnRyeSB3aWxsIG5vXG5cdCAqIGxvbmdlciBiZSBhcHBsaWVkLlxuXHQgKlxuXHQgKiBXaGVuIHRoaXMgZXZlbnQgaXMgdHJpZ2dlcmVkIGJ5IGNhbGxpbmcge0BsaW5rIEFuaW1hdGlvblN0YXRlLnNldEFuaW1hdGlvbn0sIHRha2UgY2FyZSBub3QgdG9cblx0ICogY2FsbCB7QGxpbmsgQW5pbWF0aW9uU3RhdGUudXBkYXRlfSB1bnRpbCBhZnRlciB0aGUgVHJhY2tFbnRyeSBoYXMgYmVlbiBjb25maWd1cmVkLiAqL1xuXHRzdGFydD86IChlbnRyeTogVHJhY2tFbnRyeSkgPT4gdm9pZDtcblxuXHQvKiogSW52b2tlZCB3aGVuIGFub3RoZXIgZW50cnkgaGFzIHJlcGxhY2VkIHRoaXMgZW50cnkgYXMgdGhlIGN1cnJlbnQgZW50cnkuIFRoaXMgZW50cnkgbWF5IGNvbnRpbnVlIGJlaW5nIGFwcGxpZWQgZm9yXG5cdCAqIG1peGluZy4gKi9cblx0aW50ZXJydXB0PzogKGVudHJ5OiBUcmFja0VudHJ5KSA9PiB2b2lkO1xuXG5cdC8qKiBJbnZva2VkIHdoZW4gdGhpcyBlbnRyeSB3aWxsIG5ldmVyIGJlIGFwcGxpZWQgYWdhaW4uIFRoaXMgb25seSBvY2N1cnMgaWYgdGhpcyBlbnRyeSBoYXMgcHJldmlvdXNseSBiZWVuIHNldCBhcyB0aGVcblx0ICogY3VycmVudCBlbnRyeSAoe0BsaW5rIHN0YXJ0fSB3YXMgaW52b2tlZCkuICovXG5cdGVuZD86IChlbnRyeTogVHJhY2tFbnRyeSkgPT4gdm9pZDtcblxuXHQvKiogSW52b2tlZCB3aGVuIHRoaXMgZW50cnkgd2lsbCBiZSBkaXNwb3NlZC4gVGhpcyBtYXkgb2NjdXIgd2l0aG91dCB0aGUgZW50cnkgZXZlciBiZWluZyBzZXQgYXMgdGhlIGN1cnJlbnQgZW50cnkuXG5cdCAqIFJlZmVyZW5jZXMgdG8gdGhlIGVudHJ5IHNob3VsZCBub3QgYmUga2VwdCBhZnRlciBkaXNwb3NlIGlzIGNhbGxlZCwgYXMgaXQgbWF5IGJlIGRlc3Ryb3llZCBvciByZXVzZWQuICovXG5cdGRpc3Bvc2U/OiAoZW50cnk6IFRyYWNrRW50cnkpID0+IHZvaWQ7XG5cblx0LyoqIEludm9rZWQgZXZlcnkgdGltZSB0aGlzIGVudHJ5J3MgYW5pbWF0aW9uIGNvbXBsZXRlcyBhIGxvb3AuIFRoaXMgbWF5IG9jY3VyIGR1cmluZyBtaXhpbmcgKGFmdGVyXG5cdCAqIHtAbGluayBpbnRlcnJ1cHR9KS5cblx0ICpcblx0ICogSWYgdGhpcyBlbnRyeSdzIHtAbGluayBUcmFja0VudHJ5Lm1peGluZ1RvfSBpcyBub3QgbnVsbCwgdGhpcyBlbnRyeSBpcyBtaXhpbmcgb3V0IChpdCBpcyBub3QgdGhlIGN1cnJlbnQgZW50cnkpLlxuXHQgKlxuXHQgKiBCZWNhdXNlIHRoaXMgZXZlbnQgaXMgdHJpZ2dlcmVkIGF0IHRoZSBlbmQgb2Yge0BsaW5rIEFuaW1hdGlvblN0YXRlLmFwcGx5fSwgYW55IGFuaW1hdGlvbnMgc2V0IGluIHJlc3BvbnNlIHRvXG5cdCAqIHRoZSBldmVudCB3b24ndCBiZSBhcHBsaWVkIHVudGlsIHRoZSBuZXh0IHRpbWUgdGhlIEFuaW1hdGlvblN0YXRlIGlzIGFwcGxpZWQuICovXG5cdGNvbXBsZXRlPzogKGVudHJ5OiBUcmFja0VudHJ5KSA9PiB2b2lkO1xuXG5cdC8qKiBJbnZva2VkIHdoZW4gdGhpcyBlbnRyeSdzIGFuaW1hdGlvbiB0cmlnZ2VycyBhbiBldmVudC4gKi9cblx0ZXZlbnQ/OiAoZW50cnk6IFRyYWNrRW50cnksIGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFuaW1hdGlvblN0YXRlQWRhcHRlciBpbXBsZW1lbnRzIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIge1xuXHRzdGFydCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0fVxuXG5cdGludGVycnVwdCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0fVxuXG5cdGVuZCAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0fVxuXG5cdGRpc3Bvc2UgKGVudHJ5OiBUcmFja0VudHJ5KSB7XG5cdH1cblxuXHRjb21wbGV0ZSAoZW50cnk6IFRyYWNrRW50cnkpIHtcblx0fVxuXG5cdGV2ZW50IChlbnRyeTogVHJhY2tFbnRyeSwgZXZlbnQ6IEV2ZW50KSB7XG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IFNVQlNFUVVFTlQgPSAwO1xuZXhwb3J0IGNvbnN0IEZJUlNUID0gMTtcbmV4cG9ydCBjb25zdCBIT0xEID0gMjtcbmV4cG9ydCBjb25zdCBIT0xEX0ZJUlNUID0gMztcblxuZXhwb3J0IGNvbnN0IFNFVFVQID0gMTtcbmV4cG9ydCBjb25zdCBSRVRBSU4gPSAyO1xuIl19