UNPKG

95.2 kBJavaScriptView Raw
1import { assertTNodeForLView } from '../render3/assert';
2import { getLContext } from '../render3/context_discovery';
3import { CONTAINER_HEADER_OFFSET, NATIVE } from '../render3/interfaces/container';
4import { isComponentHost, isLContainer } from '../render3/interfaces/type_checks';
5import { DECLARATION_COMPONENT_VIEW, PARENT, T_HOST, TVIEW } from '../render3/interfaces/view';
6import { getComponent, getContext, getInjectionTokens, getInjector, getListeners, getLocalRefs, getOwningComponent } from '../render3/util/discovery_utils';
7import { INTERPOLATION_DELIMITER } from '../render3/util/misc_utils';
8import { renderStringify } from '../render3/util/stringify_utils';
9import { getComponentLViewByIndex, getNativeByTNodeOrNull } from '../render3/util/view_utils';
10import { assertDomNode } from '../util/assert';
11/**
12 * @publicApi
13 */
14export class DebugEventListener {
15 constructor(name, callback) {
16 this.name = name;
17 this.callback = callback;
18 }
19}
20export class DebugNode__PRE_R3__ {
21 constructor(nativeNode, parent, _debugContext) {
22 this.listeners = [];
23 this.parent = null;
24 this._debugContext = _debugContext;
25 this.nativeNode = nativeNode;
26 if (parent && parent instanceof DebugElement__PRE_R3__) {
27 parent.addChild(this);
28 }
29 }
30 get injector() {
31 return this._debugContext.injector;
32 }
33 get componentInstance() {
34 return this._debugContext.component;
35 }
36 get context() {
37 return this._debugContext.context;
38 }
39 get references() {
40 return this._debugContext.references;
41 }
42 get providerTokens() {
43 return this._debugContext.providerTokens;
44 }
45}
46export class DebugElement__PRE_R3__ extends DebugNode__PRE_R3__ {
47 constructor(nativeNode, parent, _debugContext) {
48 super(nativeNode, parent, _debugContext);
49 this.properties = {};
50 this.attributes = {};
51 this.classes = {};
52 this.styles = {};
53 this.childNodes = [];
54 this.nativeElement = nativeNode;
55 }
56 addChild(child) {
57 if (child) {
58 this.childNodes.push(child);
59 child.parent = this;
60 }
61 }
62 removeChild(child) {
63 const childIndex = this.childNodes.indexOf(child);
64 if (childIndex !== -1) {
65 child.parent = null;
66 this.childNodes.splice(childIndex, 1);
67 }
68 }
69 insertChildrenAfter(child, newChildren) {
70 const siblingIndex = this.childNodes.indexOf(child);
71 if (siblingIndex !== -1) {
72 this.childNodes.splice(siblingIndex + 1, 0, ...newChildren);
73 newChildren.forEach(c => {
74 if (c.parent) {
75 c.parent.removeChild(c);
76 }
77 child.parent = this;
78 });
79 }
80 }
81 insertBefore(refChild, newChild) {
82 const refIndex = this.childNodes.indexOf(refChild);
83 if (refIndex === -1) {
84 this.addChild(newChild);
85 }
86 else {
87 if (newChild.parent) {
88 newChild.parent.removeChild(newChild);
89 }
90 newChild.parent = this;
91 this.childNodes.splice(refIndex, 0, newChild);
92 }
93 }
94 query(predicate) {
95 const results = this.queryAll(predicate);
96 return results[0] || null;
97 }
98 queryAll(predicate) {
99 const matches = [];
100 _queryElementChildren(this, predicate, matches);
101 return matches;
102 }
103 queryAllNodes(predicate) {
104 const matches = [];
105 _queryNodeChildren(this, predicate, matches);
106 return matches;
107 }
108 get children() {
109 return this.childNodes //
110 .filter((node) => node instanceof DebugElement__PRE_R3__);
111 }
112 triggerEventHandler(eventName, eventObj) {
113 this.listeners.forEach((listener) => {
114 if (listener.name == eventName) {
115 listener.callback(eventObj);
116 }
117 });
118 }
119}
120/**
121 * @publicApi
122 */
123export function asNativeElements(debugEls) {
124 return debugEls.map((el) => el.nativeElement);
125}
126function _queryElementChildren(element, predicate, matches) {
127 element.childNodes.forEach(node => {
128 if (node instanceof DebugElement__PRE_R3__) {
129 if (predicate(node)) {
130 matches.push(node);
131 }
132 _queryElementChildren(node, predicate, matches);
133 }
134 });
135}
136function _queryNodeChildren(parentNode, predicate, matches) {
137 if (parentNode instanceof DebugElement__PRE_R3__) {
138 parentNode.childNodes.forEach(node => {
139 if (predicate(node)) {
140 matches.push(node);
141 }
142 if (node instanceof DebugElement__PRE_R3__) {
143 _queryNodeChildren(node, predicate, matches);
144 }
145 });
146 }
147}
148class DebugNode__POST_R3__ {
149 constructor(nativeNode) {
150 this.nativeNode = nativeNode;
151 }
152 get parent() {
153 const parent = this.nativeNode.parentNode;
154 return parent ? new DebugElement__POST_R3__(parent) : null;
155 }
156 get injector() {
157 return getInjector(this.nativeNode);
158 }
159 get componentInstance() {
160 const nativeElement = this.nativeNode;
161 return nativeElement &&
162 (getComponent(nativeElement) || getOwningComponent(nativeElement));
163 }
164 get context() {
165 return getComponent(this.nativeNode) || getContext(this.nativeNode);
166 }
167 get listeners() {
168 return getListeners(this.nativeNode).filter(listener => listener.type === 'dom');
169 }
170 get references() {
171 return getLocalRefs(this.nativeNode);
172 }
173 get providerTokens() {
174 return getInjectionTokens(this.nativeNode);
175 }
176}
177class DebugElement__POST_R3__ extends DebugNode__POST_R3__ {
178 constructor(nativeNode) {
179 ngDevMode && assertDomNode(nativeNode);
180 super(nativeNode);
181 }
182 get nativeElement() {
183 return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode : null;
184 }
185 get name() {
186 const context = getLContext(this.nativeNode);
187 if (context !== null) {
188 const lView = context.lView;
189 const tData = lView[TVIEW].data;
190 const tNode = tData[context.nodeIndex];
191 return tNode.value;
192 }
193 else {
194 return this.nativeNode.nodeName;
195 }
196 }
197 /**
198 * Gets a map of property names to property values for an element.
199 *
200 * This map includes:
201 * - Regular property bindings (e.g. `[id]="id"`)
202 * - Host property bindings (e.g. `host: { '[id]': "id" }`)
203 * - Interpolated property bindings (e.g. `id="{{ value }}")
204 *
205 * It does not include:
206 * - input property bindings (e.g. `[myCustomInput]="value"`)
207 * - attribute bindings (e.g. `[attr.role]="menu"`)
208 */
209 get properties() {
210 const context = getLContext(this.nativeNode);
211 if (context === null) {
212 return {};
213 }
214 const lView = context.lView;
215 const tData = lView[TVIEW].data;
216 const tNode = tData[context.nodeIndex];
217 const properties = {};
218 // Collect properties from the DOM.
219 copyDomProperties(this.nativeElement, properties);
220 // Collect properties from the bindings. This is needed for animation renderer which has
221 // synthetic properties which don't get reflected into the DOM.
222 collectPropertyBindings(properties, tNode, lView, tData);
223 return properties;
224 }
225 get attributes() {
226 const attributes = {};
227 const element = this.nativeElement;
228 if (!element) {
229 return attributes;
230 }
231 const context = getLContext(element);
232 if (context === null) {
233 return {};
234 }
235 const lView = context.lView;
236 const tNodeAttrs = lView[TVIEW].data[context.nodeIndex].attrs;
237 const lowercaseTNodeAttrs = [];
238 // For debug nodes we take the element's attribute directly from the DOM since it allows us
239 // to account for ones that weren't set via bindings (e.g. ViewEngine keeps track of the ones
240 // that are set through `Renderer2`). The problem is that the browser will lowercase all names,
241 // however since we have the attributes already on the TNode, we can preserve the case by going
242 // through them once, adding them to the `attributes` map and putting their lower-cased name
243 // into an array. Afterwards when we're going through the native DOM attributes, we can check
244 // whether we haven't run into an attribute already through the TNode.
245 if (tNodeAttrs) {
246 let i = 0;
247 while (i < tNodeAttrs.length) {
248 const attrName = tNodeAttrs[i];
249 // Stop as soon as we hit a marker. We only care about the regular attributes. Everything
250 // else will be handled below when we read the final attributes off the DOM.
251 if (typeof attrName !== 'string')
252 break;
253 const attrValue = tNodeAttrs[i + 1];
254 attributes[attrName] = attrValue;
255 lowercaseTNodeAttrs.push(attrName.toLowerCase());
256 i += 2;
257 }
258 }
259 const eAttrs = element.attributes;
260 for (let i = 0; i < eAttrs.length; i++) {
261 const attr = eAttrs[i];
262 const lowercaseName = attr.name.toLowerCase();
263 // Make sure that we don't assign the same attribute both in its
264 // case-sensitive form and the lower-cased one from the browser.
265 if (lowercaseTNodeAttrs.indexOf(lowercaseName) === -1) {
266 // Save the lowercase name to align the behavior between browsers.
267 // IE preserves the case, while all other browser convert it to lower case.
268 attributes[lowercaseName] = attr.value;
269 }
270 }
271 return attributes;
272 }
273 get styles() {
274 if (this.nativeElement && this.nativeElement.style) {
275 return this.nativeElement.style;
276 }
277 return {};
278 }
279 get classes() {
280 const result = {};
281 const element = this.nativeElement;
282 // SVG elements return an `SVGAnimatedString` instead of a plain string for the `className`.
283 const className = element.className;
284 const classes = typeof className !== 'string' ? className.baseVal.split(' ') : className.split(' ');
285 classes.forEach((value) => result[value] = true);
286 return result;
287 }
288 get childNodes() {
289 const childNodes = this.nativeNode.childNodes;
290 const children = [];
291 for (let i = 0; i < childNodes.length; i++) {
292 const element = childNodes[i];
293 children.push(getDebugNode__POST_R3__(element));
294 }
295 return children;
296 }
297 get children() {
298 const nativeElement = this.nativeElement;
299 if (!nativeElement)
300 return [];
301 const childNodes = nativeElement.children;
302 const children = [];
303 for (let i = 0; i < childNodes.length; i++) {
304 const element = childNodes[i];
305 children.push(getDebugNode__POST_R3__(element));
306 }
307 return children;
308 }
309 query(predicate) {
310 const results = this.queryAll(predicate);
311 return results[0] || null;
312 }
313 queryAll(predicate) {
314 const matches = [];
315 _queryAllR3(this, predicate, matches, true);
316 return matches;
317 }
318 queryAllNodes(predicate) {
319 const matches = [];
320 _queryAllR3(this, predicate, matches, false);
321 return matches;
322 }
323 triggerEventHandler(eventName, eventObj) {
324 const node = this.nativeNode;
325 const invokedListeners = [];
326 this.listeners.forEach(listener => {
327 if (listener.name === eventName) {
328 const callback = listener.callback;
329 callback.call(node, eventObj);
330 invokedListeners.push(callback);
331 }
332 });
333 // We need to check whether `eventListeners` exists, because it's something
334 // that Zone.js only adds to `EventTarget` in browser environments.
335 if (typeof node.eventListeners === 'function') {
336 // Note that in Ivy we wrap event listeners with a call to `event.preventDefault` in some
337 // cases. We use '__ngUnwrap__' as a special token that gives us access to the actual event
338 // listener.
339 node.eventListeners(eventName).forEach((listener) => {
340 // In order to ensure that we can detect the special __ngUnwrap__ token described above, we
341 // use `toString` on the listener and see if it contains the token. We use this approach to
342 // ensure that it still worked with compiled code since it cannot remove or rename string
343 // literals. We also considered using a special function name (i.e. if(listener.name ===
344 // special)) but that was more cumbersome and we were also concerned the compiled code could
345 // strip the name, turning the condition in to ("" === "") and always returning true.
346 if (listener.toString().indexOf('__ngUnwrap__') !== -1) {
347 const unwrappedListener = listener('__ngUnwrap__');
348 return invokedListeners.indexOf(unwrappedListener) === -1 &&
349 unwrappedListener.call(node, eventObj);
350 }
351 });
352 }
353 }
354}
355function copyDomProperties(element, properties) {
356 if (element) {
357 // Skip own properties (as those are patched)
358 let obj = Object.getPrototypeOf(element);
359 const NodePrototype = Node.prototype;
360 while (obj !== null && obj !== NodePrototype) {
361 const descriptors = Object.getOwnPropertyDescriptors(obj);
362 for (let key in descriptors) {
363 if (!key.startsWith('__') && !key.startsWith('on')) {
364 // don't include properties starting with `__` and `on`.
365 // `__` are patched values which should not be included.
366 // `on` are listeners which also should not be included.
367 const value = element[key];
368 if (isPrimitiveValue(value)) {
369 properties[key] = value;
370 }
371 }
372 }
373 obj = Object.getPrototypeOf(obj);
374 }
375 }
376}
377function isPrimitiveValue(value) {
378 return typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' ||
379 value === null;
380}
381function _queryAllR3(parentElement, predicate, matches, elementsOnly) {
382 const context = getLContext(parentElement.nativeNode);
383 if (context !== null) {
384 const parentTNode = context.lView[TVIEW].data[context.nodeIndex];
385 _queryNodeChildrenR3(parentTNode, context.lView, predicate, matches, elementsOnly, parentElement.nativeNode);
386 }
387 else {
388 // If the context is null, then `parentElement` was either created with Renderer2 or native DOM
389 // APIs.
390 _queryNativeNodeDescendants(parentElement.nativeNode, predicate, matches, elementsOnly);
391 }
392}
393/**
394 * Recursively match the current TNode against the predicate, and goes on with the next ones.
395 *
396 * @param tNode the current TNode
397 * @param lView the LView of this TNode
398 * @param predicate the predicate to match
399 * @param matches the list of positive matches
400 * @param elementsOnly whether only elements should be searched
401 * @param rootNativeNode the root native node on which predicate should not be matched
402 */
403function _queryNodeChildrenR3(tNode, lView, predicate, matches, elementsOnly, rootNativeNode) {
404 ngDevMode && assertTNodeForLView(tNode, lView);
405 const nativeNode = getNativeByTNodeOrNull(tNode, lView);
406 // For each type of TNode, specific logic is executed.
407 if (tNode.type & (3 /* AnyRNode */ | 8 /* ElementContainer */)) {
408 // Case 1: the TNode is an element
409 // The native node has to be checked.
410 _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
411 if (isComponentHost(tNode)) {
412 // If the element is the host of a component, then all nodes in its view have to be processed.
413 // Note: the component's content (tNode.child) will be processed from the insertion points.
414 const componentView = getComponentLViewByIndex(tNode.index, lView);
415 if (componentView && componentView[TVIEW].firstChild) {
416 _queryNodeChildrenR3(componentView[TVIEW].firstChild, componentView, predicate, matches, elementsOnly, rootNativeNode);
417 }
418 }
419 else {
420 if (tNode.child) {
421 // Otherwise, its children have to be processed.
422 _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
423 }
424 // We also have to query the DOM directly in order to catch elements inserted through
425 // Renderer2. Note that this is __not__ optimal, because we're walking similar trees multiple
426 // times. ViewEngine could do it more efficiently, because all the insertions go through
427 // Renderer2, however that's not the case in Ivy. This approach is being used because:
428 // 1. Matching the ViewEngine behavior would mean potentially introducing a depedency
429 // from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
430 // 2. We would have to make `Renderer3` "know" about debug nodes.
431 // 3. It allows us to capture nodes that were inserted directly via the DOM.
432 nativeNode && _queryNativeNodeDescendants(nativeNode, predicate, matches, elementsOnly);
433 }
434 // In all cases, if a dynamic container exists for this node, each view inside it has to be
435 // processed.
436 const nodeOrContainer = lView[tNode.index];
437 if (isLContainer(nodeOrContainer)) {
438 _queryNodeChildrenInContainerR3(nodeOrContainer, predicate, matches, elementsOnly, rootNativeNode);
439 }
440 }
441 else if (tNode.type & 4 /* Container */) {
442 // Case 2: the TNode is a container
443 // The native node has to be checked.
444 const lContainer = lView[tNode.index];
445 _addQueryMatchR3(lContainer[NATIVE], predicate, matches, elementsOnly, rootNativeNode);
446 // Each view inside the container has to be processed.
447 _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode);
448 }
449 else if (tNode.type & 16 /* Projection */) {
450 // Case 3: the TNode is a projection insertion point (i.e. a <ng-content>).
451 // The nodes projected at this location all need to be processed.
452 const componentView = lView[DECLARATION_COMPONENT_VIEW];
453 const componentHost = componentView[T_HOST];
454 const head = componentHost.projection[tNode.projection];
455 if (Array.isArray(head)) {
456 for (let nativeNode of head) {
457 _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
458 }
459 }
460 else if (head) {
461 const nextLView = componentView[PARENT];
462 const nextTNode = nextLView[TVIEW].data[head.index];
463 _queryNodeChildrenR3(nextTNode, nextLView, predicate, matches, elementsOnly, rootNativeNode);
464 }
465 }
466 else if (tNode.child) {
467 // Case 4: the TNode is a view.
468 _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
469 }
470 // We don't want to go to the next sibling of the root node.
471 if (rootNativeNode !== nativeNode) {
472 // To determine the next node to be processed, we need to use the next or the projectionNext
473 // link, depending on whether the current node has been projected.
474 const nextTNode = (tNode.flags & 4 /* isProjected */) ? tNode.projectionNext : tNode.next;
475 if (nextTNode) {
476 _queryNodeChildrenR3(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
477 }
478 }
479}
480/**
481 * Process all TNodes in a given container.
482 *
483 * @param lContainer the container to be processed
484 * @param predicate the predicate to match
485 * @param matches the list of positive matches
486 * @param elementsOnly whether only elements should be searched
487 * @param rootNativeNode the root native node on which predicate should not be matched
488 */
489function _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode) {
490 for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
491 const childView = lContainer[i];
492 const firstChild = childView[TVIEW].firstChild;
493 if (firstChild) {
494 _queryNodeChildrenR3(firstChild, childView, predicate, matches, elementsOnly, rootNativeNode);
495 }
496 }
497}
498/**
499 * Match the current native node against the predicate.
500 *
501 * @param nativeNode the current native node
502 * @param predicate the predicate to match
503 * @param matches the list of positive matches
504 * @param elementsOnly whether only elements should be searched
505 * @param rootNativeNode the root native node on which predicate should not be matched
506 */
507function _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode) {
508 if (rootNativeNode !== nativeNode) {
509 const debugNode = getDebugNode(nativeNode);
510 if (!debugNode) {
511 return;
512 }
513 // Type of the "predicate and "matches" array are set based on the value of
514 // the "elementsOnly" parameter. TypeScript is not able to properly infer these
515 // types with generics, so we manually cast the parameters accordingly.
516 if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
517 matches.indexOf(debugNode) === -1) {
518 matches.push(debugNode);
519 }
520 else if (!elementsOnly && predicate(debugNode) &&
521 matches.indexOf(debugNode) === -1) {
522 matches.push(debugNode);
523 }
524 }
525}
526/**
527 * Match all the descendants of a DOM node against a predicate.
528 *
529 * @param nativeNode the current native node
530 * @param predicate the predicate to match
531 * @param matches the list where matches are stored
532 * @param elementsOnly whether only elements should be searched
533 */
534function _queryNativeNodeDescendants(parentNode, predicate, matches, elementsOnly) {
535 const nodes = parentNode.childNodes;
536 const length = nodes.length;
537 for (let i = 0; i < length; i++) {
538 const node = nodes[i];
539 const debugNode = getDebugNode(node);
540 if (debugNode) {
541 if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
542 matches.indexOf(debugNode) === -1) {
543 matches.push(debugNode);
544 }
545 else if (!elementsOnly && predicate(debugNode) &&
546 matches.indexOf(debugNode) === -1) {
547 matches.push(debugNode);
548 }
549 _queryNativeNodeDescendants(node, predicate, matches, elementsOnly);
550 }
551 }
552}
553/**
554 * Iterates through the property bindings for a given node and generates
555 * a map of property names to values. This map only contains property bindings
556 * defined in templates, not in host bindings.
557 */
558function collectPropertyBindings(properties, tNode, lView, tData) {
559 let bindingIndexes = tNode.propertyBindings;
560 if (bindingIndexes !== null) {
561 for (let i = 0; i < bindingIndexes.length; i++) {
562 const bindingIndex = bindingIndexes[i];
563 const propMetadata = tData[bindingIndex];
564 const metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
565 const propertyName = metadataParts[0];
566 if (metadataParts.length > 1) {
567 let value = metadataParts[1];
568 for (let j = 1; j < metadataParts.length - 1; j++) {
569 value += renderStringify(lView[bindingIndex + j - 1]) + metadataParts[j + 1];
570 }
571 properties[propertyName] = value;
572 }
573 else {
574 properties[propertyName] = lView[bindingIndex];
575 }
576 }
577 }
578}
579// Need to keep the nodes in a global Map so that multiple angular apps are supported.
580const _nativeNodeToDebugNode = new Map();
581function getDebugNode__PRE_R3__(nativeNode) {
582 return _nativeNodeToDebugNode.get(nativeNode) || null;
583}
584const NG_DEBUG_PROPERTY = '__ng_debug__';
585export function getDebugNode__POST_R3__(nativeNode) {
586 if (nativeNode instanceof Node) {
587 if (!(nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY))) {
588 nativeNode[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ?
589 new DebugElement__POST_R3__(nativeNode) :
590 new DebugNode__POST_R3__(nativeNode);
591 }
592 return nativeNode[NG_DEBUG_PROPERTY];
593 }
594 return null;
595}
596/**
597 * @publicApi
598 */
599export const getDebugNode = getDebugNode__POST_R3__;
600export function getDebugNodeR2__PRE_R3__(nativeNode) {
601 return getDebugNode__PRE_R3__(nativeNode);
602}
603export function getDebugNodeR2__POST_R3__(_nativeNode) {
604 return null;
605}
606export const getDebugNodeR2 = getDebugNodeR2__POST_R3__;
607export function getAllDebugNodes() {
608 return Array.from(_nativeNodeToDebugNode.values());
609}
610export function indexDebugNode(node) {
611 _nativeNodeToDebugNode.set(node.nativeNode, node);
612}
613export function removeDebugNodeFromIndex(node) {
614 _nativeNodeToDebugNode.delete(node.nativeNode);
615}
616/**
617 * @publicApi
618 */
619export const DebugNode = DebugNode__POST_R3__;
620/**
621 * @publicApi
622 */
623export const DebugElement = DebugElement__POST_R3__;
624//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWdfbm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL2RlYnVnL2RlYnVnX25vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBU0EsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQ3pELE9BQU8sRUFBQyx1QkFBdUIsRUFBYyxNQUFNLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUU1RixPQUFPLEVBQUMsZUFBZSxFQUFFLFlBQVksRUFBQyxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hGLE9BQU8sRUFBQywwQkFBMEIsRUFBUyxNQUFNLEVBQUUsTUFBTSxFQUFTLEtBQUssRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQzNHLE9BQU8sRUFBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLGtCQUFrQixFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFDMUosT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDbkUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGlDQUFpQyxDQUFDO0FBQ2hFLE9BQU8sRUFBQyx3QkFBd0IsRUFBRSxzQkFBc0IsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQzVGLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUk3Qzs7R0FFRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsWUFBbUIsSUFBWSxFQUFTLFFBQWtCO1FBQXZDLFNBQUksR0FBSixJQUFJLENBQVE7UUFBUyxhQUFRLEdBQVIsUUFBUSxDQUFVO0lBQUcsQ0FBQztDQUMvRDtBQXNERCxNQUFNLE9BQU8sbUJBQW1CO0lBTTlCLFlBQVksVUFBZSxFQUFFLE1BQXNCLEVBQUUsYUFB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QUFVLENBQUMsQ0FBQztBQUNqRCxDQUFDO0FBWUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBN2pCaEIsb0JBNmpCeUUsQ0FBQztBQUVoRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFlBQVksR0E1aEJuQix1QkE0aEJrRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7SW5qZWN0b3J9IGZyb20gJy4uL2RpL2luamVjdG9yJztcbmltcG9ydCB7YXNzZXJ0VE5vZGVGb3JMVmlld30gZnJvbSAnLi4vcmVuZGVyMy9hc3NlcnQnO1xuaW1wb3J0IHtnZXRMQ29udGV4dH0gZnJvbSAnLi4vcmVuZGVyMy9jb250ZXh0X2Rpc2NvdmVyeSc7XG5pbXBvcnQge0NPTlRBSU5FUl9IRUFERVJfT0ZGU0VULCBMQ29udGFpbmVyLCBOQVRJVkV9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy9jb250YWluZXInO1xuaW1wb3J0IHtURWxlbWVudE5vZGUsIFROb2RlLCBUTm9kZUZsYWdzLCBUTm9kZVR5cGV9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7aXNDb21wb25lbnRIb3N0LCBpc0xDb250YWluZXJ9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy90eXBlX2NoZWNrcyc7XG5pbXBvcnQge0RFQ0xBUkFUSU9OX0NPTVBPTkVOVF9WSUVXLCBMVmlldywgUEFSRU5ULCBUX0hPU1QsIFREYXRhLCBUVklFV30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtnZXRDb21wb25lbnQsIGdldENvbnRleHQsIGdldEluamVjdGlvblRva2VucywgZ2V0SW5qZWN0b3IsIGdldExpc3RlbmVycywgZ2V0TG9jYWxSZWZzLCBnZXRPd25pbmdDb21wb25lbnR9IGZyb20gJy4uL3JlbmRlcjMvdXRpbC9kaXNjb3ZlcnlfdXRpbHMnO1xuaW1wb3J0IHtJTlRFUlBPTEFUSU9OX0RFTElNSVRFUn0gZnJvbSAnLi4vcmVuZGVyMy91dGlsL21pc2NfdXRpbHMnO1xuaW1wb3J0IHtyZW5kZXJTdHJpbmdpZnl9IGZyb20gJy4uL3JlbmRlcjMvdXRpbC9zdHJpbmdpZnlfdXRpbHMnO1xuaW1wb3J0IHtnZXRDb21wb25lbnRMVmlld0J5SW5kZXgsIGdldE5hdGl2ZUJ5VE5vZGVPck51bGx9IGZyb20gJy4uL3JlbmRlcjMvdXRpbC92aWV3X3V0aWxzJztcbmltcG9ydCB7YXNzZXJ0RG9tTm9kZX0gZnJvbSAnLi4vdXRpbC9hc3NlcnQnO1xuaW1wb3J0IHtEZWJ1Z0NvbnRleHR9IGZyb20gJy4uL3ZpZXcvdHlwZXMnO1xuXG5cbi8qKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgRGVidWdFdmVudExpc3RlbmVyIHtcbiAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZywgcHVibGljIGNhbGxiYWNrOiBGdW5jdGlvbikge31cbn1cblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVidWdOb2RlIHtcbiAgLyoqXG4gICAqIFRoZSBjYWxsYmFja3MgYXR0YWNoZWQgdG8gdGhlIGNvbXBvbmVudCdzIEBPdXRwdXQgcHJvcGVydGllcyBhbmQvb3IgdGhlIGVsZW1lbnQncyBldmVudFxuICAgKiBwcm9wZXJ0aWVzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGlzdGVuZXJzOiBEZWJ1Z0V2ZW50TGlzdGVuZXJbXTtcblxuICAvKipcbiAgICogVGhlIGBEZWJ1Z0VsZW1lbnRgIHBhcmVudC4gV2lsbCBiZSBgbnVsbGAgaWYgdGhpcyBpcyB0aGUgcm9vdCBlbGVtZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgcGFyZW50OiBEZWJ1Z0VsZW1lbnR8bnVsbDtcblxuICAvKipcbiAgICogVGhlIHVuZGVybHlpbmcgRE9NIG5vZGUuXG4gICAqL1xuICByZWFkb25seSBuYXRpdmVOb2RlOiBhbnk7XG5cbiAgLyoqXG4gICAqIFRoZSBob3N0IGRlcGVuZGVuY3kgaW5qZWN0b3IuIEZvciBleGFtcGxlLCB0aGUgcm9vdCBlbGVtZW50J3MgY29tcG9uZW50IGluc3RhbmNlIGluamVjdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5qZWN0b3I6IEluamVjdG9yO1xuXG4gIC8qKlxuICAgKiBUaGUgZWxlbWVudCdzIG93biBjb21wb25lbnQgaW5zdGFuY2UsIGlmIGl0IGhhcyBvbmUuXG4gICAqL1xuICByZWFkb25seSBjb21wb25lbnRJbnN0YW5jZTogYW55O1xuXG4gIC8qKlxuICAgKiBBbiBvYmplY3QgdGhhdCBwcm92aWRlcyBwYXJlbnQgY29udGV4dCBmb3IgdGhpcyBlbGVtZW50LiBPZnRlbiBhbiBhbmNlc3RvciBjb21wb25lbnQgaW5zdGFuY2VcbiAgICogdGhhdCBnb3Zlcm5zIHRoaXMgZWxlbWVudC5cbiAgICpcbiAgICogV2hlbiBhbiBlbGVtZW50IGlzIHJlcGVhdGVkIHdpdGhpbiAqbmdGb3IsIHRoZSBjb250ZXh0IGlzIGFuIGBOZ0Zvck9mYCB3aG9zZSBgJGltcGxpY2l0YFxuICAgKiBwcm9wZXJ0eSBpcyB0aGUgdmFsdWUgb2YgdGhlIHJvdyBpbnN0YW5jZSB2YWx1ZS4gRm9yIGV4YW1wbGUsIHRoZSBgaGVyb2AgaW4gYCpuZ0Zvcj1cImxldCBoZXJvXG4gICAqIG9mIGhlcm9lc1wiYC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IGFueTtcblxuICAvKipcbiAgICogRGljdGlvbmFyeSBvZiBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0ZW1wbGF0ZSBsb2NhbCB2YXJpYWJsZXMgKGUuZy4gI2ZvbyksIGtleWVkIGJ5IHRoZSBsb2NhbFxuICAgKiB2YXJpYWJsZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVmZXJlbmNlczoge1trZXk6IHN0cmluZ106IGFueX07XG5cbiAgLyoqXG4gICAqIFRoaXMgY29tcG9uZW50J3MgaW5qZWN0b3IgbG9va3VwIHRva2Vucy4gSW5jbHVkZXMgdGhlIGNvbXBvbmVudCBpdHNlbGYgcGx1cyB0aGUgdG9rZW5zIHRoYXQgdGhlXG4gICAqIGNvbXBvbmVudCBsaXN0cyBpbiBpdHMgcHJvdmlkZXJzIG1ldGFkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdmlkZXJUb2tlbnM6IGFueVtdO1xufVxuZXhwb3J0IGNsYXNzIERlYnVnTm9kZV9fUFJFX1IzX18ge1xuICByZWFkb25seSBsaXN0ZW5lcnM6IERlYnVnRXZlbnRMaXN0ZW5lcltdID0gW107XG4gIHJlYWRvbmx5IHBhcmVudDogRGVidWdFbGVtZW50fG51bGwgPSBudWxsO1xuICByZWFkb25seSBuYXRpdmVOb2RlOiBhbnk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlYnVnQ29udGV4dDogRGVidWdDb250ZXh0O1xuXG4gIGNvbnN0cnVjdG9yKG5hdGl2ZU5vZGU6IGFueSwgcGFyZW50OiBEZWJ1Z05vZGV8bnVsbCwgX2RlYnVnQ29udGV4dDogRGVidWdDb250ZXh0KSB7XG4gICAgdGhpcy5fZGVidWdDb250ZXh0ID0gX2RlYnVnQ29udGV4dDtcbiAgICB0aGlzLm5hdGl2ZU5vZGUgPSBuYXRpdmVOb2RlO1xuICAgIGlmIChwYXJlbnQgJiYgcGFyZW50IGluc3RhbmNlb2YgRGVidWdFbGVtZW50X19QUkVfUjNfXykge1xuICAgICAgcGFyZW50LmFkZENoaWxkKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBpbmplY3RvcigpOiBJbmplY3RvciB7XG4gICAgcmV0dXJuIHRoaXMuX2RlYnVnQ29udGV4dC5pbmplY3RvcjtcbiAgfVxuXG4gIGdldCBjb21wb25lbnRJbnN0YW5jZSgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl9kZWJ1Z0NvbnRleHQuY29tcG9uZW50O1xuICB9XG5cbiAgZ2V0IGNvbnRleHQoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fZGVidWdDb250ZXh0LmNvbnRleHQ7XG4gIH1cblxuICBnZXQgcmVmZXJlbmNlcygpOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlYnVnQ29udGV4dC5yZWZlcmVuY2VzO1xuICB9XG5cbiAgZ2V0IHByb3ZpZGVyVG9rZW5zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5fZGVidWdDb250ZXh0LnByb3ZpZGVyVG9rZW5zO1xuICB9XG59XG5cbi8qKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBzZWUgW0NvbXBvbmVudCB0ZXN0aW5nIHNjZW5hcmlvc10oZ3VpZGUvdGVzdGluZy1jb21wb25lbnRzLXNjZW5hcmlvcylcbiAqIEBzZWUgW0Jhc2ljcyBvZiB0ZXN0aW5nIGNvbXBvbmVudHNdKGd1aWRlL3Rlc3RpbmctY29tcG9uZW50cy1iYXNpY3MpXG4gKiBAc2VlIFtUZXN0aW5nIHV0aWxpdHkgQVBJc10oZ3VpZGUvdGVzdGluZy11dGlsaXR5LWFwaXMpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVidWdFbGVtZW50IGV4dGVuZHMgRGVidWdOb2RlIHtcbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IHRhZyBuYW1lLCBpZiBpdCBpcyBhbiBlbGVtZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiAgQSBtYXAgb2YgcHJvcGVydHkgbmFtZXMgdG8gcHJvcGVydHkgdmFsdWVzIGZvciBhbiBlbGVtZW50LlxuICAgKlxuICAgKiAgVGhpcyBtYXAgaW5jbHVkZXM6XG4gICAqICAtIFJlZ3VsYXIgcHJvcGVydHkgYmluZGluZ3MgKGUuZy4gYFtpZF09XCJpZFwiYClcbiAgICogIC0gSG9zdCBwcm9wZXJ0eSBiaW5kaW5ncyAoZS5nLiBgaG9zdDogeyAnW2lkXSc6IFwiaWRcIiB9YClcbiAgICogIC0gSW50ZXJwb2xhdGVkIHByb3BlcnR5IGJpbmRpbmdzIChlLmcuIGBpZD1cInt7IHZhbHVlIH19XCIpXG4gICAqXG4gICAqICBJdCBkb2VzIG5vdCBpbmNsdWRlOlxuICAgKiAgLSBpbnB1dCBwcm9wZXJ0eSBiaW5kaW5ncyAoZS5nLiBgW215Q3VzdG9tSW5wdXRdPVwidmFsdWVcImApXG4gICAqICAtIGF0dHJpYnV0ZSBiaW5kaW5ncyAoZS5nLiBgW2F0dHIucm9sZV09XCJtZW51XCJgKVxuICAgKi9cbiAgcmVhZG9ubHkgcHJvcGVydGllczoge1trZXk6IHN0cmluZ106IGFueX07XG5cbiAgLyoqXG4gICAqICBBIG1hcCBvZiBhdHRyaWJ1dGUgbmFtZXMgdG8gYXR0cmlidXRlIHZhbHVlcyBmb3IgYW4gZWxlbWVudC5cbiAgICovXG4gIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVsbH07XG5cbiAgLyoqXG4gICAqIEEgbWFwIGNvbnRhaW5pbmcgdGhlIGNsYXNzIG5hbWVzIG9uIHRoZSBlbGVtZW50IGFzIGtleXMuXG4gICAqXG4gICAqIFRoaXMgbWFwIGlzIGRlcml2ZWQgZnJvbSB0aGUgYGNsYXNzTmFtZWAgcHJvcGVydHkgb2YgdGhlIERPTSBlbGVtZW50LlxuICAgKlxuICAgKiBOb3RlOiBUaGUgdmFsdWVzIG9mIHRoaXMgb2JqZWN0IHdpbGwgYWx3YXlzIGJlIGB0cnVlYC4gVGhlIGNsYXNzIGtleSB3aWxsIG5vdCBhcHBlYXIgaW4gdGhlIEtWXG4gICAqIG9iamVjdCBpZiBpdCBkb2VzIG5vdCBleGlzdCBvbiB0aGUgZWxlbWVudC5cbiAgICpcbiAgICogQHNlZSBbRWxlbWVudC5jbGFzc05hbWVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50L2NsYXNzTmFtZSlcbiAgICovXG4gIHJlYWRvbmx5IGNsYXNzZXM6IHtba2V5OiBzdHJpbmddOiBib29sZWFufTtcblxuICAvKipcbiAgICogVGhlIGlubGluZSBzdHlsZXMgb2YgdGhlIERPTSBlbGVtZW50LlxuICAgKlxuICAgKiBXaWxsIGJlIGBudWxsYCBpZiB0aGVyZSBpcyBubyBgc3R5bGVgIHByb3BlcnR5IG9uIHRoZSB1bmRlcmx5aW5nIERPTSBlbGVtZW50LlxuICAgKlxuICAgKiBAc2VlIFtFbGVtZW50Q1NTSW5saW5lU3R5bGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50Q1NTSW5saW5lU3R5bGUvc3R5bGUpXG4gICAqL1xuICByZWFkb25seSBzdHlsZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVsbH07XG5cbiAgLyoqXG4gICAqIFRoZSBgY2hpbGROb2Rlc2Agb2YgdGhlIERPTSBlbGVtZW50IGFzIGEgYERlYnVnTm9kZWAgYXJyYXkuXG4gICAqXG4gICAqIEBzZWUgW05vZGUuY2hpbGROb2Rlc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL05vZGUvY2hpbGROb2RlcylcbiAgICovXG4gIHJlYWRvbmx5IGNoaWxkTm9kZXM6IERlYnVnTm9kZVtdO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5kZXJseWluZyBET00gZWxlbWVudCBhdCB0aGUgcm9vdCBvZiB0aGUgY29tcG9uZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgbmF0aXZlRWxlbWVudDogYW55O1xuXG4gIC8qKlxuICAgKiBUaGUgaW1tZWRpYXRlIGBEZWJ1Z0VsZW1lbnRgIGNoaWxkcmVuLiBXYWxrIHRoZSB0cmVlIGJ5IGRlc2NlbmRpbmcgdGhyb3VnaCBgY2hpbGRyZW5gLlxuICAgKi9cbiAgcmVhZG9ubHkgY2hpbGRyZW46IERlYnVnRWxlbWVudFtdO1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB0aGUgZmlyc3QgYERlYnVnRWxlbWVudGAgdGhhdCBtYXRjaGVzIHRoZSBwcmVkaWNhdGUgYXQgYW55IGRlcHRoIGluIHRoZSBzdWJ0cmVlLlxuICAgKi9cbiAgcXVlcnkocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudDtcblxuICAvKipcbiAgICogQHJldHVybnMgQWxsIGBEZWJ1Z0VsZW1lbnRgIG1hdGNoZXMgZm9yIHRoZSBwcmVkaWNhdGUgYXQgYW55IGRlcHRoIGluIHRoZSBzdWJ0cmVlLlxuICAgKi9cbiAgcXVlcnlBbGwocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudFtdO1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBBbGwgYERlYnVnTm9kZWAgbWF0Y2hlcyBmb3IgdGhlIHByZWRpY2F0ZSBhdCBhbnkgZGVwdGggaW4gdGhlIHN1YnRyZWUuXG4gICAqL1xuICBxdWVyeUFsbE5vZGVzKHByZWRpY2F0ZTogUHJlZGljYXRlPERlYnVnTm9kZT4pOiBEZWJ1Z05vZGVbXTtcblxuICAvKipcbiAgICogVHJpZ2dlcnMgdGhlIGV2ZW50IGJ5IGl0cyBuYW1lIGlmIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBsaXN0ZW5lciBpbiB0aGUgZWxlbWVudCdzXG4gICAqIGBsaXN0ZW5lcnNgIGNvbGxlY3Rpb24uXG4gICAqXG4gICAqIElmIHRoZSBldmVudCBsYWNrcyBhIGxpc3RlbmVyIG9yIHRoZXJlJ3Mgc29tZSBvdGhlciBwcm9ibGVtLCBjb25zaWRlclxuICAgKiBjYWxsaW5nIGBuYXRpdmVFbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnRPYmplY3QpYC5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gdHJpZ2dlclxuICAgKiBAcGFyYW0gZXZlbnRPYmogVGhlIF9ldmVudCBvYmplY3RfIGV4cGVjdGVkIGJ5IHRoZSBoYW5kbGVyXG4gICAqXG4gICAqIEBzZWUgW1Rlc3RpbmcgY29tcG9uZW50cyBzY2VuYXJpb3NdKGd1aWRlL3Rlc3RpbmctY29tcG9uZW50cy1zY2VuYXJpb3MjdHJpZ2dlci1ldmVudC1oYW5kbGVyKVxuICAgKi9cbiAgdHJpZ2dlckV2ZW50SGFuZGxlcihldmVudE5hbWU6IHN0cmluZywgZXZlbnRPYmo6IGFueSk6IHZvaWQ7XG59XG5leHBvcnQgY2xhc3MgRGVidWdFbGVtZW50X19QUkVfUjNfXyBleHRlbmRzIERlYnVnTm9kZV9fUFJFX1IzX18gaW1wbGVtZW50cyBEZWJ1Z0VsZW1lbnQge1xuICByZWFkb25seSBuYW1lITogc3RyaW5nO1xuICByZWFkb25seSBwcm9wZXJ0aWVzOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuICByZWFkb25seSBhdHRyaWJ1dGVzOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfG51bGx9ID0ge307XG4gIHJlYWRvbmx5IGNsYXNzZXM6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHt9O1xuICByZWFkb25seSBzdHlsZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVsbH0gPSB7fTtcbiAgcmVhZG9ubHkgY2hpbGROb2RlczogRGVidWdOb2RlW10gPSBbXTtcbiAgcmVhZG9ubHkgbmF0aXZlRWxlbWVudDogYW55O1xuXG4gIGNvbnN0cnVjdG9yKG5hdGl2ZU5vZGU6IGFueSwgcGFyZW50OiBhbnksIF9kZWJ1Z0NvbnRleHQ6IERlYnVnQ29udGV4dCkge1xuICAgIHN1cGVyKG5hdGl2ZU5vZGUsIHBhcmVudCwgX2RlYnVnQ29udGV4dCk7XG4gICAgdGhpcy5uYXRpdmVFbGVtZW50ID0gbmF0aXZlTm9kZTtcbiAgfVxuXG4gIGFkZENoaWxkKGNoaWxkOiBEZWJ1Z05vZGUpIHtcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIHRoaXMuY2hpbGROb2Rlcy5wdXNoKGNoaWxkKTtcbiAgICAgIChjaGlsZCBhcyB7cGFyZW50OiBEZWJ1Z05vZGV9KS5wYXJlbnQgPSB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUNoaWxkKGNoaWxkOiBEZWJ1Z05vZGUpIHtcbiAgICBjb25zdCBjaGlsZEluZGV4ID0gdGhpcy5jaGlsZE5vZGVzLmluZGV4T2YoY2hpbGQpO1xuICAgIGlmIChjaGlsZEluZGV4ICE9PSAtMSkge1xuICAgICAgKGNoaWxkIGFzIHtwYXJlbnQ6IERlYnVnTm9kZSB8IG51bGx9KS5wYXJlbnQgPSBudWxsO1xuICAgICAgdGhpcy5jaGlsZE5vZGVzLnNwbGljZShjaGlsZEluZGV4LCAxKTtcbiAgICB9XG4gIH1cblxuICBpbnNlcnRDaGlsZHJlbkFmdGVyKGNoaWxkOiBEZWJ1Z05vZGUsIG5ld0NoaWxkcmVuOiBEZWJ1Z05vZGVbXSkge1xuICAgIGNvbnN0IHNpYmxpbmdJbmRleCA9IHRoaXMuY2hpbGROb2Rlcy5pbmRleE9mKGNoaWxkKTtcbiAgICBpZiAoc2libGluZ0luZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5jaGlsZE5vZGVzLnNwbGljZShzaWJsaW5nSW5kZXggKyAxLCAwLCAuLi5uZXdDaGlsZHJlbik7XG4gICAgICBuZXdDaGlsZHJlbi5mb3JFYWNoKGMgPT4ge1xuICAgICAgICBpZiAoYy5wYXJlbnQpIHtcbiAgICAgICAgICAoYy5wYXJlbnQgYXMgRGVidWdFbGVtZW50X19QUkVfUjNfXykucmVtb3ZlQ2hpbGQoYyk7XG4gICAgICAgIH1cbiAgICAgICAgKGNoaWxkIGFzIHtwYXJlbnQ6IERlYnVnTm9kZX0pLnBhcmVudCA9IHRoaXM7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpbnNlcnRCZWZvcmUocmVmQ2hpbGQ6IERlYnVnTm9kZSwgbmV3Q2hpbGQ6IERlYnVnTm9kZSk6IHZvaWQge1xuICAgIGNvbnN0IHJlZkluZGV4ID0gdGhpcy5jaGlsZE5vZGVzLmluZGV4T2YocmVmQ2hpbGQpO1xuICAgIGlmIChyZWZJbmRleCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuYWRkQ2hpbGQobmV3Q2hpbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobmV3Q2hpbGQucGFyZW50KSB7XG4gICAgICAgIChuZXdDaGlsZC5wYXJlbnQgYXMgRGVidWdFbGVtZW50X19QUkVfUjNfXykucmVtb3ZlQ2hpbGQobmV3Q2hpbGQpO1xuICAgICAgfVxuICAgICAgKG5ld0NoaWxkIGFzIHtwYXJlbnQ6IERlYnVnTm9kZX0pLnBhcmVudCA9IHRoaXM7XG4gICAgICB0aGlzLmNoaWxkTm9kZXMuc3BsaWNlKHJlZkluZGV4LCAwLCBuZXdDaGlsZCk7XG4gICAgfVxuICB9XG5cbiAgcXVlcnkocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudCB7XG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMucXVlcnlBbGwocHJlZGljYXRlKTtcbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgcXVlcnlBbGwocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudFtdIHtcbiAgICBjb25zdCBtYXRjaGVzOiBEZWJ1Z0VsZW1lbnRbXSA9IFtdO1xuICAgIF9xdWVyeUVsZW1lbnRDaGlsZHJlbih0aGlzLCBwcmVkaWNhdGUsIG1hdGNoZXMpO1xuICAgIHJldHVybiBtYXRjaGVzO1xuICB9XG5cbiAgcXVlcnlBbGxOb2RlcyhwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z05vZGU+KTogRGVidWdOb2RlW10ge1xuICAgIGNvbnN0IG1hdGNoZXM6IERlYnVnTm9kZVtdID0gW107XG4gICAgX3F1ZXJ5Tm9kZUNoaWxkcmVuKHRoaXMsIHByZWRpY2F0ZSwgbWF0Y2hlcyk7XG4gICAgcmV0dXJuIG1hdGNoZXM7XG4gIH1cblxuICBnZXQgY2hpbGRyZW4oKTogRGVidWdFbGVtZW50W10ge1xuICAgIHJldHVybiB0aGlzLmNoaWxkTm9kZXMgIC8vXG4gICAgICAgICAgICAgICAuZmlsdGVyKChub2RlKSA9PiBub2RlIGluc3RhbmNlb2YgRGVidWdFbGVtZW50X19QUkVfUjNfXykgYXMgRGVidWdFbGVtZW50W107XG4gIH1cblxuICB0cmlnZ2VyRXZlbnRIYW5kbGVyKGV2ZW50TmFtZTogc3RyaW5nLCBldmVudE9iajogYW55KSB7XG4gICAgdGhpcy5saXN0ZW5lcnMuZm9yRWFjaCgobGlzdGVuZXIpID0+IHtcbiAgICAgIGlmIChsaXN0ZW5lci5uYW1lID09IGV2ZW50TmFtZSkge1xuICAgICAgICBsaXN0ZW5lci5jYWxsYmFjayhldmVudE9iaik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc05hdGl2ZUVsZW1lbnRzKGRlYnVnRWxzOiBEZWJ1Z0VsZW1lbnRbXSk6IGFueSB7XG4gIHJldHVybiBkZWJ1Z0Vscy5tYXAoKGVsKSA9PiBlbC5uYXRpdmVFbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gX3F1ZXJ5RWxlbWVudENoaWxkcmVuKFxuICAgIGVsZW1lbnQ6IERlYnVnRWxlbWVudCwgcHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50PiwgbWF0Y2hlczogRGVidWdFbGVtZW50W10pIHtcbiAgZWxlbWVudC5jaGlsZE5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBEZWJ1Z0VsZW1lbnRfX1BSRV9SM19fKSB7XG4gICAgICBpZiAocHJlZGljYXRlKG5vZGUpKSB7XG4gICAgICAgIG1hdGNoZXMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICAgIF9xdWVyeUVsZW1lbnRDaGlsZHJlbihub2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMpO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIF9xdWVyeU5vZGVDaGlsZHJlbihcbiAgICBwYXJlbnROb2RlOiBEZWJ1Z05vZGUsIHByZWRpY2F0ZTogUHJlZGljYXRlPERlYnVnTm9kZT4sIG1hdGNoZXM6IERlYnVnTm9kZVtdKSB7XG4gIGlmIChwYXJlbnROb2RlIGluc3RhbmNlb2YgRGVidWdFbGVtZW50X19QUkVfUjNfXykge1xuICAgIHBhcmVudE5vZGUuY2hpbGROb2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgaWYgKHByZWRpY2F0ZShub2RlKSkge1xuICAgICAgICBtYXRjaGVzLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIERlYnVnRWxlbWVudF9fUFJFX1IzX18pIHtcbiAgICAgICAgX3F1ZXJ5Tm9kZUNoaWxkcmVuKG5vZGUsIHByZWRpY2F0ZSwgbWF0Y2hlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuY2xhc3MgRGVidWdOb2RlX19QT1NUX1IzX18gaW1wbGVtZW50cyBEZWJ1Z05vZGUge1xuICByZWFkb25seSBuYXRpdmVOb2RlOiBOb2RlO1xuXG4gIGNvbnN0cnVjdG9yKG5hdGl2ZU5vZGU6IE5vZGUpIHtcbiAgICB0aGlzLm5hdGl2ZU5vZGUgPSBuYXRpdmVOb2RlO1xuICB9XG5cbiAgZ2V0IHBhcmVudCgpOiBEZWJ1Z0VsZW1lbnR8bnVsbCB7XG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5uYXRpdmVOb2RlLnBhcmVudE5vZGUgYXMgRWxlbWVudDtcbiAgICByZXR1cm4gcGFyZW50ID8gbmV3IERlYnVnRWxlbWVudF9fUE9TVF9SM19fKHBhcmVudCkgOiBudWxsO1xuICB9XG5cbiAgZ2V0IGluamVjdG9yKCk6IEluamVjdG9yIHtcbiAgICByZXR1cm4gZ2V0SW5qZWN0b3IodGhpcy5uYXRpdmVOb2RlKTtcbiAgfVxuXG4gIGdldCBjb21wb25lbnRJbnN0YW5jZSgpOiBhbnkge1xuICAgIGNvbnN0IG5hdGl2ZUVsZW1lbnQgPSB0aGlzLm5hdGl2ZU5vZGU7XG4gICAgcmV0dXJuIG5hdGl2ZUVsZW1lbnQgJiZcbiAgICAgICAgKGdldENvbXBvbmVudChuYXRpdmVFbGVtZW50IGFzIEVsZW1lbnQpIHx8IGdldE93bmluZ0NvbXBvbmVudChuYXRpdmVFbGVtZW50KSk7XG4gIH1cbiAgZ2V0IGNvbnRleHQoKTogYW55IHtcbiAgICByZXR1cm4gZ2V0Q29tcG9uZW50KHRoaXMubmF0aXZlTm9kZSBhcyBFbGVtZW50KSB8fCBnZXRDb250ZXh0KHRoaXMubmF0aXZlTm9kZSBhcyBFbGVtZW50KTtcbiAgfVxuXG4gIGdldCBsaXN0ZW5lcnMoKTogRGVidWdFdmVudExpc3RlbmVyW10ge1xuICAgIHJldHVybiBnZXRMaXN0ZW5lcnModGhpcy5uYXRpdmVOb2RlIGFzIEVsZW1lbnQpLmZpbHRlcihsaXN0ZW5lciA9PiBsaXN0ZW5lci50eXBlID09PSAnZG9tJyk7XG4gIH1cblxuICBnZXQgcmVmZXJlbmNlcygpOiB7W2tleTogc3RyaW5nXTogYW55O30ge1xuICAgIHJldHVybiBnZXRMb2NhbFJlZnModGhpcy5uYXRpdmVOb2RlKTtcbiAgfVxuXG4gIGdldCBwcm92aWRlclRva2VucygpOiBhbnlbXSB7XG4gICAgcmV0dXJuIGdldEluamVjdGlvblRva2Vucyh0aGlzLm5hdGl2ZU5vZGUgYXMgRWxlbWVudCk7XG4gIH1cbn1cblxuY2xhc3MgRGVidWdFbGVtZW50X19QT1NUX1IzX18gZXh0ZW5kcyBEZWJ1Z05vZGVfX1BPU1RfUjNfXyBpbXBsZW1lbnRzIERlYnVnRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKG5hdGl2ZU5vZGU6IEVsZW1lbnQpIHtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RG9tTm9kZShuYXRpdmVOb2RlKTtcbiAgICBzdXBlcihuYXRpdmVOb2RlKTtcbiAgfVxuXG4gIGdldCBuYXRpdmVFbGVtZW50KCk6IEVsZW1lbnR8bnVsbCB7XG4gICAgcmV0dXJuIHRoaXMubmF0aXZlTm9kZS5ub2RlVHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSA/IHRoaXMubmF0aXZlTm9kZSBhcyBFbGVtZW50IDogbnVsbDtcbiAgfVxuXG4gIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgY29uc3QgY29udGV4dCA9IGdldExDb250ZXh0KHRoaXMubmF0aXZlTm9kZSk7XG4gICAgaWYgKGNvbnRleHQgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IGxWaWV3ID0gY29udGV4dC5sVmlldztcbiAgICAgIGNvbnN0IHREYXRhID0gbFZpZXdbVFZJRVddLmRhdGE7XG4gICAgICBjb25zdCB0Tm9kZSA9IHREYXRhW2NvbnRleHQubm9kZUluZGV4XSBhcyBUTm9kZTtcbiAgICAgIHJldHVybiB0Tm9kZS52YWx1ZSE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLm5hdGl2ZU5vZGUubm9kZU5hbWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqICBHZXRzIGEgbWFwIG9mIHByb3BlcnR5IG5hbWVzIHRvIHByb3BlcnR5IHZhbHVlcyBmb3IgYW4gZWxlbWVudC5cbiAgICpcbiAgICogIFRoaXMgbWFwIGluY2x1ZGVzOlxuICAgKiAgLSBSZWd1bGFyIHByb3BlcnR5IGJpbmRpbmdzIChlLmcuIGBbaWRdPVwiaWRcImApXG4gICAqICAtIEhvc3QgcHJvcGVydHkgYmluZGluZ3MgKGUuZy4gYGhvc3Q6IHsgJ1tpZF0nOiBcImlkXCIgfWApXG4gICAqICAtIEludGVycG9sYXRlZCBwcm9wZXJ0eSBiaW5kaW5ncyAoZS5nLiBgaWQ9XCJ7eyB2YWx1ZSB9fVwiKVxuICAgKlxuICAgKiAgSXQgZG9lcyBub3QgaW5jbHVkZTpcbiAgICogIC0gaW5wdXQgcHJvcGVydHkgYmluZGluZ3MgKGUuZy4gYFtteUN1c3RvbUlucHV0XT1cInZhbHVlXCJgKVxuICAgKiAgLSBhdHRyaWJ1dGUgYmluZGluZ3MgKGUuZy4gYFthdHRyLnJvbGVdPVwibWVudVwiYClcbiAgICovXG4gIGdldCBwcm9wZXJ0aWVzKCk6IHtba2V5OiBzdHJpbmddOiBhbnk7fSB7XG4gICAgY29uc3QgY29udGV4dCA9IGdldExDb250ZXh0KHRoaXMubmF0aXZlTm9kZSk7XG4gICAgaWYgKGNvbnRleHQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBsVmlldyA9IGNvbnRleHQubFZpZXc7XG4gICAgY29uc3QgdERhdGEgPSBsVmlld1tUVklFV10uZGF0YTtcbiAgICBjb25zdCB0Tm9kZSA9IHREYXRhW2NvbnRleHQubm9kZUluZGV4XSBhcyBUTm9kZTtcblxuICAgIGNvbnN0IHByb3BlcnRpZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gICAgLy8gQ29sbGVjdCBwcm9wZXJ0aWVzIGZyb20gdGhlIERPTS5cbiAgICBjb3B5RG9tUHJvcGVydGllcyh0aGlzLm5hdGl2ZUVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgIC8vIENvbGxlY3QgcHJvcGVydGllcyBmcm9tIHRoZSBiaW5kaW5ncy4gVGhpcyBpcyBuZWVkZWQgZm9yIGFuaW1hdGlvbiByZW5kZXJlciB3aGljaCBoYXNcbiAgICAvLyBzeW50aGV0aWMgcHJvcGVydGllcyB3aGljaCBkb24ndCBnZXQgcmVmbGVjdGVkIGludG8gdGhlIERPTS5cbiAgICBjb2xsZWN0UHJvcGVydHlCaW5kaW5ncyhwcm9wZXJ0aWVzLCB0Tm9kZSwgbFZpZXcsIHREYXRhKTtcbiAgICByZXR1cm4gcHJvcGVydGllcztcbiAgfVxuXG4gIGdldCBhdHRyaWJ1dGVzKCk6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVsbDt9IHtcbiAgICBjb25zdCBhdHRyaWJ1dGVzOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfG51bGw7fSA9IHt9O1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRleHQgPSBnZXRMQ29udGV4dChlbGVtZW50KTtcbiAgICBpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIGNvbnN0IGxWaWV3ID0gY29udGV4dC5sVmlldztcbiAgICBjb25zdCB0Tm9kZUF0dHJzID0gKGxWaWV3W1RWSUVXXS5kYXRhW2NvbnRleHQubm9kZUluZGV4XSBhcyBUTm9kZSkuYXR0cnM7XG4gICAgY29uc3QgbG93ZXJjYXNlVE5vZGVBdHRyczogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIEZvciBkZWJ1ZyBub2RlcyB3ZSB0YWtlIHRoZSBlbGVtZW50J3MgYXR0cmlidXRlIGRpcmVjdGx5IGZyb20gdGhlIERPTSBzaW5jZSBpdCBhbGxvd3MgdXNcbiAgICAvLyB0byBhY2NvdW50IGZvciBvbmVzIHRoYXQgd2VyZW4ndCBzZXQgdmlhIGJpbmRpbmdzIChlLmcuIFZpZXdFbmdpbmUga2VlcHMgdHJhY2sgb2YgdGhlIG9uZXNcbiAgICAvLyB0aGF0IGFyZSBzZXQgdGhyb3VnaCBgUmVuZGVyZXIyYCkuIFRoZSBwcm9ibGVtIGlzIHRoYXQgdGhlIGJyb3dzZXIgd2lsbCBsb3dlcmNhc2UgYWxsIG5hbWVzLFxuICAgIC8vIGhvd2V2ZXIgc2luY2Ugd2UgaGF2ZSB0aGUgYXR0cmlidXRlcyBhbHJlYWR5IG9uIHRoZSBUTm9kZSwgd2UgY2FuIHByZXNlcnZlIHRoZSBjYXNlIGJ5IGdvaW5nXG4gICAgLy8gdGhyb3VnaCB0aGVtIG9uY2UsIGFkZGluZyB0aGVtIHRvIHRoZSBgYXR0cmlidXRlc2AgbWFwIGFuZCBwdXR0aW5nIHRoZWlyIGxvd2VyLWNhc2VkIG5hbWVcbiAgICAvLyBpbnRvIGFuIGFycmF5LiBBZnRlcndhcmRzIHdoZW4gd2UncmUgZ29pbmcgdGhyb3VnaCB0aGUgbmF0aXZlIERPTSBhdHRyaWJ1dGVzLCB3ZSBjYW4gY2hlY2tcbiAgICAvLyB3aGV0aGVyIHdlIGhhdmVuJ3QgcnVuIGludG8gYW4gYXR0cmlidXRlIGFscmVhZHkgdGhyb3VnaCB0aGUgVE5vZGUuXG4gICAgaWYgKHROb2RlQXR0cnMpIHtcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIHdoaWxlIChpIDwgdE5vZGVBdHRycy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgYXR0ck5hbWUgPSB0Tm9kZUF0dHJzW2ldO1xuXG4gICAgICAgIC8vIFN0b3AgYXMgc29vbiBhcyB3ZSBoaXQgYSBtYXJrZXIuIFdlIG9ubHkgY2FyZSBhYm91dCB0aGUgcmVndWxhciBhdHRyaWJ1dGVzLiBFdmVyeXRoaW5nXG4gICAgICAgIC8vIGVsc2Ugd2lsbCBiZSBoYW5kbGVkIGJlbG93IHdoZW4gd2UgcmVhZCB0aGUgZmluYWwgYXR0cmlidXRlcyBvZmYgdGhlIERPTS5cbiAgICAgICAgaWYgKHR5cGVvZiBhdHRyTmFtZSAhPT0gJ3N0cmluZycpIGJyZWFrO1xuXG4gICAgICAgIGNvbnN0IGF0dHJWYWx1ZSA9IHROb2RlQXR0cnNbaSArIDFdO1xuICAgICAgICBhdHRyaWJ1dGVzW2F0dHJOYW1lXSA9IGF0dHJWYWx1ZSBhcyBzdHJpbmc7XG4gICAgICAgIGxvd2VyY2FzZVROb2RlQXR0cnMucHVzaChhdHRyTmFtZS50b0xvd2VyQ2FzZSgpKTtcblxuICAgICAgICBpICs9IDI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZUF0dHJzID0gZWxlbWVudC5hdHRyaWJ1dGVzO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZUF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBhdHRyID0gZUF0dHJzW2ldO1xuICAgICAgY29uc3QgbG93ZXJjYXNlTmFtZSA9IGF0dHIubmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAvLyBNYWtlIHN1cmUgdGhhdCB3ZSBkb24ndCBhc3NpZ24gdGhlIHNhbWUgYXR0cmlidXRlIGJvdGggaW4gaXRzXG4gICAgICAvLyBjYXNlLXNlbnNpdGl2ZSBmb3JtIGFuZCB0aGUgbG93ZXItY2FzZWQgb25lIGZyb20gdGhlIGJyb3dzZXIuXG4gICAgICBpZiAobG93ZXJjYXNlVE5vZGVBdHRycy5pbmRleE9mKGxvd2VyY2FzZU5hbWUpID09PSAtMSkge1xuICAgICAgICAvLyBTYXZlIHRoZSBsb3dlcmNhc2UgbmFtZSB0byBhbGlnbiB0aGUgYmVoYXZpb3IgYmV0d2VlbiBicm93c2Vycy5cbiAgICAgICAgLy8gSUUgcHJlc2VydmVzIHRoZSBjYXNlLCB3aGlsZSBhbGwgb3RoZXIgYnJvd3NlciBjb252ZXJ0IGl0IHRvIGxvd2VyIGNhc2UuXG4gICAgICAgIGF0dHJpYnV0ZXNbbG93ZXJjYXNlTmFtZV0gPSBhdHRyLnZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICB9XG5cbiAgZ2V0IHN0eWxlcygpOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfG51bGx9IHtcbiAgICBpZiAodGhpcy5uYXRpdmVFbGVtZW50ICYmICh0aGlzLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpLnN0eWxlKSB7XG4gICAgICByZXR1cm4gKHRoaXMubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkuc3R5bGUgYXMge1trZXk6IHN0cmluZ106IGFueX07XG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGdldCBjbGFzc2VzKCk6IHtba2V5OiBzdHJpbmddOiBib29sZWFuO30ge1xuICAgIGNvbnN0IHJlc3VsdDoge1trZXk6IHN0cmluZ106IGJvb2xlYW47fSA9IHt9O1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQgfCBTVkdFbGVtZW50O1xuXG4gICAgLy8gU1ZHIGVsZW1lbnRzIHJldHVybiBhbiBgU1ZHQW5pbWF0ZWRTdHJpbmdgIGluc3RlYWQgb2YgYSBwbGFpbiBzdHJpbmcgZm9yIHRoZSBgY2xhc3NOYW1lYC5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZSBhcyBzdHJpbmcgfCBTVkdBbmltYXRlZFN0cmluZztcbiAgICBjb25zdCBjbGFzc2VzID1cbiAgICAgICAgdHlwZW9mIGNsYXNzTmFtZSAhPT0gJ3N0cmluZycgPyBjbGFzc05hbWUuYmFzZVZhbC5zcGxpdCgnICcpIDogY2xhc3NOYW1lLnNwbGl0KCcgJyk7XG5cbiAgICBjbGFzc2VzLmZvckVhY2goKHZhbHVlOiBzdHJpbmcpID0+IHJlc3VsdFt2YWx1ZV0gPSB0cnVlKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBnZXQgY2hpbGROb2RlcygpOiBEZWJ1Z05vZGVbXSB7XG4gICAgY29uc3QgY2hpbGROb2RlcyA9IHRoaXMubmF0aXZlTm9kZS5jaGlsZE5vZGVzO1xuICAgIGNvbnN0IGNoaWxkcmVuOiBEZWJ1Z05vZGVbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGNoaWxkTm9kZXNbaV07XG4gICAgICBjaGlsZHJlbi5wdXNoKGdldERlYnVnTm9kZV9fUE9TVF9SM19fKGVsZW1lbnQpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkcmVuO1xuICB9XG5cbiAgZ2V0IGNoaWxkcmVuKCk6IERlYnVnRWxlbWVudFtdIHtcbiAgICBjb25zdCBuYXRpdmVFbGVtZW50ID0gdGhpcy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghbmF0aXZlRWxlbWVudCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGNoaWxkTm9kZXMgPSBuYXRpdmVFbGVtZW50LmNoaWxkcmVuO1xuICAgIGNvbnN0IGNoaWxkcmVuOiBEZWJ1Z0VsZW1lbnRbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGNoaWxkTm9kZXNbaV07XG4gICAgICBjaGlsZHJlbi5wdXNoKGdldERlYnVnTm9kZV9fUE9TVF9SM19fKGVsZW1lbnQpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkcmVuO1xuICB9XG5cbiAgcXVlcnkocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudCB7XG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMucXVlcnlBbGwocHJlZGljYXRlKTtcbiAgICByZXR1cm4gcmVzdWx0c1swXSB8fCBudWxsO1xuICB9XG5cbiAgcXVlcnlBbGwocHJlZGljYXRlOiBQcmVkaWNhdGU8RGVidWdFbGVtZW50Pik6IERlYnVnRWxlbWVudFtdIHtcbiAgICBjb25zdCBtYXRjaGVzOiBEZWJ1Z0VsZW1lbnRbXSA9IFtdO1xuICAgIF9xdWVyeUFsbFIzKHRoaXMsIHByZWRpY2F0ZSwgbWF0Y2hlcywgdHJ1ZSk7XG4gICAgcmV0dXJuIG1hdGNoZXM7XG4gIH1cblxuICBxdWVyeUFsbE5vZGVzKHByZWRpY2F0ZTogUHJlZGljYXRlPERlYnVnTm9kZT4pOiBEZWJ1Z05vZGVbXSB7XG4gICAgY29uc3QgbWF0Y2hlczogRGVidWdOb2RlW10gPSBbXTtcbiAgICBfcXVlcnlBbGxSMyh0aGlzLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGZhbHNlKTtcbiAgICByZXR1cm4gbWF0Y2hlcztcbiAgfVxuXG4gIHRyaWdnZXJFdmVudEhhbmRsZXIoZXZlbnROYW1lOiBzdHJpbmcsIGV2ZW50T2JqOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5uYXRpdmVOb2RlIGFzIGFueTtcbiAgICBjb25zdCBpbnZva2VkTGlzdGVuZXJzOiBGdW5jdGlvbltdID0gW107XG5cbiAgICB0aGlzLmxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcbiAgICAgIGlmIChsaXN0ZW5lci5uYW1lID09PSBldmVudE5hbWUpIHtcbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBsaXN0ZW5lci5jYWxsYmFjaztcbiAgICAgICAgY2FsbGJhY2suY2FsbChub2RlLCBldmVudE9iaik7XG4gICAgICAgIGludm9rZWRMaXN0ZW5lcnMucHVzaChjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgYGV2ZW50TGlzdGVuZXJzYCBleGlzdHMsIGJlY2F1c2UgaXQncyBzb21ldGhpbmdcbiAgICAvLyB0aGF0IFpvbmUuanMgb25seSBhZGRzIHRvIGBFdmVudFRhcmdldGAgaW4gYnJvd3NlciBlbnZpcm9ubWVudHMuXG4gICAgaWYgKHR5cGVvZiBub2RlLmV2ZW50TGlzdGVuZXJzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBOb3RlIHRoYXQgaW4gSXZ5IHdlIHdyYXAgZXZlbnQgbGlzdGVuZXJzIHdpdGggYSBjYWxsIHRvIGBldmVudC5wcmV2ZW50RGVmYXVsdGAgaW4gc29tZVxuICAgICAgLy8gY2FzZXMuIFdlIHVzZSAnX19uZ1Vud3JhcF9fJyBhcyBhIHNwZWNpYWwgdG9rZW4gdGhhdCBnaXZlcyB1cyBhY2Nlc3MgdG8gdGhlIGFjdHVhbCBldmVudFxuICAgICAgLy8gbGlzdGVuZXIuXG4gICAgICBub2RlLmV2ZW50TGlzdGVuZXJzKGV2ZW50TmFtZSkuZm9yRWFjaCgobGlzdGVuZXI6IEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgIC8vIEluIG9yZGVyIHRvIGVuc3VyZSB0aGF0IHdlIGNhbiBkZXRlY3QgdGhlIHNwZWNpYWwgX19uZ1Vud3JhcF9fIHRva2VuIGRlc2NyaWJlZCBhYm92ZSwgd2VcbiAgICAgICAgLy8gdXNlIGB0b1N0cmluZ2Agb24gdGhlIGxpc3RlbmVyIGFuZCBzZWUgaWYgaXQgY29udGFpbnMgdGhlIHRva2VuLiBXZSB1c2UgdGhpcyBhcHByb2FjaCB0b1xuICAgICAgICAvLyBlbnN1cmUgdGhhdCBpdCBzdGlsbCB3b3JrZWQgd2l0aCBjb21waWxlZCBjb2RlIHNpbmNlIGl0IGNhbm5vdCByZW1vdmUgb3IgcmVuYW1lIHN0cmluZ1xuICAgICAgICAvLyBsaXRlcmFscy4gV2UgYWxzbyBjb25zaWRlcmVkIHVzaW5nIGEgc3BlY2lhbCBmdW5jdGlvbiBuYW1lIChpLmUuIGlmKGxpc3RlbmVyLm5hbWUgPT09XG4gICAgICAgIC8vIHNwZWNpYWwpKSBidXQgdGhhdCB3YXMgbW9yZSBjdW1iZXJzb21lIGFuZCB3ZSB3ZXJlIGFsc28gY29uY2VybmVkIHRoZSBjb21waWxlZCBjb2RlIGNvdWxkXG4gICAgICAgIC8vIHN0cmlwIHRoZSBuYW1lLCB0dXJuaW5nIHRoZSBjb25kaXRpb24gaW4gdG8gKFwiXCIgPT09IFwiXCIpIGFuZCBhbHdheXMgcmV0dXJuaW5nIHRydWUuXG4gICAgICAgIGlmIChsaXN0ZW5lci50b1N0cmluZygpLmluZGV4T2YoJ19fbmdVbndyYXBfXycpICE9PSAtMSkge1xuICAgICAgICAgIGNvbnN0IHVud3JhcHBlZExpc3RlbmVyID0gbGlzdGVuZXIoJ19fbmdVbndyYXBfXycpO1xuICAgICAgICAgIHJldHVybiBpbnZva2VkTGlzdGVuZXJzLmluZGV4T2YodW53cmFwcGVkTGlzdGVuZXIpID09PSAtMSAmJlxuICAgICAgICAgICAgICB1bndyYXBwZWRMaXN0ZW5lci5jYWxsKG5vZGUsIGV2ZW50T2JqKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvcHlEb21Qcm9wZXJ0aWVzKGVsZW1lbnQ6IEVsZW1lbnR8bnVsbCwgcHJvcGVydGllczoge1tuYW1lOiBzdHJpbmddOiBzdHJpbmd9KTogdm9pZCB7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgLy8gU2tpcCBvd24gcHJvcGVydGllcyAoYXMgdGhvc2UgYXJlIHBhdGNoZWQpXG4gICAgbGV0IG9iaiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihlbGVtZW50KTtcbiAgICBjb25zdCBOb2RlUHJvdG90eXBlOiBhbnkgPSBOb2RlLnByb3RvdHlwZTtcbiAgICB3aGlsZSAob2JqICE9PSBudWxsICYmIG9iaiAhPT0gTm9kZVByb3RvdHlwZSkge1xuICAgICAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmopO1xuICAgICAgZm9yIChsZXQga2V5IGluIGRlc2NyaXB0b3JzKSB7XG4gICAgICAgIGlmICgha2V5LnN0YXJ0c1dpdGgoJ19fJykgJiYgIWtleS5zdGFydHNXaXRoKCdvbicpKSB7XG4gICAgICAgICAgLy8gZG9uJ3QgaW5jbHVkZSBwcm9wZXJ0aWVzIHN0YXJ0aW5nIHdpdGggYF9fYCBhbmQgYG9uYC5cbiAgICAgICAgICAvLyBgX19gIGFyZSBwYXRjaGVkIHZhbHVlcyB3aGljaCBzaG91bGQgbm90IGJlIGluY2x1ZGVkLlxuICAgICAgICAgIC8vIGBvbmAgYXJlIGxpc3RlbmVycyB3aGljaCBhbHNvIHNob3VsZCBub3QgYmUgaW5jbHVkZWQuXG4gICAgICAgICAgY29uc3QgdmFsdWUgPSAoZWxlbWVudCBhcyBhbnkpW2tleV07XG4gICAgICAgICAgaWYgKGlzUHJpbWl0aXZlVmFsdWUodmFsdWUpKSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG9iaiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZVZhbHVlKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fFxuICAgICAgdmFsdWUgPT09IG51bGw7XG59XG5cbi8qKlxuICogV2FsayB0aGUgVE5vZGUgdHJlZSB0byBmaW5kIG1hdGNoZXMgZm9yIHRoZSBwcmVkaWNhdGUuXG4gKlxuICogQHBhcmFtIHBhcmVudEVsZW1lbnQgdGhlIGVsZW1lbnQgZnJvbSB3aGljaCB0aGUgd2FsayBpcyBzdGFydGVkXG4gKiBAcGFyYW0gcHJlZGljYXRlIHRoZSBwcmVkaWNhdGUgdG8gbWF0Y2hcbiAqIEBwYXJhbSBtYXRjaGVzIHRoZSBsaXN0IG9mIHBvc2l0aXZlIG1hdGNoZXNcbiAqIEBwYXJhbSBlbGVtZW50c09ubHkgd2hldGhlciBvbmx5IGVsZW1lbnRzIHNob3VsZCBiZSBzZWFyY2hlZFxuICovXG5mdW5jdGlvbiBfcXVlcnlBbGxSMyhcbiAgICBwYXJlbnRFbGVtZW50OiBEZWJ1Z0VsZW1lbnQsIHByZWRpY2F0ZTogUHJlZGljYXRlPERlYnVnRWxlbWVudD4sIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdLFxuICAgIGVsZW1lbnRzT25seTogdHJ1ZSk6IHZvaWQ7XG5mdW5jdGlvbiBfcXVlcnlBbGxSMyhcbiAgICBwYXJlbnRFbGVtZW50OiBEZWJ1Z0VsZW1lbnQsIHByZWRpY2F0ZTogUHJlZGljYXRlPERlYnVnTm9kZT4sIG1hdGNoZXM6IERlYnVnTm9kZVtdLFxuICAgIGVsZW1lbnRzT25seTogZmFsc2UpOiB2b2lkO1xuZnVuY3Rpb24gX3F1ZXJ5QWxsUjMoXG4gICAgcGFyZW50RWxlbWVudDogRGVidWdFbGVtZW50LCBwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z0VsZW1lbnQ+fFByZWRpY2F0ZTxEZWJ1Z05vZGU+LFxuICAgIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdfERlYnVnTm9kZVtdLCBlbGVtZW50c09ubHk6IGJvb2xlYW4pIHtcbiAgY29uc3QgY29udGV4dCA9IGdldExDb250ZXh0KHBhcmVudEVsZW1lbnQubmF0aXZlTm9kZSk7XG4gIGlmIChjb250ZXh0ICE9PSBudWxsKSB7XG4gICAgY29uc3QgcGFyZW50VE5vZGUgPSBjb250ZXh0LmxWaWV3W1RWSUVXXS5kYXRhW2NvbnRleHQubm9kZUluZGV4XSBhcyBUTm9kZTtcbiAgICBfcXVlcnlOb2RlQ2hpbGRyZW5SMyhcbiAgICAgICAgcGFyZW50VE5vZGUsIGNvbnRleHQubFZpZXcsIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LCBwYXJlbnRFbGVtZW50Lm5hdGl2ZU5vZGUpO1xuICB9IGVsc2Uge1xuICAgIC8vIElmIHRoZSBjb250ZXh0IGlzIG51bGwsIHRoZW4gYHBhcmVudEVsZW1lbnRgIHdhcyBlaXRoZXIgY3JlYXRlZCB3aXRoIFJlbmRlcmVyMiBvciBuYXRpdmUgRE9NXG4gICAgLy8gQVBJcy5cbiAgICBfcXVlcnlOYXRpdmVOb2RlRGVzY2VuZGFudHMocGFyZW50RWxlbWVudC5uYXRpdmVOb2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBtYXRjaCB0aGUgY3VycmVudCBUTm9kZSBhZ2FpbnN0IHRoZSBwcmVkaWNhdGUsIGFuZCBnb2VzIG9uIHdpdGggdGhlIG5leHQgb25lcy5cbiAqXG4gKiBAcGFyYW0gdE5vZGUgdGhlIGN1cnJlbnQgVE5vZGVcbiAqIEBwYXJhbSBsVmlldyB0aGUgTFZpZXcgb2YgdGhpcyBUTm9kZVxuICogQHBhcmFtIHByZWRpY2F0ZSB0aGUgcHJlZGljYXRlIHRvIG1hdGNoXG4gKiBAcGFyYW0gbWF0Y2hlcyB0aGUgbGlzdCBvZiBwb3NpdGl2ZSBtYXRjaGVzXG4gKiBAcGFyYW0gZWxlbWVudHNPbmx5IHdoZXRoZXIgb25seSBlbGVtZW50cyBzaG91bGQgYmUgc2VhcmNoZWRcbiAqIEBwYXJhbSByb290TmF0aXZlTm9kZSB0aGUgcm9vdCBuYXRpdmUgbm9kZSBvbiB3aGljaCBwcmVkaWNhdGUgc2hvdWxkIG5vdCBiZSBtYXRjaGVkXG4gKi9cbmZ1bmN0aW9uIF9xdWVyeU5vZGVDaGlsZHJlblIzKFxuICAgIHROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3LCBwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z0VsZW1lbnQ+fFByZWRpY2F0ZTxEZWJ1Z05vZGU+LFxuICAgIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdfERlYnVnTm9kZVtdLCBlbGVtZW50c09ubHk6IGJvb2xlYW4sIHJvb3ROYXRpdmVOb2RlOiBhbnkpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydFROb2RlRm9yTFZpZXcodE5vZGUsIGxWaWV3KTtcbiAgY29uc3QgbmF0aXZlTm9kZSA9IGdldE5hdGl2ZUJ5VE5vZGVPck51bGwodE5vZGUsIGxWaWV3KTtcbiAgLy8gRm9yIGVhY2ggdHlwZSBvZiBUTm9kZSwgc3BlY2lmaWMgbG9naWMgaXMgZXhlY3V0ZWQuXG4gIGlmICh0Tm9kZS50eXBlICYgKFROb2RlVHlwZS5BbnlSTm9kZSB8IFROb2RlVHlwZS5FbGVtZW50Q29udGFpbmVyKSkge1xuICAgIC8vIENhc2UgMTogdGhlIFROb2RlIGlzIGFuIGVsZW1lbnRcbiAgICAvLyBUaGUgbmF0aXZlIG5vZGUgaGFzIHRvIGJlIGNoZWNrZWQuXG4gICAgX2FkZFF1ZXJ5TWF0Y2hSMyhuYXRpdmVOb2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSwgcm9vdE5hdGl2ZU5vZGUpO1xuICAgIGlmIChpc0NvbXBvbmVudEhvc3QodE5vZGUpKSB7XG4gICAgICAvLyBJZiB0aGUgZWxlbWVudCBpcyB0aGUgaG9zdCBvZiBhIGNvbXBvbmVudCwgdGhlbiBhbGwgbm9kZXMgaW4gaXRzIHZpZXcgaGF2ZSB0byBiZSBwcm9jZXNzZWQuXG4gICAgICAvLyBOb3RlOiB0aGUgY29tcG9uZW50J3MgY29udGVudCAodE5vZGUuY2hpbGQpIHdpbGwgYmUgcHJvY2Vzc2VkIGZyb20gdGhlIGluc2VydGlvbiBwb2ludHMuXG4gICAgICBjb25zdCBjb21wb25lbnRWaWV3ID0gZ2V0Q29tcG9uZW50TFZpZXdCeUluZGV4KHROb2RlLmluZGV4LCBsVmlldyk7XG4gICAgICBpZiAoY29tcG9uZW50VmlldyAmJiBjb21wb25lbnRWaWV3W1RWSUVXXS5maXJzdENoaWxkKSB7XG4gICAgICAgIF9xdWVyeU5vZGVDaGlsZHJlblIzKFxuICAgICAgICAgICAgY29tcG9uZW50Vmlld1tUVklFV10uZmlyc3RDaGlsZCEsIGNvbXBvbmVudFZpZXcsIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LFxuICAgICAgICAgICAgcm9vdE5hdGl2ZU5vZGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodE5vZGUuY2hpbGQpIHtcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdHMgY2hpbGRyZW4gaGF2ZSB0byBiZSBwcm9jZXNzZWQuXG4gICAgICAgIF9xdWVyeU5vZGVDaGlsZHJlblIzKHROb2RlLmNoaWxkLCBsVmlldywgcHJlZGljYXRlLCBtYXRjaGVzLCBlbGVtZW50c09ubHksIHJvb3ROYXRpdmVOb2RlKTtcbiAgICAgIH1cblxuICAgICAgLy8gV2UgYWxzbyBoYXZlIHRvIHF1ZXJ5IHRoZSBET00gZGlyZWN0bHkgaW4gb3JkZXIgdG8gY2F0Y2ggZWxlbWVudHMgaW5zZXJ0ZWQgdGhyb3VnaFxuICAgICAgLy8gUmVuZGVyZXIyLiBOb3RlIHRoYXQgdGhpcyBpcyBfX25vdF9fIG9wdGltYWwsIGJlY2F1c2Ugd2UncmUgd2Fsa2luZyBzaW1pbGFyIHRyZWVzIG11bHRpcGxlXG4gICAgICAvLyB0aW1lcy4gVmlld0VuZ2luZSBjb3VsZCBkbyBpdCBtb3JlIGVmZmljaWVudGx5LCBiZWNhdXNlIGFsbCB0aGUgaW5zZXJ0aW9ucyBnbyB0aHJvdWdoXG4gICAgICAvLyBSZW5kZXJlcjIsIGhvd2V2ZXIgdGhhdCdzIG5vdCB0aGUgY2FzZSBpbiBJdnkuIFRoaXMgYXBwcm9hY2ggaXMgYmVpbmcgdXNlZCBiZWNhdXNlOlxuICAgICAgLy8gMS4gTWF0Y2hpbmcgdGhlIFZpZXdFbmdpbmUgYmVoYXZpb3Igd291bGQgbWVhbiBwb3RlbnRpYWxseSBpbnRyb2R1Y2luZyBhIGRlcGVkZW5jeVxuICAgICAgLy8gICAgZnJvbSBgUmVuZGVyZXIyYCB0byBJdnkgd2hpY2ggY291bGQgYnJpbmcgSXZ5IGNvZGUgaW50byBWaWV3RW5naW5lLlxuICAgICAgLy8gMi4gV2Ugd291bGQgaGF2ZSB0byBtYWtlIGBSZW5kZXJlcjNgIFwia25vd1wiIGFib3V0IGRlYnVnIG5vZGVzLlxuICAgICAgLy8gMy4gSXQgYWxsb3dzIHVzIHRvIGNhcHR1cmUgbm9kZXMgdGhhdCB3ZXJlIGluc2VydGVkIGRpcmVjdGx5IHZpYSB0aGUgRE9NLlxuICAgICAgbmF0aXZlTm9kZSAmJiBfcXVlcnlOYXRpdmVOb2RlRGVzY2VuZGFudHMobmF0aXZlTm9kZSwgcHJlZGljYXRlLCBtYXRjaGVzLCBlbGVtZW50c09ubHkpO1xuICAgIH1cbiAgICAvLyBJbiBhbGwgY2FzZXMsIGlmIGEgZHluYW1pYyBjb250YWluZXIgZXhpc3RzIGZvciB0aGlzIG5vZGUsIGVhY2ggdmlldyBpbnNpZGUgaXQgaGFzIHRvIGJlXG4gICAgLy8gcHJvY2Vzc2VkLlxuICAgIGNvbnN0IG5vZGVPckNvbnRhaW5lciA9IGxWaWV3W3ROb2RlLmluZGV4XTtcbiAgICBpZiAoaXNMQ29udGFpbmVyKG5vZGVPckNvbnRhaW5lcikpIHtcbiAgICAgIF9xdWVyeU5vZGVDaGlsZHJlbkluQ29udGFpbmVyUjMoXG4gICAgICAgICAgbm9kZU9yQ29udGFpbmVyLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSwgcm9vdE5hdGl2ZU5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0Tm9kZS50eXBlICYgVE5vZGVUeXBlLkNvbnRhaW5lcikge1xuICAgIC8vIENhc2UgMjogdGhlIFROb2RlIGlzIGEgY29udGFpbmVyXG4gICAgLy8gVGhlIG5hdGl2ZSBub2RlIGhhcyB0byBiZSBjaGVja2VkLlxuICAgIGNvbnN0IGxDb250YWluZXIgPSBsVmlld1t0Tm9kZS5pbmRleF07XG4gICAgX2FkZFF1ZXJ5TWF0Y2hSMyhsQ29udGFpbmVyW05BVElWRV0sIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LCByb290TmF0aXZlTm9kZSk7XG4gICAgLy8gRWFjaCB2aWV3IGluc2lkZSB0aGUgY29udGFpbmVyIGhhcyB0byBiZSBwcm9jZXNzZWQuXG4gICAgX3F1ZXJ5Tm9kZUNoaWxkcmVuSW5Db250YWluZXJSMyhsQ29udGFpbmVyLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSwgcm9vdE5hdGl2ZU5vZGUpO1xuICB9IGVsc2UgaWYgKHROb2RlLnR5cGUgJiBUTm9kZVR5cGUuUHJvamVjdGlvbikge1xuICAgIC8vIENhc2UgMzogdGhlIFROb2RlIGlzIGEgcHJvamVjdGlvbiBpbnNlcnRpb24gcG9pbnQgKGkuZS4gYSA8bmctY29udGVudD4pLlxuICAgIC8vIFRoZSBub2RlcyBwcm9qZWN0ZWQgYXQgdGhpcyBsb2NhdGlvbiBhbGwgbmVlZCB0byBiZSBwcm9jZXNzZWQuXG4gICAgY29uc3QgY29tcG9uZW50VmlldyA9IGxWaWV3IVtERUNMQVJBVElPTl9DT01QT05FTlRfVklFV107XG4gICAgY29uc3QgY29tcG9uZW50SG9zdCA9IGNvbXBvbmVudFZpZXdbVF9IT1NUXSBhcyBURWxlbWVudE5vZGU7XG4gICAgY29uc3QgaGVhZDogVE5vZGV8bnVsbCA9XG4gICAgICAgIChjb21wb25lbnRIb3N0LnByb2plY3Rpb24gYXMgKFROb2RlIHwgbnVsbClbXSlbdE5vZGUucHJvamVjdGlvbiBhcyBudW1iZXJdO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaGVhZCkpIHtcbiAgICAgIGZvciAobGV0IG5hdGl2ZU5vZGUgb2YgaGVhZCkge1xuICAgICAgICBfYWRkUXVlcnlNYXRjaFIzKG5hdGl2ZU5vZGUsIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LCByb290TmF0aXZlTm9kZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChoZWFkKSB7XG4gICAgICBjb25zdCBuZXh0TFZpZXcgPSBjb21wb25lbnRWaWV3W1BBUkVOVF0hIGFzIExWaWV3O1xuICAgICAgY29uc3QgbmV4dFROb2RlID0gbmV4dExWaWV3W1RWSUVXXS5kYXRhW2hlYWQuaW5kZXhdIGFzIFROb2RlO1xuICAgICAgX3F1ZXJ5Tm9kZUNoaWxkcmVuUjMobmV4dFROb2RlLCBuZXh0TFZpZXcsIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LCByb290TmF0aXZlTm9kZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHROb2RlLmNoaWxkKSB7XG4gICAgLy8gQ2FzZSA0OiB0aGUgVE5vZGUgaXMgYSB2aWV3LlxuICAgIF9xdWVyeU5vZGVDaGlsZHJlblIzKHROb2RlLmNoaWxkLCBsVmlldywgcHJlZGljYXRlLCBtYXRjaGVzLCBlbGVtZW50c09ubHksIHJvb3ROYXRpdmVOb2RlKTtcbiAgfVxuXG4gIC8vIFdlIGRvbid0IHdhbnQgdG8gZ28gdG8gdGhlIG5leHQgc2libGluZyBvZiB0aGUgcm9vdCBub2RlLlxuICBpZiAocm9vdE5hdGl2ZU5vZGUgIT09IG5hdGl2ZU5vZGUpIHtcbiAgICAvLyBUbyBkZXRlcm1pbmUgdGhlIG5leHQgbm9kZSB0byBiZSBwcm9jZXNzZWQsIHdlIG5lZWQgdG8gdXNlIHRoZSBuZXh0IG9yIHRoZSBwcm9qZWN0aW9uTmV4dFxuICAgIC8vIGxpbmssIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBjdXJyZW50IG5vZGUgaGFzIGJlZW4gcHJvamVjdGVkLlxuICAgIGNvbnN0IG5leHRUTm9kZSA9ICh0Tm9kZS5mbGFncyAmIFROb2RlRmxhZ3MuaXNQcm9qZWN0ZWQpID8gdE5vZGUucHJvamVjdGlvbk5leHQgOiB0Tm9kZS5uZXh0O1xuICAgIGlmIChuZXh0VE5vZGUpIHtcbiAgICAgIF9xdWVyeU5vZGVDaGlsZHJlblIzKG5leHRUTm9kZSwgbFZpZXcsIHByZWRpY2F0ZSwgbWF0Y2hlcywgZWxlbWVudHNPbmx5LCByb290TmF0aXZlTm9kZSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUHJvY2VzcyBhbGwgVE5vZGVzIGluIGEgZ2l2ZW4gY29udGFpbmVyLlxuICpcbiAqIEBwYXJhbSBsQ29udGFpbmVyIHRoZSBjb250YWluZXIgdG8gYmUgcHJvY2Vzc2VkXG4gKiBAcGFyYW0gcHJlZGljYXRlIHRoZSBwcmVkaWNhdGUgdG8gbWF0Y2hcbiAqIEBwYXJhbSBtYXRjaGVzIHRoZSBsaXN0IG9mIHBvc2l0aXZlIG1hdGNoZXNcbiAqIEBwYXJhbSBlbGVtZW50c09ubHkgd2hldGhlciBvbmx5IGVsZW1lbnRzIHNob3VsZCBiZSBzZWFyY2hlZFxuICogQHBhcmFtIHJvb3ROYXRpdmVOb2RlIHRoZSByb290IG5hdGl2ZSBub2RlIG9uIHdoaWNoIHByZWRpY2F0ZSBzaG91bGQgbm90IGJlIG1hdGNoZWRcbiAqL1xuZnVuY3Rpb24gX3F1ZXJ5Tm9kZUNoaWxkcmVuSW5Db250YWluZXJSMyhcbiAgICBsQ29udGFpbmVyOiBMQ29udGFpbmVyLCBwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z0VsZW1lbnQ+fFByZWRpY2F0ZTxEZWJ1Z05vZGU+LFxuICAgIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdfERlYnVnTm9kZVtdLCBlbGVtZW50c09ubHk6IGJvb2xlYW4sIHJvb3ROYXRpdmVOb2RlOiBhbnkpIHtcbiAgZm9yIChsZXQgaSA9IENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUOyBpIDwgbENvbnRhaW5lci5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkVmlldyA9IGxDb250YWluZXJbaV0gYXMgTFZpZXc7XG4gICAgY29uc3QgZmlyc3RDaGlsZCA9IGNoaWxkVmlld1tUVklFV10uZmlyc3RDaGlsZDtcbiAgICBpZiAoZmlyc3RDaGlsZCkge1xuICAgICAgX3F1ZXJ5Tm9kZUNoaWxkcmVuUjMoZmlyc3RDaGlsZCwgY2hpbGRWaWV3LCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSwgcm9vdE5hdGl2ZU5vZGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoIHRoZSBjdXJyZW50IG5hdGl2ZSBub2RlIGFnYWluc3QgdGhlIHByZWRpY2F0ZS5cbiAqXG4gKiBAcGFyYW0gbmF0aXZlTm9kZSB0aGUgY3VycmVudCBuYXRpdmUgbm9kZVxuICogQHBhcmFtIHByZWRpY2F0ZSB0aGUgcHJlZGljYXRlIHRvIG1hdGNoXG4gKiBAcGFyYW0gbWF0Y2hlcyB0aGUgbGlzdCBvZiBwb3NpdGl2ZSBtYXRjaGVzXG4gKiBAcGFyYW0gZWxlbWVudHNPbmx5IHdoZXRoZXIgb25seSBlbGVtZW50cyBzaG91bGQgYmUgc2VhcmNoZWRcbiAqIEBwYXJhbSByb290TmF0aXZlTm9kZSB0aGUgcm9vdCBuYXRpdmUgbm9kZSBvbiB3aGljaCBwcmVkaWNhdGUgc2hvdWxkIG5vdCBiZSBtYXRjaGVkXG4gKi9cbmZ1bmN0aW9uIF9hZGRRdWVyeU1hdGNoUjMoXG4gICAgbmF0aXZlTm9kZTogYW55LCBwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z0VsZW1lbnQ+fFByZWRpY2F0ZTxEZWJ1Z05vZGU+LFxuICAgIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdfERlYnVnTm9kZVtdLCBlbGVtZW50c09ubHk6IGJvb2xlYW4sIHJvb3ROYXRpdmVOb2RlOiBhbnkpIHtcbiAgaWYgKHJvb3ROYXRpdmVOb2RlICE9PSBuYXRpdmVOb2RlKSB7XG4gICAgY29uc3QgZGVidWdOb2RlID0gZ2V0RGVidWdOb2RlKG5hdGl2ZU5vZGUpO1xuICAgIGlmICghZGVidWdOb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFR5cGUgb2YgdGhlIFwicHJlZGljYXRlIGFuZCBcIm1hdGNoZXNcIiBhcnJheSBhcmUgc2V0IGJhc2VkIG9uIHRoZSB2YWx1ZSBvZlxuICAgIC8vIHRoZSBcImVsZW1lbnRzT25seVwiIHBhcmFtZXRlci4gVHlwZVNjcmlwdCBpcyBub3QgYWJsZSB0byBwcm9wZXJseSBpbmZlciB0aGVzZVxuICAgIC8vIHR5cGVzIHdpdGggZ2VuZXJpY3MsIHNvIHdlIG1hbnVhbGx5IGNhc3QgdGhlIHBhcmFtZXRlcnMgYWNjb3JkaW5nbHkuXG4gICAgaWYgKGVsZW1lbnRzT25seSAmJiBkZWJ1Z05vZGUgaW5zdGFuY2VvZiBEZWJ1Z0VsZW1lbnRfX1BPU1RfUjNfXyAmJiBwcmVkaWNhdGUoZGVidWdOb2RlKSAmJlxuICAgICAgICBtYXRjaGVzLmluZGV4T2YoZGVidWdOb2RlKSA9PT0gLTEpIHtcbiAgICAgIG1hdGNoZXMucHVzaChkZWJ1Z05vZGUpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICFlbGVtZW50c09ubHkgJiYgKHByZWRpY2F0ZSBhcyBQcmVkaWNhdGU8RGVidWdOb2RlPikoZGVidWdOb2RlKSAmJlxuICAgICAgICAobWF0Y2hlcyBhcyBEZWJ1Z05vZGVbXSkuaW5kZXhPZihkZWJ1Z05vZGUpID09PSAtMSkge1xuICAgICAgKG1hdGNoZXMgYXMgRGVidWdOb2RlW10pLnB1c2goZGVidWdOb2RlKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaCBhbGwgdGhlIGRlc2NlbmRhbnRzIG9mIGEgRE9NIG5vZGUgYWdhaW5zdCBhIHByZWRpY2F0ZS5cbiAqXG4gKiBAcGFyYW0gbmF0aXZlTm9kZSB0aGUgY3VycmVudCBuYXRpdmUgbm9kZVxuICogQHBhcmFtIHByZWRpY2F0ZSB0aGUgcHJlZGljYXRlIHRvIG1hdGNoXG4gKiBAcGFyYW0gbWF0Y2hlcyB0aGUgbGlzdCB3aGVyZSBtYXRjaGVzIGFyZSBzdG9yZWRcbiAqIEBwYXJhbSBlbGVtZW50c09ubHkgd2hldGhlciBvbmx5IGVsZW1lbnRzIHNob3VsZCBiZSBzZWFyY2hlZFxuICovXG5mdW5jdGlvbiBfcXVlcnlOYXRpdmVOb2RlRGVzY2VuZGFudHMoXG4gICAgcGFyZW50Tm9kZTogYW55LCBwcmVkaWNhdGU6IFByZWRpY2F0ZTxEZWJ1Z0VsZW1lbnQ+fFByZWRpY2F0ZTxEZWJ1Z05vZGU+LFxuICAgIG1hdGNoZXM6IERlYnVnRWxlbWVudFtdfERlYnVnTm9kZVtdLCBlbGVtZW50c09ubHk6IGJvb2xlYW4pIHtcbiAgY29uc3Qgbm9kZXMgPSBwYXJlbnROb2RlLmNoaWxkTm9kZXM7XG4gIGNvbnN0IGxlbmd0aCA9IG5vZGVzLmxlbmd0aDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgbm9kZSA9IG5vZGVzW2ldO1xuICAgIGNvbnN0IGRlYnVnTm9kZSA9IGdldERlYnVnTm9kZShub2RlKTtcblxuICAgIGlmIChkZWJ1Z05vZGUpIHtcbiAgICAgIGlmIChlbGVtZW50c09ubHkgJiYgZGVidWdOb2RlIGluc3RhbmNlb2YgRGVidWdFbGVtZW50X19QT1NUX1IzX18gJiYgcHJlZGljYXRlKGRlYnVnTm9kZSkgJiZcbiAgICAgICAgICBtYXRjaGVzLmluZGV4T2YoZGVidWdOb2RlKSA9PT0gLTEpIHtcbiAgICAgICAgbWF0Y2hlcy5wdXNoKGRlYnVnTm9kZSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICFlbGVtZW50c09ubHkgJiYgKHByZWRpY2F0ZSBhcyBQcmVkaWNhdGU8RGVidWdOb2RlPikoZGVidWdOb2RlKSAmJlxuICAgICAgICAgIChtYXRjaGVzIGFzIERlYnVnTm9kZVtdKS5pbmRleE9mKGRlYnVnTm9kZSkgPT09IC0xKSB7XG4gICAgICAgIChtYXRjaGVzIGFzIERlYnVnTm9kZVtdKS5wdXNoKGRlYnVnTm9kZSk7XG4gICAgICB9XG5cbiAgICAgIF9xdWVyeU5hdGl2ZU5vZGVEZXNjZW5kYW50cyhub2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMsIGVsZW1lbnRzT25seSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcHJvcGVydHkgYmluZGluZ3MgZm9yIGEgZ2l2ZW4gbm9kZSBhbmQgZ2VuZXJhdGVzXG4gKiBhIG1hcCBvZiBwcm9wZXJ0eSBuYW1lcyB0byB2YWx1ZXMuIFRoaXMgbWFwIG9ubHkgY29udGFpbnMgcHJvcGVydHkgYmluZGluZ3NcbiAqIGRlZmluZWQgaW4gdGVtcGxhdGVzLCBub3QgaW4gaG9zdCBiaW5kaW5ncy5cbiAqL1xuZnVuY3Rpb24gY29sbGVjdFByb3BlcnR5QmluZGluZ3MoXG4gICAgcHJvcGVydGllczoge1trZXk6IHN0cmluZ106IHN0cmluZ30sIHROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3LCB0RGF0YTogVERhdGEpOiB2b2lkIHtcbiAgbGV0IGJpbmRpbmdJbmRleGVzID0gdE5vZGUucHJvcGVydHlCaW5kaW5ncztcblxuICBpZiAoYmluZGluZ0luZGV4ZXMgIT09IG51bGwpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJpbmRpbmdJbmRleGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBiaW5kaW5nSW5kZXggPSBiaW5kaW5nSW5kZXhlc1tpXTtcbiAgICAgIGNvbnN0IHByb3BNZXRhZGF0YSA9IHREYXRhW2JpbmRpbmdJbmRleF0gYXMgc3RyaW5nO1xuICAgICAgY29uc3QgbWV0YWRhdGFQYXJ0cyA9IHByb3BNZXRhZGF0YS5zcGxpdChJTlRFUlBPTEFUSU9OX0RFTElNSVRFUik7XG4gICAgICBjb25zdCBwcm9wZXJ0eU5hbWUgPSBtZXRhZGF0YVBhcnRzWzBdO1xuICAgICAgaWYgKG1ldGFkYXRhUGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsZXQgdmFsdWUgPSBtZXRhZGF0YVBhcnRzWzFdO1xuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IG1ldGFkYXRhUGFydHMubGVuZ3RoIC0gMTsgaisrKSB7XG4gICAgICAgICAgdmFsdWUgKz0gcmVuZGVyU3RyaW5naWZ5KGxWaWV3W2JpbmRpbmdJbmRleCArIGogLSAxXSkgKyBtZXRhZGF0YVBhcnRzW2ogKyAxXTtcbiAgICAgICAgfVxuICAgICAgICBwcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXSA9IGxWaWV3W2JpbmRpbmdJbmRleF07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuLy8gTmVlZCB0byBrZWVwIHRoZSBub2RlcyBpbiBhIGdsb2JhbCBNYXAgc28gdGhhdCBtdWx0aXBsZSBhbmd1bGFyIGFwcHMgYXJlIHN1cHBvcnRlZC5cbmNvbnN0IF9uYXRpdmVOb2RlVG9EZWJ1Z05vZGUgPSBuZXcgTWFwPGFueSwgRGVidWdOb2RlPigpO1xuXG5mdW5jdGlvbiBnZXREZWJ1Z05vZGVfX1BSRV9SM19fKG5hdGl2ZU5vZGU6IGFueSk6IERlYnVnTm9kZXxudWxsIHtcbiAgcmV0dXJuIF9uYXRpdmVOb2RlVG9EZWJ1Z05vZGUuZ2V0KG5hdGl2ZU5vZGUpIHx8IG51bGw7XG59XG5cbmNvbnN0IE5HX0RFQlVHX1BST1BFUlRZID0gJ19fbmdfZGVidWdfXyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWJ1Z05vZGVfX1BPU1RfUjNfXyhuYXRpdmVOb2RlOiBFbGVtZW50KTogRGVidWdFbGVtZW50X19QT1NUX1IzX187XG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVidWdOb2RlX19QT1NUX1IzX18obmF0aXZlTm9kZTogTm9kZSk6IERlYnVnTm9kZV9fUE9TVF9SM19fO1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlYnVnTm9kZV9fUE9TVF9SM19fKG5hdGl2ZU5vZGU6IG51bGwpOiBudWxsO1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlYnVnTm9kZV9fUE9TVF9SM19fKG5hdGl2ZU5vZGU6IGFueSk6IERlYnVnTm9kZXxudWxsIHtcbiAgaWYgKG5hdGl2ZU5vZGUgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgaWYgKCEobmF0aXZlTm9kZS5oYXNPd25Qcm9wZXJ0eShOR19ERUJVR19QUk9QRVJUWSkpKSB7XG4gICAgICAobmF0aXZlTm9kZSBhcyBhbnkpW05HX0RFQlVHX1BST1BFUlRZXSA9IG5hdGl2ZU5vZGUubm9kZVR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUgP1xuICAgICAgICAgIG5ldyBEZWJ1Z0VsZW1lbnRfX1BPU1RfUjNfXyhuYXRpdmVOb2RlIGFzIEVsZW1lbnQpIDpcbiAgICAgICAgICBuZXcgRGVidWdOb2RlX19QT1NUX1IzX18obmF0aXZlTm9kZSk7XG4gICAgfVxuICAgIHJldHVybiAobmF0aXZlTm9kZSBhcyBhbnkpW05HX0RFQlVHX1BST1BFUlRZXTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjb25zdCBnZXREZWJ1Z05vZGU6IChuYXRpdmVOb2RlOiBhbnkpID0+IERlYnVnTm9kZSB8IG51bGwgPSBnZXREZWJ1Z05vZGVfX1BSRV9SM19fO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWJ1Z05vZGVSMl9fUFJFX1IzX18obmF0aXZlTm9kZTogYW55KTogRGVidWdOb2RlfG51bGwge1xuICByZXR1cm4gZ2V0RGVidWdOb2RlX19QUkVfUjNfXyhuYXRpdmVOb2RlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlYnVnTm9kZVIyX19QT1NUX1IzX18oX25hdGl2ZU5vZGU6IGFueSk6IERlYnVnTm9kZXxudWxsIHtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBjb25zdCBnZXREZWJ1Z05vZGVSMjogKG5hdGl2ZU5vZGU6IGFueSkgPT4gRGVidWdOb2RlIHwgbnVsbCA9IGdldERlYnVnTm9kZVIyX19QUkVfUjNfXztcblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsRGVidWdOb2RlcygpOiBEZWJ1Z05vZGVbXSB7XG4gIHJldHVybiBBcnJheS5mcm9tKF9uYXRpdmVOb2RlVG9EZWJ1Z05vZGUudmFsdWVzKCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5kZXhEZWJ1Z05vZGUobm9kZTogRGVidWdOb2RlKSB7XG4gIF9uYXRpdmVOb2RlVG9EZWJ1Z05vZGUuc2V0KG5vZGUubmF0aXZlTm9kZSwgbm9kZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVEZWJ1Z05vZGVGcm9tSW5kZXgobm9kZTogRGVidWdOb2RlKSB7XG4gIF9uYXRpdmVOb2RlVG9EZWJ1Z05vZGUuZGVsZXRlKG5vZGUubmF0aXZlTm9kZSk7XG59XG5cbi8qKlxuICogQSBib29sZWFuLXZhbHVlZCBmdW5jdGlvbiBvdmVyIGEgdmFsdWUsIHBvc3NpYmx5IGluY2x1ZGluZyBjb250ZXh0IGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgdGhhdCB2YWx1ZSdzIHBvc2l0aW9uIGluIGFuIGFycmF5LlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVkaWNhdGU8VD4ge1xuICAodmFsdWU6IFQpOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNvbnN0IERlYnVnTm9kZToge25ldyAoLi4uYXJnczogYW55W10pOiBEZWJ1Z05vZGV9ID0gRGVidWdOb2RlX19QUkVfUjNfXztcblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjb25zdCBEZWJ1Z0VsZW1lbnQ6IHtuZXcgKC4uLmFyZ3M6IGFueVtdKTogRGVidWdFbGVtZW50fSA9IERlYnVnRWxlbWVudF9fUFJFX1IzX187XG4iXX0=
\No newline at end of file