package.esm2022.src.navigation_transition.mjs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of router Show documentation
Show all versions of router Show documentation
Angular - the routing library
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Location } from '@angular/common';
import { EnvironmentInjector, inject, Injectable, InjectionToken, runInInjectionContext, } from '@angular/core';
import { BehaviorSubject, combineLatest, EMPTY, from, of, Subject } from 'rxjs';
import { catchError, defaultIfEmpty, filter, finalize, map, switchMap, take, takeUntil, tap, } from 'rxjs/operators';
import { createRouterState } from './create_router_state';
import { INPUT_BINDER } from './directives/router_outlet';
import { BeforeActivateRoutes, GuardsCheckEnd, GuardsCheckStart, IMPERATIVE_NAVIGATION, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationError, NavigationSkipped, NavigationSkippedCode, NavigationStart, RedirectRequest, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized, } from './events';
import { RedirectCommand, } from './models';
import { isNavigationCancelingError, isRedirectingNavigationCancelingError, redirectingNavigationError, } from './navigation_canceling_error';
import { activateRoutes } from './operators/activate_routes';
import { checkGuards } from './operators/check_guards';
import { recognize } from './operators/recognize';
import { resolveData } from './operators/resolve_data';
import { switchTap } from './operators/switch_tap';
import { TitleStrategy } from './page_title_strategy';
import { ROUTER_CONFIGURATION } from './router_config';
import { RouterConfigLoader } from './router_config_loader';
import { ChildrenOutletContexts } from './router_outlet_context';
import { createEmptyState, } from './router_state';
import { UrlHandlingStrategy } from './url_handling_strategy';
import { UrlSerializer } from './url_tree';
import { getAllRouteGuards } from './utils/preactivation';
import { CREATE_VIEW_TRANSITION } from './utils/view_transition';
import * as i0 from "@angular/core";
export const NAVIGATION_ERROR_HANDLER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'navigation error handler' : '');
export class NavigationTransitions {
get hasRequestedNavigation() {
return this.navigationId !== 0;
}
constructor() {
this.currentNavigation = null;
this.currentTransition = null;
this.lastSuccessfulNavigation = null;
/**
* These events are used to communicate back to the Router about the state of the transition. The
* Router wants to respond to these events in various ways. Because the `NavigationTransition`
* class is not public, this event subject is not publicly exposed.
*/
this.events = new Subject();
/**
* Used to abort the current transition with an error.
*/
this.transitionAbortSubject = new Subject();
this.configLoader = inject(RouterConfigLoader);
this.environmentInjector = inject(EnvironmentInjector);
this.urlSerializer = inject(UrlSerializer);
this.rootContexts = inject(ChildrenOutletContexts);
this.location = inject(Location);
this.inputBindingEnabled = inject(INPUT_BINDER, { optional: true }) !== null;
this.titleStrategy = inject(TitleStrategy);
this.options = inject(ROUTER_CONFIGURATION, { optional: true }) || {};
this.paramsInheritanceStrategy = this.options.paramsInheritanceStrategy || 'emptyOnly';
this.urlHandlingStrategy = inject(UrlHandlingStrategy);
this.createViewTransition = inject(CREATE_VIEW_TRANSITION, { optional: true });
this.navigationErrorHandler = inject(NAVIGATION_ERROR_HANDLER, { optional: true });
this.navigationId = 0;
/**
* Hook that enables you to pause navigation after the preactivation phase.
* Used by `RouterModule`.
*
* @internal
*/
this.afterPreactivation = () => of(void 0);
/** @internal */
this.rootComponentType = null;
const onLoadStart = (r) => this.events.next(new RouteConfigLoadStart(r));
const onLoadEnd = (r) => this.events.next(new RouteConfigLoadEnd(r));
this.configLoader.onLoadEndListener = onLoadEnd;
this.configLoader.onLoadStartListener = onLoadStart;
}
complete() {
this.transitions?.complete();
}
handleNavigationRequest(request) {
const id = ++this.navigationId;
this.transitions?.next({ ...this.transitions.value, ...request, id });
}
setupNavigations(router, initialUrlTree, initialRouterState) {
this.transitions = new BehaviorSubject({
id: 0,
currentUrlTree: initialUrlTree,
currentRawUrl: initialUrlTree,
extractedUrl: this.urlHandlingStrategy.extract(initialUrlTree),
urlAfterRedirects: this.urlHandlingStrategy.extract(initialUrlTree),
rawUrl: initialUrlTree,
extras: {},
resolve: () => { },
reject: () => { },
promise: Promise.resolve(true),
source: IMPERATIVE_NAVIGATION,
restoredState: null,
currentSnapshot: initialRouterState.snapshot,
targetSnapshot: null,
currentRouterState: initialRouterState,
targetRouterState: null,
guards: { canActivateChecks: [], canDeactivateChecks: [] },
guardsResult: null,
});
return this.transitions.pipe(filter((t) => t.id !== 0),
// Extract URL
map((t) => ({
...t,
extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl),
})),
// Using switchMap so we cancel executing navigations when a new one comes in
switchMap((overallTransitionState) => {
let completed = false;
let errored = false;
return of(overallTransitionState).pipe(switchMap((t) => {
// It is possible that `switchMap` fails to cancel previous navigations if a new one happens synchronously while the operator
// is processing the `next` notification of that previous navigation. This can happen when a new navigation (say 2) cancels a
// previous one (1) and yet another navigation (3) happens synchronously in response to the `NavigationCancel` event for (1).
// https://github.com/ReactiveX/rxjs/issues/7455
if (this.navigationId > overallTransitionState.id) {
const cancellationReason = typeof ngDevMode === 'undefined' || ngDevMode
? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}`
: '';
this.cancelNavigationTransition(overallTransitionState, cancellationReason, NavigationCancellationCode.SupersededByNewNavigation);
return EMPTY;
}
this.currentTransition = overallTransitionState;
// Store the Navigation object
this.currentNavigation = {
id: t.id,
initialUrl: t.rawUrl,
extractedUrl: t.extractedUrl,
targetBrowserUrl: typeof t.extras.browserUrl === 'string'
? this.urlSerializer.parse(t.extras.browserUrl)
: t.extras.browserUrl,
trigger: t.source,
extras: t.extras,
previousNavigation: !this.lastSuccessfulNavigation
? null
: {
...this.lastSuccessfulNavigation,
previousNavigation: null,
},
};
const urlTransition = !router.navigated || this.isUpdatingInternalState() || this.isUpdatedBrowserUrl();
const onSameUrlNavigation = t.extras.onSameUrlNavigation ?? router.onSameUrlNavigation;
if (!urlTransition && onSameUrlNavigation !== 'reload') {
const reason = typeof ngDevMode === 'undefined' || ngDevMode
? `Navigation to ${t.rawUrl} was ignored because it is the same as the current Router URL.`
: '';
this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.rawUrl), reason, NavigationSkippedCode.IgnoredSameUrlNavigation));
t.resolve(false);
return EMPTY;
}
if (this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl)) {
return of(t).pipe(
// Fire NavigationStart event
switchMap((t) => {
const transition = this.transitions?.getValue();
this.events.next(new NavigationStart(t.id, this.urlSerializer.serialize(t.extractedUrl), t.source, t.restoredState));
if (transition !== this.transitions?.getValue()) {
return EMPTY;
}
// This delay is required to match old behavior that forced
// navigation to always be async
return Promise.resolve(t);
}),
// Recognize
recognize(this.environmentInjector, this.configLoader, this.rootComponentType, router.config, this.urlSerializer, this.paramsInheritanceStrategy),
// Update URL if in `eager` update mode
tap((t) => {
overallTransitionState.targetSnapshot = t.targetSnapshot;
overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
this.currentNavigation = {
...this.currentNavigation,
finalUrl: t.urlAfterRedirects,
};
// Fire RoutesRecognized
const routesRecognized = new RoutesRecognized(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
this.events.next(routesRecognized);
}));
}
else if (urlTransition &&
this.urlHandlingStrategy.shouldProcessUrl(t.currentRawUrl)) {
/* When the current URL shouldn't be processed, but the previous one
* was, we handle this "error condition" by navigating to the
* previously successful URL, but leaving the URL intact.*/
const { id, extractedUrl, source, restoredState, extras } = t;
const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState);
this.events.next(navStart);
const targetSnapshot = createEmptyState(this.rootComponentType).snapshot;
this.currentTransition = overallTransitionState = {
...t,
targetSnapshot,
urlAfterRedirects: extractedUrl,
extras: { ...extras, skipLocationChange: false, replaceUrl: false },
};
this.currentNavigation.finalUrl = extractedUrl;
return of(overallTransitionState);
}
else {
/* When neither the current or previous URL can be processed, do
* nothing other than update router's internal reference to the
* current "settled" URL. This way the next navigation will be coming
* from the current URL in the browser.
*/
const reason = typeof ngDevMode === 'undefined' || ngDevMode
? `Navigation was ignored because the UrlHandlingStrategy` +
` indicated neither the current URL ${t.currentRawUrl} nor target URL ${t.rawUrl} should be processed.`
: '';
this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, NavigationSkippedCode.IgnoredByUrlHandlingStrategy));
t.resolve(false);
return EMPTY;
}
}),
// --- GUARDS ---
tap((t) => {
const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
this.events.next(guardsStart);
}), map((t) => {
this.currentTransition = overallTransitionState = {
...t,
guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts),
};
return overallTransitionState;
}), checkGuards(this.environmentInjector, (evt) => this.events.next(evt)), tap((t) => {
overallTransitionState.guardsResult = t.guardsResult;
if (t.guardsResult && typeof t.guardsResult !== 'boolean') {
throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
}
const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
this.events.next(guardsEnd);
}), filter((t) => {
if (!t.guardsResult) {
this.cancelNavigationTransition(t, '', NavigationCancellationCode.GuardRejected);
return false;
}
return true;
}),
// --- RESOLVE ---
switchTap((t) => {
if (t.guards.canActivateChecks.length) {
return of(t).pipe(tap((t) => {
const resolveStart = new ResolveStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
this.events.next(resolveStart);
}), switchMap((t) => {
let dataResolved = false;
return of(t).pipe(resolveData(this.paramsInheritanceStrategy, this.environmentInjector), tap({
next: () => (dataResolved = true),
complete: () => {
if (!dataResolved) {
this.cancelNavigationTransition(t, typeof ngDevMode === 'undefined' || ngDevMode
? `At least one route resolver didn't emit any value.`
: '', NavigationCancellationCode.NoDataFromResolver);
}
},
}));
}), tap((t) => {
const resolveEnd = new ResolveEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
this.events.next(resolveEnd);
}));
}
return undefined;
}),
// --- LOAD COMPONENTS ---
switchTap((t) => {
const loadComponents = (route) => {
const loaders = [];
if (route.routeConfig?.loadComponent && !route.routeConfig._loadedComponent) {
loaders.push(this.configLoader.loadComponent(route.routeConfig).pipe(tap((loadedComponent) => {
route.component = loadedComponent;
}), map(() => void 0)));
}
for (const child of route.children) {
loaders.push(...loadComponents(child));
}
return loaders;
};
return combineLatest(loadComponents(t.targetSnapshot.root)).pipe(defaultIfEmpty(null), take(1));
}), switchTap(() => this.afterPreactivation()), switchMap(() => {
const { currentSnapshot, targetSnapshot } = overallTransitionState;
const viewTransitionStarted = this.createViewTransition?.(this.environmentInjector, currentSnapshot.root, targetSnapshot.root);
// If view transitions are enabled, block the navigation until the view
// transition callback starts. Otherwise, continue immediately.
return viewTransitionStarted
? from(viewTransitionStarted).pipe(map(() => overallTransitionState))
: of(overallTransitionState);
}), map((t) => {
const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
this.currentTransition = overallTransitionState = { ...t, targetRouterState };
this.currentNavigation.targetRouterState = targetRouterState;
return overallTransitionState;
}), tap(() => {
this.events.next(new BeforeActivateRoutes());
}), activateRoutes(this.rootContexts, router.routeReuseStrategy, (evt) => this.events.next(evt), this.inputBindingEnabled),
// Ensure that if some observable used to drive the transition doesn't
// complete, the navigation still finalizes This should never happen, but
// this is done as a safety measure to avoid surfacing this error (#49567).
take(1), tap({
next: (t) => {
completed = true;
this.lastSuccessfulNavigation = this.currentNavigation;
this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects)));
this.titleStrategy?.updateTitle(t.targetRouterState.snapshot);
t.resolve(true);
},
complete: () => {
completed = true;
},
}),
// There used to be a lot more logic happening directly within the
// transition Observable. Some of this logic has been refactored out to
// other places but there may still be errors that happen there. This gives
// us a way to cancel the transition from the outside. This may also be
// required in the future to support something like the abort signal of the
// Navigation API where the navigation gets aborted from outside the
// transition.
takeUntil(this.transitionAbortSubject.pipe(tap((err) => {
throw err;
}))), finalize(() => {
/* When the navigation stream finishes either through error or success,
* we set the `completed` or `errored` flag. However, there are some
* situations where we could get here without either of those being set.
* For instance, a redirect during NavigationStart. Therefore, this is a
* catch-all to make sure the NavigationCancel event is fired when a
* navigation gets cancelled but not caught by other means. */
if (!completed && !errored) {
const cancelationReason = typeof ngDevMode === 'undefined' || ngDevMode
? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}`
: '';
this.cancelNavigationTransition(overallTransitionState, cancelationReason, NavigationCancellationCode.SupersededByNewNavigation);
}
// Only clear current navigation if it is still set to the one that
// finalized.
if (this.currentTransition?.id === overallTransitionState.id) {
this.currentNavigation = null;
this.currentTransition = null;
}
}), catchError((e) => {
errored = true;
/* This error type is issued during Redirect, and is handled as a
* cancellation rather than an error. */
if (isNavigationCancelingError(e)) {
this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode));
// When redirecting, we need to delay resolving the navigation
// promise and push it to the redirect navigation
if (!isRedirectingNavigationCancelingError(e)) {
overallTransitionState.resolve(false);
}
else {
this.events.next(new RedirectRequest(e.url, e.navigationBehaviorOptions));
}
/* All other errors should reset to the router's internal URL reference
* to the pre-error state. */
}
else {
const navigationError = new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
try {
const navigationErrorHandlerResult = runInInjectionContext(this.environmentInjector, () => this.navigationErrorHandler?.(navigationError));
if (navigationErrorHandlerResult instanceof RedirectCommand) {
const { message, cancellationCode } = redirectingNavigationError(this.urlSerializer, navigationErrorHandlerResult);
this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), message, cancellationCode));
this.events.next(new RedirectRequest(navigationErrorHandlerResult.redirectTo, navigationErrorHandlerResult.navigationBehaviorOptions));
}
else {
this.events.next(navigationError);
// TODO(atscott): remove deprecation on errorHandler in RouterModule.forRoot and change behavior to provide NAVIGATION_ERROR_HANDLER
// Note: Still remove public `Router.errorHandler` property, as this is supposed to be configured in DI.
const errorHandlerResult = router.errorHandler(e);
overallTransitionState.resolve(!!errorHandlerResult);
}
}
catch (ee) {
// TODO(atscott): consider flipping the default behavior of
// resolveNavigationPromiseOnError to be `resolve(false)` when
// undefined. This is the most sane thing to do given that
// applications very rarely handle the promise rejection and, as a
// result, would get "unhandled promise rejection" console logs.
// The vast majority of applications would not be affected by this
// change so omitting a migration seems reasonable. Instead,
// applications that rely on rejection can specifically opt-in to the
// old behavior.
if (this.options.resolveNavigationPromiseOnError) {
overallTransitionState.resolve(false);
}
else {
overallTransitionState.reject(ee);
}
}
}
return EMPTY;
}));
// casting because `pipe` returns observable({}) when called with 8+ arguments
}));
}
cancelNavigationTransition(t, reason, code) {
const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code);
this.events.next(navCancel);
t.resolve(false);
}
/**
* @returns Whether we're navigating to somewhere that is not what the Router is
* currently set to.
*/
isUpdatingInternalState() {
// TODO(atscott): The serializer should likely be used instead of
// `UrlTree.toString()`. Custom serializers are often written to handle
// things better than the default one (objects, for example will be
// [Object object] with the custom serializer and be "the same" when they
// aren't).
// (Same for isUpdatedBrowserUrl)
return (this.currentTransition?.extractedUrl.toString() !==
this.currentTransition?.currentUrlTree.toString());
}
/**
* @returns Whether we're updating the browser URL to something new (navigation is going
* to somewhere not displayed in the URL bar and we will update the URL
* bar if navigation succeeds).
*/
isUpdatedBrowserUrl() {
// The extracted URL is the part of the URL that this application cares about. `extract` may
// return only part of the browser URL and that part may have not changed even if some other
// portion of the URL did.
const currentBrowserUrl = this.urlHandlingStrategy.extract(this.urlSerializer.parse(this.location.path(true)));
const targetBrowserUrl = this.currentNavigation?.targetBrowserUrl ?? this.currentNavigation?.extractedUrl;
return (currentBrowserUrl.toString() !== targetBrowserUrl?.toString() &&
!this.currentNavigation?.extras.skipLocationChange);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NavigationTransitions, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: NavigationTransitions, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [] });
export function isBrowserTriggeredNavigation(source) {
return source !== IMPERATIVE_NAVIGATION;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbl90cmFuc2l0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9uYXZpZ2F0aW9uX3RyYW5zaXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsTUFBTSxFQUNOLFVBQVUsRUFDVixjQUFjLEVBQ2QscUJBQXFCLEdBRXRCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyxlQUFlLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUMxRixPQUFPLEVBQ0wsVUFBVSxFQUNWLGNBQWMsRUFDZCxNQUFNLEVBQ04sUUFBUSxFQUNSLEdBQUcsRUFDSCxTQUFTLEVBQ1QsSUFBSSxFQUNKLFNBQVMsRUFDVCxHQUFHLEdBQ0osTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDeEQsT0FBTyxFQUNMLG9CQUFvQixFQUVwQixjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLHFCQUFxQixFQUNyQixnQkFBZ0IsRUFDaEIsMEJBQTBCLEVBQzFCLGFBQWEsRUFDYixlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQUNyQixlQUFlLEVBRWYsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osa0JBQWtCLEVBQ2xCLG9CQUFvQixFQUNwQixnQkFBZ0IsR0FDakIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUlMLGVBQWUsR0FHaEIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUNMLDBC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QyxJQUFJLENBQUMsQ0FBQyxDQUNuRCxDQUFDO1FBQ0YsTUFBTSxnQkFBZ0IsR0FDcEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGdCQUFnQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxZQUFZLENBQUM7UUFDbkYsT0FBTyxDQUNMLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxLQUFLLGdCQUFnQixFQUFFLFFBQVEsRUFBRTtZQUM3RCxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUMsa0JBQWtCLENBQ25ELENBQUM7SUFDSixDQUFDO3lIQXhuQlUscUJBQXFCOzZIQUFyQixxQkFBcUIsY0FEVCxNQUFNOztzR0FDbEIscUJBQXFCO2tCQURqQyxVQUFVO21CQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQzs7QUE0bkJoQyxNQUFNLFVBQVUsNEJBQTRCLENBQUMsTUFBeUI7SUFDcEUsT0FBTyxNQUFNLEtBQUsscUJBQXFCLENBQUM7QUFDMUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmRldi9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEVudmlyb25tZW50SW5qZWN0b3IsXG4gIGluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIHJ1bkluSW5qZWN0aW9uQ29udGV4dCxcbiAgVHlwZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgRU1QVFksIGZyb20sIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIGRlZmF1bHRJZkVtcHR5LFxuICBmaWx0ZXIsXG4gIGZpbmFsaXplLFxuICBtYXAsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZSxcbiAgdGFrZVVudGlsLFxuICB0YXAsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtjcmVhdGVSb3V0ZXJTdGF0ZX0gZnJvbSAnLi9jcmVhdGVfcm91dGVyX3N0YXRlJztcbmltcG9ydCB7SU5QVVRfQklOREVSfSBmcm9tICcuL2RpcmVjdGl2ZXMvcm91dGVyX291dGxldCc7XG5pbXBvcnQge1xuICBCZWZvcmVBY3RpdmF0ZVJvdXRlcyxcbiAgRXZlbnQsXG4gIEd1YXJkc0NoZWNrRW5kLFxuICBHdWFyZHNDaGVja1N0YXJ0LFxuICBJTVBFUkFUSVZFX05BVklHQVRJT04sXG4gIE5hdmlnYXRpb25DYW5jZWwsXG4gIE5hdmlnYXRpb25DYW5jZWxsYXRpb25Db2RlLFxuICBOYXZpZ2F0aW9uRW5kLFxuICBOYXZpZ2F0aW9uRXJyb3IsXG4gIE5hdmlnYXRpb25Ta2lwcGVkLFxuICBOYXZpZ2F0aW9uU2tpcHBlZENvZGUsXG4gIE5hdmlnYXRpb25TdGFydCxcbiAgTmF2aWdhdGlvblRyaWdnZXIsXG4gIFJlZGlyZWN0UmVxdWVzdCxcbiAgUmVzb2x2ZUVuZCxcbiAgUmVzb2x2ZVN0YXJ0LFxuICBSb3V0ZUNvbmZpZ0xvYWRFbmQsXG4gIFJvdXRlQ29uZmlnTG9hZFN0YXJ0LFxuICBSb3V0ZXNSZWNvZ25pemVkLFxufSBmcm9tICcuL2V2ZW50cyc7XG5pbXBvcnQge1xuICBHdWFyZFJlc3VsdCxcbiAgTmF2aWdhdGlvbkJlaGF2aW9yT3B0aW9ucyxcbiAgUXVlcnlQYXJhbXNIYW5kbGluZyxcbiAgUmVkaXJlY3RDb21tYW5kLFxuICBSb3V0ZSxcbiAgUm91dGVzLFxufSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQge1xuICBpc05hdmlnYXRpb25DYW5jZWxpbmdFcnJvcixcbiAgaXNSZWRpcmVjdGluZ05hdmlnYXRpb25DYW5jZWxpbmdFcnJvcixcbiAgcmVkaXJlY3RpbmdOYXZpZ2F0aW9uRXJyb3IsXG59IGZyb20gJy4vbmF2aWdhdGlvbl9jYW5jZWxpbmdfZXJyb3InO1xuaW1wb3J0IHthY3RpdmF0ZVJvdXRlc30gZnJvbSAnLi9vcGVyYXRvcnMvYWN0aXZhdGVfcm91dGVzJztcbmltcG9ydCB7Y2hlY2tHdWFyZHN9IGZyb20gJy4vb3BlcmF0b3JzL2NoZWNrX2d1YXJkcyc7XG5pbXBvcnQge3JlY29nbml6ZX0gZnJvbSAnLi9vcGVyYXRvcnMvcmVjb2duaXplJztcbmltcG9ydCB7cmVzb2x2ZURhdGF9IGZyb20gJy4vb3BlcmF0b3JzL3Jlc29sdmVfZGF0YSc7XG5pbXBvcnQge3N3aXRjaFRhcH0gZnJvbSAnLi9vcGVyYXRvcnMvc3dpdGNoX3RhcCc7XG5pbXBvcnQge1RpdGxlU3RyYXRlZ3l9IGZyb20gJy4vcGFnZV90aXRsZV9zdHJhdGVneSc7XG5pbXBvcnQge1JvdXRlUmV1c2VTdHJhdGVneX0gZnJvbSAnLi9yb3V0ZV9yZXVzZV9zdHJhdGVneSc7XG5pbXBvcnQge1JPVVRFUl9DT05GSUdVUkFUSU9OfSBmcm9tICcuL3JvdXRlcl9jb25maWcnO1xuaW1wb3J0IHtSb3V0ZXJDb25maWdMb2FkZXJ9IGZyb20gJy4vcm91dGVyX2NvbmZpZ19sb2FkZXInO1xuaW1wb3J0IHtDaGlsZHJlbk91dGxldENvbnRleHRzfSBmcm9tICcuL3JvdXRlcl9vdXRsZXRfY29udGV4dCc7XG5pbXBvcnQge1xuICBBY3RpdmF0ZWRSb3V0ZSxcbiAgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcbiAgY3JlYXRlRW1wdHlTdGF0ZSxcbiAgUm91dGVyU3RhdGUsXG4gIFJvdXRlclN0YXRlU25hcHNob3QsXG59IGZyb20gJy4vcm91dGVyX3N0YXRlJztcbmltcG9ydCB7UGFyYW1zfSBmcm9tICcuL3NoYXJlZCc7XG5pbXBvcnQge1VybEhhbmRsaW5nU3RyYXRlZ3l9IGZyb20gJy4vdXJsX2hhbmRsaW5nX3N0cmF0ZWd5JztcbmltcG9ydCB7aXNVcmxUcmVlLCBVcmxTZXJpYWxpemVyLCBVcmxUcmVlfSBmcm9tICcuL3VybF90cmVlJztcbmltcG9ydCB7Q2hlY2tzLCBnZXRBbGxSb3V0ZUd1YXJkc30gZnJvbSAnLi91dGlscy9wcmVhY3RpdmF0aW9uJztcbmltcG9ydCB7Q1JFQVRFX1ZJRVdfVFJBTlNJVElPTn0gZnJvbSAnLi91dGlscy92aWV3X3RyYW5zaXRpb24nO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIE9wdGlvbnMgdGhhdCBtb2RpZnkgdGhlIGBSb3V0ZXJgIFVSTC5cbiAqIFN1cHBseSBhbiBvYmplY3QgY29udGFpbmluZyBhbnkgb2YgdGhlc2UgcHJvcGVydGllcyB0byBhIGBSb3V0ZXJgIG5hdmlnYXRpb24gZnVuY3Rpb24gdG9cbiAqIGNvbnRyb2wgaG93IHRoZSB0YXJnZXQgVVJMIHNob3VsZCBiZSBjb25zdHJ1Y3RlZC5cbiAqXG4gKiBAc2VlIHtAbGluayBSb3V0ZXIjbmF2aWdhdGV9XG4gKiBAc2VlIHtAbGluayBSb3V0ZXIjY3JlYXRlVXJsVHJlZX1cbiAqIEBzZWUgW1JvdXRpbmcgYW5kIE5hdmlnYXRpb24gZ3VpZGVdKGd1aWRlL3JvdXRpbmcvY29tbW9uLXJvdXRlci10YXNrcylcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVXJsQ3JlYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZmllcyBhIHJvb3QgVVJJIHRvIHVzZSBmb3IgcmVsYXRpdmUgbmF2aWdhdGlvbi5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgcm91dGUgY29uZmlndXJhdGlvbiB3aGVyZSB0aGUgcGFyZW50IHJvdXRlXG4gICAqIGhhcyB0d28gY2hpbGRyZW4uXG4gICAqXG4gICAqIGBgYFxuICAgKiBbe1xuICAgKiAgIHBhdGg6ICdwYXJlbnQnLFxuICAgKiAgIGNvbXBvbmVudDogUGFyZW50Q29tcG9uZW50LFxuICAgKiAgIGNoaWxkcmVuOiBbe1xuICAgKiAgICAgcGF0aDogJ2xpc3QnLFxuICAgKiAgICAgY29tcG9uZW50OiBMaXN0Q29tcG9uZW50XG4gICAqICAgfSx7XG4gICAqICAgICBwYXRoOiAnY2hpbGQnLFxuICAgKiAgICAgY29tcG9uZW50OiBDaGlsZENvbXBvbmVudFxuICAgKiAgIH1dXG4gICAqIH1dXG4gICAqIGBgYFxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGBnbygpYCBmdW5jdGlvbiBuYXZpZ2F0ZXMgdG8gdGhlIGBsaXN0YCByb3V0ZSBieVxuICAgKiBpbnRlcnByZXRpbmcgdGhlIGRlc3RpbmF0aW9uIFVSSSBhcyByZWxhdGl2ZSB0byB0aGUgYWN0aXZhdGVkIGBjaGlsZGAgIHJvdXRlXG4gICAqXG4gICAqIGBgYFxuICAgKiAgQENvbXBvbmVudCh7Li4ufSlcbiAgICogIGNsYXNzIENoaWxkQ29tcG9uZW50IHtcbiAgICogICAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZXI6IFJvdXRlciwgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUpIHt9XG4gICAqXG4gICAqICAgIGdvKCkge1xuICAgKiAgICAgIHJvdXRlci5uYXZpZ2F0ZShbJy4uL2xpc3QnXSwgeyByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlIH0pO1xuICAgKiAgICB9XG4gICAqICB9XG4gICAqIGBgYFxuICAgKlxuICAgKiBBIHZhbHVlIG9mIGBudWxsYCBvciBgdW5kZWZpbmVkYCBpbmRpY2F0ZXMgdGhhdCB0aGUgbmF2aWdhdGlvbiBjb21tYW5kcyBzaG91bGQgYmUgYXBwbGllZFxuICAgKiByZWxhdGl2ZSB0byB0aGUgcm9vdC5cbiAgICovXG4gIHJlbGF0aXZlVG8/OiBBY3RpdmF0ZWRSb3V0ZSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIFNldHMgcXVlcnkgcGFyYW1ldGVycyB0byB0aGUgVVJMLlxuICAgKlxuICAgKiBgYGBcbiAgICogLy8gTmF2aWdhdGUgdG8gL3Jlc3VsdHM/cGFnZT0xXG4gICAqIHJvdXRlci5uYXZpZ2F0ZShbJy9yZXN1bHRzJ10sIHsgcXVlcnlQYXJhbXM6IHsgcGFnZTogMSB9IH0pO1xuICAgKiBgYGBcbiAgICovXG4gIHF1ZXJ5UGFyYW1zPzogUGFyYW1zIHwgbnVsbDtcblxuICAvKipcbiAgICogU2V0cyB0aGUgaGFzaCBmcmFnbWVudCBmb3IgdGhlIFVSTC5cbiAgICpcbiAgICogYGBgXG4gICAqIC8vIE5hdmlnYXRlIHRvIC9yZXN1bHRzI3RvcFxuICAgKiByb3V0ZXIubmF2aWdhdGUoWycvcmVzdWx0cyddLCB7IGZyYWdtZW50OiAndG9wJyB9KTtcbiAgICogYGBgXG4gICAqL1xuICBmcmFnbWVudD86IHN0cmluZztcblxuICAvKipcbiAgICogSG93IHRvIGhhbmRsZSBxdWVyeSBwYXJhbWV0ZXJzIGluIHRoZSByb3V0ZXIgbGluayBmb3IgdGhlIG5leHQgbmF2aWdhdGlvbi5cbiAgICogT25lIG9mOlxuICAgKiAqIGBwcmVzZXJ2ZWAgOiBQcmVzZXJ2ZSBjdXJyZW50IHBhcmFtZXRlcnMuXG4gICAqICogYG1lcmdlYCA6IE1lcmdlIG5ldyB3aXRoIGN1cnJlbnQgcGFyYW1ldGVycy5cbiAgICpcbiAgICogVGhlIFwicHJlc2VydmVcIiBvcHRpb24gZGlzY2FyZHMgYW55IG5ldyBxdWVyeSBwYXJhbXM6XG4gICAqIGBgYFxuICAgKiAvLyBmcm9tIC92aWV3MT9wYWdlPTEgdG8vdmlldzI/cGFnZT0xXG4gICAqIHJvdXRlci5uYXZpZ2F0ZShbJy92aWV3MiddLCB7IHF1ZXJ5UGFyYW1zOiB7IHBhZ2U6IDIgfSwgIHF1ZXJ5UGFyYW1zSGFuZGxpbmc6IFwicHJlc2VydmVcIlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqIFRoZSBcIm1lcmdlXCIgb3B0aW9uIGFwcGVuZHMgbmV3IHF1ZXJ5IHBhcmFtcyB0byB0aGUgcGFyYW1zIGZyb20gdGhlIGN1cnJlbnQgVVJMOlxuICAgKiBgYGBcbiAgICogLy8gZnJvbSAvdmlldzE/cGFnZT0xIHRvL3ZpZXcyP3BhZ2U9MSZvdGhlcktleT0yXG4gICAqIHJvdXRlci5uYXZpZ2F0ZShbJy92aWV3MiddLCB7IHF1ZXJ5UGFyYW1zOiB7IG90aGVyS2V5OiAyIH0sICBxdWVyeVBhcmFtc0hhbmRsaW5nOiBcIm1lcmdlXCJcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKiBJbiBjYXNlIG9mIGEga2V5IGNvbGxpc2lvbiBiZXR3ZWVuIGN1cnJlbnQgcGFyYW1ldGVycyBhbmQgdGhvc2UgaW4gdGhlIGBxdWVyeVBhcmFtc2Agb2JqZWN0LFxuICAgKiB0aGUgbmV3IHZhbHVlIGlzIHVzZWQuXG4gICAqXG4gICAqL1xuICBxdWVyeVBhcmFtc0hhbmRsaW5nPzogUXVlcnlQYXJhbXNIYW5kbGluZyB8IG51bGw7XG5cbiAgLyoqXG4gICAqIFdoZW4gdHJ1ZSwgcHJlc2VydmVzIHRoZSBVUkwgZnJhZ21lbnQgZm9yIHRoZSBuZXh0IG5hdmlnYXRpb25cbiAgICpcbiAgICogYGBgXG4gICAqIC8vIFByZXNlcnZlIGZyYWdtZW50IGZyb20gL3Jlc3VsdHMjdG9wIHRvIC92aWV3I3RvcFxuICAgKiByb3V0ZXIubmF2aWdhdGUoWycvdmlldyddLCB7IHByZXNlcnZlRnJhZ21lbnQ6IHRydWUgfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgcHJlc2VydmVGcmFnbWVudD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogT3B0aW9ucyB0aGF0IG1vZGlmeSB0aGUgYFJvdXRlcmAgbmF2aWdhdGlvbiBzdHJhdGVneS5cbiAqIFN1cHBseSBhbiBvYmplY3QgY29udGFpbmluZyBhbnkgb2YgdGhlc2UgcHJvcGVydGllcyB0byBhIGBSb3V0ZXJgIG5hdmlnYXRpb24gZnVuY3Rpb24gdG9cbiAqIGNvbnRyb2wgaG93IHRoZSB0YXJnZXQgVVJMIHNob3VsZCBiZSBjb25zdHJ1Y3RlZCBvciBpbnRlcnByZXRlZC5cbiAqXG4gKiBAc2VlIHtAbGluayBSb3V0ZXIjbmF2aWdhdGV9XG4gKiBAc2VlIHtAbGluayBSb3V0ZXIjbmF2aWdhdGVCeVVybH1cbiAqIEBzZWUge0BsaW5rIFJvdXRlciNjcmVhdGV1cmx0cmVlfVxuICogQHNlZSBbUm91dGluZyBhbmQgTmF2aWdhdGlvbiBndWlkZV0oZ3VpZGUvcm91dGluZy9jb21tb24tcm91dGVyLXRhc2tzKVxuICogQHNlZSB7QGxpbmsgVXJsQ3JlYXRpb25PcHRpb25zfVxuICogQHNlZSB7QGxpbmsgTmF2aWdhdGlvbkJlaGF2aW9yT3B0aW9uc31cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvbkV4dHJhcyBleHRlbmRzIFVybENyZWF0aW9uT3B0aW9ucywgTmF2aWdhdGlvbkJlaGF2aW9yT3B0aW9ucyB7fVxuXG5leHBvcnQgdHlwZSBSZXN0b3JlZFN0YXRlID0ge1xuICBbazogc3RyaW5nXTogYW55O1xuICAvLyBUT0RPKCMyNzYwNyk6IFJlbW92ZSBgbmF2aWdhdGlvbklkYCBhbmQgYMm1cm91dGVyUGFnZUlkYCBhbmQgbW92ZSB0byBgbmdgIG9yIGDJtWAgbmFtZXNwYWNlLlxuICBuYXZpZ2F0aW9uSWQ6IG51bWJlcjtcbiAgLy8gVGhlIGDJtWAgcHJlZml4IGlzIHRoZXJlIHRvIHJlZHVjZSB0aGUgY2hhbmNlIG9mIGNvbGxpZGluZyB3aXRoIGFueSBleGlzdGluZyB1c2VyIHByb3BlcnRpZXMgb25cbiAgLy8gdGhlIGhpc3Rvcnkgc3RhdGUuXG4gIMm1cm91dGVyUGFnZUlkPzogbnVtYmVyO1xufTtcblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBhYm91dCBhIG5hdmlnYXRpb24gb3BlcmF0aW9uLlxuICogUmV0cmlldmUgdGhlIG1vc3QgcmVjZW50IG5hdmlnYXRpb24gb2JqZWN0IHdpdGggdGhlXG4gKiBbUm91dGVyLmdldEN1cnJlbnROYXZpZ2F0aW9uKCkgbWV0aG9kXShhcGkvcm91dGVyL1JvdXRlciNnZXRjdXJyZW50bmF2aWdhdGlvbikgLlxuICpcbiAqICogKmlkKiA6IFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgY3VycmVudCBuYXZpZ2F0aW9uLlxuICogKiAqaW5pdGlhbFVybCogOiBUaGUgdGFyZ2V0IFVSTCBwYXNzZWQgaW50byB0aGUgYFJvdXRlciNuYXZpZ2F0ZUJ5VXJsKClgIGNhbGwgYmVmb3JlIG5hdmlnYXRpb24uXG4gKiBUaGlzIGlzIHRoZSB2YWx1ZSBiZWZvcmUgdGhlIHJvdXRlciBoYXMgcGFyc2VkIG9yIGFwcGxpZWQgcmVkaXJlY3RzIHRvIGl0LlxuICogKiAqZXh0cmFjdGVkVXJsKiA6IFRoZSBpbml0aWFsIHRhcmdldCBVUkwgYWZ0ZXIgYmVpbmcgcGFyc2VkIHdpdGggYFVybFNlcmlhbGl6ZXIuZXh0cmFjdCgpYC5cbiAqICogKmZpbmFsVXJsKiA6IFRoZSBleHRyYWN0ZWQgVVJMIGFmdGVyIHJlZGlyZWN0cyBoYXZlIGJlZW4gYXBwbGllZC5cbiAqIFRoaXMgVVJMIG1heSBub3QgYmUgYXZhaWxhYmxlIGltbWVkaWF0ZWx5LCB0aGVyZWZvcmUgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgYHVuZGVmaW5lZGAuXG4gKiBJdCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCBhZnRlciB0aGUgYFJvdXRlc1JlY29nbml6ZWRgIGV2ZW50IGZpcmVzLlxuICogKiAqdHJpZ2dlciogOiBJZGVudGlmaWVzIGhvdyB0aGlzIG5hdmlnYXRpb24gd2FzIHRyaWdnZXJlZC5cbiAqIC0tICdpbXBlcmF0aXZlJy0tVHJpZ2dlcmVkIGJ5IGByb3V0ZXIubmF2aWdhdGVCeVVybGAgb3IgYHJvdXRlci5uYXZpZ2F0ZWAuXG4gKiAtLSAncG9wc3RhdGUnLS1UcmlnZ2VyZWQgYnkgYSBwb3BzdGF0ZSBldmVudC5cbiAqIC0tICdoYXNoY2hhbmdlJy0tVHJpZ2dlcmVkIGJ5IGEgaGFzaGNoYW5nZSBldmVudC5cbiAqICogKmV4dHJhcyogOiBBIGBOYXZpZ2F0aW9uRXh0cmFzYCBvcHRpb25zIG9iamVjdCB0aGF0IGNvbnRyb2xsZWQgdGhlIHN0cmF0ZWd5IHVzZWQgZm9yIHRoaXNcbiAqIG5hdmlnYXRpb24uXG4gKiAqICpwcmV2aW91c05hdmlnYXRpb24qIDogVGhlIHByZXZpb3VzbHkgc3VjY2Vzc2Z1bCBgTmF2aWdhdGlvbmAgb2JqZWN0LiBPbmx5IG9uZSBwcmV2aW91c1xuICogbmF2aWdhdGlvbiBpcyBhdmFpbGFibGUsIHRoZXJlZm9yZSB0aGlzIHByZXZpb3VzIGBOYXZpZ2F0aW9uYCBvYmplY3QgaGFzIGEgYG51bGxgIHZhbHVlIGZvciBpdHNcbiAqIG93biBgcHJldmlvdXNOYXZpZ2F0aW9uYC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGN1cnJlbnQgbmF2aWdhdGlvbi5cbiAgICovXG4gIGlkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgdGFyZ2V0IFVSTCBwYXNzZWQgaW50byB0aGUgYFJvdXRlciNuYXZpZ2F0ZUJ5VXJsKClgIGNhbGwgYmVmb3JlIG5hdmlnYXRpb24uIFRoaXMgaXNcbiAgICogdGhlIHZhbHVlIGJlZm9yZSB0aGUgcm91dGVyIGhhcyBwYXJzZWQgb3IgYXBwbGllZCByZWRpcmVjdHMgdG8gaXQuXG4gICAqL1xuICBpbml0aWFsVXJsOiBVcmxUcmVlO1xuICAvKipcbiAgICogVGhlIGluaXRpYWwgdGFyZ2V0IFVSTCBhZnRlciBiZWluZyBwYXJzZWQgd2l0aCBgVXJsSGFuZGxpbmdTdHJhdGVneS5leHRyYWN0KClgLlxuICAgKi9cbiAgZXh0cmFjdGVkVXJsOiBVcmxUcmVlO1xuICAvKipcbiAgICogVGhlIGV4dHJhY3RlZCBVUkwgYWZ0ZXIgcmVkaXJlY3RzIGhhdmUgYmVlbiBhcHBsaWVkLlxuICAgKiBUaGlzIFVSTCBtYXkgbm90IGJlIGF2YWlsYWJsZSBpbW1lZGlhdGVseSwgdGhlcmVmb3JlIHRoaXMgcHJvcGVydHkgY2FuIGJlIGB1bmRlZmluZWRgLlxuICAgKiBJdCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCBhZnRlciB0aGUgYFJvdXRlc1JlY29nbml6ZWRgIGV2ZW50IGZpcmVzLlxuICAgKi9cbiAgZmluYWxVcmw/OiBVcmxUcmVlO1xuICAvKipcbiAgICogYFVybFRyZWVgIHRvIHVzZSB3aGVuIHVwZGF0aW5nIHRoZSBicm93c2VyIFVSTCBmb3IgdGhlIG5hdmlnYXRpb24gd2hlbiBgZXh0cmFzLmJyb3dzZXJVcmxgIGlzXG4gICAqIGRlZmluZWQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcmVhZG9ubHkgdGFyZ2V0QnJvd3NlclVybD86IFVybFRyZWUgfCBzdHJpbmc7XG4gIC8qKlxuICAgKiBUT0RPKGF0c2NvdHQpOiBJZiB3ZSB3YW50IHRvIG1ha2UgU3RhdGVNYW5hZ2VyIHB1YmxpYywgdGhleSB3aWxsIG5lZWQgYWNjZXNzIHRvIHRoaXMuIE5vdGUgdGhhdFxuICAgKiBpdCdzIGFscmVhZHkgZXZlbnR1YWxseSBleHBvc2VkIHRocm91Z2ggcm91dGVyLnJvdXRlclN0YXRlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHRhcmdldFJvdXRlclN0YXRlPzogUm91dGVyU3RhdGU7XG4gIC8qKlxuICAgKiBJZGVudGlmaWVzIGhvdyB0aGlzIG5hdmlnYXRpb24gd2FzIHRyaWdnZXJlZC5cbiAgICpcbiAgICogKiAnaW1wZXJhdGl2ZSctLVRyaWdnZXJlZCBieSBgcm91dGVyLm5hdmlnYXRlQnlVcmxgIG9yIGByb3V0ZXIubmF2aWdhdGVgLlxuICAgKiAqICdwb3BzdGF0ZSctLVRyaWdnZXJlZCBieSBhIHBvcHN0YXRlIGV2ZW50LlxuICAgKiAqICdoYXNoY2hhbmdlJy0tVHJpZ2dlcmVkIGJ5IGEgaGFzaGNoYW5nZSBldmVudC5cbiAgICovXG4gIHRyaWdnZXI6ICdpbXBlcmF0aXZlJyB8ICdwb3BzdGF0ZScgfCAnaGFzaGNoYW5nZSc7XG4gIC8qKlxuICAgKiBPcHRpb25zIHRoYXQgY29udHJvbGxlZCB0aGUgc3RyYXRlZ3kgdXNlZCBmb3IgdGhpcyBuYXZpZ2F0aW9uLlxuICAgKiBTZWUgYE5hdmlnYXRpb25FeHRyYXNgLlxuICAgKi9cbiAgZXh0cmFzOiBOYXZpZ2F0aW9uRXh0cmFzO1xuICAvKipcbiAgICogVGhlIHByZXZpb3VzbHkgc3VjY2Vzc2Z1bCBgTmF2aWdhdGlvbmAgb2JqZWN0LiBPbmx5IG9uZSBwcmV2aW91cyBuYXZpZ2F0aW9uXG4gICAqIGlzIGF2YWlsYWJsZSwgdGhlcmVmb3JlIHRoaXMgcHJldmlvdXMgYE5hdmlnYXRpb25gIG9iamVjdCBoYXMgYSBgbnVsbGAgdmFsdWVcbiAgICogZm9yIGl0cyBvd24gYHByZXZpb3VzTmF2aWdhdGlvbmAuXG4gICAqL1xuICBwcmV2aW91c05hdmlnYXRpb246IE5hdmlnYXRpb24gfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5hdmlnYXRpb25UcmFuc2l0aW9uIHtcbiAgaWQ6IG51bWJlcjtcbiAgY3VycmVudFVybFRyZWU6IFVybFRyZWU7XG4gIGV4dHJhY3RlZFVybDogVXJsVHJlZTtcbiAgY3VycmVudFJhd1VybDogVXJsVHJlZTtcbiAgdXJsQWZ0ZXJSZWRpcmVjdHM/OiBVcmxUcmVlO1xuICByYXdVcmw6IFVybFRyZWU7XG4gIGV4dHJhczogTmF2aWdhdGlvbkV4dHJhcztcbiAgcmVzb2x2ZTogKHZhbHVlOiBib29sZWFuIHwgUHJvbWlzZUxpa2U8Ym9vbGVhbj4pID0+IHZvaWQ7XG4gIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZDtcbiAgcHJvbWlzZTogUHJvbWlzZTxib29sZWFuPjtcbiAgc291cmNlOiBOYXZpZ2F0aW9uVHJpZ2dlcjtcbiAgcmVzdG9yZWRTdGF0ZTogUmVzdG9yZWRTdGF0ZSB8IG51bGw7XG4gIGN1cnJlbnRTbmFwc2hvdDogUm91dGVyU3RhdGVTbmFwc2hvdDtcbiAgdGFyZ2V0U25hcHNob3Q6IFJvdXRlclN0YXRlU25hcHNob3QgfCBudWxsO1xuICBjdXJyZW50Um91dGVyU3RhdGU6IFJvdXRlclN0YXRlO1xuICB0YXJnZXRSb3V0ZXJTdGF0ZTogUm91dGVyU3RhdGUgfCBudWxsO1xuICBndWFyZHM6IENoZWNrcztcbiAgZ3VhcmRzUmVzdWx0OiBHdWFyZFJlc3VsdCB8IG51bGw7XG59XG5cbi8qKlxuICogVGhlIGludGVyZmFjZSBmcm9tIHRoZSBSb3V0ZXIgbmVlZGVkIGJ5IHRoZSB0cmFuc2l0aW9ucy4gVXNlZCB0byBhdm9pZCBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgb25cbiAqIFJvdXRlci4gVGhpcyBpbnRlcmZhY2Ugc2hvdWxkIGJlIHdoaXR0bGVkIGRvd24gd2l0aCBmdXR1cmUgcmVmYWN0b3JzLiBGb3IgZXhhbXBsZSwgd2UgZG8gbm90IG5lZWRcbiAqIHRvIGdldCBgVXJsU2VyaWFsaXplcmAgZnJvbSB0aGUgUm91dGVyLiBXZSBjYW4gaW5zdGVhZCBpbmplY3QgaXQgaW4gYE5hdmlnYXRpb25UcmFuc2l0aW9uc2BcbiAqIGRpcmVjdGx5LlxuICovXG5pbnRlcmZhY2UgSW50ZXJuYWxSb3V0ZXJJbnRlcmZhY2Uge1xuICBjb25maWc6IFJvdXRlcztcbiAgLy8gQWxsIG9mIHRoZXNlIGFyZSBwdWJsaWMgQVBJIG9mIHJvdXRlciBpbnRlcmZhY2UgYW5kIGNhbiBjaGFuZ2UgZHVyaW5nIHJ1bnRpbWUgYmVjYXVzZSB0aGV5IGFyZVxuICAvLyB3cml0ZWFibGUuIElkZWFsbHksIHRoZXNlIHdvdWxkIGJlIHJlbW92ZWQgYW5kIHRoZSB2YWx1ZXMgcmV0cmlldmVkIGluc3RlYWQgZnJvbSB0aGUgdmFsdWVzXG4gIC8vIGF2YWlsYWJsZSBpbiBESS5cbiAgZXJyb3JIYW5kbGVyOiAoZXJyb3I6IGFueSkgPT4gYW55O1xuICBuYXZpZ2F0ZWQ6IGJvb2xlYW47XG4gIHJvdXRlUmV1c2VTdHJhdGVneTogUm91dGVSZXVzZVN0cmF0ZWd5O1xuICBvblNhbWVVcmxOYXZpZ2F0aW9uOiAncmVsb2FkJyB8ICdpZ25vcmUnO1xufVxuXG5leHBvcnQgY29uc3QgTkFWSUdBVElPTl9FUlJPUl9IQU5ETEVSID0gbmV3IEluamVjdGlvblRva2VuPFxuICAoZXJyb3I6IE5hdmlnYXRpb25FcnJvcikgPT4gdW5rbm93biB8IFJlZGlyZWN0Q29tbWFuZFxuPih0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUgPyAnbmF2aWdhdGlvbiBlcnJvciBoYW5kbGVyJyA6ICcnKTtcblxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgTmF2aWdhdGlvblRyYW5zaXRpb25zIHtcbiAgY3VycmVudE5hdmlnYXRpb246IE5hdmlnYXRpb24gfCBudWxsID0gbnVsbDtcbiAgY3VycmVudFRyYW5zaXRpb246IE5hdmlnYXRpb25UcmFuc2l0aW9uIHwgbnVsbCA9IG51bGw7XG4gIGxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvbjogTmF2aWdhdGlvbiB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogVGhlc2UgZXZlbnRzIGFyZSB1c2VkIHRvIGNvbW11bmljYXRlIGJhY2sgdG8gdGhlIFJvdXRlciBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIHRyYW5zaXRpb24uIFRoZVxuICAgKiBSb3V0ZXIgd2FudHMgdG8gcmVzcG9uZCB0byB0aGVzZSBldmVudHMgaW4gdmFyaW91cyB3YXlzLiBCZWNhdXNlIHRoZSBgTmF2aWdhdGlvblRyYW5zaXRpb25gXG4gICAqIGNsYXNzIGlzIG5vdCBwdWJsaWMsIHRoaXMgZXZlbnQgc3ViamVjdCBpcyBub3QgcHVibGljbHkgZXhwb3NlZC5cbiAgICovXG4gIHJlYWRvbmx5IGV2ZW50cyA9IG5ldyBTdWJqZWN0PEV2ZW50IHwgQmVmb3JlQWN0aXZhdGVSb3V0ZXMgfCBSZWRpcmVjdFJlcXVlc3Q+KCk7XG4gIC8qKlxuICAgKiBVc2VkIHRvIGFib3J0IHRoZSBjdXJyZW50IHRyYW5zaXRpb24gd2l0aCBhbiBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zaXRpb25BYm9ydFN1YmplY3QgPSBuZXcgU3ViamVjdDxFcnJvcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWdMb2FkZXIgPSBpbmplY3QoUm91dGVyQ29uZmlnTG9hZGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbnZpcm9ubWVudEluamVjdG9yID0gaW5qZWN0KEVudmlyb25tZW50SW5qZWN0b3IpO1xuICBwcml2YXRlIHJlYWRvbmx5IHVybFNlcmlhbGl6ZXIgPSBpbmplY3QoVXJsU2VyaWFsaXplcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdENvbnRleHRzID0gaW5qZWN0KENoaWxkcmVuT3V0bGV0Q29udGV4dHMpO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvY2F0aW9uID0gaW5qZWN0KExvY2F0aW9uKTtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnB1dEJpbmRpbmdFbmFibGVkID0gaW5qZWN0KElOUFVUX0JJTkRFUiwge29wdGlvbmFsOiB0cnVlfSkgIT09IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGl0bGVTdHJhdGVneT86IFRpdGxlU3RyYXRlZ3kgPSBpbmplY3QoVGl0bGVTdHJhdGVneSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucyA9IGluamVjdChST1VURVJfQ09ORklHVVJBVElPTiwge29wdGlvbmFsOiB0cnVlfSkgfHwge307XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFyYW1zSW5oZXJpdGFuY2VTdHJhdGVneSA9XG4gICAgdGhpcy5vcHRpb25zLnBhcmFtc0luaGVyaXRhbmNlU3RyYXRlZ3kgfHwgJ2VtcHR5T25seSc7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXJsSGFuZGxpbmdTdHJhdGVneSA9IGluamVjdChVcmxIYW5kbGluZ1N0cmF0ZWd5KTtcbiAgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVWaWV3VHJhbnNpdGlvbiA9IGluamVjdChDUkVBVEVfVklFV19UUkFOU0lUSU9OLCB7b3B0aW9uYWw6IHRydWV9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBuYXZpZ2F0aW9uRXJyb3JIYW5kbGVyID0gaW5qZWN0KE5BVklHQVRJT05fRVJST1JfSEFORExFUiwge29wdGlvbmFsOiB0cnVlfSk7XG5cbiAgbmF2aWdhdGlvbklkID0gMDtcbiAgZ2V0IGhhc1JlcXVlc3RlZE5hdmlnYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMubmF2aWdhdGlvbklkICE9PSAwO1xuICB9XG4gIHByaXZhdGUgdHJhbnNpdGlvbnM/OiBCZWhhdmlvclN1YmplY3Q8TmF2aWdhdGlvblRyYW5zaXRpb24+O1xuICAvKipcbiAgICogSG9vayB0aGF0IGVuYWJsZXMgeW91IHRvIHBhdXNlIG5hdmlnYXRpb24gYWZ0ZXIgdGhlIHByZWFjdGl2YXRpb24gcGhhc2UuXG4gICAqIFVzZWQgYnkgYFJvdXRlck1vZHVsZWAuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgYWZ0ZXJQcmVhY3RpdmF0aW9uOiAoKSA9PiBPYnNlcnZhYmxlPHZvaWQ+ID0gKCkgPT4gb2Yodm9pZCAwKTtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByb290Q29tcG9uZW50VHlwZTogVHlwZTxhbnk+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgY29uc3Qgb25Mb2FkU3RhcnQgPSAocjogUm91dGUpID0+IHRoaXMuZXZlbnRzLm5leHQobmV3IFJvdXRlQ29uZmlnTG9hZFN0YXJ0KHIpKTtcbiAgICBjb25zdCBvbkxvYWRFbmQgPSAocjogUm91dGUpID0+IHRoaXMuZXZlbnRzLm5leHQobmV3IFJvdXRlQ29uZmlnTG9hZEVuZChyKSk7XG4gICAgdGhpcy5jb25maWdMb2FkZXIub25Mb2FkRW5kTGlzdGVuZXIgPSBvbkxvYWRFbmQ7XG4gICAgdGhpcy5jb25maWdMb2FkZXIub25Mb2FkU3RhcnRMaXN0ZW5lciA9IG9uTG9hZFN0YXJ0O1xuICB9XG5cbiAgY29tcGxldGUoKSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucz8uY29tcGxldGUoKTtcbiAgfVxuXG4gIGhhbmRsZU5hdmlnYXRpb25SZXF1ZXN0KFxuICAgIHJlcXVlc3Q6IFBpY2s8XG4gICAgICBOYXZpZ2F0aW9uVHJhbnNpdGlvbixcbiAgICAgIHwgJ3NvdXJjZSdcbiAgICAgIHwgJ3Jlc3RvcmVkU3RhdGUnXG4gICAgICB8ICdjdXJyZW50VXJsVHJlZSdcbiAgICAgIHwgJ2N1cnJlbnRSYXdVcmwnXG4gICAgICB8ICdyYXdVcmwnXG4gICAgICB8ICdleHRyYXMnXG4gICAgICB8ICdyZXNvbHZlJ1xuICAgICAgfCAncmVqZWN0J1xuICAgICAgfCAncHJvbWlzZSdcbiAgICAgIHwgJ2N1cnJlbnRTbmFwc2hvdCdcbiAgICAgIHwgJ2N1cnJlbnRSb3V0ZXJTdGF0ZSdcbiAgICA+LFxuICApIHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5uYXZpZ2F0aW9uSWQ7XG4gICAgdGhpcy50cmFuc2l0aW9ucz8ubmV4dCh7Li4udGhpcy50cmFuc2l0aW9ucy52YWx1ZSwgLi4ucmVxdWVzdCwgaWR9KTtcbiAgfVxuXG4gIHNldHVwTmF2aWdhdGlvbnMoXG4gICAgcm91dGVyOiBJbnRlcm5hbFJvdXRlckludGVyZmFjZSxcbiAgICBpbml0aWFsVXJsVHJlZTogVXJsVHJlZSxcbiAgICBpbml0aWFsUm91dGVyU3RhdGU6IFJvdXRlclN0YXRlLFxuICApOiBPYnNlcnZhYmxlPE5hdmlnYXRpb25UcmFuc2l0aW9uPiB7XG4gICAgdGhpcy50cmFuc2l0aW9ucyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8TmF2aWdhdGlvblRyYW5zaXRpb24+KHtcbiAgICAgIGlkOiAwLFxuICAgICAgY3VycmVudFVybFRyZWU6IGluaXRpYWxVcmxUcmVlLFxuICAgICAgY3VycmVudFJhd1VybDogaW5pdGlhbFVybFRyZWUsXG4gICAgICBleHRyYWN0ZWRVcmw6IHRoaXMudXJsSGFuZGxpbmdTdHJhdGVneS5leHRyYWN0KGluaXRpYWxVcmxUcmVlKSxcbiAgICAgIHVybEFmdGVyUmVkaXJlY3RzOiB0aGlzLnVybEhhbmRsaW5nU3RyYXRlZ3kuZXh0cmFjdChpbml0aWFsVXJsVHJlZSksXG4gICAgICByYXdVcmw6IGluaXRpYWxVcmxUcmVlLFxuICAgICAgZXh0cmFzOiB7fSxcbiAgICAgIHJlc29sdmU6ICgpID0+IHt9LFxuICAgICAgcmVqZWN0OiAoKSA9PiB7fSxcbiAgICAgIHByb21pc2U6IFByb21pc2UucmVzb2x2ZSh0cnVlKSxcbiAgICAgIHNvdXJjZTogSU1QRVJBVElWRV9OQVZJR0FUSU9OLFxuICAgICAgcmVzdG9yZWRTdGF0ZTogbnVsbCxcbiAgICAgIGN1cnJlbnRTbmFwc2hvdDogaW5pdGlhbFJvdXRlclN0YXRlLnNuYXBzaG90LFxuICAgICAgdGFyZ2V0U25hcHNob3Q6IG51bGwsXG4gICAgICBjdXJyZW50Um91dGVyU3RhdGU6IGluaXRpYWxSb3V0ZXJTdGF0ZSxcbiAgICAgIHRhcmdldFJvdXRlclN0YXRlOiBudWxsLFxuICAgICAgZ3VhcmRzOiB7Y2FuQWN0aXZhdGVDaGVja3M6IFtdLCBjYW5EZWFjdGl2YXRlQ2hlY2tzOiBbXX0sXG4gICAgICBndWFyZHNSZXN1bHQ6IG51bGwsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMucGlwZShcbiAgICAgIGZpbHRlcigodCkgPT4gdC5pZCAhPT0gMCksXG5cbiAgICAgIC8vIEV4dHJhY3QgVVJMXG4gICAgICBtYXAoXG4gICAgICAgICh0KSA9PlxuICAgICAgICAgICh7XG4gICAgICAgICAgICAuLi50LFxuICAgICAgICAgICAgZXh0cmFjdGVkVXJsOiB0aGlzLnVybEhhbmRsaW5nU3RyYXRlZ3kuZXh0cmFjdCh0LnJhd1VybCksXG4gICAgICAgICAgfSkgYXMgTmF2aWdhdGlvblRyYW5zaXRpb24sXG4gICAgICApLFxuXG4gICAgICAvLyBVc2luZyBzd2l0Y2hNYXAgc28gd2UgY2FuY2VsIGV4ZWN1dGluZyBuYXZpZ2F0aW9ucyB3aGVuIGEgbmV3IG9uZSBjb21lcyBpblxuICAgICAgc3dpdGNoTWFwKChvdmVyYWxsVHJhbnNpdGlvblN0YXRlKSA9PiB7XG4gICAgICAgIGxldCBjb21wbGV0ZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IGVycm9yZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIG9mKG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUpLnBpcGUoXG4gICAgICAgICAgc3dpdGNoTWFwKCh0KSA9PiB7XG4gICAgICAgICAgICAvLyBJdCBpcyBwb3NzaWJsZSB0aGF0IGBzd2l0Y2hNYXBgIGZhaWxzIHRvIGNhbmNlbCBwcmV2aW91cyBuYXZpZ2F0aW9ucyBpZiBhIG5ldyBvbmUgaGFwcGVucyBzeW5jaHJvbm91c2x5IHdoaWxlIHRoZSBvcGVyYXRvclxuICAgICAgICAgICAgLy8gaXMgcHJvY2Vzc2luZyB0aGUgYG5leHRgIG5vdGlmaWNhdGlvbiBvZiB0aGF0IHByZXZpb3VzIG5hdmlnYXRpb24uIFRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgbmV3IG5hdmlnYXRpb24gKHNheSAyKSBjYW5jZWxzIGFcbiAgICAgICAgICAgIC8vIHByZXZpb3VzIG9uZSAoMSkgYW5kIHlldCBhbm90aGVyIG5hdmlnYXRpb24gKDMpIGhhcHBlbnMgc3luY2hyb25vdXNseSBpbiByZXNwb25zZSB0byB0aGUgYE5hdmlnYXRpb25DYW5jZWxgIGV2ZW50IGZvciAoMSkuXG4gICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vUmVhY3RpdmVYL3J4anMvaXNzdWVzLzc0NTVcbiAgICAgICAgICAgIGlmICh0aGlzLm5hdmlnYXRpb25JZCA+IG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUuaWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgY2FuY2VsbGF0aW9uUmVhc29uID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGVcbiAgICAgICAgICAgICAgICAgID8gYE5hdmlnYXRpb24gSUQgJHtvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmlkfSBpcyBub3QgZXF1YWwgdG8gdGhlIGN1cnJlbnQgbmF2aWdhdGlvbiBpZCAke3RoaXMubmF2aWdhdGlvbklkfWBcbiAgICAgICAgICAgICAgICAgIDogJyc7XG4gICAgICAgICAgICAgIHRoaXMuY2FuY2VsTmF2aWdhdGlvblRyYW5zaXRpb24oXG4gICAgICAgICAgICAgICAgb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSxcbiAgICAgICAgICAgICAgICBjYW5jZWxsYXRpb25SZWFzb24sXG4gICAgICAgICAgICAgICAgTmF2aWdhdGlvbkNhbmNlbGxhdGlvbkNvZGUuU3VwZXJzZWRlZEJ5TmV3TmF2aWdhdGlvbixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50VHJhbnNpdGlvbiA9IG92ZXJhbGxUcmFuc2l0aW9uU3RhdGU7XG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgTmF2aWdhdGlvbiBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuY3VycmVudE5hdmlnYXRpb24gPSB7XG4gICAgICAgICAgICAgIGlkOiB0LmlkLFxuICAgICAgICAgICAgICBpbml0aWFsVXJsOiB0LnJhd1VybCxcbiAgICAgICAgICAgICAgZXh0cmFjdGVkVXJsOiB0LmV4dHJhY3RlZFVybCxcbiAgICAgICAgICAgICAgdGFyZ2V0QnJvd3NlclVybDpcbiAgICAgICAgICAgICAgICB0eXBlb2YgdC5leHRyYXMuYnJvd3NlclVybCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgID8gdGhpcy51cmxTZXJpYWxpemVyLnBhcnNlKHQuZXh0cmFzLmJyb3dzZXJVcmwpXG4gICAgICAgICAgICAgICAgICA6IHQuZXh0cmFzLmJyb3dzZXJVcmwsXG4gICAgICAgICAgICAgIHRyaWdnZXI6IHQuc291cmNlLFxuICAgICAgICAgICAgICBleHRyYXM6IHQuZXh0cmFzLFxuICAgICAgICAgICAgICBwcmV2aW91c05hdmlnYXRpb246ICF0aGlzLmxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvblxuICAgICAgICAgICAgICAgID8gbnVsbFxuICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAuLi50aGlzLmxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNOYXZpZ2F0aW9uOiBudWxsLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB1cmxUcmFuc2l0aW9uID1cbiAgICAgICAgICAgICAgIXJvdXRlci5uYXZpZ2F0ZWQgfHwgdGhpcy5pc1VwZGF0aW5nSW50ZXJuYWxTdGF0ZSgpIHx8IHRoaXMuaXNVcGRhdGVkQnJvd3NlclVybCgpO1xuXG4gICAgICAgICAgICBjb25zdCBvblNhbWVVcmxOYXZpZ2F0aW9uID0gdC5leHRyYXMub25TYW1lVXJsTmF2aWdhdGlvbiA/PyByb3V0ZXIub25TYW1lVXJsTmF2aWdhdGlvbjtcbiAgICAgICAgICAgIGlmICghdXJsVHJhbnNpdGlvbiAmJiBvblNhbWVVcmxOYXZpZ2F0aW9uICE9PSAncmVsb2FkJykge1xuICAgICAgICAgICAgICBjb25zdCByZWFzb24gPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZVxuICAgICAgICAgICAgICAgICAgPyBgTmF2aWdhdGlvbiB0byAke3QucmF3VXJsfSB3YXMgaWdub3JlZCBiZWNhdXNlIGl0IGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IFJvdXRlciBVUkwuYFxuICAgICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChcbiAgICAgICAgICAgICAgICBuZXcgTmF2aWdhdGlvblNraXBwZWQoXG4gICAgICAgICAgICAgICAgICB0LmlkLFxuICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnJhd1VybCksXG4gICAgICAgICAgICAgICAgICByZWFzb24sXG4gICAgICAgICAgICAgICAgICBOYXZpZ2F0aW9uU2tpcHBlZENvZGUuSWdub3JlZFNhbWVVcmxOYXZpZ2F0aW9uLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHQucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMudXJsSGFuZGxpbmdTdHJhdGVneS5zaG91bGRQcm9jZXNzVXJsKHQucmF3VXJsKSkge1xuICAgICAgICAgICAgICByZXR1cm4gb2YodCkucGlwZShcbiAgICAgICAgICAgICAgICAvLyBGaXJlIE5hdmlnYXRpb25TdGFydCBldmVudFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgodCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHRoaXMudHJhbnNpdGlvbnM/LmdldFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgTmF2aWdhdGlvblN0YXJ0KFxuICAgICAgICAgICAgICAgICAgICAgIHQuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgICAgdC5zb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgdC5yZXN0b3JlZFN0YXRlLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2l0aW9uICE9PSB0aGlzLnRyYW5zaXRpb25zPy5nZXRWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgLy8gVGhpcyBkZWxheSBpcyByZXF1aXJlZCB0byBtYXRjaCBvbGQgYmVoYXZpb3IgdGhhdCBmb3JjZWRcbiAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gdG8gYWx3YXlzIGJlIGFzeW5jXG4gICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHQpO1xuICAgICAgICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgICAgICAgLy8gUmVjb2duaXplXG4gICAgICAgICAgICAgICAgcmVjb2duaXplKFxuICAgICAgICAgICAgICAgICAgdGhpcy5lbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWdMb2FkZXIsXG4gICAgICAgICAgICAgICAgICB0aGlzLnJvb3RDb21wb25lbnRUeXBlLFxuICAgICAgICAgICAgICAgICAgcm91dGVyLmNvbmZpZyxcbiAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplcixcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zSW5oZXJpdGFuY2VTdHJhdGVneSxcbiAgICAgICAgICAgICAgICApLFxuXG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIFVSTCBpZiBpbiBgZWFnZXJgIHVwZGF0ZSBtb2RlXG4gICAgICAgICAgICAgICAgdGFwKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnRhcmdldFNuYXBzaG90ID0gdC50YXJnZXRTbmFwc2hvdDtcbiAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUudXJsQWZ0ZXJSZWRpcmVjdHMgPSB0LnVybEFmdGVyUmVkaXJlY3RzO1xuICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50TmF2aWdhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgLi4udGhpcy5jdXJyZW50TmF2aWdhdGlvbiEsXG4gICAgICAgICAgICAgICAgICAgIGZpbmFsVXJsOiB0LnVybEFmdGVyUmVkaXJlY3RzLFxuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgLy8gRmlyZSBSb3V0ZXNSZWNvZ25pemVkXG4gICAgICAgICAgICAgICAgICBjb25zdCByb3V0ZXNSZWNvZ25pemVkID0gbmV3IFJvdXRlc1JlY29nbml6ZWQoXG4gICAgICAgICAgICAgICAgICAgIHQuaWQsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC5leHRyYWN0ZWRVcmwpLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQudXJsQWZ0ZXJSZWRpcmVjdHMhKSxcbiAgICAgICAgICAgICAgICAgICAgdC50YXJnZXRTbmFwc2hvdCEsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChyb3V0ZXNSZWNvZ25pemVkKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIHVybFRyYW5zaXRpb24gJiZcbiAgICAgICAgICAgICAgdGhpcy51cmxIYW5kbGluZ1N0cmF0ZWd5LnNob3VsZFByb2Nlc3NVcmwodC5jdXJyZW50UmF3VXJsKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIC8qIFdoZW4gdGhlIGN1cnJlbnQgVVJMIHNob3VsZG4ndCBiZSBwcm9jZXNzZWQsIGJ1dCB0aGUgcHJldmlvdXMgb25lXG4gICAgICAgICAgICAgICAqIHdhcywgd2UgaGFuZGxlIHRoaXMgXCJlcnJvciBjb25kaXRpb25cIiBieSBuYXZpZ2F0aW5nIHRvIHRoZVxuICAgICAgICAgICAgICAgKiBwcmV2aW91c2x5IHN1Y2Nlc3NmdWwgVVJMLCBidXQgbGVhdmluZyB0aGUgVVJMIGludGFjdC4qL1xuICAgICAgICAgICAgICBjb25zdCB7aWQsIGV4dHJhY3RlZFVybCwgc291cmNlLCByZXN0b3JlZFN0YXRlLCBleHRyYXN9ID0gdDtcbiAgICAgICAgICAgICAgY29uc3QgbmF2U3RhcnQgPSBuZXcgTmF2aWdhdGlvblN0YXJ0KFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUoZXh0cmFjdGVkVXJsKSxcbiAgICAgICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgICAgICAgcmVzdG9yZWRTdGF0ZSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChuYXZTdGFydCk7XG4gICAgICAgICAgICAgIGNvbnN0IHRhcmdldFNuYXBzaG90ID0gY3JlYXRlRW1wdHlTdGF0ZSh0aGlzLnJvb3RDb21wb25lbnRUeXBlKS5zbmFwc2hvdDtcblxuICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRUcmFuc2l0aW9uID0gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICAuLi50LFxuICAgICAgICAgICAgICAgIHRhcmdldFNuYXBzaG90LFxuICAgICAgICAgICAgICAgIHVybEFmdGVyUmVkaXJlY3RzOiBleHRyYWN0ZWRVcmwsXG4gICAgICAgICAgICAgICAgZXh0cmFzOiB7Li4uZXh0cmFzLCBza2lwTG9jYXRpb25DaGFuZ2U6IGZhbHNlLCByZXBsYWNlVXJsOiBmYWxzZX0sXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHRoaXMuY3VycmVudE5hdmlnYXRpb24hLmZpbmFsVXJsID0gZXh0cmFjdGVkVXJsO1xuICAgICAgICAgICAgICByZXR1cm4gb2Yob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvKiBXaGVuIG5laXRoZXIgdGhlIGN1cnJlbnQgb3IgcHJldmlvdXMgVVJMIGNhbiBiZSBwcm9jZXNzZWQsIGRvXG4gICAgICAgICAgICAgICAqIG5vdGhpbmcgb3RoZXIgdGhhbiB1cGRhdGUgcm91dGVyJ3MgaW50ZXJuYWwgcmVmZXJlbmNlIHRvIHRoZVxuICAgICAgICAgICAgICAgKiBjdXJyZW50IFwic2V0dGxlZFwiIFVSTC4gVGhpcyB3YXkgdGhlIG5leHQgbmF2aWdhdGlvbiB3aWxsIGJlIGNvbWluZ1xuICAgICAgICAgICAgICAgKiBmcm9tIHRoZSBjdXJyZW50IFVSTCBpbiB0aGUgYnJvd3Nlci5cbiAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgIGNvbnN0IHJlYXNvbiA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlXG4gICAgICAgICAgICAgICAgICA/IGBOYXZpZ2F0aW9uIHdhcyBpZ25vcmVkIGJlY2F1c2UgdGhlIFVybEhhbmRsaW5nU3RyYXRlZ3lgICtcbiAgICAgICAgICAgICAgICAgICAgYCBpbmRpY2F0ZWQgbmVpdGhlciB0aGUgY3VycmVudCBVUkwgJHt0LmN1cnJlbnRSYXdVcmx9IG5vciB0YXJnZXQgVVJMICR7dC5yYXdVcmx9IHNob3VsZCBiZSBwcm9jZXNzZWQuYFxuICAgICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChcbiAgICAgICAgICAgICAgICBuZXcgTmF2aWdhdGlvblNraXBwZWQoXG4gICAgICAgICAgICAgICAgICB0LmlkLFxuICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICByZWFzb24sXG4gICAgICAgICAgICAgICAgICBOYXZpZ2F0aW9uU2tpcHBlZENvZGUuSWdub3JlZEJ5VXJsSGFuZGxpbmdTdHJhdGVneSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0LnJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICAvLyAtLS0gR1VBUkRTIC0tLVxuICAgICAgICAgIHRhcCgodCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZ3VhcmRzU3RhcnQgPSBuZXcgR3VhcmRzQ2hlY2tTdGFydChcbiAgICAgICAgICAgICAgdC5pZCxcbiAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC51cmxBZnRlclJlZGlyZWN0cyEpLFxuICAgICAgICAgICAgICB0LnRhcmdldFNuYXBzaG90ISxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KGd1YXJkc1N0YXJ0KTtcbiAgICAgICAgICB9KSxcblxuICAgICAgICAgIG1hcCgodCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VHJhbnNpdGlvbiA9IG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUgPSB7XG4gICAgICAgICAgICAgIC4uLnQsXG4gICAgICAgICAgICAgIGd1YXJkczogZ2V0QWxsUm91dGVHdWFyZHModC50YXJnZXRTbmFwc2hvdCEsIHQuY3VycmVudFNuYXBzaG90LCB0aGlzLnJvb3RDb250ZXh0cyksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGU7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICBjaGVja0d1YXJkcyh0aGlzLmVudmlyb25tZW50SW5qZWN0b3IsIChldnQ6IEV2ZW50KSA9PiB0aGlzLmV2ZW50cy5uZXh0KGV2dCkpLFxuICAgICAgICAgIHRhcCgodCkgPT4ge1xuICAgICAgICAgICAgb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5ndWFyZHNSZXN1bHQgPSB0Lmd1YXJkc1Jlc3VsdDtcbiAgICAgICAgICAgIGlmICh0Lmd1YXJkc1Jlc3VsdCAmJiB0eXBlb2YgdC5ndWFyZHNSZXN1bHQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICB0aHJvdyByZWRpcmVjdGluZ05hdmlnYXRpb25FcnJvcih0aGlzLnVybFNlcmlhbGl6ZXIsIHQuZ3VhcmRzUmVzdWx0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZ3VhcmRzRW5kID0gbmV3IEd1YXJkc0NoZWNrRW5kKFxuICAgICAgICAgICAgICB0LmlkLFxuICAgICAgICAgICAgICB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQuZXh0cmFjdGVkVXJsKSxcbiAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnVybEFmdGVyUmVkaXJlY3RzISksXG4gICAgICAgICAgICAgIHQudGFyZ2V0U25hcHNob3QhLFxuICAgICAgICAgICAgICAhIXQuZ3VhcmRzUmVzdWx0LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQoZ3VhcmRzRW5kKTtcbiAgICAgICAgICB9KSxcblxuICAgICAgICAgIGZpbHRlcigodCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0Lmd1YXJkc1Jlc3VsdCkge1xuICAgICAgICAgICAgICB0aGlzLmNhbmNlbE5hdmlnYXRpb25UcmFuc2l0aW9uKHQsICcnLCBOYXZpZ2F0aW9uQ2FuY2VsbGF0aW9uQ29kZS5HdWFyZFJlamVjdGVkKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICAvLyAtLS0gUkVTT0xWRSAtLS1cbiAgICAgICAgICBzd2l0Y2hUYXAoKHQpID0+IHtcbiAgICAgICAgICAgIGlmICh0Lmd1YXJkcy5jYW5BY3RpdmF0ZUNoZWNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG9mKHQpLnBpcGUoXG4gICAgICAgICAgICAgICAgdGFwKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlU3RhcnQgPSBuZXcgUmVzb2x2ZVN0YXJ0KFxuICAgICAgICAgICAgICAgICAgICB0LmlkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQuZXh0cmFjdGVkVXJsKSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnVybEFmdGVyUmVkaXJlY3RzISksXG4gICAgICAgICAgICAgICAgICAgIHQudGFyZ2V0U25hcHNob3QhLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQocmVzb2x2ZVN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHQpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxldCBkYXRhUmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBvZih0KS5waXBlKFxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlRGF0YSh0aGlzLnBhcmFtc0luaGVyaXRhbmNlU3RyYXRlZ3ksIHRoaXMuZW52aXJvbm1lbnRJbmplY3RvciksXG4gICAgICAgICAgICAgICAgICAgIHRhcCh7XG4gICAgICAgICAgICAgICAgICAgICAgbmV4dDogKCkgPT4gKGRhdGFSZXNvbHZlZCA9IHRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGFSZXNvbHZlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbE5hdmlnYXRpb25UcmFuc2l0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGBBdCBsZWFzdCBvbmUgcm91dGUgcmVzb2x2ZXIgZGlkbid0IGVtaXQgYW55IHZhbHVlLmBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF2aWdhdGlvbkNhbmNlbGxhdGlvbkNvZGUuTm9EYXRhRnJvbVJlc29sdmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0YXAoKHQpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVFbmQgPSBuZXcgUmVzb2x2ZUVuZChcbiAgICAgICAgICAgICAgICAgICAgdC5pZCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC51cmxBZnRlclJlZGlyZWN0cyEpLFxuICAgICAgICAgICAgICAgICAgICB0LnRhcmdldFNuYXBzaG90ISxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KHJlc29sdmVFbmQpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9KSxcblxuICAgICAgICAgIC8vIC0tLSBMT0FEIENPTVBPTkVOVFMgLS0tXG4gICAgICAgICAgc3dpdGNoVGFwKCh0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgbG9hZENvbXBvbmVudHMgPSAocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBBcnJheTxPYnNlcnZhYmxlPHZvaWQ+PiA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGxvYWRlcnM6IEFycmF5PE9ic2VydmFibGU8dm9pZD4+ID0gW107XG4gICAgICAgICAgICAgIGlmIChyb3V0ZS5yb3V0ZUNvbmZpZz8ubG9hZENvbXBvbmVudCAmJiAhcm91dGUucm91dGVDb25maWcuX2xvYWRlZENvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGxvYWRlcnMucHVzaChcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnTG9hZGVyLmxvYWRDb21wb25lbnQocm91dGUucm91dGVDb25maWcpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIHRhcCgobG9hZGVkQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgcm91dGUuY29tcG9uZW50ID0gbG9hZGVkQ29tcG9uZW50O1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHZvaWQgMCksXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiByb3V0ZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIGxvYWRlcnMucHVzaCguLi5sb2FkQ29tcG9uZW50cyhjaGlsZCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBsb2FkZXJzO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KGxvYWRDb21wb25lbnRzKHQudGFyZ2V0U25hcHNob3QhLnJvb3QpKS5waXBlKFxuICAgICAgICAgICAgICBkZWZhdWx0SWZFbXB0eShudWxsKSxcbiAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICBzd2l0Y2hUYXAoKCkgPT4gdGhpcy5hZnRlclByZWFjdGl2YXRpb24oKSksXG5cbiAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qge2N1cnJlbnRTbmFwc2hvdCwgdGFyZ2V0U25hcHNob3R9ID0gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZTtcbiAgICAgICAgICAgIGNvbnN0IHZpZXdUcmFuc2l0aW9uU3RhcnRlZCA9IHRoaXMuY3JlYXRlVmlld1RyYW5zaXRpb24/LihcbiAgICAgICAgICAgICAgdGhpcy5lbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgICAgICAgICBjdXJyZW50U25hcHNob3Qucm9vdCxcbiAgICAgICAgICAgICAgdGFyZ2V0U25hcHNob3QhLnJvb3QsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBJZiB2aWV3IHRyYW5zaXRpb25zIGFyZSBlbmFibGVkLCBibG9jayB0aGUgbmF2aWdhdGlvbiB1bnRpbCB0aGUgdmlld1xuICAgICAgICAgICAgLy8gdHJhbnNpdGlvbiBjYWxsYmFjayBzdGFydHMuIE90aGVyd2lzZSwgY29udGludWUgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICByZXR1cm4gdmlld1RyYW5zaXRpb25TdGFydGVkXG4gICAgICAgICAgICAgID8gZnJvbSh2aWV3VHJhbnNpdGlvblN0YXJ0ZWQpLnBpcGUobWFwKCgpID0+IG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUpKVxuICAgICAgICAgICAgICA6IG9mKG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUpO1xuICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgbWFwKCh0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0Um91dGVyU3RhdGUgPSBjcmVhdGVSb3V0ZXJTdGF0ZShcbiAgICAgICAgICAgICAgcm91dGVyLnJvdXRlUmV1c2VTdHJhdGVneSxcbiAgICAgICAgICAgICAgdC50YXJnZXRTbmFwc2hvdCEsXG4gICAgICAgICAgICAgIHQuY3VycmVudFJvdXRlclN0YXRlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFRyYW5zaXRpb24gPSBvdmVyYWxsVHJhbnNpdGlvblN0YXRlID0gey4uLnQsIHRhcmdldFJvdXRlclN0YXRlfTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudE5hdmlnYXRpb24hLnRhcmdldFJvdXRlclN0YXRlID0gdGFyZ2V0Um91dGVyU3RhdGU7XG4gICAgICAgICAgICByZXR1cm4gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZTtcbiAgICAgICAgICB9KSxcblxuICAgICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KG5ldyBCZWZvcmVBY3RpdmF0ZVJvdXRlcygpKTtcbiAgICAgICAgICB9KSxcblxuICAgICAgICAgIGFjdGl2YXRlUm91dGVzKFxuICAgICAgICAgICAgdGhpcy5yb290Q29udGV4dHMsXG4gICAgICAgICAgICByb3V0ZXIucm91dGVSZXVzZVN0cmF0ZWd5LFxuICAgICAgICAgICAgKGV2dDogRXZlbnQpID0+IHRoaXMuZXZlbnRzLm5leHQoZXZ0KSxcbiAgICAgICAgICAgIHRoaXMuaW5wdXRCaW5kaW5nRW5hYmxlZCxcbiAgICAgICAgICApLFxuXG4gICAgICAgICAgLy8gRW5zdXJlIHRoYXQgaWYgc29tZSBvYnNlcnZhYmxlIHVzZWQgdG8gZHJpdmUgdGhlIHRyYW5zaXRpb24gZG9lc24ndFxuICAgICAgICAgIC8vIGNvbXBsZXRlLCB0aGUgbmF2aWdhdGlvbiBzdGlsbCBmaW5hbGl6ZXMgVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBidXRcbiAgICAgICAgICAvLyB0aGlzIGlzIGRvbmUgYXMgYSBzYWZldHkgbWVhc3VyZSB0byBhdm9pZCBzdXJmYWNpbmcgdGhpcyBlcnJvciAoIzQ5NTY3KS5cbiAgICAgICAgICB0YWtlKDEpLFxuXG4gICAgICAgICAgdGFwKHtcbiAgICAgICAgICAgIG5leHQ6ICh0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbikgPT4ge1xuICAgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB0aGlzLmxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvbiA9IHRoaXMuY3VycmVudE5hdmlnYXRpb247XG4gICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQoXG4gICAgICAgICAgICAgICAgbmV3IE5hdmlnYXRpb25FbmQoXG4gICAgICAgICAgICAgICAgICB0LmlkLFxuICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQudXJsQWZ0ZXJSZWRpcmVjdHMhKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLnRpdGxlU3RyYXRlZ3k/LnVwZGF0ZVRpdGxlKHQudGFyZ2V0Um91dGVyU3RhdGUhLnNuYXBzaG90KTtcbiAgICAgICAgICAgICAgdC5yZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgLy8gVGhlcmUgdXNlZCB0byBiZSBhIGxvdCBtb3JlIGxvZ2ljIGhhcHBlbmluZyBkaXJlY3RseSB3aXRoaW4gdGhlXG4gICAgICAgICAgLy8gdHJhbnNpdGlvbiBPYnNlcnZhYmxlLiBTb21lIG9mIHRoaXMgbG9naWMgaGFzIGJlZW4gcmVmYWN0b3JlZCBvdXQgdG9cbiAgICAgICAgICAvLyBvdGhlciBwbGFjZXMgYnV0IHRoZXJlIG1heSBzdGlsbCBiZSBlcnJvcnMgdGhhdCBoYXBwZW4gdGhlcmUuIFRoaXMgZ2l2ZXNcbiAgICAgICAgICAvLyB1cyBhIHdheSB0byBjYW5jZWwgdGhlIHRyYW5zaXRpb24gZnJvbSB0aGUgb3V0c2lkZS4gVGhpcyBtYXkgYWxzbyBiZVxuICAgICAgICAgIC8vIHJlcXVpcmVkIGluIHRoZSBmdXR1cmUgdG8gc3VwcG9ydCBzb21ldGhpbmcgbGlrZSB0aGUgYWJvcnQgc2lnbmFsIG9mIHRoZVxuICAgICAgICAgIC8vIE5hdmlnYXRpb24gQVBJIHdoZXJlIHRoZSBuYXZpZ2F0aW9uIGdldHMgYWJvcnRlZCBmcm9tIG91dHNpZGUgdGhlXG4gICAgICAgICAgLy8gdHJhbnNpdGlvbi5cbiAgICAgICAgICB0YWtlVW50aWwoXG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25BYm9ydFN1YmplY3QucGlwZShcbiAgICAgICAgICAgICAgdGFwKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuXG4gICAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgICAgLyogV2hlbiB0aGUgbmF2aWdhdGlvbiBzdHJlYW0gZmluaXNoZXMgZWl0aGVyIHRocm91Z2ggZXJyb3Igb3Igc3VjY2VzcyxcbiAgICAgICAgICAgICAqIHdlIHNldCB0aGUgYGNvbXBsZXRlZGAgb3IgYGVycm9yZWRgIGZsYWcuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lXG4gICAgICAgICAgICAgKiBzaXR1YXRpb25zIHdoZXJlIHdlIGNvdWxkIGdldCBoZXJlIHdpdGhvdXQgZWl0aGVyIG9mIHRob3NlIGJlaW5nIHNldC5cbiAgICAgICAgICAgICAqIEZvciBpbnN0YW5jZSwgYSByZWRpcmVjdCBkdXJpbmcgTmF2aWdhdGlvblN0YXJ0LiBUaGVyZWZvcmUsIHRoaXMgaXMgYVxuICAgICAgICAgICAgICogY2F0Y2gtYWxsIHRvIG1ha2Ugc3VyZSB0aGUgTmF2aWdhdGlvbkNhbmNlbCBldmVudCBpcyBmaXJlZCB3aGVuIGFcbiAgICAgICAgICAgICAqIG5hdmlnYXRpb24gZ2V0cyBjYW5jZWxsZWQgYnV0IG5vdCBjYXVnaHQgYnkgb3RoZXIgbWVhbnMuICovXG4gICAgICAgICAgICBpZiAoIWNvbXBsZXRlZCAmJiAhZXJyb3JlZCkge1xuICAgICAgICAgICAgICBjb25zdCBjYW5jZWxhdGlvblJlYXNvbiA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlXG4gICAgICAgICAgICAgICAgICA/IGBOYXZpZ2F0aW9uIElEICR7b3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5pZH0gaXMgbm90IGVxdWFsIHRvIHRoZSBjdXJyZW50IG5hdmlnYXRpb24gaWQgJHt0aGlzLm5hdmlnYXRpb25JZH1gXG4gICAgICAgICAgICAgICAgICA6ICcnO1xuICAgICAgICAgICAgICB0aGlzLmNhbmNlbE5hdmlnYXRpb25UcmFuc2l0aW9uKFxuICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUsXG4gICAgICAgICAgICAgICAgY2FuY2VsYXRpb25SZWFzb24sXG4gICAgICAgICAgICAgICAgTmF2aWdhdGlvbkNhbmNlbGxhdGlvbkNvZGUuU3VwZXJzZWRlZEJ5TmV3TmF2aWdhdGlvbixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE9ubHkgY2xlYXIgY3VycmVudCBuYXZpZ2F0aW9uIGlmIGl0IGlzIHN0aWxsIHNldCB0byB0aGUgb25lIHRoYXRcbiAgICAgICAgICAgIC8vIGZpbmFsaXplZC5cbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRUcmFuc2l0aW9uPy5pZCA9PT0gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5pZCkge1xuICAgICAgICAgICAgICB0aGlzLmN1cnJlbnROYXZpZ2F0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50VHJhbnNpdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICAgY2F0Y2hFcnJvcigoZSkgPT4ge1xuICAgICAgICAgICAgZXJyb3JlZCA9IHRydWU7XG4gICAgICAgICAgICAvKiBUaGlzIGVycm9yIHR5cGUgaXMgaXNzdWVkIGR1cmluZyBSZWRpcmVjdCwgYW5kIGlzIGhhbmRsZWQgYXMgYVxuICAgICAgICAgICAgICogY2FuY2VsbGF0aW9uIHJhdGhlciB0aGFuIGFuIGVycm9yLiAqL1xuICAgICAgICAgICAgaWYgKGlzTmF2aWdhdGlvbkNhbmNlbGluZ0Vycm9yKGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQoXG4gICAgICAgICAgICAgICAgbmV3IE5hdmlnYXRpb25DYW5jZWwoXG4gICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmlkLFxuICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZShvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICBlLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICBlLmNhbmNlbGxhdGlvbkNvZGUsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAvLyBXaGVuIHJlZGlyZWN0aW5nLCB3ZSBuZWVkIHRvIGRlbGF5IHJlc29sdmluZyB0aGUgbmF2aWdhdGlvblxuICAgICAgICAgICAgICAvLyBwcm9taXNlIGFuZCBwdXNoIGl0IHRvIHRoZSByZWRpcmVjdCBuYXZpZ2F0aW9uXG4gICAgICAgICAgICAgIGlmICghaXNSZWRpcmVjdGluZ05hdmlnYXRpb25DYW5jZWxpbmdFcnJvcihlKSkge1xuICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChuZXcgUmVkaXJlY3RSZXF1ZXN0KGUudXJsLCBlLm5hdmlnYXRpb25CZWhhdmlvck9wdGlvbnMpKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8qIEFsbCBvdGhlciBlcnJvcnMgc2hvdWxkIHJlc2V0IHRvIHRoZSByb3V0ZXIncyBpbnRlcm5hbCBVUkwgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAqIHRvIHRoZSBwcmUtZXJyb3Igc3RhdGUuICovXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCBuYXZpZ2F0aW9uRXJyb3IgPSBuZXcgTmF2aWdhdGlvbkVycm9yKFxuICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUuaWQsXG4gICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZShvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgZSxcbiAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnRhcmdldFNuYXBzaG90ID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hdmlnYXRpb25FcnJvckhhbmRsZXJSZXN1bHQgPSBydW5JbkluamVjdGlvbkNvbnRleHQoXG4gICAgICAgICAgICAgICAgICB0aGlzLmVudmlyb25tZW50SW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgICAoKSA9PiB0aGlzLm5hdmlnYXRpb25FcnJvckhhbmRsZXI/LihuYXZpZ2F0aW9uRXJyb3IpLFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBpZiAobmF2aWdhdGlvbkVycm9ySGFuZGxlclJlc3VsdCBpbnN0YW5jZW9mIFJlZGlyZWN0Q29tbWFuZCkge1xuICAgICAgICAgICAgICAgICAgY29uc3Qge21lc3NhZ2UsIGNhbmNlbGxhdGlvbkNvZGV9ID0gcmVkaXJlY3RpbmdOYXZpZ2F0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplcixcbiAgICAgICAgICAgICAgICAgICAgbmF2aWdhdGlvbkVycm9ySGFuZGxlclJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgTmF2aWdhdGlvbkNhbmNlbChcbiAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5leHRyYWN0ZWRVcmwpLFxuICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgY2FuY2VsbGF0aW9uQ29kZSxcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgUmVkaXJlY3RSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgIG5hdmlnYXRpb25FcnJvckhhbmRsZXJSZXN1bHQucmVkaXJlY3RUbyxcbiAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uRXJyb3JIYW5kbGVyUmVzdWx0Lm5hdmlnYXRpb25CZWhhdmlvck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KG5hdmlnYXRpb25FcnJvcik7XG4gICAgICAgICAgICAgICAgICAvLyBUT0RPKGF0c2NvdHQpOiByZW1vdmUgZGVwcmVjYXRpb24gb24gZXJyb3JIYW5kbGVyIGluIFJvdXRlck1vZHVsZS5mb3JSb290IGFuZCBjaGFuZ2UgYmVoYXZpb3IgdG8gcHJvdmlkZSBOQVZJR0FUSU9OX0VSUk9SX0hBTkRMRVJcbiAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IFN0aWxsIHJlbW92ZSBwdWJsaWMgYFJvdXRlci5lcnJvckhhbmRsZXJgIHByb3BlcnR5LCBhcyB0aGlzIGlzIHN1cHBvc2VkIHRvIGJlIGNvbmZpZ3VyZWQgaW4gREkuXG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnJvckhhbmRsZXJSZXN1bHQgPSByb3V0ZXIuZXJyb3JIYW5kbGVyKGUpO1xuICAgICAgICAgICAgICAgICAgb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5yZXNvbHZlKCEhZXJyb3JIYW5kbGVyUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVlKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETyhhdHNjb3R0KTogY29uc2lkZXIgZmxpcHBpbmcgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2ZcbiAgICAgICAgICAgICAgICAvLyByZXNvbHZlTmF2aWdhdGlvblByb21pc2VPbkVycm9yIHRvIGJlIGByZXNvbHZlKGZhbHNlKWAgd2hlblxuICAgICAgICAgICAgICAgIC8vIHVuZGVmaW5lZC4gVGhpcyBpcyB0aGUgbW9zdCBzYW5lIHRoaW5nIHRvIGRvIGdpdmVuIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBhcHBsaWNhdGlvbnMgdmVyeSByYXJlbHkgaGFuZGxlIHRoZSBwcm9taXNlIHJlamVjdGlvbiBhbmQsIGFzIGFcbiAgICAgICAgICAgICAgICAvLyByZXN1bHQsIHdvdWxkIGdldCBcInVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvblwiIGNvbnNvbGUgbG9ncy5cbiAgICAgICAgICAgICAgICAvLyBUaGUgdmFzdCBtYWpvcml0eSBvZiBhcHBsaWNhdGlvbnMgd291bGQgbm90IGJlIGFmZmVjdGVkIGJ5IHRoaXNcbiAgICAgICAgICAgICAgICAvLyBjaGFuZ2Ugc28gb21pdHRpbmcgYSBtaWdyYXRpb24gc2VlbXMgcmVhc29uYWJsZS4gSW5zdGVhZCxcbiAgICAgICAgICAgICAgICAvLyBhcHBsaWNhdGlvbnMgdGhhdCByZWx5IG9uIHJlamVjdGlvbiBjYW4gc3BlY2lmaWNhbGx5IG9wdC1pbiB0byB0aGVcbiAgICAgICAgICAgICAgICAvLyBvbGQgYmVoYXZpb3IuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZXNvbHZlTmF2aWdhdGlvblByb21pc2VPbkVycm9yKSB7XG4gICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnJlamVjdChlZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgLy8gY2FzdGluZyBiZWNhdXNlIGBwaXBlYCByZXR1cm5zIG9ic2VydmFibGUoe30pIHdoZW4gY2FsbGVkIHdpdGggOCsgYXJndW1lbnRzXG4gICAgICB9KSxcbiAgICApIGFzIE9ic2VydmFibGU8TmF2aWdhdGlvblRyYW5zaXRpb24+O1xuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWxOYXZpZ2F0aW9uVHJhbnNpdGlvbihcbiAgICB0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbixcbiAgICByZWFzb246IHN0cmluZyxcbiAgICBjb2RlOiBOYXZpZ2F0aW9uQ2FuY2VsbGF0aW9uQ29kZSxcbiAgKSB7XG4gICAgY29uc3QgbmF2Q2FuY2VsID0gbmV3IE5hdmlnYXRpb25DYW5jZWwoXG4gICAgICB0LmlkLFxuICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICByZWFzb24sXG4gICAgICBjb2RlLFxuICAgICk7XG4gICAgdGhpcy5ldmVudHMubmV4dChuYXZDYW5jZWwpO1xuICAgIHQucmVzb2x2ZShmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgV2hldGhlciB3ZSdyZSBuYXZpZ2F0aW5nIHRvIHNvbWV3aGVyZSB0aGF0IGlzIG5vdCB3aGF0IHRoZSBSb3V0ZXIgaXNcbiAgICogY3VycmVudGx5IHNldCB0by5cbiAgICovXG4gIHByaXZhdGUgaXNVcGRhdGluZ0ludGVybmFsU3RhdGUoKSB7XG4gICAgLy8gVE9ETyhhdHNjb3R0KTogVGhlIHNlcmlhbGl6ZXIgc2hvdWxkIGxpa2VseSBiZSB1c2VkIGluc3RlYWQgb2ZcbiAgICAvLyBgVXJsVHJlZS50b1N0cmluZygpYC4gQ3VzdG9tIHNlcmlhbGl6ZXJzIGFyZSBvZnRlbiB3cml0dGVuIHRvIGhhbmRsZVxuICAgIC8vIHRoaW5ncyBiZXR0ZXIgdGhhbiB0aGUgZGVmYXVsdCBvbmUgKG9iamVjdHMsIGZvciBleGFtcGxlIHdpbGwgYmVcbiAgICAvLyBbT2JqZWN0IG9iamVjdF0gd2l0aCB0aGUgY3VzdG9tIHNlcmlhbGl6ZXIgYW5kIGJlIFwidGhlIHNhbWVcIiB3aGVuIHRoZXlcbiAgICAvLyBhcmVuJ3QpLlxuICAgIC8vIChTYW1lIGZvciBpc1VwZGF0ZWRCcm93c2VyVXJsKVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1cnJlbnRUcmFuc2l0aW9uPy5leHRyYWN0ZWRVcmwudG9TdHJpbmcoKSAhPT1cbiAgICAgIHRoaXMuY3VycmVudFRyYW5zaXRpb24/LmN1cnJlbnRVcmxUcmVlLnRvU3RyaW5nKClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgd2UncmUgdXBkYXRpbmcgdGhlIGJyb3dzZXIgVVJMIHRvIHNvbWV0aGluZyBuZXcgKG5hdmlnYXRpb24gaXMgZ29pbmdcbiAgICogdG8gc29tZXdoZXJlIG5vdCBkaXNwbGF5ZWQgaW4gdGhlIFVSTCBiYXIgYW5kIHdlIHdpbGwgdXBkYXRlIHRoZSBVUkxcbiAgICogYmFyIGlmIG5hdmlnYXRpb24gc3VjY2VlZHMpLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1VwZGF0ZWRCcm93c2VyVXJsKCkge1xuICAgIC8vIFRoZSBleHRyYWN0ZWQgVVJMIGlzIHRoZSBwYXJ0IG9mIHRoZSBVUkwgdGhhdCB0aGlzIGFwcGxpY2F0aW9uIGNhcmVzIGFib3V0LiBgZXh0cmFjdGAgbWF5XG4gICAgLy8gcmV0dXJuIG9ubHkgcGFydCBvZiB0aGUgYnJvd3NlciBVUkwgYW5kIHRoYXQgcGFydCBtYXkgaGF2ZSBub3QgY2hhbmdlZCBldmVuIGlmIHNvbWUgb3RoZXJcbiAgICAvLyBwb3J0aW9uIG9mIHRoZSBVUkwgZGlkLlxuICAgIGNvbnN0IGN1cnJlbnRCcm93c2VyVXJsID0gdGhpcy51cmxIYW5kbGluZ1N0cmF0ZWd5LmV4dHJhY3QoXG4gICAgICB0aGlzLnVybFNlcmlhbGl6ZXIucGFyc2UodGhpcy5sb2NhdGlvbi5wYXRoKHRydWUpKSxcbiAgICApO1xuICAgIGNvbnN0IHRhcmdldEJyb3dzZXJVcmwgPVxuICAgICAgdGhpcy5jdXJyZW50TmF2aWdhdGlvbj8udGFyZ2V0QnJvd3NlclVybCA/PyB0aGlzLmN1cnJlbnROYXZpZ2F0aW9uPy5leHRyYWN0ZWRVcmw7XG4gICAgcmV0dXJuIChcbiAgICAgIGN1cnJlbnRCcm93c2VyVXJsLnRvU3RyaW5nKCkgIT09IHRhcmdldEJyb3dzZXJVcmw/LnRvU3RyaW5nKCkgJiZcbiAgICAgICF0aGlzLmN1cnJlbnROYXZpZ2F0aW9uPy5leHRyYXMuc2tpcExvY2F0aW9uQ2hhbmdlXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNCcm93c2VyVHJpZ2dlcmVkTmF2aWdhdGlvbihzb3VyY2U6IE5hdmlnYXRpb25UcmlnZ2VyKSB7XG4gIHJldHVybiBzb3VyY2UgIT09IElNUEVSQVRJVkVfTkFWSUdBVElPTjtcbn1cbiJdfQ==