@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,675 @@
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
+ /**
9
+ * @fileoverview Implements the local event handling contract. This
10
+ * allows DOM objects in a container that enters into this contract to
11
+ * define event handlers which are executed in a local context.
12
+ *
13
+ * One EventContract instance can manage the contract for multiple
14
+ * containers, which are added using the addContainer() method.
15
+ *
16
+ * Events can be registered using the addEvent() method.
17
+ *
18
+ * A Dispatcher is added using the registerDispatcher() method. Until there is
19
+ * a dispatcher, events are queued. The idea is that the EventContract
20
+ * class is inlined in the HTML of the top level page and instantiated
21
+ * right after the start of <body>. The Dispatcher class is contained
22
+ * in the external deferred js, and instantiated and registered with
23
+ * EventContract when the external javascript in the page loads. The
24
+ * external javascript will also register the jsaction handlers, which
25
+ * then pick up the queued events at the time of registration.
26
+ *
27
+ * Since this class is meant to be inlined in the main page HTML, the
28
+ * size of the binary compiled from this file MUST be kept as small as
29
+ * possible and thus its dependencies to a minimum.
30
+ */
31
+ import * as a11yClickLib from './a11y_click';
32
+ import { Attribute as AccessibilityAttribute } from './accessibility';
33
+ import { Attribute } from './attribute';
34
+ import * as cache from './cache';
35
+ import { Char } from './char';
36
+ import * as eventLib from './event';
37
+ import { A11Y_CLICK_SUPPORT, A11Y_SUPPORT_IN_DISPATCHER, CUSTOM_EVENT_SUPPORT, JSNAMESPACE_SUPPORT, MOUSE_SPECIAL_SUPPORT, STOP_PROPAGATION, } from './event_contract_defines';
38
+ import * as eventInfoLib from './event_info';
39
+ import { EventType } from './event_type';
40
+ import { Property } from './property';
41
+ const DEFAULT_EVENT_TYPE = EventType.CLICK;
42
+ /**
43
+ * Since maps from event to action are immutable we can use a single map
44
+ * to represent the empty map.
45
+ */
46
+ const EMPTY_ACTION_MAP = {};
47
+ /**
48
+ * This regular expression matches a semicolon.
49
+ */
50
+ const REGEXP_SEMICOLON = /\s*;\s*/;
51
+ /**
52
+ * EventContract intercepts events in the bubbling phase at the
53
+ * boundary of a container element, and maps them to generic actions
54
+ * which are specified using the custom jsaction attribute in
55
+ * HTML. Behavior of the application is then specified in terms of
56
+ * handler for such actions, cf. jsaction.Dispatcher in dispatcher.js.
57
+ *
58
+ * This has several benefits: (1) No DOM event handlers need to be
59
+ * registered on the specific elements in the UI. (2) The set of
60
+ * events that the application has to handle can be specified in terms
61
+ * of the semantics of the application, rather than in terms of DOM
62
+ * events. (3) Invocation of handlers can be delayed and handlers can
63
+ * be delay loaded in a generic way.
64
+ */
65
+ export class EventContract {
66
+ static { this.CUSTOM_EVENT_SUPPORT = CUSTOM_EVENT_SUPPORT; }
67
+ static { this.STOP_PROPAGATION = STOP_PROPAGATION; }
68
+ static { this.A11Y_SUPPORT_IN_DISPATCHER = A11Y_SUPPORT_IN_DISPATCHER; }
69
+ static { this.A11Y_CLICK_SUPPORT = A11Y_CLICK_SUPPORT; }
70
+ static { this.MOUSE_SPECIAL_SUPPORT = MOUSE_SPECIAL_SUPPORT; }
71
+ static { this.JSNAMESPACE_SUPPORT = JSNAMESPACE_SUPPORT; }
72
+ constructor(containerManager) {
73
+ /**
74
+ * The DOM events which this contract covers. Used to prevent double
75
+ * registration of event types. The value of the map is the
76
+ * internally created DOM event handler function that handles the
77
+ * DOM events. See addEvent().
78
+ *
79
+ */
80
+ this.eventHandlers = {};
81
+ this.browserEventTypeToExtraEventTypes = {};
82
+ /**
83
+ * The dispatcher function. Events are passed to this function for
84
+ * handling once it was set using the registerDispatcher() method. This is
85
+ * done because the function is passed from another jsbinary, so passing the
86
+ * instance and invoking the method here would require to leave the method
87
+ * unobfuscated.
88
+ */
89
+ this.dispatcher = null;
90
+ /**
91
+ * The list of suspended `EventInfo` that will be dispatched
92
+ * as soon as the `Dispatcher` is registered.
93
+ */
94
+ this.queuedEventInfos = [];
95
+ /** Whether a11y click support has been loaded or not. */
96
+ this.hasA11yClickSupport = false;
97
+ /** Whether to add an a11y click listener. */
98
+ this.addA11yClickListener = EventContract.A11Y_SUPPORT_IN_DISPATCHER;
99
+ this.updateEventInfoForA11yClick = undefined;
100
+ this.preventDefaultForA11yClick = undefined;
101
+ this.populateClickOnlyAction = undefined;
102
+ this.containerManager = containerManager;
103
+ if (EventContract.CUSTOM_EVENT_SUPPORT) {
104
+ this.addEvent(EventType.CUSTOM);
105
+ }
106
+ if (EventContract.A11Y_CLICK_SUPPORT) {
107
+ // Add a11y click support to the `EventContract`.
108
+ this.addA11yClickSupport();
109
+ }
110
+ }
111
+ handleEvent(eventType, event, container) {
112
+ const eventInfo = eventInfoLib.createEventInfoFromParameters(
113
+ /* eventType= */ eventType,
114
+ /* event= */ event,
115
+ /* targetElement= */ event.target,
116
+ /* container= */ container,
117
+ /* timestamp= */ Date.now());
118
+ this.handleEventInfo(eventInfo);
119
+ }
120
+ /**
121
+ * Handle an `EventInfo`.
122
+ * @param allowRehandling Used in the case of a11y click casting to prevent
123
+ * us from trying to rehandle in an infinite loop.
124
+ */
125
+ handleEventInfo(eventInfo, allowRehandling = true) {
126
+ if (!this.dispatcher) {
127
+ // All events are queued when the dispatcher isn't yet loaded.
128
+ eventInfoLib.setIsReplay(eventInfo, true);
129
+ this.queuedEventInfos?.push(eventInfo);
130
+ }
131
+ if (EventContract.CUSTOM_EVENT_SUPPORT &&
132
+ eventInfoLib.getEventType(eventInfo) === EventType.CUSTOM) {
133
+ const detail = eventInfoLib.getEvent(eventInfo).detail;
134
+ // For custom events, use a secondary dispatch based on the internal
135
+ // custom type of the event.
136
+ if (!detail || !detail['_type']) {
137
+ // This should never happen.
138
+ return;
139
+ }
140
+ eventInfoLib.setEventType(eventInfo, detail['_type']);
141
+ }
142
+ this.populateAction(eventInfo);
143
+ if (this.dispatcher &&
144
+ !eventInfoLib.getEvent(eventInfo)[AccessibilityAttribute.SKIP_GLOBAL_DISPATCH]) {
145
+ const globalEventInfo = eventInfoLib.cloneEventInfo(eventInfo);
146
+ // In some cases, `populateAction` will rewrite `click` events to
147
+ // `clickonly`. Revert back to a regular click, otherwise we won't be able
148
+ // to execute global event handlers registered on click events.
149
+ if (eventInfoLib.getEventType(globalEventInfo) === EventType.CLICKONLY) {
150
+ eventInfoLib.setEventType(globalEventInfo, EventType.CLICK);
151
+ }
152
+ this.dispatcher(globalEventInfo, /* dispatch global event */ true);
153
+ }
154
+ const action = eventInfoLib.getAction(eventInfo);
155
+ if (!action && !checkDispatcherForA11yClick(eventInfo)) {
156
+ return;
157
+ }
158
+ if (this.dispatcher) {
159
+ if (action &&
160
+ shouldPreventDefaultBeforeDispatching(eventInfoLib.getActionElement(action), eventInfo)) {
161
+ eventLib.preventDefault(eventInfoLib.getEvent(eventInfo));
162
+ }
163
+ const unresolvedEventInfo = this.dispatcher(eventInfo);
164
+ if (unresolvedEventInfo && allowRehandling) {
165
+ // The dispatcher only returns an event for MAYBE_CLICK_EVENT_TYPE
166
+ // events that can't be casted to a click. We run it through the
167
+ // handler again to find keydown actions for it.
168
+ this.handleEventInfo(unresolvedEventInfo, /* allowRehandling= */ false);
169
+ return;
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * Searches for a jsaction that the DOM event maps to and creates an
175
+ * object containing event information used for dispatching by
176
+ * jsaction.Dispatcher. This method populates the `action` and `actionElement`
177
+ * fields of the EventInfo object passed in by finding the first
178
+ * jsaction attribute above the target Node of the event, and below
179
+ * the container Node, that specifies a jsaction for the event
180
+ * type. If no such jsaction is found, then action is undefined.
181
+ *
182
+ * @param eventInfo `EventInfo` to set `action` and `actionElement` if an
183
+ * action is found on any `Element` in the path of the `Event`.
184
+ */
185
+ populateAction(eventInfo) {
186
+ // We distinguish modified and plain clicks in order to support the
187
+ // default browser behavior of modified clicks on links; usually to
188
+ // open the URL of the link in new tab or new window on ctrl/cmd
189
+ // click. A DOM 'click' event is mapped to the jsaction 'click'
190
+ // event iff there is no modifier present on the event. If there is
191
+ // a modifier, it's mapped to 'clickmod' instead.
192
+ //
193
+ // It's allowed to omit the event in the jsaction attribute. In that
194
+ // case, 'click' is assumed. Thus the following two are equivalent:
195
+ //
196
+ // <a href="someurl" jsaction="gna.fu">
197
+ // <a href="someurl" jsaction="click:gna.fu">
198
+ //
199
+ // For unmodified clicks, EventContract invokes the jsaction
200
+ // 'gna.fu'. For modified clicks, EventContract won't find a
201
+ // suitable action and leave the event to be handled by the
202
+ // browser.
203
+ //
204
+ // In order to also invoke a jsaction handler for a modifier click,
205
+ // 'clickmod' needs to be used:
206
+ //
207
+ // <a href="someurl" jsaction="clickmod:gna.fu">
208
+ //
209
+ // EventContract invokes the jsaction 'gna.fu' for modified
210
+ // clicks. Unmodified clicks are left to the browser.
211
+ //
212
+ // In order to set up the event contract to handle both clickonly and
213
+ // clickmod, only addEvent(EventType.CLICK) is necessary.
214
+ //
215
+ // In order to set up the event contract to handle click,
216
+ // addEvent() is necessary for CLICK, KEYDOWN, and KEYPRESS event types. If
217
+ // a11y click support is enabled, addEvent() will set up the appropriate key
218
+ // event handler automatically.
219
+ if (eventInfoLib.getEventType(eventInfo) === EventType.CLICK &&
220
+ eventLib.isModifiedClickEvent(eventInfoLib.getEvent(eventInfo))) {
221
+ eventInfoLib.setEventType(eventInfo, EventType.CLICKMOD);
222
+ }
223
+ else if (this.hasA11yClickSupport) {
224
+ this.updateEventInfoForA11yClick(eventInfo);
225
+ }
226
+ else if (EventContract.A11Y_SUPPORT_IN_DISPATCHER &&
227
+ eventInfoLib.getEventType(eventInfo) === EventType.KEYDOWN &&
228
+ !eventInfoLib.getEvent(eventInfo)[AccessibilityAttribute.SKIP_A11Y_CHECK]) {
229
+ // We use a string literal as this value needs to be referenced in the
230
+ // dispatcher's binary.
231
+ eventInfoLib.setEventType(eventInfo, AccessibilityAttribute.MAYBE_CLICK_EVENT_TYPE);
232
+ }
233
+ // Walk to the parent node, unless the node has a different owner in
234
+ // which case we walk to the owner. Attempt to walk to host of a
235
+ // shadow root if needed.
236
+ let actionElement = eventInfoLib.getTargetElement(eventInfo);
237
+ while (actionElement && actionElement !== eventInfoLib.getContainer(eventInfo)) {
238
+ this.populateActionOnElement(actionElement, eventInfo);
239
+ if (eventInfoLib.getAction(eventInfo)) {
240
+ // An event is handled by at most one jsaction. Thus we stop at the
241
+ // first matching jsaction specified in a jsaction attribute up the
242
+ // ancestor chain of the event target node.
243
+ break;
244
+ }
245
+ if (actionElement[Property.OWNER]) {
246
+ actionElement = actionElement[Property.OWNER];
247
+ continue;
248
+ }
249
+ if (actionElement.parentNode?.nodeName !== '#document-fragment') {
250
+ actionElement = actionElement.parentNode;
251
+ }
252
+ else {
253
+ actionElement = actionElement.parentNode?.host ?? null;
254
+ }
255
+ }
256
+ const action = eventInfoLib.getAction(eventInfo);
257
+ if (!action) {
258
+ // No action found.
259
+ return;
260
+ }
261
+ if (this.hasA11yClickSupport) {
262
+ this.preventDefaultForA11yClick(eventInfo);
263
+ }
264
+ // We attempt to handle the mouseenter/mouseleave events here by
265
+ // detecting whether the mouseover/mouseout events correspond to
266
+ // entering/leaving an element.
267
+ if (EventContract.MOUSE_SPECIAL_SUPPORT &&
268
+ (eventInfoLib.getEventType(eventInfo) === EventType.MOUSEENTER ||
269
+ eventInfoLib.getEventType(eventInfo) === EventType.MOUSELEAVE ||
270
+ eventInfoLib.getEventType(eventInfo) === EventType.POINTERENTER ||
271
+ eventInfoLib.getEventType(eventInfo) === EventType.POINTERLEAVE)) {
272
+ // We attempt to handle the mouseenter/mouseleave events here by
273
+ // detecting whether the mouseover/mouseout events correspond to
274
+ // entering/leaving an element.
275
+ if (eventLib.isMouseSpecialEvent(eventInfoLib.getEvent(eventInfo), eventInfoLib.getEventType(eventInfo), eventInfoLib.getActionElement(action))) {
276
+ // If both mouseover/mouseout and mouseenter/mouseleave events are
277
+ // enabled, two separate handlers for mouseover/mouseout are
278
+ // registered. Both handlers will see the same event instance
279
+ // so we create a copy to avoid interfering with the dispatching of
280
+ // the mouseover/mouseout event.
281
+ const copiedEvent = eventLib.createMouseSpecialEvent(eventInfoLib.getEvent(eventInfo), eventInfoLib.getActionElement(action));
282
+ eventInfoLib.setEvent(eventInfo, copiedEvent);
283
+ // Since the mouseenter/mouseleave events do not bubble, the target
284
+ // of the event is technically the `actionElement` (the node with the
285
+ // `jsaction` attribute)
286
+ eventInfoLib.setTargetElement(eventInfo, eventInfoLib.getActionElement(action));
287
+ }
288
+ else {
289
+ eventInfoLib.unsetAction(eventInfo);
290
+ }
291
+ }
292
+ }
293
+ /**
294
+ * Accesses the jsaction map on a node and retrieves the name of the
295
+ * action the given event is mapped to, if any. It parses the
296
+ * attribute value and stores it in a property on the node for
297
+ * subsequent retrieval without re-parsing and re-accessing the
298
+ * attribute. In order to fully qualify jsaction names using a
299
+ * namespace, the DOM is searched starting at the current node and
300
+ * going through ancestor nodes until a jsnamespace attribute is
301
+ * found.
302
+ *
303
+ * @param actionElement The DOM node to retrieve the jsaction map from.
304
+ * @param eventInfo `EventInfo` to set `action` and `actionElement` if an
305
+ * action is found on the `actionElement`.
306
+ */
307
+ populateActionOnElement(actionElement, eventInfo) {
308
+ const actionMap = parseActions(actionElement, eventInfoLib.getContainer(eventInfo));
309
+ const actionName = actionMap[eventInfoLib.getEventType(eventInfo)];
310
+ if (actionName !== undefined) {
311
+ eventInfoLib.setAction(eventInfo, actionName, actionElement);
312
+ }
313
+ if (this.hasA11yClickSupport) {
314
+ this.populateClickOnlyAction(actionElement, eventInfo, actionMap);
315
+ }
316
+ if (EventContract.A11Y_SUPPORT_IN_DISPATCHER) {
317
+ if (eventInfoLib.getEventType(eventInfo) === AccessibilityAttribute.MAYBE_CLICK_EVENT_TYPE &&
318
+ actionMap[EventType.CLICK] !== undefined) {
319
+ // We'll take the first CLICK action we find and have the dispatcher
320
+ // check if the keydown event can be used as a CLICK. If not, the
321
+ // dispatcher will retrigger the event so that we can find a keydown
322
+ // event instead.
323
+ // When we get MAYBE_CLICK_EVENT_TYPE as an eventType, we want to
324
+ // retrieve the action corresponding to CLICK, but still keep the
325
+ // eventInfoLib.getEventType(eventInfo, ) as MAYBE_CLICK_EVENT_TYPE. The
326
+ // dispatcher uses this event type to determine if it should get the
327
+ // handler for the action.
328
+ eventInfoLib.setAction(eventInfo, actionMap[EventType.CLICK], actionElement);
329
+ }
330
+ else {
331
+ a11yClickLib.populateClickOnlyAction(actionElement, eventInfo, actionMap);
332
+ }
333
+ }
334
+ }
335
+ /**
336
+ * Enables jsaction handlers to be called for the event type given by
337
+ * name.
338
+ *
339
+ * If the event is already registered, this does nothing.
340
+ *
341
+ * @param prefixedEventType If supplied, this event is used in
342
+ * the actual browser event registration instead of the name that is
343
+ * exposed to jsaction. Use this if you e.g. want users to be able
344
+ * to subscribe to jsaction="transitionEnd:foo" while the underlying
345
+ * event is webkitTransitionEnd in one browser and mozTransitionEnd
346
+ * in another.
347
+ */
348
+ addEvent(eventType, prefixedEventType) {
349
+ if (eventType in this.eventHandlers || !this.containerManager) {
350
+ return;
351
+ }
352
+ if (!EventContract.MOUSE_SPECIAL_SUPPORT &&
353
+ (eventType === EventType.MOUSEENTER ||
354
+ eventType === EventType.MOUSELEAVE ||
355
+ eventType === EventType.POINTERENTER ||
356
+ eventType === EventType.POINTERLEAVE)) {
357
+ return;
358
+ }
359
+ const eventHandler = (eventType, event, container) => {
360
+ this.handleEvent(eventType, event, container);
361
+ };
362
+ // Store the callback to allow us to replay events.
363
+ this.eventHandlers[eventType] = eventHandler;
364
+ const browserEventType = eventLib.getBrowserEventType(prefixedEventType || eventType);
365
+ if (browserEventType !== eventType) {
366
+ const eventTypes = this.browserEventTypeToExtraEventTypes[browserEventType] || [];
367
+ eventTypes.push(eventType);
368
+ this.browserEventTypeToExtraEventTypes[browserEventType] = eventTypes;
369
+ }
370
+ this.containerManager.addEventListener(browserEventType, (element) => {
371
+ return (event) => {
372
+ eventHandler(eventType, event, element);
373
+ };
374
+ });
375
+ // Automatically install a keypress/keydown event handler if support for
376
+ // accessible clicks is turned on.
377
+ if (this.addA11yClickListener && eventType === EventType.CLICK) {
378
+ this.addEvent(EventType.KEYDOWN);
379
+ }
380
+ }
381
+ /**
382
+ * Gets the queued early events and replay them using the appropriate handler
383
+ * in the provided event contract. Once all the events are replayed, it cleans
384
+ * up the early contract.
385
+ */
386
+ replayEarlyEvents() {
387
+ // Check if the early contract is present and prevent calling this function
388
+ // more than once.
389
+ const earlyJsactionData = window._ejsa;
390
+ if (!earlyJsactionData) {
391
+ return;
392
+ }
393
+ // Replay the early contract events.
394
+ const earlyEventInfos = earlyJsactionData.q;
395
+ for (let idx = 0; idx < earlyEventInfos.length; idx++) {
396
+ const earlyEventInfo = earlyEventInfos[idx];
397
+ const eventTypes = this.getEventTypesForBrowserEventType(earlyEventInfo.eventType);
398
+ for (let i = 0; i < eventTypes.length; i++) {
399
+ const eventInfo = eventInfoLib.cloneEventInfo(earlyEventInfo);
400
+ // EventInfo eventType maps to JSAction's internal event type,
401
+ // rather than the browser event type.
402
+ eventInfoLib.setEventType(eventInfo, eventTypes[i]);
403
+ this.handleEventInfo(eventInfo);
404
+ }
405
+ }
406
+ // Clean up the early contract.
407
+ const earlyEventTypes = earlyJsactionData.et;
408
+ const earlyEventHandler = earlyJsactionData.h;
409
+ for (let idx = 0; idx < earlyEventTypes.length; idx++) {
410
+ const eventType = earlyEventTypes[idx];
411
+ window.document.documentElement.removeEventListener(eventType, earlyEventHandler);
412
+ }
413
+ delete window._ejsa;
414
+ }
415
+ /**
416
+ * Returns all JSAction event types that have been registered for a given
417
+ * browser event type.
418
+ */
419
+ getEventTypesForBrowserEventType(browserEventType) {
420
+ const eventTypes = [];
421
+ if (this.eventHandlers[browserEventType]) {
422
+ eventTypes.push(browserEventType);
423
+ }
424
+ if (this.browserEventTypeToExtraEventTypes[browserEventType]) {
425
+ eventTypes.push(...this.browserEventTypeToExtraEventTypes[browserEventType]);
426
+ }
427
+ return eventTypes;
428
+ }
429
+ /**
430
+ * Returns the event handler function for a given event type.
431
+ */
432
+ handler(eventType) {
433
+ return this.eventHandlers[eventType];
434
+ }
435
+ /**
436
+ * Cleans up the event contract. This resets all of the `EventContract`'s
437
+ * internal state. Users are responsible for not using this `EventContract`
438
+ * after it has been cleaned up.
439
+ */
440
+ cleanUp() {
441
+ this.containerManager.cleanUp();
442
+ this.containerManager = null;
443
+ this.eventHandlers = {};
444
+ this.browserEventTypeToExtraEventTypes = {};
445
+ this.dispatcher = null;
446
+ this.queuedEventInfos = [];
447
+ }
448
+ /**
449
+ * Register a dispatcher function. Event info of each event mapped to
450
+ * a jsaction is passed for handling to this callback. The queued
451
+ * events are passed as well to the dispatcher for later replaying
452
+ * once the dispatcher is registered. Clears the event queue to null.
453
+ *
454
+ * @param dispatcher The dispatcher function.
455
+ * @param restriction
456
+ */
457
+ registerDispatcher(dispatcher, restriction) {
458
+ this.ecrd(dispatcher, restriction);
459
+ }
460
+ /**
461
+ * Unrenamed alias for registerDispatcher. Necessary for any codebases that
462
+ * split the `EventContract` and `Dispatcher` code into different compilation
463
+ * units.
464
+ */
465
+ ecrd(dispatcher, restriction) {
466
+ this.dispatcher = dispatcher;
467
+ if (this.queuedEventInfos?.length) {
468
+ for (let i = 0; i < this.queuedEventInfos.length; i++) {
469
+ this.handleEventInfo(this.queuedEventInfos[i]);
470
+ }
471
+ this.queuedEventInfos = null;
472
+ }
473
+ }
474
+ /**
475
+ * Adds a11y click support to the given `EventContract`. Meant to be called in
476
+ * the same compilation unit as the `EventContract`.
477
+ */
478
+ addA11yClickSupport() {
479
+ this.addA11yClickSupportImpl(a11yClickLib.updateEventInfoForA11yClick, a11yClickLib.preventDefaultForA11yClick, a11yClickLib.populateClickOnlyAction);
480
+ }
481
+ /**
482
+ * Enables a11y click support to be deferred. Meant to be called in the same
483
+ * compilation unit as the `EventContract`.
484
+ */
485
+ exportAddA11yClickSupport() {
486
+ this.addA11yClickListener = true;
487
+ this.ecaacs = this.addA11yClickSupportImpl.bind(this);
488
+ }
489
+ /**
490
+ * Unrenamed function that loads a11yClickSupport.
491
+ */
492
+ addA11yClickSupportImpl(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction) {
493
+ this.addA11yClickListener = true;
494
+ this.hasA11yClickSupport = true;
495
+ this.updateEventInfoForA11yClick = updateEventInfoForA11yClick;
496
+ this.preventDefaultForA11yClick = preventDefaultForA11yClick;
497
+ this.populateClickOnlyAction = populateClickOnlyAction;
498
+ }
499
+ }
500
+ /**
501
+ * Adds a11y click support to the given `EventContract`. Meant to be called
502
+ * in a different compilation unit from the `EventContract`. The `EventContract`
503
+ * must have called `exportAddA11yClickSupport` in its compilation unit for this
504
+ * to have any effect.
505
+ */
506
+ export function addDeferredA11yClickSupport(eventContract) {
507
+ eventContract.ecaacs?.(a11yClickLib.updateEventInfoForA11yClick, a11yClickLib.preventDefaultForA11yClick, a11yClickLib.populateClickOnlyAction);
508
+ }
509
+ /**
510
+ * Determines whether or not the `EventContract` needs to check with the
511
+ * dispatcher even if there's no action.
512
+ */
513
+ function checkDispatcherForA11yClick(eventInfo) {
514
+ return (EventContract.A11Y_SUPPORT_IN_DISPATCHER &&
515
+ eventInfoLib.getEventType(eventInfo) === AccessibilityAttribute.MAYBE_CLICK_EVENT_TYPE);
516
+ }
517
+ /**
518
+ * Returns true if the default action of this event should be prevented before
519
+ * this event is dispatched.
520
+ */
521
+ function shouldPreventDefaultBeforeDispatching(actionElement, eventInfo) {
522
+ // Prevent browser from following <a> node links if a jsaction is present
523
+ // and we are dispatching the action now. Note that the targetElement may be
524
+ // a child of an anchor that has a jsaction attached. For that reason, we
525
+ // need to check the actionElement rather than the targetElement.
526
+ return (actionElement.tagName === 'A' &&
527
+ (eventInfoLib.getEventType(eventInfo) === EventType.CLICK ||
528
+ eventInfoLib.getEventType(eventInfo) === EventType.CLICKMOD));
529
+ }
530
+ /**
531
+ * Parses and caches an element's jsaction element into a map.
532
+ *
533
+ * This is primarily for internal use.
534
+ *
535
+ * @param actionElement The DOM node to retrieve the jsaction map from.
536
+ * @param container The node which limits the namespace lookup for a jsaction
537
+ * name. The container node itself will not be searched.
538
+ * @return Map from event to qualified name of the jsaction bound to it.
539
+ */
540
+ export function parseActions(actionElement, container) {
541
+ let actionMap = cache.get(actionElement);
542
+ if (!actionMap) {
543
+ const jsactionAttribute = getAttr(actionElement, Attribute.JSACTION);
544
+ if (!jsactionAttribute) {
545
+ actionMap = EMPTY_ACTION_MAP;
546
+ cache.set(actionElement, actionMap);
547
+ }
548
+ else {
549
+ actionMap = cache.getParsed(jsactionAttribute);
550
+ if (!actionMap) {
551
+ actionMap = {};
552
+ const values = jsactionAttribute.split(REGEXP_SEMICOLON);
553
+ for (let idx = 0; idx < values.length; idx++) {
554
+ const value = values[idx];
555
+ if (!value) {
556
+ continue;
557
+ }
558
+ const colon = value.indexOf(Char.EVENT_ACTION_SEPARATOR);
559
+ const hasColon = colon !== -1;
560
+ const type = hasColon ? stringTrim(value.substr(0, colon)) : DEFAULT_EVENT_TYPE;
561
+ const action = hasColon ? stringTrim(value.substr(colon + 1)) : value;
562
+ actionMap[type] = action;
563
+ }
564
+ cache.setParsed(jsactionAttribute, actionMap);
565
+ }
566
+ // If namespace support is active we need to augment the (potentially
567
+ // cached) jsaction mapping with the namespace.
568
+ if (EventContract.JSNAMESPACE_SUPPORT) {
569
+ const noNs = actionMap;
570
+ actionMap = {};
571
+ for (const type in noNs) {
572
+ actionMap[type] = getFullyQualifiedAction(noNs[type], actionElement, container);
573
+ }
574
+ }
575
+ cache.set(actionElement, actionMap);
576
+ }
577
+ }
578
+ return actionMap;
579
+ }
580
+ /**
581
+ * Returns the fully qualified jsaction action. If the given jsaction
582
+ * name doesn't already contain the namespace, the function iterates
583
+ * over ancestor nodes until a jsnamespace attribute is found, and
584
+ * uses the value of that attribute as the namespace.
585
+ *
586
+ * @param action The jsaction action to resolve.
587
+ * @param start The node from which to start searching for a jsnamespace
588
+ * attribute.
589
+ * @param container The node which limits the search for a jsnamespace
590
+ * attribute. This node will be searched.
591
+ * @return The fully qualified name of the jsaction. If no namespace is found,
592
+ * returns the unqualified name in case it exists in the global namespace.
593
+ */
594
+ function getFullyQualifiedAction(action, start, container) {
595
+ if (EventContract.JSNAMESPACE_SUPPORT) {
596
+ if (isNamespacedAction(action)) {
597
+ return action;
598
+ }
599
+ let node = start;
600
+ while (node) {
601
+ const namespace = getNamespaceFromElement(node);
602
+ if (namespace) {
603
+ return namespace + Char.NAMESPACE_ACTION_SEPARATOR + action;
604
+ }
605
+ // If this node is the container, stop.
606
+ if (node === container) {
607
+ break;
608
+ }
609
+ node = node.parentNode;
610
+ }
611
+ }
612
+ return action;
613
+ }
614
+ /**
615
+ * Checks if a jsaction action contains a namespace part.
616
+ */
617
+ function isNamespacedAction(action) {
618
+ return action.indexOf(Char.NAMESPACE_ACTION_SEPARATOR) >= 0;
619
+ }
620
+ /**
621
+ * Returns the value of the jsnamespace attribute of the given node.
622
+ * Also caches the value for subsequent lookups.
623
+ * @param element The node whose jsnamespace attribute is being asked for.
624
+ * @return The value of the jsnamespace attribute, or null if not found.
625
+ */
626
+ function getNamespaceFromElement(element) {
627
+ let namespace = cache.getNamespace(element);
628
+ // Only query for the attribute if it has not been queried for
629
+ // before. getAttr() returns null if an attribute is not present. Thus,
630
+ // namespace is string|null if the query took place in the past, or
631
+ // undefined if the query did not take place.
632
+ if (namespace === undefined) {
633
+ namespace = getAttr(element, Attribute.JSNAMESPACE);
634
+ cache.setNamespace(element, namespace);
635
+ }
636
+ return namespace;
637
+ }
638
+ /**
639
+ * Accesses the event handler attribute value of a DOM node. It guards
640
+ * against weird situations (described in the body) that occur in
641
+ * connection with nodes that are removed from their document.
642
+ * @param element The DOM element.
643
+ * @param attribute The name of the attribute to access.
644
+ * @return The attribute value if it was found, null otherwise.
645
+ */
646
+ function getAttr(element, attribute) {
647
+ let value = null;
648
+ // NOTE: Nodes in IE do not always have a getAttribute
649
+ // method defined. This is the case where sourceElement has in
650
+ // fact been removed from the DOM before eventContract begins
651
+ // handling - where a parentNode does not have getAttribute
652
+ // defined.
653
+ // NOTE: We must use the 'in' operator instead of the regular dot
654
+ // notation, since the latter fails in IE8 if the getAttribute method is not
655
+ // defined. See b/7139109.
656
+ if ('getAttribute' in element) {
657
+ value = element.getAttribute(attribute);
658
+ }
659
+ return value;
660
+ }
661
+ /**
662
+ * Helper function to trim whitespace from the beginning and the end
663
+ * of the string. This deliberately doesn't use the closure equivalent
664
+ * to keep dependencies small.
665
+ * @param str Input string.
666
+ * @return Trimmed string.
667
+ */
668
+ function stringTrim(str) {
669
+ if (typeof String.prototype.trim === 'function') {
670
+ return str.trim();
671
+ }
672
+ const trimmedLeft = str.replace(/^\s+/, '');
673
+ return trimmedLeft.replace(/\s+$/, '');
674
+ }
675
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRjb250cmFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvcHJpbWl0aXZlcy9ldmVudC1kaXNwYXRjaC9zcmMvZXZlbnRjb250cmFjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sS0FBSyxZQUFZLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxTQUFTLElBQUksc0JBQXNCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRSxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxLQUFLLFFBQVEsTUFBTSxTQUFTLENBQUM7QUFFcEMsT0FBTyxFQUNMLGtCQUFrQixFQUNsQiwwQkFBMEIsRUFDMUIsb0JBQW9CLEVBQ3BCLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsZ0JBQWdCLEdBQ2pCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxLQUFLLFlBQVksTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBa0NwQyxNQUFNLGtCQUFrQixHQUFXLFNBQVMsQ0FBQyxLQUFLLENBQUM7QUFFbkQ7OztHQUdHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBNEIsRUFBRSxDQUFDO0FBRXJEOztHQUVHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7QUFFbkM7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sT0FBTyxhQUFhO2FBQ2pCLHlCQUFvQixHQUFHLG9CQUFvQixBQUF2QixDQUF3QjthQUM1QyxxQkFBZ0IsR0FBRyxnQkFBZ0IsQUFBbkIsQ0FBb0I7YUFDcEMsK0JBQTBCLEdBQUcsMEJBQTBCLEFBQTdCLENBQThCO2FBQ3hELHVCQUFrQixHQUFHLGtCQUFrQixBQUFyQixDQUFzQjthQUN4QywwQkFBcUIsR0FBRyxxQkFBcUIsQUFBeEIsQ0FBeUI7YUFDOUMsd0JBQW1CLEdBQUcsbUJBQW1CLEFBQXRCLENBQXVCO0lBbURqRCxZQUFZLGdCQUErQztRQS9DM0Q7Ozs7OztXQU1HO1FBQ0ssa0JBQWEsR0FBa0MsRUFBRSxDQUFDO1FBRWxELHNDQUFpQyxHQUE4QixFQUFFLENBQUM7UUFFMUU7Ozs7OztXQU1HO1FBQ0ssZUFBVSxHQUFzQixJQUFJLENBQUM7UUFFN0M7OztXQUdHO1FBQ0sscUJBQWdCLEdBQW9DLEVBQUUsQ0FBQztRQUUvRCx5REFBeUQ7UUFDakQsd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ3BDLDZDQUE2QztRQUNyQyx5QkFBb0IsR0FBRyxhQUFhLENBQUMsMEJBQTBCLENBQUM7UUFFaEUsZ0NBQTJCLEdBQWlELFNBQVMsQ0FBQztRQUV0RiwrQkFBMEIsR0FBaUQsU0FBUyxDQUFDO1FBRXJGLDRCQUF1QixHQUluQixTQUFTLENBQUM7UUFTcEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1FBQ3pDLElBQUksYUFBYSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMsQ0FBQztRQUNELElBQUksYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDckMsaURBQWlEO1lBQ2pELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDO0lBRU8sV0FBVyxDQUFDLFNBQWlCLEVBQUUsS0FBWSxFQUFFLFNBQWtCO1FBQ3JFLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyw2QkFBNkI7UUFDMUQsZ0JBQWdCLENBQUMsU0FBUztRQUMxQixZQUFZLENBQUMsS0FBSztRQUNsQixvQkFBb0IsQ0FBQyxLQUFLLENBQUMsTUFBaUI7UUFDNUMsZ0JBQWdCLENBQUMsU0FBUztRQUMxQixnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQzVCLENBQUM7UUFDRixJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZUFBZSxDQUFDLFNBQWlDLEVBQUUsZUFBZSxHQUFHLElBQUk7UUFDL0UsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNyQiw4REFBOEQ7WUFDOUQsWUFBWSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFDRSxhQUFhLENBQUMsb0JBQW9CO1lBQ2xDLFlBQVksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssU0FBUyxDQUFDLE1BQU0sRUFDekQsQ0FBQztZQUNELE1BQU0sTUFBTSxHQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFpQixDQUFDLE1BQU0sQ0FBQztZQUN4RSxvRUFBb0U7WUFDcEUsNEJBQTRCO1lBQzVCLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsNEJBQTRCO2dCQUM1QixPQUFPO1lBQ1QsQ0FBQztZQUNELFlBQVksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRS9CLElBQ0UsSUFBSSxDQUFDLFVBQVU7WUFDZixDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsc0JBQXNCLENBQUMsb0JBQW9CLENBQUMsRUFDOUUsQ0FBQztZQUNELE1BQU0sZUFBZSxHQUEyQixZQUFZLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXZGLGlFQUFpRTtZQUNqRSwwRUFBMEU7WUFDMUUsK0RBQStEO1lBQy9ELElBQUksWUFBWSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsS0FBSyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3ZFLFlBQVksQ0FBQyxZQUFZLENBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5RCxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsMkJBQTJCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLDJCQUEyQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdkQsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNwQixJQUNFLE1BQU07Z0JBQ04scUNBQXFDLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUN2RixDQUFDO2dCQUNELFFBQVEsQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQzVELENBQUM7WUFFRCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdkQsSUFBSSxtQkFBbUIsSUFBSSxlQUFlLEVBQUUsQ0FBQztnQkFDM0Msa0VBQWtFO2dCQUNsRSxnRUFBZ0U7Z0JBQ2hFLGdEQUFnRDtnQkFDaEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxtQkFBbUIsRUFBRSxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDeEUsT0FBTztZQUNULENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ssY0FBYyxDQUFDLFNBQWlDO1FBQ3RELG1FQUFtRTtRQUNuRSxtRUFBbUU7UUFDbkUsZ0VBQWdFO1FBQ2hFLCtEQUErRDtRQUMvRCxtRUFBbUU7UUFDbkUsaURBQWlEO1FBQ2pELEVBQUU7UUFDRixvRUFBb0U7UUFDcEUsbUVBQW1FO1FBQ25FLEVBQUU7UUFDRix5Q0FBeUM7UUFDekMsK0NBQStDO1FBQy9DLEVBQUU7UUFDRiw0REFBNEQ7UUFDNUQsNERBQTREO1FBQzVELDJEQUEyRDtRQUMzRCxXQUFXO1FBQ1gsRUFBRTtRQUNGLG1FQUFtRTtRQUNuRSwrQkFBK0I7UUFDL0IsRUFBRTtRQUNGLGtEQUFrRDtRQUNsRCxFQUFFO1FBQ0YsMkRBQTJEO1FBQzNELHFEQUFxRDtRQUNyRCxFQUFFO1FBQ0YscUVBQXFFO1FBQ3JFLHlEQUF5RDtRQUN6RCxFQUFFO1FBQ0YseURBQXlEO1FBQ3pELDRFQUE0RTtRQUM1RSw0RUFBNEU7UUFDNUUsK0JBQStCO1FBQy9CLElBQ0UsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsS0FBSztZQUN4RCxRQUFRLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUMvRCxDQUFDO1lBQ0QsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNELENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQywyQkFBNEIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQyxDQUFDO2FBQU0sSUFDTCxhQUFhLENBQUMsMEJBQTBCO1lBQ3hDLFlBQVksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssU0FBUyxDQUFDLE9BQU87WUFDMUQsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQyxFQUN6RSxDQUFDO1lBQ0Qsc0VBQXNFO1lBQ3RFLHVCQUF1QjtZQUN2QixZQUFZLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3RGLENBQUM7UUFFRCxvRUFBb0U7UUFDcEUsZ0VBQWdFO1FBQ2hFLHlCQUF5QjtRQUN6QixJQUFJLGFBQWEsR0FBbUIsWUFBWSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdFLE9BQU8sYUFBYSxJQUFJLGFBQWEsS0FBSyxZQUFZLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDL0UsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUV2RCxJQUFJLFlBQVksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsbUVBQW1FO2dCQUNuRSxtRUFBbUU7Z0JBQ25FLDJDQUEyQztnQkFDM0MsTUFBTTtZQUNSLENBQUM7WUFDRCxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFZLENBQUM7Z0JBQ3pELFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxhQUFhLENBQUMsVUFBVSxFQUFFLFFBQVEsS0FBSyxvQkFBb0IsRUFBRSxDQUFDO2dCQUNoRSxhQUFhLEdBQUcsYUFBYSxDQUFDLFVBQTRCLENBQUM7WUFDN0QsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGFBQWEsR0FBSSxhQUFhLENBQUMsVUFBZ0MsRUFBRSxJQUFJLElBQUksSUFBSSxDQUFDO1lBQ2hGLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixtQkFBbUI7WUFDbkIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQywwQkFBMkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSwrQkFBK0I7UUFDL0IsSUFDRSxhQUFhLENBQUMscUJBQXFCO1lBQ25DLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsVUFBVTtnQkFDNUQsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsVUFBVTtnQkFDN0QsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsWUFBWTtnQkFDL0QsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQ2xFLENBQUM7WUFDRCxnRUFBZ0U7WUFDaEUsZ0VBQWdFO1lBQ2hFLCtCQUErQjtZQUMvQixJQUNFLFFBQVEsQ0FBQyxtQkFBbUIsQ0FDMUIsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFDaEMsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFDcEMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUN0QyxFQUNELENBQUM7Z0JBQ0Qsa0VBQWtFO2dCQUNsRSw0REFBNEQ7Z0JBQzVELDZEQUE2RDtnQkFDN0QsbUVBQW1FO2dCQUNuRSxnQ0FBZ0M7Z0JBQ2hDLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyx1QkFBdUIsQ0FDbEQsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFDaEMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUN0QyxDQUFDO2dCQUNGLFlBQVksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUM5QyxtRUFBbUU7Z0JBQ25FLHFFQUFxRTtnQkFDckUsd0JBQXdCO2dCQUN4QixZQUFZLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLENBQUM7aUJBQU0sQ0FBQztnQkFDTixZQUFZLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSyx1QkFBdUIsQ0FBQyxhQUFzQixFQUFFLFNBQWlDO1FBQ3ZGLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBRXBGLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsSUFBSSxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDN0IsWUFBWSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyx1QkFBd0IsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7UUFDRCxJQUFJLGFBQWEsQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQzdDLElBQ0UsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxzQkFBc0IsQ0FBQyxzQkFBc0I7Z0JBQ3RGLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssU0FBUyxFQUN4QyxDQUFDO2dCQUNELG9FQUFvRTtnQkFDcEUsaUVBQWlFO2dCQUNqRSxvRUFBb0U7Z0JBQ3BFLGlCQUFpQjtnQkFDakIsaUVBQWlFO2dCQUNqRSxpRUFBaUU7Z0JBQ2pFLHdFQUF3RTtnQkFDeEUsb0VBQW9FO2dCQUNwRSwwQkFBMEI7Z0JBQzFCLFlBQVksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDL0UsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFlBQVksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzVFLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILFFBQVEsQ0FBQyxTQUFpQixFQUFFLGlCQUEwQjtRQUNwRCxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDOUQsT0FBTztRQUNULENBQUM7UUFFRCxJQUNFLENBQUMsYUFBYSxDQUFDLHFCQUFxQjtZQUNwQyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsVUFBVTtnQkFDakMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxVQUFVO2dCQUNsQyxTQUFTLEtBQUssU0FBUyxDQUFDLFlBQVk7Z0JBQ3BDLFNBQVMsS0FBSyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQ3ZDLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLENBQUMsU0FBaUIsRUFBRSxLQUFZLEVBQUUsU0FBa0IsRUFBRSxFQUFFO1lBQzNFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUM7UUFFRixtREFBbUQ7UUFDbkQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxZQUFZLENBQUM7UUFFN0MsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLElBQUksU0FBUyxDQUFDLENBQUM7UUFFdEYsSUFBSSxnQkFBZ0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsaUNBQWlDLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEYsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsaUNBQWlDLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxVQUFVLENBQUM7UUFDeEUsQ0FBQztRQUVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQWdCLEVBQUUsRUFBRTtZQUM1RSxPQUFPLENBQUMsS0FBWSxFQUFFLEVBQUU7Z0JBQ3RCLFlBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsd0VBQXdFO1FBQ3hFLGtDQUFrQztRQUNsQyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxTQUFTLEtBQUssU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQy9ELElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGlCQUFpQjtRQUNmLDJFQUEyRTtRQUMzRSxrQkFBa0I7UUFDbEIsTUFBTSxpQkFBaUIsR0FBa0MsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUN0RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN2QixPQUFPO1FBQ1QsQ0FBQztRQUVELG9DQUFvQztRQUNwQyxNQUFNLGVBQWUsR0FBNkIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDdEQsTUFBTSxjQUFjLEdBQTJCLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ25GLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQzNDLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQzlELDhEQUE4RDtnQkFDOUQsc0NBQXNDO2dCQUN0QyxZQUFZLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNsQyxDQUFDO1FBQ0gsQ0FBQztRQUVELCtCQUErQjtRQUMvQixNQUFNLGVBQWUsR0FBYSxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7UUFDdkQsTUFBTSxpQkFBaUIsR0FBMkIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDdEQsTUFBTSxTQUFTLEdBQVcsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9DLE1BQU0sQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3BGLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGdDQUFnQyxDQUFDLGdCQUF3QjtRQUMvRCxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUN6QyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUM3RCxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztRQUMvRSxDQUFDO1FBQ0QsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsT0FBTyxDQUFDLFNBQWlCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE9BQU87UUFDTCxJQUFJLENBQUMsZ0JBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsaUNBQWlDLEdBQUcsRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsa0JBQWtCLENBQUMsVUFBc0IsRUFBRSxXQUF3QjtRQUNqRSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQUksQ0FBQyxVQUFzQixFQUFFLFdBQXdCO1FBQ25ELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBRTdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQ2xDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsQ0FBQztZQUNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxtQkFBbUI7UUFDakIsSUFBSSxDQUFDLHVCQUF1QixDQUMxQixZQUFZLENBQUMsMkJBQTJCLEVBQ3hDLFlBQVksQ0FBQywwQkFBMEIsRUFDdkMsWUFBWSxDQUFDLHVCQUF1QixDQUNyQyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILHlCQUF5QjtRQUN2QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQ7O09BRUc7SUFDSyx1QkFBdUIsQ0FDN0IsMkJBQTRFLEVBQzVFLDBCQUEwRSxFQUMxRSx1QkFBb0U7UUFFcEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUNqQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2hDLElBQUksQ0FBQywyQkFBMkIsR0FBRywyQkFBMkIsQ0FBQztRQUMvRCxJQUFJLENBQUMsMEJBQTBCLEdBQUcsMEJBQTBCLENBQUM7UUFDN0QsSUFBSSxDQUFDLHVCQUF1QixHQUFHLHVCQUF1QixDQUFDO0lBQ3pELENBQUM7O0FBR0g7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsMkJBQTJCLENBQUMsYUFBNEI7SUFDdEUsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUNwQixZQUFZLENBQUMsMkJBQTJCLEVBQ3hDLFlBQVksQ0FBQywwQkFBMEIsRUFDdkMsWUFBWSxDQUFDLHVCQUF1QixDQUNyQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsMkJBQTJCLENBQUMsU0FBaUM7SUFDcEUsT0FBTyxDQUNMLGFBQWEsQ0FBQywwQkFBMEI7UUFDeEMsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxzQkFBc0IsQ0FBQyxzQkFBc0IsQ0FDdkYsQ0FBQztBQUNKLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLHFDQUFxQyxDQUM1QyxhQUFzQixFQUN0QixTQUFpQztJQUVqQyx5RUFBeUU7SUFDekUsNEVBQTRFO0lBQzVFLHlFQUF5RTtJQUN6RSxpRUFBaUU7SUFDakUsT0FBTyxDQUNMLGFBQWEsQ0FBQyxPQUFPLEtBQUssR0FBRztRQUM3QixDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssU0FBUyxDQUFDLEtBQUs7WUFDdkQsWUFBWSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQy9ELENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxhQUFzQixFQUFFLFNBQWU7SUFDbEUsSUFBSSxTQUFTLEdBQXdDLEtBQUssQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDOUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2YsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN2QixTQUFTLEdBQUcsZ0JBQWdCLENBQUM7WUFDN0IsS0FBSyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdEMsQ0FBQzthQUFNLENBQUM7WUFDTixTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDZixTQUFTLEdBQUcsRUFBRSxDQUFDO2dCQUNmLE1BQU0sTUFBTSxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN6RCxLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO29CQUM3QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzFCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDWCxTQUFTO29CQUNYLENBQUM7b0JBQ0QsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztvQkFDekQsTUFBTSxRQUFRLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUM5QixNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztvQkFDaEYsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO29CQUN0RSxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMzQixDQUFDO2dCQUNELEtBQUssQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUNELHFFQUFxRTtZQUNyRSwrQ0FBK0M7WUFDL0MsSUFBSSxhQUFhLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDO2dCQUN2QixTQUFTLEdBQUcsRUFBRSxDQUFDO2dCQUNmLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ3hCLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNsRixDQUFDO1lBQ0gsQ0FBQztZQUNELEtBQUssQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFTLHVCQUF1QixDQUFDLE1BQWMsRUFBRSxLQUFjLEVBQUUsU0FBZTtJQUM5RSxJQUFJLGFBQWEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3RDLElBQUksa0JBQWtCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQsSUFBSSxJQUFJLEdBQWdCLEtBQUssQ0FBQztRQUM5QixPQUFPLElBQUksRUFBRSxDQUFDO1lBQ1osTUFBTSxTQUFTLEdBQUcsdUJBQXVCLENBQUMsSUFBZSxDQUFDLENBQUM7WUFDM0QsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDZCxPQUFPLFNBQVMsR0FBRyxJQUFJLENBQUMsMEJBQTBCLEdBQUcsTUFBTSxDQUFDO1lBQzlELENBQUM7WUFFRCx1Q0FBdUM7WUFDdkMsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZCLE1BQU07WUFDUixDQUFDO1lBRUQsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDekIsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGtCQUFrQixDQUFDLE1BQWM7SUFDeEMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLHVCQUF1QixDQUFDLE9BQWdCO0lBQy9DLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsOERBQThEO0lBQzlELHVFQUF1RTtJQUN2RSxtRUFBbUU7SUFDbkUsNkNBQTZDO0lBQzdDLElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzVCLFNBQVMsR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNwRCxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLE9BQU8sQ0FBQyxPQUFnQixFQUFFLFNBQWlCO0lBQ2xELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztJQUNqQixzREFBc0Q7SUFDdEQsOERBQThEO0lBQzlELDZEQUE2RDtJQUM3RCwyREFBMkQ7SUFDM0QsV0FBVztJQUNYLGlFQUFpRTtJQUNqRSw0RUFBNEU7SUFDNUUsMEJBQTBCO0lBQzFCLElBQUksY0FBYyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzlCLEtBQUssR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxHQUFXO0lBQzdCLElBQUksT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUNoRCxPQUFPLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDNUMsT0FBTyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN6QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBJbXBsZW1lbnRzIHRoZSBsb2NhbCBldmVudCBoYW5kbGluZyBjb250cmFjdC4gVGhpc1xuICogYWxsb3dzIERPTSBvYmplY3RzIGluIGEgY29udGFpbmVyIHRoYXQgZW50ZXJzIGludG8gdGhpcyBjb250cmFjdCB0b1xuICogZGVmaW5lIGV2ZW50IGhhbmRsZXJzIHdoaWNoIGFyZSBleGVjdXRlZCBpbiBhIGxvY2FsIGNvbnRleHQuXG4gKlxuICogT25lIEV2ZW50Q29udHJhY3QgaW5zdGFuY2UgY2FuIG1hbmFnZSB0aGUgY29udHJhY3QgZm9yIG11bHRpcGxlXG4gKiBjb250YWluZXJzLCB3aGljaCBhcmUgYWRkZWQgdXNpbmcgdGhlIGFkZENvbnRhaW5lcigpIG1ldGhvZC5cbiAqXG4gKiBFdmVudHMgY2FuIGJlIHJlZ2lzdGVyZWQgdXNpbmcgdGhlIGFkZEV2ZW50KCkgbWV0aG9kLlxuICpcbiAqIEEgRGlzcGF0Y2hlciBpcyBhZGRlZCB1c2luZyB0aGUgcmVnaXN0ZXJEaXNwYXRjaGVyKCkgbWV0aG9kLiBVbnRpbCB0aGVyZSBpc1xuICogYSBkaXNwYXRjaGVyLCBldmVudHMgYXJlIHF1ZXVlZC4gVGhlIGlkZWEgaXMgdGhhdCB0aGUgRXZlbnRDb250cmFjdFxuICogY2xhc3MgaXMgaW5saW5lZCBpbiB0aGUgSFRNTCBvZiB0aGUgdG9wIGxldmVsIHBhZ2UgYW5kIGluc3RhbnRpYXRlZFxuICogcmlnaHQgYWZ0ZXIgdGhlIHN0YXJ0IG9mIDxib2R5Pi4gVGhlIERpc3BhdGNoZXIgY2xhc3MgaXMgY29udGFpbmVkXG4gKiBpbiB0aGUgZXh0ZXJuYWwgZGVmZXJyZWQganMsIGFuZCBpbnN0YW50aWF0ZWQgYW5kIHJlZ2lzdGVyZWQgd2l0aFxuICogRXZlbnRDb250cmFjdCB3aGVuIHRoZSBleHRlcm5hbCBqYXZhc2NyaXB0IGluIHRoZSBwYWdlIGxvYWRzLiBUaGVcbiAqIGV4dGVybmFsIGphdmFzY3JpcHQgd2lsbCBhbHNvIHJlZ2lzdGVyIHRoZSBqc2FjdGlvbiBoYW5kbGVycywgd2hpY2hcbiAqIHRoZW4gcGljayB1cCB0aGUgcXVldWVkIGV2ZW50cyBhdCB0aGUgdGltZSBvZiByZWdpc3RyYXRpb24uXG4gKlxuICogU2luY2UgdGhpcyBjbGFzcyBpcyBtZWFudCB0byBiZSBpbmxpbmVkIGluIHRoZSBtYWluIHBhZ2UgSFRNTCwgdGhlXG4gKiBzaXplIG9mIHRoZSBiaW5hcnkgY29tcGlsZWQgZnJvbSB0aGlzIGZpbGUgTVVTVCBiZSBrZXB0IGFzIHNtYWxsIGFzXG4gKiBwb3NzaWJsZSBhbmQgdGh1cyBpdHMgZGVwZW5kZW5jaWVzIHRvIGEgbWluaW11bS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBhMTF5Q2xpY2tMaWIgZnJvbSAnLi9hMTF5X2NsaWNrJztcbmltcG9ydCB7QXR0cmlidXRlIGFzIEFjY2Vzc2liaWxpdHlBdHRyaWJ1dGV9IGZyb20gJy4vYWNjZXNzaWJpbGl0eSc7XG5pbXBvcnQge0F0dHJpYnV0ZX0gZnJvbSAnLi9hdHRyaWJ1dGUnO1xuaW1wb3J0ICogYXMgY2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQge0NoYXJ9IGZyb20gJy4vY2hhcic7XG5pbXBvcnQge0Vhcmx5SnNhY3Rpb25EYXRhfSBmcm9tICcuL2Vhcmx5ZXZlbnRjb250cmFjdCc7XG5pbXBvcnQgKiBhcyBldmVudExpYiBmcm9tICcuL2V2ZW50JztcbmltcG9ydCB7RXZlbnRDb250cmFjdENvbnRhaW5lck1hbmFnZXJ9IGZyb20gJy4vZXZlbnRfY29udHJhY3RfY29udGFpbmVyJztcbmltcG9ydCB7XG4gIEExMVlfQ0xJQ0tfU1VQUE9SVCxcbiAgQTExWV9TVVBQT1JUX0lOX0RJU1BBVENIRVIsXG4gIENVU1RPTV9FVkVOVF9TVVBQT1JULFxuICBKU05BTUVTUEFDRV9TVVBQT1JULFxuICBNT1VTRV9TUEVDSUFMX1NVUFBPUlQsXG4gIFNUT1BfUFJPUEFHQVRJT04sXG59IGZyb20gJy4vZXZlbnRfY29udHJhY3RfZGVmaW5lcyc7XG5pbXBvcnQgKiBhcyBldmVudEluZm9MaWIgZnJvbSAnLi9ldmVudF9pbmZvJztcbmltcG9ydCB7RXZlbnRUeXBlfSBmcm9tICcuL2V2ZW50X3R5cGUnO1xuaW1wb3J0IHtQcm9wZXJ0eX0gZnJvbSAnLi9wcm9wZXJ0eSc7XG5pbXBvcnQge1Jlc3RyaWN0aW9ufSBmcm9tICcuL3Jlc3RyaWN0aW9uJztcblxuLyoqXG4gKiBUaGUgQVBJIG9mIGFuIEV2ZW50Q29udHJhY3QgdGhhdCBpcyBzYWZlIHRvIGNhbGwgZnJvbSBhbnkgY29tcGlsYXRpb24gdW5pdC5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIFVucmVuYW1lZEV2ZW50Q29udHJhY3Qge1xuICAvLyBBbGlhcyBmb3IgSnNjdGlvbiBFdmVudENvbnRyYWN0IHJlZ2lzdGVyRGlzcGF0Y2hlci5cbiAgZWNyZChkaXNwYXRjaGVyOiBEaXNwYXRjaGVyLCByZXN0cmljdGlvbjogUmVzdHJpY3Rpb24pOiB2b2lkO1xuICAvLyBVbnJlbmFtZWQgZnVuY3Rpb24uIEFiYnJldmlhdGlvbiBmb3IgYGV2ZW50Q29udHJhY3QuYWRkQTExeUNsaWNrU3VwcG9ydGAuXG4gIGVjYWFjcz86IChcbiAgICB1cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2s6IHR5cGVvZiBhMTF5Q2xpY2tMaWIudXBkYXRlRXZlbnRJbmZvRm9yQTExeUNsaWNrLFxuICAgIHByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrOiB0eXBlb2YgYTExeUNsaWNrTGliLnByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrLFxuICAgIHBvcHVsYXRlQ2xpY2tPbmx5QWN0aW9uOiB0eXBlb2YgYTExeUNsaWNrTGliLnBvcHVsYXRlQ2xpY2tPbmx5QWN0aW9uLFxuICApID0+IHZvaWQ7XG59XG5cbi8qKiBBIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHRvIGhhbmRsZSBldmVudHMgY2FwdHVyZWQgYnkgdGhlIEV2ZW50Q29udHJhY3QuICovXG5leHBvcnQgdHlwZSBEaXNwYXRjaGVyID0gKFxuICBldmVudEluZm86IGV2ZW50SW5mb0xpYi5FdmVudEluZm8sXG4gIGdsb2JhbERpc3BhdGNoPzogYm9vbGVhbixcbikgPT4gZXZlbnRJbmZvTGliLkV2ZW50SW5mbyB8IHZvaWQ7XG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgYW4gZXZlbnQgZGlzcGF0Y2hlZCBmcm9tIHRoZSBicm93c2VyLlxuICpcbiAqIGV2ZW50VHlwZTogTWF5IGRpZmZlciBmcm9tIGBldmVudC50eXBlYCBpZiBKU0FjdGlvbiB1c2VzIGFcbiAqIHNob3J0LWhhbmQgbmFtZSBvciBpcyBwYXRjaGluZyBvdmVyIGFuIG5vbi1idWJibGluZyBldmVudCB3aXRoIGEgYnViYmxpbmdcbiAqIHZhcmlhbnQuXG4gKiBldmVudDogVGhlIG5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogY29udGFpbmVyOiBUaGUgY29udGFpbmVyIGZvciB0aGlzIGRpc3BhdGNoLlxuICovXG50eXBlIEV2ZW50SGFuZGxlciA9IChldmVudFR5cGU6IHN0cmluZywgZXZlbnQ6IEV2ZW50LCBjb250YWluZXI6IEVsZW1lbnQpID0+IHZvaWQ7XG5cbmNvbnN0IERFRkFVTFRfRVZFTlRfVFlQRTogc3RyaW5nID0gRXZlbnRUeXBlLkNMSUNLO1xuXG4vKipcbiAqIFNpbmNlIG1hcHMgZnJvbSBldmVudCB0byBhY3Rpb24gYXJlIGltbXV0YWJsZSB3ZSBjYW4gdXNlIGEgc2luZ2xlIG1hcFxuICogdG8gcmVwcmVzZW50IHRoZSBlbXB0eSBtYXAuXG4gKi9cbmNvbnN0IEVNUFRZX0FDVElPTl9NQVA6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG5cbi8qKlxuICogVGhpcyByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hlcyBhIHNlbWljb2xvbi5cbiAqL1xuY29uc3QgUkVHRVhQX1NFTUlDT0xPTiA9IC9cXHMqO1xccyovO1xuXG4vKipcbiAqIEV2ZW50Q29udHJhY3QgaW50ZXJjZXB0cyBldmVudHMgaW4gdGhlIGJ1YmJsaW5nIHBoYXNlIGF0IHRoZVxuICogYm91bmRhcnkgb2YgYSBjb250YWluZXIgZWxlbWVudCwgYW5kIG1hcHMgdGhlbSB0byBnZW5lcmljIGFjdGlvbnNcbiAqIHdoaWNoIGFyZSBzcGVjaWZpZWQgdXNpbmcgdGhlIGN1c3RvbSBqc2FjdGlvbiBhdHRyaWJ1dGUgaW5cbiAqIEhUTUwuIEJlaGF2aW9yIG9mIHRoZSBhcHBsaWNhdGlvbiBpcyB0aGVuIHNwZWNpZmllZCBpbiB0ZXJtcyBvZlxuICogaGFuZGxlciBmb3Igc3VjaCBhY3Rpb25zLCBjZi4ganNhY3Rpb24uRGlzcGF0Y2hlciBpbiBkaXNwYXRjaGVyLmpzLlxuICpcbiAqIFRoaXMgaGFzIHNldmVyYWwgYmVuZWZpdHM6ICgxKSBObyBET00gZXZlbnQgaGFuZGxlcnMgbmVlZCB0byBiZVxuICogcmVnaXN0ZXJlZCBvbiB0aGUgc3BlY2lmaWMgZWxlbWVudHMgaW4gdGhlIFVJLiAoMikgVGhlIHNldCBvZlxuICogZXZlbnRzIHRoYXQgdGhlIGFwcGxpY2F0aW9uIGhhcyB0byBoYW5kbGUgY2FuIGJlIHNwZWNpZmllZCBpbiB0ZXJtc1xuICogb2YgdGhlIHNlbWFudGljcyBvZiB0aGUgYXBwbGljYXRpb24sIHJhdGhlciB0aGFuIGluIHRlcm1zIG9mIERPTVxuICogZXZlbnRzLiAoMykgSW52b2NhdGlvbiBvZiBoYW5kbGVycyBjYW4gYmUgZGVsYXllZCBhbmQgaGFuZGxlcnMgY2FuXG4gKiBiZSBkZWxheSBsb2FkZWQgaW4gYSBnZW5lcmljIHdheS5cbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50Q29udHJhY3QgaW1wbGVtZW50cyBVbnJlbmFtZWRFdmVudENvbnRyYWN0IHtcbiAgc3RhdGljIENVU1RPTV9FVkVOVF9TVVBQT1JUID0gQ1VTVE9NX0VWRU5UX1NVUFBPUlQ7XG4gIHN0YXRpYyBTVE9QX1BST1BBR0FUSU9OID0gU1RPUF9QUk9QQUdBVElPTjtcbiAgc3RhdGljIEExMVlfU1VQUE9SVF9JTl9ESVNQQVRDSEVSID0gQTExWV9TVVBQT1JUX0lOX0RJU1BBVENIRVI7XG4gIHN0YXRpYyBBMTFZX0NMSUNLX1NVUFBPUlQgPSBBMTFZX0NMSUNLX1NVUFBPUlQ7XG4gIHN0YXRpYyBNT1VTRV9TUEVDSUFMX1NVUFBPUlQgPSBNT1VTRV9TUEVDSUFMX1NVUFBPUlQ7XG4gIHN0YXRpYyBKU05BTUVTUEFDRV9TVVBQT1JUID0gSlNOQU1FU1BBQ0VfU1VQUE9SVDtcblxuICBwcml2YXRlIGNvbnRhaW5lck1hbmFnZXI6IEV2ZW50Q29udHJhY3RDb250YWluZXJNYW5hZ2VyIHwgbnVsbDtcblxuICAvKipcbiAgICogVGhlIERPTSBldmVudHMgd2hpY2ggdGhpcyBjb250cmFjdCBjb3ZlcnMuIFVzZWQgdG8gcHJldmVudCBkb3VibGVcbiAgICogcmVnaXN0cmF0aW9uIG9mIGV2ZW50IHR5cGVzLiBUaGUgdmFsdWUgb2YgdGhlIG1hcCBpcyB0aGVcbiAgICogaW50ZXJuYWxseSBjcmVhdGVkIERPTSBldmVudCBoYW5kbGVyIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyB0aGVcbiAgICogRE9NIGV2ZW50cy4gU2VlIGFkZEV2ZW50KCkuXG4gICAqXG4gICAqL1xuICBwcml2YXRlIGV2ZW50SGFuZGxlcnM6IHtba2V5OiBzdHJpbmddOiBFdmVudEhhbmRsZXJ9ID0ge307XG5cbiAgcHJpdmF0ZSBicm93c2VyRXZlbnRUeXBlVG9FeHRyYUV2ZW50VHlwZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmdbXX0gPSB7fTtcblxuICAvKipcbiAgICogVGhlIGRpc3BhdGNoZXIgZnVuY3Rpb24uIEV2ZW50cyBhcmUgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gZm9yXG4gICAqIGhhbmRsaW5nIG9uY2UgaXQgd2FzIHNldCB1c2luZyB0aGUgcmVnaXN0ZXJEaXNwYXRjaGVyKCkgbWV0aG9kLiBUaGlzIGlzXG4gICAqIGRvbmUgYmVjYXVzZSB0aGUgZnVuY3Rpb24gaXMgcGFzc2VkIGZyb20gYW5vdGhlciBqc2JpbmFyeSwgc28gcGFzc2luZyB0aGVcbiAgICogaW5zdGFuY2UgYW5kIGludm9raW5nIHRoZSBtZXRob2QgaGVyZSB3b3VsZCByZXF1aXJlIHRvIGxlYXZlIHRoZSBtZXRob2RcbiAgICogdW5vYmZ1c2NhdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwYXRjaGVyOiBEaXNwYXRjaGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIHN1c3BlbmRlZCBgRXZlbnRJbmZvYCB0aGF0IHdpbGwgYmUgZGlzcGF0Y2hlZFxuICAgKiBhcyBzb29uIGFzIHRoZSBgRGlzcGF0Y2hlcmAgaXMgcmVnaXN0ZXJlZC5cbiAgICovXG4gIHByaXZhdGUgcXVldWVkRXZlbnRJbmZvczogZXZlbnRJbmZvTGliLkV2ZW50SW5mb1tdIHwgbnVsbCA9IFtdO1xuXG4gIC8qKiBXaGV0aGVyIGExMXkgY2xpY2sgc3VwcG9ydCBoYXMgYmVlbiBsb2FkZWQgb3Igbm90LiAqL1xuICBwcml2YXRlIGhhc0ExMXlDbGlja1N1cHBvcnQgPSBmYWxzZTtcbiAgLyoqIFdoZXRoZXIgdG8gYWRkIGFuIGExMXkgY2xpY2sgbGlzdGVuZXIuICovXG4gIHByaXZhdGUgYWRkQTExeUNsaWNrTGlzdGVuZXIgPSBFdmVudENvbnRyYWN0LkExMVlfU1VQUE9SVF9JTl9ESVNQQVRDSEVSO1xuXG4gIHByaXZhdGUgdXBkYXRlRXZlbnRJbmZvRm9yQTExeUNsaWNrPzogKGV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbykgPT4gdm9pZCA9IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrPzogKGV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbykgPT4gdm9pZCA9IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHBvcHVsYXRlQ2xpY2tPbmx5QWN0aW9uPzogKFxuICAgIGFjdGlvbkVsZW1lbnQ6IEVsZW1lbnQsXG4gICAgZXZlbnRJbmZvOiBldmVudEluZm9MaWIuRXZlbnRJbmZvLFxuICAgIGFjdGlvbk1hcDoge1trZXk6IHN0cmluZ106IHN0cmluZ30sXG4gICkgPT4gdm9pZCA9IHVuZGVmaW5lZDtcblxuICBlY2FhY3M/OiAoXG4gICAgdXBkYXRlRXZlbnRJbmZvRm9yQTExeUNsaWNrOiB0eXBlb2YgYTExeUNsaWNrTGliLnVwZGF0ZUV2ZW50SW5mb0ZvckExMXlDbGljayxcbiAgICBwcmV2ZW50RGVmYXVsdEZvckExMXlDbGljazogdHlwZW9mIGExMXlDbGlja0xpYi5wcmV2ZW50RGVmYXVsdEZvckExMXlDbGljayxcbiAgICBwb3B1bGF0ZUNsaWNrT25seUFjdGlvbjogdHlwZW9mIGExMXlDbGlja0xpYi5wb3B1bGF0ZUNsaWNrT25seUFjdGlvbixcbiAgKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKGNvbnRhaW5lck1hbmFnZXI6IEV2ZW50Q29udHJhY3RDb250YWluZXJNYW5hZ2VyKSB7XG4gICAgdGhpcy5jb250YWluZXJNYW5hZ2VyID0gY29udGFpbmVyTWFuYWdlcjtcbiAgICBpZiAoRXZlbnRDb250cmFjdC5DVVNUT01fRVZFTlRfU1VQUE9SVCkge1xuICAgICAgdGhpcy5hZGRFdmVudChFdmVudFR5cGUuQ1VTVE9NKTtcbiAgICB9XG4gICAgaWYgKEV2ZW50Q29udHJhY3QuQTExWV9DTElDS19TVVBQT1JUKSB7XG4gICAgICAvLyBBZGQgYTExeSBjbGljayBzdXBwb3J0IHRvIHRoZSBgRXZlbnRDb250cmFjdGAuXG4gICAgICB0aGlzLmFkZEExMXlDbGlja1N1cHBvcnQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUV2ZW50KGV2ZW50VHlwZTogc3RyaW5nLCBldmVudDogRXZlbnQsIGNvbnRhaW5lcjogRWxlbWVudCkge1xuICAgIGNvbnN0IGV2ZW50SW5mbyA9IGV2ZW50SW5mb0xpYi5jcmVhdGVFdmVudEluZm9Gcm9tUGFyYW1ldGVycyhcbiAgICAgIC8qIGV2ZW50VHlwZT0gKi8gZXZlbnRUeXBlLFxuICAgICAgLyogZXZlbnQ9ICovIGV2ZW50LFxuICAgICAgLyogdGFyZ2V0RWxlbWVudD0gKi8gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQsXG4gICAgICAvKiBjb250YWluZXI9ICovIGNvbnRhaW5lcixcbiAgICAgIC8qIHRpbWVzdGFtcD0gKi8gRGF0ZS5ub3coKSxcbiAgICApO1xuICAgIHRoaXMuaGFuZGxlRXZlbnRJbmZvKGV2ZW50SW5mbyk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGFuIGBFdmVudEluZm9gLlxuICAgKiBAcGFyYW0gYWxsb3dSZWhhbmRsaW5nIFVzZWQgaW4gdGhlIGNhc2Ugb2YgYTExeSBjbGljayBjYXN0aW5nIHRvIHByZXZlbnRcbiAgICogdXMgZnJvbSB0cnlpbmcgdG8gcmVoYW5kbGUgaW4gYW4gaW5maW5pdGUgbG9vcC5cbiAgICovXG4gIHByaXZhdGUgaGFuZGxlRXZlbnRJbmZvKGV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbywgYWxsb3dSZWhhbmRsaW5nID0gdHJ1ZSkge1xuICAgIGlmICghdGhpcy5kaXNwYXRjaGVyKSB7XG4gICAgICAvLyBBbGwgZXZlbnRzIGFyZSBxdWV1ZWQgd2hlbiB0aGUgZGlzcGF0Y2hlciBpc24ndCB5ZXQgbG9hZGVkLlxuICAgICAgZXZlbnRJbmZvTGliLnNldElzUmVwbGF5KGV2ZW50SW5mbywgdHJ1ZSk7XG4gICAgICB0aGlzLnF1ZXVlZEV2ZW50SW5mb3M/LnB1c2goZXZlbnRJbmZvKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgRXZlbnRDb250cmFjdC5DVVNUT01fRVZFTlRfU1VQUE9SVCAmJlxuICAgICAgZXZlbnRJbmZvTGliLmdldEV2ZW50VHlwZShldmVudEluZm8pID09PSBFdmVudFR5cGUuQ1VTVE9NXG4gICAgKSB7XG4gICAgICBjb25zdCBkZXRhaWwgPSAoZXZlbnRJbmZvTGliLmdldEV2ZW50KGV2ZW50SW5mbykgYXMgQ3VzdG9tRXZlbnQpLmRldGFpbDtcbiAgICAgIC8vIEZvciBjdXN0b20gZXZlbnRzLCB1c2UgYSBzZWNvbmRhcnkgZGlzcGF0Y2ggYmFzZWQgb24gdGhlIGludGVybmFsXG4gICAgICAvLyBjdXN0b20gdHlwZSBvZiB0aGUgZXZlbnQuXG4gICAgICBpZiAoIWRldGFpbCB8fCAhZGV0YWlsWydfdHlwZSddKSB7XG4gICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZXZlbnRJbmZvTGliLnNldEV2ZW50VHlwZShldmVudEluZm8sIGRldGFpbFsnX3R5cGUnXSk7XG4gICAgfVxuXG4gICAgdGhpcy5wb3B1bGF0ZUFjdGlvbihldmVudEluZm8pO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5kaXNwYXRjaGVyICYmXG4gICAgICAhZXZlbnRJbmZvTGliLmdldEV2ZW50KGV2ZW50SW5mbylbQWNjZXNzaWJpbGl0eUF0dHJpYnV0ZS5TS0lQX0dMT0JBTF9ESVNQQVRDSF1cbiAgICApIHtcbiAgICAgIGNvbnN0IGdsb2JhbEV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbyA9IGV2ZW50SW5mb0xpYi5jbG9uZUV2ZW50SW5mbyhldmVudEluZm8pO1xuXG4gICAgICAvLyBJbiBzb21lIGNhc2VzLCBgcG9wdWxhdGVBY3Rpb25gIHdpbGwgcmV3cml0ZSBgY2xpY2tgIGV2ZW50cyB0b1xuICAgICAgLy8gYGNsaWNrb25seWAuIFJldmVydCBiYWNrIHRvIGEgcmVndWxhciBjbGljaywgb3RoZXJ3aXNlIHdlIHdvbid0IGJlIGFibGVcbiAgICAgIC8vIHRvIGV4ZWN1dGUgZ2xvYmFsIGV2ZW50IGhhbmRsZXJzIHJlZ2lzdGVyZWQgb24gY2xpY2sgZXZlbnRzLlxuICAgICAgaWYgKGV2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZ2xvYmFsRXZlbnRJbmZvKSA9PT0gRXZlbnRUeXBlLkNMSUNLT05MWSkge1xuICAgICAgICBldmVudEluZm9MaWIuc2V0RXZlbnRUeXBlKGdsb2JhbEV2ZW50SW5mbywgRXZlbnRUeXBlLkNMSUNLKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5kaXNwYXRjaGVyKGdsb2JhbEV2ZW50SW5mbywgLyogZGlzcGF0Y2ggZ2xvYmFsIGV2ZW50ICovIHRydWUpO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGlvbiA9IGV2ZW50SW5mb0xpYi5nZXRBY3Rpb24oZXZlbnRJbmZvKTtcbiAgICBpZiAoIWFjdGlvbiAmJiAhY2hlY2tEaXNwYXRjaGVyRm9yQTExeUNsaWNrKGV2ZW50SW5mbykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kaXNwYXRjaGVyKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGFjdGlvbiAmJlxuICAgICAgICBzaG91bGRQcmV2ZW50RGVmYXVsdEJlZm9yZURpc3BhdGNoaW5nKGV2ZW50SW5mb0xpYi5nZXRBY3Rpb25FbGVtZW50KGFjdGlvbiksIGV2ZW50SW5mbylcbiAgICAgICkge1xuICAgICAgICBldmVudExpYi5wcmV2ZW50RGVmYXVsdChldmVudEluZm9MaWIuZ2V0RXZlbnQoZXZlbnRJbmZvKSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVucmVzb2x2ZWRFdmVudEluZm8gPSB0aGlzLmRpc3BhdGNoZXIoZXZlbnRJbmZvKTtcbiAgICAgIGlmICh1bnJlc29sdmVkRXZlbnRJbmZvICYmIGFsbG93UmVoYW5kbGluZykge1xuICAgICAgICAvLyBUaGUgZGlzcGF0Y2hlciBvbmx5IHJldHVybnMgYW4gZXZlbnQgZm9yIE1BWUJFX0NMSUNLX0VWRU5UX1RZUEVcbiAgICAgICAgLy8gZXZlbnRzIHRoYXQgY2FuJ3QgYmUgY2FzdGVkIHRvIGEgY2xpY2suIFdlIHJ1biBpdCB0aHJvdWdoIHRoZVxuICAgICAgICAvLyBoYW5kbGVyIGFnYWluIHRvIGZpbmQga2V5ZG93biBhY3Rpb25zIGZvciBpdC5cbiAgICAgICAgdGhpcy5oYW5kbGVFdmVudEluZm8odW5yZXNvbHZlZEV2ZW50SW5mbywgLyogYWxsb3dSZWhhbmRsaW5nPSAqLyBmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VhcmNoZXMgZm9yIGEganNhY3Rpb24gdGhhdCB0aGUgRE9NIGV2ZW50IG1hcHMgdG8gYW5kIGNyZWF0ZXMgYW5cbiAgICogb2JqZWN0IGNvbnRhaW5pbmcgZXZlbnQgaW5mb3JtYXRpb24gdXNlZCBmb3IgZGlzcGF0Y2hpbmcgYnlcbiAgICoganNhY3Rpb24uRGlzcGF0Y2hlci4gVGhpcyBtZXRob2QgcG9wdWxhdGVzIHRoZSBgYWN0aW9uYCBhbmQgYGFjdGlvbkVsZW1lbnRgXG4gICAqIGZpZWxkcyBvZiB0aGUgRXZlbnRJbmZvIG9iamVjdCBwYXNzZWQgaW4gYnkgZmluZGluZyB0aGUgZmlyc3RcbiAgICoganNhY3Rpb24gYXR0cmlidXRlIGFib3ZlIHRoZSB0YXJnZXQgTm9kZSBvZiB0aGUgZXZlbnQsIGFuZCBiZWxvd1xuICAgKiB0aGUgY29udGFpbmVyIE5vZGUsIHRoYXQgc3BlY2lmaWVzIGEganNhY3Rpb24gZm9yIHRoZSBldmVudFxuICAgKiB0eXBlLiBJZiBubyBzdWNoIGpzYWN0aW9uIGlzIGZvdW5kLCB0aGVuIGFjdGlvbiBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSBldmVudEluZm8gYEV2ZW50SW5mb2AgdG8gc2V0IGBhY3Rpb25gIGFuZCBgYWN0aW9uRWxlbWVudGAgaWYgYW5cbiAgICogICAgYWN0aW9uIGlzIGZvdW5kIG9uIGFueSBgRWxlbWVudGAgaW4gdGhlIHBhdGggb2YgdGhlIGBFdmVudGAuXG4gICAqL1xuICBwcml2YXRlIHBvcHVsYXRlQWN0aW9uKGV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbykge1xuICAgIC8vIFdlIGRpc3Rpbmd1aXNoIG1vZGlmaWVkIGFuZCBwbGFpbiBjbGlja3MgaW4gb3JkZXIgdG8gc3VwcG9ydCB0aGVcbiAgICAvLyBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3Igb2YgbW9kaWZpZWQgY2xpY2tzIG9uIGxpbmtzOyB1c3VhbGx5IHRvXG4gICAgLy8gb3BlbiB0aGUgVVJMIG9mIHRoZSBsaW5rIGluIG5ldyB0YWIgb3IgbmV3IHdpbmRvdyBvbiBjdHJsL2NtZFxuICAgIC8vIGNsaWNrLiBBIERPTSAnY2xpY2snIGV2ZW50IGlzIG1hcHBlZCB0byB0aGUganNhY3Rpb24gJ2NsaWNrJ1xuICAgIC8vIGV2ZW50IGlmZiB0aGVyZSBpcyBubyBtb2RpZmllciBwcmVzZW50IG9uIHRoZSBldmVudC4gSWYgdGhlcmUgaXNcbiAgICAvLyBhIG1vZGlmaWVyLCBpdCdzIG1hcHBlZCB0byAnY2xpY2ttb2QnIGluc3RlYWQuXG4gICAgLy9cbiAgICAvLyBJdCdzIGFsbG93ZWQgdG8gb21pdCB0aGUgZXZlbnQgaW4gdGhlIGpzYWN0aW9uIGF0dHJpYnV0ZS4gSW4gdGhhdFxuICAgIC8vIGNhc2UsICdjbGljaycgaXMgYXNzdW1lZC4gVGh1cyB0aGUgZm9sbG93aW5nIHR3byBhcmUgZXF1aXZhbGVudDpcbiAgICAvL1xuICAgIC8vICAgPGEgaHJlZj1cInNvbWV1cmxcIiBqc2FjdGlvbj1cImduYS5mdVwiPlxuICAgIC8vICAgPGEgaHJlZj1cInNvbWV1cmxcIiBqc2FjdGlvbj1cImNsaWNrOmduYS5mdVwiPlxuICAgIC8vXG4gICAgLy8gRm9yIHVubW9kaWZpZWQgY2xpY2tzLCBFdmVudENvbnRyYWN0IGludm9rZXMgdGhlIGpzYWN0aW9uXG4gICAgLy8gJ2duYS5mdScuIEZvciBtb2RpZmllZCBjbGlja3MsIEV2ZW50Q29udHJhY3Qgd29uJ3QgZmluZCBhXG4gICAgLy8gc3VpdGFibGUgYWN0aW9uIGFuZCBsZWF2ZSB0aGUgZXZlbnQgdG8gYmUgaGFuZGxlZCBieSB0aGVcbiAgICAvLyBicm93c2VyLlxuICAgIC8vXG4gICAgLy8gSW4gb3JkZXIgdG8gYWxzbyBpbnZva2UgYSBqc2FjdGlvbiBoYW5kbGVyIGZvciBhIG1vZGlmaWVyIGNsaWNrLFxuICAgIC8vICdjbGlja21vZCcgbmVlZHMgdG8gYmUgdXNlZDpcbiAgICAvL1xuICAgIC8vICAgPGEgaHJlZj1cInNvbWV1cmxcIiBqc2FjdGlvbj1cImNsaWNrbW9kOmduYS5mdVwiPlxuICAgIC8vXG4gICAgLy8gRXZlbnRDb250cmFjdCBpbnZva2VzIHRoZSBqc2FjdGlvbiAnZ25hLmZ1JyBmb3IgbW9kaWZpZWRcbiAgICAvLyBjbGlja3MuIFVubW9kaWZpZWQgY2xpY2tzIGFyZSBsZWZ0IHRvIHRoZSBicm93c2VyLlxuICAgIC8vXG4gICAgLy8gSW4gb3JkZXIgdG8gc2V0IHVwIHRoZSBldmVudCBjb250cmFjdCB0byBoYW5kbGUgYm90aCBjbGlja29ubHkgYW5kXG4gICAgLy8gY2xpY2ttb2QsIG9ubHkgYWRkRXZlbnQoRXZlbnRUeXBlLkNMSUNLKSBpcyBuZWNlc3NhcnkuXG4gICAgLy9cbiAgICAvLyBJbiBvcmRlciB0byBzZXQgdXAgdGhlIGV2ZW50IGNvbnRyYWN0IHRvIGhhbmRsZSBjbGljayxcbiAgICAvLyBhZGRFdmVudCgpIGlzIG5lY2Vzc2FyeSBmb3IgQ0xJQ0ssIEtFWURPV04sIGFuZCBLRVlQUkVTUyBldmVudCB0eXBlcy4gIElmXG4gICAgLy8gYTExeSBjbGljayBzdXBwb3J0IGlzIGVuYWJsZWQsIGFkZEV2ZW50KCkgd2lsbCBzZXQgdXAgdGhlIGFwcHJvcHJpYXRlIGtleVxuICAgIC8vIGV2ZW50IGhhbmRsZXIgYXV0b21hdGljYWxseS5cbiAgICBpZiAoXG4gICAgICBldmVudEluZm9MaWIuZ2V0RXZlbnRUeXBlKGV2ZW50SW5mbykgPT09IEV2ZW50VHlwZS5DTElDSyAmJlxuICAgICAgZXZlbnRMaWIuaXNNb2RpZmllZENsaWNrRXZlbnQoZXZlbnRJbmZvTGliLmdldEV2ZW50KGV2ZW50SW5mbykpXG4gICAgKSB7XG4gICAgICBldmVudEluZm9MaWIuc2V0RXZlbnRUeXBlKGV2ZW50SW5mbywgRXZlbnRUeXBlLkNMSUNLTU9EKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaGFzQTExeUNsaWNrU3VwcG9ydCkge1xuICAgICAgdGhpcy51cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2shKGV2ZW50SW5mbyk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIEV2ZW50Q29udHJhY3QuQTExWV9TVVBQT1JUX0lOX0RJU1BBVENIRVIgJiZcbiAgICAgIGV2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZXZlbnRJbmZvKSA9PT0gRXZlbnRUeXBlLktFWURPV04gJiZcbiAgICAgICFldmVudEluZm9MaWIuZ2V0RXZlbnQoZXZlbnRJbmZvKVtBY2Nlc3NpYmlsaXR5QXR0cmlidXRlLlNLSVBfQTExWV9DSEVDS11cbiAgICApIHtcbiAgICAgIC8vIFdlIHVzZSBhIHN0cmluZyBsaXRlcmFsIGFzIHRoaXMgdmFsdWUgbmVlZHMgdG8gYmUgcmVmZXJlbmNlZCBpbiB0aGVcbiAgICAgIC8vIGRpc3BhdGNoZXIncyBiaW5hcnkuXG4gICAgICBldmVudEluZm9MaWIuc2V0RXZlbnRUeXBlKGV2ZW50SW5mbywgQWNjZXNzaWJpbGl0eUF0dHJpYnV0ZS5NQVlCRV9DTElDS19FVkVOVF9UWVBFKTtcbiAgICB9XG5cbiAgICAvLyBXYWxrIHRvIHRoZSBwYXJlbnQgbm9kZSwgdW5sZXNzIHRoZSBub2RlIGhhcyBhIGRpZmZlcmVudCBvd25lciBpblxuICAgIC8vIHdoaWNoIGNhc2Ugd2Ugd2FsayB0byB0aGUgb3duZXIuIEF0dGVtcHQgdG8gd2FsayB0byBob3N0IG9mIGFcbiAgICAvLyBzaGFkb3cgcm9vdCBpZiBuZWVkZWQuXG4gICAgbGV0IGFjdGlvbkVsZW1lbnQ6IEVsZW1lbnQgfCBudWxsID0gZXZlbnRJbmZvTGliLmdldFRhcmdldEVsZW1lbnQoZXZlbnRJbmZvKTtcbiAgICB3aGlsZSAoYWN0aW9uRWxlbWVudCAmJiBhY3Rpb25FbGVtZW50ICE9PSBldmVudEluZm9MaWIuZ2V0Q29udGFpbmVyKGV2ZW50SW5mbykpIHtcbiAgICAgIHRoaXMucG9wdWxhdGVBY3Rpb25PbkVsZW1lbnQoYWN0aW9uRWxlbWVudCwgZXZlbnRJbmZvKTtcblxuICAgICAgaWYgKGV2ZW50SW5mb0xpYi5nZXRBY3Rpb24oZXZlbnRJbmZvKSkge1xuICAgICAgICAvLyBBbiBldmVudCBpcyBoYW5kbGVkIGJ5IGF0IG1vc3Qgb25lIGpzYWN0aW9uLiBUaHVzIHdlIHN0b3AgYXQgdGhlXG4gICAgICAgIC8vIGZpcnN0IG1hdGNoaW5nIGpzYWN0aW9uIHNwZWNpZmllZCBpbiBhIGpzYWN0aW9uIGF0dHJpYnV0ZSB1cCB0aGVcbiAgICAgICAgLy8gYW5jZXN0b3IgY2hhaW4gb2YgdGhlIGV2ZW50IHRhcmdldCBub2RlLlxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChhY3Rpb25FbGVtZW50W1Byb3BlcnR5Lk9XTkVSXSkge1xuICAgICAgICBhY3Rpb25FbGVtZW50ID0gYWN0aW9uRWxlbWVudFtQcm9wZXJ0eS5PV05FUl0gYXMgRWxlbWVudDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoYWN0aW9uRWxlbWVudC5wYXJlbnROb2RlPy5ub2RlTmFtZSAhPT0gJyNkb2N1bWVudC1mcmFnbWVudCcpIHtcbiAgICAgICAgYWN0aW9uRWxlbWVudCA9IGFjdGlvbkVsZW1lbnQucGFyZW50Tm9kZSBhcyBFbGVtZW50IHwgbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjdGlvbkVsZW1lbnQgPSAoYWN0aW9uRWxlbWVudC5wYXJlbnROb2RlIGFzIFNoYWRvd1Jvb3QgfCBudWxsKT8uaG9zdCA/PyBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFjdGlvbiA9IGV2ZW50SW5mb0xpYi5nZXRBY3Rpb24oZXZlbnRJbmZvKTtcbiAgICBpZiAoIWFjdGlvbikge1xuICAgICAgLy8gTm8gYWN0aW9uIGZvdW5kLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc0ExMXlDbGlja1N1cHBvcnQpIHtcbiAgICAgIHRoaXMucHJldmVudERlZmF1bHRGb3JBMTF5Q2xpY2shKGV2ZW50SW5mbyk7XG4gICAgfVxuXG4gICAgLy8gV2UgYXR0ZW1wdCB0byBoYW5kbGUgdGhlIG1vdXNlZW50ZXIvbW91c2VsZWF2ZSBldmVudHMgaGVyZSBieVxuICAgIC8vIGRldGVjdGluZyB3aGV0aGVyIHRoZSBtb3VzZW92ZXIvbW91c2VvdXQgZXZlbnRzIGNvcnJlc3BvbmQgdG9cbiAgICAvLyBlbnRlcmluZy9sZWF2aW5nIGFuIGVsZW1lbnQuXG4gICAgaWYgKFxuICAgICAgRXZlbnRDb250cmFjdC5NT1VTRV9TUEVDSUFMX1NVUFBPUlQgJiZcbiAgICAgIChldmVudEluZm9MaWIuZ2V0RXZlbnRUeXBlKGV2ZW50SW5mbykgPT09IEV2ZW50VHlwZS5NT1VTRUVOVEVSIHx8XG4gICAgICAgIGV2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZXZlbnRJbmZvKSA9PT0gRXZlbnRUeXBlLk1PVVNFTEVBVkUgfHxcbiAgICAgICAgZXZlbnRJbmZvTGliLmdldEV2ZW50VHlwZShldmVudEluZm8pID09PSBFdmVudFR5cGUuUE9JTlRFUkVOVEVSIHx8XG4gICAgICAgIGV2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZXZlbnRJbmZvKSA9PT0gRXZlbnRUeXBlLlBPSU5URVJMRUFWRSlcbiAgICApIHtcbiAgICAgIC8vIFdlIGF0dGVtcHQgdG8gaGFuZGxlIHRoZSBtb3VzZWVudGVyL21vdXNlbGVhdmUgZXZlbnRzIGhlcmUgYnlcbiAgICAgIC8vIGRldGVjdGluZyB3aGV0aGVyIHRoZSBtb3VzZW92ZXIvbW91c2VvdXQgZXZlbnRzIGNvcnJlc3BvbmQgdG9cbiAgICAgIC8vIGVudGVyaW5nL2xlYXZpbmcgYW4gZWxlbWVudC5cbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnRMaWIuaXNNb3VzZVNwZWNpYWxFdmVudChcbiAgICAgICAgICBldmVudEluZm9MaWIuZ2V0RXZlbnQoZXZlbnRJbmZvKSxcbiAgICAgICAgICBldmVudEluZm9MaWIuZ2V0RXZlbnRUeXBlKGV2ZW50SW5mbyksXG4gICAgICAgICAgZXZlbnRJbmZvTGliLmdldEFjdGlvbkVsZW1lbnQoYWN0aW9uKSxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIC8vIElmIGJvdGggbW91c2VvdmVyL21vdXNlb3V0IGFuZCBtb3VzZWVudGVyL21vdXNlbGVhdmUgZXZlbnRzIGFyZVxuICAgICAgICAvLyBlbmFibGVkLCB0d28gc2VwYXJhdGUgaGFuZGxlcnMgZm9yIG1vdXNlb3Zlci9tb3VzZW91dCBhcmVcbiAgICAgICAgLy8gcmVnaXN0ZXJlZC4gQm90aCBoYW5kbGVycyB3aWxsIHNlZSB0aGUgc2FtZSBldmVudCBpbnN0YW5jZVxuICAgICAgICAvLyBzbyB3ZSBjcmVhdGUgYSBjb3B5IHRvIGF2b2lkIGludGVyZmVyaW5nIHdpdGggdGhlIGRpc3BhdGNoaW5nIG9mXG4gICAgICAgIC8vIHRoZSBtb3VzZW92ZXIvbW91c2VvdXQgZXZlbnQuXG4gICAgICAgIGNvbnN0IGNvcGllZEV2ZW50ID0gZXZlbnRMaWIuY3JlYXRlTW91c2VTcGVjaWFsRXZlbnQoXG4gICAgICAgICAgZXZlbnRJbmZvTGliLmdldEV2ZW50KGV2ZW50SW5mbyksXG4gICAgICAgICAgZXZlbnRJbmZvTGliLmdldEFjdGlvbkVsZW1lbnQoYWN0aW9uKSxcbiAgICAgICAgKTtcbiAgICAgICAgZXZlbnRJbmZvTGliLnNldEV2ZW50KGV2ZW50SW5mbywgY29waWVkRXZlbnQpO1xuICAgICAgICAvLyBTaW5jZSB0aGUgbW91c2VlbnRlci9tb3VzZWxlYXZlIGV2ZW50cyBkbyBub3QgYnViYmxlLCB0aGUgdGFyZ2V0XG4gICAgICAgIC8vIG9mIHRoZSBldmVudCBpcyB0ZWNobmljYWxseSB0aGUgYGFjdGlvbkVsZW1lbnRgICh0aGUgbm9kZSB3aXRoIHRoZVxuICAgICAgICAvLyBganNhY3Rpb25gIGF0dHJpYnV0ZSlcbiAgICAgICAgZXZlbnRJbmZvTGliLnNldFRhcmdldEVsZW1lbnQoZXZlbnRJbmZvLCBldmVudEluZm9MaWIuZ2V0QWN0aW9uRWxlbWVudChhY3Rpb24pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV2ZW50SW5mb0xpYi51bnNldEFjdGlvbihldmVudEluZm8pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBY2Nlc3NlcyB0aGUganNhY3Rpb24gbWFwIG9uIGEgbm9kZSBhbmQgcmV0cmlldmVzIHRoZSBuYW1lIG9mIHRoZVxuICAgKiBhY3Rpb24gdGhlIGdpdmVuIGV2ZW50IGlzIG1hcHBlZCB0bywgaWYgYW55LiBJdCBwYXJzZXMgdGhlXG4gICAqIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgc3RvcmVzIGl0IGluIGEgcHJvcGVydHkgb24gdGhlIG5vZGUgZm9yXG4gICAqIHN1YnNlcXVlbnQgcmV0cmlldmFsIHdpdGhvdXQgcmUtcGFyc2luZyBhbmQgcmUtYWNjZXNzaW5nIHRoZVxuICAgKiBhdHRyaWJ1dGUuIEluIG9yZGVyIHRvIGZ1bGx5IHF1YWxpZnkganNhY3Rpb24gbmFtZXMgdXNpbmcgYVxuICAgKiBuYW1lc3BhY2UsIHRoZSBET00gaXMgc2VhcmNoZWQgc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgbm9kZSBhbmRcbiAgICogZ29pbmcgdGhyb3VnaCBhbmNlc3RvciBub2RlcyB1bnRpbCBhIGpzbmFtZXNwYWNlIGF0dHJpYnV0ZSBpc1xuICAgKiBmb3VuZC5cbiAgICpcbiAgICogQHBhcmFtIGFjdGlvbkVsZW1lbnQgVGhlIERPTSBub2RlIHRvIHJldHJpZXZlIHRoZSBqc2FjdGlvbiBtYXAgZnJvbS5cbiAgICogQHBhcmFtIGV2ZW50SW5mbyBgRXZlbnRJbmZvYCB0byBzZXQgYGFjdGlvbmAgYW5kIGBhY3Rpb25FbGVtZW50YCBpZiBhblxuICAgKiAgICBhY3Rpb24gaXMgZm91bmQgb24gdGhlIGBhY3Rpb25FbGVtZW50YC5cbiAgICovXG4gIHByaXZhdGUgcG9wdWxhdGVBY3Rpb25PbkVsZW1lbnQoYWN0aW9uRWxlbWVudDogRWxlbWVudCwgZXZlbnRJbmZvOiBldmVudEluZm9MaWIuRXZlbnRJbmZvKSB7XG4gICAgY29uc3QgYWN0aW9uTWFwID0gcGFyc2VBY3Rpb25zKGFjdGlvbkVsZW1lbnQsIGV2ZW50SW5mb0xpYi5nZXRDb250YWluZXIoZXZlbnRJbmZvKSk7XG5cbiAgICBjb25zdCBhY3Rpb25OYW1lID0gYWN0aW9uTWFwW2V2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZXZlbnRJbmZvKV07XG4gICAgaWYgKGFjdGlvbk5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZXZlbnRJbmZvTGliLnNldEFjdGlvbihldmVudEluZm8sIGFjdGlvbk5hbWUsIGFjdGlvbkVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc0ExMXlDbGlja1N1cHBvcnQpIHtcbiAgICAgIHRoaXMucG9wdWxhdGVDbGlja09ubHlBY3Rpb24hKGFjdGlvbkVsZW1lbnQsIGV2ZW50SW5mbywgYWN0aW9uTWFwKTtcbiAgICB9XG4gICAgaWYgKEV2ZW50Q29udHJhY3QuQTExWV9TVVBQT1JUX0lOX0RJU1BBVENIRVIpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZXZlbnRJbmZvTGliLmdldEV2ZW50VHlwZShldmVudEluZm8pID09PSBBY2Nlc3NpYmlsaXR5QXR0cmlidXRlLk1BWUJFX0NMSUNLX0VWRU5UX1RZUEUgJiZcbiAgICAgICAgYWN0aW9uTWFwW0V2ZW50VHlwZS5DTElDS10gIT09IHVuZGVmaW5lZFxuICAgICAgKSB7XG4gICAgICAgIC8vIFdlJ2xsIHRha2UgdGhlIGZpcnN0IENMSUNLIGFjdGlvbiB3ZSBmaW5kIGFuZCBoYXZlIHRoZSBkaXNwYXRjaGVyXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBrZXlkb3duIGV2ZW50IGNhbiBiZSB1c2VkIGFzIGEgQ0xJQ0suIElmIG5vdCwgdGhlXG4gICAgICAgIC8vIGRpc3BhdGNoZXIgd2lsbCByZXRyaWdnZXIgdGhlIGV2ZW50IHNvIHRoYXQgd2UgY2FuIGZpbmQgYSBrZXlkb3duXG4gICAgICAgIC8vIGV2ZW50IGluc3RlYWQuXG4gICAgICAgIC8vIFdoZW4gd2UgZ2V0IE1BWUJFX0NMSUNLX0VWRU5UX1RZUEUgYXMgYW4gZXZlbnRUeXBlLCB3ZSB3YW50IHRvXG4gICAgICAgIC8vIHJldHJpZXZlIHRoZSBhY3Rpb24gY29ycmVzcG9uZGluZyB0byBDTElDSywgYnV0IHN0aWxsIGtlZXAgdGhlXG4gICAgICAgIC8vIGV2ZW50SW5mb0xpYi5nZXRFdmVudFR5cGUoZXZlbnRJbmZvLCApIGFzIE1BWUJFX0NMSUNLX0VWRU5UX1RZUEUuIFRoZVxuICAgICAgICAvLyBkaXNwYXRjaGVyIHVzZXMgdGhpcyBldmVudCB0eXBlIHRvIGRldGVybWluZSBpZiBpdCBzaG91bGQgZ2V0IHRoZVxuICAgICAgICAvLyBoYW5kbGVyIGZvciB0aGUgYWN0aW9uLlxuICAgICAgICBldmVudEluZm9MaWIuc2V0QWN0aW9uKGV2ZW50SW5mbywgYWN0aW9uTWFwW0V2ZW50VHlwZS5DTElDS10sIGFjdGlvbkVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYTExeUNsaWNrTGliLnBvcHVsYXRlQ2xpY2tPbmx5QWN0aW9uKGFjdGlvbkVsZW1lbnQsIGV2ZW50SW5mbywgYWN0aW9uTWFwKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyBqc2FjdGlvbiBoYW5kbGVycyB0byBiZSBjYWxsZWQgZm9yIHRoZSBldmVudCB0eXBlIGdpdmVuIGJ5XG4gICAqIG5hbWUuXG4gICAqXG4gICAqIElmIHRoZSBldmVudCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQsIHRoaXMgZG9lcyBub3RoaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gcHJlZml4ZWRFdmVudFR5cGUgSWYgc3VwcGxpZWQsIHRoaXMgZXZlbnQgaXMgdXNlZCBpblxuICAgKiAgICAgdGhlIGFjdHVhbCBicm93c2VyIGV2ZW50IHJlZ2lzdHJhdGlvbiBpbnN0ZWFkIG9mIHRoZSBuYW1lIHRoYXQgaXNcbiAgICogICAgIGV4cG9zZWQgdG8ganNhY3Rpb24uIFVzZSB0aGlzIGlmIHlvdSBlLmcuIHdhbnQgdXNlcnMgdG8gYmUgYWJsZVxuICAgKiAgICAgdG8gc3Vic2NyaWJlIHRvIGpzYWN0aW9uPVwidHJhbnNpdGlvbkVuZDpmb29cIiB3aGlsZSB0aGUgdW5kZXJseWluZ1xuICAgKiAgICAgZXZlbnQgaXMgd2Via2l0VHJhbnNpdGlvbkVuZCBpbiBvbmUgYnJvd3NlciBhbmQgbW96VHJhbnNpdGlvbkVuZFxuICAgKiAgICAgaW4gYW5vdGhlci5cbiAgICovXG4gIGFkZEV2ZW50KGV2ZW50VHlwZTogc3RyaW5nLCBwcmVmaXhlZEV2ZW50VHlwZT86IHN0cmluZykge1xuICAgIGlmIChldmVudFR5cGUgaW4gdGhpcy5ldmVudEhhbmRsZXJzIHx8ICF0aGlzLmNvbnRhaW5lck1hbmFnZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAhRXZlbnRDb250cmFjdC5NT1VTRV9TUEVDSUFMX1NVUFBPUlQgJiZcbiAgICAgIChldmVudFR5cGUgPT09IEV2ZW50VHlwZS5NT1VTRUVOVEVSIHx8XG4gICAgICAgIGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLk1PVVNFTEVBVkUgfHxcbiAgICAgICAgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuUE9JTlRFUkVOVEVSIHx8XG4gICAgICAgIGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLlBPSU5URVJMRUFWRSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBldmVudEhhbmRsZXIgPSAoZXZlbnRUeXBlOiBzdHJpbmcsIGV2ZW50OiBFdmVudCwgY29udGFpbmVyOiBFbGVtZW50KSA9PiB7XG4gICAgICB0aGlzLmhhbmRsZUV2ZW50KGV2ZW50VHlwZSwgZXZlbnQsIGNvbnRhaW5lcik7XG4gICAgfTtcblxuICAgIC8vIFN0b3JlIHRoZSBjYWxsYmFjayB0byBhbGxvdyB1cyB0byByZXBsYXkgZXZlbnRzLlxuICAgIHRoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdID0gZXZlbnRIYW5kbGVyO1xuXG4gICAgY29uc3QgYnJvd3NlckV2ZW50VHlwZSA9IGV2ZW50TGliLmdldEJyb3dzZXJFdmVudFR5cGUocHJlZml4ZWRFdmVudFR5cGUgfHwgZXZlbnRUeXBlKTtcblxuICAgIGlmIChicm93c2VyRXZlbnRUeXBlICE9PSBldmVudFR5cGUpIHtcbiAgICAgIGNvbnN0IGV2ZW50VHlwZXMgPSB0aGlzLmJyb3dzZXJFdmVudFR5cGVUb0V4dHJhRXZlbnRUeXBlc1ticm93c2VyRXZlbnRUeXBlXSB8fCBbXTtcbiAgICAgIGV2ZW50VHlwZXMucHVzaChldmVudFR5cGUpO1xuICAgICAgdGhpcy5icm93c2VyRXZlbnRUeXBlVG9FeHRyYUV2ZW50VHlwZXNbYnJvd3NlckV2ZW50VHlwZV0gPSBldmVudFR5cGVzO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyTWFuYWdlci5hZGRFdmVudExpc3RlbmVyKGJyb3dzZXJFdmVudFR5cGUsIChlbGVtZW50OiBFbGVtZW50KSA9PiB7XG4gICAgICByZXR1cm4gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICBldmVudEhhbmRsZXIoZXZlbnRUeXBlLCBldmVudCwgZWxlbWVudCk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQXV0b21hdGljYWxseSBpbnN0YWxsIGEga2V5cHJlc3Mva2V5ZG93biBldmVudCBoYW5kbGVyIGlmIHN1cHBvcnQgZm9yXG4gICAgLy8gYWNjZXNzaWJsZSBjbGlja3MgaXMgdHVybmVkIG9uLlxuICAgIGlmICh0aGlzLmFkZEExMXlDbGlja0xpc3RlbmVyICYmIGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLkNMSUNLKSB7XG4gICAgICB0aGlzLmFkZEV2ZW50KEV2ZW50VHlwZS5LRVlET1dOKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcXVldWVkIGVhcmx5IGV2ZW50cyBhbmQgcmVwbGF5IHRoZW0gdXNpbmcgdGhlIGFwcHJvcHJpYXRlIGhhbmRsZXJcbiAgICogaW4gdGhlIHByb3ZpZGVkIGV2ZW50IGNvbnRyYWN0LiBPbmNlIGFsbCB0aGUgZXZlbnRzIGFyZSByZXBsYXllZCwgaXQgY2xlYW5zXG4gICAqIHVwIHRoZSBlYXJseSBjb250cmFjdC5cbiAgICovXG4gIHJlcGxheUVhcmx5RXZlbnRzKCkge1xuICAgIC8vIENoZWNrIGlmIHRoZSBlYXJseSBjb250cmFjdCBpcyBwcmVzZW50IGFuZCBwcmV2ZW50IGNhbGxpbmcgdGhpcyBmdW5jdGlvblxuICAgIC8vIG1vcmUgdGhhbiBvbmNlLlxuICAgIGNvbnN0IGVhcmx5SnNhY3Rpb25EYXRhOiBFYXJseUpzYWN0aW9uRGF0YSB8IHVuZGVmaW5lZCA9IHdpbmRvdy5fZWpzYTtcbiAgICBpZiAoIWVhcmx5SnNhY3Rpb25EYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVwbGF5IHRoZSBlYXJseSBjb250cmFjdCBldmVudHMuXG4gICAgY29uc3QgZWFybHlFdmVudEluZm9zOiBldmVudEluZm9MaWIuRXZlbnRJbmZvW10gPSBlYXJseUpzYWN0aW9uRGF0YS5xO1xuICAgIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IGVhcmx5RXZlbnRJbmZvcy5sZW5ndGg7IGlkeCsrKSB7XG4gICAgICBjb25zdCBlYXJseUV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbyA9IGVhcmx5RXZlbnRJbmZvc1tpZHhdO1xuICAgICAgY29uc3QgZXZlbnRUeXBlcyA9IHRoaXMuZ2V0RXZlbnRUeXBlc0ZvckJyb3dzZXJFdmVudFR5cGUoZWFybHlFdmVudEluZm8uZXZlbnRUeXBlKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBldmVudEluZm8gPSBldmVudEluZm9MaWIuY2xvbmVFdmVudEluZm8oZWFybHlFdmVudEluZm8pO1xuICAgICAgICAvLyBFdmVudEluZm8gZXZlbnRUeXBlIG1hcHMgdG8gSlNBY3Rpb24ncyBpbnRlcm5hbCBldmVudCB0eXBlLFxuICAgICAgICAvLyByYXRoZXIgdGhhbiB0aGUgYnJvd3NlciBldmVudCB0eXBlLlxuICAgICAgICBldmVudEluZm9MaWIuc2V0RXZlbnRUeXBlKGV2ZW50SW5mbywgZXZlbnRUeXBlc1tpXSk7XG4gICAgICAgIHRoaXMuaGFuZGxlRXZlbnRJbmZvKGV2ZW50SW5mbyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgdGhlIGVhcmx5IGNvbnRyYWN0LlxuICAgIGNvbnN0IGVhcmx5RXZlbnRUeXBlczogc3RyaW5nW10gPSBlYXJseUpzYWN0aW9uRGF0YS5ldDtcbiAgICBjb25zdCBlYXJseUV2ZW50SGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCA9IGVhcmx5SnNhY3Rpb25EYXRhLmg7XG4gICAgZm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgZWFybHlFdmVudFR5cGVzLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgIGNvbnN0IGV2ZW50VHlwZTogc3RyaW5nID0gZWFybHlFdmVudFR5cGVzW2lkeF07XG4gICAgICB3aW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBlYXJseUV2ZW50SGFuZGxlcik7XG4gICAgfVxuICAgIGRlbGV0ZSB3aW5kb3cuX2Vqc2E7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbGwgSlNBY3Rpb24gZXZlbnQgdHlwZXMgdGhhdCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCBmb3IgYSBnaXZlblxuICAgKiBicm93c2VyIGV2ZW50IHR5cGUuXG4gICAqL1xuICBwcml2YXRlIGdldEV2ZW50VHlwZXNGb3JCcm93c2VyRXZlbnRUeXBlKGJyb3dzZXJFdmVudFR5cGU6IHN0cmluZykge1xuICAgIGNvbnN0IGV2ZW50VHlwZXMgPSBbXTtcbiAgICBpZiAodGhpcy5ldmVudEhhbmRsZXJzW2Jyb3dzZXJFdmVudFR5cGVdKSB7XG4gICAgICBldmVudFR5cGVzLnB1c2goYnJvd3NlckV2ZW50VHlwZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmJyb3dzZXJFdmVudFR5cGVUb0V4dHJhRXZlbnRUeXBlc1ticm93c2VyRXZlbnRUeXBlXSkge1xuICAgICAgZXZlbnRUeXBlcy5wdXNoKC4uLnRoaXMuYnJvd3NlckV2ZW50VHlwZVRvRXh0cmFFdmVudFR5cGVzW2Jyb3dzZXJFdmVudFR5cGVdKTtcbiAgICB9XG4gICAgcmV0dXJuIGV2ZW50VHlwZXM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZXZlbnQgaGFuZGxlciBmdW5jdGlvbiBmb3IgYSBnaXZlbiBldmVudCB0eXBlLlxuICAgKi9cbiAgaGFuZGxlcihldmVudFR5cGU6IHN0cmluZyk6IEV2ZW50SGFuZGxlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyB1cCB0aGUgZXZlbnQgY29udHJhY3QuIFRoaXMgcmVzZXRzIGFsbCBvZiB0aGUgYEV2ZW50Q29udHJhY3RgJ3NcbiAgICogaW50ZXJuYWwgc3RhdGUuIFVzZXJzIGFyZSByZXNwb25zaWJsZSBmb3Igbm90IHVzaW5nIHRoaXMgYEV2ZW50Q29udHJhY3RgXG4gICAqIGFmdGVyIGl0IGhhcyBiZWVuIGNsZWFuZWQgdXAuXG4gICAqL1xuICBjbGVhblVwKCkge1xuICAgIHRoaXMuY29udGFpbmVyTWFuYWdlciEuY2xlYW5VcCgpO1xuICAgIHRoaXMuY29udGFpbmVyTWFuYWdlciA9IG51bGw7XG4gICAgdGhpcy5ldmVudEhhbmRsZXJzID0ge307XG4gICAgdGhpcy5icm93c2VyRXZlbnRUeXBlVG9FeHRyYUV2ZW50VHlwZXMgPSB7fTtcbiAgICB0aGlzLmRpc3BhdGNoZXIgPSBudWxsO1xuICAgIHRoaXMucXVldWVkRXZlbnRJbmZvcyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgZGlzcGF0Y2hlciBmdW5jdGlvbi4gRXZlbnQgaW5mbyBvZiBlYWNoIGV2ZW50IG1hcHBlZCB0b1xuICAgKiBhIGpzYWN0aW9uIGlzIHBhc3NlZCBmb3IgaGFuZGxpbmcgdG8gdGhpcyBjYWxsYmFjay4gVGhlIHF1ZXVlZFxuICAgKiBldmVudHMgYXJlIHBhc3NlZCBhcyB3ZWxsIHRvIHRoZSBkaXNwYXRjaGVyIGZvciBsYXRlciByZXBsYXlpbmdcbiAgICogb25jZSB0aGUgZGlzcGF0Y2hlciBpcyByZWdpc3RlcmVkLiBDbGVhcnMgdGhlIGV2ZW50IHF1ZXVlIHRvIG51bGwuXG4gICAqXG4gICAqIEBwYXJhbSBkaXNwYXRjaGVyIFRoZSBkaXNwYXRjaGVyIGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0gcmVzdHJpY3Rpb25cbiAgICovXG4gIHJlZ2lzdGVyRGlzcGF0Y2hlcihkaXNwYXRjaGVyOiBEaXNwYXRjaGVyLCByZXN0cmljdGlvbjogUmVzdHJpY3Rpb24pIHtcbiAgICB0aGlzLmVjcmQoZGlzcGF0Y2hlciwgcmVzdHJpY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVuYW1lZCBhbGlhcyBmb3IgcmVnaXN0ZXJEaXNwYXRjaGVyLiBOZWNlc3NhcnkgZm9yIGFueSBjb2RlYmFzZXMgdGhhdFxuICAgKiBzcGxpdCB0aGUgYEV2ZW50Q29udHJhY3RgIGFuZCBgRGlzcGF0Y2hlcmAgY29kZSBpbnRvIGRpZmZlcmVudCBjb21waWxhdGlvblxuICAgKiB1bml0cy5cbiAgICovXG4gIGVjcmQoZGlzcGF0Y2hlcjogRGlzcGF0Y2hlciwgcmVzdHJpY3Rpb246IFJlc3RyaWN0aW9uKSB7XG4gICAgdGhpcy5kaXNwYXRjaGVyID0gZGlzcGF0Y2hlcjtcblxuICAgIGlmICh0aGlzLnF1ZXVlZEV2ZW50SW5mb3M/Lmxlbmd0aCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnF1ZXVlZEV2ZW50SW5mb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5oYW5kbGVFdmVudEluZm8odGhpcy5xdWV1ZWRFdmVudEluZm9zW2ldKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucXVldWVkRXZlbnRJbmZvcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYTExeSBjbGljayBzdXBwb3J0IHRvIHRoZSBnaXZlbiBgRXZlbnRDb250cmFjdGAuIE1lYW50IHRvIGJlIGNhbGxlZCBpblxuICAgKiB0aGUgc2FtZSBjb21waWxhdGlvbiB1bml0IGFzIHRoZSBgRXZlbnRDb250cmFjdGAuXG4gICAqL1xuICBhZGRBMTF5Q2xpY2tTdXBwb3J0KCkge1xuICAgIHRoaXMuYWRkQTExeUNsaWNrU3VwcG9ydEltcGwoXG4gICAgICBhMTF5Q2xpY2tMaWIudXBkYXRlRXZlbnRJbmZvRm9yQTExeUNsaWNrLFxuICAgICAgYTExeUNsaWNrTGliLnByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrLFxuICAgICAgYTExeUNsaWNrTGliLnBvcHVsYXRlQ2xpY2tPbmx5QWN0aW9uLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyBhMTF5IGNsaWNrIHN1cHBvcnQgdG8gYmUgZGVmZXJyZWQuIE1lYW50IHRvIGJlIGNhbGxlZCBpbiB0aGUgc2FtZVxuICAgKiBjb21waWxhdGlvbiB1bml0IGFzIHRoZSBgRXZlbnRDb250cmFjdGAuXG4gICAqL1xuICBleHBvcnRBZGRBMTF5Q2xpY2tTdXBwb3J0KCkge1xuICAgIHRoaXMuYWRkQTExeUNsaWNrTGlzdGVuZXIgPSB0cnVlO1xuICAgIHRoaXMuZWNhYWNzID0gdGhpcy5hZGRBMTF5Q2xpY2tTdXBwb3J0SW1wbC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVuYW1lZCBmdW5jdGlvbiB0aGF0IGxvYWRzIGExMXlDbGlja1N1cHBvcnQuXG4gICAqL1xuICBwcml2YXRlIGFkZEExMXlDbGlja1N1cHBvcnRJbXBsKFxuICAgIHVwZGF0ZUV2ZW50SW5mb0ZvckExMXlDbGljazogdHlwZW9mIGExMXlDbGlja0xpYi51cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2ssXG4gICAgcHJldmVudERlZmF1bHRGb3JBMTF5Q2xpY2s6IHR5cGVvZiBhMTF5Q2xpY2tMaWIucHJldmVudERlZmF1bHRGb3JBMTF5Q2xpY2ssXG4gICAgcG9wdWxhdGVDbGlja09ubHlBY3Rpb246IHR5cGVvZiBhMTF5Q2xpY2tMaWIucG9wdWxhdGVDbGlja09ubHlBY3Rpb24sXG4gICkge1xuICAgIHRoaXMuYWRkQTExeUNsaWNrTGlzdGVuZXIgPSB0cnVlO1xuICAgIHRoaXMuaGFzQTExeUNsaWNrU3VwcG9ydCA9IHRydWU7XG4gICAgdGhpcy51cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2sgPSB1cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2s7XG4gICAgdGhpcy5wcmV2ZW50RGVmYXVsdEZvckExMXlDbGljayA9IHByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrO1xuICAgIHRoaXMucG9wdWxhdGVDbGlja09ubHlBY3Rpb24gPSBwb3B1bGF0ZUNsaWNrT25seUFjdGlvbjtcbiAgfVxufVxuXG4vKipcbiAqIEFkZHMgYTExeSBjbGljayBzdXBwb3J0IHRvIHRoZSBnaXZlbiBgRXZlbnRDb250cmFjdGAuIE1lYW50IHRvIGJlIGNhbGxlZFxuICogaW4gYSBkaWZmZXJlbnQgY29tcGlsYXRpb24gdW5pdCBmcm9tIHRoZSBgRXZlbnRDb250cmFjdGAuIFRoZSBgRXZlbnRDb250cmFjdGBcbiAqIG11c3QgaGF2ZSBjYWxsZWQgYGV4cG9ydEFkZEExMXlDbGlja1N1cHBvcnRgIGluIGl0cyBjb21waWxhdGlvbiB1bml0IGZvciB0aGlzXG4gKiB0byBoYXZlIGFueSBlZmZlY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGREZWZlcnJlZEExMXlDbGlja1N1cHBvcnQoZXZlbnRDb250cmFjdDogRXZlbnRDb250cmFjdCkge1xuICBldmVudENvbnRyYWN0LmVjYWFjcz8uKFxuICAgIGExMXlDbGlja0xpYi51cGRhdGVFdmVudEluZm9Gb3JBMTF5Q2xpY2ssXG4gICAgYTExeUNsaWNrTGliLnByZXZlbnREZWZhdWx0Rm9yQTExeUNsaWNrLFxuICAgIGExMXlDbGlja0xpYi5wb3B1bGF0ZUNsaWNrT25seUFjdGlvbixcbiAgKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRoZSBgRXZlbnRDb250cmFjdGAgbmVlZHMgdG8gY2hlY2sgd2l0aCB0aGVcbiAqIGRpc3BhdGNoZXIgZXZlbiBpZiB0aGVyZSdzIG5vIGFjdGlvbi5cbiAqL1xuZnVuY3Rpb24gY2hlY2tEaXNwYXRjaGVyRm9yQTExeUNsaWNrKGV2ZW50SW5mbzogZXZlbnRJbmZvTGliLkV2ZW50SW5mbyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIEV2ZW50Q29udHJhY3QuQTExWV9TVVBQT1JUX0lOX0RJU1BBVENIRVIgJiZcbiAgICBldmVudEluZm9MaWIuZ2V0RXZlbnRUeXBlKGV2ZW50SW5mbykgPT09IEFjY2Vzc2liaWxpdHlBdHRyaWJ1dGUuTUFZQkVfQ0xJQ0tfRVZFTlRfVFlQRVxuICApO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZGVmYXVsdCBhY3Rpb24gb2YgdGhpcyBldmVudCBzaG91bGQgYmUgcHJldmVudGVkIGJlZm9yZVxuICogdGhpcyBldmVudCBpcyBkaXNwYXRjaGVkLlxuICovXG5mdW5jdGlvbiBzaG91bGRQcmV2ZW50RGVmYXVsdEJlZm9yZURpc3BhdGNoaW5nKFxuICBhY3Rpb25FbGVtZW50OiBFbGVtZW50LFxuICBldmVudEluZm86IGV2ZW50SW5mb0xpYi5FdmVudEluZm8sXG4pOiBib29sZWFuIHtcbiAgLy8gUHJldmVudCBicm93c2VyIGZyb20gZm9sbG93aW5nIDxhPiBub2RlIGxpbmtzIGlmIGEganNhY3Rpb24gaXMgcHJlc2VudFxuICAvLyBhbmQgd2UgYXJlIGRpc3BhdGNoaW5nIHRoZSBhY3Rpb24gbm93LiBOb3RlIHRoYXQgdGhlIHRhcmdldEVsZW1lbnQgbWF5IGJlXG4gIC8vIGEgY2hpbGQgb2YgYW4gYW5jaG9yIHRoYXQgaGFzIGEganNhY3Rpb24gYXR0YWNoZWQuIEZvciB0aGF0IHJlYXNvbiwgd2VcbiAgLy8gbmVlZCB0byBjaGVjayB0aGUgYWN0aW9uRWxlbWVudCByYXRoZXIgdGhhbiB0aGUgdGFyZ2V0RWxlbWVudC5cbiAgcmV0dXJuIChcbiAgICBhY3Rpb25FbGVtZW50LnRhZ05hbWUgPT09ICdBJyAmJlxuICAgIChldmVudEluZm9MaWIuZ2V0RXZlbnRUeXBlKGV2ZW50SW5mbykgPT09IEV2ZW50VHlwZS5DTElDSyB8fFxuICAgICAgZXZlbnRJbmZvTGliLmdldEV2ZW50VHlwZShldmVudEluZm8pID09PSBFdmVudFR5cGUuQ0xJQ0tNT0QpXG4gICk7XG59XG5cbi8qKlxuICogUGFyc2VzIGFuZCBjYWNoZXMgYW4gZWxlbWVudCdzIGpzYWN0aW9uIGVsZW1lbnQgaW50byBhIG1hcC5cbiAqXG4gKiBUaGlzIGlzIHByaW1hcmlseSBmb3IgaW50ZXJuYWwgdXNlLlxuICpcbiAqIEBwYXJhbSBhY3Rpb25FbGVtZW50IFRoZSBET00gbm9kZSB0byByZXRyaWV2ZSB0aGUganNhY3Rpb24gbWFwIGZyb20uXG4gKiBAcGFyYW0gY29udGFpbmVyIFRoZSBub2RlIHdoaWNoIGxpbWl0cyB0aGUgbmFtZXNwYWNlIGxvb2t1cCBmb3IgYSBqc2FjdGlvblxuICogbmFtZS4gVGhlIGNvbnRhaW5lciBub2RlIGl0c2VsZiB3aWxsIG5vdCBiZSBzZWFyY2hlZC5cbiAqIEByZXR1cm4gTWFwIGZyb20gZXZlbnQgdG8gcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGpzYWN0aW9uIGJvdW5kIHRvIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VBY3Rpb25zKGFjdGlvbkVsZW1lbnQ6IEVsZW1lbnQsIGNvbnRhaW5lcjogTm9kZSk6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9IHtcbiAgbGV0IGFjdGlvbk1hcDoge1trZXk6IHN0cmluZ106IHN0cmluZ30gfCB1bmRlZmluZWQgPSBjYWNoZS5nZXQoYWN0aW9uRWxlbWVudCk7XG4gIGlmICghYWN0aW9uTWFwKSB7XG4gICAgY29uc3QganNhY3Rpb25BdHRyaWJ1dGUgPSBnZXRBdHRyKGFjdGlvbkVsZW1lbnQsIEF0dHJpYnV0ZS5KU0FDVElPTik7XG4gICAgaWYgKCFqc2FjdGlvbkF0dHJpYnV0ZSkge1xuICAgICAgYWN0aW9uTWFwID0gRU1QVFlfQUNUSU9OX01BUDtcbiAgICAgIGNhY2hlLnNldChhY3Rpb25FbGVtZW50LCBhY3Rpb25NYXApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY3Rpb25NYXAgPSBjYWNoZS5nZXRQYXJzZWQoanNhY3Rpb25BdHRyaWJ1dGUpO1xuICAgICAgaWYgKCFhY3Rpb25NYXApIHtcbiAgICAgICAgYWN0aW9uTWFwID0ge307XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGpzYWN0aW9uQXR0cmlidXRlLnNwbGl0KFJFR0VYUF9TRU1JQ09MT04pO1xuICAgICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCB2YWx1ZXMubGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW2lkeF07XG4gICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGNvbG9uID0gdmFsdWUuaW5kZXhPZihDaGFyLkVWRU5UX0FDVElPTl9TRVBBUkFUT1IpO1xuICAgICAgICAgIGNvbnN0IGhhc0NvbG9uID0gY29sb24gIT09IC0xO1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBoYXNDb2xvbiA/IHN0cmluZ1RyaW0odmFsdWUuc3Vic3RyKDAsIGNvbG9uKSkgOiBERUZBVUxUX0VWRU5UX1RZUEU7XG4gICAgICAgICAgY29uc3QgYWN0aW9uID0gaGFzQ29sb24gPyBzdHJpbmdUcmltKHZhbHVlLnN1YnN0cihjb2xvbiArIDEpKSA6IHZhbHVlO1xuICAgICAgICAgIGFjdGlvbk1hcFt0eXBlXSA9IGFjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBjYWNoZS5zZXRQYXJzZWQoanNhY3Rpb25BdHRyaWJ1dGUsIGFjdGlvbk1hcCk7XG4gICAgICB9XG4gICAgICAvLyBJZiBuYW1lc3BhY2Ugc3VwcG9ydCBpcyBhY3RpdmUgd2UgbmVlZCB0byBhdWdtZW50IHRoZSAocG90ZW50aWFsbHlcbiAgICAgIC8vIGNhY2hlZCkganNhY3Rpb24gbWFwcGluZyB3aXRoIHRoZSBuYW1lc3BhY2UuXG4gICAgICBpZiAoRXZlbnRDb250cmFjdC5KU05BTUVTUEFDRV9TVVBQT1JUKSB7XG4gICAgICAgIGNvbnN0IG5vTnMgPSBhY3Rpb25NYXA7XG4gICAgICAgIGFjdGlvbk1hcCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHR5cGUgaW4gbm9Ocykge1xuICAgICAgICAgIGFjdGlvbk1hcFt0eXBlXSA9IGdldEZ1bGx5UXVhbGlmaWVkQWN0aW9uKG5vTnNbdHlwZV0sIGFjdGlvbkVsZW1lbnQsIGNvbnRhaW5lcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNhY2hlLnNldChhY3Rpb25FbGVtZW50LCBhY3Rpb25NYXApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYWN0aW9uTWFwO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBqc2FjdGlvbiBhY3Rpb24uIElmIHRoZSBnaXZlbiBqc2FjdGlvblxuICogbmFtZSBkb2Vzbid0IGFscmVhZHkgY29udGFpbiB0aGUgbmFtZXNwYWNlLCB0aGUgZnVuY3Rpb24gaXRlcmF0ZXNcbiAqIG92ZXIgYW5jZXN0b3Igbm9kZXMgdW50aWwgYSBqc25hbWVzcGFjZSBhdHRyaWJ1dGUgaXMgZm91bmQsIGFuZFxuICogdXNlcyB0aGUgdmFsdWUgb2YgdGhhdCBhdHRyaWJ1dGUgYXMgdGhlIG5hbWVzcGFjZS5cbiAqXG4gKiBAcGFyYW0gYWN0aW9uIFRoZSBqc2FjdGlvbiBhY3Rpb24gdG8gcmVzb2x2ZS5cbiAqIEBwYXJhbSBzdGFydCBUaGUgbm9kZSBmcm9tIHdoaWNoIHRvIHN0YXJ0IHNlYXJjaGluZyBmb3IgYSBqc25hbWVzcGFjZVxuICogYXR0cmlidXRlLlxuICogQHBhcmFtIGNvbnRhaW5lciBUaGUgbm9kZSB3aGljaCBsaW1pdHMgdGhlIHNlYXJjaCBmb3IgYSBqc25hbWVzcGFjZVxuICogYXR0cmlidXRlLiBUaGlzIG5vZGUgd2lsbCBiZSBzZWFyY2hlZC5cbiAqIEByZXR1cm4gVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBqc2FjdGlvbi4gSWYgbm8gbmFtZXNwYWNlIGlzIGZvdW5kLFxuICogcmV0dXJucyB0aGUgdW5xdWFsaWZpZWQgbmFtZSBpbiBjYXNlIGl0IGV4aXN0cyBpbiB0aGUgZ2xvYmFsIG5hbWVzcGFjZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RnVsbHlRdWFsaWZpZWRBY3Rpb24oYWN0aW9uOiBzdHJpbmcsIHN0YXJ0OiBFbGVtZW50LCBjb250YWluZXI6IE5vZGUpOiBzdHJpbmcge1xuICBpZiAoRXZlbnRDb250cmFjdC5KU05BTUVTUEFDRV9TVVBQT1JUKSB7XG4gICAgaWYgKGlzTmFtZXNwYWNlZEFjdGlvbihhY3Rpb24pKSB7XG4gICAgICByZXR1cm4gYWN0aW9uO1xuICAgIH1cblxuICAgIGxldCBub2RlOiBOb2RlIHwgbnVsbCA9IHN0YXJ0O1xuICAgIHdoaWxlIChub2RlKSB7XG4gICAgICBjb25zdCBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VGcm9tRWxlbWVudChub2RlIGFzIEVsZW1lbnQpO1xuICAgICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICByZXR1cm4gbmFtZXNwYWNlICsgQ2hhci5OQU1FU1BBQ0VfQUNUSU9OX1NFUEFSQVRPUiArIGFjdGlvbjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhpcyBub2RlIGlzIHRoZSBjb250YWluZXIsIHN0b3AuXG4gICAgICBpZiAobm9kZSA9PT0gY29udGFpbmVyKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhY3Rpb247XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEganNhY3Rpb24gYWN0aW9uIGNvbnRhaW5zIGEgbmFtZXNwYWNlIHBhcnQuXG4gKi9cbmZ1bmN0aW9uIGlzTmFtZXNwYWNlZEFjdGlvbihhY3Rpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gYWN0aW9uLmluZGV4T2YoQ2hhci5OQU1FU1BBQ0VfQUNUSU9OX1NFUEFSQVRPUikgPj0gMDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUganNuYW1lc3BhY2UgYXR0cmlidXRlIG9mIHRoZSBnaXZlbiBub2RlLlxuICogQWxzbyBjYWNoZXMgdGhlIHZhbHVlIGZvciBzdWJzZXF1ZW50IGxvb2t1cHMuXG4gKiBAcGFyYW0gZWxlbWVudCBUaGUgbm9kZSB3aG9zZSBqc25hbWVzcGFjZSBhdHRyaWJ1dGUgaXMgYmVpbmcgYXNrZWQgZm9yLlxuICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIGpzbmFtZXNwYWNlIGF0dHJpYnV0ZSwgb3IgbnVsbCBpZiBub3QgZm91bmQuXG4gKi9cbmZ1bmN0aW9uIGdldE5hbWVzcGFjZUZyb21FbGVtZW50KGVsZW1lbnQ6IEVsZW1lbnQpOiBzdHJpbmcgfCBudWxsIHtcbiAgbGV0IG5hbWVzcGFjZSA9IGNhY2hlLmdldE5hbWVzcGFjZShlbGVtZW50KTtcbiAgLy8gT25seSBxdWVyeSBmb3IgdGhlIGF0dHJpYnV0ZSBpZiBpdCBoYXMgbm90IGJlZW4gcXVlcmllZCBmb3JcbiAgLy8gYmVmb3JlLiBnZXRBdHRyKCkgcmV0dXJucyBudWxsIGlmIGFuIGF0dHJpYnV0ZSBpcyBub3QgcHJlc2VudC4gVGh1cyxcbiAgLy8gbmFtZXNwYWNlIGlzIHN0cmluZ3xudWxsIGlmIHRoZSBxdWVyeSB0b29rIHBsYWNlIGluIHRoZSBwYXN0LCBvclxuICAvLyB1bmRlZmluZWQgaWYgdGhlIHF1ZXJ5IGRpZCBub3QgdGFrZSBwbGFjZS5cbiAgaWYgKG5hbWVzcGFjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbmFtZXNwYWNlID0gZ2V0QXR0cihlbGVtZW50LCBBdHRyaWJ1dGUuSlNOQU1FU1BBQ0UpO1xuICAgIGNhY2hlLnNldE5hbWVzcGFjZShlbGVtZW50LCBuYW1lc3BhY2UpO1xuICB9XG4gIHJldHVybiBuYW1lc3BhY2U7XG59XG5cbi8qKlxuICogQWNjZXNzZXMgdGhlIGV2ZW50IGhhbmRsZXIgYXR0cmlidXRlIHZhbHVlIG9mIGEgRE9NIG5vZGUuIEl0IGd1YXJkc1xuICogYWdhaW5zdCB3ZWlyZCBzaXR1YXRpb25zIChkZXNjcmliZWQgaW4gdGhlIGJvZHkpIHRoYXQgb2NjdXIgaW5cbiAqIGNvbm5lY3Rpb24gd2l0aCBub2RlcyB0aGF0IGFyZSByZW1vdmVkIGZyb20gdGhlaXIgZG9jdW1lbnQuXG4gKiBAcGFyYW0gZWxlbWVudCBUaGUgRE9NIGVsZW1lbnQuXG4gKiBAcGFyYW0gYXR0cmlidXRlIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gYWNjZXNzLlxuICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGlmIGl0IHdhcyBmb3VuZCwgbnVsbCBvdGhlcndpc2UuXG4gKi9cbmZ1bmN0aW9uIGdldEF0dHIoZWxlbWVudDogRWxlbWVudCwgYXR0cmlidXRlOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgbGV0IHZhbHVlID0gbnVsbDtcbiAgLy8gTk9URTogTm9kZXMgaW4gSUUgZG8gbm90IGFsd2F5cyBoYXZlIGEgZ2V0QXR0cmlidXRlXG4gIC8vIG1ldGhvZCBkZWZpbmVkLiBUaGlzIGlzIHRoZSBjYXNlIHdoZXJlIHNvdXJjZUVsZW1lbnQgaGFzIGluXG4gIC8vIGZhY3QgYmVlbiByZW1vdmVkIGZyb20gdGhlIERPTSBiZWZvcmUgZXZlbnRDb250cmFjdCBiZWdpbnNcbiAgLy8gaGFuZGxpbmcgLSB3aGVyZSBhIHBhcmVudE5vZGUgZG9lcyBub3QgaGF2ZSBnZXRBdHRyaWJ1dGVcbiAgLy8gZGVmaW5lZC5cbiAgLy8gTk9URTogV2UgbXVzdCB1c2UgdGhlICdpbicgb3BlcmF0b3IgaW5zdGVhZCBvZiB0aGUgcmVndWxhciBkb3RcbiAgLy8gbm90YXRpb24sIHNpbmNlIHRoZSBsYXR0ZXIgZmFpbHMgaW4gSUU4IGlmIHRoZSBnZXRBdHRyaWJ1dGUgbWV0aG9kIGlzIG5vdFxuICAvLyBkZWZpbmVkLiBTZWUgYi83MTM5MTA5LlxuICBpZiAoJ2dldEF0dHJpYnV0ZScgaW4gZWxlbWVudCkge1xuICAgIHZhbHVlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIHRyaW0gd2hpdGVzcGFjZSBmcm9tIHRoZSBiZWdpbm5pbmcgYW5kIHRoZSBlbmRcbiAqIG9mIHRoZSBzdHJpbmcuIFRoaXMgZGVsaWJlcmF0ZWx5IGRvZXNuJ3QgdXNlIHRoZSBjbG9zdXJlIGVxdWl2YWxlbnRcbiAqIHRvIGtlZXAgZGVwZW5kZW5jaWVzIHNtYWxsLlxuICogQHBhcmFtIHN0ciAgSW5wdXQgc3RyaW5nLlxuICogQHJldHVybiAgVHJpbW1lZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ1RyaW0oc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIFN0cmluZy5wcm90b3R5cGUudHJpbSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBzdHIudHJpbSgpO1xuICB9XG5cbiAgY29uc3QgdHJpbW1lZExlZnQgPSBzdHIucmVwbGFjZSgvXlxccysvLCAnJyk7XG4gIHJldHVybiB0cmltbWVkTGVmdC5yZXBsYWNlKC9cXHMrJC8sICcnKTtcbn1cbiJdfQ==