import { __assign, __extends } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { invariant } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29"; import { equal } from "/_nuxt/node_modules/@wry/equality/lib/index.js?v=e4f18c29"; import { NetworkStatus, isNetworkRequestInFlight } from "/_nuxt/node_modules/@apollo/client/core/networkStatus.js?v=e4f18c29"; import { cloneDeep, compact, getOperationDefinition, Observable, iterateObserversSafely, fixObservableSubclass, getQueryDefinition, preventUnhandledRejection, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { ApolloError, isApolloError } from "/_nuxt/node_modules/@apollo/client/errors/index.js?v=e4f18c29"; import { equalByQuery } from "/_nuxt/node_modules/@apollo/client/core/equalByQuery.js?v=e4f18c29"; import { Slot } from "/_nuxt/node_modules/optimism/lib/index.js?v=e4f18c29"; var assign = Object.assign, hasOwnProperty = Object.hasOwnProperty; var ObservableQuery = /** @class */ (function (_super) { __extends(ObservableQuery, _super); function ObservableQuery(_a) { var queryManager = _a.queryManager, queryInfo = _a.queryInfo, options = _a.options; var _this = this; var startedInactive = ObservableQuery.inactiveOnCreation.getValue(); _this = _super.call(this, function (observer) { if (startedInactive) { queryManager["queries"].set(_this.queryId, queryInfo); startedInactive = false; } // Zen Observable has its own error function, so in order to log correctly // we need to provide a custom error callback. try { var subObserver = observer._subscription._observer; if (subObserver && !subObserver.error) { subObserver.error = defaultSubscriptionObserverErrorCallback; } } catch (_a) { } var first = !_this.observers.size; _this.observers.add(observer); // Deliver most recent error or result. var last = _this.last; if (last && last.error) { observer.error && observer.error(last.error); } else if (last && last.result) { observer.next && observer.next(_this.maskResult(last.result)); } // Initiate observation of this query if it hasn't been reported to // the QueryManager yet. if (first) { // Blindly catching here prevents unhandled promise rejections, // and is safe because the ObservableQuery handles this error with // this.observer.error, so we're not just swallowing the error by // ignoring it here. _this.reobserve().catch(function () { }); } return function () { if (_this.observers.delete(observer) && !_this.observers.size) { _this.tearDownQuery(); } }; }) || this; _this.observers = new Set(); _this.subscriptions = new Set(); _this.dirty = false; // related classes _this.queryInfo = queryInfo; _this.queryManager = queryManager; // active state _this.waitForOwnResult = skipCacheDataFor(options.fetchPolicy); _this.isTornDown = false; _this.subscribeToMore = _this.subscribeToMore.bind(_this); _this.maskResult = _this.maskResult.bind(_this); var _b = queryManager.defaultOptions.watchQuery, _c = _b === void 0 ? {} : _b, _d = _c.fetchPolicy, defaultFetchPolicy = _d === void 0 ? "cache-first" : _d; var _e = options.fetchPolicy, fetchPolicy = _e === void 0 ? defaultFetchPolicy : _e, // Make sure we don't store "standby" as the initialFetchPolicy. _f = options.initialFetchPolicy, // Make sure we don't store "standby" as the initialFetchPolicy. initialFetchPolicy = _f === void 0 ? fetchPolicy === "standby" ? defaultFetchPolicy : (fetchPolicy) : _f; _this.options = __assign(__assign({}, options), { // Remember the initial options.fetchPolicy so we can revert back to this // policy when variables change. This information can also be specified // (or overridden) by providing options.initialFetchPolicy explicitly. initialFetchPolicy: initialFetchPolicy, // This ensures this.options.fetchPolicy always has a string value, in // case options.fetchPolicy was not provided. fetchPolicy: fetchPolicy }); _this.queryId = queryInfo.queryId || queryManager.generateQueryId(); var opDef = getOperationDefinition(_this.query); _this.queryName = opDef && opDef.name && opDef.name.value; return _this; } Object.defineProperty(ObservableQuery.prototype, "query", { // The `query` computed property will always reflect the document transformed // by the last run query. `this.options.query` will always reflect the raw // untransformed query to ensure document transforms with runtime conditionals // are run on the original document. get: function () { return this.lastQuery || this.options.query; }, enumerable: false, configurable: true }); Object.defineProperty(ObservableQuery.prototype, "variables", { // Computed shorthand for this.options.variables, preserved for // backwards compatibility. /** * An object containing the variables that were provided for the query. */ get: function () { return this.options.variables; }, enumerable: false, configurable: true }); ObservableQuery.prototype.result = function () { var _this = this; return new Promise(function (resolve, reject) { // TODO: this code doesn’t actually make sense insofar as the observer // will never exist in this.observers due how zen-observable wraps observables. // https://github.com/zenparsing/zen-observable/blob/master/src/Observable.js#L169 var observer = { next: function (result) { resolve(result); // Stop the query within the QueryManager if we can before // this function returns. // // We do this in order to prevent observers piling up within // the QueryManager. Notice that we only fully unsubscribe // from the subscription in a setTimeout(..., 0) call. This call can // actually be handled by the browser at a much later time. If queries // are fired in the meantime, observers that should have been removed // from the QueryManager will continue to fire, causing an unnecessary // performance hit. _this.observers.delete(observer); if (!_this.observers.size) { _this.queryManager.removeQuery(_this.queryId); } setTimeout(function () { subscription.unsubscribe(); }, 0); }, error: reject, }; var subscription = _this.subscribe(observer); }); }; /** @internal */ ObservableQuery.prototype.resetDiff = function () { this.queryInfo.resetDiff(); }; ObservableQuery.prototype.getCurrentFullResult = function (saveAsLastResult) { if (saveAsLastResult === void 0) { saveAsLastResult = true; } // Use the last result as long as the variables match this.variables. var lastResult = this.getLastResult(true); var networkStatus = this.queryInfo.networkStatus || (lastResult && lastResult.networkStatus) || NetworkStatus.ready; var result = __assign(__assign({}, lastResult), { loading: isNetworkRequestInFlight(networkStatus), networkStatus: networkStatus }); var _a = this.options.fetchPolicy, fetchPolicy = _a === void 0 ? "cache-first" : _a; if ( // These fetch policies should never deliver data from the cache, unless // redelivering a previously delivered result. skipCacheDataFor(fetchPolicy) || // If this.options.query has @client(always: true) fields, we cannot // trust diff.result, since it was read from the cache without running // local resolvers (and it's too late to run resolvers now, since we must // return a result synchronously). this.queryManager.getDocumentInfo(this.query).hasForcedResolvers) { // Fall through. } else if (this.waitForOwnResult) { // This would usually be a part of `QueryInfo.getDiff()`. // which we skip in the waitForOwnResult case since we are not // interested in the diff. this.queryInfo["updateWatch"](); } else { var diff = this.queryInfo.getDiff(); if (diff.complete || this.options.returnPartialData) { result.data = diff.result; } if (equal(result.data, {})) { result.data = void 0; } if (diff.complete) { // Similar to setting result.partial to false, but taking advantage of the // falsiness of missing fields. delete result.partial; // If the diff is complete, and we're using a FetchPolicy that // terminates after a complete cache read, we can assume the next result // we receive will have NetworkStatus.ready and !loading. if (diff.complete && result.networkStatus === NetworkStatus.loading && (fetchPolicy === "cache-first" || fetchPolicy === "cache-only")) { result.networkStatus = NetworkStatus.ready; result.loading = false; } } else { result.partial = true; } // We need to check for both both `error` and `errors` field because there // are cases where sometimes `error` is set, but not `errors` and // vice-versa. This will be updated in the next major version when // `errors` is deprecated in favor of `error`. if (result.networkStatus === NetworkStatus.ready && (result.error || result.errors)) { result.networkStatus = NetworkStatus.error; } if (globalThis.__DEV__ !== false && !diff.complete && !this.options.partialRefetch && !result.loading && !result.data && !result.error) { logMissingFieldErrors(diff.missing); } } if (saveAsLastResult) { this.updateLastResult(result); } return result; }; ObservableQuery.prototype.getCurrentResult = function (saveAsLastResult) { if (saveAsLastResult === void 0) { saveAsLastResult = true; } return this.maskResult(this.getCurrentFullResult(saveAsLastResult)); }; // Compares newResult to the snapshot we took of this.lastResult when it was // first received. ObservableQuery.prototype.isDifferentFromLastResult = function (newResult, variables) { if (!this.last) { return true; } var documentInfo = this.queryManager.getDocumentInfo(this.query); var dataMasking = this.queryManager.dataMasking; var query = dataMasking ? documentInfo.nonReactiveQuery : this.query; var resultIsDifferent = dataMasking || documentInfo.hasNonreactiveDirective ? !equalByQuery(query, this.last.result, newResult, this.variables) : !equal(this.last.result, newResult); return (resultIsDifferent || (variables && !equal(this.last.variables, variables))); }; ObservableQuery.prototype.getLast = function (key, variablesMustMatch) { var last = this.last; if (last && last[key] && (!variablesMustMatch || equal(last.variables, this.variables))) { return last[key]; } }; ObservableQuery.prototype.getLastResult = function (variablesMustMatch) { return this.getLast("result", variablesMustMatch); }; ObservableQuery.prototype.getLastError = function (variablesMustMatch) { return this.getLast("error", variablesMustMatch); }; ObservableQuery.prototype.resetLastResults = function () { delete this.last; this.isTornDown = false; }; ObservableQuery.prototype.resetQueryStoreErrors = function () { this.queryManager.resetErrors(this.queryId); }; /** * Update the variables of this observable query, and fetch the new results. * This method should be preferred over `setVariables` in most use cases. * * @param variables - The new set of variables. If there are missing variables, * the previous values of those variables will be used. */ ObservableQuery.prototype.refetch = function (variables) { var _a; var reobserveOptions = { // Always disable polling for refetches. pollInterval: 0, }; // Unless the provided fetchPolicy always consults the network // (no-cache, network-only, or cache-and-network), override it with // network-only to force the refetch for this fetchQuery call. var fetchPolicy = this.options.fetchPolicy; if (fetchPolicy === "no-cache") { reobserveOptions.fetchPolicy = "no-cache"; } else { reobserveOptions.fetchPolicy = "network-only"; } if (globalThis.__DEV__ !== false && variables && hasOwnProperty.call(variables, "variables")) { var queryDef = getQueryDefinition(this.query); var vars = queryDef.variableDefinitions; if (!vars || !vars.some(function (v) { return v.variable.name.value === "variables"; })) { globalThis.__DEV__ !== false && invariant.warn( 21, variables, ((_a = queryDef.name) === null || _a === void 0 ? void 0 : _a.value) || queryDef ); } } if (variables && !equal(this.options.variables, variables)) { // Update the existing options with new variables reobserveOptions.variables = this.options.variables = __assign(__assign({}, this.options.variables), variables); } this.queryInfo.resetLastWrite(); return this.reobserve(reobserveOptions, NetworkStatus.refetch); }; /** * A function that helps you fetch the next set of results for a [paginated list field](https://www.apollographql.com/docs/react/pagination/core-api/). */ ObservableQuery.prototype.fetchMore = function (fetchMoreOptions) { var _this = this; var combinedOptions = __assign(__assign({}, (fetchMoreOptions.query ? fetchMoreOptions : (__assign(__assign(__assign(__assign({}, this.options), { query: this.options.query }), fetchMoreOptions), { variables: __assign(__assign({}, this.options.variables), fetchMoreOptions.variables) })))), { // The fetchMore request goes immediately to the network and does // not automatically write its result to the cache (hence no-cache // instead of network-only), because we allow the caller of // fetchMore to provide an updateQuery callback that determines how // the data gets written to the cache. fetchPolicy: "no-cache" }); combinedOptions.query = this.transformDocument(combinedOptions.query); var qid = this.queryManager.generateQueryId(); // If a temporary query is passed to `fetchMore`, we don't want to store // it as the last query result since it may be an optimized query for // pagination. We will however run the transforms on the original document // as well as the document passed in `fetchMoreOptions` to ensure the cache // uses the most up-to-date document which may rely on runtime conditionals. this.lastQuery = fetchMoreOptions.query ? this.transformDocument(this.options.query) : combinedOptions.query; // Simulate a loading result for the original query with // result.networkStatus === NetworkStatus.fetchMore. var queryInfo = this.queryInfo; var originalNetworkStatus = queryInfo.networkStatus; queryInfo.networkStatus = NetworkStatus.fetchMore; if (combinedOptions.notifyOnNetworkStatusChange) { this.observe(); } var updatedQuerySet = new Set(); var updateQuery = fetchMoreOptions === null || fetchMoreOptions === void 0 ? void 0 : fetchMoreOptions.updateQuery; var isCached = this.options.fetchPolicy !== "no-cache"; if (!isCached) { invariant(updateQuery, 22); } return this.queryManager .fetchQuery(qid, combinedOptions, NetworkStatus.fetchMore) .then(function (fetchMoreResult) { _this.queryManager.removeQuery(qid); if (queryInfo.networkStatus === NetworkStatus.fetchMore) { queryInfo.networkStatus = originalNetworkStatus; } if (isCached) { // Performing this cache update inside a cache.batch transaction ensures // any affected cache.watch watchers are notified at most once about any // updates. Most watchers will be using the QueryInfo class, which // responds to notifications by calling reobserveCacheFirst to deliver // fetchMore cache results back to this ObservableQuery. _this.queryManager.cache.batch({ update: function (cache) { var updateQuery = fetchMoreOptions.updateQuery; if (updateQuery) { cache.updateQuery({ query: _this.query, variables: _this.variables, returnPartialData: true, optimistic: false, }, function (previous) { return updateQuery(previous, { fetchMoreResult: fetchMoreResult.data, variables: combinedOptions.variables, }); }); } else { // If we're using a field policy instead of updateQuery, the only // thing we need to do is write the new data to the cache using // combinedOptions.variables (instead of this.variables, which is // what this.updateQuery uses, because it works by abusing the // original field value, keyed by the original variables). cache.writeQuery({ query: combinedOptions.query, variables: combinedOptions.variables, data: fetchMoreResult.data, }); } }, onWatchUpdated: function (watch) { // Record the DocumentNode associated with any watched query whose // data were updated by the cache writes above. updatedQuerySet.add(watch.query); }, }); } else { // There is a possibility `lastResult` may not be set when // `fetchMore` is called which would cause this to crash. This should // only happen if we haven't previously reported a result. We don't // quite know what the right behavior should be here since this block // of code runs after the fetch result has executed on the network. // We plan to let it crash in the meantime. // // If we get bug reports due to the `data` property access on // undefined, this should give us a real-world scenario that we can // use to test against and determine the right behavior. If we do end // up changing this behavior, this may require, for example, an // adjustment to the types on `updateQuery` since that function // expects that the first argument always contains previous result // data, but not `undefined`. var lastResult = _this.getLast("result"); var data = updateQuery(lastResult.data, { fetchMoreResult: fetchMoreResult.data, variables: combinedOptions.variables, }); _this.reportResult(__assign(__assign({}, lastResult), { networkStatus: originalNetworkStatus, loading: isNetworkRequestInFlight(originalNetworkStatus), data: data }), _this.variables); } return _this.maskResult(fetchMoreResult); }) .finally(function () { // In case the cache writes above did not generate a broadcast // notification (which would have been intercepted by onWatchUpdated), // likely because the written data were the same as what was already in // the cache, we still want fetchMore to deliver its final loading:false // result with the unchanged data. if (isCached && !updatedQuerySet.has(_this.query)) { _this.reobserveCacheFirst(); } }); }; // XXX the subscription variables are separate from the query variables. // if you want to update subscription variables, right now you have to do that separately, // and you can only do it by stopping the subscription and then subscribing again with new variables. /** * A function that enables you to execute a [subscription](https://www.apollographql.com/docs/react/data/subscriptions/), usually to subscribe to specific fields that were included in the query. * * This function returns _another_ function that you can call to terminate the subscription. */ ObservableQuery.prototype.subscribeToMore = function (options) { var _this = this; var subscription = this.queryManager .startGraphQLSubscription({ query: options.document, variables: options.variables, context: options.context, }) .subscribe({ next: function (subscriptionData) { var updateQuery = options.updateQuery; if (updateQuery) { _this.updateQuery(function (previous, updateOptions) { return updateQuery(previous, __assign({ subscriptionData: subscriptionData }, updateOptions)); }); } }, error: function (err) { if (options.onError) { options.onError(err); return; } globalThis.__DEV__ !== false && invariant.error(23, err); }, }); this.subscriptions.add(subscription); return function () { if (_this.subscriptions.delete(subscription)) { subscription.unsubscribe(); } }; }; ObservableQuery.prototype.setOptions = function (newOptions) { return this.reobserve(newOptions); }; ObservableQuery.prototype.silentSetOptions = function (newOptions) { var mergedOptions = compact(this.options, newOptions || {}); assign(this.options, mergedOptions); }; /** * Update the variables of this observable query, and fetch the new results * if they've changed. Most users should prefer `refetch` instead of * `setVariables` in order to to be properly notified of results even when * they come from the cache. * * Note: the `next` callback will *not* fire if the variables have not changed * or if the result is coming from cache. * * Note: the promise will return the old results immediately if the variables * have not changed. * * Note: the promise will return null immediately if the query is not active * (there are no subscribers). * * @param variables - The new set of variables. If there are missing variables, * the previous values of those variables will be used. */ ObservableQuery.prototype.setVariables = function (variables) { if (equal(this.variables, variables)) { // If we have no observers, then we don't actually want to make a network // request. As soon as someone observes the query, the request will kick // off. For now, we just store any changes. (See #1077) return this.observers.size ? this.result() : Promise.resolve(); } this.options.variables = variables; // See comment above if (!this.observers.size) { return Promise.resolve(); } return this.reobserve({ // Reset options.fetchPolicy to its original value. fetchPolicy: this.options.initialFetchPolicy, variables: variables, }, NetworkStatus.setVariables); }; /** * A function that enables you to update the query's cached result without executing a followup GraphQL operation. * * See [using updateQuery and updateFragment](https://www.apollographql.com/docs/react/caching/cache-interaction/#using-updatequery-and-updatefragment) for additional information. */ ObservableQuery.prototype.updateQuery = function (mapFn) { var queryManager = this.queryManager; var _a = queryManager.cache.diff({ query: this.options.query, variables: this.variables, returnPartialData: true, optimistic: false, }), result = _a.result, complete = _a.complete; var newResult = mapFn(result, { variables: this.variables, complete: !!complete, previousData: result, }); if (newResult) { queryManager.cache.writeQuery({ query: this.options.query, data: newResult, variables: this.variables, }); queryManager.broadcastQueries(); } }; /** * A function that instructs the query to begin re-executing at a specified interval (in milliseconds). */ ObservableQuery.prototype.startPolling = function (pollInterval) { this.options.pollInterval = pollInterval; this.updatePolling(); }; /** * A function that instructs the query to stop polling after a previous call to `startPolling`. */ ObservableQuery.prototype.stopPolling = function () { this.options.pollInterval = 0; this.updatePolling(); }; // Update options.fetchPolicy according to options.nextFetchPolicy. ObservableQuery.prototype.applyNextFetchPolicy = function (reason, // It's possible to use this method to apply options.nextFetchPolicy to // options.fetchPolicy even if options !== this.options, though that happens // most often when the options are temporary, used for only one request and // then thrown away, so nextFetchPolicy may not end up mattering. options) { if (options.nextFetchPolicy) { var _a = options.fetchPolicy, fetchPolicy = _a === void 0 ? "cache-first" : _a, _b = options.initialFetchPolicy, initialFetchPolicy = _b === void 0 ? fetchPolicy : _b; if (fetchPolicy === "standby") { // Do nothing, leaving options.fetchPolicy unchanged. } else if (typeof options.nextFetchPolicy === "function") { // When someone chooses "cache-and-network" or "network-only" as their // initial FetchPolicy, they often do not want future cache updates to // trigger unconditional network requests, which is what repeatedly // applying the "cache-and-network" or "network-only" policies would // seem to imply. Instead, when the cache reports an update after the // initial network request, it may be desirable for subsequent network // requests to be triggered only if the cache result is incomplete. To // that end, the options.nextFetchPolicy option provides an easy way to // update options.fetchPolicy after the initial network request, without // having to call observableQuery.setOptions. options.fetchPolicy = options.nextFetchPolicy(fetchPolicy, { reason: reason, options: options, observable: this, initialFetchPolicy: initialFetchPolicy, }); } else if (reason === "variables-changed") { options.fetchPolicy = initialFetchPolicy; } else { options.fetchPolicy = options.nextFetchPolicy; } } return options.fetchPolicy; }; ObservableQuery.prototype.fetch = function (options, newNetworkStatus, query) { // TODO Make sure we update the networkStatus (and infer fetchVariables) // before actually committing to the fetch. var queryInfo = this.queryManager.getOrCreateQuery(this.queryId); queryInfo.setObservableQuery(this); return this.queryManager["fetchConcastWithInfo"](queryInfo, options, newNetworkStatus, query); }; // Turns polling on or off based on this.options.pollInterval. ObservableQuery.prototype.updatePolling = function () { var _this = this; // Avoid polling in SSR mode if (this.queryManager.ssrMode) { return; } var _a = this, pollingInfo = _a.pollingInfo, pollInterval = _a.options.pollInterval; if (!pollInterval || !this.hasObservers()) { if (pollingInfo) { clearTimeout(pollingInfo.timeout); delete this.pollingInfo; } return; } if (pollingInfo && pollingInfo.interval === pollInterval) { return; } invariant(pollInterval, 24); var info = pollingInfo || (this.pollingInfo = {}); info.interval = pollInterval; var maybeFetch = function () { var _a, _b; if (_this.pollingInfo) { if (!isNetworkRequestInFlight(_this.queryInfo.networkStatus) && !((_b = (_a = _this.options).skipPollAttempt) === null || _b === void 0 ? void 0 : _b.call(_a))) { _this.reobserve({ // Most fetchPolicy options don't make sense to use in a polling context, as // users wouldn't want to be polling the cache directly. However, network-only and // no-cache are both useful for when the user wants to control whether or not the // polled results are written to the cache. fetchPolicy: _this.options.initialFetchPolicy === "no-cache" ? "no-cache" : "network-only", }, NetworkStatus.poll).then(poll, poll); } else { poll(); } } }; var poll = function () { var info = _this.pollingInfo; if (info) { clearTimeout(info.timeout); info.timeout = setTimeout(maybeFetch, info.interval); } }; poll(); }; ObservableQuery.prototype.updateLastResult = function (newResult, variables) { if (variables === void 0) { variables = this.variables; } var error = this.getLastError(); // Preserve this.last.error unless the variables have changed. if (error && this.last && !equal(variables, this.last.variables)) { error = void 0; } return (this.last = __assign({ result: this.queryManager.assumeImmutableResults ? newResult : cloneDeep(newResult), variables: variables }, (error ? { error: error } : null))); }; ObservableQuery.prototype.reobserveAsConcast = function (newOptions, newNetworkStatus) { var _this = this; this.isTornDown = false; var useDisposableConcast = // Refetching uses a disposable Concast to allow refetches using different // options/variables, without permanently altering the options of the // original ObservableQuery. newNetworkStatus === NetworkStatus.refetch || // The fetchMore method does not actually call the reobserve method, but, // if it did, it would definitely use a disposable Concast. newNetworkStatus === NetworkStatus.fetchMore || // Polling uses a disposable Concast so the polling options (which force // fetchPolicy to be "network-only" or "no-cache") won't override the original options. newNetworkStatus === NetworkStatus.poll; // Save the old variables, since Object.assign may modify them below. var oldVariables = this.options.variables; var oldFetchPolicy = this.options.fetchPolicy; var mergedOptions = compact(this.options, newOptions || {}); var options = useDisposableConcast ? // Disposable Concast fetches receive a shallow copy of this.options // (merged with newOptions), leaving this.options unmodified. mergedOptions : assign(this.options, mergedOptions); // Don't update options.query with the transformed query to avoid // overwriting this.options.query when we aren't using a disposable concast. // We want to ensure we can re-run the custom document transforms the next // time a request is made against the original query. var query = this.transformDocument(options.query); this.lastQuery = query; if (!useDisposableConcast) { // We can skip calling updatePolling if we're not changing this.options. this.updatePolling(); // Reset options.fetchPolicy to its original value when variables change, // unless a new fetchPolicy was provided by newOptions. if (newOptions && newOptions.variables && !equal(newOptions.variables, oldVariables) && // Don't mess with the fetchPolicy if it's currently "standby". options.fetchPolicy !== "standby" && // If we're changing the fetchPolicy anyway, don't try to change it here // using applyNextFetchPolicy. The explicit options.fetchPolicy wins. (options.fetchPolicy === oldFetchPolicy || // A `nextFetchPolicy` function has even higher priority, though, // so in that case `applyNextFetchPolicy` must be called. typeof options.nextFetchPolicy === "function")) { this.applyNextFetchPolicy("variables-changed", options); if (newNetworkStatus === void 0) { newNetworkStatus = NetworkStatus.setVariables; } } } this.waitForOwnResult && (this.waitForOwnResult = skipCacheDataFor(options.fetchPolicy)); var finishWaitingForOwnResult = function () { if (_this.concast === concast) { _this.waitForOwnResult = false; } }; var variables = options.variables && __assign({}, options.variables); var _a = this.fetch(options, newNetworkStatus, query), concast = _a.concast, fromLink = _a.fromLink; var observer = { next: function (result) { if (equal(_this.variables, variables)) { finishWaitingForOwnResult(); _this.reportResult(result, variables); } }, error: function (error) { if (equal(_this.variables, variables)) { // Coming from `getResultsFromLink`, `error` here should always be an `ApolloError`. // However, calling `concast.cancel` can inject another type of error, so we have to // wrap it again here. if (!isApolloError(error)) { error = new ApolloError({ networkError: error }); } finishWaitingForOwnResult(); _this.reportError(error, variables); } }, }; if (!useDisposableConcast && (fromLink || !this.concast)) { // We use the {add,remove}Observer methods directly to avoid wrapping // observer with an unnecessary SubscriptionObserver object. if (this.concast && this.observer) { this.concast.removeObserver(this.observer); } this.concast = concast; this.observer = observer; } concast.addObserver(observer); return concast; }; ObservableQuery.prototype.reobserve = function (newOptions, newNetworkStatus) { return preventUnhandledRejection(this.reobserveAsConcast(newOptions, newNetworkStatus).promise.then(this.maskResult)); }; ObservableQuery.prototype.resubscribeAfterError = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // If `lastError` is set in the current when the subscription is re-created, // the subscription will immediately receive the error, which will // cause it to terminate again. To avoid this, we first clear // the last error/result from the `observableQuery` before re-starting // the subscription, and restore the last value afterwards so that the // subscription has a chance to stay open. var last = this.last; this.resetLastResults(); var subscription = this.subscribe.apply(this, args); this.last = last; return subscription; }; // (Re)deliver the current result to this.observers without applying fetch // policies or making network requests. ObservableQuery.prototype.observe = function () { this.reportResult( // Passing false is important so that this.getCurrentResult doesn't // save the fetchMore result as this.lastResult, causing it to be // ignored due to the this.isDifferentFromLastResult check in // this.reportResult. this.getCurrentFullResult(false), this.variables); }; ObservableQuery.prototype.reportResult = function (result, variables) { var lastError = this.getLastError(); var isDifferent = this.isDifferentFromLastResult(result, variables); // Update the last result even when isDifferentFromLastResult returns false, // because the query may be using the @nonreactive directive, and we want to // save the the latest version of any nonreactive subtrees (in case // getCurrentResult is called), even though we skip broadcasting changes. if (lastError || !result.partial || this.options.returnPartialData) { this.updateLastResult(result, variables); } if (lastError || isDifferent) { iterateObserversSafely(this.observers, "next", this.maskResult(result)); } }; ObservableQuery.prototype.reportError = function (error, variables) { // Since we don't get the current result on errors, only the error, we // must mirror the updates that occur in QueryStore.markQueryError here var errorResult = __assign(__assign({}, this.getLastResult()), { error: error, errors: error.graphQLErrors, networkStatus: NetworkStatus.error, loading: false }); this.updateLastResult(errorResult, variables); iterateObserversSafely(this.observers, "error", (this.last.error = error)); }; ObservableQuery.prototype.hasObservers = function () { return this.observers.size > 0; }; ObservableQuery.prototype.tearDownQuery = function () { if (this.isTornDown) return; if (this.concast && this.observer) { this.concast.removeObserver(this.observer); delete this.concast; delete this.observer; } this.stopPolling(); // stop all active GraphQL subscriptions this.subscriptions.forEach(function (sub) { return sub.unsubscribe(); }); this.subscriptions.clear(); this.queryManager.stopQuery(this.queryId); this.observers.clear(); this.isTornDown = true; }; ObservableQuery.prototype.transformDocument = function (document) { return this.queryManager.transform(document); }; ObservableQuery.prototype.maskResult = function (result) { return result && "data" in result ? __assign(__assign({}, result), { data: this.queryManager.maskOperation({ document: this.query, data: result.data, fetchPolicy: this.options.fetchPolicy, id: this.queryId, }) }) : result; }; /** @internal */ ObservableQuery.prototype.resetNotifications = function () { this.cancelNotifyTimeout(); this.dirty = false; }; ObservableQuery.prototype.cancelNotifyTimeout = function () { if (this.notifyTimeout) { clearTimeout(this.notifyTimeout); this.notifyTimeout = void 0; } }; /** @internal */ ObservableQuery.prototype.scheduleNotify = function () { var _this = this; if (this.dirty) return; this.dirty = true; if (!this.notifyTimeout) { this.notifyTimeout = setTimeout(function () { return _this.notify(); }, 0); } }; /** @internal */ ObservableQuery.prototype.notify = function () { this.cancelNotifyTimeout(); if (this.dirty) { if (this.options.fetchPolicy == "cache-only" || this.options.fetchPolicy == "cache-and-network" || !isNetworkRequestInFlight(this.queryInfo.networkStatus)) { var diff = this.queryInfo.getDiff(); if (diff.fromOptimisticTransaction) { // If this diff came from an optimistic transaction, deliver the // current cache data to the ObservableQuery, but don't perform a // reobservation, since oq.reobserveCacheFirst might make a network // request, and we never want to trigger network requests in the // middle of optimistic updates. this.observe(); } else { // Otherwise, make the ObservableQuery "reobserve" the latest data // using a temporary fetch policy of "cache-first", so complete cache // results have a chance to be delivered without triggering additional // network requests, even when options.fetchPolicy is "network-only" // or "cache-and-network". All other fetch policies are preserved by // this method, and are handled by calling oq.reobserve(). If this // reobservation is spurious, isDifferentFromLastResult still has a // chance to catch it before delivery to ObservableQuery subscribers. this.reobserveCacheFirst(); } } } this.dirty = false; }; // Reobserve with fetchPolicy effectively set to "cache-first", triggering // delivery of any new data from the cache, possibly falling back to the network // if any cache data are missing. This allows _complete_ cache results to be // delivered without also kicking off unnecessary network requests when // this.options.fetchPolicy is "cache-and-network" or "network-only". When // this.options.fetchPolicy is any other policy ("cache-first", "cache-only", // "standby", or "no-cache"), we call this.reobserve() as usual. ObservableQuery.prototype.reobserveCacheFirst = function () { var _a = this.options, fetchPolicy = _a.fetchPolicy, nextFetchPolicy = _a.nextFetchPolicy; if (fetchPolicy === "cache-and-network" || fetchPolicy === "network-only") { return this.reobserve({ fetchPolicy: "cache-first", // Use a temporary nextFetchPolicy function that replaces itself with the // previous nextFetchPolicy value and returns the original fetchPolicy. nextFetchPolicy: function (currentFetchPolicy, context) { // Replace this nextFetchPolicy function in the options object with the // original this.options.nextFetchPolicy value. this.nextFetchPolicy = nextFetchPolicy; // If the original nextFetchPolicy value was a function, give it a // chance to decide what happens here. if (typeof this.nextFetchPolicy === "function") { return this.nextFetchPolicy(currentFetchPolicy, context); } // Otherwise go back to the original this.options.fetchPolicy. return fetchPolicy; }, }); } return this.reobserve(); }; /** * @internal * A slot used by the `useQuery` hook to indicate that `client.watchQuery` * should not register the query immediately, but instead wait for the query to * be started registered with the `QueryManager` when `useSyncExternalStore` * actively subscribes to it. */ ObservableQuery.inactiveOnCreation = new Slot(); return ObservableQuery; }(Observable)); export { ObservableQuery }; // Necessary because the ObservableQuery constructor has a different // signature than the Observable constructor. fixObservableSubclass(ObservableQuery); function defaultSubscriptionObserverErrorCallback(error) { globalThis.__DEV__ !== false && invariant.error(25, error.message, error.stack); } export function logMissingFieldErrors(missing) { if (globalThis.__DEV__ !== false && missing) { globalThis.__DEV__ !== false && invariant.debug(26, missing); } } function skipCacheDataFor(fetchPolicy /* `undefined` would mean `"cache-first"` */) { return (fetchPolicy === "network-only" || fetchPolicy === "no-cache" || fetchPolicy === "standby"); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2JzZXJ2YWJsZVF1ZXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvT2JzZXJ2YWJsZVF1ZXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFMUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFNN0UsT0FBTyxFQUNMLFNBQVMsRUFDVCxPQUFPLEVBQ1Asc0JBQXNCLEVBQ3RCLFVBQVUsRUFDVixzQkFBc0IsRUFDdEIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQix5QkFBeUIsR0FDMUIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBbUJoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHakQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUV4QixJQUFBLE1BQU0sR0FBcUIsTUFBTSxPQUEzQixFQUFFLGNBQWMsR0FBSyxNQUFNLGVBQVgsQ0FBWTtBQXFCMUM7SUFHVSxtQ0FBaUQ7SUFzRHpELHlCQUFZLEVBUVg7WUFQQyxZQUFZLGtCQUFBLEVBQ1osU0FBUyxlQUFBLEVBQ1QsT0FBTyxhQUFBO1FBSFQsaUJBNkZDO1FBcEZDLElBQUksZUFBZSxHQUFHLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwRSxRQUFBLE1BQUssWUFBQyxVQUFDLFFBQXlEO1lBQzlELElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDckQsZUFBZSxHQUFH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QztBQUM3QyxxQkFBcUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUV2QyxTQUFTLHdDQUF3QyxDQUFDLEtBQWtCO0lBQ2xFLFNBQVMsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakUsQ0FBQztBQUVELE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsT0FBc0Q7SUFFdEQsSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkIsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQ3ZCLFdBQW1DLENBQUMsNENBQTRDO0lBRWhGLE9BQU8sQ0FDTCxXQUFXLEtBQUssY0FBYztRQUM5QixXQUFXLEtBQUssVUFBVTtRQUMxQixXQUFXLEtBQUssU0FBUyxDQUMxQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGludmFyaWFudCB9IGZyb20gXCIuLi91dGlsaXRpZXMvZ2xvYmFscy9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBEb2N1bWVudE5vZGUgfSBmcm9tIFwiZ3JhcGhxbFwiO1xuaW1wb3J0IHsgZXF1YWwgfSBmcm9tIFwiQHdyeS9lcXVhbGl0eVwiO1xuXG5pbXBvcnQgeyBOZXR3b3JrU3RhdHVzLCBpc05ldHdvcmtSZXF1ZXN0SW5GbGlnaHQgfSBmcm9tIFwiLi9uZXR3b3JrU3RhdHVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvbmNhc3QsXG4gIE9ic2VydmVyLFxuICBPYnNlcnZhYmxlU3Vic2NyaXB0aW9uLFxufSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQge1xuICBjbG9uZURlZXAsXG4gIGNvbXBhY3QsXG4gIGdldE9wZXJhdGlvbkRlZmluaXRpb24sXG4gIE9ic2VydmFibGUsXG4gIGl0ZXJhdGVPYnNlcnZlcnNTYWZlbHksXG4gIGZpeE9ic2VydmFibGVTdWJjbGFzcyxcbiAgZ2V0UXVlcnlEZWZpbml0aW9uLFxuICBwcmV2ZW50VW5oYW5kbGVkUmVqZWN0aW9uLFxufSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBBcG9sbG9FcnJvciwgaXNBcG9sbG9FcnJvciB9IGZyb20gXCIuLi9lcnJvcnMvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgUXVlcnlNYW5hZ2VyIH0gZnJvbSBcIi4vUXVlcnlNYW5hZ2VyLmpzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIEFwb2xsb1F1ZXJ5UmVzdWx0LFxuICBPcGVyYXRpb25WYXJpYWJsZXMsXG4gIFR5cGVkRG9jdW1lbnROb2RlLFxufSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHR5cGUge1xuICBXYXRjaFF1ZXJ5T3B0aW9ucyxcbiAgRmV0Y2hNb3JlUXVlcnlPcHRpb25zLFxuICBTdWJzY3JpYmVUb01vcmVPcHRpb25zLFxuICBOZXh0RmV0Y2hQb2xpY3lDb250ZXh0LFxuICBXYXRjaFF1ZXJ5RmV0Y2hQb2xpY3ksXG4gIFVwZGF0ZVF1ZXJ5TWFwRm4sXG4gIFVwZGF0ZVF1ZXJ5T3B0aW9ucyxcbn0gZnJvbSBcIi4vd2F0Y2hRdWVyeU9wdGlvbnMuanNcIjtcbmltcG9ydCB0eXBlIHsgUXVlcnlJbmZvIH0gZnJvbSBcIi4vUXVlcnlJbmZvLmpzXCI7XG5pbXBvcnQgdHlwZSB7IE1pc3NpbmdGaWVsZEVycm9yIH0gZnJvbSBcIi4uL2NhY2hlL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IE1pc3NpbmdUcmVlIH0gZnJvbSBcIi4uL2NhY2hlL2NvcmUvdHlwZXMvY29tbW9uLmpzXCI7XG5pbXBvcnQgeyBlcXVhbEJ5UXVlcnkgfSBmcm9tIFwiLi9lcXVhbEJ5UXVlcnkuanNcIjtcbmltcG9ydCB0eXBlIHsgVE9ETyB9IGZyb20gXCIuLi91dGlsaXRpZXMvdHlwZXMvVE9ETy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBNYXliZU1hc2tlZCwgVW5tYXNrZWQgfSBmcm9tIFwiLi4vbWFza2luZy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgU2xvdCB9IGZyb20gXCJvcHRpbWlzbVwiO1xuXG5jb25zdCB7IGFzc2lnbiwgaGFzT3duUHJvcGVydHkgfSA9IE9iamVjdDtcblxuZXhwb3J0IGludGVyZmFjZSBGZXRjaE1vcmVPcHRpb25zPFxuICBURGF0YSA9IGFueSxcbiAgVFZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcyxcbj4ge1xuICB1cGRhdGVRdWVyeT86IChcbiAgICBwcmV2aW91c1F1ZXJ5UmVzdWx0OiBURGF0YSxcbiAgICBvcHRpb25zOiB7XG4gICAgICBmZXRjaE1vcmVSZXN1bHQ/OiBURGF0YTtcbiAgICAgIHZhcmlhYmxlcz86IFRWYXJpYWJsZXM7XG4gICAgfVxuICApID0+IFREYXRhO1xufVxuXG5pbnRlcmZhY2UgTGFzdDxURGF0YSwgVFZhcmlhYmxlcz4ge1xuICByZXN1bHQ6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPjtcbiAgdmFyaWFibGVzPzogVFZhcmlhYmxlcztcbiAgZXJyb3I/OiBBcG9sbG9FcnJvcjtcbn1cblxuZXhwb3J0IGNsYXNzIE9ic2VydmFibGVRdWVyeTxcbiAgVERhdGEgPSBhbnksXG4gIFRWYXJpYWJsZXMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXMgPSBPcGVyYXRpb25WYXJpYWJsZXMsXG4+IGV4dGVuZHMgT2JzZXJ2YWJsZTxBcG9sbG9RdWVyeVJlc3VsdDxNYXliZU1hc2tlZDxURGF0YT4+PiB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQSBzbG90IHVzZWQgYnkgdGhlIGB1c2VRdWVyeWAgaG9vayB0byBpbmRpY2F0ZSB0aGF0IGBjbGllbnQud2F0Y2hRdWVyeWBcbiAgICogc2hvdWxkIG5vdCByZWdpc3RlciB0aGUgcXVlcnkgaW1tZWRpYXRlbHksIGJ1dCBpbnN0ZWFkIHdhaXQgZm9yIHRoZSBxdWVyeSB0b1xuICAgKiBiZSBzdGFydGVkIHJlZ2lzdGVyZWQgd2l0aCB0aGUgYFF1ZXJ5TWFuYWdlcmAgd2hlbiBgdXNlU3luY0V4dGVybmFsU3RvcmVgXG4gICAqIGFjdGl2ZWx5IHN1YnNjcmliZXMgdG8gaXQuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBpbmFjdGl2ZU9uQ3JlYXRpb24gPSBuZXcgU2xvdDxib29sZWFuPigpO1xuXG4gIHB1YmxpYyByZWFkb25seSBvcHRpb25zOiBXYXRjaFF1ZXJ5T3B0aW9uczxUVmFyaWFibGVzLCBURGF0YT47XG4gIHB1YmxpYyByZWFkb25seSBxdWVyeUlkOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBxdWVyeU5hbWU/OiBzdHJpbmc7XG5cbiAgLy8gVGhlIGBxdWVyeWAgY29tcHV0ZWQgcHJvcGVydHkgd2lsbCBhbHdheXMgcmVmbGVjdCB0aGUgZG9jdW1lbnQgdHJhbnNmb3JtZWRcbiAgLy8gYnkgdGhlIGxhc3QgcnVuIHF1ZXJ5LiBgdGhpcy5vcHRpb25zLnF1ZXJ5YCB3aWxsIGFsd2F5cyByZWZsZWN0IHRoZSByYXdcbiAgLy8gdW50cmFuc2Zvcm1lZCBxdWVyeSB0byBlbnN1cmUgZG9jdW1lbnQgdHJhbnNmb3JtcyB3aXRoIHJ1bnRpbWUgY29uZGl0aW9uYWxzXG4gIC8vIGFyZSBydW4gb24gdGhlIG9yaWdpbmFsIGRvY3VtZW50LlxuICBwdWJsaWMgZ2V0IHF1ZXJ5KCk6IFR5cGVkRG9jdW1lbnROb2RlPFREYXRhLCBUVmFyaWFibGVzPiB7XG4gICAgcmV0dXJuIHRoaXMubGFzdFF1ZXJ5IHx8IHRoaXMub3B0aW9ucy5xdWVyeTtcbiAgfVxuXG4gIC8vIENvbXB1dGVkIHNob3J0aGFuZCBmb3IgdGhpcy5vcHRpb25zLnZhcmlhYmxlcywgcHJlc2VydmVkIGZvclxuICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgLyoqXG4gICAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSB2YXJpYWJsZXMgdGhhdCB3ZXJlIHByb3ZpZGVkIGZvciB0aGUgcXVlcnkuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHZhcmlhYmxlcygpOiBUVmFyaWFibGVzIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhcmlhYmxlcztcbiAgfVxuXG4gIHByaXZhdGUgaXNUb3JuRG93bjogYm9vbGVhbjtcbiAgcHJpdmF0ZSBxdWVyeU1hbmFnZXI6IFF1ZXJ5TWFuYWdlcjxhbnk+O1xuICBwcml2YXRlIG9ic2VydmVycyA9IG5ldyBTZXQ8XG4gICAgT2JzZXJ2ZXI8QXBvbGxvUXVlcnlSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+Pj5cbiAgPigpO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU2V0PE9ic2VydmFibGVTdWJzY3JpcHRpb24+KCk7XG5cbiAgcHJpdmF0ZSB3YWl0Rm9yT3duUmVzdWx0OiBib29sZWFuO1xuICBwcml2YXRlIGxhc3Q/OiBMYXN0PFREYXRhLCBUVmFyaWFibGVzPjtcbiAgcHJpdmF0ZSBsYXN0UXVlcnk/OiBEb2N1bWVudE5vZGU7XG5cbiAgcHJpdmF0ZSBxdWVyeUluZm86IFF1ZXJ5SW5mbztcblxuICAvLyBXaGVuIHRoaXMuY29uY2FzdCBpcyBkZWZpbmVkLCB0aGlzLm9ic2VydmVyIGlzIHRoZSBPYnNlcnZlciBjdXJyZW50bHlcbiAgLy8gc3Vic2NyaWJlZCB0byB0aGF0IENvbmNhc3QuXG4gIHByaXZhdGUgY29uY2FzdD86IENvbmNhc3Q8QXBvbGxvUXVlcnlSZXN1bHQ8VERhdGE+PjtcbiAgcHJpdmF0ZSBvYnNlcnZlcj86IE9ic2VydmVyPEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPj47XG5cbiAgcHJpdmF0ZSBwb2xsaW5nSW5mbz86IHtcbiAgICBpbnRlcnZhbDogbnVtYmVyO1xuICAgIHRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+O1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBxdWVyeU1hbmFnZXIsXG4gICAgcXVlcnlJbmZvLFxuICAgIG9wdGlvbnMsXG4gIH06IHtcbiAgICBxdWVyeU1hbmFnZXI6IFF1ZXJ5TWFuYWdlcjxhbnk+O1xuICAgIHF1ZXJ5SW5mbzogUXVlcnlJbmZvO1xuICAgIG9wdGlvbnM6IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJpYWJsZXMsIFREYXRhPjtcbiAgfSkge1xuICAgIGxldCBzdGFydGVkSW5hY3RpdmUgPSBPYnNlcnZhYmxlUXVlcnkuaW5hY3RpdmVPbkNyZWF0aW9uLmdldFZhbHVlKCk7XG4gICAgc3VwZXIoKG9ic2VydmVyOiBPYnNlcnZlcjxBcG9sbG9RdWVyeVJlc3VsdDxNYXliZU1hc2tlZDxURGF0YT4+PikgPT4ge1xuICAgICAgaWYgKHN0YXJ0ZWRJbmFjdGl2ZSkge1xuICAgICAgICBxdWVyeU1hbmFnZXJbXCJxdWVyaWVzXCJdLnNldCh0aGlzLnF1ZXJ5SWQsIHF1ZXJ5SW5mbyk7XG4gICAgICAgIHN0YXJ0ZWRJbmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBaZW4gT2JzZXJ2YWJsZSBoYXMgaXRzIG93biBlcnJvciBmdW5jdGlvbiwgc28gaW4gb3JkZXIgdG8gbG9nIGNvcnJlY3RseVxuICAgICAgLy8gd2UgbmVlZCB0byBwcm92aWRlIGEgY3VzdG9tIGVycm9yIGNhbGxiYWNrLlxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHN1Yk9ic2VydmVyID0gKG9ic2VydmVyIGFzIGFueSkuX3N1YnNjcmlwdGlvbi5fb2JzZXJ2ZXI7XG4gICAgICAgIGlmIChzdWJPYnNlcnZlciAmJiAhc3ViT2JzZXJ2ZXIuZXJyb3IpIHtcbiAgICAgICAgICBzdWJPYnNlcnZlci5lcnJvciA9IGRlZmF1bHRTdWJzY3JpcHRpb25PYnNlcnZlckVycm9yQ2FsbGJhY2s7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge31cblxuICAgICAgY29uc3QgZmlyc3QgPSAhdGhpcy5vYnNlcnZlcnMuc2l6ZTtcbiAgICAgIHRoaXMub2JzZXJ2ZXJzLmFkZChvYnNlcnZlcik7XG5cbiAgICAgIC8vIERlbGl2ZXIgbW9zdCByZWNlbnQgZXJyb3Igb3IgcmVzdWx0LlxuICAgICAgY29uc3QgbGFzdCA9IHRoaXMubGFzdDtcbiAgICAgIGlmIChsYXN0ICYmIGxhc3QuZXJyb3IpIHtcbiAgICAgICAgb2JzZXJ2ZXIuZXJyb3IgJiYgb2JzZXJ2ZXIuZXJyb3IobGFzdC5lcnJvcik7XG4gICAgICB9IGVsc2UgaWYgKGxhc3QgJiYgbGFzdC5yZXN1bHQpIHtcbiAgICAgICAgb2JzZXJ2ZXIubmV4dCAmJiBvYnNlcnZlci5uZXh0KHRoaXMubWFza1Jlc3VsdChsYXN0LnJlc3VsdCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBJbml0aWF0ZSBvYnNlcnZhdGlvbiBvZiB0aGlzIHF1ZXJ5IGlmIGl0IGhhc24ndCBiZWVuIHJlcG9ydGVkIHRvXG4gICAgICAvLyB0aGUgUXVlcnlNYW5hZ2VyIHlldC5cbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICAvLyBCbGluZGx5IGNhdGNoaW5nIGhlcmUgcHJldmVudHMgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9ucyxcbiAgICAgICAgLy8gYW5kIGlzIHNhZmUgYmVjYXVzZSB0aGUgT2JzZXJ2YWJsZVF1ZXJ5IGhhbmRsZXMgdGhpcyBlcnJvciB3aXRoXG4gICAgICAgIC8vIHRoaXMub2JzZXJ2ZXIuZXJyb3IsIHNvIHdlJ3JlIG5vdCBqdXN0IHN3YWxsb3dpbmcgdGhlIGVycm9yIGJ5XG4gICAgICAgIC8vIGlnbm9yaW5nIGl0IGhlcmUuXG4gICAgICAgIHRoaXMucmVvYnNlcnZlKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5vYnNlcnZlcnMuZGVsZXRlKG9ic2VydmVyKSAmJiAhdGhpcy5vYnNlcnZlcnMuc2l6ZSkge1xuICAgICAgICAgIHRoaXMudGVhckRvd25RdWVyeSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gcmVsYXRlZCBjbGFzc2VzXG4gICAgdGhpcy5xdWVyeUluZm8gPSBxdWVyeUluZm87XG4gICAgdGhpcy5xdWVyeU1hbmFnZXIgPSBxdWVyeU1hbmFnZXI7XG5cbiAgICAvLyBhY3RpdmUgc3RhdGVcbiAgICB0aGlzLndhaXRGb3JPd25SZXN1bHQgPSBza2lwQ2FjaGVEYXRhRm9yKG9wdGlvbnMuZmV0Y2hQb2xpY3kpO1xuICAgIHRoaXMuaXNUb3JuRG93biA9IGZhbHNlO1xuXG4gICAgdGhpcy5zdWJzY3JpYmVUb01vcmUgPSB0aGlzLnN1YnNjcmliZVRvTW9yZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMubWFza1Jlc3VsdCA9IHRoaXMubWFza1Jlc3VsdC5iaW5kKHRoaXMpO1xuXG4gICAgY29uc3Qge1xuICAgICAgd2F0Y2hRdWVyeTogeyBmZXRjaFBvbGljeTogZGVmYXVsdEZldGNoUG9saWN5ID0gXCJjYWNoZS1maXJzdFwiIH0gPSB7fSxcbiAgICB9ID0gcXVlcnlNYW5hZ2VyLmRlZmF1bHRPcHRpb25zO1xuXG4gICAgY29uc3Qge1xuICAgICAgZmV0Y2hQb2xpY3kgPSBkZWZhdWx0RmV0Y2hQb2xpY3ksXG4gICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3Qgc3RvcmUgXCJzdGFuZGJ5XCIgYXMgdGhlIGluaXRpYWxGZXRjaFBvbGljeS5cbiAgICAgIGluaXRpYWxGZXRjaFBvbGljeSA9IGZldGNoUG9saWN5ID09PSBcInN0YW5kYnlcIiA/IGRlZmF1bHRGZXRjaFBvbGljeSA6IChcbiAgICAgICAgZmV0Y2hQb2xpY3lcbiAgICAgICksXG4gICAgfSA9IG9wdGlvbnM7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuXG4gICAgICAvLyBSZW1lbWJlciB0aGUgaW5pdGlhbCBvcHRpb25zLmZldGNoUG9saWN5IHNvIHdlIGNhbiByZXZlcnQgYmFjayB0byB0aGlzXG4gICAgICAvLyBwb2xpY3kgd2hlbiB2YXJpYWJsZXMgY2hhbmdlLiBUaGlzIGluZm9ybWF0aW9uIGNhbiBhbHNvIGJlIHNwZWNpZmllZFxuICAgICAgLy8gKG9yIG92ZXJyaWRkZW4pIGJ5IHByb3ZpZGluZyBvcHRpb25zLmluaXRpYWxGZXRjaFBvbGljeSBleHBsaWNpdGx5LlxuICAgICAgaW5pdGlhbEZldGNoUG9saWN5LFxuXG4gICAgICAvLyBUaGlzIGVuc3VyZXMgdGhpcy5vcHRpb25zLmZldGNoUG9saWN5IGFsd2F5cyBoYXMgYSBzdHJpbmcgdmFsdWUsIGluXG4gICAgICAvLyBjYXNlIG9wdGlvbnMuZmV0Y2hQb2xpY3kgd2FzIG5vdCBwcm92aWRlZC5cbiAgICAgIGZldGNoUG9saWN5LFxuICAgIH07XG5cbiAgICB0aGlzLnF1ZXJ5SWQgPSBxdWVyeUluZm8ucXVlcnlJZCB8fCBxdWVyeU1hbmFnZXIuZ2VuZXJhdGVRdWVyeUlkKCk7XG5cbiAgICBjb25zdCBvcERlZiA9IGdldE9wZXJhdGlvbkRlZmluaXRpb24odGhpcy5xdWVyeSk7XG4gICAgdGhpcy5xdWVyeU5hbWUgPSBvcERlZiAmJiBvcERlZi5uYW1lICYmIG9wRGVmLm5hbWUudmFsdWU7XG4gIH1cblxuICBwdWJsaWMgcmVzdWx0KCk6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+Pj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBUT0RPOiB0aGlzIGNvZGUgZG9lc27igJl0IGFjdHVhbGx5IG1ha2Ugc2Vuc2UgaW5zb2ZhciBhcyB0aGUgb2JzZXJ2ZXJcbiAgICAgIC8vIHdpbGwgbmV2ZXIgZXhpc3QgaW4gdGhpcy5vYnNlcnZlcnMgZHVlIGhvdyB6ZW4tb2JzZXJ2YWJsZSB3cmFwcyBvYnNlcnZhYmxlcy5cbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS96ZW5wYXJzaW5nL3plbi1vYnNlcnZhYmxlL2Jsb2IvbWFzdGVyL3NyYy9PYnNlcnZhYmxlLmpzI0wxNjlcbiAgICAgIGNvbnN0IG9ic2VydmVyOiBPYnNlcnZlcjxBcG9sbG9RdWVyeVJlc3VsdDxNYXliZU1hc2tlZDxURGF0YT4+PiA9IHtcbiAgICAgICAgbmV4dDogKHJlc3VsdCkgPT4ge1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcblxuICAgICAgICAgIC8vIFN0b3AgdGhlIHF1ZXJ5IHdpdGhpbiB0aGUgUXVlcnlNYW5hZ2VyIGlmIHdlIGNhbiBiZWZvcmVcbiAgICAgICAgICAvLyB0aGlzIGZ1bmN0aW9uIHJldHVybnMuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBXZSBkbyB0aGlzIGluIG9yZGVyIHRvIHByZXZlbnQgb2JzZXJ2ZXJzIHBpbGluZyB1cCB3aXRoaW5cbiAgICAgICAgICAvLyB0aGUgUXVlcnlNYW5hZ2VyLiBOb3RpY2UgdGhhdCB3ZSBvbmx5IGZ1bGx5IHVuc3Vic2NyaWJlXG4gICAgICAgICAgLy8gZnJvbSB0aGUgc3Vic2NyaXB0aW9uIGluIGEgc2V0VGltZW91dCguLi4sIDApICBjYWxsLiBUaGlzIGNhbGwgY2FuXG4gICAgICAgICAgLy8gYWN0dWFsbHkgYmUgaGFuZGxlZCBieSB0aGUgYnJvd3NlciBhdCBhIG11Y2ggbGF0ZXIgdGltZS4gSWYgcXVlcmllc1xuICAgICAgICAgIC8vIGFyZSBmaXJlZCBpbiB0aGUgbWVhbnRpbWUsIG9ic2VydmVycyB0aGF0IHNob3VsZCBoYXZlIGJlZW4gcmVtb3ZlZFxuICAgICAgICAgIC8vIGZyb20gdGhlIFF1ZXJ5TWFuYWdlciB3aWxsIGNvbnRpbnVlIHRvIGZpcmUsIGNhdXNpbmcgYW4gdW5uZWNlc3NhcnlcbiAgICAgICAgICAvLyBwZXJmb3JtYW5jZSBoaXQuXG4gICAgICAgICAgdGhpcy5vYnNlcnZlcnMuZGVsZXRlKG9ic2VydmVyKTtcbiAgICAgICAgICBpZiAoIXRoaXMub2JzZXJ2ZXJzLnNpemUpIHtcbiAgICAgICAgICAgIHRoaXMucXVlcnlNYW5hZ2VyLnJlbW92ZVF1ZXJ5KHRoaXMucXVlcnlJZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHJlamVjdCxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLnN1YnNjcmliZShvYnNlcnZlcik7XG4gICAgfSk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHB1YmxpYyByZXNldERpZmYoKSB7XG4gICAgdGhpcy5xdWVyeUluZm8ucmVzZXREaWZmKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEN1cnJlbnRGdWxsUmVzdWx0KFxuICAgIHNhdmVBc0xhc3RSZXN1bHQgPSB0cnVlXG4gICk6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPiB7XG4gICAgLy8gVXNlIHRoZSBsYXN0IHJlc3VsdCBhcyBsb25nIGFzIHRoZSB2YXJpYWJsZXMgbWF0Y2ggdGhpcy52YXJpYWJsZXMuXG4gICAgY29uc3QgbGFzdFJlc3VsdCA9IHRoaXMuZ2V0TGFzdFJlc3VsdCh0cnVlKTtcblxuICAgIGNvbnN0IG5ldHdvcmtTdGF0dXMgPVxuICAgICAgdGhpcy5xdWVyeUluZm8ubmV0d29ya1N0YXR1cyB8fFxuICAgICAgKGxhc3RSZXN1bHQgJiYgbGFzdFJlc3VsdC5uZXR3b3JrU3RhdHVzKSB8fFxuICAgICAgTmV0d29ya1N0YXR1cy5yZWFkeTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIC4uLmxhc3RSZXN1bHQsXG4gICAgICBsb2FkaW5nOiBpc05ldHdvcmtSZXF1ZXN0SW5GbGlnaHQobmV0d29ya1N0YXR1cyksXG4gICAgICBuZXR3b3JrU3RhdHVzLFxuICAgIH0gYXMgQXBvbGxvUXVlcnlSZXN1bHQ8VERhdGE+O1xuXG4gICAgY29uc3QgeyBmZXRjaFBvbGljeSA9IFwiY2FjaGUtZmlyc3RcIiB9ID0gdGhpcy5vcHRpb25zO1xuICAgIGlmIChcbiAgICAgIC8vIFRoZXNlIGZldGNoIHBvbGljaWVzIHNob3VsZCBuZXZlciBkZWxpdmVyIGRhdGEgZnJvbSB0aGUgY2FjaGUsIHVubGVzc1xuICAgICAgLy8gcmVkZWxpdmVyaW5nIGEgcHJldmlvdXNseSBkZWxpdmVyZWQgcmVzdWx0LlxuICAgICAgc2tpcENhY2hlRGF0YUZvcihmZXRjaFBvbGljeSkgfHxcbiAgICAgIC8vIElmIHRoaXMub3B0aW9ucy5xdWVyeSBoYXMgQGNsaWVudChhbHdheXM6IHRydWUpIGZpZWxkcywgd2UgY2Fubm90XG4gICAgICAvLyB0cnVzdCBkaWZmLnJlc3VsdCwgc2luY2UgaXQgd2FzIHJlYWQgZnJvbSB0aGUgY2FjaGUgd2l0aG91dCBydW5uaW5nXG4gICAgICAvLyBsb2NhbCByZXNvbHZlcnMgKGFuZCBpdCdzIHRvbyBsYXRlIHRvIHJ1biByZXNvbHZlcnMgbm93LCBzaW5jZSB3ZSBtdXN0XG4gICAgICAvLyByZXR1cm4gYSByZXN1bHQgc3luY2hyb25vdXNseSkuXG4gICAgICB0aGlzLnF1ZXJ5TWFuYWdlci5nZXREb2N1bWVudEluZm8odGhpcy5xdWVyeSkuaGFzRm9yY2VkUmVzb2x2ZXJzXG4gICAgKSB7XG4gICAgICAvLyBGYWxsIHRocm91Z2guXG4gICAgfSBlbHNlIGlmICh0aGlzLndhaXRGb3JPd25SZXN1bHQpIHtcbiAgICAgIC8vIFRoaXMgd291bGQgdXN1YWxseSBiZSBhIHBhcnQgb2YgYFF1ZXJ5SW5mby5nZXREaWZmKClgLlxuICAgICAgLy8gd2hpY2ggd2Ugc2tpcCBpbiB0aGUgd2FpdEZvck93blJlc3VsdCBjYXNlIHNpbmNlIHdlIGFyZSBub3RcbiAgICAgIC8vIGludGVyZXN0ZWQgaW4gdGhlIGRpZmYuXG4gICAgICB0aGlzLnF1ZXJ5SW5mb1tcInVwZGF0ZVdhdGNoXCJdKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRpZmYgPSB0aGlzLnF1ZXJ5SW5mby5nZXREaWZmKCk7XG5cbiAgICAgIGlmIChkaWZmLmNvbXBsZXRlIHx8IHRoaXMub3B0aW9ucy5yZXR1cm5QYXJ0aWFsRGF0YSkge1xuICAgICAgICByZXN1bHQuZGF0YSA9IGRpZmYucmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoZXF1YWwocmVzdWx0LmRhdGEsIHt9KSkge1xuICAgICAgICByZXN1bHQuZGF0YSA9IHZvaWQgMCBhcyBhbnk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaWZmLmNvbXBsZXRlKSB7XG4gICAgICAgIC8vIFNpbWlsYXIgdG8gc2V0dGluZyByZXN1bHQucGFydGlhbCB0byBmYWxzZSwgYnV0IHRha2luZyBhZHZhbnRhZ2Ugb2YgdGhlXG4gICAgICAgIC8vIGZhbHNpbmVzcyBvZiBtaXNzaW5nIGZpZWxkcy5cbiAgICAgICAgZGVsZXRlIHJlc3VsdC5wYXJ0aWFsO1xuXG4gICAgICAgIC8vIElmIHRoZSBkaWZmIGlzIGNvbXBsZXRlLCBhbmQgd2UncmUgdXNpbmcgYSBGZXRjaFBvbGljeSB0aGF0XG4gICAgICAgIC8vIHRlcm1pbmF0ZXMgYWZ0ZXIgYSBjb21wbGV0ZSBjYWNoZSByZWFkLCB3ZSBjYW4gYXNzdW1lIHRoZSBuZXh0IHJlc3VsdFxuICAgICAgICAvLyB3ZSByZWNlaXZlIHdpbGwgaGF2ZSBOZXR3b3JrU3RhdHVzLnJlYWR5IGFuZCAhbG9hZGluZy5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpZmYuY29tcGxldGUgJiZcbiAgICAgICAgICByZXN1bHQubmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5sb2FkaW5nICYmXG4gICAgICAgICAgKGZldGNoUG9saWN5ID09PSBcImNhY2hlLWZpcnN0XCIgfHwgZmV0Y2hQb2xpY3kgPT09IFwiY2FjaGUtb25seVwiKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXN1bHQubmV0d29ya1N0YXR1cyA9IE5ldHdvcmtTdGF0dXMucmVhZHk7XG4gICAgICAgICAgcmVzdWx0LmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LnBhcnRpYWwgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIGZvciBib3RoIGJvdGggYGVycm9yYCBhbmQgYGVycm9yc2AgZmllbGQgYmVjYXVzZSB0aGVyZVxuICAgICAgLy8gYXJlIGNhc2VzIHdoZXJlIHNvbWV0aW1lcyBgZXJyb3JgIGlzIHNldCwgYnV0IG5vdCBgZXJyb3JzYCBhbmRcbiAgICAgIC8vIHZpY2UtdmVyc2EuIFRoaXMgd2lsbCBiZSB1cGRhdGVkIGluIHRoZSBuZXh0IG1ham9yIHZlcnNpb24gd2hlblxuICAgICAgLy8gYGVycm9yc2AgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBgZXJyb3JgLlxuICAgICAgaWYgKFxuICAgICAgICByZXN1bHQubmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5yZWFkeSAmJlxuICAgICAgICAocmVzdWx0LmVycm9yIHx8IHJlc3VsdC5lcnJvcnMpXG4gICAgICApIHtcbiAgICAgICAgcmVzdWx0Lm5ldHdvcmtTdGF0dXMgPSBOZXR3b3JrU3RhdHVzLmVycm9yO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIF9fREVWX18gJiZcbiAgICAgICAgIWRpZmYuY29tcGxldGUgJiZcbiAgICAgICAgIXRoaXMub3B0aW9ucy5wYXJ0aWFsUmVmZXRjaCAmJlxuICAgICAgICAhcmVzdWx0LmxvYWRpbmcgJiZcbiAgICAgICAgIXJlc3VsdC5kYXRhICYmXG4gICAgICAgICFyZXN1bHQuZXJyb3JcbiAgICAgICkge1xuICAgICAgICBsb2dNaXNzaW5nRmllbGRFcnJvcnMoZGlmZi5taXNzaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2F2ZUFzTGFzdFJlc3VsdCkge1xuICAgICAgdGhpcy51cGRhdGVMYXN0UmVzdWx0KHJlc3VsdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDdXJyZW50UmVzdWx0KFxuICAgIHNhdmVBc0xhc3RSZXN1bHQgPSB0cnVlXG4gICk6IEFwb2xsb1F1ZXJ5UmVzdWx0PE1heWJlTWFza2VkPFREYXRhPj4ge1xuICAgIHJldHVybiB0aGlzLm1hc2tSZXN1bHQodGhpcy5nZXRDdXJyZW50RnVsbFJlc3VsdChzYXZlQXNMYXN0UmVzdWx0KSk7XG4gIH1cblxuICAvLyBDb21wYXJlcyBuZXdSZXN1bHQgdG8gdGhlIHNuYXBzaG90IHdlIHRvb2sgb2YgdGhpcy5sYXN0UmVzdWx0IHdoZW4gaXQgd2FzXG4gIC8vIGZpcnN0IHJlY2VpdmVkLlxuICBwdWJsaWMgaXNEaWZmZXJlbnRGcm9tTGFzdFJlc3VsdChcbiAgICBuZXdSZXN1bHQ6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPixcbiAgICB2YXJpYWJsZXM/OiBUVmFyaWFibGVzXG4gICkge1xuICAgIGlmICghdGhpcy5sYXN0KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBkb2N1bWVudEluZm8gPSB0aGlzLnF1ZXJ5TWFuYWdlci5nZXREb2N1bWVudEluZm8odGhpcy5xdWVyeSk7XG4gICAgY29uc3QgZGF0YU1hc2tpbmcgPSB0aGlzLnF1ZXJ5TWFuYWdlci5kYXRhTWFza2luZztcbiAgICBjb25zdCBxdWVyeSA9IGRhdGFNYXNraW5nID8gZG9jdW1lbnRJbmZvLm5vblJlYWN0aXZlUXVlcnkgOiB0aGlzLnF1ZXJ5O1xuXG4gICAgY29uc3QgcmVzdWx0SXNEaWZmZXJlbnQgPVxuICAgICAgZGF0YU1hc2tpbmcgfHwgZG9jdW1lbnRJbmZvLmhhc05vbnJlYWN0aXZlRGlyZWN0aXZlID9cbiAgICAgICAgIWVxdWFsQnlRdWVyeShxdWVyeSwgdGhpcy5sYXN0LnJlc3VsdCwgbmV3UmVzdWx0LCB0aGlzLnZhcmlhYmxlcylcbiAgICAgIDogIWVxdWFsKHRoaXMubGFzdC5yZXN1bHQsIG5ld1Jlc3VsdCk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgcmVzdWx0SXNEaWZmZXJlbnQgfHwgKHZhcmlhYmxlcyAmJiAhZXF1YWwodGhpcy5sYXN0LnZhcmlhYmxlcywgdmFyaWFibGVzKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMYXN0PEsgZXh0ZW5kcyBrZXlvZiBMYXN0PFREYXRhLCBUVmFyaWFibGVzPj4oXG4gICAga2V5OiBLLFxuICAgIHZhcmlhYmxlc011c3RNYXRjaD86IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3QgbGFzdCA9IHRoaXMubGFzdDtcbiAgICBpZiAoXG4gICAgICBsYXN0ICYmXG4gICAgICBsYXN0W2tleV0gJiZcbiAgICAgICghdmFyaWFibGVzTXVzdE1hdGNoIHx8IGVxdWFsKGxhc3QudmFyaWFibGVzLCB0aGlzLnZhcmlhYmxlcykpXG4gICAgKSB7XG4gICAgICByZXR1cm4gbGFzdFtrZXldO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRMYXN0UmVzdWx0KFxuICAgIHZhcmlhYmxlc011c3RNYXRjaD86IGJvb2xlYW5cbiAgKTogQXBvbGxvUXVlcnlSZXN1bHQ8VERhdGE+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXRMYXN0KFwicmVzdWx0XCIsIHZhcmlhYmxlc011c3RNYXRjaCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0TGFzdEVycm9yKHZhcmlhYmxlc011c3RNYXRjaD86IGJvb2xlYW4pOiBBcG9sbG9FcnJvciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TGFzdChcImVycm9yXCIsIHZhcmlhYmxlc011c3RNYXRjaCk7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRMYXN0UmVzdWx0cygpOiB2b2lkIHtcbiAgICBkZWxldGUgdGhpcy5sYXN0O1xuICAgIHRoaXMuaXNUb3JuRG93biA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIHJlc2V0UXVlcnlTdG9yZUVycm9ycygpIHtcbiAgICB0aGlzLnF1ZXJ5TWFuYWdlci5yZXNldEVycm9ycyh0aGlzLnF1ZXJ5SWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgdmFyaWFibGVzIG9mIHRoaXMgb2JzZXJ2YWJsZSBxdWVyeSwgYW5kIGZldGNoIHRoZSBuZXcgcmVzdWx0cy5cbiAgICogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIHByZWZlcnJlZCBvdmVyIGBzZXRWYXJpYWJsZXNgIGluIG1vc3QgdXNlIGNhc2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gVGhlIG5ldyBzZXQgb2YgdmFyaWFibGVzLiBJZiB0aGVyZSBhcmUgbWlzc2luZyB2YXJpYWJsZXMsXG4gICAqIHRoZSBwcmV2aW91cyB2YWx1ZXMgb2YgdGhvc2UgdmFyaWFibGVzIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHB1YmxpYyByZWZldGNoKFxuICAgIHZhcmlhYmxlcz86IFBhcnRpYWw8VFZhcmlhYmxlcz5cbiAgKTogUHJvbWlzZTxBcG9sbG9RdWVyeVJlc3VsdDxNYXliZU1hc2tlZDxURGF0YT4+PiB7XG4gICAgY29uc3QgcmVvYnNlcnZlT3B0aW9uczogUGFydGlhbDxXYXRjaFF1ZXJ5T3B0aW9uczxUVmFyaWFibGVzLCBURGF0YT4+ID0ge1xuICAgICAgLy8gQWx3YXlzIGRpc2FibGUgcG9sbGluZyBmb3IgcmVmZXRjaGVzLlxuICAgICAgcG9sbEludGVydmFsOiAwLFxuICAgIH07XG5cbiAgICAvLyBVbmxlc3MgdGhlIHByb3ZpZGVkIGZldGNoUG9saWN5IGFsd2F5cyBjb25zdWx0cyB0aGUgbmV0d29ya1xuICAgIC8vIChuby1jYWNoZSwgbmV0d29yay1vbmx5LCBvciBjYWNoZS1hbmQtbmV0d29yayksIG92ZXJyaWRlIGl0IHdpdGhcbiAgICAvLyBuZXR3b3JrLW9ubHkgdG8gZm9yY2UgdGhlIHJlZmV0Y2ggZm9yIHRoaXMgZmV0Y2hRdWVyeSBjYWxsLlxuICAgIGNvbnN0IHsgZmV0Y2hQb2xpY3kgfSA9IHRoaXMub3B0aW9ucztcbiAgICBpZiAoZmV0Y2hQb2xpY3kgPT09IFwibm8tY2FjaGVcIikge1xuICAgICAgcmVvYnNlcnZlT3B0aW9ucy5mZXRjaFBvbGljeSA9IFwibm8tY2FjaGVcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVvYnNlcnZlT3B0aW9ucy5mZXRjaFBvbGljeSA9IFwibmV0d29yay1vbmx5XCI7XG4gICAgfVxuXG4gICAgaWYgKF9fREVWX18gJiYgdmFyaWFibGVzICYmIGhhc093blByb3BlcnR5LmNhbGwodmFyaWFibGVzLCBcInZhcmlhYmxlc1wiKSkge1xuICAgICAgY29uc3QgcXVlcnlEZWYgPSBnZXRRdWVyeURlZmluaXRpb24odGhpcy5xdWVyeSk7XG4gICAgICBjb25zdCB2YXJzID0gcXVlcnlEZWYudmFyaWFibGVEZWZpbml0aW9ucztcbiAgICAgIGlmICghdmFycyB8fCAhdmFycy5zb21lKCh2KSA9PiB2LnZhcmlhYmxlLm5hbWUudmFsdWUgPT09IFwidmFyaWFibGVzXCIpKSB7XG4gICAgICAgIGludmFyaWFudC53YXJuKFxuICAgICAgICAgIGBDYWxsZWQgcmVmZXRjaCglbykgZm9yIHF1ZXJ5ICVvLCB3aGljaCBkb2VzIG5vdCBkZWNsYXJlIGEgJHZhcmlhYmxlcyB2YXJpYWJsZS5cbkRpZCB5b3UgbWVhbiB0byBjYWxsIHJlZmV0Y2godmFyaWFibGVzKSBpbnN0ZWFkIG9mIHJlZmV0Y2goeyB2YXJpYWJsZXMgfSk/YCxcbiAgICAgICAgICB2YXJpYWJsZXMsXG4gICAgICAgICAgcXVlcnlEZWYubmFtZT8udmFsdWUgfHwgcXVlcnlEZWZcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodmFyaWFibGVzICYmICFlcXVhbCh0aGlzLm9wdGlvbnMudmFyaWFibGVzLCB2YXJpYWJsZXMpKSB7XG4gICAgICAvLyBVcGRhdGUgdGhlIGV4aXN0aW5nIG9wdGlvbnMgd2l0aCBuZXcgdmFyaWFibGVzXG4gICAgICByZW9ic2VydmVPcHRpb25zLnZhcmlhYmxlcyA9IHRoaXMub3B0aW9ucy52YXJpYWJsZXMgPSB7XG4gICAgICAgIC4uLnRoaXMub3B0aW9ucy52YXJpYWJsZXMsXG4gICAgICAgIC4uLnZhcmlhYmxlcyxcbiAgICAgIH0gYXMgVFZhcmlhYmxlcztcbiAgICB9XG5cbiAgICB0aGlzLnF1ZXJ5SW5mby5yZXNldExhc3RXcml0ZSgpO1xuICAgIHJldHVybiB0aGlzLnJlb2JzZXJ2ZShyZW9ic2VydmVPcHRpb25zLCBOZXR3b3JrU3RhdHVzLnJlZmV0Y2gpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBoZWxwcyB5b3UgZmV0Y2ggdGhlIG5leHQgc2V0IG9mIHJlc3VsdHMgZm9yIGEgW3BhZ2luYXRlZCBsaXN0IGZpZWxkXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L3BhZ2luYXRpb24vY29yZS1hcGkvKS5cbiAgICovXG4gIHB1YmxpYyBmZXRjaE1vcmU8XG4gICAgVEZldGNoRGF0YSA9IFREYXRhLFxuICAgIFRGZXRjaFZhcnMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXMgPSBUVmFyaWFibGVzLFxuICA+KFxuICAgIGZldGNoTW9yZU9wdGlvbnM6IEZldGNoTW9yZVF1ZXJ5T3B0aW9uczxURmV0Y2hWYXJzLCBURmV0Y2hEYXRhPiAmIHtcbiAgICAgIHVwZGF0ZVF1ZXJ5PzogKFxuICAgICAgICBwcmV2aW91c1F1ZXJ5UmVzdWx0OiBVbm1hc2tlZDxURGF0YT4sXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBmZXRjaE1vcmVSZXN1bHQ6IFVubWFza2VkPFRGZXRjaERhdGE+O1xuICAgICAgICAgIHZhcmlhYmxlczogVEZldGNoVmFycztcbiAgICAgICAgfVxuICAgICAgKSA9PiBVbm1hc2tlZDxURGF0YT47XG4gICAgfVxuICApOiBQcm9taXNlPEFwb2xsb1F1ZXJ5UmVzdWx0PE1heWJlTWFza2VkPFRGZXRjaERhdGE+Pj4ge1xuICAgIGNvbnN0IGNvbWJpbmVkT3B0aW9ucyA9IHtcbiAgICAgIC4uLihmZXRjaE1vcmVPcHRpb25zLnF1ZXJ5ID8gZmV0Y2hNb3JlT3B0aW9ucyA6IChcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMub3B0aW9ucyxcbiAgICAgICAgICBxdWVyeTogdGhpcy5vcHRpb25zLnF1ZXJ5LFxuICAgICAgICAgIC4uLmZldGNoTW9yZU9wdGlvbnMsXG4gICAgICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgICAgICAuLi50aGlzLm9wdGlvbnMudmFyaWFibGVzLFxuICAgICAgICAgICAgLi4uZmV0Y2hNb3JlT3B0aW9ucy52YXJpYWJsZXMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgKSksXG4gICAgICAvLyBUaGUgZmV0Y2hNb3JlIHJlcXVlc3QgZ29lcyBpbW1lZGlhdGVseSB0byB0aGUgbmV0d29yayBhbmQgZG9lc1xuICAgICAgLy8gbm90IGF1dG9tYXRpY2FsbHkgd3JpdGUgaXRzIHJlc3VsdCB0byB0aGUgY2FjaGUgKGhlbmNlIG5vLWNhY2hlXG4gICAgICAvLyBpbnN0ZWFkIG9mIG5ldHdvcmstb25seSksIGJlY2F1c2Ugd2UgYWxsb3cgdGhlIGNhbGxlciBvZlxuICAgICAgLy8gZmV0Y2hNb3JlIHRvIHByb3ZpZGUgYW4gdXBkYXRlUXVlcnkgY2FsbGJhY2sgdGhhdCBkZXRlcm1pbmVzIGhvd1xuICAgICAgLy8gdGhlIGRhdGEgZ2V0cyB3cml0dGVuIHRvIHRoZSBjYWNoZS5cbiAgICAgIGZldGNoUG9saWN5OiBcIm5vLWNhY2hlXCIsXG4gICAgfSBhcyBXYXRjaFF1ZXJ5T3B0aW9uczxURmV0Y2hWYXJzLCBURmV0Y2hEYXRhPjtcblxuICAgIGNvbWJpbmVkT3B0aW9ucy5xdWVyeSA9IHRoaXMudHJhbnNmb3JtRG9jdW1lbnQoY29tYmluZWRPcHRpb25zLnF1ZXJ5KTtcblxuICAgIGNvbnN0IHFpZCA9IHRoaXMucXVlcnlNYW5hZ2VyLmdlbmVyYXRlUXVlcnlJZCgpO1xuXG4gICAgLy8gSWYgYSB0ZW1wb3JhcnkgcXVlcnkgaXMgcGFzc2VkIHRvIGBmZXRjaE1vcmVgLCB3ZSBkb24ndCB3YW50IHRvIHN0b3JlXG4gICAgLy8gaXQgYXMgdGhlIGxhc3QgcXVlcnkgcmVzdWx0IHNpbmNlIGl0IG1heSBiZSBhbiBvcHRpbWl6ZWQgcXVlcnkgZm9yXG4gICAgLy8gcGFnaW5hdGlvbi4gV2Ugd2lsbCBob3dldmVyIHJ1biB0aGUgdHJhbnNmb3JtcyBvbiB0aGUgb3JpZ2luYWwgZG9jdW1lbnRcbiAgICAvLyBhcyB3ZWxsIGFzIHRoZSBkb2N1bWVudCBwYXNzZWQgaW4gYGZldGNoTW9yZU9wdGlvbnNgIHRvIGVuc3VyZSB0aGUgY2FjaGVcbiAgICAvLyB1c2VzIHRoZSBtb3N0IHVwLXRvLWRhdGUgZG9jdW1lbnQgd2hpY2ggbWF5IHJlbHkgb24gcnVudGltZSBjb25kaXRpb25hbHMuXG4gICAgdGhpcy5sYXN0UXVlcnkgPVxuICAgICAgZmV0Y2hNb3JlT3B0aW9ucy5xdWVyeSA/XG4gICAgICAgIHRoaXMudHJhbnNmb3JtRG9jdW1lbnQodGhpcy5vcHRpb25zLnF1ZXJ5KVxuICAgICAgOiBjb21iaW5lZE9wdGlvbnMucXVlcnk7XG5cbiAgICAvLyBTaW11bGF0ZSBhIGxvYWRpbmcgcmVzdWx0IGZvciB0aGUgb3JpZ2luYWwgcXVlcnkgd2l0aFxuICAgIC8vIHJlc3VsdC5uZXR3b3JrU3RhdHVzID09PSBOZXR3b3JrU3RhdHVzLmZldGNoTW9yZS5cbiAgICBjb25zdCB7IHF1ZXJ5SW5mbyB9ID0gdGhpcztcbiAgICBjb25zdCBvcmlnaW5hbE5ldHdvcmtTdGF0dXMgPSBxdWVyeUluZm8ubmV0d29ya1N0YXR1cztcbiAgICBxdWVyeUluZm8ubmV0d29ya1N0YXR1cyA9IE5ldHdvcmtTdGF0dXMuZmV0Y2hNb3JlO1xuICAgIGlmIChjb21iaW5lZE9wdGlvbnMubm90aWZ5T25OZXR3b3JrU3RhdHVzQ2hhbmdlKSB7XG4gICAgICB0aGlzLm9ic2VydmUoKTtcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVkUXVlcnlTZXQgPSBuZXcgU2V0PERvY3VtZW50Tm9kZT4oKTtcblxuICAgIGNvbnN0IHVwZGF0ZVF1ZXJ5ID0gZmV0Y2hNb3JlT3B0aW9ucz8udXBkYXRlUXVlcnk7XG4gICAgY29uc3QgaXNDYWNoZWQgPSB0aGlzLm9wdGlvbnMuZmV0Y2hQb2xpY3kgIT09IFwibm8tY2FjaGVcIjtcblxuICAgIGlmICghaXNDYWNoZWQpIHtcbiAgICAgIGludmFyaWFudChcbiAgICAgICAgdXBkYXRlUXVlcnksXG4gICAgICAgIFwiWW91IG11c3QgcHJvdmlkZSBhbiBgdXBkYXRlUXVlcnlgIGZ1bmN0aW9uIHdoZW4gdXNpbmcgYGZldGNoTW9yZWAgd2l0aCBhIGBuby1jYWNoZWAgZmV0Y2ggcG9saWN5LlwiXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnF1ZXJ5TWFuYWdlclxuICAgICAgLmZldGNoUXVlcnkocWlkLCBjb21iaW5lZE9wdGlvbnMsIE5ldHdvcmtTdGF0dXMuZmV0Y2hNb3JlKVxuICAgICAgLnRoZW4oKGZldGNoTW9yZVJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnF1ZXJ5TWFuYWdlci5yZW1vdmVRdWVyeShxaWQpO1xuXG4gICAgICAgIGlmIChxdWVyeUluZm8ubmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5mZXRjaE1vcmUpIHtcbiAgICAgICAgICBxdWVyeUluZm8ubmV0d29ya1N0YXR1cyA9IG9yaWdpbmFsTmV0d29ya1N0YXR1cztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0NhY2hlZCkge1xuICAgICAgICAgIC8vIFBlcmZvcm1pbmcgdGhpcyBjYWNoZSB1cGRhdGUgaW5zaWRlIGEgY2FjaGUuYmF0Y2ggdHJhbnNhY3Rpb24gZW5zdXJlc1xuICAgICAgICAgIC8vIGFueSBhZmZlY3RlZCBjYWNoZS53YXRjaCB3YXRjaGVycyBhcmUgbm90aWZpZWQgYXQgbW9zdCBvbmNlIGFib3V0IGFueVxuICAgICAgICAgIC8vIHVwZGF0ZXMuIE1vc3Qgd2F0Y2hlcnMgd2lsbCBiZSB1c2luZyB0aGUgUXVlcnlJbmZvIGNsYXNzLCB3aGljaFxuICAgICAgICAgIC8vIHJlc3BvbmRzIHRvIG5vdGlmaWNhdGlvbnMgYnkgY2FsbGluZyByZW9ic2VydmVDYWNoZUZpcnN0IHRvIGRlbGl2ZXJcbiAgICAgICAgICAvLyBmZXRjaE1vcmUgY2FjaGUgcmVzdWx0cyBiYWNrIHRvIHRoaXMgT2JzZXJ2YWJsZVF1ZXJ5LlxuICAgICAgICAgIHRoaXMucXVlcnlNYW5hZ2VyLmNhY2hlLmJhdGNoKHtcbiAgICAgICAgICAgIHVwZGF0ZTogKGNhY2hlKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgdXBkYXRlUXVlcnkgfSA9IGZldGNoTW9yZU9wdGlvbnM7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVRdWVyeSkge1xuICAgICAgICAgICAgICAgIGNhY2hlLnVwZGF0ZVF1ZXJ5KFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBxdWVyeTogdGhpcy5xdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzOiB0aGlzLnZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuUGFydGlhbERhdGE6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG9wdGltaXN0aWM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIChwcmV2aW91cykgPT5cbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlUXVlcnkocHJldmlvdXMhIGFzIGFueSwge1xuICAgICAgICAgICAgICAgICAgICAgIGZldGNoTW9yZVJlc3VsdDogZmV0Y2hNb3JlUmVzdWx0LmRhdGEgYXMgYW55LFxuICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlczogY29tYmluZWRPcHRpb25zLnZhcmlhYmxlcyBhcyBURmV0Y2hWYXJzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgd2UncmUgdXNpbmcgYSBmaWVsZCBwb2xpY3kgaW5zdGVhZCBvZiB1cGRhdGVRdWVyeSwgdGhlIG9ubHlcbiAgICAgICAgICAgICAgICAvLyB0aGluZyB3ZSBuZWVkIHRvIGRvIGlzIHdyaXRlIHRoZSBuZXcgZGF0YSB0byB0aGUgY2FjaGUgdXNpbmdcbiAgICAgICAgICAgICAgICAvLyBjb21iaW5lZE9wdGlvbnMudmFyaWFibGVzIChpbnN0ZWFkIG9mIHRoaXMudmFyaWFibGVzLCB3aGljaCBpc1xuICAgICAgICAgICAgICAgIC8vIHdoYXQgdGhpcy51cGRhdGVRdWVyeSB1c2VzLCBiZWNhdXNlIGl0IHdvcmtzIGJ5IGFidXNpbmcgdGhlXG4gICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgZmllbGQgdmFsdWUsIGtleWVkIGJ5IHRoZSBvcmlnaW5hbCB2YXJpYWJsZXMpLlxuICAgICAgICAgICAgICAgIGNhY2hlLndyaXRlUXVlcnkoe1xuICAgICAgICAgICAgICAgICAgcXVlcnk6IGNvbWJpbmVkT3B0aW9ucy5xdWVyeSxcbiAgICAgICAgICAgICAgICAgIHZhcmlhYmxlczogY29tYmluZWRPcHRpb25zLnZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGZldGNoTW9yZVJlc3VsdC5kYXRhIGFzIFVubWFza2VkPFRGZXRjaERhdGE+LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBvbldhdGNoVXBkYXRlZDogKHdhdGNoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIFJlY29yZCB0aGUgRG9jdW1lbnROb2RlIGFzc29jaWF0ZWQgd2l0aCBhbnkgd2F0Y2hlZCBxdWVyeSB3aG9zZVxuICAgICAgICAgICAgICAvLyBkYXRhIHdlcmUgdXBkYXRlZCBieSB0aGUgY2FjaGUgd3JpdGVzIGFib3ZlLlxuICAgICAgICAgICAgICB1cGRhdGVkUXVlcnlTZXQuYWRkKHdhdGNoLnF1ZXJ5KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlcmUgaXMgYSBwb3NzaWJpbGl0eSBgbGFzdFJlc3VsdGAgbWF5IG5vdCBiZSBzZXQgd2hlblxuICAgICAgICAgIC8vIGBmZXRjaE1vcmVgIGlzIGNhbGxlZCB3aGljaCB3b3VsZCBjYXVzZSB0aGlzIHRvIGNyYXNoLiBUaGlzIHNob3VsZFxuICAgICAgICAgIC8vIG9ubHkgaGFwcGVuIGlmIHdlIGhhdmVuJ3QgcHJldmlvdXNseSByZXBvcnRlZCBhIHJlc3VsdC4gV2UgZG9uJ3RcbiAgICAgICAgICAvLyBxdWl0ZSBrbm93IHdoYXQgdGhlIHJpZ2h0IGJlaGF2aW9yIHNob3VsZCBiZSBoZXJlIHNpbmNlIHRoaXMgYmxvY2tcbiAgICAgICAgICAvLyBvZiBjb2RlIHJ1bnMgYWZ0ZXIgdGhlIGZldGNoIHJlc3VsdCBoYXMgZXhlY3V0ZWQgb24gdGhlIG5ldHdvcmsuXG4gICAgICAgICAgLy8gV2UgcGxhbiB0byBsZXQgaXQgY3Jhc2ggaW4gdGhlIG1lYW50aW1lLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gSWYgd2UgZ2V0IGJ1ZyByZXBvcnRzIGR1ZSB0byB0aGUgYGRhdGFgIHByb3BlcnR5IGFjY2VzcyBvblxuICAgICAgICAgIC8vIHVuZGVmaW5lZCwgdGhpcyBzaG91bGQgZ2l2ZSB1cyBhIHJlYWwtd29ybGQgc2NlbmFyaW8gdGhhdCB3ZSBjYW5cbiAgICAgICAgICAvLyB1c2UgdG8gdGVzdCBhZ2FpbnN0IGFuZCBkZXRlcm1pbmUgdGhlIHJpZ2h0IGJlaGF2aW9yLiBJZiB3ZSBkbyBlbmRcbiAgICAgICAgICAvLyB1cCBjaGFuZ2luZyB0aGlzIGJlaGF2aW9yLCB0aGlzIG1heSByZXF1aXJlLCBmb3IgZXhhbXBsZSwgYW5cbiAgICAgICAgICAvLyBhZGp1c3RtZW50IHRvIHRoZSB0eXBlcyBvbiBgdXBkYXRlUXVlcnlgIHNpbmNlIHRoYXQgZnVuY3Rpb25cbiAgICAgICAgICAvLyBleHBlY3RzIHRoYXQgdGhlIGZpcnN0IGFyZ3VtZW50IGFsd2F5cyBjb250YWlucyBwcmV2aW91cyByZXN1bHRcbiAgICAgICAgICAvLyBkYXRhLCBidXQgbm90IGB1bmRlZmluZWRgLlxuICAgICAgICAgIGNvbnN0IGxhc3RSZXN1bHQgPSB0aGlzLmdldExhc3QoXCJyZXN1bHRcIikhO1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB1cGRhdGVRdWVyeSEobGFzdFJlc3VsdC5kYXRhIGFzIFVubWFza2VkPFREYXRhPiwge1xuICAgICAgICAgICAgZmV0Y2hNb3JlUmVzdWx0OiBmZXRjaE1vcmVSZXN1bHQuZGF0YSBhcyBVbm1hc2tlZDxURmV0Y2hEYXRhPixcbiAgICAgICAgICAgIHZhcmlhYmxlczogY29tYmluZWRPcHRpb25zLnZhcmlhYmxlcyBhcyBURmV0Y2hWYXJzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdGhpcy5yZXBvcnRSZXN1bHQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLmxhc3RSZXN1bHQsXG4gICAgICAgICAgICAgIG5ldHdvcmtTdGF0dXM6IG9yaWdpbmFsTmV0d29ya1N0YXR1cyEsXG4gICAgICAgICAgICAgIGxvYWRpbmc6IGlzTmV0d29ya1JlcXVlc3RJbkZsaWdodChvcmlnaW5hbE5ldHdvcmtTdGF0dXMpLFxuICAgICAgICAgICAgICBkYXRhOiBkYXRhIGFzIFREYXRhLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMudmFyaWFibGVzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLm1hc2tSZXN1bHQoZmV0Y2hNb3JlUmVzdWx0KTtcbiAgICAgIH0pXG4gICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgIC8vIEluIGNhc2UgdGhlIGNhY2hlIHdyaXRlcyBhYm92ZSBkaWQgbm90IGdlbmVyYXRlIGEgYnJvYWRjYXN0XG4gICAgICAgIC8vIG5vdGlmaWNhdGlvbiAod2hpY2ggd291bGQgaGF2ZSBiZWVuIGludGVyY2VwdGVkIGJ5IG9uV2F0Y2hVcGRhdGVkKSxcbiAgICAgICAgLy8gbGlrZWx5IGJlY2F1c2UgdGhlIHdyaXR0ZW4gZGF0YSB3ZXJlIHRoZSBzYW1lIGFzIHdoYXQgd2FzIGFscmVhZHkgaW5cbiAgICAgICAgLy8gdGhlIGNhY2hlLCB3ZSBzdGlsbCB3YW50IGZldGNoTW9yZSB0byBkZWxpdmVyIGl0cyBmaW5hbCBsb2FkaW5nOmZhbHNlXG4gICAgICAgIC8vIHJlc3VsdCB3aXRoIHRoZSB1bmNoYW5nZWQgZGF0YS5cbiAgICAgICAgaWYgKGlzQ2FjaGVkICYmICF1cGRhdGVkUXVlcnlTZXQuaGFzKHRoaXMucXVlcnkpKSB7XG4gICAgICAgICAgdGhpcy5yZW9ic2VydmVDYWNoZUZpcnN0KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gWFhYIHRoZSBzdWJzY3JpcHRpb24gdmFyaWFibGVzIGFyZSBzZXBhcmF0ZSBmcm9tIHRoZSBxdWVyeSB2YXJpYWJsZXMuXG4gIC8vIGlmIHlvdSB3YW50IHRvIHVwZGF0ZSBzdWJzY3JpcHRpb24gdmFyaWFibGVzLCByaWdodCBub3cgeW91IGhhdmUgdG8gZG8gdGhhdCBzZXBhcmF0ZWx5LFxuICAvLyBhbmQgeW91IGNhbiBvbmx5IGRvIGl0IGJ5IHN0b3BwaW5nIHRoZSBzdWJzY3JpcHRpb24gYW5kIHRoZW4gc3Vic2NyaWJpbmcgYWdhaW4gd2l0aCBuZXcgdmFyaWFibGVzLlxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGVuYWJsZXMgeW91IHRvIGV4ZWN1dGUgYSBbc3Vic2NyaXB0aW9uXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2RhdGEvc3Vic2NyaXB0aW9ucy8pLCB1c3VhbGx5IHRvIHN1YnNjcmliZSB0byBzcGVjaWZpYyBmaWVsZHMgdGhhdCB3ZXJlIGluY2x1ZGVkIGluIHRoZSBxdWVyeS5cbiAgICpcbiAgICogVGhpcyBmdW5jdGlvbiByZXR1cm5zIF9hbm90aGVyXyBmdW5jdGlvbiB0aGF0IHlvdSBjYW4gY2FsbCB0byB0ZXJtaW5hdGUgdGhlIHN1YnNjcmlwdGlvbi5cbiAgICovXG4gIHB1YmxpYyBzdWJzY3JpYmVUb01vcmU8XG4gICAgVFN1YnNjcmlwdGlvbkRhdGEgPSBURGF0YSxcbiAgICBUU3Vic2NyaXB0aW9uVmFyaWFibGVzIGV4dGVuZHMgT3BlcmF0aW9uVmFyaWFibGVzID0gVFZhcmlhYmxlcyxcbiAgPihcbiAgICBvcHRpb25zOiBTdWJzY3JpYmVUb01vcmVPcHRpb25zPFxuICAgICAgVERhdGEsXG4gICAgICBUU3Vic2NyaXB0aW9uVmFyaWFibGVzLFxuICAgICAgVFN1YnNjcmlwdGlvbkRhdGEsXG4gICAgICBUVmFyaWFibGVzXG4gICAgPlxuICApOiAoKSA9PiB2b2lkIHtcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLnF1ZXJ5TWFuYWdlclxuICAgICAgLnN0YXJ0R3JhcGhRTFN1YnNjcmlwdGlvbih7XG4gICAgICAgIHF1ZXJ5OiBvcHRpb25zLmRvY3VtZW50LFxuICAgICAgICB2YXJpYWJsZXM6IG9wdGlvbnMudmFyaWFibGVzLFxuICAgICAgICBjb250ZXh0OiBvcHRpb25zLmNvbnRleHQsXG4gICAgICB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChzdWJzY3JpcHRpb25EYXRhOiB7IGRhdGE6IFVubWFza2VkPFRTdWJzY3JpcHRpb25EYXRhPiB9KSA9PiB7XG4gICAgICAgICAgY29uc3QgeyB1cGRhdGVRdWVyeSB9ID0gb3B0aW9ucztcbiAgICAgICAgICBpZiAodXBkYXRlUXVlcnkpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUXVlcnkoKHByZXZpb3VzLCB1cGRhdGVPcHRpb25zKSA9PlxuICAgICAgICAgICAgICB1cGRhdGVRdWVyeShwcmV2aW91cywge1xuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbkRhdGEsXG4gICAgICAgICAgICAgICAgLi4udXBkYXRlT3B0aW9ucyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKG9wdGlvbnMub25FcnJvcikge1xuICAgICAgICAgICAgb3B0aW9ucy5vbkVycm9yKGVycik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGludmFyaWFudC5lcnJvcihcIlVuaGFuZGxlZCBHcmFwaFFMIHN1YnNjcmlwdGlvbiBlcnJvclwiLCBlcnIpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHN1YnNjcmlwdGlvbik7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uKSkge1xuICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHNldE9wdGlvbnMoXG4gICAgbmV3T3B0aW9uczogUGFydGlhbDxXYXRjaFF1ZXJ5T3B0aW9uczxUVmFyaWFibGVzLCBURGF0YT4+XG4gICk6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+Pj4ge1xuICAgIHJldHVybiB0aGlzLnJlb2JzZXJ2ZShuZXdPcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBzaWxlbnRTZXRPcHRpb25zKFxuICAgIG5ld09wdGlvbnM6IFBhcnRpYWw8V2F0Y2hRdWVyeU9wdGlvbnM8VFZhcmlhYmxlcywgVERhdGE+PlxuICApIHtcbiAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gY29tcGFjdCh0aGlzLm9wdGlvbnMsIG5ld09wdGlvbnMgfHwge30pO1xuICAgIGFzc2lnbih0aGlzLm9wdGlvbnMsIG1lcmdlZE9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgdmFyaWFibGVzIG9mIHRoaXMgb2JzZXJ2YWJsZSBxdWVyeSwgYW5kIGZldGNoIHRoZSBuZXcgcmVzdWx0c1xuICAgKiBpZiB0aGV5J3ZlIGNoYW5nZWQuIE1vc3QgdXNlcnMgc2hvdWxkIHByZWZlciBgcmVmZXRjaGAgaW5zdGVhZCBvZlxuICAgKiBgc2V0VmFyaWFibGVzYCBpbiBvcmRlciB0byB0byBiZSBwcm9wZXJseSBub3RpZmllZCBvZiByZXN1bHRzIGV2ZW4gd2hlblxuICAgKiB0aGV5IGNvbWUgZnJvbSB0aGUgY2FjaGUuXG4gICAqXG4gICAqIE5vdGU6IHRoZSBgbmV4dGAgY2FsbGJhY2sgd2lsbCAqbm90KiBmaXJlIGlmIHRoZSB2YXJpYWJsZXMgaGF2ZSBub3QgY2hhbmdlZFxuICAgKiBvciBpZiB0aGUgcmVzdWx0IGlzIGNvbWluZyBmcm9tIGNhY2hlLlxuICAgKlxuICAgKiBOb3RlOiB0aGUgcHJvbWlzZSB3aWxsIHJldHVybiB0aGUgb2xkIHJlc3VsdHMgaW1tZWRpYXRlbHkgaWYgdGhlIHZhcmlhYmxlc1xuICAgKiBoYXZlIG5vdCBjaGFuZ2VkLlxuICAgKlxuICAgKiBOb3RlOiB0aGUgcHJvbWlzZSB3aWxsIHJldHVybiBudWxsIGltbWVkaWF0ZWx5IGlmIHRoZSBxdWVyeSBpcyBub3QgYWN0aXZlXG4gICAqICh0aGVyZSBhcmUgbm8gc3Vic2NyaWJlcnMpLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gVGhlIG5ldyBzZXQgb2YgdmFyaWFibGVzLiBJZiB0aGVyZSBhcmUgbWlzc2luZyB2YXJpYWJsZXMsXG4gICAqIHRoZSBwcmV2aW91cyB2YWx1ZXMgb2YgdGhvc2UgdmFyaWFibGVzIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHB1YmxpYyBzZXRWYXJpYWJsZXMoXG4gICAgdmFyaWFibGVzOiBUVmFyaWFibGVzXG4gICk6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+PiB8IHZvaWQ+IHtcbiAgICBpZiAoZXF1YWwodGhpcy52YXJpYWJsZXMsIHZhcmlhYmxlcykpIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgbm8gb2JzZXJ2ZXJzLCB0aGVuIHdlIGRvbid0IGFjdHVhbGx5IHdhbnQgdG8gbWFrZSBhIG5ldHdvcmtcbiAgICAgIC8vIHJlcXVlc3QuIEFzIHNvb24gYXMgc29tZW9uZSBvYnNlcnZlcyB0aGUgcXVlcnksIHRoZSByZXF1ZXN0IHdpbGwga2lja1xuICAgICAgLy8gb2ZmLiBGb3Igbm93LCB3ZSBqdXN0IHN0b3JlIGFueSBjaGFuZ2VzLiAoU2VlICMxMDc3KVxuICAgICAgcmV0dXJuIHRoaXMub2JzZXJ2ZXJzLnNpemUgPyB0aGlzLnJlc3VsdCgpIDogUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zLnZhcmlhYmxlcyA9IHZhcmlhYmxlcztcblxuICAgIC8vIFNlZSBjb21tZW50IGFib3ZlXG4gICAgaWYgKCF0aGlzLm9ic2VydmVycy5zaXplKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVvYnNlcnZlKFxuICAgICAge1xuICAgICAgICAvLyBSZXNldCBvcHRpb25zLmZldGNoUG9saWN5IHRvIGl0cyBvcmlnaW5hbCB2YWx1ZS5cbiAgICAgICAgZmV0Y2hQb2xpY3k6IHRoaXMub3B0aW9ucy5pbml0aWFsRmV0Y2hQb2xpY3ksXG4gICAgICAgIHZhcmlhYmxlcyxcbiAgICAgIH0sXG4gICAgICBOZXR3b3JrU3RhdHVzLnNldFZhcmlhYmxlc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGVuYWJsZXMgeW91IHRvIHVwZGF0ZSB0aGUgcXVlcnkncyBjYWNoZWQgcmVzdWx0IHdpdGhvdXQgZXhlY3V0aW5nIGEgZm9sbG93dXAgR3JhcGhRTCBvcGVyYXRpb24uXG4gICAqXG4gICAqIFNlZSBbdXNpbmcgdXBkYXRlUXVlcnkgYW5kIHVwZGF0ZUZyYWdtZW50XShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2NhY2hpbmcvY2FjaGUtaW50ZXJhY3Rpb24vI3VzaW5nLXVwZGF0ZXF1ZXJ5LWFuZC11cGRhdGVmcmFnbWVudCkgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlUXVlcnkobWFwRm46IFVwZGF0ZVF1ZXJ5TWFwRm48VERhdGEsIFRWYXJpYWJsZXM+KTogdm9pZCB7XG4gICAgY29uc3QgeyBxdWVyeU1hbmFnZXIgfSA9IHRoaXM7XG4gICAgY29uc3QgeyByZXN1bHQsIGNvbXBsZXRlIH0gPSBxdWVyeU1hbmFnZXIuY2FjaGUuZGlmZjxURGF0YT4oe1xuICAgICAgcXVlcnk6IHRoaXMub3B0aW9ucy5xdWVyeSxcbiAgICAgIHZhcmlhYmxlczogdGhpcy52YXJpYWJsZXMsXG4gICAgICByZXR1cm5QYXJ0aWFsRGF0YTogdHJ1ZSxcbiAgICAgIG9wdGltaXN0aWM6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbmV3UmVzdWx0ID0gbWFwRm4oXG4gICAgICByZXN1bHQhIGFzIFVubWFza2VkPFREYXRhPixcbiAgICAgIHtcbiAgICAgICAgdmFyaWFibGVzOiB0aGlzLnZhcmlhYmxlcyxcbiAgICAgICAgY29tcGxldGU6ICEhY29tcGxldGUsXG4gICAgICAgIHByZXZpb3VzRGF0YTogcmVzdWx0LFxuICAgICAgfSBhcyBVcGRhdGVRdWVyeU9wdGlvbnM8VERhdGEsIFRWYXJpYWJsZXM+XG4gICAgKTtcblxuICAgIGlmIChuZXdSZXN1bHQpIHtcbiAgICAgIHF1ZXJ5TWFuYWdlci5jYWNoZS53cml0ZVF1ZXJ5KHtcbiAgICAgICAgcXVlcnk6IHRoaXMub3B0aW9ucy5xdWVyeSxcbiAgICAgICAgZGF0YTogbmV3UmVzdWx0LFxuICAgICAgICB2YXJpYWJsZXM6IHRoaXMudmFyaWFibGVzLFxuICAgICAgfSk7XG5cbiAgICAgIHF1ZXJ5TWFuYWdlci5icm9hZGNhc3RRdWVyaWVzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBpbnN0cnVjdHMgdGhlIHF1ZXJ5IHRvIGJlZ2luIHJlLWV4ZWN1dGluZyBhdCBhIHNwZWNpZmllZCBpbnRlcnZhbCAoaW4gbWlsbGlzZWNvbmRzKS5cbiAgICovXG4gIHB1YmxpYyBzdGFydFBvbGxpbmcocG9sbEludGVydmFsOiBudW1iZXIpIHtcbiAgICB0aGlzLm9wdGlvbnMucG9sbEludGVydmFsID0gcG9sbEludGVydmFsO1xuICAgIHRoaXMudXBkYXRlUG9sbGluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBpbnN0cnVjdHMgdGhlIHF1ZXJ5IHRvIHN0b3AgcG9sbGluZyBhZnRlciBhIHByZXZpb3VzIGNhbGwgdG8gYHN0YXJ0UG9sbGluZ2AuXG4gICAqL1xuICBwdWJsaWMgc3RvcFBvbGxpbmcoKSB7XG4gICAgdGhpcy5vcHRpb25zLnBvbGxJbnRlcnZhbCA9IDA7XG4gICAgdGhpcy51cGRhdGVQb2xsaW5nKCk7XG4gIH1cblxuICAvLyBVcGRhdGUgb3B0aW9ucy5mZXRjaFBvbGljeSBhY2NvcmRpbmcgdG8gb3B0aW9ucy5uZXh0RmV0Y2hQb2xpY3kuXG4gIHByaXZhdGUgYXBwbHlOZXh0RmV0Y2hQb2xpY3koXG4gICAgcmVhc29uOiBOZXh0RmV0Y2hQb2xpY3lDb250ZXh0PFREYXRhLCBUVmFyaWFibGVzPltcInJlYXNvblwiXSxcbiAgICAvLyBJdCdzIHBvc3NpYmxlIHRvIHVzZSB0aGlzIG1ldGhvZCB0byBhcHBseSBvcHRpb25zLm5leHRGZXRjaFBvbGljeSB0b1xuICAgIC8vIG9wdGlvbnMuZmV0Y2hQb2xpY3kgZXZlbiBpZiBvcHRpb25zICE9PSB0aGlzLm9wdGlvbnMsIHRob3VnaCB0aGF0IGhhcHBlbnNcbiAgICAvLyBtb3N0IG9mdGVuIHdoZW4gdGhlIG9wdGlvbnMgYXJlIHRlbXBvcmFyeSwgdXNlZCBmb3Igb25seSBvbmUgcmVxdWVzdCBhbmRcbiAgICAvLyB0aGVuIHRocm93biBhd2F5LCBzbyBuZXh0RmV0Y2hQb2xpY3kgbWF5IG5vdCBlbmQgdXAgbWF0dGVyaW5nLlxuICAgIG9wdGlvbnM6IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJpYWJsZXMsIFREYXRhPlxuICApIHtcbiAgICBpZiAob3B0aW9ucy5uZXh0RmV0Y2hQb2xpY3kpIHtcbiAgICAgIGNvbnN0IHsgZmV0Y2hQb2xpY3kgPSBcImNhY2hlLWZpcnN0XCIsIGluaXRpYWxGZXRjaFBvbGljeSA9IGZldGNoUG9saWN5IH0gPVxuICAgICAgICBvcHRpb25zO1xuXG4gICAgICBpZiAoZmV0Y2hQb2xpY3kgPT09IFwic3RhbmRieVwiKSB7XG4gICAgICAgIC8vIERvIG5vdGhpbmcsIGxlYXZpbmcgb3B0aW9ucy5mZXRjaFBvbGljeSB1bmNoYW5nZWQuXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zLm5leHRGZXRjaFBvbGljeSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIC8vIFdoZW4gc29tZW9uZSBjaG9vc2VzIFwiY2FjaGUtYW5kLW5ldHdvcmtcIiBvciBcIm5ldHdvcmstb25seVwiIGFzIHRoZWlyXG4gICAgICAgIC8vIGluaXRpYWwgRmV0Y2hQb2xpY3ksIHRoZXkgb2Z0ZW4gZG8gbm90IHdhbnQgZnV0dXJlIGNhY2hlIHVwZGF0ZXMgdG9cbiAgICAgICAgLy8gdHJpZ2dlciB1bmNvbmRpdGlvbmFsIG5ldHdvcmsgcmVxdWVzdHMsIHdoaWNoIGlzIHdoYXQgcmVwZWF0ZWRseVxuICAgICAgICAvLyBhcHBseWluZyB0aGUgXCJjYWNoZS1hbmQtbmV0d29ya1wiIG9yIFwibmV0d29yay1vbmx5XCIgcG9saWNpZXMgd291bGRcbiAgICAgICAgLy8gc2VlbSB0byBpbXBseS4gSW5zdGVhZCwgd2hlbiB0aGUgY2FjaGUgcmVwb3J0cyBhbiB1cGRhdGUgYWZ0ZXIgdGhlXG4gICAgICAgIC8vIGluaXRpYWwgbmV0d29yayByZXF1ZXN0LCBpdCBtYXkgYmUgZGVzaXJhYmxlIGZvciBzdWJzZXF1ZW50IG5ldHdvcmtcbiAgICAgICAgLy8gcmVxdWVzdHMgdG8gYmUgdHJpZ2dlcmVkIG9ubHkgaWYgdGhlIGNhY2hlIHJlc3VsdCBpcyBpbmNvbXBsZXRlLiBUb1xuICAgICAgICAvLyB0aGF0IGVuZCwgdGhlIG9wdGlvbnMubmV4dEZldGNoUG9saWN5IG9wdGlvbiBwcm92aWRlcyBhbiBlYXN5IHdheSB0b1xuICAgICAgICAvLyB1cGRhdGUgb3B0aW9ucy5mZXRjaFBvbGljeSBhZnRlciB0aGUgaW5pdGlhbCBuZXR3b3JrIHJlcXVlc3QsIHdpdGhvdXRcbiAgICAgICAgLy8gaGF2aW5nIHRvIGNhbGwgb2JzZXJ2YWJsZVF1ZXJ5LnNldE9wdGlvbnMuXG4gICAgICAgIG9wdGlvbnMuZmV0Y2hQb2xpY3kgPSBvcHRpb25zLm5leHRGZXRjaFBvbGljeShmZXRjaFBvbGljeSwge1xuICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgIG9ic2VydmFibGU6IHRoaXMsXG4gICAgICAgICAgaW5pdGlhbEZldGNoUG9saWN5LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocmVhc29uID09PSBcInZhcmlhYmxlcy1jaGFuZ2VkXCIpIHtcbiAgICAgICAgb3B0aW9ucy5mZXRjaFBvbGljeSA9IGluaXRpYWxGZXRjaFBvbGljeTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wdGlvbnMuZmV0Y2hQb2xpY3kgPSBvcHRpb25zLm5leHRGZXRjaFBvbGljeTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucy5mZXRjaFBvbGljeTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2goXG4gICAgb3B0aW9uczogV2F0Y2hRdWVyeU9wdGlvbnM8VFZhcmlhYmxlcywgVERhdGE+LFxuICAgIG5ld05ldHdvcmtTdGF0dXM/OiBOZXR3b3JrU3RhdHVzLFxuICAgIHF1ZXJ5PzogRG9jdW1lbnROb2RlXG4gICkge1xuICAgIC8vIFRPRE8gTWFrZSBzdXJlIHdlIHVwZGF0ZSB0aGUgbmV0d29ya1N0YXR1cyAoYW5kIGluZmVyIGZldGNoVmFyaWFibGVzKVxuICAgIC8vIGJlZm9yZSBhY3R1YWxseSBjb21taXR0aW5nIHRvIHRoZSBmZXRjaC5cbiAgICBjb25zdCBxdWVyeUluZm8gPSB0aGlzLnF1ZXJ5TWFuYWdlci5nZXRPckNyZWF0ZVF1ZXJ5KHRoaXMucXVlcnlJZCk7XG4gICAgcXVlcnlJbmZvLnNldE9ic2VydmFibGVRdWVyeSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5xdWVyeU1hbmFnZXJbXCJmZXRjaENvbmNhc3RXaXRoSW5mb1wiXShcbiAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBuZXdOZXR3b3JrU3RhdHVzLFxuICAgICAgcXVlcnlcbiAgICApO1xuICB9XG5cbiAgLy8gVHVybnMgcG9sbGluZyBvbiBvciBvZmYgYmFzZWQgb24gdGhpcy5vcHRpb25zLnBvbGxJbnRlcnZhbC5cbiAgcHJpdmF0ZSB1cGRhdGVQb2xsaW5nKCkge1xuICAgIC8vIEF2b2lkIHBvbGxpbmcgaW4gU1NSIG1vZGVcbiAgICBpZiAodGhpcy5xdWVyeU1hbmFnZXIuc3NyTW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIHBvbGxpbmdJbmZvLFxuICAgICAgb3B0aW9uczogeyBwb2xsSW50ZXJ2YWwgfSxcbiAgICB9ID0gdGhpcztcblxuICAgIGlmICghcG9sbEludGVydmFsIHx8ICF0aGlzLmhhc09ic2VydmVycygpKSB7XG4gICAgICBpZiAocG9sbGluZ0luZm8pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHBvbGxpbmdJbmZvLnRpbWVvdXQpO1xuICAgICAgICBkZWxldGUgdGhpcy5wb2xsaW5nSW5mbztcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocG9sbGluZ0luZm8gJiYgcG9sbGluZ0luZm8uaW50ZXJ2YWwgPT09IHBvbGxJbnRlcnZhbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGludmFyaWFudChcbiAgICAgIHBvbGxJbnRlcnZhbCxcbiAgICAgIFwiQXR0ZW1wdGVkIHRvIHN0YXJ0IGEgcG9sbGluZyBxdWVyeSB3aXRob3V0IGEgcG9sbGluZyBpbnRlcnZhbC5cIlxuICAgICk7XG5cbiAgICBjb25zdCBpbmZvID0gcG9sbGluZ0luZm8gfHwgKHRoaXMucG9sbGluZ0luZm8gPSB7fSBhcyBhbnkpO1xuICAgIGluZm8uaW50ZXJ2YWwgPSBwb2xsSW50ZXJ2YWw7XG5cbiAgICBjb25zdCBtYXliZUZldGNoID0gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMucG9sbGluZ0luZm8pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFpc05ldHdvcmtSZXF1ZXN0SW5GbGlnaHQodGhpcy5xdWVyeUluZm8ubmV0d29ya1N0YXR1cykgJiZcbiAgICAgICAgICAhdGhpcy5vcHRpb25zLnNraXBQb2xsQXR0ZW1wdD8uKClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5yZW9ic2VydmUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC8vIE1vc3QgZmV0Y2hQb2xpY3kgb3B0aW9ucyBkb24ndCBtYWtlIHNlbnNlIHRvIHVzZSBpbiBhIHBvbGxpbmcgY29udGV4dCwgYXNcbiAgICAgICAgICAgICAgLy8gdXNlcnMgd291bGRuJ3Qgd2FudCB0byBiZSBwb2xsaW5nIHRoZSBjYWNoZSBkaXJlY3RseS4gSG93ZXZlciwgbmV0d29yay1vbmx5IGFuZFxuICAgICAgICAgICAgICAvLyBuby1jYWNoZSBhcmUgYm90aCB1c2VmdWwgZm9yIHdoZW4gdGhlIHVzZXIgd2FudHMgdG8gY29udHJvbCB3aGV0aGVyIG9yIG5vdCB0aGVcbiAgICAgICAgICAgICAgLy8gcG9sbGVkIHJlc3VsdHMgYXJlIHdyaXR0ZW4gdG8gdGhlIGNhY2hlLlxuICAgICAgICAgICAgICBmZXRjaFBvbGljeTpcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuaW5pdGlhbEZldGNoUG9saWN5ID09PSBcIm5vLWNhY2hlXCIgP1xuICAgICAgICAgICAgICAgICAgXCJuby1jYWNoZVwiXG4gICAgICAgICAgICAgICAgOiBcIm5ldHdvcmstb25seVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE5ldHdvcmtTdGF0dXMucG9sbFxuICAgICAgICAgICkudGhlbihwb2xsLCBwb2xsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwb2xsKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcG9sbCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGluZm8gPSB0aGlzLnBvbGxpbmdJbmZvO1xuICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGluZm8udGltZW91dCk7XG4gICAgICAgIGluZm8udGltZW91dCA9IHNldFRpbWVvdXQobWF5YmVGZXRjaCwgaW5mby5pbnRlcnZhbCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHBvbGwoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTGFzdFJlc3VsdChcbiAgICBuZXdSZXN1bHQ6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPixcbiAgICB2YXJpYWJsZXMgPSB0aGlzLnZhcmlhYmxlc1xuICApIHtcbiAgICBsZXQgZXJyb3I6IEFwb2xsb0Vycm9yIHwgdW5kZWZpbmVkID0gdGhpcy5nZXRMYXN0RXJyb3IoKTtcbiAgICAvLyBQcmVzZXJ2ZSB0aGlzLmxhc3QuZXJyb3IgdW5sZXNzIHRoZSB2YXJpYWJsZXMgaGF2ZSBjaGFuZ2VkLlxuICAgIGlmIChlcnJvciAmJiB0aGlzLmxhc3QgJiYgIWVxdWFsKHZhcmlhYmxlcywgdGhpcy5sYXN0LnZhcmlhYmxlcykpIHtcbiAgICAgIGVycm9yID0gdm9pZCAwO1xuICAgIH1cbiAgICByZXR1cm4gKHRoaXMubGFzdCA9IHtcbiAgICAgIHJlc3VsdDpcbiAgICAgICAgdGhpcy5xdWVyeU1hbmFnZXIuYXNzdW1lSW1tdXRhYmxlUmVzdWx0cyA/XG4gICAgICAgICAgbmV3UmVzdWx0XG4gICAgICAgIDogY2xvbmVEZWVwKG5ld1Jlc3VsdCksXG4gICAgICB2YXJpYWJsZXMsXG4gICAgICAuLi4oZXJyb3IgPyB7IGVycm9yIH0gOiBudWxsKSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZW9ic2VydmVBc0NvbmNhc3QoXG4gICAgbmV3T3B0aW9ucz86IFBhcnRpYWw8V2F0Y2hRdWVyeU9wdGlvbnM8VFZhcmlhYmxlcywgVERhdGE+PixcbiAgICBuZXdOZXR3b3JrU3RhdHVzPzogTmV0d29ya1N0YXR1c1xuICApOiBDb25jYXN0PEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPj4ge1xuICAgIHRoaXMuaXNUb3JuRG93biA9IGZhbHNlO1xuXG4gICAgY29uc3QgdXNlRGlzcG9zYWJsZUNvbmNhc3QgPVxuICAgICAgLy8gUmVmZXRjaGluZyB1c2VzIGEgZGlzcG9zYWJsZSBDb25jYXN0IHRvIGFsbG93IHJlZmV0Y2hlcyB1c2luZyBkaWZmZXJlbnRcbiAgICAgIC8vIG9wdGlvbnMvdmFyaWFibGVzLCB3aXRob3V0IHBlcm1hbmVudGx5IGFsdGVyaW5nIHRoZSBvcHRpb25zIG9mIHRoZVxuICAgICAgLy8gb3JpZ2luYWwgT2JzZXJ2YWJsZVF1ZXJ5LlxuICAgICAgbmV3TmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5yZWZldGNoIHx8XG4gICAgICAvLyBUaGUgZmV0Y2hNb3JlIG1ldGhvZCBkb2VzIG5vdCBhY3R1YWxseSBjYWxsIHRoZSByZW9ic2VydmUgbWV0aG9kLCBidXQsXG4gICAgICAvLyBpZiBpdCBkaWQsIGl0IHdvdWxkIGRlZmluaXRlbHkgdXNlIGEgZGlzcG9zYWJsZSBDb25jYXN0LlxuICAgICAgbmV3TmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5mZXRjaE1vcmUgfHxcbiAgICAgIC8vIFBvbGxpbmcgdXNlcyBhIGRpc3Bvc2FibGUgQ29uY2FzdCBzbyB0aGUgcG9sbGluZyBvcHRpb25zICh3aGljaCBmb3JjZVxuICAgICAgLy8gZmV0Y2hQb2xpY3kgdG8gYmUgXCJuZXR3b3JrLW9ubHlcIiBvciBcIm5vLWNhY2hlXCIpIHdvbid0IG92ZXJyaWRlIHRoZSBvcmlnaW5hbCBvcHRpb25zLlxuICAgICAgbmV3TmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5wb2xsO1xuXG4gICAgLy8gU2F2ZSB0aGUgb2xkIHZhcmlhYmxlcywgc2luY2UgT2JqZWN0LmFzc2lnbiBtYXkgbW9kaWZ5IHRoZW0gYmVsb3cuXG4gICAgY29uc3Qgb2xkVmFyaWFibGVzID0gdGhpcy5vcHRpb25zLnZhcmlhYmxlcztcbiAgICBjb25zdCBvbGRGZXRjaFBvbGljeSA9IHRoaXMub3B0aW9ucy5mZXRjaFBvbGljeTtcblxuICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBjb21wYWN0KHRoaXMub3B0aW9ucywgbmV3T3B0aW9ucyB8fCB7fSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9XG4gICAgICB1c2VEaXNwb3NhYmxlQ29uY2FzdCA/XG4gICAgICAgIC8vIERpc3Bvc2FibGUgQ29uY2FzdCBmZXRjaGVzIHJlY2VpdmUgYSBzaGFsbG93IGNvcHkgb2YgdGhpcy5vcHRpb25zXG4gICAgICAgIC8vIChtZXJnZWQgd2l0aCBuZXdPcHRpb25zKSwgbGVhdmluZyB0aGlzLm9wdGlvbnMgdW5tb2RpZmllZC5cbiAgICAgICAgbWVyZ2VkT3B0aW9uc1xuICAgICAgOiBhc3NpZ24odGhpcy5vcHRpb25zLCBtZXJnZWRPcHRpb25zKTtcblxuICAgIC8vIERvbid0IHVwZGF0ZSBvcHRpb25zLnF1ZXJ5IHdpdGggdGhlIHRyYW5zZm9ybWVkIHF1ZXJ5IHRvIGF2b2lkXG4gICAgLy8gb3ZlcndyaXRpbmcgdGhpcy5vcHRpb25zLnF1ZXJ5IHdoZW4gd2UgYXJlbid0IHVzaW5nIGEgZGlzcG9zYWJsZSBjb25jYXN0LlxuICAgIC8vIFdlIHdhbnQgdG8gZW5zdXJlIHdlIGNhbiByZS1ydW4gdGhlIGN1c3RvbSBkb2N1bWVudCB0cmFuc2Zvcm1zIHRoZSBuZXh0XG4gICAgLy8gdGltZSBhIHJlcXVlc3QgaXMgbWFkZSBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBxdWVyeS5cbiAgICBjb25zdCBxdWVyeSA9IHRoaXMudHJhbnNmb3JtRG9jdW1lbnQob3B0aW9ucy5xdWVyeSk7XG5cbiAgICB0aGlzLmxhc3RRdWVyeSA9IHF1ZXJ5O1xuXG4gICAgaWYgKCF1c2VEaXNwb3NhYmxlQ29uY2FzdCkge1xuICAgICAgLy8gV2UgY2FuIHNraXAgY2FsbGluZyB1cGRhdGVQb2xsaW5nIGlmIHdlJ3JlIG5vdCBjaGFuZ2luZyB0aGlzLm9wdGlvbnMuXG4gICAgICB0aGlzLnVwZGF0ZVBvbGxpbmcoKTtcblxuICAgICAgLy8gUmVzZXQgb3B0aW9ucy5mZXRjaFBvbGljeSB0byBpdHMgb3JpZ2luYWwgdmFsdWUgd2hlbiB2YXJpYWJsZXMgY2hhbmdlLFxuICAgICAgLy8gdW5sZXNzIGEgbmV3IGZldGNoUG9saWN5IHdhcyBwcm92aWRlZCBieSBuZXdPcHRpb25zLlxuICAgICAgaWYgKFxuICAgICAgICBuZXdPcHRpb25zICYmXG4gICAgICAgIG5ld09wdGlvbnMudmFyaWFibGVzICYmXG4gICAgICAgICFlcXVhbChuZXdPcHRpb25zLnZhcmlhYmxlcywgb2xkVmFyaWFibGVzKSAmJlxuICAgICAgICAvLyBEb24ndCBtZXNzIHdpdGggdGhlIGZldGNoUG9saWN5IGlmIGl0J3MgY3VycmVudGx5IFwic3RhbmRieVwiLlxuICAgICAgICBvcHRpb25zLmZldGNoUG9saWN5ICE9PSBcInN0YW5kYnlcIiAmJlxuICAgICAgICAvLyBJZiB3ZSdyZSBjaGFuZ2luZyB0aGUgZmV0Y2hQb2xpY3kgYW55d2F5LCBkb24ndCB0cnkgdG8gY2hhbmdlIGl0IGhlcmVcbiAgICAgICAgLy8gdXNpbmcgYXBwbHlOZXh0RmV0Y2hQb2xpY3kuIFRoZSBleHBsaWNpdCBvcHRpb25zLmZldGNoUG9saWN5IHdpbnMuXG4gICAgICAgIChvcHRpb25zLmZldGNoUG9saWN5ID09PSBvbGRGZXRjaFBvbGljeSB8fFxuICAgICAgICAgIC8vIEEgYG5leHRGZXRjaFBvbGljeWAgZnVuY3Rpb24gaGFzIGV2ZW4gaGlnaGVyIHByaW9yaXR5LCB0aG91Z2gsXG4gICAgICAgICAgLy8gc28gaW4gdGhhdCBjYXNlIGBhcHBseU5leHRGZXRjaFBvbGljeWAgbXVzdCBiZSBjYWxsZWQuXG4gICAgICAgICAgdHlwZW9mIG9wdGlvbnMubmV4dEZldGNoUG9saWN5ID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hcHBseU5leHRGZXRjaFBvbGljeShcInZhcmlhYmxlcy1jaGFuZ2VkXCIsIG9wdGlvbnMpO1xuICAgICAgICBpZiAobmV3TmV0d29ya1N0YXR1cyA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgbmV3TmV0d29ya1N0YXR1cyA9IE5ldHdvcmtTdGF0dXMuc2V0VmFyaWFibGVzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy53YWl0Rm9yT3duUmVzdWx0ICYmPSBza2lwQ2FjaGVEYXRhRm9yKG9wdGlvbnMuZmV0Y2hQb2xpY3kpO1xuICAgIGNvbnN0IGZpbmlzaFdhaXRpbmdGb3JPd25SZXN1bHQgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5jb25jYXN0ID09PSBjb25jYXN0KSB7XG4gICAgICAgIHRoaXMud2FpdEZvck93blJlc3VsdCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCB2YXJpYWJsZXMgPSBvcHRpb25zLnZhcmlhYmxlcyAmJiB7IC4uLm9wdGlvbnMudmFyaWFibGVzIH07XG4gICAgY29uc3QgeyBjb25jYXN0LCBmcm9tTGluayB9ID0gdGhpcy5mZXRjaChvcHRpb25zLCBuZXdOZXR3b3JrU3RhdHVzLCBxdWVyeSk7XG4gICAgY29uc3Qgb2JzZXJ2ZXI6IE9ic2VydmVyPEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPj4gPSB7XG4gICAgICBuZXh0OiAocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChlcXVhbCh0aGlzLnZhcmlhYmxlcywgdmFyaWFibGVzKSkge1xuICAgICAgICAgIGZpbmlzaFdhaXRpbmdGb3JPd25SZXN1bHQoKTtcbiAgICAgICAgICB0aGlzLnJlcG9ydFJlc3VsdChyZXN1bHQsIHZhcmlhYmxlcyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcXVhbCh0aGlzLnZhcmlhYmxlcywgdmFyaWFibGVzKSkge1xuICAgICAgICAgIC8vIENvbWluZyBmcm9tIGBnZXRSZXN1bHRzRnJvbUxpbmtgLCBgZXJyb3JgIGhlcmUgc2hvdWxkIGFsd2F5cyBiZSBhbiBgQXBvbGxvRXJyb3JgLlxuICAgICAgICAgIC8vIEhvd2V2ZXIsIGNhbGxpbmcgYGNvbmNhc3QuY2FuY2VsYCBjYW4gaW5qZWN0IGFub3RoZXIgdHlwZSBvZiBlcnJvciwgc28gd2UgaGF2ZSB0b1xuICAgICAgICAgIC8vIHdyYXAgaXQgYWdhaW4gaGVyZS5cbiAgICAgICAgICBpZiAoIWlzQXBvbGxvRXJyb3IoZXJyb3IpKSB7XG4gICAgICAgICAgICBlcnJvciA9IG5ldyBBcG9sbG9FcnJvcih7IG5ldHdvcmtFcnJvcjogZXJyb3IgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZpbmlzaFdhaXRpbmdGb3JPd25SZXN1bHQoKTtcbiAgICAgICAgICB0aGlzLnJlcG9ydEVycm9yKGVycm9yLCB2YXJpYWJsZXMpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH07XG5cbiAgICBpZiAoIXVzZURpc3Bvc2FibGVDb25jYXN0ICYmIChmcm9tTGluayB8fCAhdGhpcy5jb25jYXN0KSkge1xuICAgICAgLy8gV2UgdXNlIHRoZSB7YWRkLHJlbW92ZX1PYnNlcnZlciBtZXRob2RzIGRpcmVjdGx5IHRvIGF2b2lkIHdyYXBwaW5nXG4gICAgICAvLyBvYnNlcnZlciB3aXRoIGFuIHVubmVjZXNzYXJ5IFN1YnNjcmlwdGlvbk9ic2VydmVyIG9iamVjdC5cbiAgICAgIGlmICh0aGlzLmNvbmNhc3QgJiYgdGhpcy5vYnNlcnZlcikge1xuICAgICAgICB0aGlzLmNvbmNhc3QucmVtb3ZlT2JzZXJ2ZXIodGhpcy5vYnNlcnZlcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY29uY2FzdCA9IGNvbmNhc3Q7XG4gICAgICB0aGlzLm9ic2VydmVyID0gb2JzZXJ2ZXI7XG4gICAgfVxuXG4gICAgY29uY2FzdC5hZGRPYnNlcnZlcihvYnNlcnZlcik7XG5cbiAgICByZXR1cm4gY29uY2FzdDtcbiAgfVxuXG4gIHB1YmxpYyByZW9ic2VydmUoXG4gICAgbmV3T3B0aW9ucz86IFBhcnRpYWw8V2F0Y2hRdWVyeU9wdGlvbnM8VFZhcmlhYmxlcywgVERhdGE+PixcbiAgICBuZXdOZXR3b3JrU3RhdHVzPzogTmV0d29ya1N0YXR1c1xuICApOiBQcm9taXNlPEFwb2xsb1F1ZXJ5UmVzdWx0PE1heWJlTWFza2VkPFREYXRhPj4+IHtcbiAgICByZXR1cm4gcHJldmVudFVuaGFuZGxlZFJlamVjdGlvbihcbiAgICAgIHRoaXMucmVvYnNlcnZlQXNDb25jYXN0KG5ld09wdGlvbnMsIG5ld05ldHdvcmtTdGF0dXMpLnByb21pc2UudGhlbihcbiAgICAgICAgdGhpcy5tYXNrUmVzdWx0IGFzIFRPRE9cbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIHJlc3Vic2NyaWJlQWZ0ZXJFcnJvcihcbiAgICBvbk5leHQ6ICh2YWx1ZTogQXBvbGxvUXVlcnlSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+PikgPT4gdm9pZCxcbiAgICBvbkVycm9yPzogKGVycm9yOiBhbnkpID0+IHZvaWQsXG4gICAgb25Db21wbGV0ZT86ICgpID0+IHZvaWRcbiAgKTogT2JzZXJ2YWJsZVN1YnNjcmlwdGlvbjtcblxuICBwdWJsaWMgcmVzdWJzY3JpYmVBZnRlckVycm9yKFxuICAgIG9ic2VydmVyOiBPYnNlcnZlcjxBcG9sbG9RdWVyeVJlc3VsdDxURGF0YT4+XG4gICk6IE9ic2VydmFibGVTdWJzY3JpcHRpb247XG5cbiAgcHVibGljIHJlc3Vic2NyaWJlQWZ0ZXJFcnJvciguLi5hcmdzOiBbYW55LCBhbnk/LCBhbnk/XSkge1xuICAgIC8vIElmIGBsYXN0RXJyb3JgIGlzIHNldCBpbiB0aGUgY3VycmVudCB3aGVuIHRoZSBzdWJzY3JpcHRpb24gaXMgcmUtY3JlYXRlZCxcbiAgICAvLyB0aGUgc3Vic2NyaXB0aW9uIHdpbGwgaW1tZWRpYXRlbHkgcmVjZWl2ZSB0aGUgZXJyb3IsIHdoaWNoIHdpbGxcbiAgICAvLyBjYXVzZSBpdCB0byB0ZXJtaW5hdGUgYWdhaW4uIFRvIGF2b2lkIHRoaXMsIHdlIGZpcnN0IGNsZWFyXG4gICAgLy8gdGhlIGxhc3QgZXJyb3IvcmVzdWx0IGZyb20gdGhlIGBvYnNlcnZhYmxlUXVlcnlgIGJlZm9yZSByZS1zdGFydGluZ1xuICAgIC8vIHRoZSBzdWJzY3JpcHRpb24sIGFuZCByZXN0b3JlIHRoZSBsYXN0IHZhbHVlIGFmdGVyd2FyZHMgc28gdGhhdCB0aGVcbiAgICAvLyBzdWJzY3JpcHRpb24gaGFzIGEgY2hhbmNlIHRvIHN0YXkgb3Blbi5cbiAgICBjb25zdCBsYXN0ID0gdGhpcy5sYXN0O1xuICAgIHRoaXMucmVzZXRMYXN0UmVzdWx0cygpO1xuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gdGhpcy5zdWJzY3JpYmUoLi4uYXJncyk7XG4gICAgdGhpcy5sYXN0ID0gbGFzdDtcblxuICAgIHJldHVybiBzdWJzY3JpcHRpb247XG4gIH1cblxuICAvLyAoUmUpZGVsaXZlciB0aGUgY3VycmVudCByZXN1bHQgdG8gdGhpcy5vYnNlcnZlcnMgd2l0aG91dCBhcHBseWluZyBmZXRjaFxuICAvLyBwb2xpY2llcyBvciBtYWtpbmcgbmV0d29yayByZXF1ZXN0cy5cbiAgcHJpdmF0ZSBvYnNlcnZlKCkge1xuICAgIHRoaXMucmVwb3J0UmVzdWx0KFxuICAgICAgLy8gUGFzc2luZyBmYWxzZSBpcyBpbXBvcnRhbnQgc28gdGhhdCB0aGlzLmdldEN1cnJlbnRSZXN1bHQgZG9lc24ndFxuICAgICAgLy8gc2F2ZSB0aGUgZmV0Y2hNb3JlIHJlc3VsdCBhcyB0aGlzLmxhc3RSZXN1bHQsIGNhdXNpbmcgaXQgdG8gYmVcbiAgICAgIC8vIGlnbm9yZWQgZHVlIHRvIHRoZSB0aGlzLmlzRGlmZmVyZW50RnJvbUxhc3RSZXN1bHQgY2hlY2sgaW5cbiAgICAgIC8vIHRoaXMucmVwb3J0UmVzdWx0LlxuICAgICAgdGhpcy5nZXRDdXJyZW50RnVsbFJlc3VsdChmYWxzZSksXG4gICAgICB0aGlzLnZhcmlhYmxlc1xuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlcG9ydFJlc3VsdChcbiAgICByZXN1bHQ6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPixcbiAgICB2YXJpYWJsZXM6IFRWYXJpYWJsZXMgfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgY29uc3QgbGFzdEVycm9yID0gdGhpcy5nZXRMYXN0RXJyb3IoKTtcbiAgICBjb25zdCBpc0RpZmZlcmVudCA9IHRoaXMuaXNEaWZmZXJlbnRGcm9tTGFzdFJlc3VsdChyZXN1bHQsIHZhcmlhYmxlcyk7XG4gICAgLy8gVXBkYXRlIHRoZSBsYXN0IHJlc3VsdCBldmVuIHdoZW4gaXNEaWZmZXJlbnRGcm9tTGFzdFJlc3VsdCByZXR1cm5zIGZhbHNlLFxuICAgIC8vIGJlY2F1c2UgdGhlIHF1ZXJ5IG1heSBiZSB1c2luZyB0aGUgQG5vbnJlYWN0aXZlIGRpcmVjdGl2ZSwgYW5kIHdlIHdhbnQgdG9cbiAgICAvLyBzYXZlIHRoZSB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgYW55IG5vbnJlYWN0aXZlIHN1YnRyZWVzIChpbiBjYXNlXG4gICAgLy8gZ2V0Q3VycmVudFJlc3VsdCBpcyBjYWxsZWQpLCBldmVuIHRob3VnaCB3ZSBza2lwIGJyb2FkY2FzdGluZyBjaGFuZ2VzLlxuICAgIGlmIChsYXN0RXJyb3IgfHwgIXJlc3VsdC5wYXJ0aWFsIHx8IHRoaXMub3B0aW9ucy5yZXR1cm5QYXJ0aWFsRGF0YSkge1xuICAgICAgdGhpcy51cGRhdGVMYXN0UmVzdWx0KHJlc3VsdCwgdmFyaWFibGVzKTtcbiAgICB9XG4gICAgaWYgKGxhc3RFcnJvciB8fCBpc0RpZmZlcmVudCkge1xuICAgICAgaXRlcmF0ZU9ic2VydmVyc1NhZmVseSh0aGlzLm9ic2VydmVycywgXCJuZXh0XCIsIHRoaXMubWFza1Jlc3VsdChyZXN1bHQpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlcG9ydEVycm9yKGVycm9yOiBBcG9sbG9FcnJvciwgdmFyaWFibGVzOiBUVmFyaWFibGVzIHwgdW5kZWZpbmVkKSB7XG4gICAgLy8gU2luY2Ugd2UgZG9uJ3QgZ2V0IHRoZSBjdXJyZW50IHJlc3VsdCBvbiBlcnJvcnMsIG9ubHkgdGhlIGVycm9yLCB3ZVxuICAgIC8vIG11c3QgbWlycm9yIHRoZSB1cGRhdGVzIHRoYXQgb2NjdXIgaW4gUXVlcnlTdG9yZS5tYXJrUXVlcnlFcnJvciBoZXJlXG4gICAgY29uc3QgZXJyb3JSZXN1bHQgPSB7XG4gICAgICAuLi50aGlzLmdldExhc3RSZXN1bHQoKSxcbiAgICAgIGVycm9yLFxuICAgICAgZXJyb3JzOiBlcnJvci5ncmFwaFFMRXJyb3JzLFxuICAgICAgbmV0d29ya1N0YXR1czogTmV0d29ya1N0YXR1cy5lcnJvcixcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgIH0gYXMgQXBvbGxvUXVlcnlSZXN1bHQ8VERhdGE+O1xuXG4gICAgdGhpcy51cGRhdGVMYXN0UmVzdWx0KGVycm9yUmVzdWx0LCB2YXJpYWJsZXMpO1xuXG4gICAgaXRlcmF0ZU9ic2VydmVyc1NhZmVseSh0aGlzLm9ic2VydmVycywgXCJlcnJvclwiLCAodGhpcy5sYXN0IS5lcnJvciA9IGVycm9yKSk7XG4gIH1cblxuICBwdWJsaWMgaGFzT2JzZXJ2ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLm9ic2VydmVycy5zaXplID4gMDtcbiAgfVxuXG4gIHByaXZhdGUgdGVhckRvd25RdWVyeSgpIHtcbiAgICBpZiAodGhpcy5pc1Rvcm5Eb3duKSByZXR1cm47XG4gICAgaWYgKHRoaXMuY29uY2FzdCAmJiB0aGlzLm9ic2VydmVyKSB7XG4gICAgICB0aGlzLmNvbmNhc3QucmVtb3ZlT2JzZXJ2ZXIodGhpcy5vYnNlcnZlcik7XG4gICAgICBkZWxldGUgdGhpcy5jb25jYXN0O1xuICAgICAgZGVsZXRlIHRoaXMub2JzZXJ2ZXI7XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wUG9sbGluZygpO1xuICAgIC8vIHN0b3AgYWxsIGFjdGl2ZSBHcmFwaFFMIHN1YnNjcmlwdGlvbnNcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgoc3ViKSA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmNsZWFyKCk7XG4gICAgdGhpcy5xdWVyeU1hbmFnZXIuc3RvcFF1ZXJ5KHRoaXMucXVlcnlJZCk7XG4gICAgdGhpcy5vYnNlcnZlcnMuY2xlYXIoKTtcbiAgICB0aGlzLmlzVG9ybkRvd24gPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2Zvcm1Eb2N1bWVudChkb2N1bWVudDogRG9jdW1lbnROb2RlKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlNYW5hZ2VyLnRyYW5zZm9ybShkb2N1bWVudCk7XG4gIH1cblxuICBwcml2YXRlIG1hc2tSZXN1bHQ8VCA9IFREYXRhPihcbiAgICByZXN1bHQ6IEFwb2xsb1F1ZXJ5UmVzdWx0PFQ+XG4gICk6IEFwb2xsb1F1ZXJ5UmVzdWx0PE1heWJlTWFza2VkPFQ+PiB7XG4gICAgcmV0dXJuIHJlc3VsdCAmJiBcImRhdGFcIiBpbiByZXN1bHQgP1xuICAgICAgICB7XG4gICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgIGRhdGE6IHRoaXMucXVlcnlNYW5hZ2VyLm1hc2tPcGVyYXRpb24oe1xuICAgICAgICAgICAgZG9jdW1lbnQ6IHRoaXMucXVlcnksXG4gICAgICAgICAgICBkYXRhOiByZXN1bHQuZGF0YSxcbiAgICAgICAgICAgIGZldGNoUG9saWN5OiB0aGlzLm9wdGlvbnMuZmV0Y2hQb2xpY3ksXG4gICAgICAgICAgICBpZDogdGhpcy5xdWVyeUlkLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9XG4gICAgICA6IHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZGlydHk6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIG5vdGlmeVRpbWVvdXQ/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcblxuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCByZXNldE5vdGlmaWNhdGlvbnMoKSB7XG4gICAgdGhpcy5jYW5jZWxOb3RpZnlUaW1lb3V0KCk7XG4gICAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWxOb3RpZnlUaW1lb3V0KCkge1xuICAgIGlmICh0aGlzLm5vdGlmeVRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLm5vdGlmeVRpbWVvdXQpO1xuICAgICAgdGhpcy5ub3RpZnlUaW1lb3V0ID0gdm9pZCAwO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHNjaGVkdWxlTm90aWZ5KCkge1xuICAgIGlmICh0aGlzLmRpcnR5KSByZXR1cm47XG4gICAgdGhpcy5kaXJ0eSA9IHRydWU7XG4gICAgaWYgKCF0aGlzLm5vdGlmeVRpbWVvdXQpIHtcbiAgICAgIHRoaXMubm90aWZ5VGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ub3RpZnkoKSwgMCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgbm90aWZ5KCkge1xuICAgIHRoaXMuY2FuY2VsTm90aWZ5VGltZW91dCgpO1xuXG4gICAgaWYgKHRoaXMuZGlydHkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5vcHRpb25zLmZldGNoUG9saWN5ID09IFwiY2FjaGUtb25seVwiIHx8XG4gICAgICAgIHRoaXMub3B0aW9ucy5mZXRjaFBvbGljeSA9PSBcImNhY2hlLWFuZC1uZXR3b3JrXCIgfHxcbiAgICAgICAgIWlzTmV0d29ya1JlcXVlc3RJbkZsaWdodCh0aGlzLnF1ZXJ5SW5mby5uZXR3b3JrU3RhdHVzKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSB0aGlzLnF1ZXJ5SW5mby5nZXREaWZmKCk7XG4gICAgICAgIGlmIChkaWZmLmZyb21PcHRpbWlzdGljVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgICAvLyBJZiB0aGlzIGRpZmYgY2FtZSBmcm9tIGFuIG9wdGltaXN0aWMgdHJhbnNhY3Rpb24sIGRlbGl2ZXIgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBjYWNoZSBkYXRhIHRvIHRoZSBPYnNlcnZhYmxlUXVlcnksIGJ1dCBkb24ndCBwZXJmb3JtIGFcbiAgICAgICAgICAvLyByZW9ic2VydmF0aW9uLCBzaW5jZSBvcS5yZW9ic2VydmVDYWNoZUZpcnN0IG1pZ2h0IG1ha2UgYSBuZXR3b3JrXG4gICAgICAgICAgLy8gcmVxdWVzdCwgYW5kIHdlIG5ldmVyIHdhbnQgdG8gdHJpZ2dlciBuZXR3b3JrIHJlcXVlc3RzIGluIHRoZVxuICAgICAgICAgIC8vIG1pZGRsZSBvZiBvcHRpbWlzdGljIHVwZGF0ZXMuXG4gICAgICAgICAgdGhpcy5vYnNlcnZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlLCBtYWtlIHRoZSBPYnNlcnZhYmxlUXVlcnkgXCJyZW9ic2VydmVcIiB0aGUgbGF0ZXN0IGRhdGFcbiAgICAgICAgICAvLyB1c2luZyBhIHRlbXBvcmFyeSBmZXRjaCBwb2xpY3kgb2YgXCJjYWNoZS1maXJzdFwiLCBzbyBjb21wbGV0ZSBjYWNoZVxuICAgICAgICAgIC8vIHJlc3VsdHMgaGF2ZSBhIGNoYW5jZSB0byBiZSBkZWxpdmVyZWQgd2l0aG91dCB0cmlnZ2VyaW5nIGFkZGl0aW9uYWxcbiAgICAgICAgICAvLyBuZXR3b3JrIHJlcXVlc3RzLCBldmVuIHdoZW4gb3B0aW9ucy5mZXRjaFBvbGljeSBpcyBcIm5ldHdvcmstb25seVwiXG4gICAgICAgICAgLy8gb3IgXCJjYWNoZS1hbmQtbmV0d29ya1wiLiBBbGwgb3RoZXIgZmV0Y2ggcG9saWNpZXMgYXJlIHByZXNlcnZlZCBieVxuICAgICAgICAgIC8vIHRoaXMgbWV0aG9kLCBhbmQgYXJlIGhhbmRsZWQgYnkgY2FsbGluZyBvcS5yZW9ic2VydmUoKS4gSWYgdGhpc1xuICAgICAgICAgIC8vIHJlb2JzZXJ2YXRpb24gaXMgc3B1cmlvdXMsIGlzRGlmZmVyZW50RnJvbUxhc3RSZXN1bHQgc3RpbGwgaGFzIGFcbiAgICAgICAgICAvLyBjaGFuY2UgdG8gY2F0Y2ggaXQgYmVmb3JlIGRlbGl2ZXJ5IHRvIE9ic2VydmFibGVRdWVyeSBzdWJzY3JpYmVycy5cbiAgICAgICAgICB0aGlzLnJlb2JzZXJ2ZUNhY2hlRmlyc3QoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIFJlb2JzZXJ2ZSB3aXRoIGZldGNoUG9saWN5IGVmZmVjdGl2ZWx5IHNldCB0byBcImNhY2hlLWZpcnN0XCIsIHRyaWdnZXJpbmdcbiAgLy8gZGVsaXZlcnkgb2YgYW55IG5ldyBkYXRhIGZyb20gdGhlIGNhY2hlLCBwb3NzaWJseSBmYWxsaW5nIGJhY2sgdG8gdGhlIG5ldHdvcmtcbiAgLy8gaWYgYW55IGNhY2hlIGRhdGEgYXJlIG1pc3NpbmcuIFRoaXMgYWxsb3dzIF9jb21wbGV0ZV8gY2FjaGUgcmVzdWx0cyB0byBiZVxuICAvLyBkZWxpdmVyZWQgd2l0aG91dCBhbHNvIGtpY2tpbmcgb2ZmIHVubmVjZXNzYXJ5IG5ldHdvcmsgcmVxdWVzdHMgd2hlblxuICAvLyB0aGlzLm9wdGlvbnMuZmV0Y2hQb2xpY3kgaXMgXCJjYWNoZS1hbmQtbmV0d29ya1wiIG9yIFwibmV0d29yay1vbmx5XCIuIFdoZW5cbiAgLy8gdGhpcy5vcHRpb25zLmZldGNoUG9saWN5IGlzIGFueSBvdGhlciBwb2xpY3kgKFwiY2FjaGUtZmlyc3RcIiwgXCJjYWNoZS1vbmx5XCIsXG4gIC8vIFwic3RhbmRieVwiLCBvciBcIm5vLWNhY2hlXCIpLCB3ZSBjYWxsIHRoaXMucmVvYnNlcnZlKCkgYXMgdXN1YWwuXG4gIHByaXZhdGUgcmVvYnNlcnZlQ2FjaGVGaXJzdCgpIHtcbiAgICBjb25zdCB7IGZldGNoUG9saWN5LCBuZXh0RmV0Y2hQb2xpY3kgfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmIChmZXRjaFBvbGljeSA9PT0gXCJjYWNoZS1hbmQtbmV0d29ya1wiIHx8IGZldGNoUG9saWN5ID09PSBcIm5ldHdvcmstb25seVwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZW9ic2VydmUoe1xuICAgICAgICBmZXRjaFBvbGljeTogXCJjYWNoZS1maXJzdFwiLFxuICAgICAgICAvLyBVc2UgYSB0ZW1wb3JhcnkgbmV4dEZldGNoUG9saWN5IGZ1bmN0aW9uIHRoYXQgcmVwbGFjZXMgaXRzZWxmIHdpdGggdGhlXG4gICAgICAgIC8vIHByZXZpb3VzIG5leHRGZXRjaFBvbGljeSB2YWx1ZSBhbmQgcmV0dXJucyB0aGUgb3JpZ2luYWwgZmV0Y2hQb2xpY3kuXG4gICAgICAgIG5leHRGZXRjaFBvbGljeShcbiAgICAgICAgICB0aGlzOiBXYXRjaFF1ZXJ5T3B0aW9uczxUVmFyaWFibGVzLCBURGF0YT4sXG4gICAgICAgICAgY3VycmVudEZldGNoUG9saWN5OiBXYXRjaFF1ZXJ5RmV0Y2hQb2xpY3ksXG4gICAgICAgICAgY29udGV4dDogTmV4dEZldGNoUG9saWN5Q29udGV4dDxURGF0YSwgVFZhcmlhYmxlcz5cbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gUmVwbGFjZSB0aGlzIG5leHRGZXRjaFBvbGljeSBmdW5jdGlvbiBpbiB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGVcbiAgICAgICAgICAvLyBvcmlnaW5hbCB0aGlzLm9wdGlvbnMubmV4dEZldGNoUG9saWN5IHZhbHVlLlxuICAgICAgICAgIHRoaXMubmV4dEZldGNoUG9saWN5ID0gbmV4dEZldGNoUG9saWN5O1xuICAgICAgICAgIC8vIElmIHRoZSBvcmlnaW5hbCBuZXh0RmV0Y2hQb2xpY3kgdmFsdWUgd2FzIGEgZnVuY3Rpb24sIGdpdmUgaXQgYVxuICAgICAgICAgIC8vIGNoYW5jZSB0byBkZWNpZGUgd2hhdCBoYXBwZW5zIGhlcmUuXG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm5leHRGZXRjaFBvbGljeSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5uZXh0RmV0Y2hQb2xpY3koY3VycmVudEZldGNoUG9saWN5LCBjb250ZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIGdvIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHRoaXMub3B0aW9ucy5mZXRjaFBvbGljeS5cbiAgICAgICAgICByZXR1cm4gZmV0Y2hQb2xpY3khO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVvYnNlcnZlKCk7XG4gIH1cbn1cblxuLy8gTmVjZXNzYXJ5IGJlY2F1c2UgdGhlIE9ic2VydmFibGVRdWVyeSBjb25zdHJ1Y3RvciBoYXMgYSBkaWZmZXJlbnRcbi8vIHNpZ25hdHVyZSB0aGFuIHRoZSBPYnNlcnZhYmxlIGNvbnN0cnVjdG9yLlxuZml4T2JzZXJ2YWJsZVN1YmNsYXNzKE9ic2VydmFibGVRdWVyeSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTdWJzY3JpcHRpb25PYnNlcnZlckVycm9yQ2FsbGJhY2soZXJyb3I6IEFwb2xsb0Vycm9yKSB7XG4gIGludmFyaWFudC5lcnJvcihcIlVuaGFuZGxlZCBlcnJvclwiLCBlcnJvci5tZXNzYWdlLCBlcnJvci5zdGFjayk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dNaXNzaW5nRmllbGRFcnJvcnMoXG4gIG1pc3Npbmc6IE1pc3NpbmdGaWVsZEVycm9yW10gfCBNaXNzaW5nVHJlZSB8IHVuZGVmaW5lZFxuKSB7XG4gIGlmIChfX0RFVl9fICYmIG1pc3NpbmcpIHtcbiAgICBpbnZhcmlhbnQuZGVidWcoYE1pc3NpbmcgY2FjaGUgcmVzdWx0IGZpZWxkczogJW9gLCBtaXNzaW5nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBza2lwQ2FjaGVEYXRhRm9yKFxuICBmZXRjaFBvbGljeT86IFdhdGNoUXVlcnlGZXRjaFBvbGljeSAvKiBgdW5kZWZpbmVkYCB3b3VsZCBtZWFuIGBcImNhY2hlLWZpcnN0XCJgICovXG4pIHtcbiAgcmV0dXJuIChcbiAgICBmZXRjaFBvbGljeSA9PT0gXCJuZXR3b3JrLW9ubHlcIiB8fFxuICAgIGZldGNoUG9saWN5ID09PSBcIm5vLWNhY2hlXCIgfHxcbiAgICBmZXRjaFBvbGljeSA9PT0gXCJzdGFuZGJ5XCJcbiAgKTtcbn1cbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF19