@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.
- package/esm2022/primitives/event-dispatch/contract_binary.mjs +10 -0
- package/esm2022/primitives/event-dispatch/index.mjs +13 -0
- package/esm2022/primitives/event-dispatch/src/a11y_click.mjs +54 -0
- package/esm2022/primitives/event-dispatch/src/accessibility.mjs +35 -0
- package/esm2022/primitives/event-dispatch/src/attribute.mjs +72 -0
- package/esm2022/primitives/event-dispatch/src/base_dispatcher.mjs +196 -0
- package/esm2022/primitives/event-dispatch/src/cache.mjs +95 -0
- package/esm2022/primitives/event-dispatch/src/char.mjs +35 -0
- package/esm2022/primitives/event-dispatch/src/custom_events.mjs +63 -0
- package/esm2022/primitives/event-dispatch/src/dispatcher.mjs +254 -0
- package/esm2022/primitives/event-dispatch/src/dom.mjs +48 -0
- package/esm2022/primitives/event-dispatch/src/earlyeventcontract.mjs +36 -0
- package/esm2022/primitives/event-dispatch/src/event.mjs +638 -0
- package/esm2022/primitives/event-dispatch/src/event_contract_container.mjs +63 -0
- package/esm2022/primitives/event-dispatch/src/event_contract_defines.mjs +48 -0
- package/esm2022/primitives/event-dispatch/src/event_contract_multi_container.mjs +192 -0
- package/esm2022/primitives/event-dispatch/src/event_handler.mjs +9 -0
- package/esm2022/primitives/event-dispatch/src/event_info.mjs +199 -0
- package/esm2022/primitives/event-dispatch/src/event_type.mjs +244 -0
- package/esm2022/primitives/event-dispatch/src/eventcontract.mjs +675 -0
- package/esm2022/primitives/event-dispatch/src/key_code.mjs +21 -0
- package/esm2022/primitives/event-dispatch/src/legacy_dispatcher.mjs +9 -0
- package/esm2022/primitives/event-dispatch/src/property.mjs +35 -0
- package/esm2022/primitives/event-dispatch/src/register_events.mjs +32 -0
- package/esm2022/primitives/event-dispatch/src/replay.mjs +389 -0
- package/esm2022/primitives/event-dispatch/src/restriction.mjs +15 -0
- package/esm2022/primitives/signals/index.mjs +3 -3
- package/esm2022/primitives/signals/src/computed.mjs +5 -3
- package/esm2022/primitives/signals/src/graph.mjs +14 -9
- package/esm2022/primitives/signals/src/signal.mjs +2 -2
- package/esm2022/primitives/signals/src/watch.mjs +2 -2
- package/esm2022/src/change_detection/scheduling/zoneless_scheduling_impl.mjs +50 -5
- package/esm2022/src/core.mjs +2 -1
- package/esm2022/src/core_private_export.mjs +2 -1
- package/esm2022/src/defer/instructions.mjs +31 -8
- package/esm2022/src/di/host_tag_name_token.mjs +65 -0
- package/esm2022/src/di/index.mjs +2 -1
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/hydration/annotate.mjs +15 -1
- package/esm2022/src/hydration/event_replay.mjs +181 -0
- package/esm2022/src/hydration/tokens.mjs +6 -1
- package/esm2022/src/pending_tasks.mjs +54 -11
- package/esm2022/src/render3/component_ref.mjs +1 -1
- package/esm2022/src/render3/context_discovery.mjs +15 -1
- package/esm2022/src/render3/instructions/control_flow.mjs +50 -3
- package/esm2022/src/render3/list_reconciliation.mjs +41 -1
- package/esm2022/src/util/callback_scheduler.mjs +13 -2
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/src/zone/ng_zone.mjs +22 -6
- package/esm2022/testing/src/async.mjs +2 -10
- package/esm2022/testing/src/defer.mjs +1 -2
- package/esm2022/testing/src/logger.mjs +3 -3
- package/event-dispatch-contract.min.js +1 -1
- package/fesm2022/core.mjs +516 -39
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +3044 -0
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -0
- package/fesm2022/primitives/signals.mjs +17 -10
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +3 -12
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +75 -13
- package/package.json +7 -1
- package/primitives/event-dispatch/index.d.ts +627 -0
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/{transfer-state → http-providers}/bundle.js +254 -68
- package/schematics/migrations/http-providers/bundle.js.map +7 -0
- package/schematics/migrations/invalid-two-way-bindings/bundle.js +659 -337
- package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
- package/schematics/migrations.json +6 -16
- package/schematics/ng-generate/control-flow-migration/bundle.js +667 -345
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
- package/schematics/ng-generate/standalone-migration/bundle.js +1030 -660
- package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
- package/testing/index.d.ts +2 -9
- package/schematics/migrations/block-template-entities/bundle.js +0 -22808
- package/schematics/migrations/block-template-entities/bundle.js.map +0 -7
- package/schematics/migrations/compiler-options/bundle.js +0 -582
- package/schematics/migrations/compiler-options/bundle.js.map +0 -7
- 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=
|