import { __assign } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { equal } from "/_nuxt/node_modules/@wry/equality/lib/index.js?v=e4f18c29"; import { DeepMerger } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { mergeIncrementalData } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { isNonEmptyArray, graphQLResultHasError, canUseWeakMap, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { NetworkStatus } from "/_nuxt/node_modules/@apollo/client/core/networkStatus.js?v=e4f18c29"; var destructiveMethodCounts = new (canUseWeakMap ? WeakMap : Map)(); function wrapDestructiveCacheMethod(cache, methodName) { var original = cache[methodName]; if (typeof original === "function") { // @ts-expect-error this is just too generic to be typed correctly cache[methodName] = function () { destructiveMethodCounts.set(cache, // The %1e15 allows the count to wrap around to 0 safely every // quadrillion evictions, so there's no risk of overflow. To be // clear, this is more of a pedantic principle than something // that matters in any conceivable practical scenario. (destructiveMethodCounts.get(cache) + 1) % 1e15); // @ts-expect-error this is just too generic to be typed correctly return original.apply(this, arguments); }; } } // A QueryInfo object represents a single query managed by the // QueryManager, which tracks all QueryInfo objects by queryId in its // this.queries Map. QueryInfo objects store the latest results and errors // for the given query, and are responsible for reporting those results to // the corresponding ObservableQuery, via the QueryInfo.notify method. // Results are reported asynchronously whenever setDiff marks the // QueryInfo object as dirty, though a call to the QueryManager's // broadcastQueries method may trigger the notification before it happens // automatically. This class used to be a simple interface type without // any field privacy or meaningful methods, which is why it still has so // many public fields. The effort to lock down and simplify the QueryInfo // interface is ongoing, and further improvements are welcome. var QueryInfo = /** @class */ (function () { function QueryInfo(queryManager, queryId) { if (queryId === void 0) { queryId = queryManager.generateQueryId(); } this.queryId = queryId; this.document = null; this.lastRequestId = 1; this.stopped = false; this.observableQuery = null; var cache = (this.cache = queryManager.cache); // Track how often cache.evict is called, since we want eviction to // override the feud-stopping logic in the markResult method, by // causing shouldWrite to return true. Wrapping the cache.evict method // is a bit of a hack, but it saves us from having to make eviction // counting an official part of the ApolloCache API. if (!destructiveMethodCounts.has(cache)) { destructiveMethodCounts.set(cache, 0); wrapDestructiveCacheMethod(cache, "evict"); wrapDestructiveCacheMethod(cache, "modify"); wrapDestructiveCacheMethod(cache, "reset"); } } QueryInfo.prototype.init = function (query) { var networkStatus = query.networkStatus || NetworkStatus.loading; if (this.variables && this.networkStatus !== NetworkStatus.loading && !equal(this.variables, query.variables)) { networkStatus = NetworkStatus.setVariables; } if (!equal(query.variables, this.variables)) { this.lastDiff = void 0; // Ensure we don't continue to receive cache updates for old variables this.cancel(); } Object.assign(this, { document: query.document, variables: query.variables, networkError: null, graphQLErrors: this.graphQLErrors || [], networkStatus: networkStatus, }); if (query.observableQuery) { this.setObservableQuery(query.observableQuery); } if (query.lastRequestId) { this.lastRequestId = query.lastRequestId; } return this; }; QueryInfo.prototype.resetDiff = function () { this.lastDiff = void 0; }; QueryInfo.prototype.getDiff = function () { var options = this.getDiffOptions(); if (this.lastDiff && equal(options, this.lastDiff.options)) { return this.lastDiff.diff; } this.updateWatch(this.variables); var oq = this.observableQuery; if (oq && oq.options.fetchPolicy === "no-cache") { return { complete: false }; } var diff = this.cache.diff(options); this.updateLastDiff(diff, options); return diff; }; QueryInfo.prototype.updateLastDiff = function (diff, options) { this.lastDiff = diff ? { diff: diff, options: options || this.getDiffOptions(), } : void 0; }; QueryInfo.prototype.getDiffOptions = function (variables) { var _a; if (variables === void 0) { variables = this.variables; } return { query: this.document, variables: variables, returnPartialData: true, optimistic: true, canonizeResults: (_a = this.observableQuery) === null || _a === void 0 ? void 0 : _a.options.canonizeResults, }; }; QueryInfo.prototype.setDiff = function (diff) { var _a, _b; var oldDiff = this.lastDiff && this.lastDiff.diff; // If we are trying to deliver an incomplete cache result, we avoid // reporting it if the query has errored, otherwise we let the broadcast try // and repair the partial result by refetching the query. This check avoids // a situation where a query that errors and another succeeds with // overlapping data does not report the partial data result to the errored // query. // // See https://github.com/apollographql/apollo-client/issues/11400 for more // information on this issue. if (diff && !diff.complete && ((_a = this.observableQuery) === null || _a === void 0 ? void 0 : _a.getLastError())) { return; } this.updateLastDiff(diff); if (!equal(oldDiff && oldDiff.result, diff && diff.result)) { (_b = this.observableQuery) === null || _b === void 0 ? void 0 : _b["scheduleNotify"](); } }; QueryInfo.prototype.setObservableQuery = function (oq) { if (oq === this.observableQuery) return; this.observableQuery = oq; if (oq) { oq["queryInfo"] = this; } }; QueryInfo.prototype.stop = function () { var _a; if (!this.stopped) { this.stopped = true; // Cancel the pending notify timeout (_a = this.observableQuery) === null || _a === void 0 ? void 0 : _a["resetNotifications"](); this.cancel(); var oq = this.observableQuery; if (oq) oq.stopPolling(); } }; QueryInfo.prototype.cancel = function () { var _a; (_a = this.cancelWatch) === null || _a === void 0 ? void 0 : _a.call(this); this.cancelWatch = void 0; }; QueryInfo.prototype.updateWatch = function (variables) { var _this = this; if (variables === void 0) { variables = this.variables; } var oq = this.observableQuery; if (oq && oq.options.fetchPolicy === "no-cache") { return; } var watchOptions = __assign(__assign({}, this.getDiffOptions(variables)), { watcher: this, callback: function (diff) { return _this.setDiff(diff); } }); if (!this.lastWatch || !equal(watchOptions, this.lastWatch)) { this.cancel(); this.cancelWatch = this.cache.watch((this.lastWatch = watchOptions)); } }; QueryInfo.prototype.resetLastWrite = function () { this.lastWrite = void 0; }; QueryInfo.prototype.shouldWrite = function (result, variables) { var lastWrite = this.lastWrite; return !(lastWrite && // If cache.evict has been called since the last time we wrote this // data into the cache, there's a chance writing this result into // the cache will repair what was evicted. lastWrite.dmCount === destructiveMethodCounts.get(this.cache) && equal(variables, lastWrite.variables) && equal(result.data, lastWrite.result.data)); }; QueryInfo.prototype.markResult = function (result, document, options, cacheWriteBehavior) { var _this = this; var _a; var merger = new DeepMerger(); var graphQLErrors = isNonEmptyArray(result.errors) ? result.errors.slice(0) : []; // Cancel the pending notify timeout (if it exists) to prevent extraneous network // requests. To allow future notify timeouts, diff and dirty are reset as well. (_a = this.observableQuery) === null || _a === void 0 ? void 0 : _a["resetNotifications"](); if ("incremental" in result && isNonEmptyArray(result.incremental)) { var mergedData = mergeIncrementalData(this.getDiff().result, result); result.data = mergedData; // Detect the first chunk of a deferred query and merge it with existing // cache data. This ensures a `cache-first` fetch policy that returns // partial cache data or a `cache-and-network` fetch policy that already // has full data in the cache does not complain when trying to merge the // initial deferred server data with existing cache data. } else if ("hasNext" in result && result.hasNext) { var diff = this.getDiff(); result.data = merger.merge(diff.result, result.data); } this.graphQLErrors = graphQLErrors; if (options.fetchPolicy === "no-cache") { this.updateLastDiff({ result: result.data, complete: true }, this.getDiffOptions(options.variables)); } else if (cacheWriteBehavior !== 0 /* CacheWriteBehavior.FORBID */) { if (shouldWriteResult(result, options.errorPolicy)) { // Using a transaction here so we have a chance to read the result // back from the cache before the watch callback fires as a result // of writeQuery, so we can store the new diff quietly and ignore // it when we receive it redundantly from the watch callback. this.cache.performTransaction(function (cache) { if (_this.shouldWrite(result, options.variables)) { cache.writeQuery({ query: document, data: result.data, variables: options.variables, overwrite: cacheWriteBehavior === 1 /* CacheWriteBehavior.OVERWRITE */, }); _this.lastWrite = { result: result, variables: options.variables, dmCount: destructiveMethodCounts.get(_this.cache), }; } else { // If result is the same as the last result we received from // the network (and the variables match too), avoid writing // result into the cache again. The wisdom of skipping this // cache write is far from obvious, since any cache write // could be the one that puts the cache back into a desired // state, fixing corruption or missing data. However, if we // always write every network result into the cache, we enable // feuds between queries competing to update the same data in // incompatible ways, which can lead to an endless cycle of // cache broadcasts and useless network requests. As with any // feud, eventually one side must step back from the brink, // letting the other side(s) have the last word(s). There may // be other points where we could break this cycle, such as // silencing the broadcast for cache.writeQuery (not a good // idea, since it just delays the feud a bit) or somehow // avoiding the network request that just happened (also bad, // because the server could return useful new data). All // options considered, skipping this cache write seems to be // the least damaging place to break the cycle, because it // reflects the intuition that we recently wrote this exact // result into the cache, so the cache *should* already/still // contain this data. If some other query has clobbered that // data in the meantime, that's too bad, but there will be no // winners if every query blindly reverts to its own version // of the data. This approach also gives the network a chance // to return new data, which will be written into the cache as // usual, notifying only those queries that are directly // affected by the cache updates, as usual. In the future, an // even more sophisticated cache could perhaps prevent or // mitigate the clobbering somehow, but that would make this // particular cache write even less important, and thus // skipping it would be even safer than it is today. if (_this.lastDiff && _this.lastDiff.diff.complete) { // Reuse data from the last good (complete) diff that we // received, when possible. result.data = _this.lastDiff.diff.result; return; } // If the previous this.diff was incomplete, fall through to // re-reading the latest data with cache.diff, below. } var diffOptions = _this.getDiffOptions(options.variables); var diff = cache.diff(diffOptions); // In case the QueryManager stops this QueryInfo before its // results are delivered, it's important to avoid restarting the // cache watch when markResult is called. We also avoid updating // the watch if we are writing a result that doesn't match the current // variables to avoid race conditions from broadcasting the wrong // result. if (!_this.stopped && equal(_this.variables, options.variables)) { // Any time we're about to update this.diff, we need to make // sure we've started watching the cache. _this.updateWatch(options.variables); } // If we're allowed to write to the cache, and we can read a // complete result from the cache, update result.data to be the // result from the cache, rather than the raw network result. // Set without setDiff to avoid triggering a notify call, since // we have other ways of notifying for this result. _this.updateLastDiff(diff, diffOptions); if (diff.complete) { result.data = diff.result; } }); } else { this.lastWrite = void 0; } } }; QueryInfo.prototype.markReady = function () { this.networkError = null; return (this.networkStatus = NetworkStatus.ready); }; QueryInfo.prototype.markError = function (error) { var _a; this.networkStatus = NetworkStatus.error; this.lastWrite = void 0; (_a = this.observableQuery) === null || _a === void 0 ? void 0 : _a["resetNotifications"](); if (error.graphQLErrors) { this.graphQLErrors = error.graphQLErrors; } if (error.networkError) { this.networkError = error.networkError; } return error; }; return QueryInfo; }()); export { QueryInfo }; export function shouldWriteResult(result, errorPolicy) { if (errorPolicy === void 0) { errorPolicy = "none"; } var ignoreErrors = errorPolicy === "ignore" || errorPolicy === "all"; var writeWithErrors = !graphQLResultHasError(result); if (!writeWithErrors && ignoreErrors && result.data) { writeWithErrors = true; } return writeWithErrors; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlJbmZvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvUXVlcnlJbmZvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3RDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUk3RCxPQUFPLEVBQ0wsZUFBZSxFQUNmLHFCQUFxQixFQUNyQixhQUFhLEdBQ2QsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFnQm5ELElBQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFHaEUsQ0FBQztBQUVKLFNBQVMsMEJBQTBCLENBQ2pDLEtBQXVCLEVBQ3ZCLFVBQXdDO0lBRXhDLElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuQyxJQUFJLE9BQU8sUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ25DLGtFQUFrRTtRQUNsRSxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUc7WUFDbEIsdUJBQXVCLENBQUMsR0FBRyxDQUN6QixLQUFLO1lBQ0wsOERBQThEO1lBQzlELCtEQUErRDtZQUMvRCw2REFBNkQ7WUFDN0Qsc0RBQXNEO1lBQ3RELENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FDakQsQ0FBQztZQUNGLGtFQUFrRTtZQUNsRSxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsOERBQThE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LE1BQUEsSUFBSSxDQUFDLGVBQWUsMENBQUcsb0JBQW9CLEdBQUcsQ0FBQztRQUUvQyxJQUFJLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUM7UUFDM0MsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUN6QyxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0gsZ0JBQUM7QUFBRCxDQUFDLEFBMVhELElBMFhDOztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsTUFBc0IsRUFDdEIsV0FBaUM7SUFBakMsNEJBQUEsRUFBQSxvQkFBaUM7SUFFakMsSUFBTSxZQUFZLEdBQUcsV0FBVyxLQUFLLFFBQVEsSUFBSSxXQUFXLEtBQUssS0FBSyxDQUFDO0lBQ3ZFLElBQUksZUFBZSxHQUFHLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckQsSUFBSSxDQUFDLGVBQWUsSUFBSSxZQUFZLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3BELGVBQWUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUNELE9BQU8sZUFBZSxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IERvY3VtZW50Tm9kZSwgR3JhcGhRTEZvcm1hdHRlZEVycm9yIH0gZnJvbSBcImdyYXBocWxcIjtcbmltcG9ydCB7IGVxdWFsIH0gZnJvbSBcIkB3cnkvZXF1YWxpdHlcIjtcblxuaW1wb3J0IHR5cGUgeyBDYWNoZSwgQXBvbGxvQ2FjaGUgfSBmcm9tIFwiLi4vY2FjaGUvaW5kZXguanNcIjtcbmltcG9ydCB7IERlZXBNZXJnZXIgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBtZXJnZUluY3JlbWVudGFsRGF0YSB9IGZyb20gXCIuLi91dGlsaXRpZXMvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgV2F0Y2hRdWVyeU9wdGlvbnMsIEVycm9yUG9saWN5IH0gZnJvbSBcIi4vd2F0Y2hRdWVyeU9wdGlvbnMuanNcIjtcbmltcG9ydCB0eXBlIHsgT2JzZXJ2YWJsZVF1ZXJ5IH0gZnJvbSBcIi4vT2JzZXJ2YWJsZVF1ZXJ5LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEZldGNoUmVzdWx0IH0gZnJvbSBcIi4uL2xpbmsvY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHtcbiAgaXNOb25FbXB0eUFycmF5LFxuICBncmFwaFFMUmVzdWx0SGFzRXJyb3IsXG4gIGNhblVzZVdlYWtNYXAsXG59IGZyb20gXCIuLi91dGlsaXRpZXMvaW5kZXguanNcIjtcbmltcG9ydCB7IE5ldHdvcmtTdGF0dXMgfSBmcm9tIFwiLi9uZXR3b3JrU3RhdHVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEFwb2xsb0Vycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBRdWVyeU1hbmFnZXIgfSBmcm9tIFwiLi9RdWVyeU1hbmFnZXIuanNcIjtcbmltcG9ydCB0eXBlIHsgVW5tYXNrZWQgfSBmcm9tIFwiLi4vbWFza2luZy9pbmRleC5qc1wiO1xuXG5leHBvcnQgdHlwZSBRdWVyeVN0b3JlVmFsdWUgPSBQaWNrPFxuICBRdWVyeUluZm8sXG4gIFwidmFyaWFibGVzXCIgfCBcIm5ldHdvcmtTdGF0dXNcIiB8IFwibmV0d29ya0Vycm9yXCIgfCBcImdyYXBoUUxFcnJvcnNcIlxuPjtcblxuZXhwb3J0IGNvbnN0IGVudW0gQ2FjaGVXcml0ZUJlaGF2aW9yIHtcbiAgRk9SQklELFxuICBPVkVSV1JJVEUsXG4gIE1FUkdFLFxufVxuXG5jb25zdCBkZXN0cnVjdGl2ZU1ldGhvZENvdW50cyA9IG5ldyAoY2FuVXNlV2Vha01hcCA/IFdlYWtNYXAgOiBNYXApPFxuICBBcG9sbG9DYWNoZTxhbnk+LFxuICBudW1iZXJcbj4oKTtcblxuZnVuY3Rpb24gd3JhcERlc3RydWN0aXZlQ2FjaGVNZXRob2QoXG4gIGNhY2hlOiBBcG9sbG9DYWNoZTxhbnk+LFxuICBtZXRob2ROYW1lOiBcImV2aWN0XCIgfCBcIm1vZGlmeVwiIHwgXCJyZXNldFwiXG4pIHtcbiAgY29uc3Qgb3JpZ2luYWwgPSBjYWNoZVttZXRob2ROYW1lXTtcbiAgaWYgKHR5cGVvZiBvcmlnaW5hbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGlzIGlzIGp1c3QgdG9vIGdlbmVyaWMgdG8gYmUgdHlwZWQgY29ycmVjdGx5XG4gICAgY2FjaGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXN0cnVjdGl2ZU1ldGhvZENvdW50cy5zZXQoXG4gICAgICAgIGNhY2hlLFxuICAgICAgICAvLyBUaGUgJTFlMTUgYWxsb3dzIHRoZSBjb3VudCB0byB3cmFwIGFyb3VuZCB0byAwIHNhZmVseSBldmVyeVxuICAgICAgICAvLyBxdWFkcmlsbGlvbiBldmljdGlvbnMsIHNvIHRoZXJlJ3Mgbm8gcmlzayBvZiBvdmVyZmxvdy4gVG8gYmVcbiAgICAgICAgLy8gY2xlYXIsIHRoaXMgaXMgbW9yZSBvZiBhIHBlZGFudGljIHByaW5jaXBsZSB0aGFuIHNvbWV0aGluZ1xuICAgICAgICAvLyB0aGF0IG1hdHRlcnMgaW4gYW55IGNvbmNlaXZhYmxlIHByYWN0aWNhbCBzY2VuYXJpby5cbiAgICAgICAgKGRlc3RydWN0aXZlTWV0aG9kQ291bnRzLmdldChjYWNoZSkhICsgMSkgJSAxZTE1XG4gICAgICApO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0aGlzIGlzIGp1c3QgdG9vIGdlbmVyaWMgdG8gYmUgdHlwZWQgY29ycmVjdGx5XG4gICAgICByZXR1cm4gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG59XG5cbi8vIEEgUXVlcnlJbmZvIG9iamVjdCByZXByZXNlbnRzIGEgc2luZ2xlIHF1ZXJ5IG1hbmFnZWQgYnkgdGhlXG4vLyBRdWVyeU1hbmFnZXIsIHdoaWNoIHRyYWNrcyBhbGwgUXVlcnlJbmZvIG9iamVjdHMgYnkgcXVlcnlJZCBpbiBpdHNcbi8vIHRoaXMucXVlcmllcyBNYXAuIFF1ZXJ5SW5mbyBvYmplY3RzIHN0b3JlIHRoZSBsYXRlc3QgcmVzdWx0cyBhbmQgZXJyb3JzXG4vLyBmb3IgdGhlIGdpdmVuIHF1ZXJ5LCBhbmQgYXJlIHJlc3BvbnNpYmxlIGZvciByZXBvcnRpbmcgdGhvc2UgcmVzdWx0cyB0b1xuLy8gdGhlIGNvcnJlc3BvbmRpbmcgT2JzZXJ2YWJsZVF1ZXJ5LCB2aWEgdGhlIFF1ZXJ5SW5mby5ub3RpZnkgbWV0aG9kLlxuLy8gUmVzdWx0cyBhcmUgcmVwb3J0ZWQgYXN5bmNocm9ub3VzbHkgd2hlbmV2ZXIgc2V0RGlmZiBtYXJrcyB0aGVcbi8vIFF1ZXJ5SW5mbyBvYmplY3QgYXMgZGlydHksIHRob3VnaCBhIGNhbGwgdG8gdGhlIFF1ZXJ5TWFuYWdlcidzXG4vLyBicm9hZGNhc3RRdWVyaWVzIG1ldGhvZCBtYXkgdHJpZ2dlciB0aGUgbm90aWZpY2F0aW9uIGJlZm9yZSBpdCBoYXBwZW5zXG4vLyBhdXRvbWF0aWNhbGx5LiBUaGlzIGNsYXNzIHVzZWQgdG8gYmUgYSBzaW1wbGUgaW50ZXJmYWNlIHR5cGUgd2l0aG91dFxuLy8gYW55IGZpZWxkIHByaXZhY3kgb3IgbWVhbmluZ2Z1bCBtZXRob2RzLCB3aGljaCBpcyB3aHkgaXQgc3RpbGwgaGFzIHNvXG4vLyBtYW55IHB1YmxpYyBmaWVsZHMuIFRoZSBlZmZvcnQgdG8gbG9jayBkb3duIGFuZCBzaW1wbGlmeSB0aGUgUXVlcnlJbmZvXG4vLyBpbnRlcmZhY2UgaXMgb25nb2luZywgYW5kIGZ1cnRoZXIgaW1wcm92ZW1lbnRzIGFyZSB3ZWxjb21lLlxuZXhwb3J0IGNsYXNzIFF1ZXJ5SW5mbyB7XG4gIGRvY3VtZW50OiBEb2N1bWVudE5vZGUgfCBudWxsID0gbnVsbDtcbiAgbGFzdFJlcXVlc3RJZCA9IDE7XG4gIHZhcmlhYmxlcz86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIG5ldHdvcmtTdGF0dXM/OiBOZXR3b3JrU3RhdHVzO1xuICBuZXR3b3JrRXJyb3I/OiBFcnJvciB8IG51bGw7XG4gIGdyYXBoUUxFcnJvcnM/OiBSZWFkb25seUFycmF5PEdyYXBoUUxGb3JtYXR0ZWRFcnJvcj47XG4gIHN0b3BwZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGNhbmNlbFdhdGNoPzogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBjYWNoZTogQXBvbGxvQ2FjaGU8YW55PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBxdWVyeU1hbmFnZXI6IFF1ZXJ5TWFuYWdlcjxhbnk+LFxuICAgIHB1YmxpYyByZWFkb25seSBxdWVyeUlkID0gcXVlcnlNYW5hZ2VyLmdlbmVyYXRlUXVlcnlJZCgpXG4gICkge1xuICAgIGNvbnN0IGNhY2hlID0gKHRoaXMuY2FjaGUgPSBxdWVyeU1hbmFnZXIuY2FjaGUpO1xuXG4gICAgLy8gVHJhY2sgaG93IG9mdGVuIGNhY2hlLmV2aWN0IGlzIGNhbGxlZCwgc2luY2Ugd2Ugd2FudCBldmljdGlvbiB0b1xuICAgIC8vIG92ZXJyaWRlIHRoZSBmZXVkLXN0b3BwaW5nIGxvZ2ljIGluIHRoZSBtYXJrUmVzdWx0IG1ldGhvZCwgYnlcbiAgICAvLyBjYXVzaW5nIHNob3VsZFdyaXRlIHRvIHJldHVybiB0cnVlLiBXcmFwcGluZyB0aGUgY2FjaGUuZXZpY3QgbWV0aG9kXG4gICAgLy8gaXMgYSBiaXQgb2YgYSBoYWNrLCBidXQgaXQgc2F2ZXMgdXMgZnJvbSBoYXZpbmcgdG8gbWFrZSBldmljdGlvblxuICAgIC8vIGNvdW50aW5nIGFuIG9mZmljaWFsIHBhcnQgb2YgdGhlIEFwb2xsb0NhY2hlIEFQSS5cbiAgICBpZiAoIWRlc3RydWN0aXZlTWV0aG9kQ291bnRzLmhhcyhjYWNoZSkpIHtcbiAgICAgIGRlc3RydWN0aXZlTWV0aG9kQ291bnRzLnNldChjYWNoZSwgMCk7XG4gICAgICB3cmFwRGVzdHJ1Y3RpdmVDYWNoZU1ldGhvZChjYWNoZSwgXCJldmljdFwiKTtcbiAgICAgIHdyYXBEZXN0cnVjdGl2ZUNhY2hlTWV0aG9kKGNhY2hlLCBcIm1vZGlmeVwiKTtcbiAgICAgIHdyYXBEZXN0cnVjdGl2ZUNhY2hlTWV0aG9kKGNhY2hlLCBcInJlc2V0XCIpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBpbml0KHF1ZXJ5OiB7XG4gICAgZG9jdW1lbnQ6IERvY3VtZW50Tm9kZTtcbiAgICB2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQ7XG4gICAgLy8gVGhlIGluaXRpYWwgbmV0d29ya1N0YXR1cyBmb3IgdGhpcyBmZXRjaCwgbW9zdCBvZnRlblxuICAgIC8vIE5ldHdvcmtTdGF0dXMubG9hZGluZywgYnV0IGFsc28gcG9zc2libHkgZmV0Y2hNb3JlLCBwb2xsLCByZWZldGNoLFxuICAgIC8vIG9yIHNldFZhcmlhYmxlcy5cbiAgICBuZXR3b3JrU3RhdHVzPzogTmV0d29ya1N0YXR1cztcbiAgICBvYnNlcnZhYmxlUXVlcnk/OiBPYnNlcnZhYmxlUXVlcnk8YW55LCBhbnk+O1xuICAgIGxhc3RSZXF1ZXN0SWQ/OiBudW1iZXI7XG4gIH0pOiB0aGlzIHtcbiAgICBsZXQgbmV0d29ya1N0YXR1cyA9IHF1ZXJ5Lm5ldHdvcmtTdGF0dXMgfHwgTmV0d29ya1N0YXR1cy5sb2FkaW5nO1xuICAgIGlmIChcbiAgICAgIHRoaXMudmFyaWFibGVzICYmXG4gICAgICB0aGlzLm5ldHdvcmtTdGF0dXMgIT09IE5ldHdvcmtTdGF0dXMubG9hZGluZyAmJlxuICAgICAgIWVxdWFsKHRoaXMudmFyaWFibGVzLCBxdWVyeS52YXJpYWJsZXMpXG4gICAgKSB7XG4gICAgICBuZXR3b3JrU3RhdHVzID0gTmV0d29ya1N0YXR1cy5zZXRWYXJpYWJsZXM7XG4gICAgfVxuXG4gICAgaWYgKCFlcXVhbChxdWVyeS52YXJpYWJsZXMsIHRoaXMudmFyaWFibGVzKSkge1xuICAgICAgdGhpcy5sYXN0RGlmZiA9IHZvaWQgMDtcbiAgICAgIC8vIEVuc3VyZSB3ZSBkb24ndCBjb250aW51ZSB0byByZWNlaXZlIGNhY2hlIHVwZGF0ZXMgZm9yIG9sZCB2YXJpYWJsZXNcbiAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCB7XG4gICAgICBkb2N1bWVudDogcXVlcnkuZG9jdW1lbnQsXG4gICAgICB2YXJpYWJsZXM6IHF1ZXJ5LnZhcmlhYmxlcyxcbiAgICAgIG5ldHdvcmtFcnJvcjogbnVsbCxcbiAgICAgIGdyYXBoUUxFcnJvcnM6IHRoaXMuZ3JhcGhRTEVycm9ycyB8fCBbXSxcbiAgICAgIG5ldHdvcmtTdGF0dXMsXG4gICAgfSk7XG5cbiAgICBpZiAocXVlcnkub2JzZXJ2YWJsZVF1ZXJ5KSB7XG4gICAgICB0aGlzLnNldE9ic2VydmFibGVRdWVyeShxdWVyeS5vYnNlcnZhYmxlUXVlcnkpO1xuICAgIH1cblxuICAgIGlmIChxdWVyeS5sYXN0UmVxdWVzdElkKSB7XG4gICAgICB0aGlzLmxhc3RSZXF1ZXN0SWQgPSBxdWVyeS5sYXN0UmVxdWVzdElkO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVzZXREaWZmKCkge1xuICAgIHRoaXMubGFzdERpZmYgPSB2b2lkIDA7XG4gIH1cblxuICBnZXREaWZmKCk6IENhY2hlLkRpZmZSZXN1bHQ8YW55PiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0RGlmZk9wdGlvbnMoKTtcblxuICAgIGlmICh0aGlzLmxhc3REaWZmICYmIGVxdWFsKG9wdGlvbnMsIHRoaXMubGFzdERpZmYub3B0aW9ucykpIHtcbiAgICAgIHJldHVybiB0aGlzLmxhc3REaWZmLmRpZmY7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVXYXRjaCh0aGlzLnZhcmlhYmxlcyk7XG5cbiAgICBjb25zdCBvcSA9IHRoaXMub2JzZXJ2YWJsZVF1ZXJ5O1xuICAgIGlmIChvcSAmJiBvcS5vcHRpb25zLmZldGNoUG9saWN5ID09PSBcIm5vLWNhY2hlXCIpIHtcbiAgICAgIHJldHVybiB7IGNvbXBsZXRlOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGRpZmYgPSB0aGlzLmNhY2hlLmRpZmYob3B0aW9ucyk7XG4gICAgdGhpcy51cGRhdGVMYXN0RGlmZihkaWZmLCBvcHRpb25zKTtcbiAgICByZXR1cm4gZGlmZjtcbiAgfVxuXG4gIHByaXZhdGUgbGFzdERpZmY/OiB7XG4gICAgZGlmZjogQ2FjaGUuRGlmZlJlc3VsdDxhbnk+O1xuICAgIG9wdGlvbnM6IENhY2hlLkRpZmZPcHRpb25zO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlTGFzdERpZmYoXG4gICAgZGlmZjogQ2FjaGUuRGlmZlJlc3VsdDxhbnk+IHwgbnVsbCxcbiAgICBvcHRpb25zPzogQ2FjaGUuRGlmZk9wdGlvbnNcbiAgKSB7XG4gICAgdGhpcy5sYXN0RGlmZiA9XG4gICAgICBkaWZmID9cbiAgICAgICAge1xuICAgICAgICAgIGRpZmYsXG4gICAgICAgICAgb3B0aW9uczogb3B0aW9ucyB8fCB0aGlzLmdldERpZmZPcHRpb25zKCksXG4gICAgICAgIH1cbiAgICAgIDogdm9pZCAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREaWZmT3B0aW9ucyh2YXJpYWJsZXMgPSB0aGlzLnZhcmlhYmxlcyk6IENhY2hlLkRpZmZPcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgcXVlcnk6IHRoaXMuZG9jdW1lbnQhLFxuICAgICAgdmFyaWFibGVzLFxuICAgICAgcmV0dXJuUGFydGlhbERhdGE6IHRydWUsXG4gICAgICBvcHRpbWlzdGljOiB0cnVlLFxuICAgICAgY2Fub25pemVSZXN1bHRzOiB0aGlzLm9ic2VydmFibGVRdWVyeT8ub3B0aW9ucy5jYW5vbml6ZVJlc3VsdHMsXG4gICAgfTtcbiAgfVxuXG4gIHNldERpZmYoZGlmZjogQ2FjaGUuRGlmZlJlc3VsdDxhbnk+IHwgbnVsbCkge1xuICAgIGNvbnN0IG9sZERpZmYgPSB0aGlzLmxhc3REaWZmICYmIHRoaXMubGFzdERpZmYuZGlmZjtcblxuICAgIC8vIElmIHdlIGFyZSB0cnlpbmcgdG8gZGVsaXZlciBhbiBpbmNvbXBsZXRlIGNhY2hlIHJlc3VsdCwgd2UgYXZvaWRcbiAgICAvLyByZXBvcnRpbmcgaXQgaWYgdGhlIHF1ZXJ5IGhhcyBlcnJvcmVkLCBvdGhlcndpc2Ugd2UgbGV0IHRoZSBicm9hZGNhc3QgdHJ5XG4gICAgLy8gYW5kIHJlcGFpciB0aGUgcGFydGlhbCByZXN1bHQgYnkgcmVmZXRjaGluZyB0aGUgcXVlcnkuIFRoaXMgY2hlY2sgYXZvaWRzXG4gICAgLy8gYSBzaXR1YXRpb24gd2hlcmUgYSBxdWVyeSB0aGF0IGVycm9ycyBhbmQgYW5vdGhlciBzdWNjZWVkcyB3aXRoXG4gICAgLy8gb3ZlcmxhcHBpbmcgZGF0YSBkb2VzIG5vdCByZXBvcnQgdGhlIHBhcnRpYWwgZGF0YSByZXN1bHQgdG8gdGhlIGVycm9yZWRcbiAgICAvLyBxdWVyeS5cbiAgICAvL1xuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYXBvbGxvZ3JhcGhxbC9hcG9sbG8tY2xpZW50L2lzc3Vlcy8xMTQwMCBmb3IgbW9yZVxuICAgIC8vIGluZm9ybWF0aW9uIG9uIHRoaXMgaXNzdWUuXG4gICAgaWYgKGRpZmYgJiYgIWRpZmYuY29tcGxldGUgJiYgdGhpcy5vYnNlcnZhYmxlUXVlcnk/LmdldExhc3RFcnJvcigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVMYXN0RGlmZihkaWZmKTtcblxuICAgIGlmICghZXF1YWwob2xkRGlmZiAmJiBvbGREaWZmLnJlc3VsdCwgZGlmZiAmJiBkaWZmLnJlc3VsdCkpIHtcbiAgICAgIHRoaXMub2JzZXJ2YWJsZVF1ZXJ5Py5bXCJzY2hlZHVsZU5vdGlmeVwiXSgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBvYnNlcnZhYmxlUXVlcnk6IE9ic2VydmFibGVRdWVyeTxhbnksIGFueT4gfCBudWxsID0gbnVsbDtcbiAgc2V0T2JzZXJ2YWJsZVF1ZXJ5KG9xOiBPYnNlcnZhYmxlUXVlcnk8YW55LCBhbnk+IHwgbnVsbCkge1xuICAgIGlmIChvcSA9PT0gdGhpcy5vYnNlcnZhYmxlUXVlcnkpIHJldHVybjtcbiAgICAodGhpcyBhcyBhbnkpLm9ic2VydmFibGVRdWVyeSA9IG9xO1xuICAgIGlmIChvcSkge1xuICAgICAgb3FbXCJxdWVyeUluZm9cIl0gPSB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdG9wKCkge1xuICAgIGlmICghdGhpcy5zdG9wcGVkKSB7XG4gICAgICB0aGlzLnN0b3BwZWQgPSB0cnVlO1xuXG4gICAgICAvLyBDYW5jZWwgdGhlIHBlbmRpbmcgbm90aWZ5IHRpbWVvdXRcbiAgICAgIHRoaXMub2JzZXJ2YWJsZVF1ZXJ5Py5bXCJyZXNldE5vdGlmaWNhdGlvbnNcIl0oKTtcbiAgICAgIHRoaXMuY2FuY2VsKCk7XG5cbiAgICAgIGNvbnN0IG9xID0gdGhpcy5vYnNlcnZhYmxlUXVlcnk7XG4gICAgICBpZiAob3EpIG9xLnN0b3BQb2xsaW5nKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWwoKSB7XG4gICAgdGhpcy5jYW5jZWxXYXRjaD8uKCk7XG4gICAgdGhpcy5jYW5jZWxXYXRjaCA9IHZvaWQgMDtcbiAgfVxuXG4gIHByaXZhdGUgbGFzdFdhdGNoPzogQ2FjaGUuV2F0Y2hPcHRpb25zO1xuXG4gIHByaXZhdGUgdXBkYXRlV2F0Y2godmFyaWFibGVzID0gdGhpcy52YXJpYWJsZXMpIHtcbiAgICBjb25zdCBvcSA9IHRoaXMub2JzZXJ2YWJsZVF1ZXJ5O1xuICAgIGlmIChvcSAmJiBvcS5vcHRpb25zLmZldGNoUG9saWN5ID09PSBcIm5vLWNhY2hlXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3YXRjaE9wdGlvbnM6IENhY2hlLldhdGNoT3B0aW9ucyA9IHtcbiAgICAgIC8vIEFsdGhvdWdoIHRoaXMuZ2V0RGlmZk9wdGlvbnMgcmV0dXJucyBDYWNoZS5EaWZmT3B0aW9ucyBpbnN0ZWFkIG9mXG4gICAgICAvLyBDYWNoZS5XYXRjaE9wdGlvbnMsIGFsbCB0aGUgb3ZlcmxhcHBpbmcgb3B0aW9ucyBzaG91bGQgYmUgdGhlIHNhbWUsIHNvXG4gICAgICAvLyB3ZSBjYW4gcmV1c2UgZ2V0RGlmZk9wdGlvbnMgaGVyZSwgZm9yIGNvbnNpc3RlbmN5LlxuICAgICAgLi4udGhpcy5nZXREaWZmT3B0aW9ucyh2YXJpYWJsZXMpLFxuICAgICAgd2F0Y2hlcjogdGhpcyxcbiAgICAgIGNhbGxiYWNrOiAoZGlmZikgPT4gdGhpcy5zZXREaWZmKGRpZmYpLFxuICAgIH07XG5cbiAgICBpZiAoIXRoaXMubGFzdFdhdGNoIHx8ICFlcXVhbCh3YXRjaE9wdGlvbnMsIHRoaXMubGFzdFdhdGNoKSkge1xuICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgIHRoaXMuY2FuY2VsV2F0Y2ggPSB0aGlzLmNhY2hlLndhdGNoKCh0aGlzLmxhc3RXYXRjaCA9IHdhdGNoT3B0aW9ucykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbGFzdFdyaXRlPzoge1xuICAgIHJlc3VsdDogRmV0Y2hSZXN1bHQ8YW55PjtcbiAgICB2YXJpYWJsZXM6IFdhdGNoUXVlcnlPcHRpb25zW1widmFyaWFibGVzXCJdO1xuICAgIGRtQ291bnQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgfTtcblxuICBwdWJsaWMgcmVzZXRMYXN0V3JpdGUoKSB7XG4gICAgdGhpcy5sYXN0V3JpdGUgPSB2b2lkIDA7XG4gIH1cblxuICBwcml2YXRlIHNob3VsZFdyaXRlKFxuICAgIHJlc3VsdDogRmV0Y2hSZXN1bHQ8YW55PixcbiAgICB2YXJpYWJsZXM6IFdhdGNoUXVlcnlPcHRpb25zW1widmFyaWFibGVzXCJdXG4gICkge1xuICAgIGNvbnN0IHsgbGFzdFdyaXRlIH0gPSB0aGlzO1xuICAgIHJldHVybiAhKFxuICAgICAgbGFzdFdyaXRlICYmXG4gICAgICAvLyBJZiBjYWNoZS5ldmljdCBoYXMgYmVlbiBjYWxsZWQgc2luY2UgdGhlIGxhc3QgdGltZSB3ZSB3cm90ZSB0aGlzXG4gICAgICAvLyBkYXRhIGludG8gdGhlIGNhY2hlLCB0aGVyZSdzIGEgY2hhbmNlIHdyaXRpbmcgdGhpcyByZXN1bHQgaW50b1xuICAgICAgLy8gdGhlIGNhY2hlIHdpbGwgcmVwYWlyIHdoYXQgd2FzIGV2aWN0ZWQuXG4gICAgICBsYXN0V3JpdGUuZG1Db3VudCA9PT0gZGVzdHJ1Y3RpdmVNZXRob2RDb3VudHMuZ2V0KHRoaXMuY2FjaGUpICYmXG4gICAgICBlcXVhbCh2YXJpYWJsZXMsIGxhc3RXcml0ZS52YXJpYWJsZXMpICYmXG4gICAgICBlcXVhbChyZXN1bHQuZGF0YSwgbGFzdFdyaXRlLnJlc3VsdC5kYXRhKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgbWFya1Jlc3VsdDxUPihcbiAgICByZXN1bHQ6IEZldGNoUmVzdWx0PFQ+LFxuICAgIGRvY3VtZW50OiBEb2N1bWVudE5vZGUsXG4gICAgb3B0aW9uczogUGljazxcbiAgICAgIFdhdGNoUXVlcnlPcHRpb25zLFxuICAgICAgXCJ2YXJpYWJsZXNcIiB8IFwiZmV0Y2hQb2xpY3lcIiB8IFwiZXJyb3JQb2xpY3lcIlxuICAgID4sXG4gICAgY2FjaGVXcml0ZUJlaGF2aW9yOiBDYWNoZVdyaXRlQmVoYXZpb3JcbiAgKSB7XG4gICAgY29uc3QgbWVyZ2VyID0gbmV3IERlZXBNZXJnZXIoKTtcbiAgICBjb25zdCBncmFwaFFMRXJyb3JzID1cbiAgICAgIGlzTm9uRW1wdHlBcnJheShyZXN1bHQuZXJyb3JzKSA/IHJlc3VsdC5lcnJvcnMuc2xpY2UoMCkgOiBbXTtcblxuICAgIC8vIENhbmNlbCB0aGUgcGVuZGluZyBub3RpZnkgdGltZW91dCAoaWYgaXQgZXhpc3RzKSB0byBwcmV2ZW50IGV4dHJhbmVvdXMgbmV0d29ya1xuICAgIC8vIHJlcXVlc3RzLiBUbyBhbGxvdyBmdXR1cmUgbm90aWZ5IHRpbWVvdXRzLCBkaWZmIGFuZCBkaXJ0eSBhcmUgcmVzZXQgYXMgd2VsbC5cbiAgICB0aGlzLm9ic2VydmFibGVRdWVyeT8uW1wicmVzZXROb3RpZmljYXRpb25zXCJdKCk7XG5cbiAgICBpZiAoXCJpbmNyZW1lbnRhbFwiIGluIHJlc3VsdCAmJiBpc05vbkVtcHR5QXJyYXkocmVzdWx0LmluY3JlbWVudGFsKSkge1xuICAgICAgY29uc3QgbWVyZ2VkRGF0YSA9IG1lcmdlSW5jcmVtZW50YWxEYXRhKHRoaXMuZ2V0RGlmZigpLnJlc3VsdCwgcmVzdWx0KTtcbiAgICAgIHJlc3VsdC5kYXRhID0gbWVyZ2VkRGF0YTtcblxuICAgICAgLy8gRGV0ZWN0IHRoZSBmaXJzdCBjaHVuayBvZiBhIGRlZmVycmVkIHF1ZXJ5IGFuZCBtZXJnZSBpdCB3aXRoIGV4aXN0aW5nXG4gICAgICAvLyBjYWNoZSBkYXRhLiBUaGlzIGVuc3VyZXMgYSBgY2FjaGUtZmlyc3RgIGZldGNoIHBvbGljeSB0aGF0IHJldHVybnNcbiAgICAgIC8vIHBhcnRpYWwgY2FjaGUgZGF0YSBvciBhIGBjYWNoZS1hbmQtbmV0d29ya2AgZmV0Y2ggcG9saWN5IHRoYXQgYWxyZWFkeVxuICAgICAgLy8gaGFzIGZ1bGwgZGF0YSBpbiB0aGUgY2FjaGUgZG9lcyBub3QgY29tcGxhaW4gd2hlbiB0cnlpbmcgdG8gbWVyZ2UgdGhlXG4gICAgICAvLyBpbml0aWFsIGRlZmVycmVkIHNlcnZlciBkYXRhIHdpdGggZXhpc3RpbmcgY2FjaGUgZGF0YS5cbiAgICB9IGVsc2UgaWYgKFwiaGFzTmV4dFwiIGluIHJlc3VsdCAmJiByZXN1bHQuaGFzTmV4dCkge1xuICAgICAgY29uc3QgZGlmZiA9IHRoaXMuZ2V0RGlmZigpO1xuICAgICAgcmVzdWx0LmRhdGEgPSBtZXJnZXIubWVyZ2UoZGlmZi5yZXN1bHQsIHJlc3VsdC5kYXRhKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYXBoUUxFcnJvcnMgPSBncmFwaFFMRXJyb3JzO1xuXG4gICAgaWYgKG9wdGlvbnMuZmV0Y2hQb2xpY3kgPT09IFwibm8tY2FjaGVcIikge1xuICAgICAgdGhpcy51cGRhdGVMYXN0RGlmZihcbiAgICAgICAgeyByZXN1bHQ6IHJlc3VsdC5kYXRhLCBjb21wbGV0ZTogdHJ1ZSB9LFxuICAgICAgICB0aGlzLmdldERpZmZPcHRpb25zKG9wdGlvbnMudmFyaWFibGVzKVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGNhY2hlV3JpdGVCZWhhdmlvciAhPT0gQ2FjaGVXcml0ZUJlaGF2aW9yLkZPUkJJRCkge1xuICAgICAgaWYgKHNob3VsZFdyaXRlUmVzdWx0KHJlc3VsdCwgb3B0aW9ucy5lcnJvclBvbGljeSkpIHtcbiAgICAgICAgLy8gVXNpbmcgYSB0cmFuc2FjdGlvbiBoZXJlIHNvIHdlIGhhdmUgYSBjaGFuY2UgdG8gcmVhZCB0aGUgcmVzdWx0XG4gICAgICAgIC8vIGJhY2sgZnJvbSB0aGUgY2FjaGUgYmVmb3JlIHRoZSB3YXRjaCBjYWxsYmFjayBmaXJlcyBhcyBhIHJlc3VsdFxuICAgICAgICAvLyBvZiB3cml0ZVF1ZXJ5LCBzbyB3ZSBjYW4gc3RvcmUgdGhlIG5ldyBkaWZmIHF1aWV0bHkgYW5kIGlnbm9yZVxuICAgICAgICAvLyBpdCB3aGVuIHdlIHJlY2VpdmUgaXQgcmVkdW5kYW50bHkgZnJvbSB0aGUgd2F0Y2ggY2FsbGJhY2suXG4gICAgICAgIHRoaXMuY2FjaGUucGVyZm9ybVRyYW5zYWN0aW9uKChjYWNoZSkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLnNob3VsZFdyaXRlKHJlc3VsdCwgb3B0aW9ucy52YXJpYWJsZXMpKSB7XG4gICAgICAgICAgICBjYWNoZS53cml0ZVF1ZXJ5KHtcbiAgICAgICAgICAgICAgcXVlcnk6IGRvY3VtZW50LFxuICAgICAgICAgICAgICBkYXRhOiByZXN1bHQuZGF0YSBhcyBVbm1hc2tlZDxUPixcbiAgICAgICAgICAgICAgdmFyaWFibGVzOiBvcHRpb25zLnZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgb3ZlcndyaXRlOiBjYWNoZVdyaXRlQmVoYXZpb3IgPT09IENhY2hlV3JpdGVCZWhhdmlvci5PVkVSV1JJVEUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5sYXN0V3JpdGUgPSB7XG4gICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgdmFyaWFibGVzOiBvcHRpb25zLnZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgZG1Db3VudDogZGVzdHJ1Y3RpdmVNZXRob2RDb3VudHMuZ2V0KHRoaXMuY2FjaGUpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgcmVzdWx0IGlzIHRoZSBzYW1lIGFzIHRoZSBsYXN0IHJlc3VsdCB3ZSByZWNlaXZlZCBmcm9tXG4gICAgICAgICAgICAvLyB0aGUgbmV0d29yayAoYW5kIHRoZSB2YXJpYWJsZXMgbWF0Y2ggdG9vKSwgYXZvaWQgd3JpdGluZ1xuICAgICAgICAgICAgLy8gcmVzdWx0IGludG8gdGhlIGNhY2hlIGFnYWluLiBUaGUgd2lzZG9tIG9mIHNraXBwaW5nIHRoaXNcbiAgICAgICAgICAgIC8vIGNhY2hlIHdyaXRlIGlzIGZhciBmcm9tIG9idmlvdXMsIHNpbmNlIGFueSBjYWNoZSB3cml0ZVxuICAgICAgICAgICAgLy8gY291bGQgYmUgdGhlIG9uZSB0aGF0IHB1dHMgdGhlIGNhY2hlIGJhY2sgaW50byBhIGRlc2lyZWRcbiAgICAgICAgICAgIC8vIHN0YXRlLCBmaXhpbmcgY29ycnVwdGlvbiBvciBtaXNzaW5nIGRhdGEuIEhvd2V2ZXIsIGlmIHdlXG4gICAgICAgICAgICAvLyBhbHdheXMgd3JpdGUgZXZlcnkgbmV0d29yayByZXN1bHQgaW50byB0aGUgY2FjaGUsIHdlIGVuYWJsZVxuICAgICAgICAgICAgLy8gZmV1ZHMgYmV0d2VlbiBxdWVyaWVzIGNvbXBldGluZyB0byB1cGRhdGUgdGhlIHNhbWUgZGF0YSBpblxuICAgICAgICAgICAgLy8gaW5jb21wYXRpYmxlIHdheXMsIHdoaWNoIGNhbiBsZWFkIHRvIGFuIGVuZGxlc3MgY3ljbGUgb2ZcbiAgICAgICAgICAgIC8vIGNhY2hlIGJyb2FkY2FzdHMgYW5kIHVzZWxlc3MgbmV0d29yayByZXF1ZXN0cy4gQXMgd2l0aCBhbnlcbiAgICAgICAgICAgIC8vIGZldWQsIGV2ZW50dWFsbHkgb25lIHNpZGUgbXVzdCBzdGVwIGJhY2sgZnJvbSB0aGUgYnJpbmssXG4gICAgICAgICAgICAvLyBsZXR0aW5nIHRoZSBvdGhlciBzaWRlKHMpIGhhdmUgdGhlIGxhc3Qgd29yZChzKS4gVGhlcmUgbWF5XG4gICAgICAgICAgICAvLyBiZSBvdGhlciBwb2ludHMgd2hlcmUgd2UgY291bGQgYnJlYWsgdGhpcyBjeWNsZSwgc3VjaCBhc1xuICAgICAgICAgICAgLy8gc2lsZW5jaW5nIHRoZSBicm9hZGNhc3QgZm9yIGNhY2hlLndyaXRlUXVlcnkgKG5vdCBhIGdvb2RcbiAgICAgICAgICAgIC8vIGlkZWEsIHNpbmNlIGl0IGp1c3QgZGVsYXlzIHRoZSBmZXVkIGEgYml0KSBvciBzb21laG93XG4gICAgICAgICAgICAvLyBhdm9pZGluZyB0aGUgbmV0d29yayByZXF1ZXN0IHRoYXQganVzdCBoYXBwZW5lZCAoYWxzbyBiYWQsXG4gICAgICAgICAgICAvLyBiZWNhdXNlIHRoZSBzZXJ2ZXIgY291bGQgcmV0dXJuIHVzZWZ1bCBuZXcgZGF0YSkuIEFsbFxuICAgICAgICAgICAgLy8gb3B0aW9ucyBjb25zaWRlcmVkLCBza2lwcGluZyB0aGlzIGNhY2hlIHdyaXRlIHNlZW1zIHRvIGJlXG4gICAgICAgICAgICAvLyB0aGUgbGVhc3QgZGFtYWdpbmcgcGxhY2UgdG8gYnJlYWsgdGhlIGN5Y2xlLCBiZWNhdXNlIGl0XG4gICAgICAgICAgICAvLyByZWZsZWN0cyB0aGUgaW50dWl0aW9uIHRoYXQgd2UgcmVjZW50bHkgd3JvdGUgdGhpcyBleGFjdFxuICAgICAgICAgICAgLy8gcmVzdWx0IGludG8gdGhlIGNhY2hlLCBzbyB0aGUgY2FjaGUgKnNob3VsZCogYWxyZWFkeS9zdGlsbFxuICAgICAgICAgICAgLy8gY29udGFpbiB0aGlzIGRhdGEuIElmIHNvbWUgb3RoZXIgcXVlcnkgaGFzIGNsb2JiZXJlZCB0aGF0XG4gICAgICAgICAgICAvLyBkYXRhIGluIHRoZSBtZWFudGltZSwgdGhhdCdzIHRvbyBiYWQsIGJ1dCB0aGVyZSB3aWxsIGJlIG5vXG4gICAgICAgICAgICAvLyB3aW5uZXJzIGlmIGV2ZXJ5IHF1ZXJ5IGJsaW5kbHkgcmV2ZXJ0cyB0byBpdHMgb3duIHZlcnNpb25cbiAgICAgICAgICAgIC8vIG9mIHRoZSBkYXRhLiBUaGlzIGFwcHJvYWNoIGFsc28gZ2l2ZXMgdGhlIG5ldHdvcmsgYSBjaGFuY2VcbiAgICAgICAgICAgIC8vIHRvIHJldHVybiBuZXcgZGF0YSwgd2hpY2ggd2lsbCBiZSB3cml0dGVuIGludG8gdGhlIGNhY2hlIGFzXG4gICAgICAgICAgICAvLyB1c3VhbCwgbm90aWZ5aW5nIG9ubHkgdGhvc2UgcXVlcmllcyB0aGF0IGFyZSBkaXJlY3RseVxuICAgICAgICAgICAgLy8gYWZmZWN0ZWQgYnkgdGhlIGNhY2hlIHVwZGF0ZXMsIGFzIHVzdWFsLiBJbiB0aGUgZnV0dXJlLCBhblxuICAgICAgICAgICAgLy8gZXZlbiBtb3JlIHNvcGhpc3RpY2F0ZWQgY2FjaGUgY291bGQgcGVyaGFwcyBwcmV2ZW50IG9yXG4gICAgICAgICAgICAvLyBtaXRpZ2F0ZSB0aGUgY2xvYmJlcmluZyBzb21laG93LCBidXQgdGhhdCB3b3VsZCBtYWtlIHRoaXNcbiAgICAgICAgICAgIC8vIHBhcnRpY3VsYXIgY2FjaGUgd3JpdGUgZXZlbiBsZXNzIGltcG9ydGFudCwgYW5kIHRodXNcbiAgICAgICAgICAgIC8vIHNraXBwaW5nIGl0IHdvdWxkIGJlIGV2ZW4gc2FmZXIgdGhhbiBpdCBpcyB0b2RheS5cbiAgICAgICAgICAgIGlmICh0aGlzLmxhc3REaWZmICYmIHRoaXMubGFzdERpZmYuZGlmZi5jb21wbGV0ZSkge1xuICAgICAgICAgICAgICAvLyBSZXVzZSBkYXRhIGZyb20gdGhlIGxhc3QgZ29vZCAoY29tcGxldGUpIGRpZmYgdGhhdCB3ZVxuICAgICAgICAgICAgICAvLyByZWNlaXZlZCwgd2hlbiBwb3NzaWJsZS5cbiAgICAgICAgICAgICAgcmVzdWx0LmRhdGEgPSB0aGlzLmxhc3REaWZmLmRpZmYucmVzdWx0O1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJZiB0aGUgcHJldmlvdXMgdGhpcy5kaWZmIHdhcyBpbmNvbXBsZXRlLCBmYWxsIHRocm91Z2ggdG9cbiAgICAgICAgICAgIC8vIHJlLXJlYWRpbmcgdGhlIGxhdGVzdCBkYXRhIHdpdGggY2FjaGUuZGlmZiwgYmVsb3cuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZGlmZk9wdGlvbnMgPSB0aGlzLmdldERpZmZPcHRpb25zKG9wdGlvbnMudmFyaWFibGVzKTtcbiAgICAgICAgICBjb25zdCBkaWZmID0gY2FjaGUuZGlmZjxUPihkaWZmT3B0aW9ucyk7XG5cbiAgICAgICAgICAvLyBJbiBjYXNlIHRoZSBRdWVyeU1hbmFnZXIgc3RvcHMgdGhpcyBRdWVyeUluZm8gYmVmb3JlIGl0c1xuICAgICAgICAgIC8vIHJlc3VsdHMgYXJlIGRlbGl2ZXJlZCwgaXQncyBpbXBvcnRhbnQgdG8gYXZvaWQgcmVzdGFydGluZyB0aGVcbiAgICAgICAgICAvLyBjYWNoZSB3YXRjaCB3aGVuIG1hcmtSZXN1bHQgaXMgY2FsbGVkLiBXZSBhbHNvIGF2b2lkIHVwZGF0aW5nXG4gICAgICAgICAgLy8gdGhlIHdhdGNoIGlmIHdlIGFyZSB3cml0aW5nIGEgcmVzdWx0IHRoYXQgZG9lc24ndCBtYXRjaCB0aGUgY3VycmVudFxuICAgICAgICAgIC8vIHZhcmlhYmxlcyB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgZnJvbSBicm9hZGNhc3RpbmcgdGhlIHdyb25nXG4gICAgICAgICAgLy8gcmVzdWx0LlxuICAgICAgICAgIGlmICghdGhpcy5zdG9wcGVkICYmIGVxdWFsKHRoaXMudmFyaWFibGVzLCBvcHRpb25zLnZhcmlhYmxlcykpIHtcbiAgICAgICAgICAgIC8vIEFueSB0aW1lIHdlJ3JlIGFib3V0IHRvIHVwZGF0ZSB0aGlzLmRpZmYsIHdlIG5lZWQgdG8gbWFrZVxuICAgICAgICAgICAgLy8gc3VyZSB3ZSd2ZSBzdGFydGVkIHdhdGNoaW5nIHRoZSBjYWNoZS5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlV2F0Y2gob3B0aW9ucy52YXJpYWJsZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIElmIHdlJ3JlIGFsbG93ZWQgdG8gd3JpdGUgdG8gdGhlIGNhY2hlLCBhbmQgd2UgY2FuIHJlYWQgYVxuICAgICAgICAgIC8vIGNvbXBsZXRlIHJlc3VsdCBmcm9tIHRoZSBjYWNoZSwgdXBkYXRlIHJlc3VsdC5kYXRhIHRvIGJlIHRoZVxuICAgICAgICAgIC8vIHJlc3VsdCBmcm9tIHRoZSBjYWNoZSwgcmF0aGVyIHRoYW4gdGhlIHJhdyBuZXR3b3JrIHJlc3VsdC5cbiAgICAgICAgICAvLyBTZXQgd2l0aG91dCBzZXREaWZmIHRvIGF2b2lkIHRyaWdnZXJpbmcgYSBub3RpZnkgY2FsbCwgc2luY2VcbiAgICAgICAgICAvLyB3ZSBoYXZlIG90aGVyIHdheXMgb2Ygbm90aWZ5aW5nIGZvciB0aGlzIHJlc3VsdC5cbiAgICAgICAgICB0aGlzLnVwZGF0ZUxhc3REaWZmKGRpZmYsIGRpZmZPcHRpb25zKTtcbiAgICAgICAgICBpZiAoZGlmZi5jb21wbGV0ZSkge1xuICAgICAgICAgICAgcmVzdWx0LmRhdGEgPSBkaWZmLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sYXN0V3JpdGUgPSB2b2lkIDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG1hcmtSZWFkeSgpIHtcbiAgICB0aGlzLm5ldHdvcmtFcnJvciA9IG51bGw7XG4gICAgcmV0dXJuICh0aGlzLm5ldHdvcmtTdGF0dXMgPSBOZXR3b3JrU3RhdHVzLnJlYWR5KTtcbiAgfVxuXG4gIHB1YmxpYyBtYXJrRXJyb3IoZXJyb3I6IEFwb2xsb0Vycm9yKSB7XG4gICAgdGhpcy5uZXR3b3JrU3RhdHVzID0gTmV0d29ya1N0YXR1cy5lcnJvcjtcbiAgICB0aGlzLmxhc3RXcml0ZSA9IHZvaWQgMDtcblxuICAgIHRoaXMub2JzZXJ2YWJsZVF1ZXJ5Py5bXCJyZXNldE5vdGlmaWNhdGlvbnNcIl0oKTtcblxuICAgIGlmIChlcnJvci5ncmFwaFFMRXJyb3JzKSB7XG4gICAgICB0aGlzLmdyYXBoUUxFcnJvcnMgPSBlcnJvci5ncmFwaFFMRXJyb3JzO1xuICAgIH1cblxuICAgIGlmIChlcnJvci5uZXR3b3JrRXJyb3IpIHtcbiAgICAgIHRoaXMubmV0d29ya0Vycm9yID0gZXJyb3IubmV0d29ya0Vycm9yO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2hvdWxkV3JpdGVSZXN1bHQ8VD4oXG4gIHJlc3VsdDogRmV0Y2hSZXN1bHQ8VD4sXG4gIGVycm9yUG9saWN5OiBFcnJvclBvbGljeSA9IFwibm9uZVwiXG4pIHtcbiAgY29uc3QgaWdub3JlRXJyb3JzID0gZXJyb3JQb2xpY3kgPT09IFwiaWdub3JlXCIgfHwgZXJyb3JQb2xpY3kgPT09IFwiYWxsXCI7XG4gIGxldCB3cml0ZVdpdGhFcnJvcnMgPSAhZ3JhcGhRTFJlc3VsdEhhc0Vycm9yKHJlc3VsdCk7XG4gIGlmICghd3JpdGVXaXRoRXJyb3JzICYmIGlnbm9yZUVycm9ycyAmJiByZXN1bHQuZGF0YSkge1xuICAgIHdyaXRlV2l0aEVycm9ycyA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHdyaXRlV2l0aEVycm9ycztcbn1cbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF19