@angular/core 18.0.0-next.5 → 18.0.0-next.6

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 (82) hide show
  1. package/esm2022/primitives/event-dispatch/contract_binary.mjs +10 -0
  2. package/esm2022/primitives/event-dispatch/index.mjs +13 -0
  3. package/esm2022/primitives/event-dispatch/src/a11y_click.mjs +54 -0
  4. package/esm2022/primitives/event-dispatch/src/accessibility.mjs +35 -0
  5. package/esm2022/primitives/event-dispatch/src/attribute.mjs +72 -0
  6. package/esm2022/primitives/event-dispatch/src/base_dispatcher.mjs +196 -0
  7. package/esm2022/primitives/event-dispatch/src/cache.mjs +95 -0
  8. package/esm2022/primitives/event-dispatch/src/char.mjs +35 -0
  9. package/esm2022/primitives/event-dispatch/src/custom_events.mjs +63 -0
  10. package/esm2022/primitives/event-dispatch/src/dispatcher.mjs +254 -0
  11. package/esm2022/primitives/event-dispatch/src/dom.mjs +48 -0
  12. package/esm2022/primitives/event-dispatch/src/earlyeventcontract.mjs +36 -0
  13. package/esm2022/primitives/event-dispatch/src/event.mjs +638 -0
  14. package/esm2022/primitives/event-dispatch/src/event_contract_container.mjs +63 -0
  15. package/esm2022/primitives/event-dispatch/src/event_contract_defines.mjs +48 -0
  16. package/esm2022/primitives/event-dispatch/src/event_contract_multi_container.mjs +192 -0
  17. package/esm2022/primitives/event-dispatch/src/event_handler.mjs +9 -0
  18. package/esm2022/primitives/event-dispatch/src/event_info.mjs +199 -0
  19. package/esm2022/primitives/event-dispatch/src/event_type.mjs +244 -0
  20. package/esm2022/primitives/event-dispatch/src/eventcontract.mjs +675 -0
  21. package/esm2022/primitives/event-dispatch/src/key_code.mjs +21 -0
  22. package/esm2022/primitives/event-dispatch/src/legacy_dispatcher.mjs +9 -0
  23. package/esm2022/primitives/event-dispatch/src/property.mjs +35 -0
  24. package/esm2022/primitives/event-dispatch/src/register_events.mjs +32 -0
  25. package/esm2022/primitives/event-dispatch/src/replay.mjs +389 -0
  26. package/esm2022/primitives/event-dispatch/src/restriction.mjs +15 -0
  27. package/esm2022/primitives/signals/index.mjs +3 -3
  28. package/esm2022/primitives/signals/src/computed.mjs +5 -3
  29. package/esm2022/primitives/signals/src/graph.mjs +14 -9
  30. package/esm2022/primitives/signals/src/signal.mjs +2 -2
  31. package/esm2022/primitives/signals/src/watch.mjs +2 -2
  32. package/esm2022/src/change_detection/scheduling/zoneless_scheduling_impl.mjs +50 -5
  33. package/esm2022/src/core.mjs +2 -1
  34. package/esm2022/src/core_private_export.mjs +2 -1
  35. package/esm2022/src/defer/instructions.mjs +31 -8
  36. package/esm2022/src/di/host_tag_name_token.mjs +65 -0
  37. package/esm2022/src/di/index.mjs +2 -1
  38. package/esm2022/src/errors.mjs +1 -1
  39. package/esm2022/src/hydration/annotate.mjs +15 -1
  40. package/esm2022/src/hydration/event_replay.mjs +181 -0
  41. package/esm2022/src/hydration/tokens.mjs +6 -1
  42. package/esm2022/src/pending_tasks.mjs +54 -11
  43. package/esm2022/src/render3/component_ref.mjs +1 -1
  44. package/esm2022/src/render3/context_discovery.mjs +15 -1
  45. package/esm2022/src/render3/instructions/control_flow.mjs +50 -3
  46. package/esm2022/src/render3/list_reconciliation.mjs +41 -1
  47. package/esm2022/src/util/callback_scheduler.mjs +13 -2
  48. package/esm2022/src/version.mjs +1 -1
  49. package/esm2022/src/zone/ng_zone.mjs +22 -6
  50. package/esm2022/testing/src/async.mjs +2 -10
  51. package/esm2022/testing/src/defer.mjs +1 -2
  52. package/esm2022/testing/src/logger.mjs +3 -3
  53. package/event-dispatch-contract.min.js +1 -1
  54. package/fesm2022/core.mjs +516 -39
  55. package/fesm2022/core.mjs.map +1 -1
  56. package/fesm2022/primitives/event-dispatch.mjs +3044 -0
  57. package/fesm2022/primitives/event-dispatch.mjs.map +1 -0
  58. package/fesm2022/primitives/signals.mjs +17 -10
  59. package/fesm2022/primitives/signals.mjs.map +1 -1
  60. package/fesm2022/rxjs-interop.mjs +1 -1
  61. package/fesm2022/testing.mjs +3 -12
  62. package/fesm2022/testing.mjs.map +1 -1
  63. package/index.d.ts +75 -13
  64. package/package.json +7 -1
  65. package/primitives/event-dispatch/index.d.ts +627 -0
  66. package/primitives/signals/index.d.ts +1 -1
  67. package/rxjs-interop/index.d.ts +1 -1
  68. package/schematics/migrations/{transfer-state → http-providers}/bundle.js +254 -68
  69. package/schematics/migrations/http-providers/bundle.js.map +7 -0
  70. package/schematics/migrations/invalid-two-way-bindings/bundle.js +659 -337
  71. package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
  72. package/schematics/migrations.json +6 -16
  73. package/schematics/ng-generate/control-flow-migration/bundle.js +667 -345
  74. package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
  75. package/schematics/ng-generate/standalone-migration/bundle.js +1030 -660
  76. package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
  77. package/testing/index.d.ts +2 -9
  78. package/schematics/migrations/block-template-entities/bundle.js +0 -22808
  79. package/schematics/migrations/block-template-entities/bundle.js.map +0 -7
  80. package/schematics/migrations/compiler-options/bundle.js +0 -582
  81. package/schematics/migrations/compiler-options/bundle.js.map +0 -7
  82. package/schematics/migrations/transfer-state/bundle.js.map +0 -7
@@ -0,0 +1,638 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import * as dom from './dom';
9
+ import { EventType } from './event_type';
10
+ import { KeyCode } from './key_code';
11
+ /**
12
+ * Gets a browser event type, if it would differ from the JSAction event type.
13
+ */
14
+ export function getBrowserEventType(eventType) {
15
+ // Mouseenter and mouseleave events are not handled directly because they
16
+ // are not available everywhere. In browsers where they are available, they
17
+ // don't bubble and aren't visible at the container boundary. Instead, we
18
+ // synthesize the mouseenter and mouseleave events from mouseover and
19
+ // mouseout events, respectively. Cf. eventcontract.js.
20
+ if (eventType === EventType.MOUSEENTER) {
21
+ return EventType.MOUSEOVER;
22
+ }
23
+ else if (eventType === EventType.MOUSELEAVE) {
24
+ return EventType.MOUSEOUT;
25
+ }
26
+ else if (eventType === EventType.POINTERENTER) {
27
+ return EventType.POINTEROVER;
28
+ }
29
+ else if (eventType === EventType.POINTERLEAVE) {
30
+ return EventType.POINTEROUT;
31
+ }
32
+ return eventType;
33
+ }
34
+ /**
35
+ * Registers the event handler function with the given DOM element for
36
+ * the given event type.
37
+ *
38
+ * @param element The element.
39
+ * @param eventType The event type.
40
+ * @param handler The handler function to install.
41
+ * @return Information needed to uninstall the event handler eventually.
42
+ */
43
+ export function addEventListener(element, eventType, handler) {
44
+ // All event handlers are registered in the bubbling
45
+ // phase.
46
+ //
47
+ // All browsers support focus and blur, but these events only are propagated
48
+ // in the capture phase. Very legacy browsers do not support focusin or
49
+ // focusout.
50
+ //
51
+ // It would be a bad idea to register all event handlers in the
52
+ // capture phase because then regular onclick handlers would not be
53
+ // executed at all on events that trigger a jsaction. That's not
54
+ // entirely what we want, at least for now.
55
+ //
56
+ // Error and load events (i.e. on images) do not bubble so they are also
57
+ // handled in the capture phase.
58
+ let capture = false;
59
+ if (eventType === EventType.FOCUS ||
60
+ eventType === EventType.BLUR ||
61
+ eventType === EventType.ERROR ||
62
+ eventType === EventType.LOAD ||
63
+ eventType === EventType.TOGGLE) {
64
+ capture = true;
65
+ }
66
+ element.addEventListener(eventType, handler, capture);
67
+ return { eventType, handler, capture };
68
+ }
69
+ /**
70
+ * Removes the event handler for the given event from the element.
71
+ * the given event type.
72
+ *
73
+ * @param element The element.
74
+ * @param info The information needed to deregister the handler, as returned by
75
+ * addEventListener(), above.
76
+ */
77
+ export function removeEventListener(element, info) {
78
+ if (element.removeEventListener) {
79
+ element.removeEventListener(info.eventType, info.handler, info.capture);
80
+ // `detachEvent` is an old DOM API.
81
+ // tslint:disable-next-line:no-any
82
+ }
83
+ else if (element.detachEvent) {
84
+ // `detachEvent` is an old DOM API.
85
+ // tslint:disable-next-line:no-any
86
+ element.detachEvent(`on${info.eventType}`, info.handler);
87
+ }
88
+ }
89
+ /**
90
+ * Cancels propagation of an event.
91
+ * @param e The event to cancel propagation for.
92
+ */
93
+ export function stopPropagation(e) {
94
+ e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
95
+ }
96
+ /**
97
+ * Prevents the default action of an event.
98
+ * @param e The event to prevent the default action for.
99
+ */
100
+ export function preventDefault(e) {
101
+ e.preventDefault ? e.preventDefault() : (e.returnValue = false);
102
+ }
103
+ /**
104
+ * Gets the target Element of the event. In Firefox, a text node may appear as
105
+ * the target of the event, in which case we return the parent element of the
106
+ * text node.
107
+ * @param e The event to get the target of.
108
+ * @return The target element.
109
+ */
110
+ export function getTarget(e) {
111
+ let el = e.target;
112
+ // In Firefox, the event may have a text node as its target. We always
113
+ // want the parent Element the text node belongs to, however.
114
+ if (!el.getAttribute && el.parentNode) {
115
+ el = el.parentNode;
116
+ }
117
+ return el;
118
+ }
119
+ /**
120
+ * Whether we are on a Mac. Not pulling in useragent just for this.
121
+ */
122
+ let isMac = typeof navigator !== 'undefined' && /Macintosh/.test(navigator.userAgent);
123
+ /**
124
+ * Determines and returns whether the given event (which is assumed to be a
125
+ * click event) is a middle click.
126
+ * NOTE: There is not a consistent way to identify middle click
127
+ * http://www.unixpapa.com/js/mouse.html
128
+ */
129
+ function isMiddleClick(e) {
130
+ return (
131
+ // `which` is an old DOM API.
132
+ // tslint:disable-next-line:no-any
133
+ e.which === 2 ||
134
+ // `which` is an old DOM API.
135
+ // tslint:disable-next-line:no-any
136
+ (e.which == null &&
137
+ // `button` is an old DOM API.
138
+ // tslint:disable-next-line:no-any
139
+ e.button === 4) // middle click for IE
140
+ );
141
+ }
142
+ /**
143
+ * Determines and returns whether the given event (which is assumed
144
+ * to be a click event) is modified. A middle click is considered a modified
145
+ * click to retain the default browser action, which opens a link in a new tab.
146
+ * @param e The event.
147
+ * @return Whether the given event is modified.
148
+ */
149
+ export function isModifiedClickEvent(e) {
150
+ return (
151
+ // `metaKey` is an old DOM API.
152
+ // tslint:disable-next-line:no-any
153
+ (isMac && e.metaKey) ||
154
+ // `ctrlKey` is an old DOM API.
155
+ // tslint:disable-next-line:no-any
156
+ (!isMac && e.ctrlKey) ||
157
+ isMiddleClick(e) ||
158
+ // `shiftKey` is an old DOM API.
159
+ // tslint:disable-next-line:no-any
160
+ e.shiftKey);
161
+ }
162
+ /** Whether we are on WebKit (e.g., Chrome). */
163
+ export const isWebKit = typeof navigator !== 'undefined' &&
164
+ !/Opera/.test(navigator.userAgent) &&
165
+ /WebKit/.test(navigator.userAgent);
166
+ /** Whether we are on IE. */
167
+ export const isIe = typeof navigator !== 'undefined' &&
168
+ (/MSIE/.test(navigator.userAgent) || /Trident/.test(navigator.userAgent));
169
+ /** Whether we are on Gecko (e.g., Firefox). */
170
+ export const isGecko = typeof navigator !== 'undefined' &&
171
+ !/Opera|WebKit/.test(navigator.userAgent) &&
172
+ /Gecko/.test(navigator.product);
173
+ /**
174
+ * Determines and returns whether the given element is a valid target for
175
+ * keypress/keydown DOM events that act like regular DOM clicks.
176
+ * @param el The element.
177
+ * @return Whether the given element is a valid action key target.
178
+ */
179
+ export function isValidActionKeyTarget(el) {
180
+ if (!('getAttribute' in el)) {
181
+ return false;
182
+ }
183
+ if (isTextControl(el)) {
184
+ return false;
185
+ }
186
+ if (isNativelyActivatable(el)) {
187
+ return false;
188
+ }
189
+ // `isContentEditable` is an old DOM API.
190
+ // tslint:disable-next-line:no-any
191
+ if (el.isContentEditable) {
192
+ return false;
193
+ }
194
+ return true;
195
+ }
196
+ /**
197
+ * Whether an event has a modifier key activated.
198
+ * @param e The event.
199
+ * @return True, if a modifier key is activated.
200
+ */
201
+ function hasModifierKey(e) {
202
+ return (
203
+ // `ctrlKey` is an old DOM API.
204
+ // tslint:disable-next-line:no-any
205
+ e.ctrlKey ||
206
+ // `shiftKey` is an old DOM API.
207
+ // tslint:disable-next-line:no-any
208
+ e.shiftKey ||
209
+ // `altKey` is an old DOM API.
210
+ // tslint:disable-next-line:no-any
211
+ e.altKey ||
212
+ // `metaKey` is an old DOM API.
213
+ // tslint:disable-next-line:no-any
214
+ e.metaKey);
215
+ }
216
+ /**
217
+ * Determines and returns whether the given event has a target that already
218
+ * has event handlers attached because it is a native HTML control. Used to
219
+ * determine if preventDefault should be called when isActionKeyEvent is true.
220
+ * @param e The event.
221
+ * @return If preventDefault should be called.
222
+ */
223
+ export function shouldCallPreventDefaultOnNativeHtmlControl(e) {
224
+ const el = getTarget(e);
225
+ const tagName = el.tagName.toUpperCase();
226
+ const role = (el.getAttribute('role') || '').toUpperCase();
227
+ if (tagName === 'BUTTON' || role === 'BUTTON') {
228
+ return true;
229
+ }
230
+ if (!isNativeHTMLControl(el)) {
231
+ return false;
232
+ }
233
+ if (tagName === 'A') {
234
+ return false;
235
+ }
236
+ /**
237
+ * Fix for physical d-pads on feature phone platforms; the native event
238
+ * (ie. isTrusted: true) needs to fire to show the OPTION list. See
239
+ * b/135288469 for more info.
240
+ */
241
+ if (tagName === 'SELECT') {
242
+ return false;
243
+ }
244
+ if (processSpace(el)) {
245
+ return false;
246
+ }
247
+ if (isTextControl(el)) {
248
+ return false;
249
+ }
250
+ return true;
251
+ }
252
+ /**
253
+ * Determines and returns whether the given event acts like a regular DOM click,
254
+ * and should be handled instead of the click. If this returns true, the caller
255
+ * will call preventDefault() to prevent a possible duplicate event.
256
+ * This is represented by a keypress (keydown on Gecko browsers) on Enter or
257
+ * Space key.
258
+ * @param e The event.
259
+ * @return True, if the event emulates a DOM click.
260
+ */
261
+ export function isActionKeyEvent(e) {
262
+ let key =
263
+ // `which` is an old DOM API.
264
+ // tslint:disable-next-line:no-any
265
+ e.which ||
266
+ // `keyCode` is an old DOM API.
267
+ // tslint:disable-next-line:no-any
268
+ e.keyCode;
269
+ if (!key && e.key) {
270
+ key = ACTION_KEY_TO_KEYCODE[e.key];
271
+ }
272
+ if (isWebKit && key === KeyCode.MAC_ENTER) {
273
+ key = KeyCode.ENTER;
274
+ }
275
+ if (key !== KeyCode.ENTER && key !== KeyCode.SPACE) {
276
+ return false;
277
+ }
278
+ const el = getTarget(e);
279
+ if (e.type !== EventType.KEYDOWN || !isValidActionKeyTarget(el) || hasModifierKey(e)) {
280
+ return false;
281
+ }
282
+ // For <input type="checkbox">, we must only handle the browser's native click
283
+ // event, so that the browser can toggle the checkbox.
284
+ if (processSpace(el) && key === KeyCode.SPACE) {
285
+ return false;
286
+ }
287
+ // If this element is non-focusable, ignore stray keystrokes (b/18337209)
288
+ // Sscreen readers can move without tab focus, so any tabIndex is focusable.
289
+ // See B/21809604
290
+ if (!isFocusable(el)) {
291
+ return false;
292
+ }
293
+ const type = (el.getAttribute('role') ||
294
+ el.type ||
295
+ el.tagName).toUpperCase();
296
+ const isSpecificTriggerKey = IDENTIFIER_TO_KEY_TRIGGER_MAPPING[type] % key === 0;
297
+ const isDefaultTriggerKey = !(type in IDENTIFIER_TO_KEY_TRIGGER_MAPPING) && key === KeyCode.ENTER;
298
+ const hasType = el.tagName.toUpperCase() !== 'INPUT' || !!el.type;
299
+ return (isSpecificTriggerKey || isDefaultTriggerKey) && hasType;
300
+ }
301
+ /**
302
+ * Checks whether a DOM element can receive keyboard focus.
303
+ * This code is based on goog.dom.isFocusable, but simplified since we shouldn't
304
+ * care about visibility if we're already handling a keyboard event.
305
+ */
306
+ function isFocusable(el) {
307
+ return ((el.tagName in NATIVELY_FOCUSABLE_ELEMENTS || hasSpecifiedTabIndex(el)) &&
308
+ !el.disabled);
309
+ }
310
+ /**
311
+ * @param element Element to check.
312
+ * @return Whether the element has a specified tab index.
313
+ */
314
+ function hasSpecifiedTabIndex(element) {
315
+ // IE returns 0 for an unset tabIndex, so we must use getAttributeNode(),
316
+ // which returns an object with a 'specified' property if tabIndex is
317
+ // specified. This works on other browsers, too.
318
+ const attrNode = element.getAttributeNode('tabindex'); // Must be lowercase!
319
+ return attrNode != null && attrNode.specified;
320
+ }
321
+ /** Element tagnames that are focusable by default. */
322
+ const NATIVELY_FOCUSABLE_ELEMENTS = {
323
+ 'A': 1,
324
+ 'INPUT': 1,
325
+ 'TEXTAREA': 1,
326
+ 'SELECT': 1,
327
+ 'BUTTON': 1,
328
+ };
329
+ /** @return True, if the Space key was pressed. */
330
+ export function isSpaceKeyEvent(e) {
331
+ const key =
332
+ // `which` is an old DOM API.
333
+ // tslint:disable-next-line:no-any
334
+ e.which ||
335
+ // `keyCode` is an old DOM API.
336
+ // tslint:disable-next-line:no-any
337
+ e.keyCode;
338
+ const el = getTarget(e);
339
+ const elementName = (el.type || el.tagName).toUpperCase();
340
+ return key === KeyCode.SPACE && elementName !== 'CHECKBOX';
341
+ }
342
+ /**
343
+ * Determines whether the event corresponds to a non-bubbling mouse
344
+ * event type (mouseenter, mouseleave, pointerenter, and pointerleave).
345
+ *
346
+ * During mouseover (mouseenter) and pointerover (pointerenter), the
347
+ * relatedTarget is the element being entered from. During mouseout (mouseleave)
348
+ * and pointerout (pointerleave), the relatedTarget is the element being exited
349
+ * to.
350
+ *
351
+ * In both cases, if relatedTarget is outside target, then the corresponding
352
+ * special event has occurred, otherwise it hasn't.
353
+ *
354
+ * @param e The mouseover/mouseout event.
355
+ * @param type The type of the mouse special event.
356
+ * @param element The element on which the jsaction for the
357
+ * mouseenter/mouseleave event is defined.
358
+ * @return True if the event is a mouseenter/mouseleave event.
359
+ */
360
+ export function isMouseSpecialEvent(e, type, element) {
361
+ // `relatedTarget` is an old DOM API.
362
+ // tslint:disable-next-line:no-any
363
+ const related = e.relatedTarget;
364
+ return (((e.type === EventType.MOUSEOVER && type === EventType.MOUSEENTER) ||
365
+ (e.type === EventType.MOUSEOUT && type === EventType.MOUSELEAVE) ||
366
+ (e.type === EventType.POINTEROVER && type === EventType.POINTERENTER) ||
367
+ (e.type === EventType.POINTEROUT && type === EventType.POINTERLEAVE)) &&
368
+ (!related || (related !== element && !dom.contains(element, related))));
369
+ }
370
+ /**
371
+ * Creates a new EventLike object for a mouseenter/mouseleave event that's
372
+ * derived from the original corresponding mouseover/mouseout event.
373
+ * @param e The event.
374
+ * @param target The element on which the jsaction for the mouseenter/mouseleave
375
+ * event is defined.
376
+ * @return A modified event-like object copied from the event object passed into
377
+ * this function.
378
+ */
379
+ export function createMouseSpecialEvent(e, target) {
380
+ // We have to create a copy of the event object because we need to mutate
381
+ // its fields. We do this for the special mouse events because the event
382
+ // target needs to be retargeted to the action element rather than the real
383
+ // element (since we are simulating the special mouse events with mouseover/
384
+ // mouseout).
385
+ //
386
+ // Since we're making a copy anyways, we might as well attempt to convert
387
+ // this event into a pseudo-real mouseenter/mouseleave event by adjusting
388
+ // its type.
389
+ //
390
+ // tslint:disable-next-line:no-any
391
+ const copy = {};
392
+ for (const property in e) {
393
+ if (property === 'srcElement' || property === 'target') {
394
+ continue;
395
+ }
396
+ const key = property;
397
+ // Making a copy requires iterating through all properties of `Event`.
398
+ // tslint:disable-next-line:no-dict-access-on-struct-type
399
+ const value = e[key];
400
+ if (typeof value === 'function') {
401
+ continue;
402
+ }
403
+ // Value should be the expected type, but the value of `key` is not known
404
+ // statically.
405
+ // tslint:disable-next-line:no-any
406
+ copy[key] = value;
407
+ }
408
+ if (e.type === EventType.MOUSEOVER) {
409
+ copy['type'] = EventType.MOUSEENTER;
410
+ }
411
+ else if (e.type === EventType.MOUSEOUT) {
412
+ copy['type'] = EventType.MOUSELEAVE;
413
+ }
414
+ else if (e.type === EventType.POINTEROVER) {
415
+ copy['type'] = EventType.POINTERENTER;
416
+ }
417
+ else {
418
+ copy['type'] = EventType.POINTERLEAVE;
419
+ }
420
+ copy['target'] = copy['srcElement'] = target;
421
+ copy['bubbles'] = false;
422
+ return copy;
423
+ }
424
+ /**
425
+ * Returns touch data extracted from the touch event: clientX, clientY, screenX
426
+ * and screenY. If the event has no touch information at all, the returned
427
+ * value is null.
428
+ *
429
+ * The fields of this Object are unquoted.
430
+ *
431
+ * @param event A touch event.
432
+ */
433
+ export function getTouchData(event) {
434
+ const touch = (event.changedTouches && event.changedTouches[0]) || (event.touches && event.touches[0]);
435
+ if (!touch) {
436
+ return null;
437
+ }
438
+ return {
439
+ clientX: touch.clientX,
440
+ clientY: touch.clientY,
441
+ screenX: touch.screenX,
442
+ screenY: touch.screenY,
443
+ };
444
+ }
445
+ /**
446
+ * Creates a new EventLike object for a "click" event that's derived from the
447
+ * original corresponding "touchend" event for a fast-click implementation.
448
+ *
449
+ * It takes a touch event, adds common fields found in a click event and
450
+ * changes the type to 'click', so that the resulting event looks more like
451
+ * a real click event.
452
+ *
453
+ * @param event A touch event.
454
+ * @return A modified event-like object copied from the event object passed into
455
+ * this function.
456
+ */
457
+ export function recreateTouchEventAsClick(event) {
458
+ const click = {};
459
+ click['originalEventType'] = event.type;
460
+ click['type'] = EventType.CLICK;
461
+ for (const property in event) {
462
+ if (property === 'type' || property === 'srcElement') {
463
+ continue;
464
+ }
465
+ const key = property;
466
+ // Making a copy requires iterating through all properties of `TouchEvent`.
467
+ // tslint:disable-next-line:no-dict-access-on-struct-type
468
+ const value = event[key];
469
+ if (typeof value === 'function') {
470
+ continue;
471
+ }
472
+ // Value should be the expected type, but the value of `key` is not known
473
+ // statically.
474
+ // tslint:disable-next-line:no-any
475
+ click[key] = value;
476
+ }
477
+ // Ensure that the event has the most recent timestamp. This timestamp
478
+ // may be used in the future to validate or cancel subsequent click events.
479
+ click['timeStamp'] = Date.now();
480
+ // Emulate preventDefault and stopPropagation behavior
481
+ click['defaultPrevented'] = false;
482
+ click['preventDefault'] = syntheticPreventDefault;
483
+ click['_propagationStopped'] = false;
484
+ click['stopPropagation'] = syntheticStopPropagation;
485
+ // Emulate click coordinates using touch info
486
+ const touch = getTouchData(event);
487
+ if (touch) {
488
+ click['clientX'] = touch.clientX;
489
+ click['clientY'] = touch.clientY;
490
+ click['screenX'] = touch.screenX;
491
+ click['screenY'] = touch.screenY;
492
+ }
493
+ return click;
494
+ }
495
+ /**
496
+ * An implementation of "preventDefault" for a synthesized event. Simply
497
+ * sets "defaultPrevented" property to true.
498
+ */
499
+ function syntheticPreventDefault() {
500
+ this.defaultPrevented = true;
501
+ }
502
+ /**
503
+ * An implementation of "stopPropagation" for a synthesized event. It simply
504
+ * sets a synthetic non-standard "_propagationStopped" property to true.
505
+ */
506
+ function syntheticStopPropagation() {
507
+ this._propagationStopped = true;
508
+ }
509
+ /**
510
+ * Mapping of KeyboardEvent.key values to
511
+ * KeyCode values.
512
+ */
513
+ const ACTION_KEY_TO_KEYCODE = {
514
+ 'Enter': KeyCode.ENTER,
515
+ ' ': KeyCode.SPACE,
516
+ };
517
+ /**
518
+ * Mapping of HTML element identifiers (ARIA role, type, or tagName) to the
519
+ * keys (enter and/or space) that should activate them. A value of zero means
520
+ * that both should activate them.
521
+ */
522
+ export const IDENTIFIER_TO_KEY_TRIGGER_MAPPING = {
523
+ 'A': KeyCode.ENTER,
524
+ 'BUTTON': 0,
525
+ 'CHECKBOX': KeyCode.SPACE,
526
+ 'COMBOBOX': KeyCode.ENTER,
527
+ 'FILE': 0,
528
+ 'GRIDCELL': KeyCode.ENTER,
529
+ 'LINK': KeyCode.ENTER,
530
+ 'LISTBOX': KeyCode.ENTER,
531
+ 'MENU': 0,
532
+ 'MENUBAR': 0,
533
+ 'MENUITEM': 0,
534
+ 'MENUITEMCHECKBOX': 0,
535
+ 'MENUITEMRADIO': 0,
536
+ 'OPTION': 0,
537
+ 'RADIO': KeyCode.SPACE,
538
+ 'RADIOGROUP': KeyCode.SPACE,
539
+ 'RESET': 0,
540
+ 'SUBMIT': 0,
541
+ 'SWITCH': KeyCode.SPACE,
542
+ 'TAB': 0,
543
+ 'TREE': KeyCode.ENTER,
544
+ 'TREEITEM': KeyCode.ENTER,
545
+ };
546
+ /**
547
+ * Returns whether or not to process space based on the type of the element;
548
+ * checks to make sure that type is not null.
549
+ * @param element The element.
550
+ * @return Whether or not to process space based on type.
551
+ */
552
+ function processSpace(element) {
553
+ const type = (element.getAttribute('type') || element.tagName).toUpperCase();
554
+ return type in PROCESS_SPACE;
555
+ }
556
+ /**
557
+ * Returns whether or not the given element is a text control.
558
+ * @param el The element.
559
+ * @return Whether or not the given element is a text control.
560
+ */
561
+ function isTextControl(el) {
562
+ const type = (el.getAttribute('type') || el.tagName).toUpperCase();
563
+ return type in TEXT_CONTROLS;
564
+ }
565
+ /**
566
+ * Returns if the given element is a native HTML control.
567
+ * @param el The element.
568
+ * @return If the given element is a native HTML control.
569
+ */
570
+ export function isNativeHTMLControl(el) {
571
+ return el.tagName.toUpperCase() in NATIVE_HTML_CONTROLS;
572
+ }
573
+ /**
574
+ * Returns if the given element is natively activatable. Browsers emit click
575
+ * events for natively activatable elements, even when activated via keyboard.
576
+ * For these elements, we don't need to raise a11y click events.
577
+ * @param el The element.
578
+ * @return If the given element is a native HTML control.
579
+ */
580
+ function isNativelyActivatable(el) {
581
+ return (el.tagName.toUpperCase() === 'BUTTON' ||
582
+ (!!el.type && el.type.toUpperCase() === 'FILE'));
583
+ }
584
+ /**
585
+ * HTML <input> types (not ARIA roles) which will auto-trigger a click event for
586
+ * the Space key, with side-effects. We will not call preventDefault if space is
587
+ * pressed, nor will we raise a11y click events. For all other elements, we can
588
+ * suppress the default event (which has no desired side-effects) and handle the
589
+ * keydown ourselves.
590
+ */
591
+ const PROCESS_SPACE = {
592
+ 'CHECKBOX': true,
593
+ 'FILE': true,
594
+ 'OPTION': true,
595
+ 'RADIO': true,
596
+ };
597
+ /** TagNames and Input types for which to not process enter/space as click. */
598
+ const TEXT_CONTROLS = {
599
+ 'COLOR': true,
600
+ 'DATE': true,
601
+ 'DATETIME': true,
602
+ 'DATETIME-LOCAL': true,
603
+ 'EMAIL': true,
604
+ 'MONTH': true,
605
+ 'NUMBER': true,
606
+ 'PASSWORD': true,
607
+ 'RANGE': true,
608
+ 'SEARCH': true,
609
+ 'TEL': true,
610
+ 'TEXT': true,
611
+ 'TEXTAREA': true,
612
+ 'TIME': true,
613
+ 'URL': true,
614
+ 'WEEK': true,
615
+ };
616
+ /** TagNames that are native HTML controls. */
617
+ const NATIVE_HTML_CONTROLS = {
618
+ 'A': true,
619
+ 'AREA': true,
620
+ 'BUTTON': true,
621
+ 'DIALOG': true,
622
+ 'IMG': true,
623
+ 'INPUT': true,
624
+ 'LINK': true,
625
+ 'MENU': true,
626
+ 'OPTGROUP': true,
627
+ 'OPTION': true,
628
+ 'PROGRESS': true,
629
+ 'SELECT': true,
630
+ 'TEXTAREA': true,
631
+ };
632
+ /** Exported for testing. */
633
+ export const testing = {
634
+ setIsMac(value) {
635
+ isMac = value;
636
+ },
637
+ };
638
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3ByaW1pdGl2ZXMvZXZlbnQtZGlzcGF0Y2gvc3JjL2V2ZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxHQUFHLE1BQU0sT0FBTyxDQUFDO0FBRTdCLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLFlBQVksQ0FBQztBQUVuQzs7R0FFRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxTQUFpQjtJQUNuRCx5RUFBeUU7SUFDekUsMkVBQTJFO0lBQzNFLHlFQUF5RTtJQUN6RSxxRUFBcUU7SUFDckUsdURBQXVEO0lBQ3ZELElBQUksU0FBUyxLQUFLLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN2QyxPQUFPLFNBQVMsQ0FBQyxTQUFTLENBQUM7SUFDN0IsQ0FBQztTQUFNLElBQUksU0FBUyxLQUFLLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM5QyxPQUFPLFNBQVMsQ0FBQyxRQUFRLENBQUM7SUFDNUIsQ0FBQztTQUFNLElBQUksU0FBUyxLQUFLLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNoRCxPQUFPLFNBQVMsQ0FBQyxXQUFXLENBQUM7SUFDL0IsQ0FBQztTQUFNLElBQUksU0FBUyxLQUFLLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNoRCxPQUFPLFNBQVMsQ0FBQyxVQUFVLENBQUM7SUFDOUIsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsT0FBZ0IsRUFDaEIsU0FBaUIsRUFDakIsT0FBK0I7SUFFL0Isb0RBQW9EO0lBQ3BELFNBQVM7SUFDVCxFQUFFO0lBQ0YsNEVB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ckQsR0FBRyxFQUFFLElBQUk7SUFDVCxNQUFNLEVBQUUsSUFBSTtJQUNaLFFBQVEsRUFBRSxJQUFJO0lBQ2QsUUFBUSxFQUFFLElBQUk7SUFDZCxLQUFLLEVBQUUsSUFBSTtJQUNYLE9BQU8sRUFBRSxJQUFJO0lBQ2IsTUFBTSxFQUFFLElBQUk7SUFDWixNQUFNLEVBQUUsSUFBSTtJQUNaLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLFFBQVEsRUFBRSxJQUFJO0lBQ2QsVUFBVSxFQUFFLElBQUk7SUFDaEIsUUFBUSxFQUFFLElBQUk7SUFDZCxVQUFVLEVBQUUsSUFBSTtDQUNqQixDQUFDO0FBRUYsNEJBQTRCO0FBQzVCLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRztJQUNyQixRQUFRLENBQUMsS0FBYztRQUNyQixLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ2hCLENBQUM7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIGRvbSBmcm9tICcuL2RvbSc7XG5pbXBvcnQge0V2ZW50SGFuZGxlckluZm99IGZyb20gJy4vZXZlbnRfaGFuZGxlcic7XG5pbXBvcnQge0V2ZW50VHlwZX0gZnJvbSAnLi9ldmVudF90eXBlJztcbmltcG9ydCB7S2V5Q29kZX0gZnJvbSAnLi9rZXlfY29kZSc7XG5cbi8qKlxuICogR2V0cyBhIGJyb3dzZXIgZXZlbnQgdHlwZSwgaWYgaXQgd291bGQgZGlmZmVyIGZyb20gdGhlIEpTQWN0aW9uIGV2ZW50IHR5cGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCcm93c2VyRXZlbnRUeXBlKGV2ZW50VHlwZTogc3RyaW5nKSB7XG4gIC8vIE1vdXNlZW50ZXIgYW5kIG1vdXNlbGVhdmUgZXZlbnRzIGFyZSBub3QgaGFuZGxlZCBkaXJlY3RseSBiZWNhdXNlIHRoZXlcbiAgLy8gYXJlIG5vdCBhdmFpbGFibGUgZXZlcnl3aGVyZS4gSW4gYnJvd3NlcnMgd2hlcmUgdGhleSBhcmUgYXZhaWxhYmxlLCB0aGV5XG4gIC8vIGRvbid0IGJ1YmJsZSBhbmQgYXJlbid0IHZpc2libGUgYXQgdGhlIGNvbnRhaW5lciBib3VuZGFyeS4gSW5zdGVhZCwgd2VcbiAgLy8gc3ludGhlc2l6ZSB0aGUgbW91c2VlbnRlciBhbmQgbW91c2VsZWF2ZSBldmVudHMgZnJvbSBtb3VzZW92ZXIgYW5kXG4gIC8vIG1vdXNlb3V0IGV2ZW50cywgcmVzcGVjdGl2ZWx5LiBDZi4gZXZlbnRjb250cmFjdC5qcy5cbiAgaWYgKGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLk1PVVNFRU5URVIpIHtcbiAgICByZXR1cm4gRXZlbnRUeXBlLk1PVVNFT1ZFUjtcbiAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09IEV2ZW50VHlwZS5NT1VTRUxFQVZFKSB7XG4gICAgcmV0dXJuIEV2ZW50VHlwZS5NT1VTRU9VVDtcbiAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09IEV2ZW50VHlwZS5QT0lOVEVSRU5URVIpIHtcbiAgICByZXR1cm4gRXZlbnRUeXBlLlBPSU5URVJPVkVSO1xuICB9IGVsc2UgaWYgKGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLlBPSU5URVJMRUFWRSkge1xuICAgIHJldHVybiBFdmVudFR5cGUuUE9JTlRFUk9VVDtcbiAgfVxuICByZXR1cm4gZXZlbnRUeXBlO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgZXZlbnQgaGFuZGxlciBmdW5jdGlvbiB3aXRoIHRoZSBnaXZlbiBET00gZWxlbWVudCBmb3JcbiAqIHRoZSBnaXZlbiBldmVudCB0eXBlLlxuICpcbiAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50LlxuICogQHBhcmFtIGV2ZW50VHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAqIEBwYXJhbSBoYW5kbGVyIFRoZSBoYW5kbGVyIGZ1bmN0aW9uIHRvIGluc3RhbGwuXG4gKiBAcmV0dXJuIEluZm9ybWF0aW9uIG5lZWRlZCB0byB1bmluc3RhbGwgdGhlIGV2ZW50IGhhbmRsZXIgZXZlbnR1YWxseS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIoXG4gIGVsZW1lbnQ6IEVsZW1lbnQsXG4gIGV2ZW50VHlwZTogc3RyaW5nLFxuICBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkLFxuKTogRXZlbnRIYW5kbGVySW5mbyB7XG4gIC8vIEFsbCBldmVudCBoYW5kbGVycyBhcmUgcmVnaXN0ZXJlZCBpbiB0aGUgYnViYmxpbmdcbiAgLy8gcGhhc2UuXG4gIC8vXG4gIC8vIEFsbCBicm93c2VycyBzdXBwb3J0IGZvY3VzIGFuZCBibHVyLCBidXQgdGhlc2UgZXZlbnRzIG9ubHkgYXJlIHByb3BhZ2F0ZWRcbiAgLy8gaW4gdGhlIGNhcHR1cmUgcGhhc2UuIFZlcnkgbGVnYWN5IGJyb3dzZXJzIGRvIG5vdCBzdXBwb3J0IGZvY3VzaW4gb3JcbiAgLy8gZm9jdXNvdXQuXG4gIC8vXG4gIC8vIEl0IHdvdWxkIGJlIGEgYmFkIGlkZWEgdG8gcmVnaXN0ZXIgYWxsIGV2ZW50IGhhbmRsZXJzIGluIHRoZVxuICAvLyBjYXB0dXJlIHBoYXNlIGJlY2F1c2UgdGhlbiByZWd1bGFyIG9uY2xpY2sgaGFuZGxlcnMgd291bGQgbm90IGJlXG4gIC8vIGV4ZWN1dGVkIGF0IGFsbCBvbiBldmVudHMgdGhhdCB0cmlnZ2VyIGEganNhY3Rpb24uIFRoYXQncyBub3RcbiAgLy8gZW50aXJlbHkgd2hhdCB3ZSB3YW50LCBhdCBsZWFzdCBmb3Igbm93LlxuICAvL1xuICAvLyBFcnJvciBhbmQgbG9hZCBldmVudHMgKGkuZS4gb24gaW1hZ2VzKSBkbyBub3QgYnViYmxlIHNvIHRoZXkgYXJlIGFsc29cbiAgLy8gaGFuZGxlZCBpbiB0aGUgY2FwdHVyZSBwaGFzZS5cbiAgbGV0IGNhcHR1cmUgPSBmYWxzZTtcblxuICBpZiAoXG4gICAgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuRk9DVVMgfHxcbiAgICBldmVudFR5cGUgPT09IEV2ZW50VHlwZS5CTFVSIHx8XG4gICAgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuRVJST1IgfHxcbiAgICBldmVudFR5cGUgPT09IEV2ZW50VHlwZS5MT0FEIHx8XG4gICAgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuVE9HR0xFXG4gICkge1xuICAgIGNhcHR1cmUgPSB0cnVlO1xuICB9XG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGhhbmRsZXIsIGNhcHR1cmUpO1xuXG4gIHJldHVybiB7ZXZlbnRUeXBlLCBoYW5kbGVyLCBjYXB0dXJlfTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBldmVudCBoYW5kbGVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQgZnJvbSB0aGUgZWxlbWVudC5cbiAqIHRoZSBnaXZlbiBldmVudCB0eXBlLlxuICpcbiAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50LlxuICogQHBhcmFtIGluZm8gVGhlIGluZm9ybWF0aW9uIG5lZWRlZCB0byBkZXJlZ2lzdGVyIHRoZSBoYW5kbGVyLCBhcyByZXR1cm5lZCBieVxuICogICAgIGFkZEV2ZW50TGlzdGVuZXIoKSwgYWJvdmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKGVsZW1lbnQ6IEVsZW1lbnQsIGluZm86IEV2ZW50SGFuZGxlckluZm8pIHtcbiAgaWYgKGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihpbmZvLmV2ZW50VHlwZSwgaW5mby5oYW5kbGVyIGFzIEV2ZW50TGlzdGVuZXIsIGluZm8uY2FwdHVyZSk7XG4gICAgLy8gYGRldGFjaEV2ZW50YCBpcyBhbiBvbGQgRE9NIEFQSS5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIH0gZWxzZSBpZiAoKGVsZW1lbnQgYXMgYW55KS5kZXRhY2hFdmVudCkge1xuICAgIC8vIGBkZXRhY2hFdmVudGAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIChlbGVtZW50IGFzIGFueSkuZGV0YWNoRXZlbnQoYG9uJHtpbmZvLmV2ZW50VHlwZX1gLCBpbmZvLmhhbmRsZXIpO1xuICB9XG59XG5cbi8qKlxuICogQ2FuY2VscyBwcm9wYWdhdGlvbiBvZiBhbiBldmVudC5cbiAqIEBwYXJhbSBlIFRoZSBldmVudCB0byBjYW5jZWwgcHJvcGFnYXRpb24gZm9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKGU6IEV2ZW50KSB7XG4gIGUuc3RvcFByb3BhZ2F0aW9uID8gZS5zdG9wUHJvcGFnYXRpb24oKSA6IChlLmNhbmNlbEJ1YmJsZSA9IHRydWUpO1xufVxuXG4vKipcbiAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGFjdGlvbiBvZiBhbiBldmVudC5cbiAqIEBwYXJhbSBlIFRoZSBldmVudCB0byBwcmV2ZW50IHRoZSBkZWZhdWx0IGFjdGlvbiBmb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChlOiBFdmVudCkge1xuICBlLnByZXZlbnREZWZhdWx0ID8gZS5wcmV2ZW50RGVmYXVsdCgpIDogKGUucmV0dXJuVmFsdWUgPSBmYWxzZSk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgdGFyZ2V0IEVsZW1lbnQgb2YgdGhlIGV2ZW50LiBJbiBGaXJlZm94LCBhIHRleHQgbm9kZSBtYXkgYXBwZWFyIGFzXG4gKiB0aGUgdGFyZ2V0IG9mIHRoZSBldmVudCwgaW4gd2hpY2ggY2FzZSB3ZSByZXR1cm4gdGhlIHBhcmVudCBlbGVtZW50IG9mIHRoZVxuICogdGV4dCBub2RlLlxuICogQHBhcmFtIGUgVGhlIGV2ZW50IHRvIGdldCB0aGUgdGFyZ2V0IG9mLlxuICogQHJldHVybiBUaGUgdGFyZ2V0IGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUYXJnZXQoZTogRXZlbnQpOiBFbGVtZW50IHtcbiAgbGV0IGVsID0gZS50YXJnZXQgYXMgRWxlbWVudDtcblxuICAvLyBJbiBGaXJlZm94LCB0aGUgZXZlbnQgbWF5IGhhdmUgYSB0ZXh0IG5vZGUgYXMgaXRzIHRhcmdldC4gV2UgYWx3YXlzXG4gIC8vIHdhbnQgdGhlIHBhcmVudCBFbGVtZW50IHRoZSB0ZXh0IG5vZGUgYmVsb25ncyB0bywgaG93ZXZlci5cbiAgaWYgKCFlbC5nZXRBdHRyaWJ1dGUgJiYgZWwucGFyZW50Tm9kZSkge1xuICAgIGVsID0gZWwucGFyZW50Tm9kZSBhcyBFbGVtZW50O1xuICB9XG5cbiAgcmV0dXJuIGVsO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgd2UgYXJlIG9uIGEgTWFjLiBOb3QgcHVsbGluZyBpbiB1c2VyYWdlbnQganVzdCBmb3IgdGhpcy5cbiAqL1xubGV0IGlzTWFjOiBib29sZWFuID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgL01hY2ludG9zaC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBEZXRlcm1pbmVzIGFuZCByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGV2ZW50ICh3aGljaCBpcyBhc3N1bWVkIHRvIGJlIGFcbiAqIGNsaWNrIGV2ZW50KSBpcyBhIG1pZGRsZSBjbGljay5cbiAqIE5PVEU6IFRoZXJlIGlzIG5vdCBhIGNvbnNpc3RlbnQgd2F5IHRvIGlkZW50aWZ5IG1pZGRsZSBjbGlja1xuICogaHR0cDovL3d3dy51bml4cGFwYS5jb20vanMvbW91c2UuaHRtbFxuICovXG5mdW5jdGlvbiBpc01pZGRsZUNsaWNrKGU6IEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgLy8gYHdoaWNoYCBpcyBhbiBvbGQgRE9NIEFQSS5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgKGUgYXMgYW55KS53aGljaCA9PT0gMiB8fFxuICAgIC8vIGB3aGljaGAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICgoZSBhcyBhbnkpLndoaWNoID09IG51bGwgJiZcbiAgICAgIC8vIGBidXR0b25gIGlzIGFuIG9sZCBET00gQVBJLlxuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgICAgKGUgYXMgYW55KS5idXR0b24gPT09IDQpIC8vIG1pZGRsZSBjbGljayBmb3IgSUVcbiAgKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIGFuZCByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGV2ZW50ICh3aGljaCBpcyBhc3N1bWVkXG4gKiB0byBiZSBhIGNsaWNrIGV2ZW50KSBpcyBtb2RpZmllZC4gQSBtaWRkbGUgY2xpY2sgaXMgY29uc2lkZXJlZCBhIG1vZGlmaWVkXG4gKiBjbGljayB0byByZXRhaW4gdGhlIGRlZmF1bHQgYnJvd3NlciBhY3Rpb24sIHdoaWNoIG9wZW5zIGEgbGluayBpbiBhIG5ldyB0YWIuXG4gKiBAcGFyYW0gZSBUaGUgZXZlbnQuXG4gKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGdpdmVuIGV2ZW50IGlzIG1vZGlmaWVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNNb2RpZmllZENsaWNrRXZlbnQoZTogRXZlbnQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICAvLyBgbWV0YUtleWAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIChpc01hYyAmJiAoZSBhcyBhbnkpLm1ldGFLZXkpIHx8XG4gICAgLy8gYGN0cmxLZXlgIGlzIGFuIG9sZCBET00gQVBJLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoIWlzTWFjICYmIChlIGFzIGFueSkuY3RybEtleSkgfHxcbiAgICBpc01pZGRsZUNsaWNrKGUpIHx8XG4gICAgLy8gYHNoaWZ0S2V5YCBpcyBhbiBvbGQgRE9NIEFQSS5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgKGUgYXMgYW55KS5zaGlmdEtleVxuICApO1xufVxuXG4vKiogV2hldGhlciB3ZSBhcmUgb24gV2ViS2l0IChlLmcuLCBDaHJvbWUpLiAqL1xuZXhwb3J0IGNvbnN0IGlzV2ViS2l0OiBib29sZWFuID1cbiAgdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgIS9PcGVyYS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJlxuICAvV2ViS2l0Ly50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4vKiogV2hldGhlciB3ZSBhcmUgb24gSUUuICovXG5leHBvcnQgY29uc3QgaXNJZTogYm9vbGVhbiA9XG4gIHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmXG4gICgvTVNJRS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSB8fCAvVHJpZGVudC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSk7XG5cbi8qKiBXaGV0aGVyIHdlIGFyZSBvbiBHZWNrbyAoZS5nLiwgRmlyZWZveCkuICovXG5leHBvcnQgY29uc3QgaXNHZWNrbzogYm9vbGVhbiA9XG4gIHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmXG4gICEvT3BlcmF8V2ViS2l0Ly50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpICYmXG4gIC9HZWNrby8udGVzdChuYXZpZ2F0b3IucHJvZHVjdCk7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBhbmQgcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBlbGVtZW50IGlzIGEgdmFsaWQgdGFyZ2V0IGZvclxuICoga2V5cHJlc3Mva2V5ZG93biBET00gZXZlbnRzIHRoYXQgYWN0IGxpa2UgcmVndWxhciBET00gY2xpY2tzLlxuICogQHBhcmFtIGVsIFRoZSBlbGVtZW50LlxuICogQHJldHVybiBXaGV0aGVyIHRoZSBnaXZlbiBlbGVtZW50IGlzIGEgdmFsaWQgYWN0aW9uIGtleSB0YXJnZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkQWN0aW9uS2V5VGFyZ2V0KGVsOiBFbGVtZW50KTogYm9vbGVhbiB7XG4gIGlmICghKCdnZXRBdHRyaWJ1dGUnIGluIGVsKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoaXNUZXh0Q29udHJvbChlbCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGlzTmF0aXZlbHlBY3RpdmF0YWJsZShlbCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gYGlzQ29udGVudEVkaXRhYmxlYCBpcyBhbiBvbGQgRE9NIEFQSS5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBpZiAoKGVsIGFzIGFueSkuaXNDb250ZW50RWRpdGFibGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGFuIGV2ZW50IGhhcyBhIG1vZGlmaWVyIGtleSBhY3RpdmF0ZWQuXG4gKiBAcGFyYW0gZSBUaGUgZXZlbnQuXG4gKiBAcmV0dXJuIFRydWUsIGlmIGEgbW9kaWZpZXIga2V5IGlzIGFjdGl2YXRlZC5cbiAqL1xuZnVuY3Rpb24gaGFzTW9kaWZpZXJLZXkoZTogRXZlbnQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICAvLyBgY3RybEtleWAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIChlIGFzIGFueSkuY3RybEtleSB8fFxuICAgIC8vIGBzaGlmdEtleWAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIChlIGFzIGFueSkuc2hpZnRLZXkgfHxcbiAgICAvLyBgYWx0S2V5YCBpcyBhbiBvbGQgRE9NIEFQSS5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgKGUgYXMgYW55KS5hbHRLZXkgfHxcbiAgICAvLyBgbWV0YUtleWAgaXMgYW4gb2xkIERPTSBBUEkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIChlIGFzIGFueSkubWV0YUtleVxuICApO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgYW5kIHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gZXZlbnQgaGFzIGEgdGFyZ2V0IHRoYXQgYWxyZWFkeVxuICogaGFzIGV2ZW50IGhhbmRsZXJzIGF0dGFjaGVkIGJlY2F1c2UgaXQgaXMgYSBuYXRpdmUgSFRNTCBjb250cm9sLiBVc2VkIHRvXG4gKiBkZXRlcm1pbmUgaWYgcHJldmVudERlZmF1bHQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGlzQWN0aW9uS2V5RXZlbnQgaXMgdHJ1ZS5cbiAqIEBwYXJhbSBlIFRoZSBldmVudC5cbiAqIEByZXR1cm4gSWYgcHJldmVudERlZmF1bHQgc2hvdWxkIGJlIGNhbGxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZENhbGxQcmV2ZW50RGVmYXVsdE9uTmF0aXZlSHRtbENvbnRyb2woZTogRXZlbnQpOiBib29sZWFuIHtcbiAgY29uc3QgZWwgPSBnZXRUYXJnZXQoZSk7XG4gIGNvbnN0IHRhZ05hbWUgPSBlbC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG4gIGNvbnN0IHJvbGUgPSAoZWwuZ2V0QXR0cmlidXRlKCdyb2xlJykgfHwgJycpLnRvVXBwZXJDYXNlKCk7XG5cbiAgaWYgKHRhZ05hbWUgPT09ICdCVVRUT04nIHx8IHJvbGUgPT09ICdCVVRUT04nKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKCFpc05hdGl2ZUhUTUxDb250cm9sKGVsKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGFnTmFtZSA9PT0gJ0EnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8qKlxuICAgKiBGaXggZm9yIHBoeXNpY2FsIGQtcGFkcyBvbiBmZWF0dXJlIHBob25lIHBsYXRmb3JtczsgdGhlIG5hdGl2ZSBldmVudFxuICAgKiAoaWUuIGlzVHJ1c3RlZDogdHJ1ZSkgbmVlZHMgdG8gZmlyZSB0byBzaG93IHRoZSBPUFRJT04gbGlzdC4gU2VlXG4gICAqIGIvMTM1Mjg4NDY5IGZvciBtb3JlIGluZm8uXG4gICAqL1xuICBpZiAodGFnTmFtZSA9PT0gJ1NFTEVDVCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHByb2Nlc3NTcGFjZShlbCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGlzVGV4dENvbnRyb2woZWwpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgYW5kIHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gZXZlbnQgYWN0cyBsaWtlIGEgcmVndWxhciBET00gY2xpY2ssXG4gKiBhbmQgc2hvdWxkIGJlIGhhbmRsZWQgaW5zdGVhZCBvZiB0aGUgY2xpY2suICBJZiB0aGlzIHJldHVybnMgdHJ1ZSwgdGhlIGNhbGxlclxuICogd2lsbCBjYWxsIHByZXZlbnREZWZhdWx0KCkgdG8gcHJldmVudCBhIHBvc3NpYmxlIGR1cGxpY2F0ZSBldmVudC5cbiAqIFRoaXMgaXMgcmVwcmVzZW50ZWQgYnkgYSBrZXlwcmVzcyAoa2V5ZG93biBvbiBHZWNrbyBicm93c2Vycykgb24gRW50ZXIgb3JcbiAqIFNwYWNlIGtleS5cbiAqIEBwYXJhbSBlIFRoZSBldmVudC5cbiAqIEByZXR1cm4gVHJ1ZSwgaWYgdGhlIGV2ZW50IGVtdWxhdGVzIGEgRE9NIGNsaWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBY3Rpb25LZXlFdmVudChlOiBFdmVudCk6IGJvb2xlYW4ge1xuICBsZXQga2V5ID1cbiAgICAvLyBgd2hpY2hgIGlzIGFuIG9sZCBET00gQVBJLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoZSBhcyBhbnkpLndoaWNoIHx8XG4gICAgLy8gYGtleUNvZGVgIGlzIGFuIG9sZCBET00gQVBJLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoZSBhcyBhbnkpLmtleUNvZGU7XG4gIGlmICgha2V5ICYmIChlIGFzIEtleWJvYXJkRXZlbnQpLmtleSkge1xuICAgIGtleSA9IEFDVElPTl9LRVlfVE9fS0VZQ09ERVsoZSBhcyBLZXlib2FyZEV2ZW50KS5rZXldO1xuICB9XG4gIGlmIChpc1dlYktpdCAmJiBrZXkgPT09IEtleUNvZGUuTUFDX0VOVEVSKSB7XG4gICAga2V5ID0gS2V5Q29kZS5FTlRFUjtcbiAgfVxuICBpZiAoa2V5ICE9PSBLZXlDb2RlLkVOVEVSICYmIGtleSAhPT0gS2V5Q29kZS5TUEFDRSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBlbCA9IGdldFRhcmdldChlKTtcbiAgaWYgKGUudHlwZSAhPT0gRXZlbnRUeXBlLktFWURPV04gfHwgIWlzVmFsaWRBY3Rpb25LZXlUYXJnZXQoZWwpIHx8IGhhc01vZGlmaWVyS2V5KGUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gRm9yIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIj4sIHdlIG11c3Qgb25seSBoYW5kbGUgdGhlIGJyb3dzZXIncyBuYXRpdmUgY2xpY2tcbiAgLy8gZXZlbnQsIHNvIHRoYXQgdGhlIGJyb3dzZXIgY2FuIHRvZ2dsZSB0aGUgY2hlY2tib3guXG4gIGlmIChwcm9jZXNzU3BhY2UoZWwpICYmIGtleSA9PT0gS2V5Q29kZS5TUEFDRSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIElmIHRoaXMgZWxlbWVudCBpcyBub24tZm9jdXNhYmxlLCBpZ25vcmUgc3RyYXkga2V5c3Ryb2tlcyAoYi8xODMzNzIwOSlcbiAgLy8gU3NjcmVlbiByZWFkZXJzIGNhbiBtb3ZlIHdpdGhvdXQgdGFiIGZvY3VzLCBzbyBhbnkgdGFiSW5kZXggaXMgZm9jdXNhYmxlLlxuICAvLyBTZWUgQi8yMTgwOTYwNFxuICBpZiAoIWlzRm9jdXNhYmxlKGVsKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHR5cGUgPSAoXG4gICAgZWwuZ2V0QXR0cmlidXRlKCdyb2xlJykgfHxcbiAgICAoZWwgYXMgSFRNTElucHV0RWxlbWVudCkudHlwZSB8fFxuICAgIGVsLnRhZ05hbWVcbiAgKS50b1VwcGVyQ2FzZSgpO1xuICBjb25zdCBpc1NwZWNpZmljVHJpZ2dlcktleSA9IElERU5USUZJRVJfVE9fS0VZX1RSSUdHRVJfTUFQUElOR1t0eXBlXSAlIGtleSA9PT0gMDtcbiAgY29uc3QgaXNEZWZhdWx0VHJpZ2dlcktleSA9ICEodHlwZSBpbiBJREVOVElGSUVSX1RPX0tFWV9UUklHR0VSX01BUFBJTkcpICYmIGtleSA9PT0gS2V5Q29kZS5FTlRFUjtcbiAgY29uc3QgaGFzVHlwZSA9IGVsLnRhZ05hbWUudG9VcHBlckNhc2UoKSAhPT0gJ0lOUFVUJyB8fCAhIShlbCBhcyBIVE1MSW5wdXRFbGVtZW50KS50eXBlO1xuICByZXR1cm4gKGlzU3BlY2lmaWNUcmlnZ2VyS2V5IHx8IGlzRGVmYXVsdFRyaWdnZXJLZXkpICYmIGhhc1R5cGU7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBET00gZWxlbWVudCBjYW4gcmVjZWl2ZSBrZXlib2FyZCBmb2N1cy5cbiAqIFRoaXMgY29kZSBpcyBiYXNlZCBvbiBnb29nLmRvbS5pc0ZvY3VzYWJsZSwgYnV0IHNpbXBsaWZpZWQgc2luY2Ugd2Ugc2hvdWxkbid0XG4gKiBjYXJlIGFib3V0IHZpc2liaWxpdHkgaWYgd2UncmUgYWxyZWFkeSBoYW5kbGluZyBhIGtleWJvYXJkIGV2ZW50LlxuICovXG5mdW5jdGlvbiBpc0ZvY3VzYWJsZShlbDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIChlbC50YWdOYW1lIGluIE5BVElWRUxZX0ZPQ1VTQUJMRV9FTEVNRU5UUyB8fCBoYXNTcGVjaWZpZWRUYWJJbmRleChlbCkpICYmXG4gICAgIShlbCBhcyBIVE1MSW5wdXRFbGVtZW50KS5kaXNhYmxlZFxuICApO1xufVxuXG4vKipcbiAqIEBwYXJhbSBlbGVtZW50IEVsZW1lbnQgdG8gY2hlY2suXG4gKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVsZW1lbnQgaGFzIGEgc3BlY2lmaWVkIHRhYiBpbmRleC5cbiAqL1xuZnVuY3Rpb24gaGFzU3BlY2lmaWVkVGFiSW5kZXgoZWxlbWVudDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICAvLyBJRSByZXR1cm5zIDAgZm9yIGFuIHVuc2V0IHRhYkluZGV4LCBzbyB3ZSBtdXN0IHVzZSBnZXRBdHRyaWJ1dGVOb2RlKCksXG4gIC8vIHdoaWNoIHJldHVybnMgYW4gb2JqZWN0IHdpdGggYSAnc3BlY2lmaWVkJyBwcm9wZXJ0eSBpZiB0YWJJbmRleCBpc1xuICAvLyBzcGVjaWZpZWQuICBUaGlzIHdvcmtzIG9uIG90aGVyIGJyb3dzZXJzLCB0b28uXG4gIGNvbnN0IGF0dHJOb2RlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKCd0YWJpbmRleCcpOyAvLyBNdXN0IGJlIGxvd2VyY2FzZSFcbiAgcmV0dXJuIGF0dHJOb2RlICE9IG51bGwgJiYgYXR0ck5vZGUuc3BlY2lmaWVkO1xufVxuXG4vKiogRWxlbWVudCB0YWduYW1lcyB0aGF0IGFyZSBmb2N1c2FibGUgYnkgZGVmYXVsdC4gKi9cbmNvbnN0IE5BVElWRUxZX0ZPQ1VTQUJMRV9FTEVNRU5UUzoge1trZXk6IHN0cmluZ106IG51bWJlcn0gPSB7XG4gICdBJzogMSxcbiAgJ0lOUFVUJzogMSxcbiAgJ1RFWFRBUkVBJzogMSxcbiAgJ1NFTEVDVCc6IDEsXG4gICdCVVRUT04nOiAxLFxufTtcblxuLyoqIEByZXR1cm4gVHJ1ZSwgaWYgdGhlIFNwYWNlIGtleSB3YXMgcHJlc3NlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NwYWNlS2V5RXZlbnQoZTogRXZlbnQpOiBib29sZWFuIHtcbiAgY29uc3Qga2V5ID1cbiAgICAvLyBgd2hpY2hgIGlzIGFuIG9sZCBET00gQVBJLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoZSBhcyBhbnkpLndoaWNoIHx8XG4gICAgLy8gYGtleUNvZGVgIGlzIGFuIG9sZCBET00gQVBJLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoZSBhcyBhbnkpLmtleUNvZGU7XG4gIGNvbnN0IGVsID0gZ2V0VGFyZ2V0KGUpO1xuICBjb25zdCBlbGVtZW50TmFtZSA9ICgoZWwgYXMgSFRNTElucHV0RWxlbWVudCkudHlwZSB8fCBlbC50YWdOYW1lKS50b1VwcGVyQ2FzZSgpO1xuICByZXR1cm4ga2V5ID09PSBLZXlDb2RlLlNQQUNFICYmIGVsZW1lbnROYW1lICE9PSAnQ0hFQ0tCT1gnO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgZXZlbnQgY29ycmVzcG9uZHMgdG8gYSBub24tYnViYmxpbmcgbW91c2VcbiAqIGV2ZW50IHR5cGUgKG1vdXNlZW50ZXIsIG1vdXNlbGVhdmUsIHBvaW50ZXJlbnRlciwgYW5kIHBvaW50ZXJsZWF2ZSkuXG4gKlxuICogRHVyaW5nIG1vdXNlb3ZlciAobW91c2VlbnRlcikgYW5kIHBvaW50ZXJvdmVyIChwb2ludGVyZW50ZXIpLCB0aGVcbiAqIHJlbGF0ZWRUYXJnZXQgaXMgdGhlIGVsZW1lbnQgYmVpbmcgZW50ZXJlZCBmcm9tLiBEdXJpbmcgbW91c2VvdXQgKG1vdXNlbGVhdmUpXG4gKiBhbmQgcG9pbnRlcm91dCAocG9pbnRlcmxlYXZlKSwgdGhlIHJlbGF0ZWRUYXJnZXQgaXMgdGhlIGVsZW1lbnQgYmVpbmcgZXhpdGVkXG4gKiB0by5cbiAqXG4gKiBJbiBib3RoIGNhc2VzLCBpZiByZWxhdGVkVGFyZ2V0IGlzIG91dHNpZGUgdGFyZ2V0LCB0aGVuIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBzcGVjaWFsIGV2ZW50IGhhcyBvY2N1cnJlZCwgb3RoZXJ3aXNlIGl0IGhhc24ndC5cbiAqXG4gKiBAcGFyYW0gZSBUaGUgbW91c2VvdmVyL21vdXNlb3V0IGV2ZW50LlxuICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgdGhlIG1vdXNlIHNwZWNpYWwgZXZlbnQuXG4gKiBAcGFyYW0gZWxlbWVudCBUaGUgZWxlbWVudCBvbiB3aGljaCB0aGUganNhY3Rpb24gZm9yIHRoZVxuICogICAgIG1vdXNlZW50ZXIvbW91c2VsZWF2ZSBldmVudCBpcyBkZWZpbmVkLlxuICogQHJldHVybiBUcnVlIGlmIHRoZSBldmVudCBpcyBhIG1vdXNlZW50ZXIvbW91c2VsZWF2ZSBldmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTW91c2VTcGVjaWFsRXZlbnQoZTogRXZlbnQsIHR5cGU6IHN0cmluZywgZWxlbWVudDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICAvLyBgcmVsYXRlZFRhcmdldGAgaXMgYW4gb2xkIERPTSBBUEkuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgY29uc3QgcmVsYXRlZCA9IChlIGFzIGFueSkucmVsYXRlZFRhcmdldCBhcyBOb2RlO1xuXG4gIHJldHVybiAoXG4gICAgKChlLnR5cGUgPT09IEV2ZW50VHlwZS5NT1VTRU9WRVIgJiYgdHlwZSA9PT0gRXZlbnRUeXBlLk1PVVNFRU5URVIpIHx8XG4gICAgICAoZS50eXBlID09PSBFdmVudFR5cGUuTU9VU0VPVVQgJiYgdHlwZSA9PT0gRXZlbnRUeXBlLk1PVVNFTEVBVkUpIHx8XG4gICAgICAoZS50eXBlID09PSBFdmVudFR5cGUuUE9JTlRFUk9WRVIgJiYgdHlwZSA9PT0gRXZlbnRUeXBlLlBPSU5URVJFTlRFUikgfHxcbiAgICAgIChlLnR5cGUgPT09IEV2ZW50VHlwZS5QT0lOVEVST1VUICYmIHR5cGUgPT09IEV2ZW50VHlwZS5QT0lOVEVSTEVBVkUpKSAmJlxuICAgICghcmVsYXRlZCB8fCAocmVsYXRlZCAhPT0gZWxlbWVudCAmJiAhZG9tLmNvbnRhaW5zKGVsZW1lbnQsIHJlbGF0ZWQpKSlcbiAgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IEV2ZW50TGlrZSBvYmplY3QgZm9yIGEgbW91c2VlbnRlci9tb3VzZWxlYXZlIGV2ZW50IHRoYXQnc1xuICogZGVyaXZlZCBmcm9tIHRoZSBvcmlnaW5hbCBjb3JyZXNwb25kaW5nIG1vdXNlb3Zlci9tb3VzZW91dCBldmVudC5cbiAqIEBwYXJhbSBlIFRoZSBldmVudC5cbiAqIEBwYXJhbSB0YXJnZXQgVGhlIGVsZW1lbnQgb24gd2hpY2ggdGhlIGpzYWN0aW9uIGZvciB0aGUgbW91c2VlbnRlci9tb3VzZWxlYXZlXG4gKiAgICAgZXZlbnQgaXMgZGVmaW5lZC5cbiAqIEByZXR1cm4gQSBtb2RpZmllZCBldmVudC1saWtlIG9iamVjdCBjb3BpZWQgZnJvbSB0aGUgZXZlbnQgb2JqZWN0IHBhc3NlZCBpbnRvXG4gKiAgICAgdGhpcyBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1vdXNlU3BlY2lhbEV2ZW50KGU6IEV2ZW50LCB0YXJnZXQ6IEVsZW1lbnQpOiBFdmVudCB7XG4gIC8vIFdlIGhhdmUgdG8gY3JlYXRlIGEgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGJlY2F1c2Ugd2UgbmVlZCB0byBtdXRhdGVcbiAgLy8gaXRzIGZpZWxkcy4gV2UgZG8gdGhpcyBmb3IgdGhlIHNwZWNpYWwgbW91c2UgZXZlbnRzIGJlY2F1c2UgdGhlIGV2ZW50XG4gIC8vIHRhcmdldCBuZWVkcyB0byBiZSByZXRhcmdldGVkIHRvIHRoZSBhY3Rpb24gZWxlbWVudCByYXRoZXIgdGhhbiB0aGUgcmVhbFxuICAvLyBlbGVtZW50IChzaW5jZSB3ZSBhcmUgc2ltdWxhdGluZyB0aGUgc3BlY2lhbCBtb3VzZSBldmVudHMgd2l0aCBtb3VzZW92ZXIvXG4gIC8vIG1vdXNlb3V0KS5cbiAgLy9cbiAgLy8gU2luY2Ugd2UncmUgbWFraW5nIGEgY29weSBhbnl3YXlzLCB3ZSBtaWdodCBhcyB3ZWxsIGF0dGVtcHQgdG8gY29udmVydFxuICAvLyB0aGlzIGV2ZW50IGludG8gYSBwc2V1ZG8tcmVhbCBtb3VzZWVudGVyL21vdXNlbGVhdmUgZXZlbnQgYnkgYWRqdXN0aW5nXG4gIC8vIGl0cyB0eXBlLlxuICAvL1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIGNvbnN0IGNvcHk6IHstcmVhZG9ubHkgW1AgaW4ga2V5b2YgRXZlbnRdPzogRXZlbnRbUF19ID0ge307XG4gIGZvciAoY29uc3QgcHJvcGVydHkgaW4gZSkge1xuICAgIGlmIChwcm9wZXJ0eSA9PT0gJ3NyY0VsZW1lbnQnIHx8IHByb3BlcnR5ID09PSAndGFyZ2V0Jykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IHByb3BlcnR5IGFzIGtleW9mIEV2ZW50O1xuICAgIC8vIE1ha2luZyBhIGNvcHkgcmVxdWlyZXMgaXRlcmF0aW5nIHRocm91Z2ggYWxsIHByb3BlcnRpZXMgb2YgYEV2ZW50YC5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZGljdC1hY2Nlc3Mtb24tc3RydWN0LXR5cGVcbiAgICBjb25zdCB2YWx1ZSA9IGVba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgLy8gVmFsdWUgc2hvdWxkIGJlIHRoZSBleHBlY3RlZCB0eXBlLCBidXQgdGhlIHZhbHVlIG9mIGBrZXlgIGlzIG5vdCBrbm93blxuICAgIC8vIHN0YXRpY2FsbHkuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIGNvcHlba2V5XSA9IHZhbHVlIGFzIGFueTtcbiAgfVxuICBpZiAoZS50eXBlID09PSBFdmVudFR5cGUuTU9VU0VPVkVSKSB7XG4gICAgY29weVsndHlwZSddID0gRXZlbnRUeXBlLk1PVVNFRU5URVI7XG4gIH0gZWxzZSBpZiAoZS50eXBlID09PSBFdmVudFR5cGUuTU9VU0VPVVQpIHtcbiAgICBjb3B5Wyd0eXBlJ10gPSBFdmVudFR5cGUuTU9VU0VMRUFWRTtcbiAgfSBlbHNlIGlmIChlLnR5cGUgPT09IEV2ZW50VHlwZS5QT0lOVEVST1ZFUikge1xuICAgIGNvcHlbJ3R5cGUnXSA9IEV2ZW50VHlwZS5QT0lOVEVSRU5URVI7XG4gIH0gZWxzZSB7XG4gICAgY29weVsndHlwZSddID0gRXZlbnRUeXBlLlBPSU5URVJMRUFWRTtcbiAgfVxuICBjb3B5Wyd0YXJnZXQnXSA9IGNvcHlbJ3NyY0VsZW1lbnQnXSA9IHRhcmdldDtcbiAgY29weVsnYnViYmxlcyddID0gZmFsc2U7XG4gIHJldHVybiBjb3B5IGFzIEV2ZW50O1xufVxuXG4vKipcbiAqIFJldHVybnMgdG91Y2ggZGF0YSBleHRyYWN0ZWQgZnJvbSB0aGUgdG91Y2ggZXZlbnQ6IGNsaWVudFgsIGNsaWVudFksIHNjcmVlblhcbiAqIGFuZCBzY3JlZW5ZLiBJZiB0aGUgZXZlbnQgaGFzIG5vIHRvdWNoIGluZm9ybWF0aW9uIGF0IGFsbCwgdGhlIHJldHVybmVkXG4gKiB2YWx1ZSBpcyBudWxsLlxuICpcbiAqIFRoZSBmaWVsZHMgb2YgdGhpcyBPYmplY3QgYXJlIHVucXVvdGVkLlxuICpcbiAqIEBwYXJhbSBldmVudCBBIHRvdWNoIGV2ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG91Y2hEYXRhKFxuICBldmVudDogVG91Y2hFdmVudCxcbik6IHtjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlcjsgc2NyZWVuWDogbnVtYmVyOyBzY3JlZW5ZOiBudW1iZXJ9IHwgbnVsbCB7XG4gIGNvbnN0IHRvdWNoID1cbiAgICAoZXZlbnQuY2hhbmdlZFRvdWNoZXMgJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0pIHx8IChldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXNbMF0pO1xuICBpZiAoIXRvdWNoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBjbGllbnRYOiB0b3VjaC5jbGllbnRYLFxuICAgIGNsaWVudFk6IHRvdWNoLmNsaWVudFksXG4gICAgc2NyZWVuWDogdG91Y2guc2NyZWVuWCxcbiAgICBzY3JlZW5ZOiB0b3VjaC5zY3JlZW5ZLFxuICB9O1xufVxuXG5kZWNsYXJlIGludGVyZmFjZSBTeW50aGV0aWNNb3VzZUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAvLyBSZWRlY2xhcmVkIGZyb20gRXZlbnQgdG8gaW5kaWNhdGUgdGhhdCBpdCBpcyBub3QgcmVhZG9ubHkuXG4gIGRlZmF1bHRQcmV2ZW50ZWQ6IGJvb2xlYW47XG4gIG9yaWdpbmFsRXZlbnRUeXBlOiBzdHJpbmc7XG4gIF9wcm9wYWdhdGlvblN0b3BwZWQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgRXZlbnRMaWtlIG9iamVjdCBmb3IgYSBcImNsaWNrXCIgZXZlbnQgdGhhdCdzIGRlcml2ZWQgZnJvbSB0aGVcbiAqIG9yaWdpbmFsIGNvcnJlc3BvbmRpbmcgXCJ0b3VjaGVuZFwiIGV2ZW50IGZvciBhIGZhc3QtY2xpY2sgaW1wbGVtZW50YXRpb24uXG4gKlxuICogSXQgdGFrZXMgYSB0b3VjaCBldmVudCwgYWRkcyBjb21tb24gZmllbGRzIGZvdW5kIGluIGEgY2xpY2sgZXZlbnQgYW5kXG4gKiBjaGFuZ2VzIHRoZSB0eXBlIHRvICdjbGljaycsIHNvIHRoYXQgdGhlIHJlc3VsdGluZyBldmVudCBsb29rcyBtb3JlIGxpa2VcbiAqIGEgcmVhbCBjbGljayBldmVudC5cbiAqXG4gKiBAcGFyYW0gZXZlbnQgQSB0b3VjaCBldmVudC5cbiAqIEByZXR1cm4gQSBtb2RpZmllZCBldmVudC1saWtlIG9iamVjdCBjb3BpZWQgZnJvbSB0aGUgZXZlbnQgb2JqZWN0IHBhc3NlZCBpbnRvXG4gKiAgICAgdGhpcyBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY3JlYXRlVG91Y2hFdmVudEFzQ2xpY2soZXZlbnQ6IFRvdWNoRXZlbnQpOiBNb3VzZUV2ZW50IHtcbiAgY29uc3QgY2xpY2s6IHstcmVhZG9ubHkgW1AgaW4ga2V5b2YgTW91c2VFdmVudF0/OiBNb3VzZUV2ZW50W1BdfSAmIFBhcnRpYWw8U3ludGhldGljTW91c2VFdmVudD4gPVxuICAgIHt9O1xuICBjbGlja1snb3JpZ2luYWxFdmVudFR5cGUnXSA9IGV2ZW50LnR5cGU7XG4gIGNsaWNrWyd0eXBlJ10gPSBFdmVudFR5cGUuQ0xJQ0s7XG4gIGZvciAoY29uc3QgcHJvcGVydHkgaW4gZXZlbnQpIHtcbiAgICBpZiAocHJvcGVydHkgPT09ICd0eXBlJyB8fCBwcm9wZXJ0eSA9PT0gJ3NyY0VsZW1lbnQnKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3Qga2V5ID0gcHJvcGVydHkgYXMga2V5b2YgVG91Y2hFdmVudDtcbiAgICAvLyBNYWtpbmcgYSBjb3B5IHJlcXVpcmVzIGl0ZXJhdGluZyB0aHJvdWdoIGFsbCBwcm9wZXJ0aWVzIG9mIGBUb3VjaEV2ZW50YC5cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZGljdC1hY2Nlc3Mtb24tc3RydWN0LXR5cGVcbiAgICBjb25zdCB2YWx1ZSA9IGV2ZW50W2tleV07XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIC8vIFZhbHVlIHNob3VsZCBiZSB0aGUgZXhwZWN0ZWQgdHlwZSwgYnV0IHRoZSB2YWx1ZSBvZiBga2V5YCBpcyBub3Qga25vd25cbiAgICAvLyBzdGF0aWNhbGx5LlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICBjbGlja1trZXkgYXMga2V5b2YgTW91c2VFdmVudF0gPSB2YWx1ZSBhcyBhbnk7XG4gIH1cblxuICAvLyBFbnN1cmUgdGhhdCB0aGUgZXZlbnQgaGFzIHRoZSBtb3N0IHJlY2VudCB0aW1lc3RhbXAuIFRoaXMgdGltZXN0YW1wXG4gIC8vIG1heSBiZSB1c2VkIGluIHRoZSBmdXR1cmUgdG8gdmFsaWRhdGUgb3IgY2FuY2VsIHN1YnNlcXVlbnQgY2xpY2sgZXZlbnRzLlxuICBjbGlja1sndGltZVN0YW1wJ10gPSBEYXRlLm5vdygpO1xuXG4gIC8vIEVtdWxhdGUgcHJldmVudERlZmF1bHQgYW5kIHN0b3BQcm9wYWdhdGlvbiBiZWhhdmlvclxuICBjbGlja1snZGVmYXVsdFByZXZlbnRlZCddID0gZmFsc2U7XG4gIGNsaWNrWydwcmV2ZW50RGVmYXVsdCddID0gc3ludGhldGljUHJldmVudERlZmF1bHQ7XG4gIGNsaWNrWydfcHJvcGFnYXRpb25TdG9wcGVkJ10gPSBmYWxzZTtcbiAgY2xpY2tbJ3N0b3BQcm9wYWdhdGlvbiddID0gc3ludGhldGljU3RvcFByb3BhZ2F0aW9uO1xuXG4gIC8vIEVtdWxhdGUgY2xpY2sgY29vcmRpbmF0ZXMgdXNpbmcgdG91Y2ggaW5mb1xuICBjb25zdCB0b3VjaCA9IGdldFRvdWNoRGF0YShldmVudCk7XG4gIGlmICh0b3VjaCkge1xuICAgIGNsaWNrWydjbGllbnRYJ10gPSB0b3VjaC5jbGllbnRYO1xuICAgIGNsaWNrWydjbGllbnRZJ10gPSB0b3VjaC5jbGllbnRZO1xuICAgIGNsaWNrWydzY3JlZW5YJ10gPSB0b3VjaC5zY3JlZW5YO1xuICAgIGNsaWNrWydzY3JlZW5ZJ10gPSB0b3VjaC5zY3JlZW5ZO1xuICB9XG4gIHJldHVybiBjbGljayBhcyBNb3VzZUV2ZW50O1xufVxuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIFwicHJldmVudERlZmF1bHRcIiBmb3IgYSBzeW50aGVzaXplZCBldmVudC4gU2ltcGx5XG4gKiBzZXRzIFwiZGVmYXVsdFByZXZlbnRlZFwiIHByb3BlcnR5IHRvIHRydWUuXG4gKi9cbmZ1bmN0aW9uIHN5bnRoZXRpY1ByZXZlbnREZWZhdWx0KHRoaXM6IEV2ZW50KSB7XG4gICh0aGlzIGFzIFN5bnRoZXRpY01vdXNlRXZlbnQpLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xufVxuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIFwic3RvcFByb3BhZ2F0aW9uXCIgZm9yIGEgc3ludGhlc2l6ZWQgZXZlbnQuIEl0IHNpbXBseVxuICogc2V0cyBhIHN5bnRoZXRpYyBub24tc3RhbmRhcmQgXCJfcHJvcGFnYXRpb25TdG9wcGVkXCIgcHJvcGVydHkgdG8gdHJ1ZS5cbiAqL1xuZnVuY3Rpb24gc3ludGhldGljU3RvcFByb3BhZ2F0aW9uKHRoaXM6IEV2ZW50KSB7XG4gICh0aGlzIGFzIFN5bnRoZXRpY01vdXNlRXZlbnQpLl9wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xufVxuXG4vKipcbiAqIE1hcHBpbmcgb2YgS2V5Ym9hcmRFdmVudC5rZXkgdmFsdWVzIHRvXG4gKiBLZXlDb2RlIHZhbHVlcy5cbiAqL1xuY29uc3QgQUNUSU9OX0tFWV9UT19LRVlDT0RFOiB7W2tleTogc3RyaW5nXTogbnVtYmVyfSA9IHtcbiAgJ0VudGVyJzogS2V5Q29kZS5FTlRFUixcbiAgJyAnOiBLZXlDb2RlLlNQQUNFLFxufTtcblxuLyoqXG4gKiBNYXBwaW5nIG9mIEhUTUwgZWxlbWVudCBpZGVudGlmaWVycyAoQVJJQSByb2xlLCB0eXBlLCBvciB0YWdOYW1lKSB0byB0aGVcbiAqIGtleXMgKGVudGVyIGFuZC9vciBzcGFjZSkgdGhhdCBzaG91bGQgYWN0aXZhdGUgdGhlbS4gQSB2YWx1ZSBvZiB6ZXJvIG1lYW5zXG4gKiB0aGF0IGJvdGggc2hvdWxkIGFjdGl2YXRlIHRoZW0uXG4gKi9cbmV4cG9ydCBjb25zdCBJREVOVElGSUVSX1RPX0tFWV9UUklHR0VSX01BUFBJTkc6IHtba2V5OiBzdHJpbmddOiBudW1iZXJ9ID0ge1xuICAnQSc6IEtleUNvZGUuRU5URVIsXG4gICdCVVRUT04nOiAwLFxuICAnQ0hFQ0tCT1gnOiBLZXlDb2RlLlNQQUNFLFxuICAnQ09NQk9CT1gnOiBLZXlDb2RlLkVOVEVSLFxuICAnRklMRSc6IDAsXG4gICdHUklEQ0VMTCc6IEtleUNvZGUuRU5URVIsXG4gICdMSU5LJzogS2V5Q29kZS5FTlRFUixcbiAgJ0xJU1RCT1gnOiBLZXlDb2RlLkVOVEVSLFxuICAnTUVOVSc6IDAsXG4gICdNRU5VQkFSJzogMCxcbiAgJ01FTlVJVEVNJzogMCxcbiAgJ01FTlVJVEVNQ0hFQ0tCT1gnOiAwLFxuICAnTUVOVUlURU1SQURJTyc6IDAsXG4gICdPUFRJT04nOiAwLFxuICAnUkFESU8nOiBLZXlDb2RlLlNQQUNFLFxuICAnUkFESU9HUk9VUCc6IEtleUNvZGUuU1BBQ0UsXG4gICdSRVNFVCc6IDAsXG4gICdTVUJNSVQnOiAwLFxuICAnU1dJVENIJzogS2V5Q29kZS5TUEFDRSxcbiAgJ1RBQic6IDAsXG4gICdUUkVFJzogS2V5Q29kZS5FTlRFUixcbiAgJ1RSRUVJVEVNJzogS2V5Q29kZS5FTlRFUixcbn07XG5cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0byBwcm9jZXNzIHNwYWNlIGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBlbGVtZW50O1xuICogY2hlY2tzIHRvIG1ha2Ugc3VyZSB0aGF0IHR5cGUgaXMgbm90IG51bGwuXG4gKiBAcGFyYW0gZWxlbWVudCBUaGUgZWxlbWVudC5cbiAqIEByZXR1cm4gV2hldGhlciBvciBub3QgdG8gcHJvY2VzcyBzcGFjZSBiYXNlZCBvbiB0eXBlLlxuICovXG5mdW5jdGlvbiBwcm9jZXNzU3BhY2UoZWxlbWVudDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICBjb25zdCB0eXBlID0gKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd0eXBlJykgfHwgZWxlbWVudC50YWdOYW1lKS50b1VwcGVyQ2FzZSgpO1xuICByZXR1cm4gdHlwZSBpbiBQUk9DRVNTX1NQQUNFO1xufVxuXG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGdpdmVuIGVsZW1lbnQgaXMgYSB0ZXh0IGNvbnRyb2wuXG4gKiBAcGFyYW0gZWwgVGhlIGVsZW1lbnQuXG4gKiBAcmV0dXJuIFdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBlbGVtZW50IGlzIGEgdGV4dCBjb250cm9sLlxuICovXG5mdW5jdGlvbiBpc1RleHRDb250cm9sKGVsOiBFbGVtZW50KTogYm9vbGVhbiB7XG4gIGNvbnN0IHR5cGUgPSAoZWwuZ2V0QXR0cmlidXRlKCd0eXBlJykgfHwgZWwudGFnTmFtZSkudG9VcHBlckNhc2UoKTtcbiAgcmV0dXJuIHR5cGUgaW4gVEVYVF9DT05UUk9MUztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGlmIHRoZSBnaXZlbiBlbGVtZW50IGlzIGEgbmF0aXZlIEhUTUwgY29udHJvbC5cbiAqIEBwYXJhbSBlbCBUaGUgZWxlbWVudC5cbiAqIEByZXR1cm4gSWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgYSBuYXRpdmUgSFRNTCBjb250cm9sLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOYXRpdmVIVE1MQ29udHJvbChlbDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZWwudGFnTmFtZS50b1VwcGVyQ2FzZSgpIGluIE5BVElWRV9IVE1MX0NPTlRST0xTO1xufVxuXG4vKipcbiAqIFJldHVybnMgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgbmF0aXZlbHkgYWN0aXZhdGFibGUuIEJyb3dzZXJzIGVtaXQgY2xpY2tcbiAqIGV2ZW50cyBmb3IgbmF0aXZlbHkgYWN0aXZhdGFibGUgZWxlbWVudHMsIGV2ZW4gd2hlbiBhY3RpdmF0ZWQgdmlhIGtleWJvYXJkLlxuICogRm9yIHRoZXNlIGVsZW1lbnRzLCB3ZSBkb24ndCBuZWVkIHRvIHJhaXNlIGExMXkgY2xpY2sgZXZlbnRzLlxuICogQHBhcmFtIGVsIFRoZSBlbGVtZW50LlxuICogQHJldHVybiBJZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyBhIG5hdGl2ZSBIVE1MIGNvbnRyb2wuXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlbHlBY3RpdmF0YWJsZShlbDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGVsLnRhZ05hbWUudG9VcHBlckNhc2UoKSA9PT0gJ0JVVFRPTicgfHxcbiAgICAoISEoZWwgYXMgSFRNTElucHV0RWxlbWVudCkudHlwZSAmJiAoZWwgYXMgSFRNTElucHV0RWxlbWVudCkudHlwZS50b1VwcGVyQ2FzZSgpID09PSAnRklMRScpXG4gICk7XG59XG5cbi8qKlxuICogSFRNTCA8aW5wdXQ+IHR5cGVzIChub3QgQVJJQSByb2xlcykgd2hpY2ggd2lsbCBhdXRvLXRyaWdnZXIgYSBjbGljayBldmVudCBmb3JcbiAqIHRoZSBTcGFjZSBrZXksIHdpdGggc2lkZS1lZmZlY3RzLiBXZSB3aWxsIG5vdCBjYWxsIHByZXZlbnREZWZhdWx0IGlmIHNwYWNlIGlzXG4gKiBwcmVzc2VkLCBub3Igd2lsbCB3ZSByYWlzZSBhMTF5IGNsaWNrIGV2ZW50cy4gIEZvciBhbGwgb3RoZXIgZWxlbWVudHMsIHdlIGNhblxuICogc3VwcHJlc3MgdGhlIGRlZmF1bHQgZXZlbnQgKHdoaWNoIGhhcyBubyBkZXNpcmVkIHNpZGUtZWZmZWN0cykgYW5kIGhhbmRsZSB0aGVcbiAqIGtleWRvd24gb3Vyc2VsdmVzLlxuICovXG5jb25zdCBQUk9DRVNTX1NQQUNFOiB7W2tleTogc3RyaW5nXTogYm9vbGVhbn0gPSB7XG4gICdDSEVDS0JPWCc6IHRydWUsXG4gICdGSUxFJzogdHJ1ZSxcbiAgJ09QVElPTic6IHRydWUsXG4gICdSQURJTyc6IHRydWUsXG59O1xuXG4vKiogVGFnTmFtZXMgYW5kIElucHV0IHR5cGVzIGZvciB3aGljaCB0byBub3QgcHJvY2VzcyBlbnRlci9zcGFjZSBhcyBjbGljay4gKi9cbmNvbnN0IFRFWFRfQ09OVFJPTFM6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHtcbiAgJ0NPTE9SJzogdHJ1ZSxcbiAgJ0RBVEUnOiB0cnVlLFxuICAnREFURVRJTUUnOiB0cnVlLFxuICAnREFURVRJTUUtTE9DQUwnOiB0cnVlLFxuICAnRU1BSUwnOiB0cnVlLFxuICAnTU9OVEgnOiB0cnVlLFxuICAnTlVNQkVSJzogdHJ1ZSxcbiAgJ1BBU1NXT1JEJzogdHJ1ZSxcbiAgJ1JBTkdFJzogdHJ1ZSxcbiAgJ1NFQVJDSCc6IHRydWUsXG4gICdURUwnOiB0cnVlLFxuICAnVEVYVCc6IHRydWUsXG4gICdURVhUQVJFQSc6IHRydWUsXG4gICdUSU1FJzogdHJ1ZSxcbiAgJ1VSTCc6IHRydWUsXG4gICdXRUVLJzogdHJ1ZSxcbn07XG5cbi8qKiBUYWdOYW1lcyB0aGF0IGFyZSBuYXRpdmUgSFRNTCBjb250cm9scy4gKi9cbmNvbnN0IE5BVElWRV9IVE1MX0NPTlRST0xTOiB7W2tleTogc3RyaW5nXTogYm9vbGVhbn0gPSB7XG4gICdBJzogdHJ1ZSxcbiAgJ0FSRUEnOiB0cnVlLFxuICAnQlVUVE9OJzogdHJ1ZSxcbiAgJ0RJQUxPRyc6IHRydWUsXG4gICdJTUcnOiB0cnVlLFxuICAnSU5QVVQnOiB0cnVlLFxuICAnTElOSyc6IHRydWUsXG4gICdNRU5VJzogdHJ1ZSxcbiAgJ09QVEdST1VQJzogdHJ1ZSxcbiAgJ09QVElPTic6IHRydWUsXG4gICdQUk9HUkVTUyc6IHRydWUsXG4gICdTRUxFQ1QnOiB0cnVlLFxuICAnVEVYVEFSRUEnOiB0cnVlLFxufTtcblxuLyoqIEV4cG9ydGVkIGZvciB0ZXN0aW5nLiAqL1xuZXhwb3J0IGNvbnN0IHRlc3RpbmcgPSB7XG4gIHNldElzTWFjKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaXNNYWMgPSB2YWx1ZTtcbiAgfSxcbn07XG4iXX0=